From 464245d4351c79a20c3ea40ca0dfe8ca164b0691 Mon Sep 17 00:00:00 2001 From: pschneid Date: Tue, 21 Oct 2025 15:43:52 +0200 Subject: [PATCH] final commit v1 --- dist/assets/index-BailLCJ0.js | 473 - dist/assets/index-CW56MEbw.css | 1 + dist/assets/index-DMWoNld2.js | 516 + dist/assets/index-HYQ6lVkA.css | 1 - dist/index.html | 4 +- server/dist/routes/users.js | 344 + server/node_modules/.package-lock.json | 58 +- .../better-sqlite3/build/Makefile | 339 + .../.deps/Release/better_sqlite3.node.d | 1 + .../Release/obj.target/better_sqlite3.node.d | 1 + .../better_sqlite3/src/better_sqlite3.o.d | 123 + .../obj.target/deps/locate_sqlite3.stamp.d | 1 + .../.deps/Release/obj.target/deps/sqlite3.a.d | 1 + .../sqlite3/gen/sqlite3/sqlite3.o.d | 4 + .../Release/obj.target/test_extension.node.d | 1 + .../test_extension/deps/test_extension.o.d | 7 + .../build/Release/.deps/Release/sqlite3.a.d | 1 + .../.deps/Release/test_extension.node.d | 1 + ...63e16015df367567cb043fed872.intermediate.d | 1 + .../build/Release/better_sqlite3.node | Bin 2038664 -> 2121056 bytes .../Release/obj.target/better_sqlite3.node | Bin 0 -> 2121056 bytes .../better_sqlite3/src/better_sqlite3.o | Bin 0 -> 160248 bytes .../obj.target/deps/locate_sqlite3.stamp | 0 .../build/Release/obj.target/deps/sqlite3.a | Bin 0 -> 2449566 bytes .../obj.target/sqlite3/gen/sqlite3/sqlite3.o | Bin 0 -> 2442672 bytes .../Release/obj.target/test_extension.node | Bin 0 -> 15280 bytes .../test_extension/deps/test_extension.o | Bin 0 -> 1800 bytes .../build/Release/obj/gen/sqlite3/sqlite3.c | 255954 +++++++++++++++ .../build/Release/obj/gen/sqlite3/sqlite3.h | 13374 + .../Release/obj/gen/sqlite3/sqlite3ext.h | 719 + .../better-sqlite3/build/Release/sqlite3.a | Bin 0 -> 2449566 bytes .../build/Release/test_extension.node | Bin 0 -> 15280 bytes .../build/better_sqlite3.target.mk | 176 + .../better-sqlite3/build/binding.Makefile | 6 + .../better-sqlite3/build/config.gypi | 416 + .../build/deps/locate_sqlite3.target.mk | 42 + .../build/deps/sqlite3.Makefile | 6 + .../build/deps/sqlite3.target.mk | 248 + .../build/node_gyp_bins/python3 | 1 + .../build/test_extension.target.mk | 170 + server/package-lock.json | 60 +- server/package.json | 2 +- server/src/routes/users.ts | 381 + spotify.db | Bin 1679360 -> 2015232 bytes spotify.db-shm | Bin 32768 -> 32768 bytes spotify.db-wal | Bin 4499072 -> 4499072 bytes src/App.tsx | 2 + src/components/Navbar.tsx | 4 +- src/pages/LastListenedPage.tsx | 12 +- src/pages/LoginPage.tsx | 45 +- src/pages/MemoryLanePage.tsx | 10 +- src/pages/MixedPlaylistPage.tsx | 20 +- src/pages/WrappedPage.tsx | 726 + src/styles/globals.css | 50 + src/types/index.ts | 43 + src/utils/spotify.ts | 6 +- 56 files changed, 273760 insertions(+), 591 deletions(-) delete mode 100644 dist/assets/index-BailLCJ0.js create mode 100644 dist/assets/index-CW56MEbw.css create mode 100644 dist/assets/index-DMWoNld2.js delete mode 100644 dist/assets/index-HYQ6lVkA.css create mode 100644 server/node_modules/better-sqlite3/build/Makefile create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/better_sqlite3.node.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3.node.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3/src/better_sqlite3.o.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/locate_sqlite3.stamp.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/sqlite3.a.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension.node.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension/deps/test_extension.o.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/sqlite3.a.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/Release/test_extension.node.d create mode 100644 server/node_modules/better-sqlite3/build/Release/.deps/ba23eeee118cd63e16015df367567cb043fed872.intermediate.d create mode 100755 server/node_modules/better-sqlite3/build/Release/obj.target/better_sqlite3.node create mode 100644 server/node_modules/better-sqlite3/build/Release/obj.target/better_sqlite3/src/better_sqlite3.o create mode 100644 server/node_modules/better-sqlite3/build/Release/obj.target/deps/locate_sqlite3.stamp create mode 100644 server/node_modules/better-sqlite3/build/Release/obj.target/deps/sqlite3.a create mode 100644 server/node_modules/better-sqlite3/build/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o create mode 100755 server/node_modules/better-sqlite3/build/Release/obj.target/test_extension.node create mode 100644 server/node_modules/better-sqlite3/build/Release/obj.target/test_extension/deps/test_extension.o create mode 100644 server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3/sqlite3.c create mode 100644 server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3/sqlite3.h create mode 100644 server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3/sqlite3ext.h create mode 100644 server/node_modules/better-sqlite3/build/Release/sqlite3.a create mode 100755 server/node_modules/better-sqlite3/build/Release/test_extension.node create mode 100644 server/node_modules/better-sqlite3/build/better_sqlite3.target.mk create mode 100644 server/node_modules/better-sqlite3/build/binding.Makefile create mode 100644 server/node_modules/better-sqlite3/build/config.gypi create mode 100644 server/node_modules/better-sqlite3/build/deps/locate_sqlite3.target.mk create mode 100644 server/node_modules/better-sqlite3/build/deps/sqlite3.Makefile create mode 100644 server/node_modules/better-sqlite3/build/deps/sqlite3.target.mk create mode 120000 server/node_modules/better-sqlite3/build/node_gyp_bins/python3 create mode 100644 server/node_modules/better-sqlite3/build/test_extension.target.mk create mode 100644 src/pages/WrappedPage.tsx diff --git a/dist/assets/index-BailLCJ0.js b/dist/assets/index-BailLCJ0.js deleted file mode 100644 index ca16719..0000000 --- a/dist/assets/index-BailLCJ0.js +++ /dev/null @@ -1,473 +0,0 @@ -function ty(e,t){for(var n=0;nr[s]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();function cu(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Fh={exports:{}},Eo={},Ih={exports:{}},Y={};/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var qs=Symbol.for("react.element"),ny=Symbol.for("react.portal"),ry=Symbol.for("react.fragment"),sy=Symbol.for("react.strict_mode"),iy=Symbol.for("react.profiler"),oy=Symbol.for("react.provider"),ay=Symbol.for("react.context"),ly=Symbol.for("react.forward_ref"),uy=Symbol.for("react.suspense"),cy=Symbol.for("react.memo"),dy=Symbol.for("react.lazy"),Vc=Symbol.iterator;function fy(e){return e===null||typeof e!="object"?null:(e=Vc&&e[Vc]||e["@@iterator"],typeof e=="function"?e:null)}var zh={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Oh=Object.assign,$h={};function Fr(e,t,n){this.props=e,this.context=t,this.refs=$h,this.updater=n||zh}Fr.prototype.isReactComponent={};Fr.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};Fr.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function Bh(){}Bh.prototype=Fr.prototype;function du(e,t,n){this.props=e,this.context=t,this.refs=$h,this.updater=n||zh}var fu=du.prototype=new Bh;fu.constructor=du;Oh(fu,Fr.prototype);fu.isPureReactComponent=!0;var Fc=Array.isArray,Uh=Object.prototype.hasOwnProperty,hu={current:null},Wh={key:!0,ref:!0,__self:!0,__source:!0};function Hh(e,t,n){var r,s={},i=null,o=null;if(t!=null)for(r in t.ref!==void 0&&(o=t.ref),t.key!==void 0&&(i=""+t.key),t)Uh.call(t,r)&&!Wh.hasOwnProperty(r)&&(s[r]=t[r]);var a=arguments.length-2;if(a===1)s.children=n;else if(1>>1,E=_[L];if(0>>1;Ls(te,F))Gs(be,te)?(_[L]=be,_[G]=F,L=G):(_[L]=te,_[X]=F,L=X);else if(Gs(be,F))_[L]=be,_[G]=F,L=G;else break e}}return N}function s(_,N){var F=_.sortIndex-N.sortIndex;return F!==0?F:_.id-N.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var o=Date,a=o.now();e.unstable_now=function(){return o.now()-a}}var l=[],c=[],d=1,f=null,u=3,h=!1,p=!1,g=!1,x=typeof setTimeout=="function"?setTimeout:null,v=typeof clearTimeout=="function"?clearTimeout:null,y=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function w(_){for(var N=n(c);N!==null;){if(N.callback===null)r(c);else if(N.startTime<=_)r(c),N.sortIndex=N.expirationTime,t(l,N);else break;N=n(c)}}function b(_){if(g=!1,w(_),!p)if(n(l)!==null)p=!0,A(S);else{var N=n(c);N!==null&&q(b,N.startTime-_)}}function S(_,N){p=!1,g&&(g=!1,v(j),j=-1),h=!0;var F=u;try{for(w(N),f=n(l);f!==null&&(!(f.expirationTime>N)||_&&!z());){var L=f.callback;if(typeof L=="function"){f.callback=null,u=f.priorityLevel;var E=L(f.expirationTime<=N);N=e.unstable_now(),typeof E=="function"?f.callback=E:f===n(l)&&r(l),w(N)}else r(l);f=n(l)}if(f!==null)var W=!0;else{var X=n(c);X!==null&&q(b,X.startTime-N),W=!1}return W}finally{f=null,u=F,h=!1}}var C=!1,P=null,j=-1,D=5,T=-1;function z(){return!(e.unstable_now()-T_||125<_?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):D=0<_?Math.floor(1e3/_):5},e.unstable_getCurrentPriorityLevel=function(){return u},e.unstable_getFirstCallbackNode=function(){return n(l)},e.unstable_next=function(_){switch(u){case 1:case 2:case 3:var N=3;break;default:N=u}var F=u;u=N;try{return _()}finally{u=F}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(_,N){switch(_){case 1:case 2:case 3:case 4:case 5:break;default:_=3}var F=u;u=_;try{return N()}finally{u=F}},e.unstable_scheduleCallback=function(_,N,F){var L=e.unstable_now();switch(typeof F=="object"&&F!==null?(F=F.delay,F=typeof F=="number"&&0L?(_.sortIndex=F,t(c,_),n(l)===null&&_===n(c)&&(g?(v(j),j=-1):g=!0,q(b,F-L))):(_.sortIndex=E,t(l,_),p||h||(p=!0,A(S))),_},e.unstable_shouldYield=z,e.unstable_wrapCallback=function(_){var N=u;return function(){var F=u;u=N;try{return _.apply(this,arguments)}finally{u=F}}}})(Xh);Kh.exports=Xh;var Cy=Kh.exports;/** - * @license React - * react-dom.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Py=k,Ze=Cy;function M(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Xa=Object.prototype.hasOwnProperty,jy=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,zc={},Oc={};function Ey(e){return Xa.call(Oc,e)?!0:Xa.call(zc,e)?!1:jy.test(e)?Oc[e]=!0:(zc[e]=!0,!1)}function Ty(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function Ny(e,t,n,r){if(t===null||typeof t>"u"||Ty(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function $e(e,t,n,r,s,i,o){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=s,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=o}var _e={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){_e[e]=new $e(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];_e[t]=new $e(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){_e[e]=new $e(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){_e[e]=new $e(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){_e[e]=new $e(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){_e[e]=new $e(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){_e[e]=new $e(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){_e[e]=new $e(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){_e[e]=new $e(e,5,!1,e.toLowerCase(),null,!1,!1)});var mu=/[\-:]([a-z])/g;function gu(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(mu,gu);_e[t]=new $e(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(mu,gu);_e[t]=new $e(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(mu,gu);_e[t]=new $e(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){_e[e]=new $e(e,1,!1,e.toLowerCase(),null,!1,!1)});_e.xlinkHref=new $e("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){_e[e]=new $e(e,1,!1,e.toLowerCase(),null,!0,!0)});function yu(e,t,n,r){var s=_e.hasOwnProperty(t)?_e[t]:null;(s!==null?s.type!==0:r||!(2a||s[o]!==i[a]){var l=` -`+s[o].replace(" at new "," at ");return e.displayName&&l.includes("")&&(l=l.replace("",e.displayName)),l}while(1<=o&&0<=a);break}}}finally{ia=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?rs(e):""}function My(e){switch(e.tag){case 5:return rs(e.type);case 16:return rs("Lazy");case 13:return rs("Suspense");case 19:return rs("SuspenseList");case 0:case 2:case 15:return e=oa(e.type,!1),e;case 11:return e=oa(e.type.render,!1),e;case 1:return e=oa(e.type,!0),e;default:return""}}function el(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case rr:return"Fragment";case nr:return"Portal";case Qa:return"Profiler";case vu:return"StrictMode";case Za:return"Suspense";case Ja:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Jh:return(e.displayName||"Context")+".Consumer";case Zh:return(e._context.displayName||"Context")+".Provider";case xu:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case wu:return t=e.displayName||null,t!==null?t:el(e.type)||"Memo";case Zt:t=e._payload,e=e._init;try{return el(e(t))}catch{}}return null}function _y(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return el(t);case 8:return t===vu?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function vn(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function tp(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Ay(e){var t=tp(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var s=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return s.call(this)},set:function(o){r=""+o,i.call(this,o)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(o){r=""+o},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function oi(e){e._valueTracker||(e._valueTracker=Ay(e))}function np(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=tp(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function Ui(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function tl(e,t){var n=t.checked;return fe({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function Bc(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=vn(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function rp(e,t){t=t.checked,t!=null&&yu(e,"checked",t,!1)}function nl(e,t){rp(e,t);var n=vn(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?rl(e,t.type,n):t.hasOwnProperty("defaultValue")&&rl(e,t.type,vn(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function Uc(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function rl(e,t,n){(t!=="number"||Ui(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var ss=Array.isArray;function vr(e,t,n,r){if(e=e.options,t){t={};for(var s=0;s"+t.valueOf().toString()+"",t=ai.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Cs(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var ls={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Ly=["Webkit","ms","Moz","O"];Object.keys(ls).forEach(function(e){Ly.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ls[t]=ls[e]})});function ap(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||ls.hasOwnProperty(e)&&ls[e]?(""+t).trim():t+"px"}function lp(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,s=ap(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,s):e[n]=s}}var Dy=fe({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ol(e,t){if(t){if(Dy[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(M(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(M(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(M(61))}if(t.style!=null&&typeof t.style!="object")throw Error(M(62))}}function al(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var ll=null;function bu(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var ul=null,xr=null,wr=null;function qc(e){if(e=Xs(e)){if(typeof ul!="function")throw Error(M(280));var t=e.stateNode;t&&(t=Ao(t),ul(e.stateNode,e.type,t))}}function up(e){xr?wr?wr.push(e):wr=[e]:xr=e}function cp(){if(xr){var e=xr,t=wr;if(wr=xr=null,qc(e),t)for(e=0;e>>=0,e===0?32:31-(Hy(e)/qy|0)|0}var li=64,ui=4194304;function is(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Gi(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,s=e.suspendedLanes,i=e.pingedLanes,o=n&268435455;if(o!==0){var a=o&~s;a!==0?r=is(a):(i&=o,i!==0&&(r=is(i)))}else o=n&~s,o!==0?r=is(o):i!==0&&(r=is(i));if(r===0)return 0;if(t!==0&&t!==r&&!(t&s)&&(s=r&-r,i=t&-t,s>=i||s===16&&(i&4194240)!==0))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Ys(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-gt(t),e[t]=n}function Xy(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=cs),td=" ",nd=!1;function Mp(e,t){switch(e){case"keyup":return C1.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function _p(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var sr=!1;function j1(e,t){switch(e){case"compositionend":return _p(t);case"keypress":return t.which!==32?null:(nd=!0,td);case"textInput":return e=t.data,e===td&&nd?null:e;default:return null}}function E1(e,t){if(sr)return e==="compositionend"||!Nu&&Mp(e,t)?(e=Tp(),Mi=ju=sn=null,sr=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=od(n)}}function Rp(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Rp(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Vp(){for(var e=window,t=Ui();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=Ui(e.document)}return t}function Mu(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function V1(e){var t=Vp(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Rp(n.ownerDocument.documentElement,n)){if(r!==null&&Mu(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var s=n.textContent.length,i=Math.min(r.start,s);r=r.end===void 0?i:Math.min(r.end,s),!e.extend&&i>r&&(s=r,r=i,i=s),s=ad(n,i);var o=ad(n,r);s&&o&&(e.rangeCount!==1||e.anchorNode!==s.node||e.anchorOffset!==s.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&(t=t.createRange(),t.setStart(s.node,s.offset),e.removeAllRanges(),i>r?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,ir=null,ml=null,fs=null,gl=!1;function ld(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;gl||ir==null||ir!==Ui(r)||(r=ir,"selectionStart"in r&&Mu(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),fs&&Ms(fs,r)||(fs=r,r=Xi(ml,"onSelect"),0lr||(e.current=Sl[lr],Sl[lr]=null,lr--)}function J(e,t){lr++,Sl[lr]=e.current,e.current=t}var xn={},Ve=kn(xn),We=kn(!1),Un=xn;function Er(e,t){var n=e.type.contextTypes;if(!n)return xn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var s={},i;for(i in n)s[i]=t[i];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=s),s}function He(e){return e=e.childContextTypes,e!=null}function Zi(){ie(We),ie(Ve)}function md(e,t,n){if(Ve.current!==xn)throw Error(M(168));J(Ve,t),J(We,n)}function Hp(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var s in r)if(!(s in t))throw Error(M(108,_y(e)||"Unknown",s));return fe({},n,r)}function Ji(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||xn,Un=Ve.current,J(Ve,e),J(We,We.current),!0}function gd(e,t,n){var r=e.stateNode;if(!r)throw Error(M(169));n?(e=Hp(e,t,Un),r.__reactInternalMemoizedMergedChildContext=e,ie(We),ie(Ve),J(Ve,e)):ie(We),J(We,n)}var Lt=null,Lo=!1,wa=!1;function qp(e){Lt===null?Lt=[e]:Lt.push(e)}function Y1(e){Lo=!0,qp(e)}function Cn(){if(!wa&&Lt!==null){wa=!0;var e=0,t=Z;try{var n=Lt;for(Z=1;e>=o,s-=o,Dt=1<<32-gt(t)+s|n<j?(D=P,P=null):D=P.sibling;var T=u(v,P,w[j],b);if(T===null){P===null&&(P=D);break}e&&P&&T.alternate===null&&t(v,P),y=i(T,y,j),C===null?S=T:C.sibling=T,C=T,P=D}if(j===w.length)return n(v,P),le&&An(v,j),S;if(P===null){for(;jj?(D=P,P=null):D=P.sibling;var z=u(v,P,T.value,b);if(z===null){P===null&&(P=D);break}e&&P&&z.alternate===null&&t(v,P),y=i(z,y,j),C===null?S=z:C.sibling=z,C=z,P=D}if(T.done)return n(v,P),le&&An(v,j),S;if(P===null){for(;!T.done;j++,T=w.next())T=f(v,T.value,b),T!==null&&(y=i(T,y,j),C===null?S=T:C.sibling=T,C=T);return le&&An(v,j),S}for(P=r(v,P);!T.done;j++,T=w.next())T=h(P,v,j,T.value,b),T!==null&&(e&&T.alternate!==null&&P.delete(T.key===null?j:T.key),y=i(T,y,j),C===null?S=T:C.sibling=T,C=T);return e&&P.forEach(function(V){return t(v,V)}),le&&An(v,j),S}function x(v,y,w,b){if(typeof w=="object"&&w!==null&&w.type===rr&&w.key===null&&(w=w.props.children),typeof w=="object"&&w!==null){switch(w.$$typeof){case ii:e:{for(var S=w.key,C=y;C!==null;){if(C.key===S){if(S=w.type,S===rr){if(C.tag===7){n(v,C.sibling),y=s(C,w.props.children),y.return=v,v=y;break e}}else if(C.elementType===S||typeof S=="object"&&S!==null&&S.$$typeof===Zt&&xd(S)===C.type){n(v,C.sibling),y=s(C,w.props),y.ref=Xr(v,C,w),y.return=v,v=y;break e}n(v,C);break}else t(v,C);C=C.sibling}w.type===rr?(y=$n(w.props.children,v.mode,b,w.key),y.return=v,v=y):(b=Ii(w.type,w.key,w.props,null,v.mode,b),b.ref=Xr(v,y,w),b.return=v,v=b)}return o(v);case nr:e:{for(C=w.key;y!==null;){if(y.key===C)if(y.tag===4&&y.stateNode.containerInfo===w.containerInfo&&y.stateNode.implementation===w.implementation){n(v,y.sibling),y=s(y,w.children||[]),y.return=v,v=y;break e}else{n(v,y);break}else t(v,y);y=y.sibling}y=Ta(w,v.mode,b),y.return=v,v=y}return o(v);case Zt:return C=w._init,x(v,y,C(w._payload),b)}if(ss(w))return p(v,y,w,b);if(Hr(w))return g(v,y,w,b);gi(v,w)}return typeof w=="string"&&w!==""||typeof w=="number"?(w=""+w,y!==null&&y.tag===6?(n(v,y.sibling),y=s(y,w),y.return=v,v=y):(n(v,y),y=Ea(w,v.mode,b),y.return=v,v=y),o(v)):n(v,y)}return x}var Nr=Xp(!0),Qp=Xp(!1),no=kn(null),ro=null,dr=null,Du=null;function Ru(){Du=dr=ro=null}function Vu(e){var t=no.current;ie(no),e._currentValue=t}function Pl(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Sr(e,t){ro=e,Du=dr=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&t&&(Ue=!0),e.firstContext=null)}function ut(e){var t=e._currentValue;if(Du!==e)if(e={context:e,memoizedValue:t,next:null},dr===null){if(ro===null)throw Error(M(308));dr=e,ro.dependencies={lanes:0,firstContext:e}}else dr=dr.next=e;return t}var Fn=null;function Fu(e){Fn===null?Fn=[e]:Fn.push(e)}function Zp(e,t,n,r){var s=t.interleaved;return s===null?(n.next=n,Fu(t)):(n.next=s.next,s.next=n),t.interleaved=n,Bt(e,r)}function Bt(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var Jt=!1;function Iu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Jp(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Ft(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function fn(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var s=r.pending;return s===null?t.next=t:(t.next=s.next,s.next=t),r.pending=t,Bt(e,n)}return s=r.interleaved,s===null?(t.next=t,Fu(r)):(t.next=s.next,s.next=t),r.interleaved=t,Bt(e,n)}function Ai(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,ku(e,n)}}function wd(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var s=null,i=null;if(n=n.firstBaseUpdate,n!==null){do{var o={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};i===null?s=i=o:i=i.next=o,n=n.next}while(n!==null);i===null?s=i=t:i=i.next=t}else s=i=t;n={baseState:r.baseState,firstBaseUpdate:s,lastBaseUpdate:i,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function so(e,t,n,r){var s=e.updateQueue;Jt=!1;var i=s.firstBaseUpdate,o=s.lastBaseUpdate,a=s.shared.pending;if(a!==null){s.shared.pending=null;var l=a,c=l.next;l.next=null,o===null?i=c:o.next=c,o=l;var d=e.alternate;d!==null&&(d=d.updateQueue,a=d.lastBaseUpdate,a!==o&&(a===null?d.firstBaseUpdate=c:a.next=c,d.lastBaseUpdate=l))}if(i!==null){var f=s.baseState;o=0,d=c=l=null,a=i;do{var u=a.lane,h=a.eventTime;if((r&u)===u){d!==null&&(d=d.next={eventTime:h,lane:0,tag:a.tag,payload:a.payload,callback:a.callback,next:null});e:{var p=e,g=a;switch(u=t,h=n,g.tag){case 1:if(p=g.payload,typeof p=="function"){f=p.call(h,f,u);break e}f=p;break e;case 3:p.flags=p.flags&-65537|128;case 0:if(p=g.payload,u=typeof p=="function"?p.call(h,f,u):p,u==null)break e;f=fe({},f,u);break e;case 2:Jt=!0}}a.callback!==null&&a.lane!==0&&(e.flags|=64,u=s.effects,u===null?s.effects=[a]:u.push(a))}else h={eventTime:h,lane:u,tag:a.tag,payload:a.payload,callback:a.callback,next:null},d===null?(c=d=h,l=f):d=d.next=h,o|=u;if(a=a.next,a===null){if(a=s.shared.pending,a===null)break;u=a,a=u.next,u.next=null,s.lastBaseUpdate=u,s.shared.pending=null}}while(!0);if(d===null&&(l=f),s.baseState=l,s.firstBaseUpdate=c,s.lastBaseUpdate=d,t=s.shared.interleaved,t!==null){s=t;do o|=s.lane,s=s.next;while(s!==t)}else i===null&&(s.shared.lanes=0);qn|=o,e.lanes=o,e.memoizedState=f}}function bd(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=Sa.transition;Sa.transition={};try{e(!1),t()}finally{Z=n,Sa.transition=r}}function gm(){return ct().memoizedState}function Z1(e,t,n){var r=pn(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},ym(e))vm(t,n);else if(n=Zp(e,t,n,r),n!==null){var s=ze();yt(n,e,r,s),xm(n,t,r)}}function J1(e,t,n){var r=pn(e),s={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(ym(e))vm(t,s);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var o=t.lastRenderedState,a=i(o,n);if(s.hasEagerState=!0,s.eagerState=a,xt(a,o)){var l=t.interleaved;l===null?(s.next=s,Fu(t)):(s.next=l.next,l.next=s),t.interleaved=s;return}}catch{}finally{}n=Zp(e,t,s,r),n!==null&&(s=ze(),yt(n,e,r,s),xm(n,t,r))}}function ym(e){var t=e.alternate;return e===de||t!==null&&t===de}function vm(e,t){hs=oo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function xm(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,ku(e,n)}}var ao={readContext:ut,useCallback:Ae,useContext:Ae,useEffect:Ae,useImperativeHandle:Ae,useInsertionEffect:Ae,useLayoutEffect:Ae,useMemo:Ae,useReducer:Ae,useRef:Ae,useState:Ae,useDebugValue:Ae,useDeferredValue:Ae,useTransition:Ae,useMutableSource:Ae,useSyncExternalStore:Ae,useId:Ae,unstable_isNewReconciler:!1},ev={readContext:ut,useCallback:function(e,t){return St().memoizedState=[e,t===void 0?null:t],e},useContext:ut,useEffect:kd,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,Di(4194308,4,dm.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Di(4194308,4,e,t)},useInsertionEffect:function(e,t){return Di(4,2,e,t)},useMemo:function(e,t){var n=St();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=St();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=Z1.bind(null,de,e),[r.memoizedState,e]},useRef:function(e){var t=St();return e={current:e},t.memoizedState=e},useState:Sd,useDebugValue:qu,useDeferredValue:function(e){return St().memoizedState=e},useTransition:function(){var e=Sd(!1),t=e[0];return e=Q1.bind(null,e[1]),St().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=de,s=St();if(le){if(n===void 0)throw Error(M(407));n=n()}else{if(n=t(),Ee===null)throw Error(M(349));Hn&30||rm(r,t,n)}s.memoizedState=n;var i={value:n,getSnapshot:t};return s.queue=i,kd(im.bind(null,r,i,e),[e]),r.flags|=2048,Is(9,sm.bind(null,r,i,n,t),void 0,null),n},useId:function(){var e=St(),t=Ee.identifierPrefix;if(le){var n=Rt,r=Dt;n=(r&~(1<<32-gt(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=Vs++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=o.createElement(n,{is:r.is}):(e=o.createElement(n),n==="select"&&(o=e,r.multiple?o.multiple=!0:r.size&&(o.size=r.size))):e=o.createElementNS(e,n),e[kt]=t,e[Ls]=r,Nm(e,t,!1,!1),t.stateNode=e;e:{switch(o=al(n,r),n){case"dialog":re("cancel",e),re("close",e),s=r;break;case"iframe":case"object":case"embed":re("load",e),s=r;break;case"video":case"audio":for(s=0;sAr&&(t.flags|=128,r=!0,Qr(i,!1),t.lanes=4194304)}else{if(!r)if(e=io(o),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),Qr(i,!0),i.tail===null&&i.tailMode==="hidden"&&!o.alternate&&!le)return Le(t),null}else 2*ge()-i.renderingStartTime>Ar&&n!==1073741824&&(t.flags|=128,r=!0,Qr(i,!1),t.lanes=4194304);i.isBackwards?(o.sibling=t.child,t.child=o):(n=i.last,n!==null?n.sibling=o:t.child=o,i.last=o)}return i.tail!==null?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=ge(),t.sibling=null,n=ue.current,J(ue,r?n&1|2:n&1),t):(Le(t),null);case 22:case 23:return Zu(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&t.mode&1?Ye&1073741824&&(Le(t),t.subtreeFlags&6&&(t.flags|=8192)):Le(t),null;case 24:return null;case 25:return null}throw Error(M(156,t.tag))}function lv(e,t){switch(Au(t),t.tag){case 1:return He(t.type)&&Zi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Mr(),ie(We),ie(Ve),$u(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Ou(t),null;case 13:if(ie(ue),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(M(340));Tr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ie(ue),null;case 4:return Mr(),null;case 10:return Vu(t.type._context),null;case 22:case 23:return Zu(),null;case 24:return null;default:return null}}var vi=!1,Re=!1,uv=typeof WeakSet=="function"?WeakSet:Set,I=null;function fr(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){pe(e,t,r)}else n.current=null}function Dl(e,t,n){try{n()}catch(r){pe(e,t,r)}}var Dd=!1;function cv(e,t){if(yl=Yi,e=Vp(),Mu(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var s=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var o=0,a=-1,l=-1,c=0,d=0,f=e,u=null;t:for(;;){for(var h;f!==n||s!==0&&f.nodeType!==3||(a=o+s),f!==i||r!==0&&f.nodeType!==3||(l=o+r),f.nodeType===3&&(o+=f.nodeValue.length),(h=f.firstChild)!==null;)u=f,f=h;for(;;){if(f===e)break t;if(u===n&&++c===s&&(a=o),u===i&&++d===r&&(l=o),(h=f.nextSibling)!==null)break;f=u,u=f.parentNode}f=h}n=a===-1||l===-1?null:{start:a,end:l}}else n=null}n=n||{start:0,end:0}}else n=null;for(vl={focusedElem:e,selectionRange:n},Yi=!1,I=t;I!==null;)if(t=I,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,I=e;else for(;I!==null;){t=I;try{var p=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(p!==null){var g=p.memoizedProps,x=p.memoizedState,v=t.stateNode,y=v.getSnapshotBeforeUpdate(t.elementType===t.type?g:ft(t.type,g),x);v.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var w=t.stateNode.containerInfo;w.nodeType===1?w.textContent="":w.nodeType===9&&w.documentElement&&w.removeChild(w.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(M(163))}}catch(b){pe(t,t.return,b)}if(e=t.sibling,e!==null){e.return=t.return,I=e;break}I=t.return}return p=Dd,Dd=!1,p}function ps(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var s=r=r.next;do{if((s.tag&e)===e){var i=s.destroy;s.destroy=void 0,i!==void 0&&Dl(t,n,i)}s=s.next}while(s!==r)}}function Vo(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function Rl(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function Am(e){var t=e.alternate;t!==null&&(e.alternate=null,Am(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[kt],delete t[Ls],delete t[bl],delete t[q1],delete t[G1])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Lm(e){return e.tag===5||e.tag===3||e.tag===4}function Rd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Lm(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Vl(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Qi));else if(r!==4&&(e=e.child,e!==null))for(Vl(e,t,n),e=e.sibling;e!==null;)Vl(e,t,n),e=e.sibling}function Fl(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(Fl(e,t,n),e=e.sibling;e!==null;)Fl(e,t,n),e=e.sibling}var Ne=null,ht=!1;function Yt(e,t,n){for(n=n.child;n!==null;)Dm(e,t,n),n=n.sibling}function Dm(e,t,n){if(jt&&typeof jt.onCommitFiberUnmount=="function")try{jt.onCommitFiberUnmount(To,n)}catch{}switch(n.tag){case 5:Re||fr(n,t);case 6:var r=Ne,s=ht;Ne=null,Yt(e,t,n),Ne=r,ht=s,Ne!==null&&(ht?(e=Ne,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):Ne.removeChild(n.stateNode));break;case 18:Ne!==null&&(ht?(e=Ne,n=n.stateNode,e.nodeType===8?xa(e.parentNode,n):e.nodeType===1&&xa(e,n),Ts(e)):xa(Ne,n.stateNode));break;case 4:r=Ne,s=ht,Ne=n.stateNode.containerInfo,ht=!0,Yt(e,t,n),Ne=r,ht=s;break;case 0:case 11:case 14:case 15:if(!Re&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){s=r=r.next;do{var i=s,o=i.destroy;i=i.tag,o!==void 0&&(i&2||i&4)&&Dl(n,t,o),s=s.next}while(s!==r)}Yt(e,t,n);break;case 1:if(!Re&&(fr(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(a){pe(n,t,a)}Yt(e,t,n);break;case 21:Yt(e,t,n);break;case 22:n.mode&1?(Re=(r=Re)||n.memoizedState!==null,Yt(e,t,n),Re=r):Yt(e,t,n);break;default:Yt(e,t,n)}}function Vd(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new uv),t.forEach(function(r){var s=xv.bind(null,e,r);n.has(r)||(n.add(r),r.then(s,s))})}}function dt(e,t){var n=t.deletions;if(n!==null)for(var r=0;rs&&(s=o),r&=~i}if(r=s,r=ge()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*fv(r/1960))-r,10e?16:e,on===null)var r=!1;else{if(e=on,on=null,co=0,K&6)throw Error(M(331));var s=K;for(K|=4,I=e.current;I!==null;){var i=I,o=i.child;if(I.flags&16){var a=i.deletions;if(a!==null){for(var l=0;lge()-Xu?On(e,0):Ku|=n),qe(e,t)}function Bm(e,t){t===0&&(e.mode&1?(t=ui,ui<<=1,!(ui&130023424)&&(ui=4194304)):t=1);var n=ze();e=Bt(e,t),e!==null&&(Ys(e,t,n),qe(e,n))}function vv(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Bm(e,n)}function xv(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,s=e.memoizedState;s!==null&&(n=s.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(M(314))}r!==null&&r.delete(t),Bm(e,n)}var Um;Um=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||We.current)Ue=!0;else{if(!(e.lanes&n)&&!(t.flags&128))return Ue=!1,ov(e,t,n);Ue=!!(e.flags&131072)}else Ue=!1,le&&t.flags&1048576&&Gp(t,to,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Ri(e,t),e=t.pendingProps;var s=Er(t,Ve.current);Sr(t,n),s=Uu(null,t,r,e,s,n);var i=Wu();return t.flags|=1,typeof s=="object"&&s!==null&&typeof s.render=="function"&&s.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,He(r)?(i=!0,Ji(t)):i=!1,t.memoizedState=s.state!==null&&s.state!==void 0?s.state:null,Iu(t),s.updater=Ro,t.stateNode=s,s._reactInternals=t,El(t,r,e,n),t=Ml(null,t,r,!0,i,n)):(t.tag=0,le&&i&&_u(t),Ie(null,t,s,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Ri(e,t),e=t.pendingProps,s=r._init,r=s(r._payload),t.type=r,s=t.tag=bv(r),e=ft(r,e),s){case 0:t=Nl(null,t,r,e,n);break e;case 1:t=_d(null,t,r,e,n);break e;case 11:t=Nd(null,t,r,e,n);break e;case 14:t=Md(null,t,r,ft(r.type,e),n);break e}throw Error(M(306,r,""))}return t;case 0:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:ft(r,s),Nl(e,t,r,s,n);case 1:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:ft(r,s),_d(e,t,r,s,n);case 3:e:{if(jm(t),e===null)throw Error(M(387));r=t.pendingProps,i=t.memoizedState,s=i.element,Jp(e,t),so(t,r,null,n);var o=t.memoizedState;if(r=o.element,i.isDehydrated)if(i={element:r,isDehydrated:!1,cache:o.cache,pendingSuspenseBoundaries:o.pendingSuspenseBoundaries,transitions:o.transitions},t.updateQueue.baseState=i,t.memoizedState=i,t.flags&256){s=_r(Error(M(423)),t),t=Ad(e,t,r,n,s);break e}else if(r!==s){s=_r(Error(M(424)),t),t=Ad(e,t,r,n,s);break e}else for(Ke=dn(t.stateNode.containerInfo.firstChild),Qe=t,le=!0,pt=null,n=Qp(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Tr(),r===s){t=Ut(e,t,n);break e}Ie(e,t,r,n)}t=t.child}return t;case 5:return em(t),e===null&&Cl(t),r=t.type,s=t.pendingProps,i=e!==null?e.memoizedProps:null,o=s.children,xl(r,s)?o=null:i!==null&&xl(r,i)&&(t.flags|=32),Pm(e,t),Ie(e,t,o,n),t.child;case 6:return e===null&&Cl(t),null;case 13:return Em(e,t,n);case 4:return zu(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Nr(t,null,r,n):Ie(e,t,r,n),t.child;case 11:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:ft(r,s),Nd(e,t,r,s,n);case 7:return Ie(e,t,t.pendingProps,n),t.child;case 8:return Ie(e,t,t.pendingProps.children,n),t.child;case 12:return Ie(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,s=t.pendingProps,i=t.memoizedProps,o=s.value,J(no,r._currentValue),r._currentValue=o,i!==null)if(xt(i.value,o)){if(i.children===s.children&&!We.current){t=Ut(e,t,n);break e}}else for(i=t.child,i!==null&&(i.return=t);i!==null;){var a=i.dependencies;if(a!==null){o=i.child;for(var l=a.firstContext;l!==null;){if(l.context===r){if(i.tag===1){l=Ft(-1,n&-n),l.tag=2;var c=i.updateQueue;if(c!==null){c=c.shared;var d=c.pending;d===null?l.next=l:(l.next=d.next,d.next=l),c.pending=l}}i.lanes|=n,l=i.alternate,l!==null&&(l.lanes|=n),Pl(i.return,n,t),a.lanes|=n;break}l=l.next}}else if(i.tag===10)o=i.type===t.type?null:i.child;else if(i.tag===18){if(o=i.return,o===null)throw Error(M(341));o.lanes|=n,a=o.alternate,a!==null&&(a.lanes|=n),Pl(o,n,t),o=i.sibling}else o=i.child;if(o!==null)o.return=i;else for(o=i;o!==null;){if(o===t){o=null;break}if(i=o.sibling,i!==null){i.return=o.return,o=i;break}o=o.return}i=o}Ie(e,t,s.children,n),t=t.child}return t;case 9:return s=t.type,r=t.pendingProps.children,Sr(t,n),s=ut(s),r=r(s),t.flags|=1,Ie(e,t,r,n),t.child;case 14:return r=t.type,s=ft(r,t.pendingProps),s=ft(r.type,s),Md(e,t,r,s,n);case 15:return km(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:ft(r,s),Ri(e,t),t.tag=1,He(r)?(e=!0,Ji(t)):e=!1,Sr(t,n),wm(t,r,s),El(t,r,s,n),Ml(null,t,r,!0,e,n);case 19:return Tm(e,t,n);case 22:return Cm(e,t,n)}throw Error(M(156,t.tag))};function Wm(e,t){return yp(e,t)}function wv(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function at(e,t,n,r){return new wv(e,t,n,r)}function ec(e){return e=e.prototype,!(!e||!e.isReactComponent)}function bv(e){if(typeof e=="function")return ec(e)?1:0;if(e!=null){if(e=e.$$typeof,e===xu)return 11;if(e===wu)return 14}return 2}function mn(e,t){var n=e.alternate;return n===null?(n=at(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ii(e,t,n,r,s,i){var o=2;if(r=e,typeof e=="function")ec(e)&&(o=1);else if(typeof e=="string")o=5;else e:switch(e){case rr:return $n(n.children,s,i,t);case vu:o=8,s|=8;break;case Qa:return e=at(12,n,t,s|2),e.elementType=Qa,e.lanes=i,e;case Za:return e=at(13,n,t,s),e.elementType=Za,e.lanes=i,e;case Ja:return e=at(19,n,t,s),e.elementType=Ja,e.lanes=i,e;case ep:return Io(n,s,i,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case Zh:o=10;break e;case Jh:o=9;break e;case xu:o=11;break e;case wu:o=14;break e;case Zt:o=16,r=null;break e}throw Error(M(130,e==null?e:typeof e,""))}return t=at(o,n,t,s),t.elementType=e,t.type=r,t.lanes=i,t}function $n(e,t,n,r){return e=at(7,e,r,t),e.lanes=n,e}function Io(e,t,n,r){return e=at(22,e,r,t),e.elementType=ep,e.lanes=n,e.stateNode={isHidden:!1},e}function Ea(e,t,n){return e=at(6,e,null,t),e.lanes=n,e}function Ta(e,t,n){return t=at(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Sv(e,t,n,r,s){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=la(0),this.expirationTimes=la(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=la(0),this.identifierPrefix=r,this.onRecoverableError=s,this.mutableSourceEagerHydrationData=null}function tc(e,t,n,r,s,i,o,a,l){return e=new Sv(e,t,n,a,l),t===1?(t=1,i===!0&&(t|=8)):t=0,i=at(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Iu(i),e}function kv(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(Ym)}catch(e){console.error(e)}}Ym(),Yh.exports=et;var Tv=Yh.exports,Wd=Tv;Ka.createRoot=Wd.createRoot,Ka.hydrateRoot=Wd.hydrateRoot;/** - * @remix-run/router v1.23.0 - * - * Copyright (c) Remix Software Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE.md file in the root directory of this source tree. - * - * @license MIT - */function Os(){return Os=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u")throw new Error(t)}function Km(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function Mv(){return Math.random().toString(36).substr(2,8)}function qd(e,t){return{usr:e.state,key:e.key,idx:t}}function Bl(e,t,n,r){return n===void 0&&(n=null),Os({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?Or(t):t,{state:n,key:t&&t.key||r||Mv()})}function po(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&n!=="?"&&(t+=n.charAt(0)==="?"?n:"?"+n),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function Or(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function _v(e,t,n,r){r===void 0&&(r={});let{window:s=document.defaultView,v5Compat:i=!1}=r,o=s.history,a=an.Pop,l=null,c=d();c==null&&(c=0,o.replaceState(Os({},o.state,{idx:c}),""));function d(){return(o.state||{idx:null}).idx}function f(){a=an.Pop;let x=d(),v=x==null?null:x-c;c=x,l&&l({action:a,location:g.location,delta:v})}function u(x,v){a=an.Push;let y=Bl(g.location,x,v);c=d()+1;let w=qd(y,c),b=g.createHref(y);try{o.pushState(w,"",b)}catch(S){if(S instanceof DOMException&&S.name==="DataCloneError")throw S;s.location.assign(b)}i&&l&&l({action:a,location:g.location,delta:1})}function h(x,v){a=an.Replace;let y=Bl(g.location,x,v);c=d();let w=qd(y,c),b=g.createHref(y);o.replaceState(w,"",b),i&&l&&l({action:a,location:g.location,delta:0})}function p(x){let v=s.location.origin!=="null"?s.location.origin:s.location.href,y=typeof x=="string"?x:po(x);return y=y.replace(/ $/,"%20"),ve(v,"No window.location.(origin|href) available to create URL for href: "+y),new URL(y,v)}let g={get action(){return a},get location(){return e(s,o)},listen(x){if(l)throw new Error("A history only accepts one active listener");return s.addEventListener(Hd,f),l=x,()=>{s.removeEventListener(Hd,f),l=null}},createHref(x){return t(s,x)},createURL:p,encodeLocation(x){let v=p(x);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:u,replace:h,go(x){return o.go(x)}};return g}var Gd;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(Gd||(Gd={}));function Av(e,t,n){return n===void 0&&(n="/"),Lv(e,t,n)}function Lv(e,t,n,r){let s=typeof t=="string"?Or(t):t,i=ic(s.pathname||"/",n);if(i==null)return null;let o=Xm(e);Dv(o);let a=null;for(let l=0;a==null&&l{let l={relativePath:a===void 0?i.path||"":a,caseSensitive:i.caseSensitive===!0,childrenIndex:o,route:i};l.relativePath.startsWith("/")&&(ve(l.relativePath.startsWith(r),'Absolute route path "'+l.relativePath+'" nested under path '+('"'+r+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),l.relativePath=l.relativePath.slice(r.length));let c=gn([r,l.relativePath]),d=n.concat(l);i.children&&i.children.length>0&&(ve(i.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+c+'".')),Xm(i.children,t,d,c)),!(i.path==null&&!i.index)&&t.push({path:c,score:$v(c,i.index),routesMeta:d})};return e.forEach((i,o)=>{var a;if(i.path===""||!((a=i.path)!=null&&a.includes("?")))s(i,o);else for(let l of Qm(i.path))s(i,o,l)}),t}function Qm(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,s=n.endsWith("?"),i=n.replace(/\?$/,"");if(r.length===0)return s?[i,""]:[i];let o=Qm(r.join("/")),a=[];return a.push(...o.map(l=>l===""?i:[i,l].join("/"))),s&&a.push(...o),a.map(l=>e.startsWith("/")&&l===""?"/":l)}function Dv(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:Bv(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const Rv=/^:[\w-]+$/,Vv=3,Fv=2,Iv=1,zv=10,Ov=-2,Yd=e=>e==="*";function $v(e,t){let n=e.split("/"),r=n.length;return n.some(Yd)&&(r+=Ov),t&&(r+=Fv),n.filter(s=>!Yd(s)).reduce((s,i)=>s+(Rv.test(i)?Vv:i===""?Iv:zv),r)}function Bv(e,t){return e.length===t.length&&e.slice(0,-1).every((r,s)=>r===t[s])?e[e.length-1]-t[t.length-1]:0}function Uv(e,t,n){let{routesMeta:r}=e,s={},i="/",o=[];for(let a=0;a{let{paramName:u,isOptional:h}=d;if(u==="*"){let g=a[f]||"";o=i.slice(0,i.length-g.length).replace(/(.)\/+$/,"$1")}const p=a[f];return h&&!p?c[u]=void 0:c[u]=(p||"").replace(/%2F/g,"/"),c},{}),pathname:i,pathnameBase:o,pattern:e}}function Hv(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),Km(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let r=[],s="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,a,l)=>(r.push({paramName:a,isOptional:l!=null}),l?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),s+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?s+="\\/*$":e!==""&&e!=="/"&&(s+="(?:(?=\\/|$))"),[new RegExp(s,t?void 0:"i"),r]}function qv(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return Km(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function ic(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}function Gv(e,t){t===void 0&&(t="/");let{pathname:n,search:r="",hash:s=""}=typeof e=="string"?Or(e):e;return{pathname:n?n.startsWith("/")?n:Yv(n,t):t,search:Qv(r),hash:Zv(s)}}function Yv(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(s=>{s===".."?n.length>1&&n.pop():s!=="."&&n.push(s)}),n.length>1?n.join("/"):"/"}function Na(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(r)+"]. Please separate it out to the ")+("`to."+n+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function Kv(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function oc(e,t){let n=Kv(e);return t?n.map((r,s)=>s===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function ac(e,t,n,r){r===void 0&&(r=!1);let s;typeof e=="string"?s=Or(e):(s=Os({},e),ve(!s.pathname||!s.pathname.includes("?"),Na("?","pathname","search",s)),ve(!s.pathname||!s.pathname.includes("#"),Na("#","pathname","hash",s)),ve(!s.search||!s.search.includes("#"),Na("#","search","hash",s)));let i=e===""||s.pathname==="",o=i?"/":s.pathname,a;if(o==null)a=n;else{let f=t.length-1;if(!r&&o.startsWith("..")){let u=o.split("/");for(;u[0]==="..";)u.shift(),f-=1;s.pathname=u.join("/")}a=f>=0?t[f]:"/"}let l=Gv(s,a),c=o&&o!=="/"&&o.endsWith("/"),d=(i||o===".")&&n.endsWith("/");return!l.pathname.endsWith("/")&&(c||d)&&(l.pathname+="/"),l}const gn=e=>e.join("/").replace(/\/\/+/g,"/"),Xv=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),Qv=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,Zv=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function Jv(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const Zm=["post","put","patch","delete"];new Set(Zm);const ex=["get",...Zm];new Set(ex);/** - * React Router v6.30.1 - * - * Copyright (c) Remix Software Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE.md file in the root directory of this source tree. - * - * @license MIT - */function $s(){return $s=Object.assign?Object.assign.bind():function(e){for(var t=1;t{a.current=!0}),k.useCallback(function(c,d){if(d===void 0&&(d={}),!a.current)return;if(typeof c=="number"){r.go(c);return}let f=ac(c,JSON.parse(o),i,d.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:gn([t,f.pathname])),(d.replace?r.replace:r.push)(f,d.state,d)},[t,r,o,i,e])}function t0(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=k.useContext(Pn),{matches:s}=k.useContext(jn),{pathname:i}=En(),o=JSON.stringify(oc(s,r.v7_relativeSplatPath));return k.useMemo(()=>ac(e,JSON.parse(o),i,n==="path"),[e,o,i,n])}function sx(e,t){return ix(e,t)}function ix(e,t,n,r){$r()||ve(!1);let{navigator:s}=k.useContext(Pn),{matches:i}=k.useContext(jn),o=i[i.length-1],a=o?o.params:{};o&&o.pathname;let l=o?o.pathnameBase:"/";o&&o.route;let c=En(),d;if(t){var f;let x=typeof t=="string"?Or(t):t;l==="/"||(f=x.pathname)!=null&&f.startsWith(l)||ve(!1),d=x}else d=c;let u=d.pathname||"/",h=u;if(l!=="/"){let x=l.replace(/^\//,"").split("/");h="/"+u.replace(/^\//,"").split("/").slice(x.length).join("/")}let p=Av(e,{pathname:h}),g=cx(p&&p.map(x=>Object.assign({},x,{params:Object.assign({},a,x.params),pathname:gn([l,s.encodeLocation?s.encodeLocation(x.pathname).pathname:x.pathname]),pathnameBase:x.pathnameBase==="/"?l:gn([l,s.encodeLocation?s.encodeLocation(x.pathnameBase).pathname:x.pathnameBase])})),i,n,r);return t&&g?k.createElement(Uo.Provider,{value:{location:$s({pathname:"/",search:"",hash:"",state:null,key:"default"},d),navigationType:an.Pop}},g):g}function ox(){let e=px(),t=Jv(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,s={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return k.createElement(k.Fragment,null,k.createElement("h2",null,"Unexpected Application Error!"),k.createElement("h3",{style:{fontStyle:"italic"}},t),n?k.createElement("pre",{style:s},n):null,null)}const ax=k.createElement(ox,null);class lx extends k.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,n){return n.location!==t.location||n.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error("React Router caught the following error during render",t,n)}render(){return this.state.error!==void 0?k.createElement(jn.Provider,{value:this.props.routeContext},k.createElement(Jm.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function ux(e){let{routeContext:t,match:n,children:r}=e,s=k.useContext(lc);return s&&s.static&&s.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=n.route.id),k.createElement(jn.Provider,{value:t},r)}function cx(e,t,n,r){var s;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var i;if(!n)return null;if(n.errors)e=n.matches;else if((i=r)!=null&&i.v7_partialHydration&&t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let o=e,a=(s=n)==null?void 0:s.errors;if(a!=null){let d=o.findIndex(f=>f.route.id&&(a==null?void 0:a[f.route.id])!==void 0);d>=0||ve(!1),o=o.slice(0,Math.min(o.length,d+1))}let l=!1,c=-1;if(n&&r&&r.v7_partialHydration)for(let d=0;d=0?o=o.slice(0,c+1):o=[o[0]];break}}}return o.reduceRight((d,f,u)=>{let h,p=!1,g=null,x=null;n&&(h=a&&f.route.id?a[f.route.id]:void 0,g=f.route.errorElement||ax,l&&(c<0&&u===0?(gx("route-fallback"),p=!0,x=null):c===u&&(p=!0,x=f.route.hydrateFallbackElement||null)));let v=t.concat(o.slice(0,u+1)),y=()=>{let w;return h?w=g:p?w=x:f.route.Component?w=k.createElement(f.route.Component,null):f.route.element?w=f.route.element:w=d,k.createElement(ux,{match:f,routeContext:{outlet:d,matches:v,isDataRoute:n!=null},children:w})};return n&&(f.route.ErrorBoundary||f.route.errorElement||u===0)?k.createElement(lx,{location:n.location,revalidation:n.revalidation,component:g,error:h,children:y(),routeContext:{outlet:null,matches:v,isDataRoute:!0}}):y()},null)}var n0=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(n0||{}),r0=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(r0||{});function dx(e){let t=k.useContext(lc);return t||ve(!1),t}function fx(e){let t=k.useContext(tx);return t||ve(!1),t}function hx(e){let t=k.useContext(jn);return t||ve(!1),t}function s0(e){let t=hx(),n=t.matches[t.matches.length-1];return n.route.id||ve(!1),n.route.id}function px(){var e;let t=k.useContext(Jm),n=fx(),r=s0();return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function mx(){let{router:e}=dx(n0.UseNavigateStable),t=s0(r0.UseNavigateStable),n=k.useRef(!1);return e0(()=>{n.current=!0}),k.useCallback(function(s,i){i===void 0&&(i={}),n.current&&(typeof s=="number"?e.navigate(s):e.navigate(s,$s({fromRouteId:t},i)))},[e,t])}const Kd={};function gx(e,t,n){Kd[e]||(Kd[e]=!0)}function yx(e,t){e==null||e.v7_startTransition,e==null||e.v7_relativeSplatPath}function vx(e){let{to:t,replace:n,state:r,relative:s}=e;$r()||ve(!1);let{future:i,static:o}=k.useContext(Pn),{matches:a}=k.useContext(jn),{pathname:l}=En(),c=Wo(),d=ac(t,oc(a,i.v7_relativeSplatPath),l,s==="path"),f=JSON.stringify(d);return k.useEffect(()=>c(JSON.parse(f),{replace:n,state:r,relative:s}),[c,f,s,n,r]),null}function _t(e){ve(!1)}function xx(e){let{basename:t="/",children:n=null,location:r,navigationType:s=an.Pop,navigator:i,static:o=!1,future:a}=e;$r()&&ve(!1);let l=t.replace(/^\/*/,"/"),c=k.useMemo(()=>({basename:l,navigator:i,static:o,future:$s({v7_relativeSplatPath:!1},a)}),[l,a,i,o]);typeof r=="string"&&(r=Or(r));let{pathname:d="/",search:f="",hash:u="",state:h=null,key:p="default"}=r,g=k.useMemo(()=>{let x=ic(d,l);return x==null?null:{location:{pathname:x,search:f,hash:u,state:h,key:p},navigationType:s}},[l,d,f,u,h,p,s]);return g==null?null:k.createElement(Pn.Provider,{value:c},k.createElement(Uo.Provider,{children:n,value:g}))}function wx(e){let{children:t,location:n}=e;return sx(Ul(t),n)}new Promise(()=>{});function Ul(e,t){t===void 0&&(t=[]);let n=[];return k.Children.forEach(e,(r,s)=>{if(!k.isValidElement(r))return;let i=[...t,s];if(r.type===k.Fragment){n.push.apply(n,Ul(r.props.children,i));return}r.type!==_t&&ve(!1),!r.props.index||!r.props.children||ve(!1);let o={id:r.props.id||i.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,loader:r.props.loader,action:r.props.action,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(o.children=Ul(r.props.children,i)),n.push(o)}),n}/** - * React Router DOM v6.30.1 - * - * Copyright (c) Remix Software Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE.md file in the root directory of this source tree. - * - * @license MIT - */function Wl(){return Wl=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&(n[s]=e[s]);return n}function Sx(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function kx(e,t){return e.button===0&&(!t||t==="_self")&&!Sx(e)}function Hl(e){return e===void 0&&(e=""),new URLSearchParams(typeof e=="string"||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(s=>[n,s]):[[n,r]])},[]))}function Cx(e,t){let n=Hl(e);return t&&t.forEach((r,s)=>{n.has(s)||t.getAll(s).forEach(i=>{n.append(s,i)})}),n}const Px=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],jx="6";try{window.__reactRouterVersion=jx}catch{}const Ex="startTransition",Xd=yy[Ex];function Tx(e){let{basename:t,children:n,future:r,window:s}=e,i=k.useRef();i.current==null&&(i.current=Nv({window:s,v5Compat:!0}));let o=i.current,[a,l]=k.useState({action:o.action,location:o.location}),{v7_startTransition:c}=r||{},d=k.useCallback(f=>{c&&Xd?Xd(()=>l(f)):l(f)},[l,c]);return k.useLayoutEffect(()=>o.listen(d),[o,d]),k.useEffect(()=>yx(r),[r]),k.createElement(xx,{basename:t,children:n,location:a.location,navigationType:a.action,navigator:o,future:r})}const Nx=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",Mx=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,zi=k.forwardRef(function(t,n){let{onClick:r,relative:s,reloadDocument:i,replace:o,state:a,target:l,to:c,preventScrollReset:d,viewTransition:f}=t,u=bx(t,Px),{basename:h}=k.useContext(Pn),p,g=!1;if(typeof c=="string"&&Mx.test(c)&&(p=c,Nx))try{let w=new URL(window.location.href),b=c.startsWith("//")?new URL(w.protocol+c):new URL(c),S=ic(b.pathname,h);b.origin===w.origin&&S!=null?c=S+b.search+b.hash:g=!0}catch{}let x=nx(c,{relative:s}),v=_x(c,{replace:o,state:a,target:l,preventScrollReset:d,relative:s,viewTransition:f});function y(w){r&&r(w),w.defaultPrevented||v(w)}return k.createElement("a",Wl({},u,{href:p||x,onClick:g||i?r:y,ref:n,target:l}))});var Qd;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(Qd||(Qd={}));var Zd;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Zd||(Zd={}));function _x(e,t){let{target:n,replace:r,state:s,preventScrollReset:i,relative:o,viewTransition:a}=t===void 0?{}:t,l=Wo(),c=En(),d=t0(e,{relative:o});return k.useCallback(f=>{if(kx(f,n)){f.preventDefault();let u=r!==void 0?r:po(c)===po(d);l(e,{replace:u,state:s,preventScrollReset:i,relative:o,viewTransition:a})}},[c,l,d,r,s,n,e,i,o,a])}function Ax(e){let t=k.useRef(Hl(e)),n=k.useRef(!1),r=En(),s=k.useMemo(()=>Cx(r.search,n.current?null:t.current),[r.search]),i=Wo(),o=k.useCallback((a,l)=>{const c=Hl(typeof a=="function"?a(s):a);n.current=!0,i("?"+c,l)},[i,s]);return[s,o]}let Lx={data:""},Dx=e=>{if(typeof window=="object"){let t=(e?e.querySelector("#_goober"):window._goober)||Object.assign(document.createElement("style"),{innerHTML:" ",id:"_goober"});return t.nonce=window.__nonce__,t.parentNode||(e||document.head).appendChild(t),t.firstChild}return e||Lx},Rx=/(?:([\u0080-\uFFFF\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\s*)/g,Vx=/\/\*[^]*?\*\/| +/g,Jd=/\n+/g,rn=(e,t)=>{let n="",r="",s="";for(let i in e){let o=e[i];i[0]=="@"?i[1]=="i"?n=i+" "+o+";":r+=i[1]=="f"?rn(o,i):i+"{"+rn(o,i[1]=="k"?"":t)+"}":typeof o=="object"?r+=rn(o,t?t.replace(/([^,])+/g,a=>i.replace(/([^,]*:\S+\([^)]*\))|([^,])+/g,l=>/&/.test(l)?l.replace(/&/g,a):a?a+" "+l:l)):i):o!=null&&(i=/^--/.test(i)?i:i.replace(/[A-Z]/g,"-$&").toLowerCase(),s+=rn.p?rn.p(i,o):i+":"+o+";")}return n+(t&&s?t+"{"+s+"}":s)+r},Nt={},i0=e=>{if(typeof e=="object"){let t="";for(let n in e)t+=n+i0(e[n]);return t}return e},Fx=(e,t,n,r,s)=>{let i=i0(e),o=Nt[i]||(Nt[i]=(l=>{let c=0,d=11;for(;c>>0;return"go"+d})(i));if(!Nt[o]){let l=i!==e?e:(c=>{let d,f,u=[{}];for(;d=Rx.exec(c.replace(Vx,""));)d[4]?u.shift():d[3]?(f=d[3].replace(Jd," ").trim(),u.unshift(u[0][f]=u[0][f]||{})):u[0][d[1]]=d[2].replace(Jd," ").trim();return u[0]})(e);Nt[o]=rn(s?{["@keyframes "+o]:l}:l,n?"":"."+o)}let a=n&&Nt.g?Nt.g:null;return n&&(Nt.g=Nt[o]),((l,c,d,f)=>{f?c.data=c.data.replace(f,l):c.data.indexOf(l)===-1&&(c.data=d?l+c.data:c.data+l)})(Nt[o],t,r,a),o},Ix=(e,t,n)=>e.reduce((r,s,i)=>{let o=t[i];if(o&&o.call){let a=o(n),l=a&&a.props&&a.props.className||/^go/.test(a)&&a;o=l?"."+l:a&&typeof a=="object"?a.props?"":rn(a,""):a===!1?"":a}return r+s+(o??"")},"");function Ho(e){let t=this||{},n=e.call?e(t.p):e;return Fx(n.unshift?n.raw?Ix(n,[].slice.call(arguments,1),t.p):n.reduce((r,s)=>Object.assign(r,s&&s.call?s(t.p):s),{}):n,Dx(t.target),t.g,t.o,t.k)}let o0,ql,Gl;Ho.bind({g:1});let Wt=Ho.bind({k:1});function zx(e,t,n,r){rn.p=t,o0=e,ql=n,Gl=r}function Tn(e,t){let n=this||{};return function(){let r=arguments;function s(i,o){let a=Object.assign({},i),l=a.className||s.className;n.p=Object.assign({theme:ql&&ql()},a),n.o=/ *go\d+/.test(l),a.className=Ho.apply(n,r)+(l?" "+l:"");let c=e;return e[0]&&(c=a.as||e,delete a.as),Gl&&c[0]&&Gl(a),o0(c,a)}return s}}var Ox=e=>typeof e=="function",mo=(e,t)=>Ox(e)?e(t):e,$x=(()=>{let e=0;return()=>(++e).toString()})(),a0=(()=>{let e;return()=>{if(e===void 0&&typeof window<"u"){let t=matchMedia("(prefers-reduced-motion: reduce)");e=!t||t.matches}return e}})(),Bx=20,uc="default",l0=(e,t)=>{let{toastLimit:n}=e.settings;switch(t.type){case 0:return{...e,toasts:[t.toast,...e.toasts].slice(0,n)};case 1:return{...e,toasts:e.toasts.map(o=>o.id===t.toast.id?{...o,...t.toast}:o)};case 2:let{toast:r}=t;return l0(e,{type:e.toasts.find(o=>o.id===r.id)?1:0,toast:r});case 3:let{toastId:s}=t;return{...e,toasts:e.toasts.map(o=>o.id===s||s===void 0?{...o,dismissed:!0,visible:!1}:o)};case 4:return t.toastId===void 0?{...e,toasts:[]}:{...e,toasts:e.toasts.filter(o=>o.id!==t.toastId)};case 5:return{...e,pausedAt:t.time};case 6:let i=t.time-(e.pausedAt||0);return{...e,pausedAt:void 0,toasts:e.toasts.map(o=>({...o,pauseDuration:o.pauseDuration+i}))}}},Oi=[],u0={toasts:[],pausedAt:void 0,settings:{toastLimit:Bx}},Ct={},c0=(e,t=uc)=>{Ct[t]=l0(Ct[t]||u0,e),Oi.forEach(([n,r])=>{n===t&&r(Ct[t])})},d0=e=>Object.keys(Ct).forEach(t=>c0(e,t)),Ux=e=>Object.keys(Ct).find(t=>Ct[t].toasts.some(n=>n.id===e)),qo=(e=uc)=>t=>{c0(t,e)},Wx={blank:4e3,error:4e3,success:2e3,loading:1/0,custom:4e3},Hx=(e={},t=uc)=>{let[n,r]=k.useState(Ct[t]||u0),s=k.useRef(Ct[t]);k.useEffect(()=>(s.current!==Ct[t]&&r(Ct[t]),Oi.push([t,r]),()=>{let o=Oi.findIndex(([a])=>a===t);o>-1&&Oi.splice(o,1)}),[t]);let i=n.toasts.map(o=>{var a,l,c;return{...e,...e[o.type],...o,removeDelay:o.removeDelay||((a=e[o.type])==null?void 0:a.removeDelay)||(e==null?void 0:e.removeDelay),duration:o.duration||((l=e[o.type])==null?void 0:l.duration)||(e==null?void 0:e.duration)||Wx[o.type],style:{...e.style,...(c=e[o.type])==null?void 0:c.style,...o.style}}});return{...n,toasts:i}},qx=(e,t="blank",n)=>({createdAt:Date.now(),visible:!0,dismissed:!1,type:t,ariaProps:{role:"status","aria-live":"polite"},message:e,pauseDuration:0,...n,id:(n==null?void 0:n.id)||$x()}),Zs=e=>(t,n)=>{let r=qx(t,e,n);return qo(r.toasterId||Ux(r.id))({type:2,toast:r}),r.id},ke=(e,t)=>Zs("blank")(e,t);ke.error=Zs("error");ke.success=Zs("success");ke.loading=Zs("loading");ke.custom=Zs("custom");ke.dismiss=(e,t)=>{let n={type:3,toastId:e};t?qo(t)(n):d0(n)};ke.dismissAll=e=>ke.dismiss(void 0,e);ke.remove=(e,t)=>{let n={type:4,toastId:e};t?qo(t)(n):d0(n)};ke.removeAll=e=>ke.remove(void 0,e);ke.promise=(e,t,n)=>{let r=ke.loading(t.loading,{...n,...n==null?void 0:n.loading});return typeof e=="function"&&(e=e()),e.then(s=>{let i=t.success?mo(t.success,s):void 0;return i?ke.success(i,{id:r,...n,...n==null?void 0:n.success}):ke.dismiss(r),s}).catch(s=>{let i=t.error?mo(t.error,s):void 0;i?ke.error(i,{id:r,...n,...n==null?void 0:n.error}):ke.dismiss(r)}),e};var Gx=1e3,Yx=(e,t="default")=>{let{toasts:n,pausedAt:r}=Hx(e,t),s=k.useRef(new Map).current,i=k.useCallback((f,u=Gx)=>{if(s.has(f))return;let h=setTimeout(()=>{s.delete(f),o({type:4,toastId:f})},u);s.set(f,h)},[]);k.useEffect(()=>{if(r)return;let f=Date.now(),u=n.map(h=>{if(h.duration===1/0)return;let p=(h.duration||0)+h.pauseDuration-(f-h.createdAt);if(p<0){h.visible&&ke.dismiss(h.id);return}return setTimeout(()=>ke.dismiss(h.id,t),p)});return()=>{u.forEach(h=>h&&clearTimeout(h))}},[n,r,t]);let o=k.useCallback(qo(t),[t]),a=k.useCallback(()=>{o({type:5,time:Date.now()})},[o]),l=k.useCallback((f,u)=>{o({type:1,toast:{id:f,height:u}})},[o]),c=k.useCallback(()=>{r&&o({type:6,time:Date.now()})},[r,o]),d=k.useCallback((f,u)=>{let{reverseOrder:h=!1,gutter:p=8,defaultPosition:g}=u||{},x=n.filter(w=>(w.position||g)===(f.position||g)&&w.height),v=x.findIndex(w=>w.id===f.id),y=x.filter((w,b)=>bw.visible).slice(...h?[y+1]:[0,y]).reduce((w,b)=>w+(b.height||0)+p,0)},[n]);return k.useEffect(()=>{n.forEach(f=>{if(f.dismissed)i(f.id,f.removeDelay);else{let u=s.get(f.id);u&&(clearTimeout(u),s.delete(f.id))}})},[n,i]),{toasts:n,handlers:{updateHeight:l,startPause:a,endPause:c,calculateOffset:d}}},Kx=Wt` -from { - transform: scale(0) rotate(45deg); - opacity: 0; -} -to { - transform: scale(1) rotate(45deg); - opacity: 1; -}`,Xx=Wt` -from { - transform: scale(0); - opacity: 0; -} -to { - transform: scale(1); - opacity: 1; -}`,Qx=Wt` -from { - transform: scale(0) rotate(90deg); - opacity: 0; -} -to { - transform: scale(1) rotate(90deg); - opacity: 1; -}`,Zx=Tn("div")` - width: 20px; - opacity: 0; - height: 20px; - border-radius: 10px; - background: ${e=>e.primary||"#ff4b4b"}; - position: relative; - transform: rotate(45deg); - - animation: ${Kx} 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) - forwards; - animation-delay: 100ms; - - &:after, - &:before { - content: ''; - animation: ${Xx} 0.15s ease-out forwards; - animation-delay: 150ms; - position: absolute; - border-radius: 3px; - opacity: 0; - background: ${e=>e.secondary||"#fff"}; - bottom: 9px; - left: 4px; - height: 2px; - width: 12px; - } - - &:before { - animation: ${Qx} 0.15s ease-out forwards; - animation-delay: 180ms; - transform: rotate(90deg); - } -`,Jx=Wt` - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -`,e2=Tn("div")` - width: 12px; - height: 12px; - box-sizing: border-box; - border: 2px solid; - border-radius: 100%; - border-color: ${e=>e.secondary||"#e0e0e0"}; - border-right-color: ${e=>e.primary||"#616161"}; - animation: ${Jx} 1s linear infinite; -`,t2=Wt` -from { - transform: scale(0) rotate(45deg); - opacity: 0; -} -to { - transform: scale(1) rotate(45deg); - opacity: 1; -}`,n2=Wt` -0% { - height: 0; - width: 0; - opacity: 0; -} -40% { - height: 0; - width: 6px; - opacity: 1; -} -100% { - opacity: 1; - height: 10px; -}`,r2=Tn("div")` - width: 20px; - opacity: 0; - height: 20px; - border-radius: 10px; - background: ${e=>e.primary||"#61d345"}; - position: relative; - transform: rotate(45deg); - - animation: ${t2} 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) - forwards; - animation-delay: 100ms; - &:after { - content: ''; - box-sizing: border-box; - animation: ${n2} 0.2s ease-out forwards; - opacity: 0; - animation-delay: 200ms; - position: absolute; - border-right: 2px solid; - border-bottom: 2px solid; - border-color: ${e=>e.secondary||"#fff"}; - bottom: 6px; - left: 6px; - height: 10px; - width: 6px; - } -`,s2=Tn("div")` - position: absolute; -`,i2=Tn("div")` - position: relative; - display: flex; - justify-content: center; - align-items: center; - min-width: 20px; - min-height: 20px; -`,o2=Wt` -from { - transform: scale(0.6); - opacity: 0.4; -} -to { - transform: scale(1); - opacity: 1; -}`,a2=Tn("div")` - position: relative; - transform: scale(0.6); - opacity: 0.4; - min-width: 20px; - animation: ${o2} 0.3s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275) - forwards; -`,l2=({toast:e})=>{let{icon:t,type:n,iconTheme:r}=e;return t!==void 0?typeof t=="string"?k.createElement(a2,null,t):t:n==="blank"?null:k.createElement(i2,null,k.createElement(e2,{...r}),n!=="loading"&&k.createElement(s2,null,n==="error"?k.createElement(Zx,{...r}):k.createElement(r2,{...r})))},u2=e=>` -0% {transform: translate3d(0,${e*-200}%,0) scale(.6); opacity:.5;} -100% {transform: translate3d(0,0,0) scale(1); opacity:1;} -`,c2=e=>` -0% {transform: translate3d(0,0,-1px) scale(1); opacity:1;} -100% {transform: translate3d(0,${e*-150}%,-1px) scale(.6); opacity:0;} -`,d2="0%{opacity:0;} 100%{opacity:1;}",f2="0%{opacity:1;} 100%{opacity:0;}",h2=Tn("div")` - display: flex; - align-items: center; - background: #fff; - color: #363636; - line-height: 1.3; - will-change: transform; - box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05); - max-width: 350px; - pointer-events: auto; - padding: 8px 10px; - border-radius: 8px; -`,p2=Tn("div")` - display: flex; - justify-content: center; - margin: 4px 10px; - color: inherit; - flex: 1 1 auto; - white-space: pre-line; -`,m2=(e,t)=>{let n=e.includes("top")?1:-1,[r,s]=a0()?[d2,f2]:[u2(n),c2(n)];return{animation:t?`${Wt(r)} 0.35s cubic-bezier(.21,1.02,.73,1) forwards`:`${Wt(s)} 0.4s forwards cubic-bezier(.06,.71,.55,1)`}},g2=k.memo(({toast:e,position:t,style:n,children:r})=>{let s=e.height?m2(e.position||t||"top-center",e.visible):{opacity:0},i=k.createElement(l2,{toast:e}),o=k.createElement(p2,{...e.ariaProps},mo(e.message,e));return k.createElement(h2,{className:e.className,style:{...s,...n,...e.style}},typeof r=="function"?r({icon:i,message:o}):k.createElement(k.Fragment,null,i,o))});zx(k.createElement);var y2=({id:e,className:t,style:n,onHeightUpdate:r,children:s})=>{let i=k.useCallback(o=>{if(o){let a=()=>{let l=o.getBoundingClientRect().height;r(e,l)};a(),new MutationObserver(a).observe(o,{subtree:!0,childList:!0,characterData:!0})}},[e,r]);return k.createElement("div",{ref:i,className:t,style:n},s)},v2=(e,t)=>{let n=e.includes("top"),r=n?{top:0}:{bottom:0},s=e.includes("center")?{justifyContent:"center"}:e.includes("right")?{justifyContent:"flex-end"}:{};return{left:0,right:0,display:"flex",position:"absolute",transition:a0()?void 0:"all 230ms cubic-bezier(.21,1.02,.73,1)",transform:`translateY(${t*(n?1:-1)}px)`,...r,...s}},x2=Ho` - z-index: 9999; - > * { - pointer-events: auto; - } -`,bi=16,w2=({reverseOrder:e,position:t="top-center",toastOptions:n,gutter:r,children:s,toasterId:i,containerStyle:o,containerClassName:a})=>{let{toasts:l,handlers:c}=Yx(n,i);return k.createElement("div",{"data-rht-toaster":i||"",style:{position:"fixed",zIndex:9999,top:bi,left:bi,right:bi,bottom:bi,pointerEvents:"none",...o},className:a,onMouseEnter:c.startPause,onMouseLeave:c.endPause},l.map(d=>{let f=d.position||t,u=c.calculateOffset(d,{reverseOrder:e,gutter:r,defaultPosition:t}),h=v2(f,u);return k.createElement(y2,{id:d.id,key:d.id,onHeightUpdate:c.updateHeight,className:d.visible?x2:"",style:h},d.type==="custom"?mo(d.message,d):s?s(d):k.createElement(g2,{toast:d,position:f}))}))},he=ke;const f0=k.createContext({transformPagePoint:e=>e,isStatic:!1,reducedMotion:"never"}),Go=k.createContext({}),cc=k.createContext(null),Yo=typeof document<"u",b2=Yo?k.useLayoutEffect:k.useEffect,h0=k.createContext({strict:!1}),dc=e=>e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),S2="framerAppearId",p0="data-"+dc(S2);function k2(e,t,n,r){const{visualElement:s}=k.useContext(Go),i=k.useContext(h0),o=k.useContext(cc),a=k.useContext(f0).reducedMotion,l=k.useRef();r=r||i.renderer,!l.current&&r&&(l.current=r(e,{visualState:t,parent:s,props:n,presenceContext:o,blockInitialAnimation:o?o.initial===!1:!1,reducedMotionConfig:a}));const c=l.current;k.useInsertionEffect(()=>{c&&c.update(n,o)});const d=k.useRef(!!(n[p0]&&!window.HandoffComplete));return b2(()=>{c&&(c.render(),d.current&&c.animationState&&c.animationState.animateChanges())}),k.useEffect(()=>{c&&(c.updateFeatures(),!d.current&&c.animationState&&c.animationState.animateChanges(),d.current&&(d.current=!1,window.HandoffComplete=!0))}),c}function pr(e){return e&&typeof e=="object"&&Object.prototype.hasOwnProperty.call(e,"current")}function C2(e,t,n){return k.useCallback(r=>{r&&e.mount&&e.mount(r),t&&(r?t.mount(r):t.unmount()),n&&(typeof n=="function"?n(r):pr(n)&&(n.current=r))},[t])}function Bs(e){return typeof e=="string"||Array.isArray(e)}function Ko(e){return e!==null&&typeof e=="object"&&typeof e.start=="function"}const fc=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],hc=["initial",...fc];function Xo(e){return Ko(e.animate)||hc.some(t=>Bs(e[t]))}function m0(e){return!!(Xo(e)||e.variants)}function P2(e,t){if(Xo(e)){const{initial:n,animate:r}=e;return{initial:n===!1||Bs(n)?n:void 0,animate:Bs(r)?r:void 0}}return e.inherit!==!1?t:{}}function j2(e){const{initial:t,animate:n}=P2(e,k.useContext(Go));return k.useMemo(()=>({initial:t,animate:n}),[ef(t),ef(n)])}function ef(e){return Array.isArray(e)?e.join(" "):e}const tf={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]},Us={};for(const e in tf)Us[e]={isEnabled:t=>tf[e].some(n=>!!t[n])};function E2(e){for(const t in e)Us[t]={...Us[t],...e[t]}}const g0=k.createContext({}),y0=k.createContext({}),T2=Symbol.for("motionComponentSymbol");function N2({preloadedFeatures:e,createVisualElement:t,useRender:n,useVisualState:r,Component:s}){e&&E2(e);function i(a,l){let c;const d={...k.useContext(f0),...a,layoutId:M2(a)},{isStatic:f}=d,u=j2(a),h=r(a,f);if(!f&&Yo){u.visualElement=k2(s,h,d,t);const p=k.useContext(y0),g=k.useContext(h0).strict;u.visualElement&&(c=u.visualElement.loadFeatures(d,g,e,p))}return k.createElement(Go.Provider,{value:u},c&&u.visualElement?k.createElement(c,{visualElement:u.visualElement,...d}):null,n(s,a,C2(h,u.visualElement,l),h,f,u.visualElement))}const o=k.forwardRef(i);return o[T2]=s,o}function M2({layoutId:e}){const t=k.useContext(g0).id;return t&&e!==void 0?t+"-"+e:e}function _2(e){function t(r,s={}){return N2(e(r,s))}if(typeof Proxy>"u")return t;const n=new Map;return new Proxy(t,{get:(r,s)=>(n.has(s)||n.set(s,t(s)),n.get(s))})}const A2=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function pc(e){return typeof e!="string"||e.includes("-")?!1:!!(A2.indexOf(e)>-1||/[A-Z]/.test(e))}const go={};function L2(e){Object.assign(go,e)}const Js=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],Qn=new Set(Js);function v0(e,{layout:t,layoutId:n}){return Qn.has(e)||e.startsWith("origin")||(t||n!==void 0)&&(!!go[e]||e==="opacity")}const Ge=e=>!!(e&&e.getVelocity),D2={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},R2=Js.length;function V2(e,{enableHardwareAcceleration:t=!0,allowTransformNone:n=!0},r,s){let i="";for(let o=0;ot=>typeof t=="string"&&t.startsWith(e),w0=x0("--"),Yl=x0("var(--"),F2=/var\s*\(\s*--[\w-]+(\s*,\s*(?:(?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)+)?\s*\)/g,I2=(e,t)=>t&&typeof e=="number"?t.transform(e):e,wn=(e,t,n)=>Math.min(Math.max(n,e),t),Zn={test:e=>typeof e=="number",parse:parseFloat,transform:e=>e},ys={...Zn,transform:e=>wn(0,1,e)},Si={...Zn,default:1},vs=e=>Math.round(e*1e5)/1e5,Qo=/(-)?([\d]*\.?[\d])+/g,b0=/(#[0-9a-f]{3,8}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))/gi,z2=/^(#[0-9a-f]{3,8}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))$/i;function ei(e){return typeof e=="string"}const ti=e=>({test:t=>ei(t)&&t.endsWith(e)&&t.split(" ").length===1,parse:parseFloat,transform:t=>`${t}${e}`}),Qt=ti("deg"),Tt=ti("%"),B=ti("px"),O2=ti("vh"),$2=ti("vw"),nf={...Tt,parse:e=>Tt.parse(e)/100,transform:e=>Tt.transform(e*100)},rf={...Zn,transform:Math.round},S0={borderWidth:B,borderTopWidth:B,borderRightWidth:B,borderBottomWidth:B,borderLeftWidth:B,borderRadius:B,radius:B,borderTopLeftRadius:B,borderTopRightRadius:B,borderBottomRightRadius:B,borderBottomLeftRadius:B,width:B,maxWidth:B,height:B,maxHeight:B,size:B,top:B,right:B,bottom:B,left:B,padding:B,paddingTop:B,paddingRight:B,paddingBottom:B,paddingLeft:B,margin:B,marginTop:B,marginRight:B,marginBottom:B,marginLeft:B,rotate:Qt,rotateX:Qt,rotateY:Qt,rotateZ:Qt,scale:Si,scaleX:Si,scaleY:Si,scaleZ:Si,skew:Qt,skewX:Qt,skewY:Qt,distance:B,translateX:B,translateY:B,translateZ:B,x:B,y:B,z:B,perspective:B,transformPerspective:B,opacity:ys,originX:nf,originY:nf,originZ:B,zIndex:rf,fillOpacity:ys,strokeOpacity:ys,numOctaves:rf};function mc(e,t,n,r){const{style:s,vars:i,transform:o,transformOrigin:a}=e;let l=!1,c=!1,d=!0;for(const f in t){const u=t[f];if(w0(f)){i[f]=u;continue}const h=S0[f],p=I2(u,h);if(Qn.has(f)){if(l=!0,o[f]=p,!d)continue;u!==(h.default||0)&&(d=!1)}else f.startsWith("origin")?(c=!0,a[f]=p):s[f]=p}if(t.transform||(l||r?s.transform=V2(e.transform,n,d,r):s.transform&&(s.transform="none")),c){const{originX:f="50%",originY:u="50%",originZ:h=0}=a;s.transformOrigin=`${f} ${u} ${h}`}}const gc=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function k0(e,t,n){for(const r in t)!Ge(t[r])&&!v0(r,n)&&(e[r]=t[r])}function B2({transformTemplate:e},t,n){return k.useMemo(()=>{const r=gc();return mc(r,t,{enableHardwareAcceleration:!n},e),Object.assign({},r.vars,r.style)},[t])}function U2(e,t,n){const r=e.style||{},s={};return k0(s,r,e),Object.assign(s,B2(e,t,n)),e.transformValues?e.transformValues(s):s}function W2(e,t,n){const r={},s=U2(e,t,n);return e.drag&&e.dragListener!==!1&&(r.draggable=!1,s.userSelect=s.WebkitUserSelect=s.WebkitTouchCallout="none",s.touchAction=e.drag===!0?"none":`pan-${e.drag==="x"?"y":"x"}`),e.tabIndex===void 0&&(e.onTap||e.onTapStart||e.whileTap)&&(r.tabIndex=0),r.style=s,r}const H2=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","transformValues","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","ignoreStrict","viewport"]);function yo(e){return e.startsWith("while")||e.startsWith("drag")&&e!=="draggable"||e.startsWith("layout")||e.startsWith("onTap")||e.startsWith("onPan")||e.startsWith("onLayout")||H2.has(e)}let C0=e=>!yo(e);function q2(e){e&&(C0=t=>t.startsWith("on")?!yo(t):e(t))}try{q2(require("@emotion/is-prop-valid").default)}catch{}function G2(e,t,n){const r={};for(const s in e)s==="values"&&typeof e.values=="object"||(C0(s)||n===!0&&yo(s)||!t&&!yo(s)||e.draggable&&s.startsWith("onDrag"))&&(r[s]=e[s]);return r}function sf(e,t,n){return typeof e=="string"?e:B.transform(t+n*e)}function Y2(e,t,n){const r=sf(t,e.x,e.width),s=sf(n,e.y,e.height);return`${r} ${s}`}const K2={offset:"stroke-dashoffset",array:"stroke-dasharray"},X2={offset:"strokeDashoffset",array:"strokeDasharray"};function Q2(e,t,n=1,r=0,s=!0){e.pathLength=1;const i=s?K2:X2;e[i.offset]=B.transform(-r);const o=B.transform(t),a=B.transform(n);e[i.array]=`${o} ${a}`}function yc(e,{attrX:t,attrY:n,attrScale:r,originX:s,originY:i,pathLength:o,pathSpacing:a=1,pathOffset:l=0,...c},d,f,u){if(mc(e,c,d,u),f){e.style.viewBox&&(e.attrs.viewBox=e.style.viewBox);return}e.attrs=e.style,e.style={};const{attrs:h,style:p,dimensions:g}=e;h.transform&&(g&&(p.transform=h.transform),delete h.transform),g&&(s!==void 0||i!==void 0||p.transform)&&(p.transformOrigin=Y2(g,s!==void 0?s:.5,i!==void 0?i:.5)),t!==void 0&&(h.x=t),n!==void 0&&(h.y=n),r!==void 0&&(h.scale=r),o!==void 0&&Q2(h,o,a,l,!1)}const P0=()=>({...gc(),attrs:{}}),vc=e=>typeof e=="string"&&e.toLowerCase()==="svg";function Z2(e,t,n,r){const s=k.useMemo(()=>{const i=P0();return yc(i,t,{enableHardwareAcceleration:!1},vc(r),e.transformTemplate),{...i.attrs,style:{...i.style}}},[t]);if(e.style){const i={};k0(i,e.style,e),s.style={...i,...s.style}}return s}function J2(e=!1){return(n,r,s,{latestValues:i},o)=>{const l=(pc(n)?Z2:W2)(r,i,o,n),d={...G2(r,typeof n=="string",e),...l,ref:s},{children:f}=r,u=k.useMemo(()=>Ge(f)?f.get():f,[f]);return k.createElement(n,{...d,children:u})}}function j0(e,{style:t,vars:n},r,s){Object.assign(e.style,t,s&&s.getProjectionStyles(r));for(const i in n)e.style.setProperty(i,n[i])}const E0=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]);function T0(e,t,n,r){j0(e,t,void 0,r);for(const s in t.attrs)e.setAttribute(E0.has(s)?s:dc(s),t.attrs[s])}function xc(e,t){const{style:n}=e,r={};for(const s in n)(Ge(n[s])||t.style&&Ge(t.style[s])||v0(s,e))&&(r[s]=n[s]);return r}function N0(e,t){const n=xc(e,t);for(const r in e)if(Ge(e[r])||Ge(t[r])){const s=Js.indexOf(r)!==-1?"attr"+r.charAt(0).toUpperCase()+r.substring(1):r;n[s]=e[r]}return n}function wc(e,t,n,r={},s={}){return typeof t=="function"&&(t=t(n!==void 0?n:e.custom,r,s)),typeof t=="string"&&(t=e.variants&&e.variants[t]),typeof t=="function"&&(t=t(n!==void 0?n:e.custom,r,s)),t}function ew(e){const t=k.useRef(null);return t.current===null&&(t.current=e()),t.current}const vo=e=>Array.isArray(e),tw=e=>!!(e&&typeof e=="object"&&e.mix&&e.toValue),nw=e=>vo(e)?e[e.length-1]||0:e;function $i(e){const t=Ge(e)?e.get():e;return tw(t)?t.toValue():t}function rw({scrapeMotionValuesFromProps:e,createRenderState:t,onMount:n},r,s,i){const o={latestValues:sw(r,s,i,e),renderState:t()};return n&&(o.mount=a=>n(r,a,o)),o}const M0=e=>(t,n)=>{const r=k.useContext(Go),s=k.useContext(cc),i=()=>rw(e,t,r,s);return n?i():ew(i)};function sw(e,t,n,r){const s={},i=r(e,{});for(const u in i)s[u]=$i(i[u]);let{initial:o,animate:a}=e;const l=Xo(e),c=m0(e);t&&c&&!l&&e.inherit!==!1&&(o===void 0&&(o=t.initial),a===void 0&&(a=t.animate));let d=n?n.initial===!1:!1;d=d||o===!1;const f=d?a:o;return f&&typeof f!="boolean"&&!Ko(f)&&(Array.isArray(f)?f:[f]).forEach(h=>{const p=wc(e,h);if(!p)return;const{transitionEnd:g,transition:x,...v}=p;for(const y in v){let w=v[y];if(Array.isArray(w)){const b=d?w.length-1:0;w=w[b]}w!==null&&(s[y]=w)}for(const y in g)s[y]=g[y]}),s}const ye=e=>e;class of{constructor(){this.order=[],this.scheduled=new Set}add(t){if(!this.scheduled.has(t))return this.scheduled.add(t),this.order.push(t),!0}remove(t){const n=this.order.indexOf(t);n!==-1&&(this.order.splice(n,1),this.scheduled.delete(t))}clear(){this.order.length=0,this.scheduled.clear()}}function iw(e){let t=new of,n=new of,r=0,s=!1,i=!1;const o=new WeakSet,a={schedule:(l,c=!1,d=!1)=>{const f=d&&s,u=f?t:n;return c&&o.add(l),u.add(l)&&f&&s&&(r=t.order.length),l},cancel:l=>{n.remove(l),o.delete(l)},process:l=>{if(s){i=!0;return}if(s=!0,[t,n]=[n,t],n.clear(),r=t.order.length,r)for(let c=0;c(f[u]=iw(()=>n=!0),f),{}),o=f=>i[f].process(s),a=()=>{const f=performance.now();n=!1,s.delta=r?1e3/60:Math.max(Math.min(f-s.timestamp,ow),1),s.timestamp=f,s.isProcessing=!0,ki.forEach(o),s.isProcessing=!1,n&&t&&(r=!1,e(a))},l=()=>{n=!0,r=!0,s.isProcessing||e(a)};return{schedule:ki.reduce((f,u)=>{const h=i[u];return f[u]=(p,g=!1,x=!1)=>(n||l(),h.schedule(p,g,x)),f},{}),cancel:f=>ki.forEach(u=>i[u].cancel(f)),state:s,steps:i}}const{schedule:oe,cancel:Ht,state:De,steps:Ma}=aw(typeof requestAnimationFrame<"u"?requestAnimationFrame:ye,!0),lw={useVisualState:M0({scrapeMotionValuesFromProps:N0,createRenderState:P0,onMount:(e,t,{renderState:n,latestValues:r})=>{oe.read(()=>{try{n.dimensions=typeof t.getBBox=="function"?t.getBBox():t.getBoundingClientRect()}catch{n.dimensions={x:0,y:0,width:0,height:0}}}),oe.render(()=>{yc(n,r,{enableHardwareAcceleration:!1},vc(t.tagName),e.transformTemplate),T0(t,n)})}})},uw={useVisualState:M0({scrapeMotionValuesFromProps:xc,createRenderState:gc})};function cw(e,{forwardMotionProps:t=!1},n,r){return{...pc(e)?lw:uw,preloadedFeatures:n,useRender:J2(t),createVisualElement:r,Component:e}}function Vt(e,t,n,r={passive:!0}){return e.addEventListener(t,n,r),()=>e.removeEventListener(t,n)}const _0=e=>e.pointerType==="mouse"?typeof e.button!="number"||e.button<=0:e.isPrimary!==!1;function Zo(e,t="page"){return{point:{x:e[t+"X"],y:e[t+"Y"]}}}const dw=e=>t=>_0(t)&&e(t,Zo(t));function It(e,t,n,r){return Vt(e,t,dw(n),r)}const fw=(e,t)=>n=>t(e(n)),yn=(...e)=>e.reduce(fw);function A0(e){let t=null;return()=>{const n=()=>{t=null};return t===null?(t=e,n):!1}}const af=A0("dragHorizontal"),lf=A0("dragVertical");function L0(e){let t=!1;if(e==="y")t=lf();else if(e==="x")t=af();else{const n=af(),r=lf();n&&r?t=()=>{n(),r()}:(n&&n(),r&&r())}return t}function D0(){const e=L0(!0);return e?(e(),!1):!0}class Nn{constructor(t){this.isMounted=!1,this.node=t}update(){}}function uf(e,t){const n="pointer"+(t?"enter":"leave"),r="onHover"+(t?"Start":"End"),s=(i,o)=>{if(i.pointerType==="touch"||D0())return;const a=e.getProps();e.animationState&&a.whileHover&&e.animationState.setActive("whileHover",t),a[r]&&oe.update(()=>a[r](i,o))};return It(e.current,n,s,{passive:!e.getProps()[r]})}class hw extends Nn{mount(){this.unmount=yn(uf(this.node,!0),uf(this.node,!1))}unmount(){}}class pw extends Nn{constructor(){super(...arguments),this.isActive=!1}onFocus(){let t=!1;try{t=this.node.current.matches(":focus-visible")}catch{t=!0}!t||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=yn(Vt(this.node.current,"focus",()=>this.onFocus()),Vt(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}const R0=(e,t)=>t?e===t?!0:R0(e,t.parentElement):!1;function _a(e,t){if(!t)return;const n=new PointerEvent("pointer"+e);t(n,Zo(n))}class mw extends Nn{constructor(){super(...arguments),this.removeStartListeners=ye,this.removeEndListeners=ye,this.removeAccessibleListeners=ye,this.startPointerPress=(t,n)=>{if(this.isPressing)return;this.removeEndListeners();const r=this.node.getProps(),i=It(window,"pointerup",(a,l)=>{if(!this.checkPressEnd())return;const{onTap:c,onTapCancel:d,globalTapTarget:f}=this.node.getProps();oe.update(()=>{!f&&!R0(this.node.current,a.target)?d&&d(a,l):c&&c(a,l)})},{passive:!(r.onTap||r.onPointerUp)}),o=It(window,"pointercancel",(a,l)=>this.cancelPress(a,l),{passive:!(r.onTapCancel||r.onPointerCancel)});this.removeEndListeners=yn(i,o),this.startPress(t,n)},this.startAccessiblePress=()=>{const t=i=>{if(i.key!=="Enter"||this.isPressing)return;const o=a=>{a.key!=="Enter"||!this.checkPressEnd()||_a("up",(l,c)=>{const{onTap:d}=this.node.getProps();d&&oe.update(()=>d(l,c))})};this.removeEndListeners(),this.removeEndListeners=Vt(this.node.current,"keyup",o),_a("down",(a,l)=>{this.startPress(a,l)})},n=Vt(this.node.current,"keydown",t),r=()=>{this.isPressing&&_a("cancel",(i,o)=>this.cancelPress(i,o))},s=Vt(this.node.current,"blur",r);this.removeAccessibleListeners=yn(n,s)}}startPress(t,n){this.isPressing=!0;const{onTapStart:r,whileTap:s}=this.node.getProps();s&&this.node.animationState&&this.node.animationState.setActive("whileTap",!0),r&&oe.update(()=>r(t,n))}checkPressEnd(){return this.removeEndListeners(),this.isPressing=!1,this.node.getProps().whileTap&&this.node.animationState&&this.node.animationState.setActive("whileTap",!1),!D0()}cancelPress(t,n){if(!this.checkPressEnd())return;const{onTapCancel:r}=this.node.getProps();r&&oe.update(()=>r(t,n))}mount(){const t=this.node.getProps(),n=It(t.globalTapTarget?window:this.node.current,"pointerdown",this.startPointerPress,{passive:!(t.onTapStart||t.onPointerStart)}),r=Vt(this.node.current,"focus",this.startAccessiblePress);this.removeStartListeners=yn(n,r)}unmount(){this.removeStartListeners(),this.removeEndListeners(),this.removeAccessibleListeners()}}const Kl=new WeakMap,Aa=new WeakMap,gw=e=>{const t=Kl.get(e.target);t&&t(e)},yw=e=>{e.forEach(gw)};function vw({root:e,...t}){const n=e||document;Aa.has(n)||Aa.set(n,{});const r=Aa.get(n),s=JSON.stringify(t);return r[s]||(r[s]=new IntersectionObserver(yw,{root:e,...t})),r[s]}function xw(e,t,n){const r=vw(t);return Kl.set(e,n),r.observe(e),()=>{Kl.delete(e),r.unobserve(e)}}const ww={some:0,all:1};class bw extends Nn{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.unmount();const{viewport:t={}}=this.node.getProps(),{root:n,margin:r,amount:s="some",once:i}=t,o={root:n?n.current:void 0,rootMargin:r,threshold:typeof s=="number"?s:ww[s]},a=l=>{const{isIntersecting:c}=l;if(this.isInView===c||(this.isInView=c,i&&!c&&this.hasEnteredView))return;c&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",c);const{onViewportEnter:d,onViewportLeave:f}=this.node.getProps(),u=c?d:f;u&&u(l)};return xw(this.node.current,o,a)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:t,prevProps:n}=this.node;["amount","margin","root"].some(Sw(t,n))&&this.startObserver()}unmount(){}}function Sw({viewport:e={}},{viewport:t={}}={}){return n=>e[n]!==t[n]}const kw={inView:{Feature:bw},tap:{Feature:mw},focus:{Feature:pw},hover:{Feature:hw}};function V0(e,t){if(!Array.isArray(t))return!1;const n=t.length;if(n!==e.length)return!1;for(let r=0;rt[r]=n.get()),t}function Pw(e){const t={};return e.values.forEach((n,r)=>t[r]=n.getVelocity()),t}function Jo(e,t,n){const r=e.getProps();return wc(r,t,n!==void 0?n:r.custom,Cw(e),Pw(e))}let bc=ye;const Bn=e=>e*1e3,zt=e=>e/1e3,jw={current:!1},F0=e=>Array.isArray(e)&&typeof e[0]=="number";function I0(e){return!!(!e||typeof e=="string"&&z0[e]||F0(e)||Array.isArray(e)&&e.every(I0))}const as=([e,t,n,r])=>`cubic-bezier(${e}, ${t}, ${n}, ${r})`,z0={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:as([0,.65,.55,1]),circOut:as([.55,0,1,.45]),backIn:as([.31,.01,.66,-.59]),backOut:as([.33,1.53,.69,.99])};function O0(e){if(e)return F0(e)?as(e):Array.isArray(e)?e.map(O0):z0[e]}function Ew(e,t,n,{delay:r=0,duration:s,repeat:i=0,repeatType:o="loop",ease:a,times:l}={}){const c={[t]:n};l&&(c.offset=l);const d=O0(a);return Array.isArray(d)&&(c.easing=d),e.animate(c,{delay:r,duration:s,easing:Array.isArray(d)?"linear":d,fill:"both",iterations:i+1,direction:o==="reverse"?"alternate":"normal"})}function Tw(e,{repeat:t,repeatType:n="loop"}){const r=t&&n!=="loop"&&t%2===1?0:e.length-1;return e[r]}const $0=(e,t,n)=>(((1-3*n+3*t)*e+(3*n-6*t))*e+3*t)*e,Nw=1e-7,Mw=12;function _w(e,t,n,r,s){let i,o,a=0;do o=t+(n-t)/2,i=$0(o,r,s)-e,i>0?n=o:t=o;while(Math.abs(i)>Nw&&++a_w(i,0,1,e,n);return i=>i===0||i===1?i:$0(s(i),t,r)}const Aw=ni(.42,0,1,1),Lw=ni(0,0,.58,1),B0=ni(.42,0,.58,1),Dw=e=>Array.isArray(e)&&typeof e[0]!="number",U0=e=>t=>t<=.5?e(2*t)/2:(2-e(2*(1-t)))/2,W0=e=>t=>1-e(1-t),Sc=e=>1-Math.sin(Math.acos(e)),H0=W0(Sc),Rw=U0(Sc),q0=ni(.33,1.53,.69,.99),kc=W0(q0),Vw=U0(kc),Fw=e=>(e*=2)<1?.5*kc(e):.5*(2-Math.pow(2,-10*(e-1))),Iw={linear:ye,easeIn:Aw,easeInOut:B0,easeOut:Lw,circIn:Sc,circInOut:Rw,circOut:H0,backIn:kc,backInOut:Vw,backOut:q0,anticipate:Fw},cf=e=>{if(Array.isArray(e)){bc(e.length===4);const[t,n,r,s]=e;return ni(t,n,r,s)}else if(typeof e=="string")return Iw[e];return e},Cc=(e,t)=>n=>!!(ei(n)&&z2.test(n)&&n.startsWith(e)||t&&Object.prototype.hasOwnProperty.call(n,t)),G0=(e,t,n)=>r=>{if(!ei(r))return r;const[s,i,o,a]=r.match(Qo);return{[e]:parseFloat(s),[t]:parseFloat(i),[n]:parseFloat(o),alpha:a!==void 0?parseFloat(a):1}},zw=e=>wn(0,255,e),La={...Zn,transform:e=>Math.round(zw(e))},zn={test:Cc("rgb","red"),parse:G0("red","green","blue"),transform:({red:e,green:t,blue:n,alpha:r=1})=>"rgba("+La.transform(e)+", "+La.transform(t)+", "+La.transform(n)+", "+vs(ys.transform(r))+")"};function Ow(e){let t="",n="",r="",s="";return e.length>5?(t=e.substring(1,3),n=e.substring(3,5),r=e.substring(5,7),s=e.substring(7,9)):(t=e.substring(1,2),n=e.substring(2,3),r=e.substring(3,4),s=e.substring(4,5),t+=t,n+=n,r+=r,s+=s),{red:parseInt(t,16),green:parseInt(n,16),blue:parseInt(r,16),alpha:s?parseInt(s,16)/255:1}}const Xl={test:Cc("#"),parse:Ow,transform:zn.transform},mr={test:Cc("hsl","hue"),parse:G0("hue","saturation","lightness"),transform:({hue:e,saturation:t,lightness:n,alpha:r=1})=>"hsla("+Math.round(e)+", "+Tt.transform(vs(t))+", "+Tt.transform(vs(n))+", "+vs(ys.transform(r))+")"},Fe={test:e=>zn.test(e)||Xl.test(e)||mr.test(e),parse:e=>zn.test(e)?zn.parse(e):mr.test(e)?mr.parse(e):Xl.parse(e),transform:e=>ei(e)?e:e.hasOwnProperty("red")?zn.transform(e):mr.transform(e)},ce=(e,t,n)=>-n*e+n*t+e;function Da(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<1/2?t:n<2/3?e+(t-e)*(2/3-n)*6:e}function $w({hue:e,saturation:t,lightness:n,alpha:r}){e/=360,t/=100,n/=100;let s=0,i=0,o=0;if(!t)s=i=o=n;else{const a=n<.5?n*(1+t):n+t-n*t,l=2*n-a;s=Da(l,a,e+1/3),i=Da(l,a,e),o=Da(l,a,e-1/3)}return{red:Math.round(s*255),green:Math.round(i*255),blue:Math.round(o*255),alpha:r}}const Ra=(e,t,n)=>{const r=e*e;return Math.sqrt(Math.max(0,n*(t*t-r)+r))},Bw=[Xl,zn,mr],Uw=e=>Bw.find(t=>t.test(e));function df(e){const t=Uw(e);let n=t.parse(e);return t===mr&&(n=$w(n)),n}const Y0=(e,t)=>{const n=df(e),r=df(t),s={...n};return i=>(s.red=Ra(n.red,r.red,i),s.green=Ra(n.green,r.green,i),s.blue=Ra(n.blue,r.blue,i),s.alpha=ce(n.alpha,r.alpha,i),zn.transform(s))};function Ww(e){var t,n;return isNaN(e)&&ei(e)&&(((t=e.match(Qo))===null||t===void 0?void 0:t.length)||0)+(((n=e.match(b0))===null||n===void 0?void 0:n.length)||0)>0}const K0={regex:F2,countKey:"Vars",token:"${v}",parse:ye},X0={regex:b0,countKey:"Colors",token:"${c}",parse:Fe.parse},Q0={regex:Qo,countKey:"Numbers",token:"${n}",parse:Zn.parse};function Va(e,{regex:t,countKey:n,token:r,parse:s}){const i=e.tokenised.match(t);i&&(e["num"+n]=i.length,e.tokenised=e.tokenised.replace(t,r),e.values.push(...i.map(s)))}function xo(e){const t=e.toString(),n={value:t,tokenised:t,values:[],numVars:0,numColors:0,numNumbers:0};return n.value.includes("var(--")&&Va(n,K0),Va(n,X0),Va(n,Q0),n}function Z0(e){return xo(e).values}function J0(e){const{values:t,numColors:n,numVars:r,tokenised:s}=xo(e),i=t.length;return o=>{let a=s;for(let l=0;ltypeof e=="number"?0:e;function qw(e){const t=Z0(e);return J0(e)(t.map(Hw))}const bn={test:Ww,parse:Z0,createTransformer:J0,getAnimatableNone:qw},eg=(e,t)=>n=>`${n>0?t:e}`;function tg(e,t){return typeof e=="number"?n=>ce(e,t,n):Fe.test(e)?Y0(e,t):e.startsWith("var(")?eg(e,t):rg(e,t)}const ng=(e,t)=>{const n=[...e],r=n.length,s=e.map((i,o)=>tg(i,t[o]));return i=>{for(let o=0;o{const n={...e,...t},r={};for(const s in n)e[s]!==void 0&&t[s]!==void 0&&(r[s]=tg(e[s],t[s]));return s=>{for(const i in r)n[i]=r[i](s);return n}},rg=(e,t)=>{const n=bn.createTransformer(t),r=xo(e),s=xo(t);return r.numVars===s.numVars&&r.numColors===s.numColors&&r.numNumbers>=s.numNumbers?yn(ng(r.values,s.values),n):eg(e,t)},Ws=(e,t,n)=>{const r=t-e;return r===0?1:(n-e)/r},ff=(e,t)=>n=>ce(e,t,n);function Yw(e){return typeof e=="number"?ff:typeof e=="string"?Fe.test(e)?Y0:rg:Array.isArray(e)?ng:typeof e=="object"?Gw:ff}function Kw(e,t,n){const r=[],s=n||Yw(e[0]),i=e.length-1;for(let o=0;ot[0];e[0]>e[i-1]&&(e=[...e].reverse(),t=[...t].reverse());const o=Kw(t,r,s),a=o.length,l=c=>{let d=0;if(a>1)for(;dl(wn(e[0],e[i-1],c)):l}function Xw(e,t){const n=e[e.length-1];for(let r=1;r<=t;r++){const s=Ws(0,t,r);e.push(ce(n,1,s))}}function Qw(e){const t=[0];return Xw(t,e.length-1),t}function Zw(e,t){return e.map(n=>n*t)}function Jw(e,t){return e.map(()=>t||B0).splice(0,e.length-1)}function wo({duration:e=300,keyframes:t,times:n,ease:r="easeInOut"}){const s=Dw(r)?r.map(cf):cf(r),i={done:!1,value:t[0]},o=Zw(n&&n.length===t.length?n:Qw(t),e),a=sg(o,t,{ease:Array.isArray(s)?s:Jw(t,s)});return{calculatedDuration:e,next:l=>(i.value=a(l),i.done=l>=e,i)}}function ig(e,t){return t?e*(1e3/t):0}const e5=5;function og(e,t,n){const r=Math.max(t-e5,0);return ig(n-e(r),t-r)}const Fa=.001,t5=.01,n5=10,r5=.05,s5=1;function i5({duration:e=800,bounce:t=.25,velocity:n=0,mass:r=1}){let s,i,o=1-t;o=wn(r5,s5,o),e=wn(t5,n5,zt(e)),o<1?(s=c=>{const d=c*o,f=d*e,u=d-n,h=Ql(c,o),p=Math.exp(-f);return Fa-u/h*p},i=c=>{const f=c*o*e,u=f*n+n,h=Math.pow(o,2)*Math.pow(c,2)*e,p=Math.exp(-f),g=Ql(Math.pow(c,2),o);return(-s(c)+Fa>0?-1:1)*((u-h)*p)/g}):(s=c=>{const d=Math.exp(-c*e),f=(c-n)*e+1;return-Fa+d*f},i=c=>{const d=Math.exp(-c*e),f=(n-c)*(e*e);return d*f});const a=5/e,l=a5(s,i,a);if(e=Bn(e),isNaN(l))return{stiffness:100,damping:10,duration:e};{const c=Math.pow(l,2)*r;return{stiffness:c,damping:o*2*Math.sqrt(r*c),duration:e}}}const o5=12;function a5(e,t,n){let r=n;for(let s=1;se[n]!==void 0)}function c5(e){let t={velocity:0,stiffness:100,damping:10,mass:1,isResolvedFromDuration:!1,...e};if(!hf(e,u5)&&hf(e,l5)){const n=i5(e);t={...t,...n,mass:1},t.isResolvedFromDuration=!0}return t}function ag({keyframes:e,restDelta:t,restSpeed:n,...r}){const s=e[0],i=e[e.length-1],o={done:!1,value:s},{stiffness:a,damping:l,mass:c,duration:d,velocity:f,isResolvedFromDuration:u}=c5({...r,velocity:-zt(r.velocity||0)}),h=f||0,p=l/(2*Math.sqrt(a*c)),g=i-s,x=zt(Math.sqrt(a/c)),v=Math.abs(g)<5;n||(n=v?.01:2),t||(t=v?.005:.5);let y;if(p<1){const w=Ql(x,p);y=b=>{const S=Math.exp(-p*x*b);return i-S*((h+p*x*g)/w*Math.sin(w*b)+g*Math.cos(w*b))}}else if(p===1)y=w=>i-Math.exp(-x*w)*(g+(h+x*g)*w);else{const w=x*Math.sqrt(p*p-1);y=b=>{const S=Math.exp(-p*x*b),C=Math.min(w*b,300);return i-S*((h+p*x*g)*Math.sinh(C)+w*g*Math.cosh(C))/w}}return{calculatedDuration:u&&d||null,next:w=>{const b=y(w);if(u)o.done=w>=d;else{let S=h;w!==0&&(p<1?S=og(y,w,b):S=0);const C=Math.abs(S)<=n,P=Math.abs(i-b)<=t;o.done=C&&P}return o.value=o.done?i:b,o}}}function pf({keyframes:e,velocity:t=0,power:n=.8,timeConstant:r=325,bounceDamping:s=10,bounceStiffness:i=500,modifyTarget:o,min:a,max:l,restDelta:c=.5,restSpeed:d}){const f=e[0],u={done:!1,value:f},h=j=>a!==void 0&&jl,p=j=>a===void 0?l:l===void 0||Math.abs(a-j)-g*Math.exp(-j/r),w=j=>v+y(j),b=j=>{const D=y(j),T=w(j);u.done=Math.abs(D)<=c,u.value=u.done?v:T};let S,C;const P=j=>{h(u.value)&&(S=j,C=ag({keyframes:[u.value,p(u.value)],velocity:og(w,j,u.value),damping:s,stiffness:i,restDelta:c,restSpeed:d}))};return P(0),{calculatedDuration:null,next:j=>{let D=!1;return!C&&S===void 0&&(D=!0,b(j),P(j)),S!==void 0&&j>S?C.next(j-S):(!D&&b(j),u)}}}const d5=e=>{const t=({timestamp:n})=>e(n);return{start:()=>oe.update(t,!0),stop:()=>Ht(t),now:()=>De.isProcessing?De.timestamp:performance.now()}},mf=2e4;function gf(e){let t=0;const n=50;let r=e.next(t);for(;!r.done&&t=mf?1/0:t}const f5={decay:pf,inertia:pf,tween:wo,keyframes:wo,spring:ag};function bo({autoplay:e=!0,delay:t=0,driver:n=d5,keyframes:r,type:s="keyframes",repeat:i=0,repeatDelay:o=0,repeatType:a="loop",onPlay:l,onStop:c,onComplete:d,onUpdate:f,...u}){let h=1,p=!1,g,x;const v=()=>{x=new Promise(L=>{g=L})};v();let y;const w=f5[s]||wo;let b;w!==wo&&typeof r[0]!="number"&&(b=sg([0,100],r,{clamp:!1}),r=[0,100]);const S=w({...u,keyframes:r});let C;a==="mirror"&&(C=w({...u,keyframes:[...r].reverse(),velocity:-(u.velocity||0)}));let P="idle",j=null,D=null,T=null;S.calculatedDuration===null&&i&&(S.calculatedDuration=gf(S));const{calculatedDuration:z}=S;let V=1/0,U=1/0;z!==null&&(V=z+o,U=V*(i+1)-o);let R=0;const Q=L=>{if(D===null)return;h>0&&(D=Math.min(D,L)),h<0&&(D=Math.min(L-U/h,D)),j!==null?R=j:R=Math.round(L-D)*h;const E=R-t*(h>=0?1:-1),W=h>=0?E<0:E>U;R=Math.max(E,0),P==="finished"&&j===null&&(R=U);let X=R,te=S;if(i){const Jn=Math.min(R,U)/V;let Mn=Math.floor(Jn),wt=Jn%1;!wt&&Jn>=1&&(wt=1),wt===1&&Mn--,Mn=Math.min(Mn,i+1),!!(Mn%2)&&(a==="reverse"?(wt=1-wt,o&&(wt-=o/V)):a==="mirror"&&(te=C)),X=wn(0,1,wt)*V}const G=W?{done:!1,value:r[0]}:te.next(X);b&&(G.value=b(G.value));let{done:be}=G;!W&&z!==null&&(be=h>=0?R>=U:R<=0);const ri=j===null&&(P==="finished"||P==="running"&&be);return f&&f(G.value),ri&&_(),G},A=()=>{y&&y.stop(),y=void 0},q=()=>{P="idle",A(),g(),v(),D=T=null},_=()=>{P="finished",d&&d(),A(),g()},N=()=>{if(p)return;y||(y=n(Q));const L=y.now();l&&l(),j!==null?D=L-j:(!D||P==="finished")&&(D=L),P==="finished"&&v(),T=D,j=null,P="running",y.start()};e&&N();const F={then(L,E){return x.then(L,E)},get time(){return zt(R)},set time(L){L=Bn(L),R=L,j!==null||!y||h===0?j=L:D=y.now()-L/h},get duration(){const L=S.calculatedDuration===null?gf(S):S.calculatedDuration;return zt(L)},get speed(){return h},set speed(L){L===h||!y||(h=L,F.time=zt(R))},get state(){return P},play:N,pause:()=>{P="paused",j=R},stop:()=>{p=!0,P!=="idle"&&(P="idle",c&&c(),q())},cancel:()=>{T!==null&&Q(T),q()},complete:()=>{P="finished"},sample:L=>(D=0,Q(L))};return F}function h5(e){let t;return()=>(t===void 0&&(t=e()),t)}const p5=h5(()=>Object.hasOwnProperty.call(Element.prototype,"animate")),m5=new Set(["opacity","clipPath","filter","transform","backgroundColor"]),Ci=10,g5=2e4,y5=(e,t)=>t.type==="spring"||e==="backgroundColor"||!I0(t.ease);function v5(e,t,{onUpdate:n,onComplete:r,...s}){if(!(p5()&&m5.has(t)&&!s.repeatDelay&&s.repeatType!=="mirror"&&s.damping!==0&&s.type!=="inertia"))return!1;let o=!1,a,l,c=!1;const d=()=>{l=new Promise(w=>{a=w})};d();let{keyframes:f,duration:u=300,ease:h,times:p}=s;if(y5(t,s)){const w=bo({...s,repeat:0,delay:0});let b={done:!1,value:f[0]};const S=[];let C=0;for(;!b.done&&C{c=!1,g.cancel()},v=()=>{c=!0,oe.update(x),a(),d()};return g.onfinish=()=>{c||(e.set(Tw(f,s)),r&&r(),v())},{then(w,b){return l.then(w,b)},attachTimeline(w){return g.timeline=w,g.onfinish=null,ye},get time(){return zt(g.currentTime||0)},set time(w){g.currentTime=Bn(w)},get speed(){return g.playbackRate},set speed(w){g.playbackRate=w},get duration(){return zt(u)},play:()=>{o||(g.play(),Ht(x))},pause:()=>g.pause(),stop:()=>{if(o=!0,g.playState==="idle")return;const{currentTime:w}=g;if(w){const b=bo({...s,autoplay:!1});e.setWithVelocity(b.sample(w-Ci).value,b.sample(w).value,Ci)}v()},complete:()=>{c||g.finish()},cancel:v}}function x5({keyframes:e,delay:t,onUpdate:n,onComplete:r}){const s=()=>(n&&n(e[e.length-1]),r&&r(),{time:0,speed:1,duration:0,play:ye,pause:ye,stop:ye,then:i=>(i(),Promise.resolve()),cancel:ye,complete:ye});return t?bo({keyframes:[0,1],duration:0,delay:t,onComplete:s}):s()}const w5={type:"spring",stiffness:500,damping:25,restSpeed:10},b5=e=>({type:"spring",stiffness:550,damping:e===0?2*Math.sqrt(550):30,restSpeed:10}),S5={type:"keyframes",duration:.8},k5={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},C5=(e,{keyframes:t})=>t.length>2?S5:Qn.has(e)?e.startsWith("scale")?b5(t[1]):w5:k5,Zl=(e,t)=>e==="zIndex"?!1:!!(typeof t=="number"||Array.isArray(t)||typeof t=="string"&&(bn.test(t)||t==="0")&&!t.startsWith("url(")),P5=new Set(["brightness","contrast","saturate","opacity"]);function j5(e){const[t,n]=e.slice(0,-1).split("(");if(t==="drop-shadow")return e;const[r]=n.match(Qo)||[];if(!r)return e;const s=n.replace(r,"");let i=P5.has(t)?1:0;return r!==n&&(i*=100),t+"("+i+s+")"}const E5=/([a-z-]*)\(.*?\)/g,Jl={...bn,getAnimatableNone:e=>{const t=e.match(E5);return t?t.map(j5).join(" "):e}},T5={...S0,color:Fe,backgroundColor:Fe,outlineColor:Fe,fill:Fe,stroke:Fe,borderColor:Fe,borderTopColor:Fe,borderRightColor:Fe,borderBottomColor:Fe,borderLeftColor:Fe,filter:Jl,WebkitFilter:Jl},Pc=e=>T5[e];function lg(e,t){let n=Pc(e);return n!==Jl&&(n=bn),n.getAnimatableNone?n.getAnimatableNone(t):void 0}const ug=e=>/^0[^.\s]+$/.test(e);function N5(e){if(typeof e=="number")return e===0;if(e!==null)return e==="none"||e==="0"||ug(e)}function M5(e,t,n,r){const s=Zl(t,n);let i;Array.isArray(n)?i=[...n]:i=[null,n];const o=r.from!==void 0?r.from:e.get();let a;const l=[];for(let c=0;cs=>{const i=jc(r,e)||{},o=i.delay||r.delay||0;let{elapsed:a=0}=r;a=a-Bn(o);const l=M5(t,e,n,i),c=l[0],d=l[l.length-1],f=Zl(e,c),u=Zl(e,d);let h={keyframes:l,velocity:t.getVelocity(),ease:"easeOut",...i,delay:-a,onUpdate:p=>{t.set(p),i.onUpdate&&i.onUpdate(p)},onComplete:()=>{s(),i.onComplete&&i.onComplete()}};if(_5(i)||(h={...h,...C5(e,h)}),h.duration&&(h.duration=Bn(h.duration)),h.repeatDelay&&(h.repeatDelay=Bn(h.repeatDelay)),!f||!u||jw.current||i.type===!1||A5.skipAnimations)return x5(h);if(!r.isHandoff&&t.owner&&t.owner.current instanceof HTMLElement&&!t.owner.getProps().onUpdate){const p=v5(t,e,h);if(p)return p}return bo(h)};function So(e){return!!(Ge(e)&&e.add)}const cg=e=>/^\-?\d*\.?\d+$/.test(e);function Tc(e,t){e.indexOf(t)===-1&&e.push(t)}function Nc(e,t){const n=e.indexOf(t);n>-1&&e.splice(n,1)}class Mc{constructor(){this.subscriptions=[]}add(t){return Tc(this.subscriptions,t),()=>Nc(this.subscriptions,t)}notify(t,n,r){const s=this.subscriptions.length;if(s)if(s===1)this.subscriptions[0](t,n,r);else for(let i=0;i!isNaN(parseFloat(e));class D5{constructor(t,n={}){this.version="10.18.0",this.timeDelta=0,this.lastUpdated=0,this.canTrackVelocity=!1,this.events={},this.updateAndNotify=(r,s=!0)=>{this.prev=this.current,this.current=r;const{delta:i,timestamp:o}=De;this.lastUpdated!==o&&(this.timeDelta=i,this.lastUpdated=o,oe.postRender(this.scheduleVelocityCheck)),this.prev!==this.current&&this.events.change&&this.events.change.notify(this.current),this.events.velocityChange&&this.events.velocityChange.notify(this.getVelocity()),s&&this.events.renderRequest&&this.events.renderRequest.notify(this.current)},this.scheduleVelocityCheck=()=>oe.postRender(this.velocityCheck),this.velocityCheck=({timestamp:r})=>{r!==this.lastUpdated&&(this.prev=this.current,this.events.velocityChange&&this.events.velocityChange.notify(this.getVelocity()))},this.hasAnimated=!1,this.prev=this.current=t,this.canTrackVelocity=L5(this.current),this.owner=n.owner}onChange(t){return this.on("change",t)}on(t,n){this.events[t]||(this.events[t]=new Mc);const r=this.events[t].add(n);return t==="change"?()=>{r(),oe.read(()=>{this.events.change.getSize()||this.stop()})}:r}clearListeners(){for(const t in this.events)this.events[t].clear()}attach(t,n){this.passiveEffect=t,this.stopPassiveEffect=n}set(t,n=!0){!n||!this.passiveEffect?this.updateAndNotify(t,n):this.passiveEffect(t,this.updateAndNotify)}setWithVelocity(t,n,r){this.set(n),this.prev=t,this.timeDelta=r}jump(t){this.updateAndNotify(t),this.prev=t,this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}get(){return this.current}getPrevious(){return this.prev}getVelocity(){return this.canTrackVelocity?ig(parseFloat(this.current)-parseFloat(this.prev),this.timeDelta):0}start(t){return this.stop(),new Promise(n=>{this.hasAnimated=!0,this.animation=t(n),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function Lr(e,t){return new D5(e,t)}const dg=e=>t=>t.test(e),R5={test:e=>e==="auto",parse:e=>e},fg=[Zn,B,Tt,Qt,$2,O2,R5],Jr=e=>fg.find(dg(e)),V5=[...fg,Fe,bn],F5=e=>V5.find(dg(e));function I5(e,t,n){e.hasValue(t)?e.getValue(t).set(n):e.addValue(t,Lr(n))}function z5(e,t){const n=Jo(e,t);let{transitionEnd:r={},transition:s={},...i}=n?e.makeTargetAnimatable(n,!1):{};i={...i,...r};for(const o in i){const a=nw(i[o]);I5(e,o,a)}}function O5(e,t,n){var r,s;const i=Object.keys(t).filter(a=>!e.hasValue(a)),o=i.length;if(o)for(let a=0;al.remove(f))),c.push(x)}return o&&Promise.all(c).then(()=>{o&&z5(e,o)}),c}function eu(e,t,n={}){const r=Jo(e,t,n.custom);let{transition:s=e.getDefaultTransition()||{}}=r||{};n.transitionOverride&&(s=n.transitionOverride);const i=r?()=>Promise.all(hg(e,r,n)):()=>Promise.resolve(),o=e.variantChildren&&e.variantChildren.size?(l=0)=>{const{delayChildren:c=0,staggerChildren:d,staggerDirection:f}=s;return H5(e,t,c+l,d,f,n)}:()=>Promise.resolve(),{when:a}=s;if(a){const[l,c]=a==="beforeChildren"?[i,o]:[o,i];return l().then(()=>c())}else return Promise.all([i(),o(n.delay)])}function H5(e,t,n=0,r=0,s=1,i){const o=[],a=(e.variantChildren.size-1)*r,l=s===1?(c=0)=>c*r:(c=0)=>a-c*r;return Array.from(e.variantChildren).sort(q5).forEach((c,d)=>{c.notify("AnimationStart",t),o.push(eu(c,t,{...i,delay:n+l(d)}).then(()=>c.notify("AnimationComplete",t)))}),Promise.all(o)}function q5(e,t){return e.sortNodePosition(t)}function G5(e,t,n={}){e.notify("AnimationStart",t);let r;if(Array.isArray(t)){const s=t.map(i=>eu(e,i,n));r=Promise.all(s)}else if(typeof t=="string")r=eu(e,t,n);else{const s=typeof t=="function"?Jo(e,t,n.custom):t;r=Promise.all(hg(e,s,n))}return r.then(()=>e.notify("AnimationComplete",t))}const Y5=[...fc].reverse(),K5=fc.length;function X5(e){return t=>Promise.all(t.map(({animation:n,options:r})=>G5(e,n,r)))}function Q5(e){let t=X5(e);const n=J5();let r=!0;const s=(l,c)=>{const d=Jo(e,c);if(d){const{transition:f,transitionEnd:u,...h}=d;l={...l,...h,...u}}return l};function i(l){t=l(e)}function o(l,c){const d=e.getProps(),f=e.getVariantContext(!0)||{},u=[],h=new Set;let p={},g=1/0;for(let v=0;vg&&S,T=!1;const z=Array.isArray(b)?b:[b];let V=z.reduce(s,{});C===!1&&(V={});const{prevResolvedValues:U={}}=w,R={...U,...V},Q=A=>{D=!0,h.has(A)&&(T=!0,h.delete(A)),w.needsAnimating[A]=!0};for(const A in R){const q=V[A],_=U[A];if(p.hasOwnProperty(A))continue;let N=!1;vo(q)&&vo(_)?N=!V0(q,_):N=q!==_,N?q!==void 0?Q(A):h.add(A):q!==void 0&&h.has(A)?Q(A):w.protectedKeys[A]=!0}w.prevProp=b,w.prevResolvedValues=V,w.isActive&&(p={...p,...V}),r&&e.blockInitialAnimation&&(D=!1),D&&(!P||T)&&u.push(...z.map(A=>({animation:A,options:{type:y,...l}})))}if(h.size){const v={};h.forEach(y=>{const w=e.getBaseTarget(y);w!==void 0&&(v[y]=w)}),u.push({animation:v})}let x=!!u.length;return r&&(d.initial===!1||d.initial===d.animate)&&!e.manuallyAnimateOnMount&&(x=!1),r=!1,x?t(u):Promise.resolve()}function a(l,c,d){var f;if(n[l].isActive===c)return Promise.resolve();(f=e.variantChildren)===null||f===void 0||f.forEach(h=>{var p;return(p=h.animationState)===null||p===void 0?void 0:p.setActive(l,c)}),n[l].isActive=c;const u=o(d,l);for(const h in n)n[h].protectedKeys={};return u}return{animateChanges:o,setActive:a,setAnimateFunction:i,getState:()=>n}}function Z5(e,t){return typeof t=="string"?t!==e:Array.isArray(t)?!V0(t,e):!1}function _n(e=!1){return{isActive:e,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function J5(){return{animate:_n(!0),whileInView:_n(),whileHover:_n(),whileTap:_n(),whileDrag:_n(),whileFocus:_n(),exit:_n()}}class e3 extends Nn{constructor(t){super(t),t.animationState||(t.animationState=Q5(t))}updateAnimationControlsSubscription(){const{animate:t}=this.node.getProps();this.unmount(),Ko(t)&&(this.unmount=t.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:t}=this.node.getProps(),{animate:n}=this.node.prevProps||{};t!==n&&this.updateAnimationControlsSubscription()}unmount(){}}let t3=0;class n3 extends Nn{constructor(){super(...arguments),this.id=t3++}update(){if(!this.node.presenceContext)return;const{isPresent:t,onExitComplete:n,custom:r}=this.node.presenceContext,{isPresent:s}=this.node.prevPresenceContext||{};if(!this.node.animationState||t===s)return;const i=this.node.animationState.setActive("exit",!t,{custom:r??this.node.getProps().custom});n&&!t&&i.then(()=>n(this.id))}mount(){const{register:t}=this.node.presenceContext||{};t&&(this.unmount=t(this.id))}unmount(){}}const r3={animation:{Feature:e3},exit:{Feature:n3}},yf=(e,t)=>Math.abs(e-t);function s3(e,t){const n=yf(e.x,t.x),r=yf(e.y,t.y);return Math.sqrt(n**2+r**2)}class pg{constructor(t,n,{transformPagePoint:r,contextWindow:s,dragSnapToOrigin:i=!1}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const f=za(this.lastMoveEventInfo,this.history),u=this.startEvent!==null,h=s3(f.offset,{x:0,y:0})>=3;if(!u&&!h)return;const{point:p}=f,{timestamp:g}=De;this.history.push({...p,timestamp:g});const{onStart:x,onMove:v}=this.handlers;u||(x&&x(this.lastMoveEvent,f),this.startEvent=this.lastMoveEvent),v&&v(this.lastMoveEvent,f)},this.handlePointerMove=(f,u)=>{this.lastMoveEvent=f,this.lastMoveEventInfo=Ia(u,this.transformPagePoint),oe.update(this.updatePoint,!0)},this.handlePointerUp=(f,u)=>{this.end();const{onEnd:h,onSessionEnd:p,resumeAnimation:g}=this.handlers;if(this.dragSnapToOrigin&&g&&g(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const x=za(f.type==="pointercancel"?this.lastMoveEventInfo:Ia(u,this.transformPagePoint),this.history);this.startEvent&&h&&h(f,x),p&&p(f,x)},!_0(t))return;this.dragSnapToOrigin=i,this.handlers=n,this.transformPagePoint=r,this.contextWindow=s||window;const o=Zo(t),a=Ia(o,this.transformPagePoint),{point:l}=a,{timestamp:c}=De;this.history=[{...l,timestamp:c}];const{onSessionStart:d}=n;d&&d(t,za(a,this.history)),this.removeListeners=yn(It(this.contextWindow,"pointermove",this.handlePointerMove),It(this.contextWindow,"pointerup",this.handlePointerUp),It(this.contextWindow,"pointercancel",this.handlePointerUp))}updateHandlers(t){this.handlers=t}end(){this.removeListeners&&this.removeListeners(),Ht(this.updatePoint)}}function Ia(e,t){return t?{point:t(e.point)}:e}function vf(e,t){return{x:e.x-t.x,y:e.y-t.y}}function za({point:e},t){return{point:e,delta:vf(e,mg(t)),offset:vf(e,i3(t)),velocity:o3(t,.1)}}function i3(e){return e[0]}function mg(e){return e[e.length-1]}function o3(e,t){if(e.length<2)return{x:0,y:0};let n=e.length-1,r=null;const s=mg(e);for(;n>=0&&(r=e[n],!(s.timestamp-r.timestamp>Bn(t)));)n--;if(!r)return{x:0,y:0};const i=zt(s.timestamp-r.timestamp);if(i===0)return{x:0,y:0};const o={x:(s.x-r.x)/i,y:(s.y-r.y)/i};return o.x===1/0&&(o.x=0),o.y===1/0&&(o.y=0),o}function Je(e){return e.max-e.min}function tu(e,t=0,n=.01){return Math.abs(e-t)<=n}function xf(e,t,n,r=.5){e.origin=r,e.originPoint=ce(t.min,t.max,e.origin),e.scale=Je(n)/Je(t),(tu(e.scale,1,1e-4)||isNaN(e.scale))&&(e.scale=1),e.translate=ce(n.min,n.max,e.origin)-e.originPoint,(tu(e.translate)||isNaN(e.translate))&&(e.translate=0)}function xs(e,t,n,r){xf(e.x,t.x,n.x,r?r.originX:void 0),xf(e.y,t.y,n.y,r?r.originY:void 0)}function wf(e,t,n){e.min=n.min+t.min,e.max=e.min+Je(t)}function a3(e,t,n){wf(e.x,t.x,n.x),wf(e.y,t.y,n.y)}function bf(e,t,n){e.min=t.min-n.min,e.max=e.min+Je(t)}function ws(e,t,n){bf(e.x,t.x,n.x),bf(e.y,t.y,n.y)}function l3(e,{min:t,max:n},r){return t!==void 0&&en&&(e=r?ce(n,e,r.max):Math.min(e,n)),e}function Sf(e,t,n){return{min:t!==void 0?e.min+t:void 0,max:n!==void 0?e.max+n-(e.max-e.min):void 0}}function u3(e,{top:t,left:n,bottom:r,right:s}){return{x:Sf(e.x,n,s),y:Sf(e.y,t,r)}}function kf(e,t){let n=t.min-e.min,r=t.max-e.max;return t.max-t.minr?n=Ws(t.min,t.max-r,e.min):r>s&&(n=Ws(e.min,e.max-s,t.min)),wn(0,1,n)}function f3(e,t){const n={};return t.min!==void 0&&(n.min=t.min-e.min),t.max!==void 0&&(n.max=t.max-e.min),n}const nu=.35;function h3(e=nu){return e===!1?e=0:e===!0&&(e=nu),{x:Cf(e,"left","right"),y:Cf(e,"top","bottom")}}function Cf(e,t,n){return{min:Pf(e,t),max:Pf(e,n)}}function Pf(e,t){return typeof e=="number"?e:e[t]||0}const jf=()=>({translate:0,scale:1,origin:0,originPoint:0}),gr=()=>({x:jf(),y:jf()}),Ef=()=>({min:0,max:0}),xe=()=>({x:Ef(),y:Ef()});function st(e){return[e("x"),e("y")]}function gg({top:e,left:t,right:n,bottom:r}){return{x:{min:t,max:n},y:{min:e,max:r}}}function p3({x:e,y:t}){return{top:t.min,right:e.max,bottom:t.max,left:e.min}}function m3(e,t){if(!t)return e;const n=t({x:e.left,y:e.top}),r=t({x:e.right,y:e.bottom});return{top:n.y,left:n.x,bottom:r.y,right:r.x}}function Oa(e){return e===void 0||e===1}function ru({scale:e,scaleX:t,scaleY:n}){return!Oa(e)||!Oa(t)||!Oa(n)}function Dn(e){return ru(e)||yg(e)||e.z||e.rotate||e.rotateX||e.rotateY}function yg(e){return Tf(e.x)||Tf(e.y)}function Tf(e){return e&&e!=="0%"}function ko(e,t,n){const r=e-n,s=t*r;return n+s}function Nf(e,t,n,r,s){return s!==void 0&&(e=ko(e,s,r)),ko(e,n,r)+t}function su(e,t=0,n=1,r,s){e.min=Nf(e.min,t,n,r,s),e.max=Nf(e.max,t,n,r,s)}function vg(e,{x:t,y:n}){su(e.x,t.translate,t.scale,t.originPoint),su(e.y,n.translate,n.scale,n.originPoint)}function g3(e,t,n,r=!1){const s=n.length;if(!s)return;t.x=t.y=1;let i,o;for(let a=0;a1.0000000000001||e<.999999999999?e:1}function en(e,t){e.min=e.min+t,e.max=e.max+t}function _f(e,t,[n,r,s]){const i=t[s]!==void 0?t[s]:.5,o=ce(e.min,e.max,i);su(e,t[n],t[r],o,t.scale)}const y3=["x","scaleX","originX"],v3=["y","scaleY","originY"];function yr(e,t){_f(e.x,t,y3),_f(e.y,t,v3)}function xg(e,t){return gg(m3(e.getBoundingClientRect(),t))}function x3(e,t,n){const r=xg(e,n),{scroll:s}=t;return s&&(en(r.x,s.offset.x),en(r.y,s.offset.y)),r}const wg=({current:e})=>e?e.ownerDocument.defaultView:null,w3=new WeakMap;class b3{constructor(t){this.openGlobalLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=xe(),this.visualElement=t}start(t,{snapToCursor:n=!1}={}){const{presenceContext:r}=this.visualElement;if(r&&r.isPresent===!1)return;const s=d=>{const{dragSnapToOrigin:f}=this.getProps();f?this.pauseAnimation():this.stopAnimation(),n&&this.snapToCursor(Zo(d,"page").point)},i=(d,f)=>{const{drag:u,dragPropagation:h,onDragStart:p}=this.getProps();if(u&&!h&&(this.openGlobalLock&&this.openGlobalLock(),this.openGlobalLock=L0(u),!this.openGlobalLock))return;this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),st(x=>{let v=this.getAxisMotionValue(x).get()||0;if(Tt.test(v)){const{projection:y}=this.visualElement;if(y&&y.layout){const w=y.layout.layoutBox[x];w&&(v=Je(w)*(parseFloat(v)/100))}}this.originPoint[x]=v}),p&&oe.update(()=>p(d,f),!1,!0);const{animationState:g}=this.visualElement;g&&g.setActive("whileDrag",!0)},o=(d,f)=>{const{dragPropagation:u,dragDirectionLock:h,onDirectionLock:p,onDrag:g}=this.getProps();if(!u&&!this.openGlobalLock)return;const{offset:x}=f;if(h&&this.currentDirection===null){this.currentDirection=S3(x),this.currentDirection!==null&&p&&p(this.currentDirection);return}this.updateAxis("x",f.point,x),this.updateAxis("y",f.point,x),this.visualElement.render(),g&&g(d,f)},a=(d,f)=>this.stop(d,f),l=()=>st(d=>{var f;return this.getAnimationState(d)==="paused"&&((f=this.getAxisMotionValue(d).animation)===null||f===void 0?void 0:f.play())}),{dragSnapToOrigin:c}=this.getProps();this.panSession=new pg(t,{onSessionStart:s,onStart:i,onMove:o,onSessionEnd:a,resumeAnimation:l},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:c,contextWindow:wg(this.visualElement)})}stop(t,n){const r=this.isDragging;if(this.cancel(),!r)return;const{velocity:s}=n;this.startAnimation(s);const{onDragEnd:i}=this.getProps();i&&oe.update(()=>i(t,n))}cancel(){this.isDragging=!1;const{projection:t,animationState:n}=this.visualElement;t&&(t.isAnimationBlocked=!1),this.panSession&&this.panSession.end(),this.panSession=void 0;const{dragPropagation:r}=this.getProps();!r&&this.openGlobalLock&&(this.openGlobalLock(),this.openGlobalLock=null),n&&n.setActive("whileDrag",!1)}updateAxis(t,n,r){const{drag:s}=this.getProps();if(!r||!Pi(t,s,this.currentDirection))return;const i=this.getAxisMotionValue(t);let o=this.originPoint[t]+r[t];this.constraints&&this.constraints[t]&&(o=l3(o,this.constraints[t],this.elastic[t])),i.set(o)}resolveConstraints(){var t;const{dragConstraints:n,dragElastic:r}=this.getProps(),s=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):(t=this.visualElement.projection)===null||t===void 0?void 0:t.layout,i=this.constraints;n&&pr(n)?this.constraints||(this.constraints=this.resolveRefConstraints()):n&&s?this.constraints=u3(s.layoutBox,n):this.constraints=!1,this.elastic=h3(r),i!==this.constraints&&s&&this.constraints&&!this.hasMutatedConstraints&&st(o=>{this.getAxisMotionValue(o)&&(this.constraints[o]=f3(s.layoutBox[o],this.constraints[o]))})}resolveRefConstraints(){const{dragConstraints:t,onMeasureDragConstraints:n}=this.getProps();if(!t||!pr(t))return!1;const r=t.current,{projection:s}=this.visualElement;if(!s||!s.layout)return!1;const i=x3(r,s.root,this.visualElement.getTransformPagePoint());let o=c3(s.layout.layoutBox,i);if(n){const a=n(p3(o));this.hasMutatedConstraints=!!a,a&&(o=gg(a))}return o}startAnimation(t){const{drag:n,dragMomentum:r,dragElastic:s,dragTransition:i,dragSnapToOrigin:o,onDragTransitionEnd:a}=this.getProps(),l=this.constraints||{},c=st(d=>{if(!Pi(d,n,this.currentDirection))return;let f=l&&l[d]||{};o&&(f={min:0,max:0});const u=s?200:1e6,h=s?40:1e7,p={type:"inertia",velocity:r?t[d]:0,bounceStiffness:u,bounceDamping:h,timeConstant:750,restDelta:1,restSpeed:10,...i,...f};return this.startAxisValueAnimation(d,p)});return Promise.all(c).then(a)}startAxisValueAnimation(t,n){const r=this.getAxisMotionValue(t);return r.start(Ec(t,r,0,n))}stopAnimation(){st(t=>this.getAxisMotionValue(t).stop())}pauseAnimation(){st(t=>{var n;return(n=this.getAxisMotionValue(t).animation)===null||n===void 0?void 0:n.pause()})}getAnimationState(t){var n;return(n=this.getAxisMotionValue(t).animation)===null||n===void 0?void 0:n.state}getAxisMotionValue(t){const n="_drag"+t.toUpperCase(),r=this.visualElement.getProps(),s=r[n];return s||this.visualElement.getValue(t,(r.initial?r.initial[t]:void 0)||0)}snapToCursor(t){st(n=>{const{drag:r}=this.getProps();if(!Pi(n,r,this.currentDirection))return;const{projection:s}=this.visualElement,i=this.getAxisMotionValue(n);if(s&&s.layout){const{min:o,max:a}=s.layout.layoutBox[n];i.set(t[n]-ce(o,a,.5))}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:t,dragConstraints:n}=this.getProps(),{projection:r}=this.visualElement;if(!pr(n)||!r||!this.constraints)return;this.stopAnimation();const s={x:0,y:0};st(o=>{const a=this.getAxisMotionValue(o);if(a){const l=a.get();s[o]=d3({min:l,max:l},this.constraints[o])}});const{transformTemplate:i}=this.visualElement.getProps();this.visualElement.current.style.transform=i?i({},""):"none",r.root&&r.root.updateScroll(),r.updateLayout(),this.resolveConstraints(),st(o=>{if(!Pi(o,t,null))return;const a=this.getAxisMotionValue(o),{min:l,max:c}=this.constraints[o];a.set(ce(l,c,s[o]))})}addListeners(){if(!this.visualElement.current)return;w3.set(this.visualElement,this);const t=this.visualElement.current,n=It(t,"pointerdown",l=>{const{drag:c,dragListener:d=!0}=this.getProps();c&&d&&this.start(l)}),r=()=>{const{dragConstraints:l}=this.getProps();pr(l)&&(this.constraints=this.resolveRefConstraints())},{projection:s}=this.visualElement,i=s.addEventListener("measure",r);s&&!s.layout&&(s.root&&s.root.updateScroll(),s.updateLayout()),r();const o=Vt(window,"resize",()=>this.scalePositionWithinConstraints()),a=s.addEventListener("didUpdate",({delta:l,hasLayoutChanged:c})=>{this.isDragging&&c&&(st(d=>{const f=this.getAxisMotionValue(d);f&&(this.originPoint[d]+=l[d].translate,f.set(f.get()+l[d].translate))}),this.visualElement.render())});return()=>{o(),n(),i(),a&&a()}}getProps(){const t=this.visualElement.getProps(),{drag:n=!1,dragDirectionLock:r=!1,dragPropagation:s=!1,dragConstraints:i=!1,dragElastic:o=nu,dragMomentum:a=!0}=t;return{...t,drag:n,dragDirectionLock:r,dragPropagation:s,dragConstraints:i,dragElastic:o,dragMomentum:a}}}function Pi(e,t,n){return(t===!0||t===e)&&(n===null||n===e)}function S3(e,t=10){let n=null;return Math.abs(e.y)>t?n="y":Math.abs(e.x)>t&&(n="x"),n}class k3 extends Nn{constructor(t){super(t),this.removeGroupControls=ye,this.removeListeners=ye,this.controls=new b3(t)}mount(){const{dragControls:t}=this.node.getProps();t&&(this.removeGroupControls=t.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||ye}unmount(){this.removeGroupControls(),this.removeListeners()}}const Af=e=>(t,n)=>{e&&oe.update(()=>e(t,n))};class C3 extends Nn{constructor(){super(...arguments),this.removePointerDownListener=ye}onPointerDown(t){this.session=new pg(t,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:wg(this.node)})}createPanHandlers(){const{onPanSessionStart:t,onPanStart:n,onPan:r,onPanEnd:s}=this.node.getProps();return{onSessionStart:Af(t),onStart:Af(n),onMove:r,onEnd:(i,o)=>{delete this.session,s&&oe.update(()=>s(i,o))}}}mount(){this.removePointerDownListener=It(this.node.current,"pointerdown",t=>this.onPointerDown(t))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}function P3(){const e=k.useContext(cc);if(e===null)return[!0,null];const{isPresent:t,onExitComplete:n,register:r}=e,s=k.useId();return k.useEffect(()=>r(s),[]),!t&&n?[!1,()=>n&&n(s)]:[!0]}const Bi={hasAnimatedSinceResize:!0,hasEverUpdated:!1};function Lf(e,t){return t.max===t.min?0:e/(t.max-t.min)*100}const es={correct:(e,t)=>{if(!t.target)return e;if(typeof e=="string")if(B.test(e))e=parseFloat(e);else return e;const n=Lf(e,t.target.x),r=Lf(e,t.target.y);return`${n}% ${r}%`}},j3={correct:(e,{treeScale:t,projectionDelta:n})=>{const r=e,s=bn.parse(e);if(s.length>5)return r;const i=bn.createTransformer(e),o=typeof s[0]!="number"?1:0,a=n.x.scale*t.x,l=n.y.scale*t.y;s[0+o]/=a,s[1+o]/=l;const c=ce(a,l,.5);return typeof s[2+o]=="number"&&(s[2+o]/=c),typeof s[3+o]=="number"&&(s[3+o]/=c),i(s)}};class E3 extends Gs.Component{componentDidMount(){const{visualElement:t,layoutGroup:n,switchLayoutGroup:r,layoutId:s}=this.props,{projection:i}=t;L2(T3),i&&(n.group&&n.group.add(i),r&&r.register&&s&&r.register(i),i.root.didUpdate(),i.addEventListener("animationComplete",()=>{this.safeToRemove()}),i.setOptions({...i.options,onExitComplete:()=>this.safeToRemove()})),Bi.hasEverUpdated=!0}getSnapshotBeforeUpdate(t){const{layoutDependency:n,visualElement:r,drag:s,isPresent:i}=this.props,o=r.projection;return o&&(o.isPresent=i,s||t.layoutDependency!==n||n===void 0?o.willUpdate():this.safeToRemove(),t.isPresent!==i&&(i?o.promote():o.relegate()||oe.postRender(()=>{const a=o.getStack();(!a||!a.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{projection:t}=this.props.visualElement;t&&(t.root.didUpdate(),queueMicrotask(()=>{!t.currentAnimation&&t.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:t,layoutGroup:n,switchLayoutGroup:r}=this.props,{projection:s}=t;s&&(s.scheduleCheckAfterUnmount(),n&&n.group&&n.group.remove(s),r&&r.deregister&&r.deregister(s))}safeToRemove(){const{safeToRemove:t}=this.props;t&&t()}render(){return null}}function bg(e){const[t,n]=P3(),r=k.useContext(g0);return Gs.createElement(E3,{...e,layoutGroup:r,switchLayoutGroup:k.useContext(y0),isPresent:t,safeToRemove:n})}const T3={borderRadius:{...es,applyTo:["borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"]},borderTopLeftRadius:es,borderTopRightRadius:es,borderBottomLeftRadius:es,borderBottomRightRadius:es,boxShadow:j3},Sg=["TopLeft","TopRight","BottomLeft","BottomRight"],N3=Sg.length,Df=e=>typeof e=="string"?parseFloat(e):e,Rf=e=>typeof e=="number"||B.test(e);function M3(e,t,n,r,s,i){s?(e.opacity=ce(0,n.opacity!==void 0?n.opacity:1,_3(r)),e.opacityExit=ce(t.opacity!==void 0?t.opacity:1,0,A3(r))):i&&(e.opacity=ce(t.opacity!==void 0?t.opacity:1,n.opacity!==void 0?n.opacity:1,r));for(let o=0;ort?1:n(Ws(e,t,r))}function Ff(e,t){e.min=t.min,e.max=t.max}function rt(e,t){Ff(e.x,t.x),Ff(e.y,t.y)}function If(e,t,n,r,s){return e-=t,e=ko(e,1/n,r),s!==void 0&&(e=ko(e,1/s,r)),e}function L3(e,t=0,n=1,r=.5,s,i=e,o=e){if(Tt.test(t)&&(t=parseFloat(t),t=ce(o.min,o.max,t/100)-o.min),typeof t!="number")return;let a=ce(i.min,i.max,r);e===i&&(a-=t),e.min=If(e.min,t,n,a,s),e.max=If(e.max,t,n,a,s)}function zf(e,t,[n,r,s],i,o){L3(e,t[n],t[r],t[s],t.scale,i,o)}const D3=["x","scaleX","originX"],R3=["y","scaleY","originY"];function Of(e,t,n,r){zf(e.x,t,D3,n?n.x:void 0,r?r.x:void 0),zf(e.y,t,R3,n?n.y:void 0,r?r.y:void 0)}function $f(e){return e.translate===0&&e.scale===1}function Cg(e){return $f(e.x)&&$f(e.y)}function V3(e,t){return e.x.min===t.x.min&&e.x.max===t.x.max&&e.y.min===t.y.min&&e.y.max===t.y.max}function Pg(e,t){return Math.round(e.x.min)===Math.round(t.x.min)&&Math.round(e.x.max)===Math.round(t.x.max)&&Math.round(e.y.min)===Math.round(t.y.min)&&Math.round(e.y.max)===Math.round(t.y.max)}function Bf(e){return Je(e.x)/Je(e.y)}class F3{constructor(){this.members=[]}add(t){Tc(this.members,t),t.scheduleRender()}remove(t){if(Nc(this.members,t),t===this.prevLead&&(this.prevLead=void 0),t===this.lead){const n=this.members[this.members.length-1];n&&this.promote(n)}}relegate(t){const n=this.members.findIndex(s=>t===s);if(n===0)return!1;let r;for(let s=n;s>=0;s--){const i=this.members[s];if(i.isPresent!==!1){r=i;break}}return r?(this.promote(r),!0):!1}promote(t,n){const r=this.lead;if(t!==r&&(this.prevLead=r,this.lead=t,t.show(),r)){r.instance&&r.scheduleRender(),t.scheduleRender(),t.resumeFrom=r,n&&(t.resumeFrom.preserveOpacity=!0),r.snapshot&&(t.snapshot=r.snapshot,t.snapshot.latestValues=r.animationValues||r.latestValues),t.root&&t.root.isUpdating&&(t.isLayoutDirty=!0);const{crossfade:s}=t.options;s===!1&&r.hide()}}exitAnimationComplete(){this.members.forEach(t=>{const{options:n,resumingFrom:r}=t;n.onExitComplete&&n.onExitComplete(),r&&r.options.onExitComplete&&r.options.onExitComplete()})}scheduleRender(){this.members.forEach(t=>{t.instance&&t.scheduleRender(!1)})}removeLeadSnapshot(){this.lead&&this.lead.snapshot&&(this.lead.snapshot=void 0)}}function Uf(e,t,n){let r="";const s=e.x.translate/t.x,i=e.y.translate/t.y;if((s||i)&&(r=`translate3d(${s}px, ${i}px, 0) `),(t.x!==1||t.y!==1)&&(r+=`scale(${1/t.x}, ${1/t.y}) `),n){const{rotate:l,rotateX:c,rotateY:d}=n;l&&(r+=`rotate(${l}deg) `),c&&(r+=`rotateX(${c}deg) `),d&&(r+=`rotateY(${d}deg) `)}const o=e.x.scale*t.x,a=e.y.scale*t.y;return(o!==1||a!==1)&&(r+=`scale(${o}, ${a})`),r||"none"}const I3=(e,t)=>e.depth-t.depth;class z3{constructor(){this.children=[],this.isDirty=!1}add(t){Tc(this.children,t),this.isDirty=!0}remove(t){Nc(this.children,t),this.isDirty=!0}forEach(t){this.isDirty&&this.children.sort(I3),this.isDirty=!1,this.children.forEach(t)}}function O3(e,t){const n=performance.now(),r=({timestamp:s})=>{const i=s-n;i>=t&&(Ht(r),e(i-t))};return oe.read(r,!0),()=>Ht(r)}function $3(e){window.MotionDebug&&window.MotionDebug.record(e)}function B3(e){return e instanceof SVGElement&&e.tagName!=="svg"}function U3(e,t,n){const r=Ge(e)?e:Lr(e);return r.start(Ec("",r,t,n)),r.animation}const Wf=["","X","Y","Z"],W3={visibility:"hidden"},Hf=1e3;let H3=0;const Rn={type:"projectionFrame",totalNodes:0,resolvedTargetDeltas:0,recalculatedProjection:0};function jg({attachResizeListener:e,defaultParent:t,measureScroll:n,checkIsScrollRoot:r,resetTransform:s}){return class{constructor(o={},a=t==null?void 0:t()){this.id=H3++,this.animationId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.updateScheduled=!1,this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,Rn.totalNodes=Rn.resolvedTargetDeltas=Rn.recalculatedProjection=0,this.nodes.forEach(Y3),this.nodes.forEach(J3),this.nodes.forEach(e4),this.nodes.forEach(K3),$3(Rn)},this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=o,this.root=a?a.root||a:this,this.path=a?[...a.path,a]:[],this.parent=a,this.depth=a?a.depth+1:0;for(let l=0;lthis.root.updateBlockedByResize=!1;e(o,()=>{this.root.updateBlockedByResize=!0,f&&f(),f=O3(u,250),Bi.hasAnimatedSinceResize&&(Bi.hasAnimatedSinceResize=!1,this.nodes.forEach(Gf))})}l&&this.root.registerSharedNode(l,this),this.options.animate!==!1&&d&&(l||c)&&this.addEventListener("didUpdate",({delta:f,hasLayoutChanged:u,hasRelativeTargetChanged:h,layout:p})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const g=this.options.transition||d.getDefaultTransition()||i4,{onLayoutAnimationStart:x,onLayoutAnimationComplete:v}=d.getProps(),y=!this.targetLayout||!Pg(this.targetLayout,p)||h,w=!u&&h;if(this.options.layoutRoot||this.resumeFrom&&this.resumeFrom.instance||w||u&&(y||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0),this.setAnimationOrigin(f,w);const b={...jc(g,"layout"),onPlay:x,onComplete:v};(d.shouldReduceMotion||this.options.layoutRoot)&&(b.delay=0,b.type=!1),this.startAnimation(b)}else u||Gf(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=p})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const o=this.getStack();o&&o.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,Ht(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(t4),this.animationId++)}getTransformTemplate(){const{visualElement:o}=this.options;return o&&o.getProps().transformTemplate}willUpdate(o=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let d=0;dthis.update()))}clearAllSnapshots(){this.nodes.forEach(X3),this.sharedNodes.forEach(n4)}scheduleUpdateProjection(){this.projectionUpdateScheduled||(this.projectionUpdateScheduled=!0,oe.preRender(this.updateProjection,!1,!0))}scheduleCheckAfterUnmount(){oe.postRender(()=>{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure())}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let l=0;l{const S=b/1e3;Yf(f.x,o.x,S),Yf(f.y,o.y,S),this.setTargetDelta(f),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(ws(u,this.layout.layoutBox,this.relativeParent.layout.layoutBox),r4(this.relativeTarget,this.relativeTargetOrigin,u,S),w&&V3(this.relativeTarget,w)&&(this.isProjectionDirty=!1),w||(w=xe()),rt(w,this.relativeTarget)),g&&(this.animationValues=d,M3(d,c,this.latestValues,S,y,v)),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=S},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(o){this.notifyListeners("animationStart"),this.currentAnimation&&this.currentAnimation.stop(),this.resumingFrom&&this.resumingFrom.currentAnimation&&this.resumingFrom.currentAnimation.stop(),this.pendingAnimation&&(Ht(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=oe.update(()=>{Bi.hasAnimatedSinceResize=!0,this.currentAnimation=U3(0,Hf,{...o,onUpdate:a=>{this.mixTargetDelta(a),o.onUpdate&&o.onUpdate(a)},onComplete:()=>{o.onComplete&&o.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const o=this.getStack();o&&o.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(Hf),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const o=this.getLead();let{targetWithTransforms:a,target:l,layout:c,latestValues:d}=o;if(!(!a||!l||!c)){if(this!==o&&this.layout&&c&&Eg(this.options.animationType,this.layout.layoutBox,c.layoutBox)){l=this.target||xe();const f=Je(this.layout.layoutBox.x);l.x.min=o.target.x.min,l.x.max=l.x.min+f;const u=Je(this.layout.layoutBox.y);l.y.min=o.target.y.min,l.y.max=l.y.min+u}rt(a,l),yr(a,d),xs(this.projectionDeltaWithTransform,this.layoutCorrected,a,d)}}registerSharedNode(o,a){this.sharedNodes.has(o)||this.sharedNodes.set(o,new F3),this.sharedNodes.get(o).add(a);const c=a.options.initialPromotionConfig;a.promote({transition:c?c.transition:void 0,preserveFollowOpacity:c&&c.shouldPreserveFollowOpacity?c.shouldPreserveFollowOpacity(a):void 0})}isLead(){const o=this.getStack();return o?o.lead===this:!0}getLead(){var o;const{layoutId:a}=this.options;return a?((o=this.getStack())===null||o===void 0?void 0:o.lead)||this:this}getPrevLead(){var o;const{layoutId:a}=this.options;return a?(o=this.getStack())===null||o===void 0?void 0:o.prevLead:void 0}getStack(){const{layoutId:o}=this.options;if(o)return this.root.sharedNodes.get(o)}promote({needsReset:o,transition:a,preserveFollowOpacity:l}={}){const c=this.getStack();c&&c.promote(this,l),o&&(this.projectionDelta=void 0,this.needsReset=!0),a&&this.setOptions({transition:a})}relegate(){const o=this.getStack();return o?o.relegate(this):!1}resetRotation(){const{visualElement:o}=this.options;if(!o)return;let a=!1;const{latestValues:l}=o;if((l.rotate||l.rotateX||l.rotateY||l.rotateZ)&&(a=!0),!a)return;const c={};for(let d=0;d{var a;return(a=o.currentAnimation)===null||a===void 0?void 0:a.stop()}),this.root.nodes.forEach(qf),this.root.sharedNodes.clear()}}}function q3(e){e.updateLayout()}function G3(e){var t;const n=((t=e.resumeFrom)===null||t===void 0?void 0:t.snapshot)||e.snapshot;if(e.isLead()&&e.layout&&n&&e.hasListeners("didUpdate")){const{layoutBox:r,measuredBox:s}=e.layout,{animationType:i}=e.options,o=n.source!==e.layout.source;i==="size"?st(f=>{const u=o?n.measuredBox[f]:n.layoutBox[f],h=Je(u);u.min=r[f].min,u.max=u.min+h}):Eg(i,n.layoutBox,r)&&st(f=>{const u=o?n.measuredBox[f]:n.layoutBox[f],h=Je(r[f]);u.max=u.min+h,e.relativeTarget&&!e.currentAnimation&&(e.isProjectionDirty=!0,e.relativeTarget[f].max=e.relativeTarget[f].min+h)});const a=gr();xs(a,r,n.layoutBox);const l=gr();o?xs(l,e.applyTransform(s,!0),n.measuredBox):xs(l,r,n.layoutBox);const c=!Cg(a);let d=!1;if(!e.resumeFrom){const f=e.getClosestProjectingParent();if(f&&!f.resumeFrom){const{snapshot:u,layout:h}=f;if(u&&h){const p=xe();ws(p,n.layoutBox,u.layoutBox);const g=xe();ws(g,r,h.layoutBox),Pg(p,g)||(d=!0),f.options.layoutRoot&&(e.relativeTarget=g,e.relativeTargetOrigin=p,e.relativeParent=f)}}}e.notifyListeners("didUpdate",{layout:r,snapshot:n,delta:l,layoutDelta:a,hasLayoutChanged:c,hasRelativeTargetChanged:d})}else if(e.isLead()){const{onExitComplete:r}=e.options;r&&r()}e.options.transition=void 0}function Y3(e){Rn.totalNodes++,e.parent&&(e.isProjecting()||(e.isProjectionDirty=e.parent.isProjectionDirty),e.isSharedProjectionDirty||(e.isSharedProjectionDirty=!!(e.isProjectionDirty||e.parent.isProjectionDirty||e.parent.isSharedProjectionDirty)),e.isTransformDirty||(e.isTransformDirty=e.parent.isTransformDirty))}function K3(e){e.isProjectionDirty=e.isSharedProjectionDirty=e.isTransformDirty=!1}function X3(e){e.clearSnapshot()}function qf(e){e.clearMeasurements()}function Q3(e){e.isLayoutDirty=!1}function Z3(e){const{visualElement:t}=e.options;t&&t.getProps().onBeforeLayoutMeasure&&t.notify("BeforeLayoutMeasure"),e.resetTransform()}function Gf(e){e.finishAnimation(),e.targetDelta=e.relativeTarget=e.target=void 0,e.isProjectionDirty=!0}function J3(e){e.resolveTargetDelta()}function e4(e){e.calcProjection()}function t4(e){e.resetRotation()}function n4(e){e.removeLeadSnapshot()}function Yf(e,t,n){e.translate=ce(t.translate,0,n),e.scale=ce(t.scale,1,n),e.origin=t.origin,e.originPoint=t.originPoint}function Kf(e,t,n,r){e.min=ce(t.min,n.min,r),e.max=ce(t.max,n.max,r)}function r4(e,t,n,r){Kf(e.x,t.x,n.x,r),Kf(e.y,t.y,n.y,r)}function s4(e){return e.animationValues&&e.animationValues.opacityExit!==void 0}const i4={duration:.45,ease:[.4,0,.1,1]},Xf=e=>typeof navigator<"u"&&navigator.userAgent.toLowerCase().includes(e),Qf=Xf("applewebkit/")&&!Xf("chrome/")?Math.round:ye;function Zf(e){e.min=Qf(e.min),e.max=Qf(e.max)}function o4(e){Zf(e.x),Zf(e.y)}function Eg(e,t,n){return e==="position"||e==="preserve-aspect"&&!tu(Bf(t),Bf(n),.2)}const a4=jg({attachResizeListener:(e,t)=>Vt(e,"resize",t),measureScroll:()=>({x:document.documentElement.scrollLeft||document.body.scrollLeft,y:document.documentElement.scrollTop||document.body.scrollTop}),checkIsScrollRoot:()=>!0}),$a={current:void 0},Tg=jg({measureScroll:e=>({x:e.scrollLeft,y:e.scrollTop}),defaultParent:()=>{if(!$a.current){const e=new a4({});e.mount(window),e.setOptions({layoutScroll:!0}),$a.current=e}return $a.current},resetTransform:(e,t)=>{e.style.transform=t!==void 0?t:"none"},checkIsScrollRoot:e=>window.getComputedStyle(e).position==="fixed"}),l4={pan:{Feature:C3},drag:{Feature:k3,ProjectionNode:Tg,MeasureLayout:bg}},u4=/var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;function c4(e){const t=u4.exec(e);if(!t)return[,];const[,n,r]=t;return[n,r]}function iu(e,t,n=1){const[r,s]=c4(e);if(!r)return;const i=window.getComputedStyle(t).getPropertyValue(r);if(i){const o=i.trim();return cg(o)?parseFloat(o):o}else return Yl(s)?iu(s,t,n+1):s}function d4(e,{...t},n){const r=e.current;if(!(r instanceof Element))return{target:t,transitionEnd:n};n&&(n={...n}),e.values.forEach(s=>{const i=s.get();if(!Yl(i))return;const o=iu(i,r);o&&s.set(o)});for(const s in t){const i=t[s];if(!Yl(i))continue;const o=iu(i,r);o&&(t[s]=o,n||(n={}),n[s]===void 0&&(n[s]=i))}return{target:t,transitionEnd:n}}const f4=new Set(["width","height","top","left","right","bottom","x","y","translateX","translateY"]),Ng=e=>f4.has(e),h4=e=>Object.keys(e).some(Ng),Jf=e=>e===Zn||e===B,eh=(e,t)=>parseFloat(e.split(", ")[t]),th=(e,t)=>(n,{transform:r})=>{if(r==="none"||!r)return 0;const s=r.match(/^matrix3d\((.+)\)$/);if(s)return eh(s[1],t);{const i=r.match(/^matrix\((.+)\)$/);return i?eh(i[1],e):0}},p4=new Set(["x","y","z"]),m4=Js.filter(e=>!p4.has(e));function g4(e){const t=[];return m4.forEach(n=>{const r=e.getValue(n);r!==void 0&&(t.push([n,r.get()]),r.set(n.startsWith("scale")?1:0))}),t.length&&e.render(),t}const Dr={width:({x:e},{paddingLeft:t="0",paddingRight:n="0"})=>e.max-e.min-parseFloat(t)-parseFloat(n),height:({y:e},{paddingTop:t="0",paddingBottom:n="0"})=>e.max-e.min-parseFloat(t)-parseFloat(n),top:(e,{top:t})=>parseFloat(t),left:(e,{left:t})=>parseFloat(t),bottom:({y:e},{top:t})=>parseFloat(t)+(e.max-e.min),right:({x:e},{left:t})=>parseFloat(t)+(e.max-e.min),x:th(4,13),y:th(5,14)};Dr.translateX=Dr.x;Dr.translateY=Dr.y;const y4=(e,t,n)=>{const r=t.measureViewportBox(),s=t.current,i=getComputedStyle(s),{display:o}=i,a={};o==="none"&&t.setStaticValue("display",e.display||"block"),n.forEach(c=>{a[c]=Dr[c](r,i)}),t.render();const l=t.measureViewportBox();return n.forEach(c=>{const d=t.getValue(c);d&&d.jump(a[c]),e[c]=Dr[c](l,i)}),e},v4=(e,t,n={},r={})=>{t={...t},r={...r};const s=Object.keys(t).filter(Ng);let i=[],o=!1;const a=[];if(s.forEach(l=>{const c=e.getValue(l);if(!e.hasValue(l))return;let d=n[l],f=Jr(d);const u=t[l];let h;if(vo(u)){const p=u.length,g=u[0]===null?1:0;d=u[g],f=Jr(d);for(let x=g;x=0?window.pageYOffset:null,c=y4(t,e,a);return i.length&&i.forEach(([d,f])=>{e.getValue(d).set(f)}),e.render(),Yo&&l!==null&&window.scrollTo({top:l}),{target:c,transitionEnd:r}}else return{target:t,transitionEnd:r}};function x4(e,t,n,r){return h4(t)?v4(e,t,n,r):{target:t,transitionEnd:r}}const w4=(e,t,n,r)=>{const s=d4(e,t,r);return t=s.target,r=s.transitionEnd,x4(e,t,n,r)},ou={current:null},Mg={current:!1};function b4(){if(Mg.current=!0,!!Yo)if(window.matchMedia){const e=window.matchMedia("(prefers-reduced-motion)"),t=()=>ou.current=e.matches;e.addListener(t),t()}else ou.current=!1}function S4(e,t,n){const{willChange:r}=t;for(const s in t){const i=t[s],o=n[s];if(Ge(i))e.addValue(s,i),So(r)&&r.add(s);else if(Ge(o))e.addValue(s,Lr(i,{owner:e})),So(r)&&r.remove(s);else if(o!==i)if(e.hasValue(s)){const a=e.getValue(s);!a.hasAnimated&&a.set(i)}else{const a=e.getStaticValue(s);e.addValue(s,Lr(a!==void 0?a:i,{owner:e}))}}for(const s in n)t[s]===void 0&&e.removeValue(s);return t}const nh=new WeakMap,_g=Object.keys(Us),k4=_g.length,rh=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"],C4=hc.length;class P4{constructor({parent:t,props:n,presenceContext:r,reducedMotionConfig:s,visualState:i},o={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.values=new Map,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.scheduleRender=()=>oe.render(this.render,!1,!0);const{latestValues:a,renderState:l}=i;this.latestValues=a,this.baseTarget={...a},this.initialValues=n.initial?{...a}:{},this.renderState=l,this.parent=t,this.props=n,this.presenceContext=r,this.depth=t?t.depth+1:0,this.reducedMotionConfig=s,this.options=o,this.isControllingVariants=Xo(n),this.isVariantNode=m0(n),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(t&&t.current);const{willChange:c,...d}=this.scrapeMotionValuesFromProps(n,{});for(const f in d){const u=d[f];a[f]!==void 0&&Ge(u)&&(u.set(a[f],!1),So(c)&&c.add(f))}}scrapeMotionValuesFromProps(t,n){return{}}mount(t){this.current=t,nh.set(t,this),this.projection&&!this.projection.instance&&this.projection.mount(t),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach((n,r)=>this.bindToMotionValue(r,n)),Mg.current||b4(),this.shouldReduceMotion=this.reducedMotionConfig==="never"?!1:this.reducedMotionConfig==="always"?!0:ou.current,this.parent&&this.parent.children.add(this),this.update(this.props,this.presenceContext)}unmount(){nh.delete(this.current),this.projection&&this.projection.unmount(),Ht(this.notifyUpdate),Ht(this.render),this.valueSubscriptions.forEach(t=>t()),this.removeFromVariantTree&&this.removeFromVariantTree(),this.parent&&this.parent.children.delete(this);for(const t in this.events)this.events[t].clear();for(const t in this.features)this.features[t].unmount();this.current=null}bindToMotionValue(t,n){const r=Qn.has(t),s=n.on("change",o=>{this.latestValues[t]=o,this.props.onUpdate&&oe.update(this.notifyUpdate,!1,!0),r&&this.projection&&(this.projection.isTransformDirty=!0)}),i=n.on("renderRequest",this.scheduleRender);this.valueSubscriptions.set(t,()=>{s(),i()})}sortNodePosition(t){return!this.current||!this.sortInstanceNodePosition||this.type!==t.type?0:this.sortInstanceNodePosition(this.current,t.current)}loadFeatures({children:t,...n},r,s,i){let o,a;for(let l=0;lthis.scheduleRender(),animationType:typeof c=="string"?c:"both",initialPromotionConfig:i,layoutScroll:u,layoutRoot:h})}return a}updateFeatures(){for(const t in this.features){const n=this.features[t];n.isMounted?n.update():(n.mount(),n.isMounted=!0)}}triggerBuild(){this.build(this.renderState,this.latestValues,this.options,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):xe()}getStaticValue(t){return this.latestValues[t]}setStaticValue(t,n){this.latestValues[t]=n}makeTargetAnimatable(t,n=!0){return this.makeTargetAnimatableFromInstance(t,this.props,n)}update(t,n){(t.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=t,this.prevPresenceContext=this.presenceContext,this.presenceContext=n;for(let r=0;rn.variantChildren.delete(t)}addValue(t,n){n!==this.values.get(t)&&(this.removeValue(t),this.bindToMotionValue(t,n)),this.values.set(t,n),this.latestValues[t]=n.get()}removeValue(t){this.values.delete(t);const n=this.valueSubscriptions.get(t);n&&(n(),this.valueSubscriptions.delete(t)),delete this.latestValues[t],this.removeValueFromRenderState(t,this.renderState)}hasValue(t){return this.values.has(t)}getValue(t,n){if(this.props.values&&this.props.values[t])return this.props.values[t];let r=this.values.get(t);return r===void 0&&n!==void 0&&(r=Lr(n,{owner:this}),this.addValue(t,r)),r}readValue(t){var n;return this.latestValues[t]!==void 0||!this.current?this.latestValues[t]:(n=this.getBaseTargetFromProps(this.props,t))!==null&&n!==void 0?n:this.readValueFromInstance(this.current,t,this.options)}setBaseTarget(t,n){this.baseTarget[t]=n}getBaseTarget(t){var n;const{initial:r}=this.props,s=typeof r=="string"||typeof r=="object"?(n=wc(this.props,r))===null||n===void 0?void 0:n[t]:void 0;if(r&&s!==void 0)return s;const i=this.getBaseTargetFromProps(this.props,t);return i!==void 0&&!Ge(i)?i:this.initialValues[t]!==void 0&&s===void 0?void 0:this.baseTarget[t]}on(t,n){return this.events[t]||(this.events[t]=new Mc),this.events[t].add(n)}notify(t,...n){this.events[t]&&this.events[t].notify(...n)}}class Ag extends P4{sortInstanceNodePosition(t,n){return t.compareDocumentPosition(n)&2?1:-1}getBaseTargetFromProps(t,n){return t.style?t.style[n]:void 0}removeValueFromRenderState(t,{vars:n,style:r}){delete n[t],delete r[t]}makeTargetAnimatableFromInstance({transition:t,transitionEnd:n,...r},{transformValues:s},i){let o=B5(r,t||{},this);if(s&&(n&&(n=s(n)),r&&(r=s(r)),o&&(o=s(o))),i){O5(this,r,o);const a=w4(this,r,o,n);n=a.transitionEnd,r=a.target}return{transition:t,transitionEnd:n,...r}}}function j4(e){return window.getComputedStyle(e)}class E4 extends Ag{constructor(){super(...arguments),this.type="html"}readValueFromInstance(t,n){if(Qn.has(n)){const r=Pc(n);return r&&r.default||0}else{const r=j4(t),s=(w0(n)?r.getPropertyValue(n):r[n])||0;return typeof s=="string"?s.trim():s}}measureInstanceViewportBox(t,{transformPagePoint:n}){return xg(t,n)}build(t,n,r,s){mc(t,n,r,s.transformTemplate)}scrapeMotionValuesFromProps(t,n){return xc(t,n)}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:t}=this.props;Ge(t)&&(this.childSubscription=t.on("change",n=>{this.current&&(this.current.textContent=`${n}`)}))}renderInstance(t,n,r,s){j0(t,n,r,s)}}class T4 extends Ag{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1}getBaseTargetFromProps(t,n){return t[n]}readValueFromInstance(t,n){if(Qn.has(n)){const r=Pc(n);return r&&r.default||0}return n=E0.has(n)?n:dc(n),t.getAttribute(n)}measureInstanceViewportBox(){return xe()}scrapeMotionValuesFromProps(t,n){return N0(t,n)}build(t,n,r,s){yc(t,n,r,this.isSVGTag,s.transformTemplate)}renderInstance(t,n,r,s){T0(t,n,r,s)}mount(t){this.isSVGTag=vc(t.tagName),super.mount(t)}}const N4=(e,t)=>pc(e)?new T4(t,{enableHardwareAcceleration:!1}):new E4(t,{enableHardwareAcceleration:!0}),M4={layout:{ProjectionNode:Tg,MeasureLayout:bg}},_4={...r3,...kw,...l4,...M4},O=_2((e,t)=>cw(e,t,_4,N4)),A4={},sh=e=>{let t;const n=new Set,r=(d,f)=>{const u=typeof d=="function"?d(t):d;if(!Object.is(u,t)){const h=t;t=f??(typeof u!="object"||u===null)?u:Object.assign({},t,u),n.forEach(p=>p(t,h))}},s=()=>t,l={setState:r,getState:s,getInitialState:()=>c,subscribe:d=>(n.add(d),()=>n.delete(d)),destroy:()=>{(A4?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),n.clear()}},c=t=e(r,s,l);return l},L4=e=>e?sh(e):sh;var Lg={exports:{}},Dg={},Rg={exports:{}},Vg={};/** - * @license React - * use-sync-external-store-shim.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Rr=k;function D4(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var R4=typeof Object.is=="function"?Object.is:D4,V4=Rr.useState,F4=Rr.useEffect,I4=Rr.useLayoutEffect,z4=Rr.useDebugValue;function O4(e,t){var n=t(),r=V4({inst:{value:n,getSnapshot:t}}),s=r[0].inst,i=r[1];return I4(function(){s.value=n,s.getSnapshot=t,Ba(s)&&i({inst:s})},[e,n,t]),F4(function(){return Ba(s)&&i({inst:s}),e(function(){Ba(s)&&i({inst:s})})},[e]),z4(n),n}function Ba(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!R4(e,n)}catch{return!0}}function $4(e,t){return t()}var B4=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?$4:O4;Vg.useSyncExternalStore=Rr.useSyncExternalStore!==void 0?Rr.useSyncExternalStore:B4;Rg.exports=Vg;var U4=Rg.exports;/** - * @license React - * use-sync-external-store-shim/with-selector.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var ea=k,W4=U4;function H4(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var q4=typeof Object.is=="function"?Object.is:H4,G4=W4.useSyncExternalStore,Y4=ea.useRef,K4=ea.useEffect,X4=ea.useMemo,Q4=ea.useDebugValue;Dg.useSyncExternalStoreWithSelector=function(e,t,n,r,s){var i=Y4(null);if(i.current===null){var o={hasValue:!1,value:null};i.current=o}else o=i.current;i=X4(function(){function l(h){if(!c){if(c=!0,d=h,h=r(h),s!==void 0&&o.hasValue){var p=o.value;if(s(p,h))return f=p}return f=h}if(p=f,q4(d,h))return p;var g=r(h);return s!==void 0&&s(p,g)?(d=h,p):(d=h,f=g)}var c=!1,d,f,u=n===void 0?null:n;return[function(){return l(t())},u===null?void 0:function(){return l(u())}]},[t,n,r,s]);var a=G4(e,i[0],i[1]);return K4(function(){o.hasValue=!0,o.value=a},[a]),Q4(a),a};Lg.exports=Dg;var Z4=Lg.exports;const J4=cu(Z4),Fg={},{useDebugValue:eb}=Gs,{useSyncExternalStoreWithSelector:tb}=J4;let ih=!1;const nb=e=>e;function rb(e,t=nb,n){(Fg?"production":void 0)!=="production"&&n&&!ih&&(console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"),ih=!0);const r=tb(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return eb(r),r}const sb=e=>{(Fg?"production":void 0)!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?L4(e):e,n=(r,s)=>rb(t,r,s);return Object.assign(n,t),n},ib=e=>sb,ob={};function ab(e,t){let n;try{n=e()}catch{return}return{getItem:s=>{var i;const o=l=>l===null?null:JSON.parse(l,void 0),a=(i=n.getItem(s))!=null?i:null;return a instanceof Promise?a.then(o):o(a)},setItem:(s,i)=>n.setItem(s,JSON.stringify(i,void 0)),removeItem:s=>n.removeItem(s)}}const Hs=e=>t=>{try{const n=e(t);return n instanceof Promise?n:{then(r){return Hs(r)(n)},catch(r){return this}}}catch(n){return{then(r){return this},catch(r){return Hs(r)(n)}}}},lb=(e,t)=>(n,r,s)=>{let i={getStorage:()=>localStorage,serialize:JSON.stringify,deserialize:JSON.parse,partialize:x=>x,version:0,merge:(x,v)=>({...v,...x}),...t},o=!1;const a=new Set,l=new Set;let c;try{c=i.getStorage()}catch{}if(!c)return e((...x)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),n(...x)},r,s);const d=Hs(i.serialize),f=()=>{const x=i.partialize({...r()});let v;const y=d({state:x,version:i.version}).then(w=>c.setItem(i.name,w)).catch(w=>{v=w});if(v)throw v;return y},u=s.setState;s.setState=(x,v)=>{u(x,v),f()};const h=e((...x)=>{n(...x),f()},r,s);let p;const g=()=>{var x;if(!c)return;o=!1,a.forEach(y=>y(r()));const v=((x=i.onRehydrateStorage)==null?void 0:x.call(i,r()))||void 0;return Hs(c.getItem.bind(c))(i.name).then(y=>{if(y)return i.deserialize(y)}).then(y=>{if(y)if(typeof y.version=="number"&&y.version!==i.version){if(i.migrate)return i.migrate(y.state,y.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return y.state}).then(y=>{var w;return p=i.merge(y,(w=r())!=null?w:h),n(p,!0),f()}).then(()=>{v==null||v(p,void 0),o=!0,l.forEach(y=>y(p))}).catch(y=>{v==null||v(void 0,y)})};return s.persist={setOptions:x=>{i={...i,...x},x.getStorage&&(c=x.getStorage())},clearStorage:()=>{c==null||c.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>g(),hasHydrated:()=>o,onHydrate:x=>(a.add(x),()=>{a.delete(x)}),onFinishHydration:x=>(l.add(x),()=>{l.delete(x)})},g(),p||h},ub=(e,t)=>(n,r,s)=>{let i={storage:ab(()=>localStorage),partialize:g=>g,version:0,merge:(g,x)=>({...x,...g}),...t},o=!1;const a=new Set,l=new Set;let c=i.storage;if(!c)return e((...g)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),n(...g)},r,s);const d=()=>{const g=i.partialize({...r()});return c.setItem(i.name,{state:g,version:i.version})},f=s.setState;s.setState=(g,x)=>{f(g,x),d()};const u=e((...g)=>{n(...g),d()},r,s);s.getInitialState=()=>u;let h;const p=()=>{var g,x;if(!c)return;o=!1,a.forEach(y=>{var w;return y((w=r())!=null?w:u)});const v=((x=i.onRehydrateStorage)==null?void 0:x.call(i,(g=r())!=null?g:u))||void 0;return Hs(c.getItem.bind(c))(i.name).then(y=>{if(y)if(typeof y.version=="number"&&y.version!==i.version){if(i.migrate)return[!0,i.migrate(y.state,y.version)];console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,y.state];return[!1,void 0]}).then(y=>{var w;const[b,S]=y;if(h=i.merge(S,(w=r())!=null?w:u),n(h,!0),b)return d()}).then(()=>{v==null||v(h,void 0),h=r(),o=!0,l.forEach(y=>y(h))}).catch(y=>{v==null||v(void 0,y)})};return s.persist={setOptions:g=>{i={...i,...g},g.storage&&(c=g.storage)},clearStorage:()=>{c==null||c.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>p(),hasHydrated:()=>o,onHydrate:g=>(a.add(g),()=>{a.delete(g)}),onFinishHydration:g=>(l.add(g),()=>{l.delete(g)})},i.skipHydration||p(),h||u},cb=(e,t)=>"getStorage"in t||"serialize"in t||"deserialize"in t?((ob?"production":void 0)!=="production"&&console.warn("[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."),lb(e,t)):ub(e,t),db=cb,oh={currentUser:null,partnerUser:null,isLoading:!1,error:null,currentTrack:null,isPlaying:!1},ae=ib()(db(e=>({...oh,mixedPlaylists:[],memoryLane:[],theme:"green",setCurrentUser:t=>e({currentUser:t}),setPartnerUser:t=>e({partnerUser:t}),logout:()=>e({currentUser:null,partnerUser:null,currentTrack:null,isPlaying:!1,mixedPlaylists:[],memoryLane:[],error:null}),setLoading:t=>e({isLoading:t}),setError:t=>e({error:t}),setCurrentTrack:t=>e({currentTrack:t}),setIsPlaying:t=>e({isPlaying:t}),addMixedPlaylist:t=>e(n=>({mixedPlaylists:[...n.mixedPlaylists,t]})),removeMixedPlaylist:t=>e(n=>({mixedPlaylists:n.mixedPlaylists.filter(r=>r.id!==t)})),setMixedPlaylists:t=>e({mixedPlaylists:t}),addMemoryLaneItem:t=>e(n=>({memoryLane:[...n.memoryLane,t].sort((r,s)=>new Date(s.date).getTime()-new Date(r.date).getTime())})),removeMemoryLaneItem:t=>e(n=>({memoryLane:n.memoryLane.filter(r=>r.id!==t)})),setTheme:t=>e({theme:t}),clearAllData:()=>e({...oh,mixedPlaylists:[],memoryLane:[]})}),{name:"spotify-app-settings",partialize:e=>({theme:e.theme})}));function fb(){{const e="/api";try{const t=typeof window<"u"&&window.location.protocol==="https:",n=new URL(e,window.location.origin);if(t&&n.protocol==="http:"&&n.hostname==="159.195.9.107"&&(n.port==="8081"||n.port===""))return"https://159.195.9.107:3443"}catch{}return e}}const Br=fb();function qt(){try{const e=localStorage.getItem("spotify-user");if(!e)return null;const t=JSON.parse(e);return(t==null?void 0:t.jwt)||(t==null?void 0:t.token)||null}catch{return null}}async function Pt(e,t,n){const r=await fetch(`${Br}${e}`,{method:"POST",headers:{"Content-Type":"application/json",...n?{Authorization:`Bearer ${n}`}:qt()?{Authorization:`Bearer ${qt()}`}:{}},body:t?JSON.stringify(t):void 0});if(!r.ok){const s=await r.text();throw new Error(s||`Request failed: ${r.status}`)}return r.json()}async function se(e,t){const n=await fetch(`${Br}${e}`,{headers:{...t?{Authorization:`Bearer ${t}`}:qt()?{Authorization:`Bearer ${qt()}`}:{}}});if(!n.ok){const r=await n.text();throw new Error(r||`Request failed: ${n.status}`)}return n.json()}function hb(e){const t=qt(),n=new URL(`${Br}${e}`,window.location.origin);return t&&n.searchParams.set("token",t),new EventSource(n.toString())}async function pb(e,t,n){const r=await fetch(`${Br}${e}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",...qt()?{Authorization:`Bearer ${qt()}`}:{}},body:new URLSearchParams(t).toString()});if(!r.ok){const s=await r.text();throw new Error(s||`Request failed: ${r.status}`)}return r.json()}async function mb(e,t){const n=await fetch(`${Br}${e}`,{method:"DELETE",headers:{...t?{Authorization:`Bearer ${t}`}:qt()?{Authorization:`Bearer ${qt()}`}:{}}});if(!n.ok){const r=await n.text();throw new Error(r||`Request failed: ${n.status}`)}return n.json()}const Vr=e=>{const t={green:{primary:"bg-theme-green-primary text-white",secondary:"bg-theme-green-secondary text-white",accent:"bg-theme-green-accent text-white",border:"border-theme-green-primary",text:"text-theme-green-primary",gradient:"from-theme-green-primary to-theme-green-secondary",glass:"bg-theme-green-primary/10 border-theme-green-primary/30",hover:"hover:bg-theme-green-primary/20",cssVars:{primary:"#1db954",secondary:"#1ed760",accent:"#00e676"}},pink:{primary:"bg-theme-pink-primary text-white",secondary:"bg-theme-pink-secondary text-white",accent:"bg-theme-pink-accent text-white",border:"border-theme-pink-primary",text:"text-theme-pink-primary",gradient:"from-theme-pink-primary to-theme-pink-secondary",glass:"bg-theme-pink-primary/10 border-theme-pink-primary/30",hover:"hover:bg-theme-pink-primary/20",cssVars:{primary:"#ec4899",secondary:"#f472b6",accent:"#fb7185"}},blue:{primary:"bg-theme-blue-primary text-white",secondary:"bg-theme-blue-secondary text-white",accent:"bg-theme-blue-accent text-white",border:"border-theme-blue-primary",text:"text-theme-blue-primary",gradient:"from-theme-blue-primary to-theme-blue-secondary",glass:"bg-theme-blue-primary/10 border-theme-blue-primary/30",hover:"hover:bg-theme-blue-primary/20",cssVars:{primary:"#3b82f6",secondary:"#60a5fa",accent:"#93c5fd"}},red:{primary:"bg-theme-red-primary text-white",secondary:"bg-theme-red-secondary text-white",accent:"bg-theme-red-accent text-white",border:"border-theme-red-primary",text:"text-theme-red-primary",gradient:"from-theme-red-primary to-theme-red-secondary",glass:"bg-theme-red-primary/10 border-theme-red-primary/30",hover:"hover:bg-theme-red-primary/20",cssVars:{primary:"#dc2626",secondary:"#ef4444",accent:"#f87171"}},purple:{primary:"bg-theme-purple-primary text-white",secondary:"bg-theme-purple-secondary text-white",accent:"bg-theme-purple-accent text-white",border:"border-theme-purple-primary",text:"text-theme-purple-primary",gradient:"from-theme-purple-primary to-theme-purple-secondary",glass:"bg-theme-purple-primary/10 border-theme-purple-primary/30",hover:"hover:bg-theme-purple-primary/20",cssVars:{primary:"#8b5cf6",secondary:"#a78bfa",accent:"#c4b5fd"}},yellow:{primary:"bg-theme-yellow-primary text-black",secondary:"bg-theme-yellow-secondary text-black",accent:"bg-theme-yellow-accent text-black",border:"border-theme-yellow-primary",text:"text-theme-yellow-primary",gradient:"from-theme-yellow-primary to-theme-yellow-secondary",glass:"bg-theme-yellow-primary/10 border-theme-yellow-primary/30",hover:"hover:bg-theme-yellow-primary/20",cssVars:{primary:"#eab308",secondary:"#f59e0b",accent:"#fbbf24"}},turquoise:{primary:"bg-theme-turquoise-primary text-white",secondary:"bg-theme-turquoise-secondary text-white",accent:"bg-theme-turquoise-accent text-white",border:"border-theme-turquoise-primary",text:"text-theme-turquoise-primary",gradient:"from-theme-turquoise-primary to-theme-turquoise-secondary",glass:"bg-theme-turquoise-primary/10 border-theme-turquoise-primary/30",hover:"hover:bg-theme-turquoise-primary/20",cssVars:{primary:"#06b6d4",secondary:"#22d3ee",accent:"#67e8f9"}}},n=t[e]||t.green;if(typeof document<"u"){const r=document.documentElement;r.style.setProperty("--theme-primary",n.cssVars.primary),r.style.setProperty("--theme-secondary",n.cssVars.secondary),r.style.setProperty("--theme-accent",n.cssVars.accent)}return n},ah=e=>({green:120,pink:300,blue:360,red:245,purple:280,yellow:200,turquoise:40})[e]||120;function bs(e){let t=e[0],n=e[1],r=e[2];return Math.sqrt(t*t+n*n+r*r)}function au(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}function gb(e,t,n,r){return e[0]=t,e[1]=n,e[2]=r,e}function lh(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e[2]=t[2]+n[2],e}function uh(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e[2]=t[2]-n[2],e}function yb(e,t,n){return e[0]=t[0]*n[0],e[1]=t[1]*n[1],e[2]=t[2]*n[2],e}function vb(e,t,n){return e[0]=t[0]/n[0],e[1]=t[1]/n[1],e[2]=t[2]/n[2],e}function Ua(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e}function xb(e,t){let n=t[0]-e[0],r=t[1]-e[1],s=t[2]-e[2];return Math.sqrt(n*n+r*r+s*s)}function wb(e,t){let n=t[0]-e[0],r=t[1]-e[1],s=t[2]-e[2];return n*n+r*r+s*s}function ch(e){let t=e[0],n=e[1],r=e[2];return t*t+n*n+r*r}function bb(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e}function Sb(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e}function lu(e,t){let n=t[0],r=t[1],s=t[2],i=n*n+r*r+s*s;return i>0&&(i=1/Math.sqrt(i)),e[0]=t[0]*i,e[1]=t[1]*i,e[2]=t[2]*i,e}function Ig(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function dh(e,t,n){let r=t[0],s=t[1],i=t[2],o=n[0],a=n[1],l=n[2];return e[0]=s*l-i*a,e[1]=i*o-r*l,e[2]=r*a-s*o,e}function kb(e,t,n,r){let s=t[0],i=t[1],o=t[2];return e[0]=s+r*(n[0]-s),e[1]=i+r*(n[1]-i),e[2]=o+r*(n[2]-o),e}function Cb(e,t,n,r,s){const i=Math.exp(-r*s);let o=t[0],a=t[1],l=t[2];return e[0]=n[0]+(o-n[0])*i,e[1]=n[1]+(a-n[1])*i,e[2]=n[2]+(l-n[2])*i,e}function Pb(e,t,n){let r=t[0],s=t[1],i=t[2],o=n[3]*r+n[7]*s+n[11]*i+n[15];return o=o||1,e[0]=(n[0]*r+n[4]*s+n[8]*i+n[12])/o,e[1]=(n[1]*r+n[5]*s+n[9]*i+n[13])/o,e[2]=(n[2]*r+n[6]*s+n[10]*i+n[14])/o,e}function jb(e,t,n){let r=t[0],s=t[1],i=t[2],o=n[3]*r+n[7]*s+n[11]*i+n[15];return o=o||1,e[0]=(n[0]*r+n[4]*s+n[8]*i)/o,e[1]=(n[1]*r+n[5]*s+n[9]*i)/o,e[2]=(n[2]*r+n[6]*s+n[10]*i)/o,e}function Eb(e,t,n){let r=t[0],s=t[1],i=t[2];return e[0]=r*n[0]+s*n[3]+i*n[6],e[1]=r*n[1]+s*n[4]+i*n[7],e[2]=r*n[2]+s*n[5]+i*n[8],e}function Tb(e,t,n){let r=t[0],s=t[1],i=t[2],o=n[0],a=n[1],l=n[2],c=n[3],d=a*i-l*s,f=l*r-o*i,u=o*s-a*r,h=a*u-l*f,p=l*d-o*u,g=o*f-a*d,x=c*2;return d*=x,f*=x,u*=x,h*=2,p*=2,g*=2,e[0]=r+d+h,e[1]=s+f+p,e[2]=i+u+g,e}const Nb=function(){const e=[0,0,0],t=[0,0,0];return function(n,r){au(e,n),au(t,r),lu(e,e),lu(t,t);let s=Ig(e,t);return s>1?0:s<-1?Math.PI:Math.acos(s)}}();function Mb(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]}class mt extends Array{constructor(t=0,n=t,r=t){return super(t,n,r),this}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}set x(t){this[0]=t}set y(t){this[1]=t}set z(t){this[2]=t}set(t,n=t,r=t){return t.length?this.copy(t):(gb(this,t,n,r),this)}copy(t){return au(this,t),this}add(t,n){return n?lh(this,t,n):lh(this,this,t),this}sub(t,n){return n?uh(this,t,n):uh(this,this,t),this}multiply(t){return t.length?yb(this,this,t):Ua(this,this,t),this}divide(t){return t.length?vb(this,this,t):Ua(this,this,1/t),this}inverse(t=this){return Sb(this,t),this}len(){return bs(this)}distance(t){return t?xb(this,t):bs(this)}squaredLen(){return ch(this)}squaredDistance(t){return t?wb(this,t):ch(this)}negate(t=this){return bb(this,t),this}cross(t,n){return n?dh(this,t,n):dh(this,this,t),this}scale(t){return Ua(this,this,t),this}normalize(){return lu(this,this),this}dot(t){return Ig(this,t)}equals(t){return Mb(this,t)}applyMatrix3(t){return Eb(this,this,t),this}applyMatrix4(t){return Pb(this,this,t),this}scaleRotateMatrix4(t){return jb(this,this,t),this}applyQuaternion(t){return Tb(this,this,t),this}angle(t){return Nb(this,t)}lerp(t,n){return kb(this,this,t,n),this}smoothLerp(t,n,r){return Cb(this,this,t,n,r),this}clone(){return new mt(this[0],this[1],this[2])}fromArray(t,n=0){return this[0]=t[n],this[1]=t[n+1],this[2]=t[n+2],this}toArray(t=[],n=0){return t[n]=this[0],t[n+1]=this[1],t[n+2]=this[2],t}transformDirection(t){const n=this[0],r=this[1],s=this[2];return this[0]=t[0]*n+t[4]*r+t[8]*s,this[1]=t[1]*n+t[5]*r+t[9]*s,this[2]=t[2]*n+t[6]*r+t[10]*s,this.normalize()}}const fh=new mt;let _b=1,Ab=1,hh=!1;class Lb{constructor(t,n={}){t.canvas||console.error("gl not passed as first argument to Geometry"),this.gl=t,this.attributes=n,this.id=_b++,this.VAOs={},this.drawRange={start:0,count:0},this.instancedCount=0,this.gl.renderer.bindVertexArray(null),this.gl.renderer.currentGeometry=null,this.glState=this.gl.renderer.state;for(let r in n)this.addAttribute(r,n[r])}addAttribute(t,n){if(this.attributes[t]=n,n.id=Ab++,n.size=n.size||1,n.type=n.type||(n.data.constructor===Float32Array?this.gl.FLOAT:n.data.constructor===Uint16Array?this.gl.UNSIGNED_SHORT:this.gl.UNSIGNED_INT),n.target=t==="index"?this.gl.ELEMENT_ARRAY_BUFFER:this.gl.ARRAY_BUFFER,n.normalized=n.normalized||!1,n.stride=n.stride||0,n.offset=n.offset||0,n.count=n.count||(n.stride?n.data.byteLength/n.stride:n.data.length/n.size),n.divisor=n.instanced||0,n.needsUpdate=!1,n.usage=n.usage||this.gl.STATIC_DRAW,n.buffer||this.updateAttribute(n),n.divisor){if(this.isInstanced=!0,this.instancedCount&&this.instancedCount!==n.count*n.divisor)return console.warn("geometry has multiple instanced buffers of different length"),this.instancedCount=Math.min(this.instancedCount,n.count*n.divisor);this.instancedCount=n.count*n.divisor}else t==="index"?this.drawRange.count=n.count:this.attributes.index||(this.drawRange.count=Math.max(this.drawRange.count,n.count))}updateAttribute(t){const n=!t.buffer;n&&(t.buffer=this.gl.createBuffer()),this.glState.boundBuffer!==t.buffer&&(this.gl.bindBuffer(t.target,t.buffer),this.glState.boundBuffer=t.buffer),n?this.gl.bufferData(t.target,t.data,t.usage):this.gl.bufferSubData(t.target,0,t.data),t.needsUpdate=!1}setIndex(t){this.addAttribute("index",t)}setDrawRange(t,n){this.drawRange.start=t,this.drawRange.count=n}setInstancedCount(t){this.instancedCount=t}createVAO(t){this.VAOs[t.attributeOrder]=this.gl.renderer.createVertexArray(),this.gl.renderer.bindVertexArray(this.VAOs[t.attributeOrder]),this.bindAttributes(t)}bindAttributes(t){t.attributeLocations.forEach((n,{name:r,type:s})=>{if(!this.attributes[r]){console.warn(`active attribute ${r} not being supplied`);return}const i=this.attributes[r];this.gl.bindBuffer(i.target,i.buffer),this.glState.boundBuffer=i.buffer;let o=1;s===35674&&(o=2),s===35675&&(o=3),s===35676&&(o=4);const a=i.size/o,l=o===1?0:o*o*4,c=o===1?0:o*4;for(let d=0;d{const a=this.attributes[o];a.needsUpdate&&this.updateAttribute(a)});let r=2;((s=this.attributes.index)==null?void 0:s.type)===this.gl.UNSIGNED_INT&&(r=4),this.isInstanced?this.attributes.index?this.gl.renderer.drawElementsInstanced(n,this.drawRange.count,this.attributes.index.type,this.attributes.index.offset+this.drawRange.start*r,this.instancedCount):this.gl.renderer.drawArraysInstanced(n,this.drawRange.start,this.drawRange.count,this.instancedCount):this.attributes.index?this.gl.drawElements(n,this.drawRange.count,this.attributes.index.type,this.attributes.index.offset+this.drawRange.start*r):this.gl.drawArrays(n,this.drawRange.start,this.drawRange.count)}getPosition(){const t=this.attributes.position;if(t.data)return t;if(!hh)return console.warn("No position buffer data found to compute bounds"),hh=!0}computeBoundingBox(t){t||(t=this.getPosition());const n=t.data,r=t.size;this.bounds||(this.bounds={min:new mt,max:new mt,center:new mt,scale:new mt,radius:1/0});const s=this.bounds.min,i=this.bounds.max,o=this.bounds.center,a=this.bounds.scale;s.set(1/0),i.set(-1/0);for(let l=0,c=n.length;l{let o=this.uniforms[i.uniformName];for(const a of i.nameComponents){if(!o)break;if(a in o)o=o[a];else{if(Array.isArray(o.value))break;o=void 0;break}}if(!o)return gh(`Active uniform ${i.name} has not been supplied`);if(o&&o.value===void 0)return gh(`${i.name} uniform is missing a value parameter`);if(o.value.texture)return n=n+1,o.value.update(n),Wa(this.gl,i.type,s,n);if(o.value.length&&o.value[0].texture){const a=[];return o.value.forEach(l=>{n=n+1,l.update(n),a.push(n)}),Wa(this.gl,i.type,s,a)}Wa(this.gl,i.type,s,o.value)}),this.applyState(),t&&this.gl.renderer.setFrontFace(this.frontFace===this.gl.CCW?this.gl.CW:this.gl.CCW)}remove(){this.gl.deleteProgram(this.program)}}function Wa(e,t,n,r){r=r.length?Vb(r):r;const s=e.renderer.state.uniformLocations.get(n);if(r.length)if(s===void 0||s.length!==r.length)e.renderer.state.uniformLocations.set(n,r.slice(0));else{if(Fb(s,r))return;s.set?s.set(r):Ib(s,r),e.renderer.state.uniformLocations.set(n,s)}else{if(s===r)return;e.renderer.state.uniformLocations.set(n,r)}switch(t){case 5126:return r.length?e.uniform1fv(n,r):e.uniform1f(n,r);case 35664:return e.uniform2fv(n,r);case 35665:return e.uniform3fv(n,r);case 35666:return e.uniform4fv(n,r);case 35670:case 5124:case 35678:case 36306:case 35680:case 36289:return r.length?e.uniform1iv(n,r):e.uniform1i(n,r);case 35671:case 35667:return e.uniform2iv(n,r);case 35672:case 35668:return e.uniform3iv(n,r);case 35673:case 35669:return e.uniform4iv(n,r);case 35674:return e.uniformMatrix2fv(n,!1,r);case 35675:return e.uniformMatrix3fv(n,!1,r);case 35676:return e.uniformMatrix4fv(n,!1,r)}}function mh(e){let t=e.split(` -`);for(let n=0;n100||(console.warn(e),Ha++,Ha>100&&console.warn("More than 100 program warnings - stopping logs."))}const qa=new mt;let zb=1;class Ob{constructor({canvas:t=document.createElement("canvas"),width:n=300,height:r=150,dpr:s=1,alpha:i=!1,depth:o=!0,stencil:a=!1,antialias:l=!1,premultipliedAlpha:c=!1,preserveDrawingBuffer:d=!1,powerPreference:f="default",autoClear:u=!0,webgl:h=2}={}){const p={alpha:i,depth:o,stencil:a,antialias:l,premultipliedAlpha:c,preserveDrawingBuffer:d,powerPreference:f};this.dpr=s,this.alpha=i,this.color=!0,this.depth=o,this.stencil=a,this.premultipliedAlpha=c,this.autoClear=u,this.id=zb++,h===2&&(this.gl=t.getContext("webgl2",p)),this.isWebgl2=!!this.gl,this.gl||(this.gl=t.getContext("webgl",p)),this.gl||console.error("unable to create webgl context"),this.gl.renderer=this,this.setSize(n,r),this.state={},this.state.blendFunc={src:this.gl.ONE,dst:this.gl.ZERO},this.state.blendEquation={modeRGB:this.gl.FUNC_ADD},this.state.cullFace=!1,this.state.frontFace=this.gl.CCW,this.state.depthMask=!0,this.state.depthFunc=this.gl.LEQUAL,this.state.premultiplyAlpha=!1,this.state.flipY=!1,this.state.unpackAlignment=4,this.state.framebuffer=null,this.state.viewport={x:0,y:0,width:null,height:null},this.state.textureUnits=[],this.state.activeTextureUnit=0,this.state.boundBuffer=null,this.state.uniformLocations=new Map,this.state.currentProgram=null,this.extensions={},this.isWebgl2?(this.getExtension("EXT_color_buffer_float"),this.getExtension("OES_texture_float_linear")):(this.getExtension("OES_texture_float"),this.getExtension("OES_texture_float_linear"),this.getExtension("OES_texture_half_float"),this.getExtension("OES_texture_half_float_linear"),this.getExtension("OES_element_index_uint"),this.getExtension("OES_standard_derivatives"),this.getExtension("EXT_sRGB"),this.getExtension("WEBGL_depth_texture"),this.getExtension("WEBGL_draw_buffers")),this.getExtension("WEBGL_compressed_texture_astc"),this.getExtension("EXT_texture_compression_bptc"),this.getExtension("WEBGL_compressed_texture_s3tc"),this.getExtension("WEBGL_compressed_texture_etc1"),this.getExtension("WEBGL_compressed_texture_pvrtc"),this.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),this.vertexAttribDivisor=this.getExtension("ANGLE_instanced_arrays","vertexAttribDivisor","vertexAttribDivisorANGLE"),this.drawArraysInstanced=this.getExtension("ANGLE_instanced_arrays","drawArraysInstanced","drawArraysInstancedANGLE"),this.drawElementsInstanced=this.getExtension("ANGLE_instanced_arrays","drawElementsInstanced","drawElementsInstancedANGLE"),this.createVertexArray=this.getExtension("OES_vertex_array_object","createVertexArray","createVertexArrayOES"),this.bindVertexArray=this.getExtension("OES_vertex_array_object","bindVertexArray","bindVertexArrayOES"),this.deleteVertexArray=this.getExtension("OES_vertex_array_object","deleteVertexArray","deleteVertexArrayOES"),this.drawBuffers=this.getExtension("WEBGL_draw_buffers","drawBuffers","drawBuffersWEBGL"),this.parameters={},this.parameters.maxTextureUnits=this.gl.getParameter(this.gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),this.parameters.maxAnisotropy=this.getExtension("EXT_texture_filter_anisotropic")?this.gl.getParameter(this.getExtension("EXT_texture_filter_anisotropic").MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}setSize(t,n){this.width=t,this.height=n,this.gl.canvas.width=t*this.dpr,this.gl.canvas.height=n*this.dpr,this.gl.canvas.style&&Object.assign(this.gl.canvas.style,{width:t+"px",height:n+"px"})}setViewport(t,n,r=0,s=0){this.state.viewport.width===t&&this.state.viewport.height===n||(this.state.viewport.width=t,this.state.viewport.height=n,this.state.viewport.x=r,this.state.viewport.y=s,this.gl.viewport(r,s,t,n))}setScissor(t,n,r=0,s=0){this.gl.scissor(r,s,t,n)}enable(t){this.state[t]!==!0&&(this.gl.enable(t),this.state[t]=!0)}disable(t){this.state[t]!==!1&&(this.gl.disable(t),this.state[t]=!1)}setBlendFunc(t,n,r,s){this.state.blendFunc.src===t&&this.state.blendFunc.dst===n&&this.state.blendFunc.srcAlpha===r&&this.state.blendFunc.dstAlpha===s||(this.state.blendFunc.src=t,this.state.blendFunc.dst=n,this.state.blendFunc.srcAlpha=r,this.state.blendFunc.dstAlpha=s,r!==void 0?this.gl.blendFuncSeparate(t,n,r,s):this.gl.blendFunc(t,n))}setBlendEquation(t,n){t=t||this.gl.FUNC_ADD,!(this.state.blendEquation.modeRGB===t&&this.state.blendEquation.modeAlpha===n)&&(this.state.blendEquation.modeRGB=t,this.state.blendEquation.modeAlpha=n,n!==void 0?this.gl.blendEquationSeparate(t,n):this.gl.blendEquation(t))}setCullFace(t){this.state.cullFace!==t&&(this.state.cullFace=t,this.gl.cullFace(t))}setFrontFace(t){this.state.frontFace!==t&&(this.state.frontFace=t,this.gl.frontFace(t))}setDepthMask(t){this.state.depthMask!==t&&(this.state.depthMask=t,this.gl.depthMask(t))}setDepthFunc(t){this.state.depthFunc!==t&&(this.state.depthFunc=t,this.gl.depthFunc(t))}setStencilMask(t){this.state.stencilMask!==t&&(this.state.stencilMask=t,this.gl.stencilMask(t))}setStencilFunc(t,n,r){this.state.stencilFunc===t&&this.state.stencilRef===n&&this.state.stencilFuncMask===r||(this.state.stencilFunc=t||this.gl.ALWAYS,this.state.stencilRef=n||0,this.state.stencilFuncMask=r||0,this.gl.stencilFunc(t||this.gl.ALWAYS,n||0,r||0))}setStencilOp(t,n,r){this.state.stencilFail===t&&this.state.stencilDepthFail===n&&this.state.stencilDepthPass===r||(this.state.stencilFail=t,this.state.stencilDepthFail=n,this.state.stencilDepthPass=r,this.gl.stencilOp(t,n,r))}activeTexture(t){this.state.activeTextureUnit!==t&&(this.state.activeTextureUnit=t,this.gl.activeTexture(this.gl.TEXTURE0+t))}bindFramebuffer({target:t=this.gl.FRAMEBUFFER,buffer:n=null}={}){this.state.framebuffer!==n&&(this.state.framebuffer=n,this.gl.bindFramebuffer(t,n))}getExtension(t,n,r){return n&&this.gl[n]?this.gl[n].bind(this.gl):(this.extensions[t]||(this.extensions[t]=this.gl.getExtension(t)),n?this.extensions[t]?this.extensions[t][r].bind(this.extensions[t]):null:this.extensions[t])}sortOpaque(t,n){return t.renderOrder!==n.renderOrder?t.renderOrder-n.renderOrder:t.program.id!==n.program.id?t.program.id-n.program.id:t.zDepth!==n.zDepth?t.zDepth-n.zDepth:n.id-t.id}sortTransparent(t,n){return t.renderOrder!==n.renderOrder?t.renderOrder-n.renderOrder:t.zDepth!==n.zDepth?n.zDepth-t.zDepth:n.id-t.id}sortUI(t,n){return t.renderOrder!==n.renderOrder?t.renderOrder-n.renderOrder:t.program.id!==n.program.id?t.program.id-n.program.id:n.id-t.id}getRenderList({scene:t,camera:n,frustumCull:r,sort:s}){let i=[];if(n&&r&&n.updateFrustum(),t.traverse(o=>{if(!o.visible)return!0;o.draw&&(r&&o.frustumCulled&&n&&!n.frustumIntersectsMesh(o)||i.push(o))}),s){const o=[],a=[],l=[];i.forEach(c=>{c.program.transparent?c.program.depthTest?a.push(c):l.push(c):o.push(c),c.zDepth=0,!(c.renderOrder!==0||!c.program.depthTest||!n)&&(c.worldMatrix.getTranslation(qa),qa.applyMatrix4(n.projectionViewMatrix),c.zDepth=qa.z)}),o.sort(this.sortOpaque),a.sort(this.sortTransparent),l.sort(this.sortUI),i=o.concat(a,l)}return i}render({scene:t,camera:n,target:r=null,update:s=!0,sort:i=!0,frustumCull:o=!0,clear:a}){r===null?(this.bindFramebuffer(),this.setViewport(this.width*this.dpr,this.height*this.dpr)):(this.bindFramebuffer(r),this.setViewport(r.width,r.height)),(a||this.autoClear&&a!==!1)&&(this.depth&&(!r||r.depth)&&(this.enable(this.gl.DEPTH_TEST),this.setDepthMask(!0)),(this.stencil||!r||r.stencil)&&(this.enable(this.gl.STENCIL_TEST),this.setStencilMask(255)),this.gl.clear((this.color?this.gl.COLOR_BUFFER_BIT:0)|(this.depth?this.gl.DEPTH_BUFFER_BIT:0)|(this.stencil?this.gl.STENCIL_BUFFER_BIT:0))),s&&t.updateMatrixWorld(),n&&n.updateMatrixWorld(),this.getRenderList({scene:t,camera:n,frustumCull:o,sort:i}).forEach(c=>{c.draw({camera:n})})}}function $b(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}function Bb(e,t,n,r,s){return e[0]=t,e[1]=n,e[2]=r,e[3]=s,e}function Ub(e,t){let n=t[0],r=t[1],s=t[2],i=t[3],o=n*n+r*r+s*s+i*i;return o>0&&(o=1/Math.sqrt(o)),e[0]=n*o,e[1]=r*o,e[2]=s*o,e[3]=i*o,e}function Wb(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]}function Hb(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}function qb(e,t,n){n=n*.5;let r=Math.sin(n);return e[0]=r*t[0],e[1]=r*t[1],e[2]=r*t[2],e[3]=Math.cos(n),e}function yh(e,t,n){let r=t[0],s=t[1],i=t[2],o=t[3],a=n[0],l=n[1],c=n[2],d=n[3];return e[0]=r*d+o*a+s*c-i*l,e[1]=s*d+o*l+i*a-r*c,e[2]=i*d+o*c+r*l-s*a,e[3]=o*d-r*a-s*l-i*c,e}function Gb(e,t,n){n*=.5;let r=t[0],s=t[1],i=t[2],o=t[3],a=Math.sin(n),l=Math.cos(n);return e[0]=r*l+o*a,e[1]=s*l+i*a,e[2]=i*l-s*a,e[3]=o*l-r*a,e}function Yb(e,t,n){n*=.5;let r=t[0],s=t[1],i=t[2],o=t[3],a=Math.sin(n),l=Math.cos(n);return e[0]=r*l-i*a,e[1]=s*l+o*a,e[2]=i*l+r*a,e[3]=o*l-s*a,e}function Kb(e,t,n){n*=.5;let r=t[0],s=t[1],i=t[2],o=t[3],a=Math.sin(n),l=Math.cos(n);return e[0]=r*l+s*a,e[1]=s*l-r*a,e[2]=i*l+o*a,e[3]=o*l-i*a,e}function Xb(e,t,n,r){let s=t[0],i=t[1],o=t[2],a=t[3],l=n[0],c=n[1],d=n[2],f=n[3],u,h,p,g,x;return h=s*l+i*c+o*d+a*f,h<0&&(h=-h,l=-l,c=-c,d=-d,f=-f),1-h>1e-6?(u=Math.acos(h),p=Math.sin(u),g=Math.sin((1-r)*u)/p,x=Math.sin(r*u)/p):(g=1-r,x=r),e[0]=g*s+x*l,e[1]=g*i+x*c,e[2]=g*o+x*d,e[3]=g*a+x*f,e}function Qb(e,t){let n=t[0],r=t[1],s=t[2],i=t[3],o=n*n+r*r+s*s+i*i,a=o?1/o:0;return e[0]=-n*a,e[1]=-r*a,e[2]=-s*a,e[3]=i*a,e}function Zb(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e}function Jb(e,t){let n=t[0]+t[4]+t[8],r;if(n>0)r=Math.sqrt(n+1),e[3]=.5*r,r=.5/r,e[0]=(t[5]-t[7])*r,e[1]=(t[6]-t[2])*r,e[2]=(t[1]-t[3])*r;else{let s=0;t[4]>t[0]&&(s=1),t[8]>t[s*3+s]&&(s=2);let i=(s+1)%3,o=(s+2)%3;r=Math.sqrt(t[s*3+s]-t[i*3+i]-t[o*3+o]+1),e[s]=.5*r,r=.5/r,e[3]=(t[i*3+o]-t[o*3+i])*r,e[i]=(t[i*3+s]+t[s*3+i])*r,e[o]=(t[o*3+s]+t[s*3+o])*r}return e}function eS(e,t,n="YXZ"){let r=Math.sin(t[0]*.5),s=Math.cos(t[0]*.5),i=Math.sin(t[1]*.5),o=Math.cos(t[1]*.5),a=Math.sin(t[2]*.5),l=Math.cos(t[2]*.5);return n==="XYZ"?(e[0]=r*o*l+s*i*a,e[1]=s*i*l-r*o*a,e[2]=s*o*a+r*i*l,e[3]=s*o*l-r*i*a):n==="YXZ"?(e[0]=r*o*l+s*i*a,e[1]=s*i*l-r*o*a,e[2]=s*o*a-r*i*l,e[3]=s*o*l+r*i*a):n==="ZXY"?(e[0]=r*o*l-s*i*a,e[1]=s*i*l+r*o*a,e[2]=s*o*a+r*i*l,e[3]=s*o*l-r*i*a):n==="ZYX"?(e[0]=r*o*l-s*i*a,e[1]=s*i*l+r*o*a,e[2]=s*o*a-r*i*l,e[3]=s*o*l+r*i*a):n==="YZX"?(e[0]=r*o*l+s*i*a,e[1]=s*i*l+r*o*a,e[2]=s*o*a-r*i*l,e[3]=s*o*l-r*i*a):n==="XZY"&&(e[0]=r*o*l-s*i*a,e[1]=s*i*l-r*o*a,e[2]=s*o*a+r*i*l,e[3]=s*o*l+r*i*a),e}const tS=$b,nS=Bb,rS=Wb,sS=Ub;class iS extends Array{constructor(t=0,n=0,r=0,s=1){super(t,n,r,s),this.onChange=()=>{},this._target=this;const i=["0","1","2","3"];return new Proxy(this,{set(o,a){const l=Reflect.set(...arguments);return l&&i.includes(a)&&o.onChange(),l}})}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}get w(){return this[3]}set x(t){this._target[0]=t,this.onChange()}set y(t){this._target[1]=t,this.onChange()}set z(t){this._target[2]=t,this.onChange()}set w(t){this._target[3]=t,this.onChange()}identity(){return Hb(this._target),this.onChange(),this}set(t,n,r,s){return t.length?this.copy(t):(nS(this._target,t,n,r,s),this.onChange(),this)}rotateX(t){return Gb(this._target,this._target,t),this.onChange(),this}rotateY(t){return Yb(this._target,this._target,t),this.onChange(),this}rotateZ(t){return Kb(this._target,this._target,t),this.onChange(),this}inverse(t=this._target){return Qb(this._target,t),this.onChange(),this}conjugate(t=this._target){return Zb(this._target,t),this.onChange(),this}copy(t){return tS(this._target,t),this.onChange(),this}normalize(t=this._target){return sS(this._target,t),this.onChange(),this}multiply(t,n){return n?yh(this._target,t,n):yh(this._target,this._target,t),this.onChange(),this}dot(t){return rS(this._target,t)}fromMatrix3(t){return Jb(this._target,t),this.onChange(),this}fromEuler(t,n){return eS(this._target,t,t.order),n||this.onChange(),this}fromAxisAngle(t,n){return qb(this._target,t,n),this.onChange(),this}slerp(t,n){return Xb(this._target,this._target,t,n),this.onChange(),this}fromArray(t,n=0){return this._target[0]=t[n],this._target[1]=t[n+1],this._target[2]=t[n+2],this._target[3]=t[n+3],this.onChange(),this}toArray(t=[],n=0){return t[n]=this[0],t[n+1]=this[1],t[n+2]=this[2],t[n+3]=this[3],t}}const oS=1e-6;function aS(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function lS(e,t,n,r,s,i,o,a,l,c,d,f,u,h,p,g,x){return e[0]=t,e[1]=n,e[2]=r,e[3]=s,e[4]=i,e[5]=o,e[6]=a,e[7]=l,e[8]=c,e[9]=d,e[10]=f,e[11]=u,e[12]=h,e[13]=p,e[14]=g,e[15]=x,e}function uS(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function cS(e,t){let n=t[0],r=t[1],s=t[2],i=t[3],o=t[4],a=t[5],l=t[6],c=t[7],d=t[8],f=t[9],u=t[10],h=t[11],p=t[12],g=t[13],x=t[14],v=t[15],y=n*a-r*o,w=n*l-s*o,b=n*c-i*o,S=r*l-s*a,C=r*c-i*a,P=s*c-i*l,j=d*g-f*p,D=d*x-u*p,T=d*v-h*p,z=f*x-u*g,V=f*v-h*g,U=u*v-h*x,R=y*U-w*V+b*z+S*T-C*D+P*j;return R?(R=1/R,e[0]=(a*U-l*V+c*z)*R,e[1]=(s*V-r*U-i*z)*R,e[2]=(g*P-x*C+v*S)*R,e[3]=(u*C-f*P-h*S)*R,e[4]=(l*T-o*U-c*D)*R,e[5]=(n*U-s*T+i*D)*R,e[6]=(x*b-p*P-v*w)*R,e[7]=(d*P-u*b+h*w)*R,e[8]=(o*V-a*T+c*j)*R,e[9]=(r*T-n*V-i*j)*R,e[10]=(p*C-g*b+v*y)*R,e[11]=(f*b-d*C-h*y)*R,e[12]=(a*D-o*z-l*j)*R,e[13]=(n*z-r*D+s*j)*R,e[14]=(g*w-p*S-x*y)*R,e[15]=(d*S-f*w+u*y)*R,e):null}function zg(e){let t=e[0],n=e[1],r=e[2],s=e[3],i=e[4],o=e[5],a=e[6],l=e[7],c=e[8],d=e[9],f=e[10],u=e[11],h=e[12],p=e[13],g=e[14],x=e[15],v=t*o-n*i,y=t*a-r*i,w=t*l-s*i,b=n*a-r*o,S=n*l-s*o,C=r*l-s*a,P=c*p-d*h,j=c*g-f*h,D=c*x-u*h,T=d*g-f*p,z=d*x-u*p,V=f*x-u*g;return v*V-y*z+w*T+b*D-S*j+C*P}function vh(e,t,n){let r=t[0],s=t[1],i=t[2],o=t[3],a=t[4],l=t[5],c=t[6],d=t[7],f=t[8],u=t[9],h=t[10],p=t[11],g=t[12],x=t[13],v=t[14],y=t[15],w=n[0],b=n[1],S=n[2],C=n[3];return e[0]=w*r+b*a+S*f+C*g,e[1]=w*s+b*l+S*u+C*x,e[2]=w*i+b*c+S*h+C*v,e[3]=w*o+b*d+S*p+C*y,w=n[4],b=n[5],S=n[6],C=n[7],e[4]=w*r+b*a+S*f+C*g,e[5]=w*s+b*l+S*u+C*x,e[6]=w*i+b*c+S*h+C*v,e[7]=w*o+b*d+S*p+C*y,w=n[8],b=n[9],S=n[10],C=n[11],e[8]=w*r+b*a+S*f+C*g,e[9]=w*s+b*l+S*u+C*x,e[10]=w*i+b*c+S*h+C*v,e[11]=w*o+b*d+S*p+C*y,w=n[12],b=n[13],S=n[14],C=n[15],e[12]=w*r+b*a+S*f+C*g,e[13]=w*s+b*l+S*u+C*x,e[14]=w*i+b*c+S*h+C*v,e[15]=w*o+b*d+S*p+C*y,e}function dS(e,t,n){let r=n[0],s=n[1],i=n[2],o,a,l,c,d,f,u,h,p,g,x,v;return t===e?(e[12]=t[0]*r+t[4]*s+t[8]*i+t[12],e[13]=t[1]*r+t[5]*s+t[9]*i+t[13],e[14]=t[2]*r+t[6]*s+t[10]*i+t[14],e[15]=t[3]*r+t[7]*s+t[11]*i+t[15]):(o=t[0],a=t[1],l=t[2],c=t[3],d=t[4],f=t[5],u=t[6],h=t[7],p=t[8],g=t[9],x=t[10],v=t[11],e[0]=o,e[1]=a,e[2]=l,e[3]=c,e[4]=d,e[5]=f,e[6]=u,e[7]=h,e[8]=p,e[9]=g,e[10]=x,e[11]=v,e[12]=o*r+d*s+p*i+t[12],e[13]=a*r+f*s+g*i+t[13],e[14]=l*r+u*s+x*i+t[14],e[15]=c*r+h*s+v*i+t[15]),e}function fS(e,t,n){let r=n[0],s=n[1],i=n[2];return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*s,e[5]=t[5]*s,e[6]=t[6]*s,e[7]=t[7]*s,e[8]=t[8]*i,e[9]=t[9]*i,e[10]=t[10]*i,e[11]=t[11]*i,e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function hS(e,t,n,r){let s=r[0],i=r[1],o=r[2],a=Math.hypot(s,i,o),l,c,d,f,u,h,p,g,x,v,y,w,b,S,C,P,j,D,T,z,V,U,R,Q;return Math.abs(a)0?(v=Math.sqrt(x+1)*2,t[3]=.25*v,t[0]=(u-p)/v,t[1]=(h-c)/v,t[2]=(l-d)/v):a>f&&a>g?(v=Math.sqrt(1+a-f-g)*2,t[3]=(u-p)/v,t[0]=.25*v,t[1]=(l+d)/v,t[2]=(h+c)/v):f>g?(v=Math.sqrt(1+f-a-g)*2,t[3]=(h-c)/v,t[0]=(l+d)/v,t[1]=.25*v,t[2]=(u+p)/v):(v=Math.sqrt(1+g-a-f)*2,t[3]=(l-d)/v,t[0]=(h+c)/v,t[1]=(u+p)/v,t[2]=.25*v),t}}();function gS(e,t,n,r){let s=bs([e[0],e[1],e[2]]);const i=bs([e[4],e[5],e[6]]),o=bs([e[8],e[9],e[10]]);zg(e)<0&&(s=-s),n[0]=e[12],n[1]=e[13],n[2]=e[14];const l=e.slice(),c=1/s,d=1/i,f=1/o;l[0]*=c,l[1]*=c,l[2]*=c,l[4]*=d,l[5]*=d,l[6]*=d,l[8]*=f,l[9]*=f,l[10]*=f,$g(t,l),r[0]=s,r[1]=i,r[2]=o}function yS(e,t,n,r){const s=e,i=t[0],o=t[1],a=t[2],l=t[3],c=i+i,d=o+o,f=a+a,u=i*c,h=i*d,p=i*f,g=o*d,x=o*f,v=a*f,y=l*c,w=l*d,b=l*f,S=r[0],C=r[1],P=r[2];return s[0]=(1-(g+v))*S,s[1]=(h+b)*S,s[2]=(p-w)*S,s[3]=0,s[4]=(h-b)*C,s[5]=(1-(u+v))*C,s[6]=(x+y)*C,s[7]=0,s[8]=(p+w)*P,s[9]=(x-y)*P,s[10]=(1-(u+g))*P,s[11]=0,s[12]=n[0],s[13]=n[1],s[14]=n[2],s[15]=1,s}function vS(e,t){let n=t[0],r=t[1],s=t[2],i=t[3],o=n+n,a=r+r,l=s+s,c=n*o,d=r*o,f=r*a,u=s*o,h=s*a,p=s*l,g=i*o,x=i*a,v=i*l;return e[0]=1-f-p,e[1]=d+v,e[2]=u-x,e[3]=0,e[4]=d-v,e[5]=1-c-p,e[6]=h+g,e[7]=0,e[8]=u+x,e[9]=h-g,e[10]=1-c-f,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function xS(e,t,n,r,s){let i=1/Math.tan(t/2),o=1/(r-s);return e[0]=i/n,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=(s+r)*o,e[11]=-1,e[12]=0,e[13]=0,e[14]=2*s*r*o,e[15]=0,e}function wS(e,t,n,r,s,i,o){let a=1/(t-n),l=1/(r-s),c=1/(i-o);return e[0]=-2*a,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*c,e[11]=0,e[12]=(t+n)*a,e[13]=(s+r)*l,e[14]=(o+i)*c,e[15]=1,e}function bS(e,t,n,r){let s=t[0],i=t[1],o=t[2],a=r[0],l=r[1],c=r[2],d=s-n[0],f=i-n[1],u=o-n[2],h=d*d+f*f+u*u;h===0?u=1:(h=1/Math.sqrt(h),d*=h,f*=h,u*=h);let p=l*u-c*f,g=c*d-a*u,x=a*f-l*d;return h=p*p+g*g+x*x,h===0&&(c?a+=1e-6:l?c+=1e-6:l+=1e-6,p=l*u-c*f,g=c*d-a*u,x=a*f-l*d,h=p*p+g*g+x*x),h=1/Math.sqrt(h),p*=h,g*=h,x*=h,e[0]=p,e[1]=g,e[2]=x,e[3]=0,e[4]=f*x-u*g,e[5]=u*p-d*x,e[6]=d*g-f*p,e[7]=0,e[8]=d,e[9]=f,e[10]=u,e[11]=0,e[12]=s,e[13]=i,e[14]=o,e[15]=1,e}function xh(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e[2]=t[2]+n[2],e[3]=t[3]+n[3],e[4]=t[4]+n[4],e[5]=t[5]+n[5],e[6]=t[6]+n[6],e[7]=t[7]+n[7],e[8]=t[8]+n[8],e[9]=t[9]+n[9],e[10]=t[10]+n[10],e[11]=t[11]+n[11],e[12]=t[12]+n[12],e[13]=t[13]+n[13],e[14]=t[14]+n[14],e[15]=t[15]+n[15],e}function wh(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e[2]=t[2]-n[2],e[3]=t[3]-n[3],e[4]=t[4]-n[4],e[5]=t[5]-n[5],e[6]=t[6]-n[6],e[7]=t[7]-n[7],e[8]=t[8]-n[8],e[9]=t[9]-n[9],e[10]=t[10]-n[10],e[11]=t[11]-n[11],e[12]=t[12]-n[12],e[13]=t[13]-n[13],e[14]=t[14]-n[14],e[15]=t[15]-n[15],e}function SS(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e[4]=t[4]*n,e[5]=t[5]*n,e[6]=t[6]*n,e[7]=t[7]*n,e[8]=t[8]*n,e[9]=t[9]*n,e[10]=t[10]*n,e[11]=t[11]*n,e[12]=t[12]*n,e[13]=t[13]*n,e[14]=t[14]*n,e[15]=t[15]*n,e}class Co extends Array{constructor(t=1,n=0,r=0,s=0,i=0,o=1,a=0,l=0,c=0,d=0,f=1,u=0,h=0,p=0,g=0,x=1){return super(t,n,r,s,i,o,a,l,c,d,f,u,h,p,g,x),this}get x(){return this[12]}get y(){return this[13]}get z(){return this[14]}get w(){return this[15]}set x(t){this[12]=t}set y(t){this[13]=t}set z(t){this[14]=t}set w(t){this[15]=t}set(t,n,r,s,i,o,a,l,c,d,f,u,h,p,g,x){return t.length?this.copy(t):(lS(this,t,n,r,s,i,o,a,l,c,d,f,u,h,p,g,x),this)}translate(t,n=this){return dS(this,n,t),this}rotate(t,n,r=this){return hS(this,r,t,n),this}scale(t,n=this){return fS(this,n,typeof t=="number"?[t,t,t]:t),this}add(t,n){return n?xh(this,t,n):xh(this,this,t),this}sub(t,n){return n?wh(this,t,n):wh(this,this,t),this}multiply(t,n){return t.length?n?vh(this,t,n):vh(this,this,t):SS(this,this,t),this}identity(){return uS(this),this}copy(t){return aS(this,t),this}fromPerspective({fov:t,aspect:n,near:r,far:s}={}){return xS(this,t,n,r,s),this}fromOrthogonal({left:t,right:n,bottom:r,top:s,near:i,far:o}){return wS(this,t,n,r,s,i,o),this}fromQuaternion(t){return vS(this,t),this}setPosition(t){return this.x=t[0],this.y=t[1],this.z=t[2],this}inverse(t=this){return cS(this,t),this}compose(t,n,r){return yS(this,t,n,r),this}decompose(t,n,r){return gS(this,t,n,r),this}getRotation(t){return $g(t,this),this}getTranslation(t){return pS(t,this),this}getScaling(t){return Og(t,this),this}getMaxScaleOnAxis(){return mS(this)}lookAt(t,n,r){return bS(this,t,n,r),this}determinant(){return zg(this)}fromArray(t,n=0){return this[0]=t[n],this[1]=t[n+1],this[2]=t[n+2],this[3]=t[n+3],this[4]=t[n+4],this[5]=t[n+5],this[6]=t[n+6],this[7]=t[n+7],this[8]=t[n+8],this[9]=t[n+9],this[10]=t[n+10],this[11]=t[n+11],this[12]=t[n+12],this[13]=t[n+13],this[14]=t[n+14],this[15]=t[n+15],this}toArray(t=[],n=0){return t[n]=this[0],t[n+1]=this[1],t[n+2]=this[2],t[n+3]=this[3],t[n+4]=this[4],t[n+5]=this[5],t[n+6]=this[6],t[n+7]=this[7],t[n+8]=this[8],t[n+9]=this[9],t[n+10]=this[10],t[n+11]=this[11],t[n+12]=this[12],t[n+13]=this[13],t[n+14]=this[14],t[n+15]=this[15],t}}function kS(e,t,n="YXZ"){return n==="XYZ"?(e[1]=Math.asin(Math.min(Math.max(t[8],-1),1)),Math.abs(t[8])<.99999?(e[0]=Math.atan2(-t[9],t[10]),e[2]=Math.atan2(-t[4],t[0])):(e[0]=Math.atan2(t[6],t[5]),e[2]=0)):n==="YXZ"?(e[0]=Math.asin(-Math.min(Math.max(t[9],-1),1)),Math.abs(t[9])<.99999?(e[1]=Math.atan2(t[8],t[10]),e[2]=Math.atan2(t[1],t[5])):(e[1]=Math.atan2(-t[2],t[0]),e[2]=0)):n==="ZXY"?(e[0]=Math.asin(Math.min(Math.max(t[6],-1),1)),Math.abs(t[6])<.99999?(e[1]=Math.atan2(-t[2],t[10]),e[2]=Math.atan2(-t[4],t[5])):(e[1]=0,e[2]=Math.atan2(t[1],t[0]))):n==="ZYX"?(e[1]=Math.asin(-Math.min(Math.max(t[2],-1),1)),Math.abs(t[2])<.99999?(e[0]=Math.atan2(t[6],t[10]),e[2]=Math.atan2(t[1],t[0])):(e[0]=0,e[2]=Math.atan2(-t[4],t[5]))):n==="YZX"?(e[2]=Math.asin(Math.min(Math.max(t[1],-1),1)),Math.abs(t[1])<.99999?(e[0]=Math.atan2(-t[9],t[5]),e[1]=Math.atan2(-t[2],t[0])):(e[0]=0,e[1]=Math.atan2(t[8],t[10]))):n==="XZY"&&(e[2]=Math.asin(-Math.min(Math.max(t[4],-1),1)),Math.abs(t[4])<.99999?(e[0]=Math.atan2(t[6],t[5]),e[1]=Math.atan2(t[8],t[0])):(e[0]=Math.atan2(-t[9],t[10]),e[1]=0)),e}const bh=new Co;class CS extends Array{constructor(t=0,n=t,r=t,s="YXZ"){super(t,n,r),this.order=s,this.onChange=()=>{},this._target=this;const i=["0","1","2"];return new Proxy(this,{set(o,a){const l=Reflect.set(...arguments);return l&&i.includes(a)&&o.onChange(),l}})}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}set x(t){this._target[0]=t,this.onChange()}set y(t){this._target[1]=t,this.onChange()}set z(t){this._target[2]=t,this.onChange()}set(t,n=t,r=t){return t.length?this.copy(t):(this._target[0]=t,this._target[1]=n,this._target[2]=r,this.onChange(),this)}copy(t){return this._target[0]=t[0],this._target[1]=t[1],this._target[2]=t[2],this.onChange(),this}reorder(t){return this._target.order=t,this.onChange(),this}fromRotationMatrix(t,n=this.order){return kS(this._target,t,n),this.onChange(),this}fromQuaternion(t,n=this.order,r){return bh.fromQuaternion(t),this._target.fromRotationMatrix(bh,n),r||this.onChange(),this}fromArray(t,n=0){return this._target[0]=t[n],this._target[1]=t[n+1],this._target[2]=t[n+2],this}toArray(t=[],n=0){return t[n]=this[0],t[n+1]=this[1],t[n+2]=this[2],t}}class PS{constructor(){this.parent=null,this.children=[],this.visible=!0,this.matrix=new Co,this.worldMatrix=new Co,this.matrixAutoUpdate=!0,this.worldMatrixNeedsUpdate=!1,this.position=new mt,this.quaternion=new iS,this.scale=new mt(1),this.rotation=new CS,this.up=new mt(0,1,0),this.rotation._target.onChange=()=>this.quaternion.fromEuler(this.rotation,!0),this.quaternion._target.onChange=()=>this.rotation.fromQuaternion(this.quaternion,void 0,!0)}setParent(t,n=!0){this.parent&&t!==this.parent&&this.parent.removeChild(this,!1),this.parent=t,n&&t&&t.addChild(this,!1)}addChild(t,n=!0){~this.children.indexOf(t)||this.children.push(t),n&&t.setParent(this,!1)}removeChild(t,n=!0){~this.children.indexOf(t)&&this.children.splice(this.children.indexOf(t),1),n&&t.setParent(null,!1)}updateMatrixWorld(t){this.matrixAutoUpdate&&this.updateMatrix(),(this.worldMatrixNeedsUpdate||t)&&(this.parent===null?this.worldMatrix.copy(this.matrix):this.worldMatrix.multiply(this.parent.worldMatrix,this.matrix),this.worldMatrixNeedsUpdate=!1,t=!0);for(let n=0,r=this.children.length;nr&&r({mesh:this,camera:t}));let n=this.program.cullFace&&this.worldMatrix.determinant()<0;this.program.use({flipFaces:n}),this.geometry.draw({mode:this.mode,program:this.program}),this.afterRenderCallbacks.forEach(r=>r&&r({mesh:this,camera:t}))}}function zS(e,t){return e[0]=t[0],e[1]=t[1],e}function OS(e,t,n){return e[0]=t,e[1]=n,e}function kh(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function Ch(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function $S(e,t,n){return e[0]=t[0]*n[0],e[1]=t[1]*n[1],e}function BS(e,t,n){return e[0]=t[0]/n[0],e[1]=t[1]/n[1],e}function Ga(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function US(e,t){var n=t[0]-e[0],r=t[1]-e[1];return Math.sqrt(n*n+r*r)}function WS(e,t){var n=t[0]-e[0],r=t[1]-e[1];return n*n+r*r}function Ph(e){var t=e[0],n=e[1];return Math.sqrt(t*t+n*n)}function HS(e){var t=e[0],n=e[1];return t*t+n*n}function qS(e,t){return e[0]=-t[0],e[1]=-t[1],e}function GS(e,t){return e[0]=1/t[0],e[1]=1/t[1],e}function YS(e,t){var n=t[0],r=t[1],s=n*n+r*r;return s>0&&(s=1/Math.sqrt(s)),e[0]=t[0]*s,e[1]=t[1]*s,e}function KS(e,t){return e[0]*t[0]+e[1]*t[1]}function jh(e,t){return e[0]*t[1]-e[1]*t[0]}function XS(e,t,n,r){var s=t[0],i=t[1];return e[0]=s+r*(n[0]-s),e[1]=i+r*(n[1]-i),e}function QS(e,t,n,r,s){const i=Math.exp(-r*s);let o=t[0],a=t[1];return e[0]=n[0]+(o-n[0])*i,e[1]=n[1]+(a-n[1])*i,e}function ZS(e,t,n){var r=t[0],s=t[1];return e[0]=n[0]*r+n[3]*s+n[6],e[1]=n[1]*r+n[4]*s+n[7],e}function JS(e,t,n){let r=t[0],s=t[1];return e[0]=n[0]*r+n[4]*s+n[12],e[1]=n[1]*r+n[5]*s+n[13],e}function ek(e,t){return e[0]===t[0]&&e[1]===t[1]}class _c extends Array{constructor(t=0,n=t){return super(t,n),this}get x(){return this[0]}get y(){return this[1]}set x(t){this[0]=t}set y(t){this[1]=t}set(t,n=t){return t.length?this.copy(t):(OS(this,t,n),this)}copy(t){return zS(this,t),this}add(t,n){return n?kh(this,t,n):kh(this,this,t),this}sub(t,n){return n?Ch(this,t,n):Ch(this,this,t),this}multiply(t){return t.length?$S(this,this,t):Ga(this,this,t),this}divide(t){return t.length?BS(this,this,t):Ga(this,this,1/t),this}inverse(t=this){return GS(this,t),this}len(){return Ph(this)}distance(t){return t?US(this,t):Ph(this)}squaredLen(){return this.squaredDistance()}squaredDistance(t){return t?WS(this,t):HS(this)}negate(t=this){return qS(this,t),this}cross(t,n){return n?jh(t,n):jh(this,t)}scale(t){return Ga(this,this,t),this}normalize(){return YS(this,this),this}dot(t){return KS(this,t)}equals(t){return ek(this,t)}applyMatrix3(t){return ZS(this,this,t),this}applyMatrix4(t){return JS(this,this,t),this}lerp(t,n){return XS(this,this,t,n),this}smoothLerp(t,n,r){return QS(this,this,t,n,r),this}clone(){return new _c(this[0],this[1])}fromArray(t,n=0){return this[0]=t[n],this[1]=t[n+1],this}toArray(t=[],n=0){return t[n]=this[0],t[n+1]=this[1],t}}class tk extends Lb{constructor(t,{attributes:n={}}={}){Object.assign(n,{position:{size:2,data:new Float32Array([-1,-1,3,-1,-1,3])},uv:{size:2,data:new Float32Array([0,0,2,0,0,2])}}),super(t,n)}}const nk=` -attribute vec2 position; -void main(){gl_Position=vec4(position,0.0,1.0);} -`,rk=` -#ifdef GL_ES -precision lowp float; -#endif -uniform vec2 uResolution; -uniform float uTime; -uniform float uHueShift; -uniform float uNoise; -uniform float uScan; -uniform float uScanFreq; -uniform float uWarp; -#define iTime uTime -#define iResolution uResolution - -vec4 buf[8]; -float rand(vec2 c){return fract(sin(dot(c,vec2(12.9898,78.233)))*43758.5453);} - -mat3 rgb2yiq=mat3(0.299,0.587,0.114,0.596,-0.274,-0.322,0.211,-0.523,0.312); -mat3 yiq2rgb=mat3(1.0,0.956,0.621,1.0,-0.272,-0.647,1.0,-1.106,1.703); - -vec3 hueShiftRGB(vec3 col,float deg){ - vec3 yiq=rgb2yiq*col; - float rad=radians(deg); - float cosh=cos(rad),sinh=sin(rad); - vec3 yiqShift=vec3(yiq.x,yiq.y*cosh-yiq.z*sinh,yiq.y*sinh+yiq.z*cosh); - return clamp(yiq2rgb*yiqShift,0.0,1.0); -} - -vec4 sigmoid(vec4 x){return 1./(1.+exp(-x));} - -vec4 cppn_fn(vec2 coordinate,float in0,float in1,float in2){ - buf[6]=vec4(coordinate.x,coordinate.y,0.3948333106474662+in0,0.36+in1); - buf[7]=vec4(0.14+in2,sqrt(coordinate.x*coordinate.x+coordinate.y*coordinate.y),0.,0.); - buf[0]=mat4(vec4(6.5404263,-3.6126034,0.7590882,-1.13613),vec4(2.4582713,3.1660357,1.2219609,0.06276096),vec4(-5.478085,-6.159632,1.8701609,-4.7742867),vec4(6.039214,-5.542865,-0.90925294,3.251348))*buf[6]+mat4(vec4(0.8473259,-5.722911,3.975766,1.6522468),vec4(-0.24321538,0.5839259,-1.7661959,-5.350116),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(0.21808943,1.1243913,-1.7969975,5.0294676); - buf[1]=mat4(vec4(-3.3522482,-6.0612736,0.55641043,-4.4719114),vec4(0.8631464,1.7432913,5.643898,1.6106541),vec4(2.4941394,-3.5012043,1.7184316,6.357333),vec4(3.310376,8.209261,1.1355612,-1.165539))*buf[6]+mat4(vec4(5.24046,-13.034365,0.009859298,15.870829),vec4(2.987511,3.129433,-0.89023495,-1.6822904),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(-5.9457836,-6.573602,-0.8812491,1.5436668); - buf[0]=sigmoid(buf[0]);buf[1]=sigmoid(buf[1]); - buf[2]=mat4(vec4(-15.219568,8.095543,-2.429353,-1.9381982),vec4(-5.951362,4.3115187,2.6393783,1.274315),vec4(-7.3145227,6.7297835,5.2473326,5.9411426),vec4(5.0796127,8.979051,-1.7278991,-1.158976))*buf[6]+mat4(vec4(-11.967154,-11.608155,6.1486754,11.237008),vec4(2.124141,-6.263192,-1.7050359,-0.7021966),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(-4.17164,-3.2281182,-4.576417,-3.6401186); - buf[3]=mat4(vec4(3.1832156,-13.738922,1.879223,3.233465),vec4(0.64300746,12.768129,1.9141049,0.50990224),vec4(-0.049295485,4.4807224,1.4733979,1.801449),vec4(5.0039253,13.000481,3.3991797,-4.5561905))*buf[6]+mat4(vec4(-0.1285731,7.720628,-3.1425676,4.742367),vec4(0.6393625,3.714393,-0.8108378,-0.39174938),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(-1.1811101,-21.621881,0.7851888,1.2329718); - buf[2]=sigmoid(buf[2]);buf[3]=sigmoid(buf[3]); - buf[4]=mat4(vec4(5.214916,-7.183024,2.7228765,2.6592617),vec4(-5.601878,-25.3591,4.067988,0.4602802),vec4(-10.57759,24.286327,21.102104,37.546658),vec4(4.3024497,-1.9625226,2.3458803,-1.372816))*buf[0]+mat4(vec4(-17.6526,-10.507558,2.2587414,12.462782),vec4(6.265566,-502.75443,-12.642513,0.9112289),vec4(-10.983244,20.741234,-9.701768,-0.7635988),vec4(5.383626,1.4819539,-4.1911616,-4.8444734))*buf[1]+mat4(vec4(12.785233,-16.345072,-0.39901125,1.7955981),vec4(-30.48365,-1.8345358,1.4542528,-1.1118771),vec4(19.872723,-7.337935,-42.941723,-98.52709),vec4(8.337645,-2.7312303,-2.2927687,-36.142323))*buf[2]+mat4(vec4(-16.298317,3.5471997,-0.44300047,-9.444417),vec4(57.5077,-35.609753,16.163465,-4.1534753),vec4(-0.07470326,-3.8656476,-7.0901804,3.1523974),vec4(-12.559385,-7.077619,1.490437,-0.8211543))*buf[3]+vec4(-7.67914,15.927437,1.3207729,-1.6686112); - buf[5]=mat4(vec4(-1.4109162,-0.372762,-3.770383,-21.367174),vec4(-6.2103205,-9.35908,0.92529047,8.82561),vec4(11.460242,-22.348068,13.625772,-18.693201),vec4(-0.3429052,-3.9905605,-2.4626114,-0.45033523))*buf[0]+mat4(vec4(7.3481627,-4.3661838,-6.3037653,-3.868115),vec4(1.5462853,6.5488915,1.9701879,-0.58291394),vec4(6.5858274,-2.2180402,3.7127688,-1.3730392),vec4(-5.7973905,10.134961,-2.3395722,-5.965605))*buf[1]+mat4(vec4(-2.5132585,-6.6685553,-1.4029363,-0.16285264),vec4(-0.37908727,0.53738135,4.389061,-1.3024765),vec4(-0.70647055,2.0111287,-5.1659346,-3.728635),vec4(-13.562562,10.487719,-0.9173751,-2.6487076))*buf[2]+mat4(vec4(-8.645013,6.5546675,-6.3944063,-5.5933375),vec4(-0.57783127,-1.077275,36.91025,5.736769),vec4(14.283112,3.7146652,7.1452246,-4.5958776),vec4(2.7192075,3.6021907,-4.366337,-2.3653464))*buf[3]+vec4(-5.9000807,-4.329569,1.2427121,8.59503); - buf[4]=sigmoid(buf[4]);buf[5]=sigmoid(buf[5]); - buf[6]=mat4(vec4(-1.61102,0.7970257,1.4675229,0.20917463),vec4(-28.793737,-7.1390953,1.5025433,4.656581),vec4(-10.94861,39.66238,0.74318546,-10.095605),vec4(-0.7229728,-1.5483948,0.7301322,2.1687684))*buf[0]+mat4(vec4(3.2547753,21.489103,-1.0194173,-3.3100595),vec4(-3.7316632,-3.3792162,-7.223193,-0.23685838),vec4(13.1804495,0.7916005,5.338587,5.687114),vec4(-4.167605,-17.798311,-6.815736,-1.6451967))*buf[1]+mat4(vec4(0.604885,-7.800309,-7.213122,-2.741014),vec4(-3.522382,-0.12359311,-0.5258442,0.43852118),vec4(9.6752825,-22.853785,2.062431,0.099892326),vec4(-4.3196306,-17.730087,2.5184598,5.30267))*buf[2]+mat4(vec4(-6.545563,-15.790176,-6.0438633,-5.415399),vec4(-43.591583,28.551912,-16.00161,18.84728),vec4(4.212382,8.394307,3.0958717,8.657522),vec4(-5.0237565,-4.450633,-4.4768,-5.5010443))*buf[3]+mat4(vec4(1.6985557,-67.05806,6.897715,1.9004834),vec4(1.8680354,2.3915145,2.5231109,4.081538),vec4(11.158006,1.7294737,2.0738268,7.386411),vec4(-4.256034,-306.24686,8.258898,-17.132736))*buf[4]+mat4(vec4(1.6889864,-4.5852966,3.8534803,-6.3482175),vec4(1.3543309,-1.2640043,9.932754,2.9079645),vec4(-5.2770967,0.07150358,-0.13962056,3.3269649),vec4(28.34703,-4.918278,6.1044083,4.085355))*buf[5]+vec4(6.6818056,12.522166,-3.7075126,-4.104386); - buf[7]=mat4(vec4(-8.265602,-4.7027016,5.098234,0.7509808),vec4(8.6507845,-17.15949,16.51939,-8.884479),vec4(-4.036479,-2.3946867,-2.6055532,-1.9866527),vec4(-2.2167742,-1.8135649,-5.9759874,4.8846445))*buf[0]+mat4(vec4(6.7790847,3.5076547,-2.8191125,-2.7028968),vec4(-5.743024,-0.27844876,1.4958696,-5.0517144),vec4(13.122226,15.735168,-2.9397483,-4.101023),vec4(-14.375265,-5.030483,-6.2599335,2.9848232))*buf[1]+mat4(vec4(4.0950394,-0.94011575,-5.674733,4.755022),vec4(4.3809423,4.8310084,1.7425908,-3.437416),vec4(2.117492,0.16342592,-104.56341,16.949184),vec4(-5.22543,-2.994248,3.8350096,-1.9364246))*buf[2]+mat4(vec4(-5.900337,1.7946124,-13.604192,-3.8060522),vec4(6.6583457,31.911177,25.164474,91.81147),vec4(11.840538,4.1503043,-0.7314397,6.768467),vec4(-6.3967767,4.034772,6.1714606,-0.32874924))*buf[3]+mat4(vec4(3.4992442,-196.91893,-8.923708,2.8142626),vec4(3.4806502,-3.1846354,5.1725626,5.1804223),vec4(-2.4009497,15.585794,1.2863957,2.0252278),vec4(-71.25271,-62.441242,-8.138444,0.50670296))*buf[4]+mat4(vec4(-12.291733,-11.176166,-7.3474145,4.390294),vec4(10.805477,5.6337385,-0.9385842,-4.7348723),vec4(-12.869276,-7.039391,5.3029537,7.5436664),vec4(1.4593618,8.91898,3.5101583,5.840625))*buf[5]+vec4(2.2415268,-6.705987,-0.98861027,-2.117676); - buf[6]=sigmoid(buf[6]);buf[7]=sigmoid(buf[7]); - buf[0]=mat4(vec4(1.6794263,1.3817469,2.9625452,0.),vec4(-1.8834411,-1.4806935,-3.5924516,0.),vec4(-1.3279216,-1.0918057,-2.3124623,0.),vec4(0.2662234,0.23235129,0.44178495,0.))*buf[0]+mat4(vec4(-0.6299101,-0.5945583,-0.9125601,0.),vec4(0.17828953,0.18300213,0.18182953,0.),vec4(-2.96544,-2.5819945,-4.9001055,0.),vec4(1.4195864,1.1868085,2.5176322,0.))*buf[1]+mat4(vec4(-1.2584374,-1.0552157,-2.1688404,0.),vec4(-0.7200217,-0.52666044,-1.438251,0.),vec4(0.15345335,0.15196142,0.272854,0.),vec4(0.945728,0.8861938,1.2766753,0.))*buf[2]+mat4(vec4(-2.4218085,-1.968602,-4.35166,0.),vec4(-22.683098,-18.0544,-41.954372,0.),vec4(0.63792,0.5470648,1.1078634,0.),vec4(-1.5489894,-1.3075932,-2.6444845,0.))*buf[3]+mat4(vec4(-0.49252132,-0.39877754,-0.91366625,0.),vec4(0.95609266,0.7923952,1.640221,0.),vec4(0.30616966,0.15693925,0.8639857,0.),vec4(1.1825981,0.94504964,2.176963,0.))*buf[4]+mat4(vec4(0.35446745,0.3293795,0.59547555,0.),vec4(-0.58784515,-0.48177817,-1.0614829,0.),vec4(2.5271258,1.9991658,4.6846647,0.),vec4(0.13042648,0.08864098,0.30187556,0.))*buf[5]+mat4(vec4(-1.7718065,-1.4033192,-3.3355875,0.),vec4(3.1664357,2.638297,5.378702,0.),vec4(-3.1724713,-2.6107926,-5.549295,0.),vec4(-2.851368,-2.249092,-5.3013067,0.))*buf[6]+mat4(vec4(1.5203838,1.2212278,2.8404984,0.),vec4(1.5210563,1.2651345,2.683903,0.),vec4(2.9789467,2.4364579,5.2347264,0.),vec4(2.2270417,1.8825914,3.8028636,0.))*buf[7]+vec4(-1.5468478,-3.6171484,0.24762098,0.); - buf[0]=sigmoid(buf[0]); - return vec4(buf[0].x,buf[0].y,buf[0].z,1.); -} - -void mainImage(out vec4 fragColor,in vec2 fragCoord){ - vec2 uv=fragCoord/uResolution.xy*2.-1.; - uv.y*=-1.; - uv+=uWarp*vec2(sin(uv.y*6.283+uTime*0.5),cos(uv.x*6.283+uTime*0.5))*0.05; - fragColor=cppn_fn(uv,0.1*sin(0.3*uTime),0.1*sin(0.69*uTime),0.1*sin(0.44*uTime)); -} - -void main(){ - vec4 col;mainImage(col,gl_FragCoord.xy); - col.rgb=hueShiftRGB(col.rgb,uHueShift); - float scanline_val=sin(gl_FragCoord.y*uScanFreq)*0.5+0.5; - col.rgb*=1.-(scanline_val*scanline_val)*uScan; - col.rgb+=(rand(gl_FragCoord.xy+uTime)-0.5)*uNoise; - gl_FragColor=vec4(clamp(col.rgb,0.0,1.0),1.0); -} -`;class sk extends k.Component{constructor(t){super(t),this.state={hasError:!1}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,n){console.error("ErrorBoundary caught an error:",t,n)}render(){return this.state.hasError?this.props.fallback||m.jsx("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:"100%",background:"radial-gradient(circle at center, rgba(0,0,0,0.8) 0%, rgba(0,0,0,1) 100%)",zIndex:-1,pointerEvents:"none"}}):this.props.children}}function ik({hueShift:e=60,noiseIntensity:t=.03,scanlineIntensity:n=.08,speed:r=.4,scanlineFrequency:s=.6,warpAmount:i=.15,resolutionScale:o=1}){const a=k.useRef(null);return k.useEffect(()=>{const l=a.current;if(!l){console.error("DarkVeil: Canvas not found");return}let c,d,f;try{c=new Ob({dpr:Math.min(window.devicePixelRatio,2),canvas:l});const x=c.gl;if(!x){console.error("DarkVeil: WebGL context not available");return}const v=new tk(x);d=new Rb(x,{vertex:nk,fragment:rk,uniforms:{uTime:{value:0},uResolution:{value:new _c},uHueShift:{value:e},uNoise:{value:t},uScan:{value:n},uScanFreq:{value:s},uWarp:{value:i}}}),f=new IS(x,{geometry:v,program:d}),console.log("DarkVeil: Successfully initialized")}catch(x){console.error("DarkVeil: Initialization error:",x);return}const u=()=>{const x=window.innerWidth,v=window.innerHeight;c.setSize(x*o,v*o),d.uniforms.uResolution.value.set(x,v)};window.addEventListener("resize",u),u();const h=performance.now();let p=0;const g=()=>{d.uniforms.uTime.value=(performance.now()-h)/1e3*r,d.uniforms.uHueShift.value=e,d.uniforms.uNoise.value=t,d.uniforms.uScan.value=n,d.uniforms.uScanFreq.value=s,d.uniforms.uWarp.value=i,c.render({scene:f}),p=requestAnimationFrame(g)};return g(),()=>{cancelAnimationFrame(p),window.removeEventListener("resize",u)}},[e,t,n,r,s,i,o]),m.jsxs(m.Fragment,{children:[m.jsx("div",{style:{position:"fixed",top:0,left:0,width:"100vw",height:"100vh",background:"radial-gradient(circle at center, rgba(50,20,80,0.8) 0%, rgba(20,10,40,0.9) 50%, rgba(0,0,0,1) 100%)",zIndex:-10,pointerEvents:"none"}}),m.jsx("canvas",{ref:a,style:{position:"fixed",top:0,left:0,width:"100vw",height:"100vh",zIndex:-5,pointerEvents:"none",display:"block"}})]})}function Eh(e){return m.jsx(sk,{children:m.jsx(ik,{...e})})}/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */var ok={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const ak=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase().trim(),ee=(e,t)=>{const n=k.forwardRef(({color:r="currentColor",size:s=24,strokeWidth:i=2,absoluteStrokeWidth:o,className:a="",children:l,...c},d)=>k.createElement("svg",{ref:d,...ok,width:s,height:s,stroke:r,strokeWidth:o?Number(i)*24/Number(s):i,className:["lucide",`lucide-${ak(e)}`,a].join(" "),...c},[...t.map(([f,u])=>k.createElement(f,u)),...Array.isArray(l)?l:[l]]));return n.displayName=`${e}`,n};/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const lk=ee("ArrowRight",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const uk=ee("Calendar",[["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",ry:"2",key:"eu3xkr"}],["line",{x1:"16",x2:"16",y1:"2",y2:"6",key:"m3sa8f"}],["line",{x1:"8",x2:"8",y1:"2",y2:"6",key:"18kwsl"}],["line",{x1:"3",x2:"21",y1:"10",y2:"10",key:"xt86sb"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const ck=ee("Camera",[["path",{d:"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z",key:"1tc9qg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const dk=ee("CheckCircle",[["path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14",key:"g774vq"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Po=ee("Clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Bg=ee("ExternalLink",[["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}],["polyline",{points:"15 3 21 3 21 9",key:"mznyad"}],["line",{x1:"10",x2:"21",y1:"14",y2:"3",key:"18c3s4"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Xe=ee("Heart",[["path",{d:"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z",key:"c3ymky"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const fk=ee("Loader2",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Th=ee("LogOut",[["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}],["polyline",{points:"16 17 21 12 16 7",key:"1gabdz"}],["line",{x1:"21",x2:"9",y1:"12",y2:"12",key:"1uyos4"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const hk=ee("Menu",[["line",{x1:"4",x2:"20",y1:"12",y2:"12",key:"1e0a9i"}],["line",{x1:"4",x2:"20",y1:"6",y2:"6",key:"1owob3"}],["line",{x1:"4",x2:"20",y1:"18",y2:"18",key:"yk5zj1"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const vt=ee("Music",[["path",{d:"M9 18V5l12-2v13",key:"1jmyc2"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["circle",{cx:"18",cy:"16",r:"3",key:"1hluhg"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const pk=ee("Pause",[["rect",{width:"4",height:"16",x:"6",y:"4",key:"iffhe4"}],["rect",{width:"4",height:"16",x:"14",y:"4",key:"sjin7j"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Ug=ee("PlayCircle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polygon",{points:"10 8 16 12 10 16 10 8",key:"1cimsy"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Nh=ee("Play",[["polygon",{points:"5 3 19 12 5 21 5 3",key:"191637"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Ac=ee("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Mh=ee("Settings",[["path",{d:"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z",key:"1qme2f"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Yn=ee("Sparkles",[["path",{d:"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z",key:"17u4zn"}],["path",{d:"M5 3v4",key:"bklmnn"}],["path",{d:"M19 17v4",key:"iiml17"}],["path",{d:"M3 5h4",key:"nem4j1"}],["path",{d:"M17 19h4",key:"lbex7p"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const mk=ee("Star",[["polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2",key:"8f66p6"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Wg=ee("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const gk=ee("TrendingUp",[["polyline",{points:"22 7 13.5 15.5 8.5 10.5 2 17",key:"126l90"}],["polyline",{points:"16 7 22 7 22 13",key:"kwv8wd"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Ss=ee("User",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Hg=ee("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const yk=ee("Volume2",[["polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5",key:"16drj5"}],["path",{d:"M15.54 8.46a5 5 0 0 1 0 7.07",key:"ltjumu"}],["path",{d:"M19.07 4.93a10 10 0 0 1 0 14.14",key:"1kegas"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const vk=ee("Wand2",[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72Z",key:"1bcowg"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const xk=ee("XCircle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);/** - * @license lucide-react v0.294.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const _h=ee("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);function qg(e){var t,n,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var s=e.length;for(t=0;t{const t=kk(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:o=>{const a=o.split(Lc);return a[0]===""&&a.length!==1&&a.shift(),Gg(a,t)||Sk(o)},getConflictingClassGroupIds:(o,a)=>{const l=n[o]||[];return a&&r[o]?[...l,...r[o]]:l}}},Gg=(e,t)=>{var o;if(e.length===0)return t.classGroupId;const n=e[0],r=t.nextPart.get(n),s=r?Gg(e.slice(1),r):void 0;if(s)return s;if(t.validators.length===0)return;const i=e.join(Lc);return(o=t.validators.find(({validator:a})=>a(i)))==null?void 0:o.classGroupId},Ah=/^\[(.+)\]$/,Sk=e=>{if(Ah.test(e)){const t=Ah.exec(e)[1],n=t==null?void 0:t.substring(0,t.indexOf(":"));if(n)return"arbitrary.."+n}},kk=e=>{const{theme:t,prefix:n}=e,r={nextPart:new Map,validators:[]};return Pk(Object.entries(e.classGroups),n).forEach(([i,o])=>{uu(o,r,i,t)}),r},uu=(e,t,n,r)=>{e.forEach(s=>{if(typeof s=="string"){const i=s===""?t:Lh(t,s);i.classGroupId=n;return}if(typeof s=="function"){if(Ck(s)){uu(s(r),t,n,r);return}t.validators.push({validator:s,classGroupId:n});return}Object.entries(s).forEach(([i,o])=>{uu(o,Lh(t,i),n,r)})})},Lh=(e,t)=>{let n=e;return t.split(Lc).forEach(r=>{n.nextPart.has(r)||n.nextPart.set(r,{nextPart:new Map,validators:[]}),n=n.nextPart.get(r)}),n},Ck=e=>e.isThemeGetter,Pk=(e,t)=>t?e.map(([n,r])=>{const s=r.map(i=>typeof i=="string"?t+i:typeof i=="object"?Object.fromEntries(Object.entries(i).map(([o,a])=>[t+o,a])):i);return[n,s]}):e,jk=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,n=new Map,r=new Map;const s=(i,o)=>{n.set(i,o),t++,t>e&&(t=0,r=n,n=new Map)};return{get(i){let o=n.get(i);if(o!==void 0)return o;if((o=r.get(i))!==void 0)return s(i,o),o},set(i,o){n.has(i)?n.set(i,o):s(i,o)}}},Yg="!",Ek=e=>{const{separator:t,experimentalParseClassName:n}=e,r=t.length===1,s=t[0],i=t.length,o=a=>{const l=[];let c=0,d=0,f;for(let x=0;xd?f-d:void 0;return{modifiers:l,hasImportantModifier:h,baseClassName:p,maybePostfixModifierPosition:g}};return n?a=>n({className:a,parseClassName:o}):o},Tk=e=>{if(e.length<=1)return e;const t=[];let n=[];return e.forEach(r=>{r[0]==="["?(t.push(...n.sort(),r),n=[]):n.push(r)}),t.push(...n.sort()),t},Nk=e=>({cache:jk(e.cacheSize),parseClassName:Ek(e),...bk(e)}),Mk=/\s+/,_k=(e,t)=>{const{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:s}=t,i=[],o=e.trim().split(Mk);let a="";for(let l=o.length-1;l>=0;l-=1){const c=o[l],{modifiers:d,hasImportantModifier:f,baseClassName:u,maybePostfixModifierPosition:h}=n(c);let p=!!h,g=r(p?u.substring(0,h):u);if(!g){if(!p){a=c+(a.length>0?" "+a:a);continue}if(g=r(u),!g){a=c+(a.length>0?" "+a:a);continue}p=!1}const x=Tk(d).join(":"),v=f?x+Yg:x,y=v+g;if(i.includes(y))continue;i.push(y);const w=s(g,p);for(let b=0;b0?" "+a:a)}return a};function Ak(){let e=0,t,n,r="";for(;e{if(typeof e=="string")return e;let t,n="";for(let r=0;rf(d),e());return n=Nk(c),r=n.cache.get,s=n.cache.set,i=a,a(l)}function a(l){const c=r(l);if(c)return c;const d=_k(l,n);return s(l,d),d}return function(){return i(Ak.apply(null,arguments))}}const ne=e=>{const t=n=>n[e]||[];return t.isThemeGetter=!0,t},Xg=/^\[(?:([a-z-]+):)?(.+)\]$/i,Dk=/^\d+\/\d+$/,Rk=new Set(["px","full","screen"]),Vk=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Fk=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Ik=/^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/,zk=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Ok=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Mt=e=>Cr(e)||Rk.has(e)||Dk.test(e),Kt=e=>Ur(e,"length",Yk),Cr=e=>!!e&&!Number.isNaN(Number(e)),Ya=e=>Ur(e,"number",Cr),ts=e=>!!e&&Number.isInteger(Number(e)),$k=e=>e.endsWith("%")&&Cr(e.slice(0,-1)),H=e=>Xg.test(e),Xt=e=>Vk.test(e),Bk=new Set(["length","size","percentage"]),Uk=e=>Ur(e,Bk,Qg),Wk=e=>Ur(e,"position",Qg),Hk=new Set(["image","url"]),qk=e=>Ur(e,Hk,Xk),Gk=e=>Ur(e,"",Kk),ns=()=>!0,Ur=(e,t,n)=>{const r=Xg.exec(e);return r?r[1]?typeof t=="string"?r[1]===t:t.has(r[1]):n(r[2]):!1},Yk=e=>Fk.test(e)&&!Ik.test(e),Qg=()=>!1,Kk=e=>zk.test(e),Xk=e=>Ok.test(e),Qk=()=>{const e=ne("colors"),t=ne("spacing"),n=ne("blur"),r=ne("brightness"),s=ne("borderColor"),i=ne("borderRadius"),o=ne("borderSpacing"),a=ne("borderWidth"),l=ne("contrast"),c=ne("grayscale"),d=ne("hueRotate"),f=ne("invert"),u=ne("gap"),h=ne("gradientColorStops"),p=ne("gradientColorStopPositions"),g=ne("inset"),x=ne("margin"),v=ne("opacity"),y=ne("padding"),w=ne("saturate"),b=ne("scale"),S=ne("sepia"),C=ne("skew"),P=ne("space"),j=ne("translate"),D=()=>["auto","contain","none"],T=()=>["auto","hidden","clip","visible","scroll"],z=()=>["auto",H,t],V=()=>[H,t],U=()=>["",Mt,Kt],R=()=>["auto",Cr,H],Q=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],A=()=>["solid","dashed","dotted","double","none"],q=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],_=()=>["start","end","center","between","around","evenly","stretch"],N=()=>["","0",H],F=()=>["auto","avoid","all","avoid-page","page","left","right","column"],L=()=>[Cr,H];return{cacheSize:500,separator:":",theme:{colors:[ns],spacing:[Mt,Kt],blur:["none","",Xt,H],brightness:L(),borderColor:[e],borderRadius:["none","","full",Xt,H],borderSpacing:V(),borderWidth:U(),contrast:L(),grayscale:N(),hueRotate:L(),invert:N(),gap:V(),gradientColorStops:[e],gradientColorStopPositions:[$k,Kt],inset:z(),margin:z(),opacity:L(),padding:V(),saturate:L(),scale:L(),sepia:N(),skew:L(),space:V(),translate:V()},classGroups:{aspect:[{aspect:["auto","square","video",H]}],container:["container"],columns:[{columns:[Xt]}],"break-after":[{"break-after":F()}],"break-before":[{"break-before":F()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...Q(),H]}],overflow:[{overflow:T()}],"overflow-x":[{"overflow-x":T()}],"overflow-y":[{"overflow-y":T()}],overscroll:[{overscroll:D()}],"overscroll-x":[{"overscroll-x":D()}],"overscroll-y":[{"overscroll-y":D()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[g]}],"inset-x":[{"inset-x":[g]}],"inset-y":[{"inset-y":[g]}],start:[{start:[g]}],end:[{end:[g]}],top:[{top:[g]}],right:[{right:[g]}],bottom:[{bottom:[g]}],left:[{left:[g]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",ts,H]}],basis:[{basis:z()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",H]}],grow:[{grow:N()}],shrink:[{shrink:N()}],order:[{order:["first","last","none",ts,H]}],"grid-cols":[{"grid-cols":[ns]}],"col-start-end":[{col:["auto",{span:["full",ts,H]},H]}],"col-start":[{"col-start":R()}],"col-end":[{"col-end":R()}],"grid-rows":[{"grid-rows":[ns]}],"row-start-end":[{row:["auto",{span:[ts,H]},H]}],"row-start":[{"row-start":R()}],"row-end":[{"row-end":R()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",H]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",H]}],gap:[{gap:[u]}],"gap-x":[{"gap-x":[u]}],"gap-y":[{"gap-y":[u]}],"justify-content":[{justify:["normal",..._()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",..._(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[..._(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[y]}],px:[{px:[y]}],py:[{py:[y]}],ps:[{ps:[y]}],pe:[{pe:[y]}],pt:[{pt:[y]}],pr:[{pr:[y]}],pb:[{pb:[y]}],pl:[{pl:[y]}],m:[{m:[x]}],mx:[{mx:[x]}],my:[{my:[x]}],ms:[{ms:[x]}],me:[{me:[x]}],mt:[{mt:[x]}],mr:[{mr:[x]}],mb:[{mb:[x]}],ml:[{ml:[x]}],"space-x":[{"space-x":[P]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[P]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",H,t]}],"min-w":[{"min-w":[H,t,"min","max","fit"]}],"max-w":[{"max-w":[H,t,"none","full","min","max","fit","prose",{screen:[Xt]},Xt]}],h:[{h:[H,t,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[H,t,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[H,t,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[H,t,"auto","min","max","fit"]}],"font-size":[{text:["base",Xt,Kt]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",Ya]}],"font-family":[{font:[ns]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",H]}],"line-clamp":[{"line-clamp":["none",Cr,Ya]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",Mt,H]}],"list-image":[{"list-image":["none",H]}],"list-style-type":[{list:["none","disc","decimal",H]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[e]}],"placeholder-opacity":[{"placeholder-opacity":[v]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[e]}],"text-opacity":[{"text-opacity":[v]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...A(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",Mt,Kt]}],"underline-offset":[{"underline-offset":["auto",Mt,H]}],"text-decoration-color":[{decoration:[e]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:V()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",H]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",H]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[v]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...Q(),Wk]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Uk]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},qk]}],"bg-color":[{bg:[e]}],"gradient-from-pos":[{from:[p]}],"gradient-via-pos":[{via:[p]}],"gradient-to-pos":[{to:[p]}],"gradient-from":[{from:[h]}],"gradient-via":[{via:[h]}],"gradient-to":[{to:[h]}],rounded:[{rounded:[i]}],"rounded-s":[{"rounded-s":[i]}],"rounded-e":[{"rounded-e":[i]}],"rounded-t":[{"rounded-t":[i]}],"rounded-r":[{"rounded-r":[i]}],"rounded-b":[{"rounded-b":[i]}],"rounded-l":[{"rounded-l":[i]}],"rounded-ss":[{"rounded-ss":[i]}],"rounded-se":[{"rounded-se":[i]}],"rounded-ee":[{"rounded-ee":[i]}],"rounded-es":[{"rounded-es":[i]}],"rounded-tl":[{"rounded-tl":[i]}],"rounded-tr":[{"rounded-tr":[i]}],"rounded-br":[{"rounded-br":[i]}],"rounded-bl":[{"rounded-bl":[i]}],"border-w":[{border:[a]}],"border-w-x":[{"border-x":[a]}],"border-w-y":[{"border-y":[a]}],"border-w-s":[{"border-s":[a]}],"border-w-e":[{"border-e":[a]}],"border-w-t":[{"border-t":[a]}],"border-w-r":[{"border-r":[a]}],"border-w-b":[{"border-b":[a]}],"border-w-l":[{"border-l":[a]}],"border-opacity":[{"border-opacity":[v]}],"border-style":[{border:[...A(),"hidden"]}],"divide-x":[{"divide-x":[a]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[a]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[v]}],"divide-style":[{divide:A()}],"border-color":[{border:[s]}],"border-color-x":[{"border-x":[s]}],"border-color-y":[{"border-y":[s]}],"border-color-s":[{"border-s":[s]}],"border-color-e":[{"border-e":[s]}],"border-color-t":[{"border-t":[s]}],"border-color-r":[{"border-r":[s]}],"border-color-b":[{"border-b":[s]}],"border-color-l":[{"border-l":[s]}],"divide-color":[{divide:[s]}],"outline-style":[{outline:["",...A()]}],"outline-offset":[{"outline-offset":[Mt,H]}],"outline-w":[{outline:[Mt,Kt]}],"outline-color":[{outline:[e]}],"ring-w":[{ring:U()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[e]}],"ring-opacity":[{"ring-opacity":[v]}],"ring-offset-w":[{"ring-offset":[Mt,Kt]}],"ring-offset-color":[{"ring-offset":[e]}],shadow:[{shadow:["","inner","none",Xt,Gk]}],"shadow-color":[{shadow:[ns]}],opacity:[{opacity:[v]}],"mix-blend":[{"mix-blend":[...q(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":q()}],filter:[{filter:["","none"]}],blur:[{blur:[n]}],brightness:[{brightness:[r]}],contrast:[{contrast:[l]}],"drop-shadow":[{"drop-shadow":["","none",Xt,H]}],grayscale:[{grayscale:[c]}],"hue-rotate":[{"hue-rotate":[d]}],invert:[{invert:[f]}],saturate:[{saturate:[w]}],sepia:[{sepia:[S]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[n]}],"backdrop-brightness":[{"backdrop-brightness":[r]}],"backdrop-contrast":[{"backdrop-contrast":[l]}],"backdrop-grayscale":[{"backdrop-grayscale":[c]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[d]}],"backdrop-invert":[{"backdrop-invert":[f]}],"backdrop-opacity":[{"backdrop-opacity":[v]}],"backdrop-saturate":[{"backdrop-saturate":[w]}],"backdrop-sepia":[{"backdrop-sepia":[S]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[o]}],"border-spacing-x":[{"border-spacing-x":[o]}],"border-spacing-y":[{"border-spacing-y":[o]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",H]}],duration:[{duration:L()}],ease:[{ease:["linear","in","out","in-out",H]}],delay:[{delay:L()}],animate:[{animate:["none","spin","ping","pulse","bounce",H]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[b]}],"scale-x":[{"scale-x":[b]}],"scale-y":[{"scale-y":[b]}],rotate:[{rotate:[ts,H]}],"translate-x":[{"translate-x":[j]}],"translate-y":[{"translate-y":[j]}],"skew-x":[{"skew-x":[C]}],"skew-y":[{"skew-y":[C]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",H]}],accent:[{accent:["auto",e]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",H]}],"caret-color":[{caret:[e]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":V()}],"scroll-mx":[{"scroll-mx":V()}],"scroll-my":[{"scroll-my":V()}],"scroll-ms":[{"scroll-ms":V()}],"scroll-me":[{"scroll-me":V()}],"scroll-mt":[{"scroll-mt":V()}],"scroll-mr":[{"scroll-mr":V()}],"scroll-mb":[{"scroll-mb":V()}],"scroll-ml":[{"scroll-ml":V()}],"scroll-p":[{"scroll-p":V()}],"scroll-px":[{"scroll-px":V()}],"scroll-py":[{"scroll-py":V()}],"scroll-ps":[{"scroll-ps":V()}],"scroll-pe":[{"scroll-pe":V()}],"scroll-pt":[{"scroll-pt":V()}],"scroll-pr":[{"scroll-pr":V()}],"scroll-pb":[{"scroll-pb":V()}],"scroll-pl":[{"scroll-pl":V()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",H]}],fill:[{fill:[e,"none"]}],"stroke-w":[{stroke:[Mt,Kt,Ya]}],stroke:[{stroke:[e,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},Zk=Lk(Qk);function Dh(...e){return Zk(wk(e))}function Zg(e){const t=Math.floor(e/6e4),n=Math.floor(e%6e4/1e3);return`${t}:${n.toString().padStart(2,"0")}`}function Pr(e){const t=new Date(e),r=(new Date().getTime()-t.getTime())/(1e3*60*60);return r<1?`${Math.floor(r*60)}m ago`:r<24?`${Math.floor(r)}h ago`:`${Math.floor(r/24)}d ago`}const Jk=()=>{var V,U,R,Q,A,q,_,N,F,L;const[e,t]=k.useState(!1),[n,r]=k.useState(!1),[s,i]=k.useState({x:0,y:0}),[o,a]=k.useState(!1),[l,c]=k.useState({x:0,y:0}),{currentUser:d,partnerUser:f,logout:u,theme:h,setTheme:p,setPartnerUser:g}=ae(),[x,v]=k.useState(""),[y,w]=k.useState(!1),[b,S]=k.useState(!1),C=En(),P=[{name:"Dashboard",href:"/",icon:Xe},{name:"Last Listened",href:"/last-listened",icon:vt},{name:"Mixed Playlist",href:"/mixed-playlist",icon:Ug},{name:"Memory Lane",href:"/memory-lane",icon:Yn}],j=()=>{u(),localStorage.removeItem("spotify-user"),localStorage.removeItem("spotify-partner")},D=async()=>{var E,W;if(!(!((E=d==null?void 0:d.user)!=null&&E.id)||!((W=f==null?void 0:f.user)!=null&&W.id))&&confirm(`Are you sure you want to remove ${f.user.display_name} as your partner?`)){S(!0);try{await Pt("/partners/remove",{partnerId:f.user.id})}catch(X){try{await Pt("/partners/clear",{userId:d.user.id})}catch(te){console.error("Failed to remove partner:",X,te)}}finally{g(null),localStorage.removeItem("spotify-partner"),S(!1)}}},T=Vr(h);k.useEffect(()=>{Vr(h)},[h]),k.useEffect(()=>{if(n){const E=Math.min(600,window.innerWidth-40),W=Math.min(window.innerHeight*.9,800),X=(window.innerWidth-E)/2,te=(window.innerHeight-W)/2;i({x:X,y:te})}},[n]),k.useEffect(()=>{const E=X=>{o&&i({x:X.clientX-l.x,y:X.clientY-l.y})},W=()=>{a(!1)};return o&&(document.addEventListener("mousemove",E),document.addEventListener("mouseup",W)),()=>{document.removeEventListener("mousemove",E),document.removeEventListener("mouseup",W)}},[o,l]);const z=E=>{a(!0),c({x:E.clientX-s.x,y:E.clientY-s.y})};return m.jsxs(O.nav,{initial:{y:-100,opacity:0},animate:{y:0,opacity:1},className:"sticky top-0 z-50",style:{background:"rgba(0, 0, 0, 0.8)",backdropFilter:"blur(20px)",borderBottom:"1px solid rgba(255, 255, 255, 0.05)"},children:[m.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:[m.jsxs("div",{className:"flex justify-between items-center h-16",children:[m.jsxs(zi,{to:"/",className:"flex items-center space-x-2",children:[m.jsx(O.div,{whileHover:{scale:1.1,rotate:5},className:"w-8 h-8 rounded-full flex items-center justify-center",style:{background:`linear-gradient(135deg, ${((V=T.cssVars)==null?void 0:V.primary)||"#1db954"} 0%, ${((U=T.cssVars)==null?void 0:U.secondary)||"#1ed760"} 100%)`},children:m.jsx(Xe,{className:"w-5 h-5 text-white"})}),m.jsx("span",{className:"text-xl font-bold gradient-text",children:"Our Musical Journey"})]}),m.jsx("div",{className:"hidden md:flex items-center space-x-1",children:P.map(E=>{var X,te,G,be;const W=C.pathname===E.href;return m.jsxs(zi,{to:E.href,className:Dh("flex items-center space-x-2 px-4 py-2 rounded-xl transition-all duration-300",W?"text-white":"text-white/60 hover:text-white hover:bg-white/5"),style:W?{background:`linear-gradient(135deg, ${((X=T.cssVars)==null?void 0:X.primary)||"#1db954"}15 0%, ${((te=T.cssVars)==null?void 0:te.secondary)||"#1ed760"}10 100%)`,border:`1px solid ${((G=T.cssVars)==null?void 0:G.primary)||"#1db954"}30`}:{},children:[m.jsx(E.icon,{className:"w-4 h-4",style:{color:W?(be=T.cssVars)==null?void 0:be.primary:void 0}}),m.jsx("span",{className:"font-medium",children:E.name})]},E.name)})}),m.jsxs("div",{className:"hidden md:flex items-center space-x-4",children:[!f&&m.jsxs("div",{className:"flex items-center space-x-2",children:[m.jsx("input",{value:x,onChange:E=>v(E.target.value),placeholder:"Partner Spotify ID",className:"bg-white/10 text-white text-sm px-2 py-1 rounded"}),m.jsx("button",{disabled:y||!x,onClick:async()=>{var E;if(!(!((E=d==null?void 0:d.user)!=null&&E.id)||!x)){w(!0);try{await Pt("/partners/request",{toUid:x})}finally{w(!1)}}},className:`${T.primary} ${T.hover} text-white px-3 py-1 rounded text-sm disabled:opacity-50`,children:y?"Sending...":"Send Request"})]}),f&&m.jsxs(O.div,{initial:{scale:0},animate:{scale:1},className:"flex items-center space-x-2 text-sm text-white/70",children:[m.jsx(Ss,{className:"w-4 h-4"}),m.jsxs("span",{children:["+ ",(R=f.user)==null?void 0:R.display_name]})]}),m.jsxs(O.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>r(!0),className:"flex items-center space-x-2 px-3 py-2 rounded-xl text-white/60 hover:text-white transition-all duration-300",style:{color:(Q=T.cssVars)==null?void 0:Q.primary},onMouseEnter:E=>{E.currentTarget.style.background="rgba(255, 255, 255, 0.05)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[m.jsx(Mh,{className:"w-4 h-4"}),m.jsx("span",{className:"hidden lg:block",children:"Settings"})]}),m.jsxs(O.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:j,className:"flex items-center space-x-2 px-3 py-2 rounded-xl text-white/60 hover:text-white transition-all duration-300",onMouseEnter:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.1)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[m.jsx(Th,{className:"w-4 h-4"}),m.jsx("span",{className:"hidden lg:block",children:"Logout"})]})]}),m.jsx("button",{onClick:()=>t(!e),className:"md:hidden p-2 rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-all duration-300",children:e?m.jsx(_h,{className:"w-6 h-6"}):m.jsx(hk,{className:"w-6 h-6"})})]}),e&&m.jsx(O.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},className:"md:hidden py-4 border-t border-white/10",children:m.jsxs("div",{className:"space-y-2",children:[P.map(E=>{var X,te,G,be;const W=C.pathname===E.href;return m.jsxs(zi,{to:E.href,onClick:()=>t(!1),className:Dh("flex items-center space-x-3 px-4 py-3 rounded-xl transition-all duration-300",W?"text-white":"text-white/60 hover:text-white hover:bg-white/5"),style:W?{background:`linear-gradient(135deg, ${((X=T.cssVars)==null?void 0:X.primary)||"#1db954"}15 0%, ${((te=T.cssVars)==null?void 0:te.secondary)||"#1ed760"}10 100%)`,border:`1px solid ${((G=T.cssVars)==null?void 0:G.primary)||"#1db954"}30`}:{},children:[m.jsx(E.icon,{className:"w-5 h-5",style:{color:W?(be=T.cssVars)==null?void 0:be.primary:void 0}}),m.jsx("span",{className:"font-medium",children:E.name})]},E.name)}),m.jsxs("div",{className:"pt-4 border-t border-white/10",children:[f&&m.jsxs("div",{className:"flex items-center space-x-3 px-4 py-2 text-sm text-white/70",children:[m.jsx(Ss,{className:"w-4 h-4"}),m.jsxs("span",{children:["Connected with ",(A=f.user)==null?void 0:A.display_name]})]}),m.jsxs("button",{onClick:()=>{r(!0),t(!1)},className:"w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-white/60 hover:text-white transition-all duration-300",style:{color:(q=T.cssVars)==null?void 0:q.primary},onMouseEnter:E=>{E.currentTarget.style.background="rgba(255, 255, 255, 0.05)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[m.jsx(Mh,{className:"w-5 h-5"}),m.jsx("span",{className:"font-medium",children:"Settings"})]}),m.jsxs("button",{onClick:j,className:"w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-white/60 hover:text-white transition-all duration-300",onMouseEnter:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.1)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[m.jsx(Th,{className:"w-5 h-5"}),m.jsx("span",{className:"font-medium",children:"Logout"})]})]})]})})]}),n&&m.jsxs(m.Fragment,{children:[m.jsx(O.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 bg-black/50 backdrop-blur-md z-40",onClick:()=>r(!1)}),m.jsxs(O.div,{initial:{opacity:0,scale:.8,y:30},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.8,y:30},className:"fixed z-50 overflow-hidden",style:{left:s.x,top:s.y,width:Math.min(600,window.innerWidth-40),height:Math.min(window.innerHeight*.9,800),background:"linear-gradient(135deg, rgba(0,0,0,0.9) 0%, rgba(20,20,20,0.95) 50%, rgba(0,0,0,0.9) 100%)",backdropFilter:"blur(24px) saturate(180%)",WebkitBackdropFilter:"blur(24px) saturate(180%)",border:"1px solid rgba(255,255,255,0.2)",borderRadius:"16px",boxShadow:"0 25px 50px rgba(0,0,0,0.5)",cursor:o?"grabbing":"default"},children:[m.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-white/20 cursor-grab active:cursor-grabbing select-none",onMouseDown:z,style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:[m.jsxs("div",{className:"flex items-center space-x-3",children:[m.jsxs("div",{className:"flex space-x-2",children:[m.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),m.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),m.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"})]}),m.jsx("h2",{className:"text-lg font-semibold text-white",children:"Settings"})]}),m.jsx("button",{onClick:()=>r(!1),className:"text-white/70 hover:text-white hover:bg-white/10 p-2 rounded-lg transition-all duration-200",children:m.jsx(_h,{className:"w-5 h-5"})})]}),m.jsx("div",{className:"overflow-y-auto p-4 sm:p-6",style:{height:"calc(100% - 60px)"},children:m.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[(d==null?void 0:d.user)&&m.jsxs("div",{children:[m.jsx("h3",{className:"text-lg font-semibold text-white mb-4 drop-shadow-md",children:"Your Account"}),m.jsxs("div",{className:"rounded-xl p-4 border border-white/20 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:[m.jsx("div",{className:"text-sm text-white/70 mb-2 font-medium",children:"Spotify ID"}),m.jsx("div",{className:"text-white font-mono text-sm break-all rounded-lg p-3 mb-3",style:{background:"rgba(0,0,0,0.4)",border:"1px solid rgba(255,255,255,0.1)"},children:d.user.id}),m.jsxs("div",{className:"text-sm text-white/80",children:["Display Name: ",m.jsx("span",{className:"text-white font-medium",children:d.user.display_name})]})]})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"text-lg font-semibold text-white mb-4 drop-shadow-md",children:"Partner"}),f?m.jsx("div",{className:"rounded-xl p-4 border border-white/20 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:m.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between space-y-3 sm:space-y-0",children:[m.jsxs("div",{className:"flex items-center space-x-3 sm:space-x-4",children:[m.jsx("div",{className:"w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-purple-500 to-pink-500 rounded-full flex items-center justify-center shadow-lg",children:m.jsx(Ss,{className:"w-5 h-5 sm:w-6 sm:h-6 text-white"})}),m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsx("div",{className:"text-white font-semibold text-base sm:text-lg truncate",children:(_=f.user)==null?void 0:_.display_name}),m.jsx("div",{className:"text-xs text-white/70 break-all rounded px-2 py-1 mt-1 inline-block",style:{background:"rgba(0,0,0,0.3)",border:"1px solid rgba(255,255,255,0.1)"},children:(N=f.user)==null?void 0:N.id}),m.jsx("div",{className:"text-sm text-green-400 font-medium mt-2",children:"✓ Connected"})]})]}),m.jsxs("button",{onClick:D,disabled:b,className:"flex items-center space-x-2 p-2 sm:p-3 text-red-400 hover:text-red-300 rounded-xl transition-all duration-200 disabled:opacity-50 self-start sm:self-auto",style:{background:"rgba(239, 68, 68, 0.1)"},onMouseEnter:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.2)"},onMouseLeave:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.1)"},children:[m.jsx(Wg,{className:"w-4 h-4 sm:w-5 sm:h-5"}),m.jsx("span",{className:"text-sm sm:hidden",children:"Remove"})]})]})}):m.jsxs("div",{className:"rounded-xl p-4 border border-white/20 space-y-4 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:[m.jsxs("div",{children:[m.jsx("label",{className:"text-sm text-white/70 mb-2 block font-medium",children:"Partner Spotify ID"}),m.jsx("input",{value:x,onChange:E=>v(E.target.value),placeholder:"Enter partner's Spotify ID...",className:"w-full text-white text-sm px-4 py-3 rounded-xl placeholder-white/50 border focus:outline-none transition-all",style:{background:"rgba(0,0,0,0.4)",border:"1px solid rgba(255,255,255,0.2)"},onFocus:E=>{E.target.style.border="1px solid rgba(255,255,255,0.4)"},onBlur:E=>{E.target.style.border="1px solid rgba(255,255,255,0.2)"}})]}),m.jsx("button",{disabled:y||!x,onClick:async()=>{var E;if(!(!((E=d==null?void 0:d.user)!=null&&E.id)||!x)){w(!0);try{await Pt("/partners/request",{toUid:x}),v("")}finally{w(!1)}}},className:"w-full text-white px-4 py-3 rounded-xl text-sm disabled:opacity-50 transition-all duration-200 font-medium",style:{background:`linear-gradient(135deg, ${((F=T.cssVars)==null?void 0:F.primary)||"#1db954"} 0%, ${((L=T.cssVars)==null?void 0:L.secondary)||"#1ed760"} 100%)`},onMouseEnter:E=>{var W;E.currentTarget.style.transform="translateY(-1px)",E.currentTarget.style.boxShadow=`0 8px 25px ${((W=T.cssVars)==null?void 0:W.primary)||"#1db954"}40`},onMouseLeave:E=>{E.currentTarget.style.transform="translateY(0)",E.currentTarget.style.boxShadow="none"},children:y?"Sending...":"Send Partner Request"})]})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"text-lg font-semibold text-white mb-4 drop-shadow-md",children:"Color Theme"}),m.jsx("div",{className:"rounded-xl p-4 border border-white/20 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:m.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-3",children:[{name:"Green",value:"green",color:"from-green-500 to-emerald-500"},{name:"Pink",value:"pink",color:"from-pink-500 to-rose-500"},{name:"Blue",value:"blue",color:"from-blue-400 to-cyan-400"},{name:"Red",value:"red",color:"from-red-600 to-red-800"},{name:"Purple",value:"purple",color:"from-purple-500 to-violet-600"},{name:"Yellow",value:"yellow",color:"from-yellow-400 to-orange-500"},{name:"Turquoise",value:"turquoise",color:"from-cyan-400 to-blue-500"}].map(E=>{var W,X,te;return m.jsxs("button",{onClick:()=>p(E.value),className:"flex items-center space-x-3 p-3 rounded-xl border transition-all duration-200",style:{border:h===E.value?`2px solid ${((W=T.cssVars)==null?void 0:W.primary)||"#1db954"}`:"1px solid rgba(255,255,255,0.2)",background:h===E.value?`linear-gradient(135deg, ${((X=T.cssVars)==null?void 0:X.primary)||"#1db954"}15 0%, ${((te=T.cssVars)==null?void 0:te.secondary)||"#1ed760"}10 100%)`:"rgba(255,255,255,0.02)"},onMouseEnter:G=>{var be;h!==E.value?(G.currentTarget.style.background="rgba(255,255,255,0.08)",G.currentTarget.style.border="1px solid rgba(255,255,255,0.4)",G.currentTarget.style.transform="translateY(-2px)",G.currentTarget.style.boxShadow="0 4px 12px rgba(0,0,0,0.3)"):(G.currentTarget.style.transform="translateY(-1px)",G.currentTarget.style.boxShadow=`0 6px 20px ${((be=T.cssVars)==null?void 0:be.primary)||"#1db954"}30`)},onMouseLeave:G=>{h!==E.value?(G.currentTarget.style.background="rgba(255,255,255,0.02)",G.currentTarget.style.border="1px solid rgba(255,255,255,0.2)",G.currentTarget.style.transform="translateY(0)",G.currentTarget.style.boxShadow="none"):(G.currentTarget.style.transform="translateY(0)",G.currentTarget.style.boxShadow="none")},children:[m.jsx("div",{className:`w-5 h-5 rounded-full bg-gradient-to-r ${E.color} shadow-sm`}),m.jsx("span",{className:"text-white text-sm font-medium",children:E.name})]},E.value)})})})]})]})})]})]})]})};var Jg={exports:{}};(function(e){var t=function(){var n="https://api.spotify.com/v1",r=null,s=null,i=function(u,h){return u.abort=h,u},o=function(u,h){var p;if(s!==null){var g=s.defer();u(function(x){g.resolve(x)},function(x){g.reject(x)}),p=g.promise}else window.Promise&&(p=new window.Promise(u));return p?new i(p,h):null},a=function(){var u=Array.prototype.slice.call(arguments),h=u[0],p=u.slice(1);return h=h||{},p.forEach(function(g){for(var x in g)g.hasOwnProperty(x)&&(h[x]=g[x])}),h},l=function(u,h){var p="";for(var g in h)if(h.hasOwnProperty(g)){var x=h[g];p+=encodeURIComponent(g)+"="+encodeURIComponent(x)+"&"}return p.length>0&&(p=p.substring(0,p.length-1),u=u+"?"+p),u},c=function(u,h){var p=new XMLHttpRequest,g=function(x,v){function y(C){x&&x(C),h&&h(null,C)}function w(){v&&v(p),h&&h(p,null)}var b=u.type||"GET";if(p.open(b,l(u.url,u.params)),r&&p.setRequestHeader("Authorization","Bearer "+r),p.onreadystatechange=function(){if(p.readyState===4){var C=null;try{C=p.responseText?JSON.parse(p.responseText):""}catch(P){console.error(P)}p.status>=200&&p.status<300?y(C):w()}},b==="GET")p.send(null);else{var S=null;u.postData&&(u.contentType==="image/jpeg"?(S=u.postData,p.setRequestHeader("Content-Type",u.contentType)):(S=JSON.stringify(u.postData),p.setRequestHeader("Content-Type","application/json"))),p.send(S)}};return h?(g(),null):o(g,function(){p.abort()})},d=function(u,h,p,g){var x={},v=null;typeof h=="object"?(x=h,v=p):typeof h=="function"&&(v=h);var y=u.type||"GET";return y!=="GET"&&u.postData&&!g?u.postData=a(u.postData,x):u.params=a(u.params,x),c(u,v)},f=function(){};return f.prototype={constructor:t},f.prototype.getGeneric=function(u,h){var p={url:u};return d(p,h)},f.prototype.getMe=function(u,h){var p={url:n+"/me"};return d(p,u,h)},f.prototype.getMySavedTracks=function(u,h){var p={url:n+"/me/tracks"};return d(p,u,h)},f.prototype.addToMySavedTracks=function(u,h,p){var g={url:n+"/me/tracks",type:"PUT",postData:u};return d(g,h,p)},f.prototype.removeFromMySavedTracks=function(u,h,p){var g={url:n+"/me/tracks",type:"DELETE",postData:u};return d(g,h,p)},f.prototype.containsMySavedTracks=function(u,h,p){var g={url:n+"/me/tracks/contains",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getMySavedAlbums=function(u,h){var p={url:n+"/me/albums"};return d(p,u,h)},f.prototype.addToMySavedAlbums=function(u,h,p){var g={url:n+"/me/albums",type:"PUT",postData:u};return d(g,h,p)},f.prototype.removeFromMySavedAlbums=function(u,h,p){var g={url:n+"/me/albums",type:"DELETE",postData:u};return d(g,h,p)},f.prototype.containsMySavedAlbums=function(u,h,p){var g={url:n+"/me/albums/contains",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getMyTopArtists=function(u,h){var p={url:n+"/me/top/artists"};return d(p,u,h)},f.prototype.getMyTopTracks=function(u,h){var p={url:n+"/me/top/tracks"};return d(p,u,h)},f.prototype.getMyRecentlyPlayedTracks=function(u,h){var p={url:n+"/me/player/recently-played"};return d(p,u,h)},f.prototype.followUsers=function(u,h){var p={url:n+"/me/following/",type:"PUT",params:{ids:u.join(","),type:"user"}};return d(p,h)},f.prototype.followArtists=function(u,h){var p={url:n+"/me/following/",type:"PUT",params:{ids:u.join(","),type:"artist"}};return d(p,h)},f.prototype.followPlaylist=function(u,h,p){var g={url:n+"/playlists/"+u+"/followers",type:"PUT",postData:{}};return d(g,h,p)},f.prototype.unfollowUsers=function(u,h){var p={url:n+"/me/following/",type:"DELETE",params:{ids:u.join(","),type:"user"}};return d(p,h)},f.prototype.unfollowArtists=function(u,h){var p={url:n+"/me/following/",type:"DELETE",params:{ids:u.join(","),type:"artist"}};return d(p,h)},f.prototype.unfollowPlaylist=function(u,h){var p={url:n+"/playlists/"+u+"/followers",type:"DELETE"};return d(p,h)},f.prototype.isFollowingUsers=function(u,h){var p={url:n+"/me/following/contains",type:"GET",params:{ids:u.join(","),type:"user"}};return d(p,h)},f.prototype.isFollowingArtists=function(u,h){var p={url:n+"/me/following/contains",type:"GET",params:{ids:u.join(","),type:"artist"}};return d(p,h)},f.prototype.areFollowingPlaylist=function(u,h,p){var g={url:n+"/playlists/"+u+"/followers/contains",type:"GET",params:{ids:h.join(",")}};return d(g,p)},f.prototype.getFollowedArtists=function(u,h){var p={url:n+"/me/following",type:"GET",params:{type:"artist"}};return d(p,u,h)},f.prototype.getUser=function(u,h,p){var g={url:n+"/users/"+encodeURIComponent(u)};return d(g,h,p)},f.prototype.getUserPlaylists=function(u,h,p){var g;return typeof u=="string"?g={url:n+"/users/"+encodeURIComponent(u)+"/playlists"}:(g={url:n+"/me/playlists"},p=h,h=u),d(g,h,p)},f.prototype.getPlaylist=function(u,h,p){var g={url:n+"/playlists/"+u};return d(g,h,p)},f.prototype.getPlaylistTracks=function(u,h,p){var g={url:n+"/playlists/"+u+"/tracks"};return d(g,h,p)},f.prototype.getPlaylistCoverImage=function(u,h){var p={url:n+"/playlists/"+u+"/images"};return d(p,h)},f.prototype.createPlaylist=function(u,h,p){var g={url:n+"/users/"+encodeURIComponent(u)+"/playlists",type:"POST",postData:h};return d(g,h,p)},f.prototype.changePlaylistDetails=function(u,h,p){var g={url:n+"/playlists/"+u,type:"PUT",postData:h};return d(g,h,p)},f.prototype.addTracksToPlaylist=function(u,h,p,g){var x={url:n+"/playlists/"+u+"/tracks",type:"POST",postData:{uris:h}};return d(x,p,g,!0)},f.prototype.replaceTracksInPlaylist=function(u,h,p){var g={url:n+"/playlists/"+u+"/tracks",type:"PUT",postData:{uris:h}};return d(g,{},p)},f.prototype.reorderTracksInPlaylist=function(u,h,p,g,x){var v={url:n+"/playlists/"+u+"/tracks",type:"PUT",postData:{range_start:h,insert_before:p}};return d(v,g,x)},f.prototype.removeTracksFromPlaylist=function(u,h,p){var g=h.map(function(v){return typeof v=="string"?{uri:v}:v}),x={url:n+"/playlists/"+u+"/tracks",type:"DELETE",postData:{tracks:g}};return d(x,{},p)},f.prototype.removeTracksFromPlaylistWithSnapshotId=function(u,h,p,g){var x=h.map(function(y){return typeof y=="string"?{uri:y}:y}),v={url:n+"/playlists/"+u+"/tracks",type:"DELETE",postData:{tracks:x,snapshot_id:p}};return d(v,{},g)},f.prototype.removeTracksFromPlaylistInPositions=function(u,h,p,g){var x={url:n+"/playlists/"+u+"/tracks",type:"DELETE",postData:{positions:h,snapshot_id:p}};return d(x,{},g)},f.prototype.uploadCustomPlaylistCoverImage=function(u,h,p){var g={url:n+"/playlists/"+u+"/images",type:"PUT",postData:h.replace(/^data:image\/jpeg;base64,/,""),contentType:"image/jpeg"};return d(g,{},p)},f.prototype.getAlbum=function(u,h,p){var g={url:n+"/albums/"+u};return d(g,h,p)},f.prototype.getAlbumTracks=function(u,h,p){var g={url:n+"/albums/"+u+"/tracks"};return d(g,h,p)},f.prototype.getAlbums=function(u,h,p){var g={url:n+"/albums/",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getTrack=function(u,h,p){var g={};return g.url=n+"/tracks/"+u,d(g,h,p)},f.prototype.getTracks=function(u,h,p){var g={url:n+"/tracks/",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getArtist=function(u,h,p){var g={url:n+"/artists/"+u};return d(g,h,p)},f.prototype.getArtists=function(u,h,p){var g={url:n+"/artists/",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getArtistAlbums=function(u,h,p){var g={url:n+"/artists/"+u+"/albums"};return d(g,h,p)},f.prototype.getArtistTopTracks=function(u,h,p,g){var x={url:n+"/artists/"+u+"/top-tracks",params:{country:h}};return d(x,p,g)},f.prototype.getArtistRelatedArtists=function(u,h,p){var g={url:n+"/artists/"+u+"/related-artists"};return d(g,h,p)},f.prototype.getFeaturedPlaylists=function(u,h){var p={url:n+"/browse/featured-playlists"};return d(p,u,h)},f.prototype.getNewReleases=function(u,h){var p={url:n+"/browse/new-releases"};return d(p,u,h)},f.prototype.getCategories=function(u,h){var p={url:n+"/browse/categories"};return d(p,u,h)},f.prototype.getCategory=function(u,h,p){var g={url:n+"/browse/categories/"+u};return d(g,h,p)},f.prototype.getCategoryPlaylists=function(u,h,p){var g={url:n+"/browse/categories/"+u+"/playlists"};return d(g,h,p)},f.prototype.search=function(u,h,p,g){var x={url:n+"/search/",params:{q:u,type:h.join(",")}};return d(x,p,g)},f.prototype.searchAlbums=function(u,h,p){return this.search(u,["album"],h,p)},f.prototype.searchArtists=function(u,h,p){return this.search(u,["artist"],h,p)},f.prototype.searchTracks=function(u,h,p){return this.search(u,["track"],h,p)},f.prototype.searchPlaylists=function(u,h,p){return this.search(u,["playlist"],h,p)},f.prototype.searchShows=function(u,h,p){return this.search(u,["show"],h,p)},f.prototype.searchEpisodes=function(u,h,p){return this.search(u,["episode"],h,p)},f.prototype.getAudioFeaturesForTrack=function(u,h){var p={};return p.url=n+"/audio-features/"+u,d(p,{},h)},f.prototype.getAudioFeaturesForTracks=function(u,h){var p={url:n+"/audio-features",params:{ids:u}};return d(p,{},h)},f.prototype.getAudioAnalysisForTrack=function(u,h){var p={};return p.url=n+"/audio-analysis/"+u,d(p,{},h)},f.prototype.getRecommendations=function(u,h){var p={url:n+"/recommendations"};return d(p,u,h)},f.prototype.getAvailableGenreSeeds=function(u){var h={url:n+"/recommendations/available-genre-seeds"};return d(h,{},u)},f.prototype.getMyDevices=function(u){var h={url:n+"/me/player/devices"};return d(h,{},u)},f.prototype.getMyCurrentPlaybackState=function(u,h){var p={url:n+"/me/player"};return d(p,u,h)},f.prototype.getMyCurrentPlayingTrack=function(u,h){var p={url:n+"/me/player/currently-playing"};return d(p,u,h)},f.prototype.transferMyPlayback=function(u,h,p){var g=h||{};g.device_ids=u;var x={type:"PUT",url:n+"/me/player",postData:g};return d(x,h,p)},f.prototype.play=function(u,h){u=u||{};var p="device_id"in u?{device_id:u.device_id}:null,g={};["context_uri","uris","offset","position_ms"].forEach(function(y){y in u&&(g[y]=u[y])});var x={type:"PUT",url:n+"/me/player/play",params:p,postData:g},v=typeof u=="function"?u:{};return d(x,v,h)},f.prototype.queue=function(u,h,p){h=h||{};var g="device_id"in h?{uri:u,device_id:h.device_id}:{uri:u},x={type:"POST",url:n+"/me/player/queue",params:g};return d(x,h,p)},f.prototype.pause=function(u,h){u=u||{};var p="device_id"in u?{device_id:u.device_id}:null,g={type:"PUT",url:n+"/me/player/pause",params:p};return d(g,u,h)},f.prototype.skipToNext=function(u,h){u=u||{};var p="device_id"in u?{device_id:u.device_id}:null,g={type:"POST",url:n+"/me/player/next",params:p};return d(g,u,h)},f.prototype.skipToPrevious=function(u,h){u=u||{};var p="device_id"in u?{device_id:u.device_id}:null,g={type:"POST",url:n+"/me/player/previous",params:p};return d(g,u,h)},f.prototype.seek=function(u,h,p){h=h||{};var g={position_ms:u};"device_id"in h&&(g.device_id=h.device_id);var x={type:"PUT",url:n+"/me/player/seek",params:g};return d(x,h,p)},f.prototype.setRepeat=function(u,h,p){h=h||{};var g={state:u};"device_id"in h&&(g.device_id=h.device_id);var x={type:"PUT",url:n+"/me/player/repeat",params:g};return d(x,h,p)},f.prototype.setVolume=function(u,h,p){h=h||{};var g={volume_percent:u};"device_id"in h&&(g.device_id=h.device_id);var x={type:"PUT",url:n+"/me/player/volume",params:g};return d(x,h,p)},f.prototype.setShuffle=function(u,h,p){h=h||{};var g={state:u};"device_id"in h&&(g.device_id=h.device_id);var x={type:"PUT",url:n+"/me/player/shuffle",params:g};return d(x,h,p)},f.prototype.getShow=function(u,h,p){var g={};return g.url=n+"/shows/"+u,d(g,h,p)},f.prototype.getShows=function(u,h,p){var g={url:n+"/shows/",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getMySavedShows=function(u,h){var p={url:n+"/me/shows"};return d(p,u,h)},f.prototype.addToMySavedShows=function(u,h,p){var g={url:n+"/me/shows",type:"PUT",postData:u};return d(g,h,p)},f.prototype.removeFromMySavedShows=function(u,h,p){var g={url:n+"/me/shows",type:"DELETE",postData:u};return d(g,h,p)},f.prototype.containsMySavedShows=function(u,h,p){var g={url:n+"/me/shows/contains",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getShowEpisodes=function(u,h,p){var g={url:n+"/shows/"+u+"/episodes"};return d(g,h,p)},f.prototype.getEpisode=function(u,h,p){var g={};return g.url=n+"/episodes/"+u,d(g,h,p)},f.prototype.getEpisodes=function(u,h,p){var g={url:n+"/episodes/",params:{ids:u.join(",")}};return d(g,h,p)},f.prototype.getAccessToken=function(){return r},f.prototype.setAccessToken=function(u){r=u},f.prototype.setPromiseImplementation=function(u){var h=!1;try{var p=new u(function(g){g()});typeof p.then=="function"&&typeof p.catch=="function"&&(h=!0)}catch(g){console.error(g)}if(h)s=u;else throw new Error("Unsupported implementation of Promises/A+")},f}();e.exports=t})(Jg);var e6=Jg.exports;const t6=cu(e6),n6="7cab80d02df44a5bb96725be60a45875",ey="https://159.195.9.107:3443/callback.html";console.log("🔍 Debug - Current redirect URI:",ey);console.log("🔍 Debug - Environment VITE_REDIRECT_URI:","https://159.195.9.107:3443/callback.html");const jo=new t6,r6=()=>{const e=["user-read-private","user-read-email","user-read-recently-played","user-top-read","playlist-read-private","playlist-read-collaborative","playlist-modify-public","playlist-modify-private","user-read-playback-state","user-modify-playback-state","user-read-currently-playing","ugc-image-upload"].join(" "),n=`https://accounts.spotify.com/authorize?${new URLSearchParams({client_id:n6,response_type:"code",redirect_uri:ey,scope:e,show_dialog:"true"}).toString()}`;return console.log("🔍 Debug - Generated Spotify Auth URL:",n),n},s6=async(e,t)=>{jo.setAccessToken(e),await jo.play({uris:[t]})},i6=async e=>{jo.setAccessToken(e),await jo.pause()},o6=()=>{const[e,t]=k.useState(!1),n=()=>{t(!0),window.location.href=r6()},r=[{icon:vt,title:"Last Listened",description:"Discover what your partner is listening to right now and play it instantly"},{icon:Yn,title:"Mixed Playlist",description:"AI-powered playlists that blend your musical tastes perfectly"},{icon:Xe,title:"Memory Lane",description:"Create beautiful musical memories and shared experiences together"}];return m.jsx("div",{className:"min-h-screen flex items-center justify-center px-4 bg-black",children:m.jsxs("div",{className:"max-w-4xl w-full relative",children:[m.jsxs(O.div,{initial:{opacity:0,y:50},animate:{opacity:1,y:0},transition:{duration:.8},className:"text-center mb-12",children:[m.jsx(O.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring",stiffness:200},className:"w-20 h-20 mx-auto mb-6 bg-gradient-to-br from-pink-500 to-red-500 rounded-full flex items-center justify-center",children:m.jsx(Xe,{className:"w-10 h-10 text-white"})}),m.jsxs("h1",{className:"text-5xl md:text-6xl font-bold mb-4",children:[m.jsx("span",{className:"gradient-text",children:"Our Musical"}),m.jsx("br",{}),m.jsx("span",{className:"text-white",children:"Journey"})]}),m.jsx("p",{className:"text-xl text-white/70 max-w-2xl mx-auto leading-relaxed",children:"A private space where two hearts connect through music. Discover, share, and create beautiful musical memories together."})]}),m.jsx(O.div,{initial:{opacity:0,y:30},animate:{opacity:1,y:0},transition:{delay:.4,duration:.8},className:"grid md:grid-cols-3 gap-6 mb-12",children:r.map((s,i)=>m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5+i*.1},whileHover:{y:-8,scale:1.03},className:"glass-bubble rounded-3xl p-8 text-center group cursor-pointer",children:[m.jsx(O.div,{whileHover:{rotate:15,scale:1.15},className:"w-16 h-16 mx-auto mb-6 bg-gradient-to-br from-purple-500/30 via-blue-500/30 to-pink-500/30 rounded-2xl flex items-center justify-center backdrop-blur-sm",children:m.jsx(s.icon,{className:"w-8 h-8 text-white"})}),m.jsx("h3",{className:"text-2xl font-bold text-white mb-3",children:s.title}),m.jsx("p",{className:"text-white/70 text-sm leading-relaxed",children:s.description})]},s.title))}),m.jsxs(O.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},transition:{delay:.8,duration:.6},className:"glass-fluid rounded-3xl p-10 max-w-lg mx-auto",children:[m.jsxs("div",{className:"text-center mb-8",children:[m.jsx(O.div,{initial:{scale:0},animate:{scale:1},transition:{delay:1,type:"spring",stiffness:200},className:"w-20 h-20 mx-auto mb-6 bg-gradient-to-br from-purple-500/30 via-blue-500/30 to-pink-500/30 rounded-2xl flex items-center justify-center backdrop-blur-sm",children:m.jsx(Hg,{className:"w-10 h-10 text-white"})}),m.jsx("h2",{className:"text-3xl font-bold text-white mb-3",children:"Begin Your Journey"}),m.jsx("p",{className:"text-white/70 text-lg",children:"Connect your Spotify account to start your musical love story"})]}),m.jsx(O.button,{whileHover:{scale:1.05,boxShadow:"0 15px 40px rgba(147, 51, 234, 0.4)"},whileTap:{scale:.95},onClick:n,disabled:e,className:"w-full bg-gradient-to-r from-purple-600 via-blue-600 to-pink-600 hover:from-purple-700 hover:via-blue-700 hover:to-pink-700 text-white font-bold py-5 px-8 rounded-2xl transition-all duration-300 flex items-center justify-center space-x-3 disabled:opacity-50 shadow-2xl",children:e?m.jsx("div",{className:"w-6 h-6 border-2 border-white border-t-transparent rounded-full animate-spin"}):m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-lg",children:"Connect with Spotify"}),m.jsx(lk,{className:"w-6 h-6"})]})}),m.jsx("p",{className:"text-sm text-white/60 text-center mt-6 leading-relaxed",children:"We'll only access your listening history and playlist data to create your personalized musical journey"})]}),m.jsx(O.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:1,duration:.6},className:"text-center mt-12",children:m.jsx("p",{className:"text-white/40 text-sm",children:"Made with 💕 for a special someone"})})]})})},a6=()=>{var P,j,D,T,z,V,U,R,Q,A,q,_,N,F,L,E,W,X,te,G,be,ri,Jn,Mn,wt,ta,Dc;const{currentUser:e,partnerUser:t,theme:n}=ae(),r=Vr(n),[s,i]=k.useState([]),[o,a]=k.useState(!1),[l,c]=k.useState(null),[d,f]=k.useState(""),[u,h]=k.useState(!1),[p,g]=k.useState(null),[x,v]=k.useState(null);k.useEffect(()=>{let $;const me=async()=>{var Pe,Te,nt;try{const er=(Pe=e==null?void 0:e.user)==null?void 0:Pe.id;if(er){const na=await se(`/users/${er}/recently-played`),Wr=ae.getState().currentUser;Wr&&ae.getState().setCurrentUser({...Wr,recentlyPlayed:na})}const Rc=(nt=(Te=ae.getState().partnerUser)==null?void 0:Te.user)==null?void 0:nt.id;if(Rc){const na=await se(`/users/${Rc}/recently-played`),Wr=ae.getState().partnerUser;Wr&&ae.getState().setPartnerUser({...Wr,recentlyPlayed:na})}}catch{}$=setTimeout(me,3e4)};return me(),()=>clearTimeout($)},[(P=e==null?void 0:e.user)==null?void 0:P.id,(j=t==null?void 0:t.user)==null?void 0:j.id]),k.useEffect(()=>{(async()=>{var me;if((me=e==null?void 0:e.user)!=null&&me.id){a(!0);try{const Pe=await se(`/partners/requests/${e.user.id}`);i(Pe)}catch{i([])}finally{a(!1)}}})()},[(D=e==null?void 0:e.user)==null?void 0:D.id]),k.useEffect(()=>{let $;const me=async()=>{var Te;if((Te=e==null?void 0:e.user)!=null&&Te.id)try{const nt=await se(`/users/${e.user.id}/status`);c(nt)}catch{}},Pe=()=>{if(!(l!=null&&l.nextSyncAt)){f("");return}const Te=l.nextSyncAt-Date.now();if(Te<=0){f("now");return}const nt=Math.floor(Te/6e4),er=Math.floor(Te%6e4/1e3);f(`${nt}m ${er}s`)};return me(),$=setInterval(()=>{Pe()},1e3),()=>clearInterval($)},[(T=e==null?void 0:e.user)==null?void 0:T.id,l==null?void 0:l.nextSyncAt]),k.useEffect(()=>{let $;const me=async()=>{var Pe,Te;try{const nt=(Pe=e==null?void 0:e.user)==null?void 0:Pe.id;nt&&(g(await se(`/users/${nt}/now-playing`)),(Te=t==null?void 0:t.user)!=null&&Te.id?v(await se(`/users/${t.user.id}/now-playing`)):v(null))}catch{}$=setTimeout(me,8e3)};return me(),()=>clearTimeout($)},[(z=e==null?void 0:e.user)==null?void 0:z.id,(V=t==null?void 0:t.user)==null?void 0:V.id]);const y=async()=>{var $;if(($=e==null?void 0:e.user)!=null&&$.id){h(!0);try{await Pt(`/users/${e.user.id}/sync`);const me=await se(`/users/${e.user.id}/status`);c(me);const[Pe,Te]=await Promise.all([se(`/users/${e.user.id}/recently-played`),se(`/users/${e.user.id}/top-tracks?time_range=short_term`)]),nt=ae.getState().currentUser;nt&&ae.getState().setCurrentUser({...nt,recentlyPlayed:Pe,topTracks:Te.map(er=>er.track)}),he.success("Synced latest data")}catch{he.error("Failed to sync")}finally{h(!1)}}},w=async $=>{await Pt(`/partners/requests/${$}/accept`),i(me=>me.filter(Pe=>Pe.id!==$))},b=async $=>{await Pt(`/partners/requests/${$}/decline`),i(me=>me.filter(Pe=>Pe.id!==$))},S=[{title:"Last Listened",description:"See what your partner is listening to right now",icon:vt,href:"/last-listened",primaryColor:((U=r.cssVars)==null?void 0:U.primary)||"#1db954",secondaryColor:((R=r.cssVars)==null?void 0:R.secondary)||"#1ed760",accentColor:((Q=r.cssVars)==null?void 0:Q.accent)||"#00e676"},{title:"Mixed Playlist",description:"Create AI-powered playlists blending both your tastes",icon:Ug,href:"/mixed-playlist",primaryColor:((A=r.cssVars)==null?void 0:A.secondary)||"#1ed760",secondaryColor:((q=r.cssVars)==null?void 0:q.accent)||"#00e676",accentColor:((_=r.cssVars)==null?void 0:_.primary)||"#1db954"},{title:"Memory Lane",description:"Your shared musical journey and memories",icon:Yn,href:"/memory-lane",primaryColor:((N=r.cssVars)==null?void 0:N.accent)||"#00e676",secondaryColor:((F=r.cssVars)==null?void 0:F.primary)||"#1db954",accentColor:((L=r.cssVars)==null?void 0:L.secondary)||"#1ed760"}],C=()=>{var $;return($=e==null?void 0:e.recentlyPlayed)!=null&&$[0]?Pr(e.recentlyPlayed[0].played_at):null};return m.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[m.jsxs("h1",{className:"text-4xl font-bold text-white mb-2",children:["Welcome back, ",m.jsx("span",{className:"gradient-text",children:(E=e==null?void 0:e.user)==null?void 0:E.display_name})]}),m.jsx("p",{className:"text-white/70 text-lg",children:"Ready to explore your musical connection together?"})]}),m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"grid md:grid-cols-2 gap-6 mb-8",children:[m.jsxs("div",{className:"glass rounded-2xl p-6",children:[m.jsx("div",{className:"text-white/70 mb-2",children:"You"}),p!=null&&p.is_playing&&(p!=null&&p.item)?m.jsxs("div",{className:"flex items-center gap-4",children:[m.jsx("img",{src:((te=(X=(W=p.item.album)==null?void 0:W.images)==null?void 0:X[0])==null?void 0:te.url)||"/placeholder-album.png",className:"w-14 h-14 rounded"}),m.jsxs("div",{className:"min-w-0",children:[m.jsx("div",{className:"text-white font-semibold truncate",children:p.item.name}),m.jsx("div",{className:"text-white/70 text-sm truncate",children:(G=p.item.artists)==null?void 0:G.map($=>$.name).join(", ")})]})]}):m.jsx("div",{className:"text-white/50",children:"Not playing"})]}),m.jsxs("div",{className:"glass rounded-2xl p-6",children:[m.jsx("div",{className:"text-white/70 mb-2",children:"Partner"}),x!=null&&x.is_playing&&(x!=null&&x.item)?m.jsxs("div",{className:"flex items-center gap-4",children:[m.jsx("img",{src:((Jn=(ri=(be=x.item.album)==null?void 0:be.images)==null?void 0:ri[0])==null?void 0:Jn.url)||"/placeholder-album.png",className:"w-14 h-14 rounded"}),m.jsxs("div",{className:"min-w-0",children:[m.jsx("div",{className:"text-white font-semibold truncate",children:x.item.name}),m.jsx("div",{className:"text-white/70 text-sm truncate",children:(Mn=x.item.artists)==null?void 0:Mn.map($=>$.name).join(", ")})]})]}):m.jsx("div",{className:"text-white/50",children:"Not playing"})]})]}),m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:"mb-8",children:[m.jsxs("div",{className:"flex items-center justify-between mb-4",children:[m.jsx("div",{className:"text-white/70 text-sm",children:(l==null?void 0:l.lastSyncedAt)&&m.jsxs("span",{children:["Last sync: ",new Date(l.lastSyncedAt).toLocaleTimeString()," • Next in: ",d||"—"]})}),m.jsx("button",{onClick:y,disabled:u,className:"bg-white/10 hover:bg-white/20 text-white px-4 py-2 rounded-lg text-sm disabled:opacity-50",children:u?"Refreshing…":"Hard Refresh"})]}),t?m.jsx("div",{className:"glass-bubble rounded-3xl p-8 border border-spotify-green/30 glow",children:m.jsxs("div",{className:"flex items-center space-x-6",children:[m.jsx("div",{className:"w-16 h-16 bg-gradient-to-br from-spotify-green to-green-600 rounded-2xl flex items-center justify-center",children:m.jsx(Xe,{className:"w-8 h-8 text-white"})}),m.jsxs("div",{children:[m.jsxs("h3",{className:"text-xl font-semibold text-white",children:["Connected with ",(wt=t.user)==null?void 0:wt.display_name]}),m.jsx("p",{className:"text-white/70",children:"Your musical journey is ready to begin! 💕"})]})]})}):m.jsx("div",{className:"glass-bubble rounded-3xl p-8 border border-orange-500/30",children:m.jsxs("div",{className:"flex items-center space-x-6",children:[m.jsx("div",{className:"w-16 h-16 bg-gradient-to-br from-orange-500 to-red-500 rounded-2xl flex items-center justify-center",children:m.jsx(Ac,{className:"w-8 h-8 text-white"})}),m.jsxs("div",{children:[m.jsx("h3",{className:"text-xl font-semibold text-white",children:"Invite your partner"}),m.jsx("p",{className:"text-white/70 mb-2",children:"Ask your partner to search you in the app and send a request."}),o?m.jsx("div",{className:"text-white/60",children:"Loading requests..."}):s.length>0?m.jsx("div",{className:"space-y-3",children:s.map($=>m.jsxs("div",{className:"flex items-center justify-between bg-white/5 rounded-lg p-3",children:[m.jsxs("div",{className:"text-white/80 text-sm",children:["Request from ",$.from_user_id]}),m.jsxs("div",{className:"space-x-2",children:[m.jsx("button",{onClick:()=>w($.id),className:"bg-spotify-green hover:bg-spotify-green/90 text-white px-3 py-1 rounded-md text-sm",children:"Accept"}),m.jsx("button",{onClick:()=>b($.id),className:"bg-white/10 hover:bg-white/20 text-white px-3 py-1 rounded-md text-sm",children:"Decline"})]})]},$.id))}):m.jsx("div",{className:"text-white/60 text-sm",children:"No incoming requests yet"})]})]})})]}),m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.2},className:"grid grid-cols-1 md:grid-cols-3 gap-6 mb-8",children:[m.jsx("div",{className:"glass-bubble rounded-2xl p-6",children:m.jsxs("div",{className:"flex items-center space-x-4",children:[m.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-blue-500/30 to-cyan-500/30 rounded-xl flex items-center justify-center",children:m.jsx(Po,{className:"w-6 h-6 text-blue-400"})}),m.jsxs("div",{children:[m.jsx("p",{className:"text-white/70 text-sm",children:"Your last played"}),m.jsx("p",{className:"text-white font-semibold",children:C()||"No recent plays"})]})]})}),m.jsx("div",{className:"glass-bubble rounded-2xl p-6",children:m.jsxs("div",{className:"flex items-center space-x-4",children:[m.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-green-500/30 to-emerald-500/30 rounded-xl flex items-center justify-center",children:m.jsx(gk,{className:"w-6 h-6 text-green-400"})}),m.jsxs("div",{children:[m.jsx("p",{className:"text-white/70 text-sm",children:"Top tracks analyzed"}),m.jsxs("p",{className:"text-white font-semibold",children:[((ta=e==null?void 0:e.topTracks)==null?void 0:ta.length)||0," songs"]})]})]})}),m.jsx("div",{className:"glass-bubble rounded-2xl p-6",children:m.jsxs("div",{className:"flex items-center space-x-4",children:[m.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-purple-500/30 to-pink-500/30 rounded-xl flex items-center justify-center",children:m.jsx(Ss,{className:"w-6 h-6 text-purple-400"})}),m.jsxs("div",{children:[m.jsx("p",{className:"text-white/70 text-sm",children:"Recently played"}),m.jsxs("p",{className:"text-white font-semibold",children:[((Dc=e==null?void 0:e.recentlyPlayed)==null?void 0:Dc.length)||0," tracks"]})]})]})})]}),m.jsx(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},className:"grid md:grid-cols-3 gap-6",children:S.map(($,me)=>m.jsx(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.4+me*.1},whileHover:{y:-5,scale:1.02},children:m.jsx(zi,{to:$.href,children:m.jsxs("div",{className:`glass rounded-2xl p-6 h-full border ${$.borderColor} group cursor-pointer transition-all duration-300 hover:shadow-xl`,children:[m.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center mb-4 group-hover:scale-110 transition-transform duration-300",style:{background:`linear-gradient(135deg, ${$.primaryColor}20 0%, ${$.secondaryColor}10 100%)`,border:`1px solid ${$.primaryColor}30`},children:m.jsx($.icon,{className:"w-6 h-6",style:{color:$.primaryColor}})}),m.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:$.title}),m.jsx("p",{className:"text-white/70 text-sm leading-relaxed mb-4",children:$.description}),m.jsx("div",{className:"w-full h-1 rounded-full opacity-0 group-hover:opacity-100 transition-opacity duration-300",style:{background:`linear-gradient(90deg, ${$.primaryColor} 0%, ${$.secondaryColor} 100%)`}})]})})},$.title))}),(e==null?void 0:e.recentlyPlayed)&&e.recentlyPlayed.length>0&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.6},className:"mt-8",children:[m.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"Your Recent Activity"}),m.jsx("div",{className:"glass rounded-2xl p-6",children:m.jsx("div",{className:"space-y-4",children:e.recentlyPlayed.slice(0,3).map(($,me)=>{var Pe,Te;return m.jsxs(O.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.7+me*.1},className:"flex items-center space-x-4 p-3 rounded-lg hover:bg-white/5 transition-colors",children:[m.jsx("img",{src:((Pe=$.track.album.images[0])==null?void 0:Pe.url)||"/placeholder-album.png",alt:$.track.album.name,className:"w-12 h-12 rounded-lg object-cover"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h4",{className:"text-white font-medium",children:$.track.name}),m.jsx("p",{className:"text-white/70 text-sm",children:(Te=$.track.artists[0])==null?void 0:Te.name})]}),m.jsx("div",{className:"text-white/50 text-sm",children:Pr($.played_at)})]},$.track.id)})})})]})]})};let ji=!1;const Rh=()=>{const[e]=Ax(),t=Wo(),{setCurrentUser:n,setPartnerUser:r,currentUser:s}=ae(),[i,o]=k.useState("loading"),[a,l]=k.useState("");k.useEffect(()=>{(async()=>{if(ji){console.log("🔍 CallbackPage - Already processing globally, skipping...");return}ji=!0,console.log("🔍 CallbackPage - Global processing flag set to TRUE");try{const u=e.get("code"),h=e.get("error");if(console.log("🔍 CallbackPage - Code:",u),console.log("🔍 CallbackPage - Error:",h),h)throw new Error("Spotify authorization was denied");if(!u)throw new Error("No authorization code received");l("Exchanging authorization code..."),console.log("🔍 CallbackPage - Exchanging code with backend...");const p=await pb("/auth/exchange",{code:u});l("Syncing your music data..."),await Pt(`/users/${p.uid}/sync`,void 0,p.token),l("Loading your profile...");const[g,x,v]=await Promise.all([se(`/users/${p.uid}`),se(`/users/${p.uid}/recently-played`),se(`/users/${p.uid}/top-tracks?time_range=short_term`)]),y={user:g,accessToken:p.access_token,refreshToken:p.refresh_token,isAuthenticated:!0,recentlyPlayed:x,topTracks:v.map(w=>w.track),topArtists:[],jwt:p.token};localStorage.setItem("spotify-user",JSON.stringify(y)),s?(r(y),localStorage.setItem("spotify-partner",JSON.stringify(y)),l("Partner connected! Your musical journey begins...")):(n(y),l("Welcome! Setting up your musical journey...")),o("success"),he.success(s?"Partner connected successfully!":"Successfully connected to Spotify!",{duration:3e3}),setTimeout(()=>{t("/"),setTimeout(()=>{ji=!1,console.log("🔍 CallbackPage - Global processing flag set to FALSE (after success)")},1e3)},2e3)}catch(u){console.error("🔍 CallbackPage - ERROR:",u),console.error("🔍 CallbackPage - Error details:",{message:u instanceof Error?u.message:"Unknown error",stack:u instanceof Error?u.stack:void 0}),o("error"),l(u instanceof Error?u.message:"An unexpected error occurred"),he.error("Failed to connect to Spotify. Please try again."),setTimeout(()=>{t("/"),setTimeout(()=>{ji=!1,console.log("🔍 CallbackPage - Global processing flag set to FALSE (after error)")},1e3)},3e3)}})()},[e,t,n,r,s]);const c=()=>{switch(i){case"loading":return m.jsx(fk,{className:"w-12 h-12 text-spotify-green animate-spin"});case"success":return m.jsx(dk,{className:"w-12 h-12 text-green-400"});case"error":return m.jsx(xk,{className:"w-12 h-12 text-red-400"})}},d=()=>{switch(i){case"loading":return"border-spotify-green/30";case"success":return"border-green-400/30";case"error":return"border-red-400/30"}};return m.jsx("div",{className:"min-h-screen flex items-center justify-center px-4 bg-black",children:m.jsxs(O.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"glass-fluid rounded-3xl p-10 max-w-md w-full text-center",children:[m.jsx(O.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring",stiffness:200},className:`w-20 h-20 mx-auto mb-6 rounded-full border-2 flex items-center justify-center ${d()}`,children:c()}),m.jsxs(O.h2,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},className:"text-2xl font-bold text-white mb-4",children:[i==="loading"&&"Connecting...",i==="success"&&"Success!",i==="error"&&"Connection Failed"]}),m.jsx(O.p,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.4},className:"text-white/70 mb-6",children:a}),i==="loading"&&m.jsx(O.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.5},className:"w-full bg-white/10 rounded-full h-2 mb-4",children:m.jsx(O.div,{className:"bg-spotify-green h-2 rounded-full",initial:{width:0},animate:{width:"100%"},transition:{duration:3,ease:"easeInOut"}})}),i==="error"&&m.jsx(O.button,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5},whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>t("/"),className:"bg-spotify-green hover:bg-spotify-green/90 text-white font-semibold py-3 px-6 rounded-lg transition-all duration-300",children:"Try Again"}),i==="success"&&m.jsx(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5},className:"text-spotify-green text-sm",children:"Redirecting you to your musical journey..."})]})})},l6=()=>{var g,x,v;const{currentUser:e,partnerUser:t,currentTrack:n,isPlaying:r,setCurrentTrack:s,setIsPlaying:i,theme:o}=ae(),a=Vr(o),[l,c]=k.useState(!1),[d,f]=k.useState(null),u=k.useMemo(()=>{const y=((e==null?void 0:e.recentlyPlayed)||[]).map(P=>({who:"you",played_at:new Date(P.played_at).getTime(),track:P.track,key:`you-${P.track.id}-${P.played_at}`})),w=((t==null?void 0:t.recentlyPlayed)||[]).map(P=>({who:"partner",played_at:new Date(P.played_at).getTime(),track:P.track,key:`partner-${P.track.id}-${P.played_at}`})),b=[...y,...w].sort((P,j)=>j.played_at-P.played_at).slice(0,30),S=new Set,C=new Set;return b.forEach(P=>{const j=P.track.id;S.has(j)?C.add(j):S.add(j)}),{items:b,overlaps:C}},[e==null?void 0:e.recentlyPlayed,t==null?void 0:t.recentlyPlayed]),h=async(y,w)=>{var b,S;if(!(e!=null&&e.accessToken)){he.error("Not authenticated with Spotify");return}try{c(!0),f(w),r&&d===w?(await i6(e.accessToken),i(!1),s(null),f(null)):(await s6(e.accessToken,y),i(!0),s(((S=(b=e.recentlyPlayed)==null?void 0:b.find(C=>C.track.id===w))==null?void 0:S.track)||null)),he.success(r&&d===w?"Paused":"Now playing")}catch(C){console.error("Playback error:",C),he.error("Failed to play track. Make sure Spotify is open on your device.")}finally{c(!1)}},p=({user:y,title:w,isPartner:b=!1})=>{var C,P,j,D,T;if(!((C=y==null?void 0:y.recentlyPlayed)!=null&&C.length))return m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-8 text-center",children:[m.jsx(vt,{className:"w-16 h-16 mx-auto mb-4 text-white/30"}),m.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"No recent activity"}),m.jsxs("p",{className:"text-white/70",children:[b?"Your partner":"You"," haven't played any music recently"]})]});const S=y.recentlyPlayed[0];return m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-6",children:[m.jsxs("div",{className:"flex items-center space-x-4 mb-6",children:[m.jsx("div",{className:`w-12 h-12 rounded-full flex items-center justify-center ${b?"bg-gradient-to-br from-pink-500 to-purple-600":"bg-gradient-to-br from-blue-500 to-cyan-600"}`,children:m.jsx(Ss,{className:"w-6 h-6 text-white"})}),m.jsxs("div",{children:[m.jsx("h2",{className:"text-2xl font-bold text-white",children:w}),m.jsxs("p",{className:"text-white/70",children:["Last played: ",Pr(S.played_at)]})]})]}),m.jsx(O.div,{whileHover:{scale:1.02},className:"bg-white/5 rounded-xl p-6 mb-6 border border-white/10",children:m.jsxs("div",{className:"flex items-center space-x-6",children:[m.jsxs("div",{className:"relative",children:[m.jsx("img",{src:((P=S.track.album.images[0])==null?void 0:P.url)||"/placeholder-album.png",alt:S.track.album.name,className:"w-20 h-20 rounded-lg object-cover"}),r&&d===S.track.id&&m.jsx("div",{className:"absolute inset-0 rounded-lg flex items-center justify-center",style:{backgroundColor:`${((j=a.cssVars)==null?void 0:j.primary)||"#1db954"}20`},children:m.jsx(yk,{className:"w-6 h-6",style:{color:((D=a.cssVars)==null?void 0:D.primary)||"#1db954"}})})]}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h3",{className:"text-xl font-semibold text-white mb-1",children:S.track.name}),m.jsx("p",{className:"text-white/70 mb-2",children:S.track.artists.map(z=>z.name).join(", ")}),m.jsxs("p",{className:"text-white/50 text-sm",children:[S.track.album.name," • ",Zg(S.track.duration_ms)]})]}),m.jsxs("div",{className:"flex items-center space-x-3",children:[m.jsx("button",{onClick:()=>h(S.track.external_urls.spotify,S.track.id),disabled:l,className:"w-12 h-12 rounded-full flex items-center justify-center transition-all duration-300 text-white disabled:opacity-50",style:{backgroundColor:r&&d===S.track.id?"#ef4444":((T=a.cssVars)==null?void 0:T.primary)||"#1db954"},onMouseEnter:z=>{l||(z.currentTarget.style.opacity="0.9")},onMouseLeave:z=>{l||(z.currentTarget.style.opacity="1")},children:l&&d===S.track.id?m.jsx("div",{className:"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"}):r&&d===S.track.id?m.jsx(pk,{className:"w-5 h-5"}):m.jsx(Nh,{className:"w-5 h-5 ml-0.5"})}),m.jsx("a",{href:S.track.external_urls.spotify,target:"_blank",rel:"noopener noreferrer",className:"w-10 h-10 rounded-full bg-white/10 hover:bg-white/20 flex items-center justify-center transition-colors",children:m.jsx(Bg,{className:"w-4 h-4 text-white"})})]})]})}),m.jsxs("div",{children:[m.jsxs("h3",{className:"text-lg font-semibold text-white mb-4 flex items-center space-x-2",children:[m.jsx(Po,{className:"w-5 h-5"}),m.jsx("span",{children:"Recent History"})]}),m.jsx("div",{className:"space-y-3",children:y.recentlyPlayed.slice(0,5).map((z,V)=>{var U,R,Q;return m.jsxs(O.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:V*.1},className:"flex items-center space-x-4 p-3 rounded-lg hover:bg-white/5 transition-colors group",children:[m.jsx("img",{src:((U=z.track.album.images[0])==null?void 0:U.url)||"/placeholder-album.png",alt:z.track.album.name,className:"w-12 h-12 rounded-lg object-cover"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h4",{className:"text-white font-medium group-hover:text-spotify-green transition-colors",children:z.track.name}),m.jsx("p",{className:"text-white/70 text-sm",children:(R=z.track.artists[0])==null?void 0:R.name})]}),m.jsx("div",{className:"text-white/50 text-sm",children:Pr(z.played_at)}),m.jsx("button",{onClick:()=>h(z.track.external_urls.spotify,z.track.id),disabled:l,className:"opacity-0 group-hover:opacity-100 w-8 h-8 rounded-full flex items-center justify-center transition-all disabled:opacity-50",style:{backgroundColor:((Q=a.cssVars)==null?void 0:Q.primary)||"#1db954"},onMouseEnter:A=>{l||(A.currentTarget.style.opacity="0.9")},onMouseLeave:A=>{l||(A.currentTarget.style.opacity="1")},children:m.jsx(Nh,{className:"w-4 h-4 text-white ml-0.5"})})]},z.track.id)})})]})]})};return m.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[m.jsxs("h1",{className:"text-4xl font-bold text-white mb-2 flex items-center space-x-3",children:[m.jsx(Xe,{className:"w-10 h-10",style:{color:((g=a.cssVars)==null?void 0:g.primary)||"#1db954"}}),m.jsx("span",{children:"What's Playing"})]}),m.jsx("p",{className:"text-white/70 text-lg",children:"Discover what you and your partner are listening to right now"})]}),m.jsxs("div",{className:"grid lg:grid-cols-2 gap-8",children:[e&&m.jsx(p,{user:e,title:`${(x=e.user)==null?void 0:x.display_name}'s Music`,isPartner:!1}),t&&m.jsx(p,{user:t,title:`${(v=t.user)==null?void 0:v.display_name}'s Music`,isPartner:!0}),!t&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-8 text-center",children:[m.jsx(Xe,{className:"w-16 h-16 mx-auto mb-4 text-pink-400"}),m.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"Waiting for your partner"}),m.jsx("p",{className:"text-white/70 mb-4",children:"Invite your partner to connect their Spotify account to see their music"}),m.jsx("button",{className:"bg-pink-500 hover:bg-pink-600 text-white px-6 py-3 rounded-lg transition-colors",children:"Send Invitation"})]})]}),e&&t&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-8 mt-8",children:[m.jsxs("h3",{className:"text-lg font-semibold text-white mb-4 flex items-center space-x-2",children:[m.jsx(Po,{className:"w-5 h-5"}),m.jsx("span",{children:"Shared Timeline"})]}),m.jsx("div",{className:"space-y-3",children:u.items.map(y=>{var w,b,S,C,P;return m.jsxs("div",{className:"flex items-center gap-4 p-3 rounded-lg bg-white/5",children:[m.jsx("img",{src:((S=(b=(w=y.track.album)==null?void 0:w.images)==null?void 0:b[0])==null?void 0:S.url)||"/placeholder-album.png",alt:((C=y.track.album)==null?void 0:C.name)||"Album",className:"w-10 h-10 rounded"}),m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-white font-medium truncate",children:y.track.name}),u.overlaps.has(y.track.id)&&m.jsx("span",{className:"text-pink-400 text-sm",children:"💕"})]}),m.jsx("div",{className:"text-white/70 text-sm truncate",children:(P=y.track.artists)==null?void 0:P.map(j=>j.name).join(", ")})]}),m.jsxs("div",{className:"text-white/50 text-xs w-32 text-right",children:[Pr(new Date(y.played_at).toISOString()),m.jsx("div",{className:"text-white/60",children:y.who==="you"?"You":"Partner"})]})]},y.key)})})]})]})},u6=({imageUrl:e,alt:t,fallbackGradient:n})=>{const[r,s]=k.useState(null),[i,o]=k.useState(!0),[a,l]=k.useState(!1);return k.useEffect(()=>{e.startsWith("http")?(s(e),o(!1)):(async()=>{try{const d=await fetch(`${Br}${e}`);if(d.ok){const f=await d.json();s(f.dataUrl)}else l(!0)}catch{l(!0)}finally{o(!1)}})()},[e]),i?m.jsx("div",{className:"w-full h-full bg-gradient-to-br from-gray-500 to-gray-600 flex items-center justify-center",children:m.jsx(vt,{className:"w-8 h-8 text-white animate-pulse"})}):a||!r?m.jsx("div",{className:`w-full h-full flex items-center justify-center ${n}`,children:m.jsx(vt,{className:"w-8 h-8 text-white"})}):m.jsx("img",{src:r,alt:t,className:"w-full h-full object-cover",onError:()=>l(!0)})};function Vh(e){var r;const t=(r=e.vibe)==null?void 0:r.toLowerCase(),n=e.genres||[];if(t)switch(t){case"energetic":return"bg-gradient-to-br from-red-500 to-orange-500";case"chill":return"bg-gradient-to-br from-blue-500 to-teal-500";case"romantic":return"bg-gradient-to-br from-pink-500 to-rose-500";case"party":return"bg-gradient-to-br from-purple-500 to-pink-500";case"workout":return"bg-gradient-to-br from-green-500 to-lime-500";case"study":return"bg-gradient-to-br from-indigo-500 to-blue-500";case"sad":return"bg-gradient-to-br from-gray-500 to-slate-500";case"happy":return"bg-gradient-to-br from-yellow-500 to-orange-500"}if(n.length>0)switch(n[0].toLowerCase()){case"pop":return"bg-gradient-to-br from-pink-500 to-purple-500";case"rock":return"bg-gradient-to-br from-red-500 to-black";case"hip-hop":case"rap":return"bg-gradient-to-br from-yellow-500 to-red-500";case"electronic":case"edm":return"bg-gradient-to-br from-cyan-500 to-blue-500";case"jazz":return"bg-gradient-to-br from-amber-500 to-orange-500";case"classical":return"bg-gradient-to-br from-slate-500 to-gray-600";case"country":return"bg-gradient-to-br from-green-600 to-yellow-600";case"r&b":return"bg-gradient-to-br from-purple-600 to-pink-600";case"indie":return"bg-gradient-to-br from-teal-500 to-green-500";case"alternative":return"bg-gradient-to-br from-gray-600 to-purple-600"}return"bg-gradient-to-br from-purple-500 to-pink-500"}const c6=()=>{var V,U,R,Q;const{currentUser:e,partnerUser:t,mixedPlaylists:n,addMixedPlaylist:r,removeMixedPlaylist:s,setMixedPlaylists:i,theme:o}=ae(),a=Vr(o),[l,c]=k.useState(!1),[d,f]=k.useState(!1),[u,h]=k.useState(null),[p,g]=k.useState(""),[x,v]=k.useState(""),[y,w]=k.useState(!0),[b,S]=k.useState(!1),C=x.split(",").map(A=>A.trim()).filter(A=>A.length>0);k.useEffect(()=>{(async()=>{if(e!=null&&e.jwt)try{console.log("Loading playlists from database...");const q=await se("/playlists/mixed",e.jwt);console.log("Loaded playlists:",q.playlists);const _=q.playlists.map(N=>{var L;const F=N.track_uris?JSON.parse(N.track_uris):[];return console.log("Processing playlist:",N.name,"track_uris count:",F.length,"raw track_uris:",((L=N.track_uris)==null?void 0:L.substring(0,100))+"..."),{id:N.id,name:N.name,description:N.description,tracks:[],createdAt:new Date(N.created_at),createdBy:"AI Magic ✨",spotifyId:N.creator_spotify_id,spotifyUrl:N.creator_spotify_url,partnerSpotifyId:N.partner_spotify_id,partnerSpotifyUrl:N.partner_spotify_url,vibe:N.vibe,genres:N.genres?JSON.parse(N.genres):[],trackUris:F,spotifyImageUrl:N.creator_spotify_image_url}});i(_)}catch(q){console.error("Failed to load playlists:",q)}})()},[e==null?void 0:e.jwt]);const P=async()=>{var A,q,_,N,F,L;if(!u||!((A=e==null?void 0:e.user)!=null&&A.id)){he.error("Unable to create playlist");return}if(!(e!=null&&e.jwt)){he.error("Please login again");return}f(!0);try{const E={partnerId:((q=t==null?void 0:t.user)==null?void 0:q.id)||e.user.id,createForBoth:!1,includeKnown:!0,name:u.name,description:u.description},W=await Pt("/playlists/mixed",E,e.jwt);r({...u,spotifyId:(N=(_=W==null?void 0:W.createdFor)==null?void 0:_.creator)==null?void 0:N.playlistId,spotifyUrl:(L=(F=W==null?void 0:W.createdFor)==null?void 0:F.creator)==null?void 0:L.url}),he.success("Playlist created on Spotify!"),h(null)}catch(E){console.error("Spotify playlist creation error:",E),he.error("Failed to create playlist on Spotify")}finally{f(!1)}},j=async()=>{var A,q,_,N;if(!((A=e==null?void 0:e.user)!=null&&A.id)||!((q=t==null?void 0:t.user)!=null&&q.id)){he.error("Missing users");return}if(!(e!=null&&e.jwt)){he.error("Please login again");return}f(!0);try{const F={partnerId:t.user.id,createForBoth:b,includeKnown:y,vibe:p||void 0,genres:C.length?C:void 0,description:(u==null?void 0:u.description)||"An AI-blended mix with fresh recommendations"},L=await Pt("/playlists/mixed",F,e.jwt);b&&L.createdFor.partnerError?he.success("Your playlist created! Partner sync failed: "+L.createdFor.partnerError):b&&L.createdFor.partner?he.success("Enhanced playlist created on both accounts!"):he.success("Enhanced playlist created!");const E={id:L.id,name:L.name,description:F.description,tracks:[],createdAt:new Date,createdBy:"AI Magic ✨",spotifyId:L.createdFor.creator.playlistId,spotifyUrl:L.createdFor.creator.url,partnerSpotifyId:(_=L.createdFor.partner)==null?void 0:_.playlistId,partnerSpotifyUrl:(N=L.createdFor.partner)==null?void 0:N.url,vibe:F.vibe,genres:F.genres||[],trackUris:L.trackUris||[],spotifyImageUrl:L.spotifyImageUrl};r(E),h(null)}catch(F){console.error(F),he.error("Failed to create enhanced playlist")}finally{f(!1)}},D=()=>{u&&(r(u),h(null),he.success("Playlist saved locally!"))},T=({playlist:A,isNew:q=!1})=>{var _;return m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},whileHover:{scale:1.02},className:`glass rounded-2xl p-6 ${q?"border-spotify-green/50":"border-white/10"}`,children:[m.jsxs("div",{className:"flex items-start justify-between mb-4",children:[m.jsxs("div",{className:"flex items-center space-x-4",children:[m.jsxs("div",{className:`w-16 h-16 rounded-xl flex items-center justify-center overflow-hidden ${q?"bg-gradient-to-br from-spotify-green to-green-600":"bg-gradient-to-br from-purple-500 to-pink-500"}`,children:[q?m.jsx(Yn,{className:"w-8 h-8 text-white"}):A.spotifyImageUrl?m.jsx(u6,{imageUrl:A.spotifyImageUrl,alt:A.name,fallbackGradient:Vh(A)}):null,!q&&m.jsx("div",{className:`w-full h-full flex items-center justify-center ${A.spotifyImageUrl?"bg-gradient-to-br from-purple-500 to-pink-500":Vh(A)}`,style:{display:A.spotifyImageUrl?"none":"flex"},children:m.jsx(vt,{className:"w-8 h-8 text-white"})})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"text-xl font-semibold text-white",children:A.name}),m.jsx("p",{className:"text-white/70 text-sm",children:A.description}),m.jsxs("div",{className:"flex flex-wrap gap-1 mt-1 mb-1",children:[A.vibe&&m.jsx("span",{className:"px-2 py-0.5 bg-blue-500/20 text-blue-300 text-xs rounded-full",children:A.vibe}),A.genres&&A.genres.length>0&&A.genres.slice(0,2).map((N,F)=>m.jsx("span",{className:"px-2 py-0.5 bg-green-500/20 text-green-300 text-xs rounded-full",children:N},F))]}),m.jsxs("p",{className:"text-white/50 text-xs",children:["Created ",q?"just now":new Date(A.createdAt).toLocaleDateString()," • ",A.tracks.length||((_=A.trackUris)==null?void 0:_.length)||0," tracks"]})]})]}),m.jsxs("div",{className:"flex items-center space-x-2",children:[A.spotifyUrl&&m.jsx("a",{href:A.spotifyUrl,target:"_blank",rel:"noopener noreferrer",className:"w-8 h-8 rounded-full bg-white/10 hover:bg-white/20 flex items-center justify-center transition-colors",title:"Open in Spotify",children:m.jsx(Bg,{className:"w-4 h-4 text-white"})}),A.partnerSpotifyUrl&&m.jsx("a",{href:A.partnerSpotifyUrl,target:"_blank",rel:"noopener noreferrer",className:"w-8 h-8 rounded-full bg-pink-500/20 hover:bg-pink-500/30 flex items-center justify-center transition-colors",title:"Partner's playlist in Spotify",children:m.jsx(Xe,{className:"w-4 h-4 text-pink-400"})}),!q&&m.jsx("button",{onClick:async()=>{try{e!=null&&e.jwt&&await mb(`/playlists/mixed/${A.id}`,e.jwt),s(A.id),he.success("Playlist deleted successfully")}catch(N){console.error("Failed to delete playlist:",N),he.error("Failed to delete playlist")}},className:"w-8 h-8 rounded-full bg-red-500/20 hover:bg-red-500/30 flex items-center justify-center transition-colors",children:m.jsx(Wg,{className:"w-4 h-4 text-red-400"})})]})]}),m.jsx("div",{className:"space-y-3 max-h-64 overflow-y-auto",children:A.tracks.length>0?m.jsxs(m.Fragment,{children:[A.tracks.slice(0,5).map((N,F)=>{var L,E,W,X,te,G;return m.jsxs(O.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:F*.1},className:"flex items-center space-x-3 p-2 rounded-lg hover:bg-white/5 transition-colors",children:[m.jsx("img",{src:((W=(E=(L=N.album)==null?void 0:L.images)==null?void 0:E[0])==null?void 0:W.url)||"/placeholder-album.png",alt:((X=N.album)==null?void 0:X.name)||"Unknown Album",className:"w-10 h-10 rounded-lg object-cover"}),m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsx("h4",{className:"text-white font-medium truncate",children:N.name}),m.jsx("p",{className:"text-white/70 text-sm truncate",children:((G=(te=N.artists)==null?void 0:te[0])==null?void 0:G.name)||"Unknown Artist"})]}),m.jsx("div",{className:"text-white/50 text-sm",children:Zg(N.duration_ms)})]},N.id)}),A.tracks.length>5&&m.jsxs("div",{className:"text-center text-white/50 text-sm py-2",children:["+",A.tracks.length-5," more tracks"]})]}):A.trackUris&&A.trackUris.length>0?m.jsx("div",{className:"text-center py-4"}):m.jsx("div",{className:"text-center text-white/50 text-sm py-4",children:"No tracks available"})}),q&&m.jsxs("div",{className:"flex items-center space-x-3 mt-6 pt-4 border-t border-white/10",children:[m.jsx("button",{onClick:P,disabled:d||b,className:"flex-1 bg-spotify-green hover:bg-spotify-green/90 text-white font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center space-x-2 disabled:opacity-50",children:d?m.jsx("div",{className:"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"}):m.jsxs(m.Fragment,{children:[m.jsx(Ac,{className:"w-4 h-4"}),m.jsx("span",{children:b?"Disabled (using Create for both)":"Create on Spotify"})]})}),m.jsx("button",{onClick:D,className:"px-4 py-3 bg-white/10 hover:bg-white/20 text-white rounded-lg transition-colors",children:"Save Locally"})]})]})},z=(e==null?void 0:e.topTracks)&&(t==null?void 0:t.topTracks);return m.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[m.jsxs("h1",{className:"text-4xl font-bold text-white mb-2 flex items-center space-x-3",children:[m.jsx(Yn,{className:"w-10 h-10",style:{color:((V=a.cssVars)==null?void 0:V.primary)||"#1db954"}}),m.jsx("span",{children:"Mixed Playlists"})]}),m.jsx("p",{className:"text-white/70 text-lg",children:"AI-powered playlists that perfectly blend your musical tastes together"})]}),z&&m.jsx(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:"mb-8",children:m.jsxs("div",{className:"glass rounded-2xl p-8 text-center",style:{borderColor:`${((U=a.cssVars)==null?void 0:U.primary)||"#1db954"}30`},children:[m.jsx("div",{className:"w-16 h-16 mx-auto mb-4 rounded-full flex items-center justify-center",style:{background:`linear-gradient(135deg, ${((R=a.cssVars)==null?void 0:R.primary)||"#1db954"} 0%, ${((Q=a.cssVars)==null?void 0:Q.secondary)||"#1ed760"} 100%)`},children:m.jsx(vk,{className:"w-8 h-8 text-white"})}),m.jsx("h2",{className:"text-2xl font-bold text-white mb-2",children:"Create Your Perfect Mix"}),m.jsx("p",{className:"text-white/70 mb-6 max-w-2xl mx-auto",children:"Our AI analyzes both your music tastes and creates a playlist that represents your unique musical connection"}),m.jsxs("div",{className:"mt-4 text-white/50 text-sm",children:["Analyzing ",e.topTracks.length+t.topTracks.length," tracks from both users"]}),m.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 text-left mt-8",children:[m.jsxs("div",{children:[m.jsx("label",{className:"block text-white/80 text-sm mb-1",children:"Vibe"}),m.jsxs("select",{className:"w-full bg-white/10 text-white rounded-lg p-2 appearance-none focus:outline-none focus:ring-2 focus:ring-spotify-green",value:p,onChange:A=>g(A.target.value),children:[m.jsx("option",{value:"",children:"Auto"}),m.jsx("option",{value:"energetic",children:"Energetic"}),m.jsx("option",{value:"chill",children:"Chill"}),m.jsx("option",{value:"happy",children:"Happy"}),m.jsx("option",{value:"sad",children:"Sad"}),m.jsx("option",{value:"party",children:"Party"}),m.jsx("option",{value:"focus",children:"Focus"})]})]}),m.jsxs("div",{children:[m.jsx("label",{className:"block text-white/80 text-sm mb-1",children:"Genres (comma-separated)"}),m.jsx("input",{className:"w-full bg-white/10 text-white rounded-lg p-2 placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-spotify-green",placeholder:"pop, rock, edm",value:x,onChange:A=>v(A.target.value)})]}),m.jsxs("label",{className:"flex items-center space-x-2 text-white/80",children:[m.jsx("input",{type:"checkbox",checked:y,onChange:A=>w(A.target.checked)}),m.jsx("span",{children:"Include songs we already know"})]}),m.jsxs("label",{className:"flex items-center space-x-2 text-white/80",children:[m.jsx("input",{type:"checkbox",checked:b,onChange:A=>S(A.target.checked)}),m.jsx("span",{children:"Create playlist on both accounts"}),b&&m.jsx("span",{className:"text-xs text-pink-400 ml-2",children:"✨ Synced"})]})]}),m.jsx("div",{className:"flex items-center justify-center gap-3 mt-6",children:m.jsx("button",{onClick:j,disabled:d,className:"bg-white/10 hover:bg-white/20 text-white font-semibold py-3 px-4 rounded-lg transition-colors disabled:opacity-50",children:"Create Enhanced Playlist"})})]})}),u&&m.jsxs(O.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"mb-8",children:[m.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"✨ Your New Playlist"}),m.jsx(T,{playlist:u,isNew:!0})]}),n.length>0&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},children:[m.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"Your Mixed Playlists"}),m.jsx("div",{className:"grid gap-6",children:n.map(A=>m.jsx(T,{playlist:A},A.id))})]}),!z&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-12 text-center",children:[m.jsx(Xe,{className:"w-16 h-16 mx-auto mb-4 text-pink-400"}),m.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:t?"Loading music data":"Waiting for your partner"}),m.jsx("p",{className:"text-white/70",children:t?"We need to analyze both your music tastes to create the perfect mixed playlist":"Invite your partner to connect their Spotify account to start creating mixed playlists"})]}),n.length===0&&z&&!u&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-12 text-center",children:[m.jsx(vt,{className:"w-16 h-16 mx-auto mb-4 text-white/30"}),m.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"No playlists yet"}),m.jsx("p",{className:"text-white/70",children:"Create your first mixed playlist to start your musical journey together"})]})]})},d6=()=>{const{currentUser:e,partnerUser:t,memoryLane:n,addMemoryLaneItem:r}=ae(),[s,i]=k.useState(!1),[o,a]=k.useState({title:"",description:"",type:"milestone"});k.useEffect(()=>{var u,h,p,g,x,v,y,w,b,S,C,P;e&&t&&n.length===0&&[{id:"1",type:"milestone",title:"First Musical Connection",description:`${(u=e.user)==null?void 0:u.display_name} and ${(h=t.user)==null?void 0:h.display_name} discovered their shared love for music`,date:new Date(Date.now()-6048e5),users:[((p=e.user)==null?void 0:p.id)||"",((g=t.user)==null?void 0:g.id)||""]},{id:"2",type:"shared_track",title:"Shared Love for This Song",description:`Both of you have been listening to "${((v=(x=e.recentlyPlayed)==null?void 0:x[0])==null?void 0:v.track.name)||"Your favorite track"}" recently`,track:(w=(y=e.recentlyPlayed)==null?void 0:y[0])==null?void 0:w.track,date:new Date(Date.now()-2592e5),users:[((b=e.user)==null?void 0:b.id)||"",((S=t.user)==null?void 0:S.id)||""]},{id:"3",type:"playlist_created",title:"Our First Mixed Playlist",description:"Created a beautiful blend of your musical tastes",date:new Date(Date.now()-864e5),users:[((C=e.user)==null?void 0:C.id)||"",((P=t.user)==null?void 0:P.id)||""]}].forEach(D=>{r(D)})},[e,t,n.length,r]);const l=()=>{var h,p;if(!o.title.trim()||!o.description.trim()){he.error("Please fill in both title and description");return}const u={id:Date.now().toString(),...o,date:new Date,users:[((h=e==null?void 0:e.user)==null?void 0:h.id)||"",((p=t==null?void 0:t.user)==null?void 0:p.id)||""]};r(u),a({title:"",description:"",type:"milestone"}),i(!1),he.success("Memory added to your journey!")},c=u=>{switch(u){case"shared_track":return m.jsx(vt,{className:"w-5 h-5"});case"playlist_created":return m.jsx(Yn,{className:"w-5 h-5"});case"milestone":return m.jsx(mk,{className:"w-5 h-5"});default:return m.jsx(Xe,{className:"w-5 h-5"})}},d=u=>{switch(u){case"shared_track":return"from-blue-500 to-cyan-500";case"playlist_created":return"from-purple-500 to-pink-500";case"milestone":return"from-yellow-500 to-orange-500";default:return"from-pink-500 to-red-500"}},f=({memory:u,index:h})=>{var p,g;return m.jsxs(O.div,{initial:{opacity:0,x:-50},animate:{opacity:1,x:0},transition:{delay:h*.1},className:"relative",children:[hi(!0),className:"bg-gradient-to-r from-pink-500 to-red-500 hover:from-pink-600 hover:to-red-600 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300 flex items-center space-x-2",children:[m.jsx(Ac,{className:"w-5 h-5"}),m.jsx("span",{children:"Add Memory"})]})]})}),s&&m.jsx(O.div,{initial:{opacity:0},animate:{opacity:1},className:"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4",onClick:()=>i(!1),children:m.jsxs(O.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},onClick:u=>u.stopPropagation(),className:"glass rounded-2xl p-8 max-w-md w-full",children:[m.jsx("h3",{className:"text-2xl font-bold text-white mb-6",children:"Add a New Memory"}),m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{children:[m.jsx("label",{className:"block text-white/70 text-sm font-medium mb-2",children:"Title"}),m.jsx("input",{type:"text",value:o.title,onChange:u=>a({...o,title:u.target.value}),className:"w-full px-4 py-3 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:border-spotify-green",placeholder:"What's this memory about?"})]}),m.jsxs("div",{children:[m.jsx("label",{className:"block text-white/70 text-sm font-medium mb-2",children:"Description"}),m.jsx("textarea",{value:o.description,onChange:u=>a({...o,description:u.target.value}),className:"w-full px-4 py-3 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:border-spotify-green h-24 resize-none",placeholder:"Tell the story of this memory..."})]}),m.jsxs("div",{children:[m.jsx("label",{className:"block text-white/70 text-sm font-medium mb-2",children:"Type"}),m.jsxs("select",{value:o.type,onChange:u=>a({...o,type:u.target.value}),className:"w-full px-4 py-3 bg-white/10 border border-white/20 rounded-lg text-white focus:outline-none focus:border-spotify-green",children:[m.jsx("option",{value:"milestone",children:"Milestone"}),m.jsx("option",{value:"shared_track",children:"Shared Track"}),m.jsx("option",{value:"playlist_created",children:"Playlist Created"})]})]})]}),m.jsxs("div",{className:"flex items-center space-x-3 mt-6",children:[m.jsx("button",{onClick:l,className:"flex-1 bg-spotify-green hover:bg-spotify-green/90 text-white font-semibold py-3 px-4 rounded-lg transition-colors",children:"Add Memory"}),m.jsx("button",{onClick:()=>i(!1),className:"px-4 py-3 bg-white/10 hover:bg-white/20 text-white rounded-lg transition-colors",children:"Cancel"})]})]})}),m.jsx("div",{className:"space-y-8",children:n.length>0?n.map((u,h)=>m.jsx(f,{memory:u,index:h},u.id)):m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-12 text-center",children:[m.jsx(ck,{className:"w-16 h-16 mx-auto mb-4 text-white/30"}),m.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"No memories yet"}),m.jsx("p",{className:"text-white/70 mb-6",children:"Start creating beautiful musical memories together"}),m.jsx("button",{onClick:()=>i(!0),className:"bg-gradient-to-r from-pink-500 to-red-500 hover:from-pink-600 hover:to-red-600 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300",children:"Create First Memory"})]})}),n.length>0&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5},className:"mt-12 grid grid-cols-1 md:grid-cols-3 gap-6",children:[m.jsxs("div",{className:"glass rounded-2xl p-6 text-center",children:[m.jsx("div",{className:"w-12 h-12 mx-auto mb-3 bg-gradient-to-br from-pink-500 to-red-500 rounded-full flex items-center justify-center",children:m.jsx(Xe,{className:"w-6 h-6 text-white"})}),m.jsx("h4",{className:"text-2xl font-bold text-white mb-1",children:n.length}),m.jsx("p",{className:"text-white/70 text-sm",children:"Memories Created"})]}),m.jsxs("div",{className:"glass rounded-2xl p-6 text-center",children:[m.jsx("div",{className:"w-12 h-12 mx-auto mb-3 bg-gradient-to-br from-blue-500 to-cyan-500 rounded-full flex items-center justify-center",children:m.jsx(vt,{className:"w-6 h-6 text-white"})}),m.jsx("h4",{className:"text-2xl font-bold text-white mb-1",children:n.filter(u=>u.type==="shared_track").length}),m.jsx("p",{className:"text-white/70 text-sm",children:"Shared Tracks"})]}),m.jsxs("div",{className:"glass rounded-2xl p-6 text-center",children:[m.jsx("div",{className:"w-12 h-12 mx-auto mb-3 bg-gradient-to-br from-purple-500 to-pink-500 rounded-full flex items-center justify-center",children:m.jsx(Yn,{className:"w-6 h-6 text-white"})}),m.jsx("h4",{className:"text-2xl font-bold text-white mb-1",children:n.filter(u=>u.type==="playlist_created").length}),m.jsx("p",{className:"text-white/70 text-sm",children:"Playlists Created"})]})]})]})};function f6(e,t){if(!e||!t)return 0;const n=["energy","valence"];let r=0,s=0;for(const i of n)typeof e[i]=="number"&&typeof t[i]=="number"&&(r+=1-Math.min(1,Math.abs(e[i]-t[i])),s++);return s?Math.round(r/s*100):0}const h6=()=>{var u,h;const{currentUser:e,partnerUser:t}=ae(),[n,r]=k.useState(null),[s,i]=k.useState(null),[o,a]=k.useState(null),[l,c]=k.useState(null);k.useEffect(()=>{let p;const g=async()=>{var x,v,y,w;try{const b=(x=e==null?void 0:e.user)==null?void 0:x.id;if(b){const C=await se(`/users/${b}/now-playing`);r(C);const P=(v=C==null?void 0:C.item)==null?void 0:v.id;if(P){const j=await se(`/users/${b}/audio-features?ids=${P}`);a(((j==null?void 0:j.audio_features)||[])[0]||null)}}const S=(y=t==null?void 0:t.user)==null?void 0:y.id;if(S){const C=await se(`/users/${S}/now-playing`);i(C);const P=(w=C==null?void 0:C.item)==null?void 0:w.id;if(P){const j=await se(`/users/${S}/audio-features?ids=${P}`);c(((j==null?void 0:j.audio_features)||[])[0]||null)}}}catch{}p=setTimeout(g,8e3)};return g(),()=>clearTimeout(p)},[(u=e==null?void 0:e.user)==null?void 0:u.id,(h=t==null?void 0:t.user)==null?void 0:h.id]);const d=k.useMemo(()=>f6(o,l),[o,l]),f=({data:p,who:g})=>{var v,y,w;if(!(p!=null&&p.is_playing)||!(p!=null&&p.item))return m.jsxs("div",{className:"glass rounded-2xl p-6 text-white/70",children:[g," is not playing"]});const x=p.item;return m.jsxs("div",{className:"glass rounded-2xl p-6 flex items-center gap-4",children:[m.jsx("img",{src:((w=(y=(v=x==null?void 0:x.album)==null?void 0:v.images)==null?void 0:y[0])==null?void 0:w.url)||"/placeholder-album.png",alt:x==null?void 0:x.name,className:"w-16 h-16 rounded"}),m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsx("div",{className:"text-white font-semibold truncate",children:x==null?void 0:x.name}),m.jsx("div",{className:"text-white/70 text-sm truncate",children:((x==null?void 0:x.artists)||[]).map(b=>b.name).join(", ")})]}),m.jsx("div",{className:"flex gap-1",children:[...Array(12)].map((b,S)=>m.jsx("div",{className:"w-1 bg-spotify-green/60 animate-pulse",style:{height:`${(Math.sin(S)*.5+.5)*32+8}px`,animationDelay:`${S*50}ms`}},S))})]})};return m.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-6",children:[m.jsx("h1",{className:"text-3xl font-bold text-white",children:"Live Dashboard"}),m.jsx("p",{className:"text-white/70",children:"See what you are both playing right now"})]}),m.jsxs("div",{className:"grid md:grid-cols-2 gap-6",children:[m.jsx(f,{data:n,who:"You"}),m.jsx(f,{data:s,who:"Partner"})]}),(n==null?void 0:n.is_playing)&&(s==null?void 0:s.is_playing)&&m.jsxs(O.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-6 mt-6 text-center",children:[m.jsx("div",{className:"text-white/80",children:"Harmony Match"}),m.jsxs("div",{className:"text-4xl font-extrabold text-white mt-1",children:[d,"%"]})]})]})};function p6(){var o,a;const{currentUser:e,partnerUser:t,isLoading:n,theme:r}=ae(),s=En();console.log("🔍 App - Current location:",s.pathname),k.useEffect(()=>{Vr(r)},[r]),k.useEffect(()=>{const l=localStorage.getItem("spotify-user"),c=localStorage.getItem("spotify-partner");if(l)try{const d=JSON.parse(l);ae.getState().setCurrentUser(d)}catch(d){console.error("Failed to parse stored user data:",d),localStorage.removeItem("spotify-user")}if(c)try{const d=JSON.parse(c);ae.getState().setPartnerUser(d)}catch(d){console.error("Failed to parse stored partner data:",d),localStorage.removeItem("spotify-partner")}},[]),k.useEffect(()=>{(async()=>{var d,f;const c=(f=(d=ae.getState().currentUser)==null?void 0:d.user)==null?void 0:f.id;if(c&&!ae.getState().partnerUser)try{const u=await se(`/partners/partner/${c}`);if(u.partnerId){const[h,p,g]=await Promise.all([se(`/users/${u.partnerId}`),se(`/users/${u.partnerId}/recently-played`),se(`/users/${u.partnerId}/top-tracks?time_range=short_term`)]);ae.getState().setPartnerUser({user:h,accessToken:null,refreshToken:null,isAuthenticated:!0,recentlyPlayed:p,topTracks:g.map(x=>x.track),topArtists:[]})}}catch{}})()},[(o=e==null?void 0:e.user)==null?void 0:o.id]),k.useEffect(()=>{var d,f;const l=(f=(d=ae.getState().currentUser)==null?void 0:d.user)==null?void 0:f.id;if(!l)return;const c=hb(`/partners/events/${l}`);return c.onmessage=async u=>{var h,p;if(u.data)try{const g=JSON.parse(u.data);if((g==null?void 0:g.type)==="partner:connected"||(g==null?void 0:g.type)==="partner:disconnected"){const x=await se(`/partners/partner/${l}`),v=((p=(h=ae.getState().partnerUser)==null?void 0:h.user)==null?void 0:p.id)||null;if(!(x!=null&&x.partnerId)&&v){ae.getState().setPartnerUser(null),localStorage.removeItem("spotify-partner");return}if(x!=null&&x.partnerId&&x.partnerId!==v)try{const[y,w,b]=await Promise.all([se(`/users/${x.partnerId}`),se(`/users/${x.partnerId}/recently-played`),se(`/users/${x.partnerId}/top-tracks?time_range=short_term`)]);ae.getState().setPartnerUser({user:y,accessToken:null,refreshToken:null,isAuthenticated:!0,recentlyPlayed:w,topTracks:b.map(S=>S.track),topArtists:[]})}catch{}}(g==null?void 0:g.type)==="partner:request"||(g==null||g.type)}catch{}},c.onerror=()=>{try{c.close()}catch{}},()=>{try{c.close()}catch{}}},[(a=e==null?void 0:e.user)==null?void 0:a.id]);const i=(e==null?void 0:e.isAuthenticated)||!1;return n?m.jsxs("div",{className:"min-h-screen flex items-center justify-center relative",children:[m.jsx(Eh,{hueShift:ah(r)}),m.jsxs(O.div,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},className:"glass-fluid rounded-3xl p-10 flex flex-col items-center space-y-6 relative z-20",children:[m.jsx("div",{className:"w-16 h-16 border-4 border-t-transparent rounded-full animate-spin",style:{borderColor:"var(--theme-primary) var(--theme-primary) var(--theme-primary) transparent"}}),m.jsx("p",{className:"text-white font-medium text-lg",children:"Loading your musical journey..."})]})]}):m.jsxs("div",{className:"min-h-screen relative overflow-hidden",children:[m.jsx(Eh,{hueShift:ah(r)}),m.jsxs("div",{className:"relative z-20",children:[i&&m.jsx(Jk,{}),m.jsxs(wx,{children:[m.jsx(_t,{path:"/",element:i?m.jsx(a6,{}):m.jsx(o6,{})}),m.jsx(_t,{path:"/callback",element:m.jsx(Rh,{})}),m.jsx(_t,{path:"/callback.html",element:m.jsx(Rh,{})}),i&&m.jsxs(m.Fragment,{children:[m.jsx(_t,{path:"/last-listened",element:m.jsx(l6,{})}),m.jsx(_t,{path:"/mixed-playlist",element:m.jsx(c6,{})}),m.jsx(_t,{path:"/memory-lane",element:m.jsx(d6,{})}),m.jsx(_t,{path:"/live",element:m.jsx(h6,{})})]}),m.jsx(_t,{path:"*",element:m.jsx(vx,{to:"/",replace:!0})})]})]})]})}Ka.createRoot(document.getElementById("root")).render(m.jsx(Gs.StrictMode,{children:m.jsxs(Tx,{children:[m.jsx(p6,{}),m.jsx(w2,{position:"top-right",toastOptions:{duration:4e3,style:{background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.2)",color:"#fff"}}})]})})); diff --git a/dist/assets/index-CW56MEbw.css b/dist/assets/index-CW56MEbw.css new file mode 100644 index 0000000..17173e7 --- /dev/null +++ b/dist/assets/index-CW56MEbw.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-20{bottom:5rem}.bottom-32{bottom:8rem}.bottom-6{bottom:1.5rem}.left-0{left:0}.left-1\/2{left:50%}.left-1\/4{left:25%}.left-10{left:2.5rem}.left-4{left:1rem}.left-8{left:2rem}.right-0{right:0}.right-1\/3{right:33.333333%}.right-20{right:5rem}.right-4{right:1rem}.right-6{right:1.5rem}.top-0{top:0}.top-1\/2{top:50%}.top-16{top:4rem}.top-20{top:5rem}.top-40{top:10rem}.top-6{top:1.5rem}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0\.5{margin-left:.125rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-20{height:5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-\[60vh\]{height:60vh}.h-full{height:100%}.max-h-64{max-height:16rem}.min-h-screen{min-height:100vh}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-20{width:5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-32{width:8rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize{resize:both}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-items-center{justify-items:center}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1.5rem * var(--tw-space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-green-400\/30{border-color:#4ade804d}.border-orange-500\/30{border-color:#f973164d}.border-red-400\/30{border-color:#f871714d}.border-spotify-green\/30{border-color:#1db9544d}.border-spotify-green\/50{border-color:#1db95480}.border-theme-blue-primary{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-theme-blue-primary\/30{border-color:#3b82f64d}.border-theme-green-primary{--tw-border-opacity: 1;border-color:rgb(29 185 84 / var(--tw-border-opacity, 1))}.border-theme-green-primary\/30{border-color:#1db9544d}.border-theme-pink-primary{--tw-border-opacity: 1;border-color:rgb(236 72 153 / var(--tw-border-opacity, 1))}.border-theme-pink-primary\/30{border-color:#ec48994d}.border-theme-purple-primary{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1))}.border-theme-purple-primary\/30{border-color:#8b5cf64d}.border-theme-red-primary{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}.border-theme-red-primary\/30{border-color:#dc26264d}.border-theme-turquoise-primary{--tw-border-opacity: 1;border-color:rgb(6 182 212 / var(--tw-border-opacity, 1))}.border-theme-turquoise-primary\/30{border-color:#06b6d44d}.border-theme-yellow-primary{--tw-border-opacity: 1;border-color:rgb(234 179 8 / var(--tw-border-opacity, 1))}.border-theme-yellow-primary\/30{border-color:#eab3084d}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1))}.border-white\/10{border-color:#ffffff1a}.border-white\/20{border-color:#fff3}.border-t-transparent{border-top-color:transparent}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/30{background-color:#0000004d}.bg-black\/50{background-color:#00000080}.bg-black\/70{background-color:#000000b3}.bg-blue-500\/20{background-color:#3b82f633}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/20{background-color:#22c55e33}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-pink-500\/20{background-color:#ec489933}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/20{background-color:#ef444433}.bg-spotify-green{--tw-bg-opacity: 1;background-color:rgb(29 185 84 / var(--tw-bg-opacity, 1))}.bg-spotify-green\/60{background-color:#1db95499}.bg-theme-blue-accent{--tw-bg-opacity: 1;background-color:rgb(147 197 253 / var(--tw-bg-opacity, 1))}.bg-theme-blue-primary{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-theme-blue-primary\/10{background-color:#3b82f61a}.bg-theme-blue-secondary{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.bg-theme-green-accent{--tw-bg-opacity: 1;background-color:rgb(0 230 118 / var(--tw-bg-opacity, 1))}.bg-theme-green-primary{--tw-bg-opacity: 1;background-color:rgb(29 185 84 / var(--tw-bg-opacity, 1))}.bg-theme-green-primary\/10{background-color:#1db9541a}.bg-theme-green-secondary{--tw-bg-opacity: 1;background-color:rgb(30 215 96 / var(--tw-bg-opacity, 1))}.bg-theme-pink-accent{--tw-bg-opacity: 1;background-color:rgb(251 113 133 / var(--tw-bg-opacity, 1))}.bg-theme-pink-primary{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-theme-pink-primary\/10{background-color:#ec48991a}.bg-theme-pink-secondary{--tw-bg-opacity: 1;background-color:rgb(244 114 182 / var(--tw-bg-opacity, 1))}.bg-theme-purple-accent{--tw-bg-opacity: 1;background-color:rgb(196 181 253 / var(--tw-bg-opacity, 1))}.bg-theme-purple-primary{--tw-bg-opacity: 1;background-color:rgb(139 92 246 / var(--tw-bg-opacity, 1))}.bg-theme-purple-primary\/10{background-color:#8b5cf61a}.bg-theme-purple-secondary{--tw-bg-opacity: 1;background-color:rgb(167 139 250 / var(--tw-bg-opacity, 1))}.bg-theme-red-accent{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-theme-red-primary{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-theme-red-primary\/10{background-color:#dc26261a}.bg-theme-red-secondary{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-theme-turquoise-accent{--tw-bg-opacity: 1;background-color:rgb(103 232 249 / var(--tw-bg-opacity, 1))}.bg-theme-turquoise-primary{--tw-bg-opacity: 1;background-color:rgb(6 182 212 / var(--tw-bg-opacity, 1))}.bg-theme-turquoise-primary\/10{background-color:#06b6d41a}.bg-theme-turquoise-secondary{--tw-bg-opacity: 1;background-color:rgb(34 211 238 / var(--tw-bg-opacity, 1))}.bg-theme-yellow-accent{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-theme-yellow-primary{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-theme-yellow-primary\/10{background-color:#eab3081a}.bg-theme-yellow-secondary{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/10{background-color:#ffffff1a}.bg-white\/20{background-color:#fff3}.bg-white\/30{background-color:#ffffff4d}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-amber-500{--tw-gradient-from: #f59e0b var(--tw-gradient-from-position);--tw-gradient-to: rgb(245 158 11 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-400{--tw-gradient-from: #60a5fa var(--tw-gradient-from-position);--tw-gradient-to: rgb(96 165 250 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-500{--tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-500\/30{--tw-gradient-from: rgb(59 130 246 / .3) var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-cyan-400{--tw-gradient-from: #22d3ee var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 211 238 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-cyan-500{--tw-gradient-from: #06b6d4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-gray-500{--tw-gradient-from: #6b7280 var(--tw-gradient-from-position);--tw-gradient-to: rgb(107 114 128 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-gray-600{--tw-gradient-from: #4b5563 var(--tw-gradient-from-position);--tw-gradient-to: rgb(75 85 99 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-400{--tw-gradient-from: #4ade80 var(--tw-gradient-from-position);--tw-gradient-to: rgb(74 222 128 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-500{--tw-gradient-from: #22c55e var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-500\/30{--tw-gradient-from: rgb(34 197 94 / .3) var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-600{--tw-gradient-from: #16a34a var(--tw-gradient-from-position);--tw-gradient-to: rgb(22 163 74 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-400{--tw-gradient-from: #fb923c var(--tw-gradient-from-position);--tw-gradient-to: rgb(251 146 60 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-500{--tw-gradient-from: #f97316 var(--tw-gradient-from-position);--tw-gradient-to: rgb(249 115 22 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-pink-400{--tw-gradient-from: #f472b6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(244 114 182 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-pink-500{--tw-gradient-from: #ec4899 var(--tw-gradient-from-position);--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500\/20{--tw-gradient-from: rgb(168 85 247 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500\/30{--tw-gradient-from: rgb(168 85 247 / .3) var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-600{--tw-gradient-from: #9333ea var(--tw-gradient-from-position);--tw-gradient-to: rgb(147 51 234 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-500{--tw-gradient-from: #ef4444 var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 68 68 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-600{--tw-gradient-from: #dc2626 var(--tw-gradient-from-position);--tw-gradient-to: rgb(220 38 38 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-500{--tw-gradient-from: #64748b var(--tw-gradient-from-position);--tw-gradient-to: rgb(100 116 139 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-spotify-green{--tw-gradient-from: #1db954 var(--tw-gradient-from-position);--tw-gradient-to: rgb(29 185 84 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-teal-400{--tw-gradient-from: #2dd4bf var(--tw-gradient-from-position);--tw-gradient-to: rgb(45 212 191 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-teal-500{--tw-gradient-from: #14b8a6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(20 184 166 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-blue-primary{--tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-green-primary{--tw-gradient-from: #1db954 var(--tw-gradient-from-position);--tw-gradient-to: rgb(29 185 84 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-pink-primary{--tw-gradient-from: #ec4899 var(--tw-gradient-from-position);--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-purple-primary{--tw-gradient-from: #8b5cf6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(139 92 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-red-primary{--tw-gradient-from: #dc2626 var(--tw-gradient-from-position);--tw-gradient-to: rgb(220 38 38 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-turquoise-primary{--tw-gradient-from: #06b6d4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-yellow-primary{--tw-gradient-from: #eab308 var(--tw-gradient-from-position);--tw-gradient-to: rgb(234 179 8 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-white\/20{--tw-gradient-from: rgb(255 255 255 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-400{--tw-gradient-from: #facc15 var(--tw-gradient-from-position);--tw-gradient-to: rgb(250 204 21 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-500{--tw-gradient-from: #eab308 var(--tw-gradient-from-position);--tw-gradient-to: rgb(234 179 8 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-blue-500{--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #3b82f6 var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-blue-500\/20{--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(59 130 246 / .2) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-blue-500\/30{--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(59 130 246 / .3) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-blue-600{--tw-gradient-to: rgb(37 99 235 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #2563eb var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-green-500{--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #22c55e var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-pink-500{--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #ec4899 var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-purple-500{--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #a855f7 var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-red-500{--tw-gradient-to: rgb(239 68 68 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #ef4444 var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-teal-500{--tw-gradient-to: rgb(20 184 166 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #14b8a6 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-black{--tw-gradient-to: #000 var(--tw-gradient-to-position)}.to-blue-500{--tw-gradient-to: #3b82f6 var(--tw-gradient-to-position)}.to-cyan-400{--tw-gradient-to: #22d3ee var(--tw-gradient-to-position)}.to-cyan-500{--tw-gradient-to: #06b6d4 var(--tw-gradient-to-position)}.to-cyan-500\/30{--tw-gradient-to: rgb(6 182 212 / .3) var(--tw-gradient-to-position)}.to-cyan-600{--tw-gradient-to: #0891b2 var(--tw-gradient-to-position)}.to-emerald-500{--tw-gradient-to: #10b981 var(--tw-gradient-to-position)}.to-emerald-500\/30{--tw-gradient-to: rgb(16 185 129 / .3) var(--tw-gradient-to-position)}.to-gray-600{--tw-gradient-to: #4b5563 var(--tw-gradient-to-position)}.to-green-500{--tw-gradient-to: #22c55e var(--tw-gradient-to-position)}.to-green-600{--tw-gradient-to: #16a34a var(--tw-gradient-to-position)}.to-indigo-500{--tw-gradient-to: #6366f1 var(--tw-gradient-to-position)}.to-indigo-600{--tw-gradient-to: #4f46e5 var(--tw-gradient-to-position)}.to-lime-500{--tw-gradient-to: #84cc16 var(--tw-gradient-to-position)}.to-orange-500{--tw-gradient-to: #f97316 var(--tw-gradient-to-position)}.to-pink-500{--tw-gradient-to: #ec4899 var(--tw-gradient-to-position)}.to-pink-500\/20{--tw-gradient-to: rgb(236 72 153 / .2) var(--tw-gradient-to-position)}.to-pink-500\/30{--tw-gradient-to: rgb(236 72 153 / .3) var(--tw-gradient-to-position)}.to-pink-600{--tw-gradient-to: #db2777 var(--tw-gradient-to-position)}.to-purple-500{--tw-gradient-to: #a855f7 var(--tw-gradient-to-position)}.to-purple-600{--tw-gradient-to: #9333ea var(--tw-gradient-to-position)}.to-red-500{--tw-gradient-to: #ef4444 var(--tw-gradient-to-position)}.to-red-800{--tw-gradient-to: #991b1b var(--tw-gradient-to-position)}.to-rose-500{--tw-gradient-to: #f43f5e var(--tw-gradient-to-position)}.to-slate-500{--tw-gradient-to: #64748b var(--tw-gradient-to-position)}.to-teal-500{--tw-gradient-to: #14b8a6 var(--tw-gradient-to-position)}.to-theme-blue-secondary{--tw-gradient-to: #60a5fa var(--tw-gradient-to-position)}.to-theme-green-secondary{--tw-gradient-to: #1ed760 var(--tw-gradient-to-position)}.to-theme-pink-secondary{--tw-gradient-to: #f472b6 var(--tw-gradient-to-position)}.to-theme-purple-secondary{--tw-gradient-to: #a78bfa var(--tw-gradient-to-position)}.to-theme-red-secondary{--tw-gradient-to: #ef4444 var(--tw-gradient-to-position)}.to-theme-turquoise-secondary{--tw-gradient-to: #22d3ee var(--tw-gradient-to-position)}.to-theme-yellow-secondary{--tw-gradient-to: #f59e0b var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.to-violet-600{--tw-gradient-to: #7c3aed var(--tw-gradient-to-position)}.to-yellow-600{--tw-gradient-to: #ca8a04 var(--tw-gradient-to-position)}.object-cover{-o-object-fit:cover;object-fit:cover}.p-10{padding:2.5rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-20{padding-top:5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-relaxed{line-height:1.625}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-pink-400{--tw-text-opacity: 1;color:rgb(244 114 182 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-spotify-green{--tw-text-opacity: 1;color:rgb(29 185 84 / var(--tw-text-opacity, 1))}.text-spotify-green\/20{color:#1db95433}.text-spotify-green\/25{color:#1db95440}.text-spotify-green\/30{color:#1db9544d}.text-theme-blue-primary{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-theme-green-primary{--tw-text-opacity: 1;color:rgb(29 185 84 / var(--tw-text-opacity, 1))}.text-theme-pink-primary{--tw-text-opacity: 1;color:rgb(236 72 153 / var(--tw-text-opacity, 1))}.text-theme-purple-primary{--tw-text-opacity: 1;color:rgb(139 92 246 / var(--tw-text-opacity, 1))}.text-theme-red-primary{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-theme-turquoise-primary{--tw-text-opacity: 1;color:rgb(6 182 212 / var(--tw-text-opacity, 1))}.text-theme-yellow-primary{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/30{color:#ffffff4d}.text-white\/40{color:#fff6}.text-white\/50{color:#ffffff80}.text-white\/60{color:#fff9}.text-white\/70{color:#ffffffb3}.text-white\/80{color:#fffc}.text-white\/90{color:#ffffffe6}.underline{text-decoration-line:underline}.placeholder-white\/50::-moz-placeholder{color:#ffffff80}.placeholder-white\/50::placeholder{color:#ffffff80}.placeholder-white\/60::-moz-placeholder{color:#fff9}.placeholder-white\/60::placeholder{color:#fff9}.opacity-0{opacity:0}.opacity-10{opacity:.1}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_30px_rgba\(147\,51\,234\,0\.3\)\]{--tw-shadow: 0 0 30px rgba(147,51,234,.3);--tw-shadow-colored: 0 0 30px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-md{--tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / .07)) drop-shadow(0 2px 2px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:dark;color:#ffffffde;background:transparent;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%;--theme-primary: #1db954;--theme-secondary: #1ed760;--theme-accent: #00e676}*{box-sizing:border-box}html,body{margin:0;padding:0;height:100%;overflow-x:hidden}body{background:transparent;background-attachment:fixed;min-height:100vh}#root{min-height:100vh;position:relative}.glass{background:#ffffff1a;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #0000004d}.glass-dark{background:#0003;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,.1);box-shadow:0 8px 32px #0006}.glass-theme{background:var(--theme-primary);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid var(--theme-primary);box-shadow:0 8px 32px var(--theme-primary);opacity:.1}.glass-green{background:#1db9541a;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(29,185,84,.3);box-shadow:0 8px 32px #1db95433}::-webkit-scrollbar{width:8px}::-webkit-scrollbar-track{background:#ffffff1a;border-radius:4px}::-webkit-scrollbar-thumb{background:var(--theme-primary);border-radius:4px;opacity:.6}::-webkit-scrollbar-thumb:hover{background:var(--theme-primary);opacity:.8}.particles{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:-1}.particle{position:absolute;background:radial-gradient(circle,var(--theme-primary) 0%,transparent 70%);border-radius:50%;animation:float 20s infinite linear;opacity:.3}@keyframes float{0%{transform:translateY(100vh) rotate(0);opacity:0}10%{opacity:1}90%{opacity:1}to{transform:translateY(-100px) rotate(360deg);opacity:0}}.wave-bubble{position:absolute;border-radius:50%;background:radial-gradient(circle,var(--theme-primary) 0%,var(--theme-secondary) 50%,var(--theme-accent) 100%);filter:blur(40px);animation:wave-flow 8s ease-in-out infinite;opacity:.4}.light-cylinder{position:absolute;top:-30%;transform-origin:top center;width:400px;height:150vh;background:linear-gradient(to bottom,var(--theme-primary) 0%,var(--theme-secondary) 15%,var(--theme-accent) 30%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.2) 70%,rgba(255,255,255,.1) 85%,transparent 100%);border-radius:200px;animation:liquid-flow 40s ease-in-out infinite;filter:blur(80px)}.light-cylinder-1{animation-delay:0s;left:10%;width:600px;height:160vh}.light-cylinder-2{animation-delay:13s;left:45%;width:550px;height:140vh}.light-cylinder-3{animation-delay:26s;left:70%;width:580px;height:150vh}@keyframes liquid-flow{0%{transform:translate(0) translateY(0) rotate(0) scale(1);opacity:.7;filter:blur(80px)}20%{transform:translate(40px) translateY(15px) rotate(2deg) scale(1.05);opacity:.75;filter:blur(85px)}40%{transform:translate(-25px) translateY(-8px) rotate(-1.5deg) scale(.95);opacity:.65;filter:blur(82px)}60%{transform:translate(60px) translateY(25px) rotate(3deg) scale(1.1);opacity:.8;filter:blur(88px)}80%{transform:translate(-15px) translateY(10px) rotate(-1deg) scale(.98);opacity:.75;filter:blur(84px)}to{transform:translate(0) translateY(0) rotate(0) scale(1);opacity:.7;filter:blur(80px)}}.wave-bubble:nth-child(1){width:300px;height:300px;top:10%;left:10%;animation-delay:0s;animation-duration:12s}.wave-bubble:nth-child(2){width:200px;height:200px;top:60%;right:15%;animation-delay:2s;animation-duration:10s}.wave-bubble:nth-child(3){width:250px;height:250px;bottom:20%;left:20%;animation-delay:4s;animation-duration:14s}.wave-bubble:nth-child(4){width:180px;height:180px;top:30%;right:40%;animation-delay:6s;animation-duration:9s}.wave-bubble:nth-child(5){width:320px;height:320px;bottom:40%;right:10%;animation-delay:8s;animation-duration:16s}@keyframes wave-flow{0%,to{transform:translateY(0) translate(0) scale(1);opacity:.3}25%{transform:translateY(-50px) translate(30px) scale(1.1);opacity:.6}50%{transform:translateY(-20px) translate(-20px) scale(.9);opacity:.4}75%{transform:translateY(-80px) translate(40px) scale(1.2);opacity:.7}}.soap-bubble{position:absolute;border-radius:50%;background:radial-gradient(circle at 30% 30%,#fffc,#fff6,#9333ea33,#3b82f64d,#ec489933,#ffffff1a);border:2px solid rgba(255,255,255,.3);box-shadow:inset 0 0 20px #fff3,inset 0 0 40px #9333ea1a,0 0 30px #ffffff1a;animation:bubble-float 8s ease-in-out infinite}.bubble-small{width:20px;height:20px;animation:bubble-rise 3s ease-out forwards}.bubble-medium{width:40px;height:40px;animation:bubble-float 6s ease-in-out infinite}.bubble-large{width:80px;height:80px;animation:bubble-float 10s ease-in-out infinite}@keyframes bubble-float{0%,to{transform:translateY(0) scale(1);opacity:.6}50%{transform:translateY(-20px) scale(1.1);opacity:.8}}@keyframes bubble-rise{0%{transform:translateY(0) scale(1);opacity:.8}to{transform:translateY(-150px) scale(.2);opacity:0}}.glass-fluid{background:#0000004d;-webkit-backdrop-filter:blur(30px);backdrop-filter:blur(30px);border:1px solid rgba(255,255,255,.1);box-shadow:0 8px 32px #00000080,inset 0 1px #ffffff1a}.glass-bubble{background:radial-gradient(circle at 30% 30%,#ffffff26,#ffffff14,#9333ea1a,#3b82f614,#ec48990f,#ffffff08);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,.2);box-shadow:inset 0 0 20px #ffffff1a,inset 0 0 40px #9333ea0d,0 8px 32px #9333ea1a,0 0 20px #ffffff0d;transition:all .3s cubic-bezier(.4,0,.2,1)}.glass-bubble:hover{background:radial-gradient(circle at 30% 30%,#fff3,#ffffff1f,#9333ea26,#3b82f61f,#ec48991a,#ffffff0d);border:1px solid rgba(255,255,255,.3);box-shadow:inset 0 0 25px #ffffff26,inset 0 0 50px #9333ea14,0 12px 40px #9333ea33,0 0 30px #ffffff1a;transform:translateY(-2px)}.spotify-hover{transition:all .3s cubic-bezier(.4,0,.2,1)}.spotify-hover:hover{transform:translateY(-2px);box-shadow:0 12px 40px var(--theme-primary)}.gradient-text{background:linear-gradient(135deg,var(--theme-primary),var(--theme-secondary),var(--theme-primary));background-size:200% 200%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-shift 3s ease infinite}@keyframes gradient-shift{0%,to{background-position:0% 50%}50%{background-position:100% 50%}}.pulse-play{animation:pulse-play 2s infinite}@keyframes pulse-play{0%{box-shadow:0 0 0 0 var(--theme-primary)}70%{box-shadow:0 0 0 10px var(--theme-primary)}to{box-shadow:0 0 0 0 var(--theme-primary)}}select option{background-color:#1e1e1ef2!important;color:#ffffffe6!important;border:none;padding:8px 12px;font-size:14px}select option:hover{background-color:var(--theme-primary)!important;color:#fff!important}select option:checked,select option:selected{background-color:var(--theme-primary)!important;color:#fff!important}select option:focus{background-color:var(--theme-primary)!important;color:#fff!important}select{background-color:#ffffff1a!important;color:#ffffffe6!important;border:1px solid rgba(255,255,255,.2)!important}select:focus{outline:none!important;border-color:var(--theme-primary)!important;box-shadow:0 0 0 2px #1db9544d!important}select::-webkit-list-button{background-color:#1e1e1ef2!important;color:#ffffffe6!important}select option{background:#1e1e1ef2!important;color:#ffffffe6!important}.hover\:border-white\/30:hover{border-color:#ffffff4d}.hover\:bg-pink-500\/30:hover{background-color:#ec48994d}.hover\:bg-pink-600:hover{--tw-bg-opacity: 1;background-color:rgb(219 39 119 / var(--tw-bg-opacity, 1))}.hover\:bg-red-500\/30:hover{background-color:#ef44444d}.hover\:bg-spotify-green\/90:hover{background-color:#1db954e6}.hover\:bg-theme-blue-primary\/20:hover{background-color:#3b82f633}.hover\:bg-theme-green-primary\/20:hover{background-color:#1db95433}.hover\:bg-theme-pink-primary\/20:hover{background-color:#ec489933}.hover\:bg-theme-purple-primary\/20:hover{background-color:#8b5cf633}.hover\:bg-theme-red-primary\/20:hover{background-color:#dc262633}.hover\:bg-theme-turquoise-primary\/20:hover{background-color:#06b6d433}.hover\:bg-theme-yellow-primary\/20:hover{background-color:#eab30833}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/20:hover{background-color:#fff3}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:from-pink-600:hover{--tw-gradient-from: #db2777 var(--tw-gradient-from-position);--tw-gradient-to: rgb(219 39 119 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:from-purple-700:hover{--tw-gradient-from: #7e22ce var(--tw-gradient-from-position);--tw-gradient-to: rgb(126 34 206 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:via-blue-700:hover{--tw-gradient-to: rgb(29 78 216 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #1d4ed8 var(--tw-gradient-via-position), var(--tw-gradient-to)}.hover\:to-pink-700:hover{--tw-gradient-to: #be185d var(--tw-gradient-to-position)}.hover\:to-red-600:hover{--tw-gradient-to: #dc2626 var(--tw-gradient-to-position)}.hover\:text-red-300:hover{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-white\/5:hover{--tw-shadow-color: rgb(255 255 255 / .05);--tw-shadow: var(--tw-shadow-colored)}.focus\:border-spotify-green:focus{--tw-border-opacity: 1;border-color:rgb(29 185 84 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-spotify-green:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(29 185 84 / var(--tw-ring-opacity, 1))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-spotify-green{--tw-text-opacity: 1;color:rgb(29 185 84 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:opacity-100{opacity:1}@media (min-width: 640px){.sm\:hidden{display:none}.sm\:h-12{height:3rem}.sm\:h-20{height:5rem}.sm\:h-5{height:1.25rem}.sm\:h-6{height:1.5rem}.sm\:h-\[80vh\]{height:80vh}.sm\:w-12{width:3rem}.sm\:w-20{width:5rem}.sm\:w-5{width:1.25rem}.sm\:w-6{width:1.5rem}.sm\:max-w-4xl{max-width:56rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-3{gap:.75rem}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1.5rem * var(--tw-space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.sm\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.sm\:self-auto{align-self:auto}.sm\:p-3{padding:.75rem}.sm\:p-4{padding:1rem}.sm\:p-6{padding:1.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-24{padding-top:6rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-5xl{font-size:3rem;line-height:1}.sm\:text-6xl{font-size:3.75rem;line-height:1}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:text-lg{font-size:1.125rem;line-height:1.75rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width: 768px){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:text-6xl{font-size:3.75rem;line-height:1}}@media (min-width: 1024px){.lg\:block{display:block}.lg\:h-24{height:6rem}.lg\:w-24{width:6rem}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:text-2xl{font-size:1.5rem;line-height:2rem}.lg\:text-5xl{font-size:3rem;line-height:1}.lg\:text-6xl{font-size:3.75rem;line-height:1}.lg\:text-7xl{font-size:4.5rem;line-height:1}.lg\:text-xl{font-size:1.25rem;line-height:1.75rem}} diff --git a/dist/assets/index-DMWoNld2.js b/dist/assets/index-DMWoNld2.js new file mode 100644 index 0000000..ca25605 --- /dev/null +++ b/dist/assets/index-DMWoNld2.js @@ -0,0 +1,516 @@ +function vy(e,t){for(var r=0;rn[s]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))n(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function r(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(s){if(s.ep)return;s.ep=!0;const i=r(s);fetch(s.href,i)}})();function wu(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Zh={exports:{}},Fo={},Jh={exports:{}},K={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var si=Symbol.for("react.element"),xy=Symbol.for("react.portal"),wy=Symbol.for("react.fragment"),by=Symbol.for("react.strict_mode"),Sy=Symbol.for("react.profiler"),ky=Symbol.for("react.provider"),jy=Symbol.for("react.context"),Cy=Symbol.for("react.forward_ref"),Ny=Symbol.for("react.suspense"),Py=Symbol.for("react.memo"),Ey=Symbol.for("react.lazy"),Jc=Symbol.iterator;function Ty(e){return e===null||typeof e!="object"?null:(e=Jc&&e[Jc]||e["@@iterator"],typeof e=="function"?e:null)}var ep={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},tp=Object.assign,rp={};function Wn(e,t,r){this.props=e,this.context=t,this.refs=rp,this.updater=r||ep}Wn.prototype.isReactComponent={};Wn.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};Wn.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function np(){}np.prototype=Wn.prototype;function bu(e,t,r){this.props=e,this.context=t,this.refs=rp,this.updater=r||ep}var Su=bu.prototype=new np;Su.constructor=bu;tp(Su,Wn.prototype);Su.isPureReactComponent=!0;var ed=Array.isArray,sp=Object.prototype.hasOwnProperty,ku={current:null},ip={key:!0,ref:!0,__self:!0,__source:!0};function op(e,t,r){var n,s={},i=null,o=null;if(t!=null)for(n in t.ref!==void 0&&(o=t.ref),t.key!==void 0&&(i=""+t.key),t)sp.call(t,n)&&!ip.hasOwnProperty(n)&&(s[n]=t[n]);var a=arguments.length-2;if(a===1)s.children=r;else if(1>>1,E=_[R];if(0>>1;Rs(ee,I))qs(me,ee)?(_[R]=me,_[q]=I,R=q):(_[R]=ee,_[X]=I,R=X);else if(qs(me,I))_[R]=me,_[q]=I,R=q;else break e}}return A}function s(_,A){var I=_.sortIndex-A.sortIndex;return I!==0?I:_.id-A.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var o=Date,a=o.now();e.unstable_now=function(){return o.now()-a}}var l=[],c=[],d=1,f=null,u=3,p=!1,m=!1,g=!1,w=typeof setTimeout=="function"?setTimeout:null,v=typeof clearTimeout=="function"?clearTimeout:null,y=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function x(_){for(var A=r(c);A!==null;){if(A.callback===null)n(c);else if(A.startTime<=_)n(c),A.sortIndex=A.expirationTime,t(l,A);else break;A=r(c)}}function b(_){if(g=!1,x(_),!m)if(r(l)!==null)m=!0,M(k);else{var A=r(c);A!==null&&W(b,A.startTime-_)}}function k(_,A){m=!1,g&&(g=!1,v(P),P=-1),p=!0;var I=u;try{for(x(A),f=r(l);f!==null&&(!(f.expirationTime>A)||_&&!O());){var R=f.callback;if(typeof R=="function"){f.callback=null,u=f.priorityLevel;var E=R(f.expirationTime<=A);A=e.unstable_now(),typeof E=="function"?f.callback=E:f===r(l)&&n(l),x(A)}else n(l);f=r(l)}if(f!==null)var H=!0;else{var X=r(c);X!==null&&W(b,X.startTime-A),H=!1}return H}finally{f=null,u=I,p=!1}}var C=!1,N=null,P=-1,V=5,T=-1;function O(){return!(e.unstable_now()-T_||125<_?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):V=0<_?Math.floor(1e3/_):5},e.unstable_getCurrentPriorityLevel=function(){return u},e.unstable_getFirstCallbackNode=function(){return r(l)},e.unstable_next=function(_){switch(u){case 1:case 2:case 3:var A=3;break;default:A=u}var I=u;u=A;try{return _()}finally{u=I}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(_,A){switch(_){case 1:case 2:case 3:case 4:case 5:break;default:_=3}var I=u;u=_;try{return A()}finally{u=I}},e.unstable_scheduleCallback=function(_,A,I){var R=e.unstable_now();switch(typeof I=="object"&&I!==null?(I=I.delay,I=typeof I=="number"&&0R?(_.sortIndex=I,t(c,_),r(l)===null&&_===r(c)&&(g?(v(P),P=-1):g=!0,W(b,I-R))):(_.sortIndex=E,t(l,_),m||p||(m=!0,M(k))),_},e.unstable_shouldYield=O,e.unstable_wrapCallback=function(_){var A=u;return function(){var I=u;u=A;try{return _.apply(this,arguments)}finally{u=I}}}})(dp);cp.exports=dp;var $y=cp.exports;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var By=S,rt=$y;function L(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=1;r"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),ol=Object.prototype.hasOwnProperty,Uy=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,rd={},nd={};function Wy(e){return ol.call(nd,e)?!0:ol.call(rd,e)?!1:Uy.test(e)?nd[e]=!0:(rd[e]=!0,!1)}function Hy(e,t,r,n){if(r!==null&&r.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return n?!1:r!==null?!r.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function qy(e,t,r,n){if(t===null||typeof t>"u"||Hy(e,t,r,n))return!0;if(n)return!1;if(r!==null)switch(r.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function Ue(e,t,r,n,s,i,o){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=n,this.attributeNamespace=s,this.mustUseProperty=r,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=o}var Ae={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Ae[e]=new Ue(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Ae[t]=new Ue(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){Ae[e]=new Ue(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Ae[e]=new Ue(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){Ae[e]=new Ue(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){Ae[e]=new Ue(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){Ae[e]=new Ue(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){Ae[e]=new Ue(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){Ae[e]=new Ue(e,5,!1,e.toLowerCase(),null,!1,!1)});var Cu=/[\-:]([a-z])/g;function Nu(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Cu,Nu);Ae[t]=new Ue(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Cu,Nu);Ae[t]=new Ue(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Cu,Nu);Ae[t]=new Ue(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){Ae[e]=new Ue(e,1,!1,e.toLowerCase(),null,!1,!1)});Ae.xlinkHref=new Ue("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){Ae[e]=new Ue(e,1,!1,e.toLowerCase(),null,!0,!0)});function Pu(e,t,r,n){var s=Ae.hasOwnProperty(t)?Ae[t]:null;(s!==null?s.type!==0:n||!(2a||s[o]!==i[a]){var l=` +`+s[o].replace(" at new "," at ");return e.displayName&&l.includes("")&&(l=l.replace("",e.displayName)),l}while(1<=o&&0<=a);break}}}finally{pa=!1,Error.prepareStackTrace=r}return(e=e?e.displayName||e.name:"")?fs(e):""}function Gy(e){switch(e.tag){case 5:return fs(e.type);case 16:return fs("Lazy");case 13:return fs("Suspense");case 19:return fs("SuspenseList");case 0:case 2:case 15:return e=ma(e.type,!1),e;case 11:return e=ma(e.type.render,!1),e;case 1:return e=ma(e.type,!0),e;default:return""}}function cl(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case cn:return"Fragment";case un:return"Portal";case al:return"Profiler";case Eu:return"StrictMode";case ll:return"Suspense";case ul:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case pp:return(e.displayName||"Context")+".Consumer";case hp:return(e._context.displayName||"Context")+".Provider";case Tu:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Mu:return t=e.displayName||null,t!==null?t:cl(e.type)||"Memo";case nr:t=e._payload,e=e._init;try{return cl(e(t))}catch{}}return null}function Yy(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return cl(t);case 8:return t===Eu?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Sr(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function gp(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Ky(e){var t=gp(e)?"checked":"value",r=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),n=""+e[t];if(!e.hasOwnProperty(t)&&typeof r<"u"&&typeof r.get=="function"&&typeof r.set=="function"){var s=r.get,i=r.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return s.call(this)},set:function(o){n=""+o,i.call(this,o)}}),Object.defineProperty(e,t,{enumerable:r.enumerable}),{getValue:function(){return n},setValue:function(o){n=""+o},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function yi(e){e._valueTracker||(e._valueTracker=Ky(e))}function yp(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var r=t.getValue(),n="";return e&&(n=gp(e)?e.checked?"true":"false":e.value),e=n,e!==r?(t.setValue(e),!0):!1}function eo(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function dl(e,t){var r=t.checked;return pe({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:r??e._wrapperState.initialChecked})}function id(e,t){var r=t.defaultValue==null?"":t.defaultValue,n=t.checked!=null?t.checked:t.defaultChecked;r=Sr(t.value!=null?t.value:r),e._wrapperState={initialChecked:n,initialValue:r,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function vp(e,t){t=t.checked,t!=null&&Pu(e,"checked",t,!1)}function fl(e,t){vp(e,t);var r=Sr(t.value),n=t.type;if(r!=null)n==="number"?(r===0&&e.value===""||e.value!=r)&&(e.value=""+r):e.value!==""+r&&(e.value=""+r);else if(n==="submit"||n==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?hl(e,t.type,r):t.hasOwnProperty("defaultValue")&&hl(e,t.type,Sr(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function od(e,t,r){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var n=t.type;if(!(n!=="submit"&&n!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,r||t===e.value||(e.value=t),e.defaultValue=t}r=e.name,r!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,r!==""&&(e.name=r)}function hl(e,t,r){(t!=="number"||eo(e.ownerDocument)!==e)&&(r==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+r&&(e.defaultValue=""+r))}var hs=Array.isArray;function Cn(e,t,r,n){if(e=e.options,t){t={};for(var s=0;s"+t.valueOf().toString()+"",t=vi.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Vs(e,t){if(t){var r=e.firstChild;if(r&&r===e.lastChild&&r.nodeType===3){r.nodeValue=t;return}}e.textContent=t}var ys={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Xy=["Webkit","ms","Moz","O"];Object.keys(ys).forEach(function(e){Xy.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ys[t]=ys[e]})});function Sp(e,t,r){return t==null||typeof t=="boolean"||t===""?"":r||typeof t!="number"||t===0||ys.hasOwnProperty(e)&&ys[e]?(""+t).trim():t+"px"}function kp(e,t){e=e.style;for(var r in t)if(t.hasOwnProperty(r)){var n=r.indexOf("--")===0,s=Sp(r,t[r],n);r==="float"&&(r="cssFloat"),n?e.setProperty(r,s):e[r]=s}}var Qy=pe({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function gl(e,t){if(t){if(Qy[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(L(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(L(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(L(61))}if(t.style!=null&&typeof t.style!="object")throw Error(L(62))}}function yl(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var vl=null;function Au(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var xl=null,Nn=null,Pn=null;function ud(e){if(e=li(e)){if(typeof xl!="function")throw Error(L(280));var t=e.stateNode;t&&(t=Bo(t),xl(e.stateNode,e.type,t))}}function jp(e){Nn?Pn?Pn.push(e):Pn=[e]:Nn=e}function Cp(){if(Nn){var e=Nn,t=Pn;if(Pn=Nn=null,ud(e),t)for(e=0;e>>=0,e===0?32:31-(l1(e)/u1|0)|0}var xi=64,wi=4194304;function ps(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function so(e,t){var r=e.pendingLanes;if(r===0)return 0;var n=0,s=e.suspendedLanes,i=e.pingedLanes,o=r&268435455;if(o!==0){var a=o&~s;a!==0?n=ps(a):(i&=o,i!==0&&(n=ps(i)))}else o=r&~s,o!==0?n=ps(o):i!==0&&(n=ps(i));if(n===0)return 0;if(t!==0&&t!==n&&!(t&s)&&(s=n&-n,i=t&-t,s>=i||s===16&&(i&4194240)!==0))return t;if(n&4&&(n|=r&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=n;0r;r++)t.push(e);return t}function oi(e,t,r){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-xt(t),e[t]=r}function h1(e,t){var r=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var n=e.eventTimes;for(e=e.expirationTimes;0=xs),vd=" ",xd=!1;function Hp(e,t){switch(e){case"keyup":return $1.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function qp(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var dn=!1;function U1(e,t){switch(e){case"compositionend":return qp(t);case"keypress":return t.which!==32?null:(xd=!0,vd);case"textInput":return e=t.data,e===vd&&xd?null:e;default:return null}}function W1(e,t){if(dn)return e==="compositionend"||!zu&&Hp(e,t)?(e=Up(),$i=Vu=ur=null,dn=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=kd(r)}}function Xp(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Xp(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Qp(){for(var e=window,t=eo();t instanceof e.HTMLIFrameElement;){try{var r=typeof t.contentWindow.location.href=="string"}catch{r=!1}if(r)e=t.contentWindow;else break;t=eo(e.document)}return t}function Ou(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function J1(e){var t=Qp(),r=e.focusedElem,n=e.selectionRange;if(t!==r&&r&&r.ownerDocument&&Xp(r.ownerDocument.documentElement,r)){if(n!==null&&Ou(r)){if(t=n.start,e=n.end,e===void 0&&(e=t),"selectionStart"in r)r.selectionStart=t,r.selectionEnd=Math.min(e,r.value.length);else if(e=(t=r.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var s=r.textContent.length,i=Math.min(n.start,s);n=n.end===void 0?i:Math.min(n.end,s),!e.extend&&i>n&&(s=n,n=i,i=s),s=jd(r,i);var o=jd(r,n);s&&o&&(e.rangeCount!==1||e.anchorNode!==s.node||e.anchorOffset!==s.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&(t=t.createRange(),t.setStart(s.node,s.offset),e.removeAllRanges(),i>n?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}}for(t=[],e=r;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof r.focus=="function"&&r.focus(),r=0;r=document.documentMode,fn=null,Cl=null,bs=null,Nl=!1;function Cd(e,t,r){var n=r.window===r?r.document:r.nodeType===9?r:r.ownerDocument;Nl||fn==null||fn!==eo(n)||(n=fn,"selectionStart"in n&&Ou(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}),bs&&Bs(bs,n)||(bs=n,n=ao(Cl,"onSelect"),0mn||(e.current=_l[mn],_l[mn]=null,mn--)}function re(e,t){mn++,_l[mn]=e.current,e.current=t}var kr={},Ve=Er(kr),qe=Er(!1),Kr=kr;function Dn(e,t){var r=e.type.contextTypes;if(!r)return kr;var n=e.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===t)return n.__reactInternalMemoizedMaskedChildContext;var s={},i;for(i in r)s[i]=t[i];return n&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=s),s}function Ge(e){return e=e.childContextTypes,e!=null}function uo(){ae(qe),ae(Ve)}function _d(e,t,r){if(Ve.current!==kr)throw Error(L(168));re(Ve,t),re(qe,r)}function om(e,t,r){var n=e.stateNode;if(t=t.childContextTypes,typeof n.getChildContext!="function")return r;n=n.getChildContext();for(var s in n)if(!(s in t))throw Error(L(108,Yy(e)||"Unknown",s));return pe({},r,n)}function co(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||kr,Kr=Ve.current,re(Ve,e),re(qe,qe.current),!0}function Ld(e,t,r){var n=e.stateNode;if(!n)throw Error(L(169));r?(e=om(e,t,Kr),n.__reactInternalMemoizedMergedChildContext=e,ae(qe),ae(Ve),re(Ve,e)):ae(qe),re(qe,r)}var Ft=null,Uo=!1,Ta=!1;function am(e){Ft===null?Ft=[e]:Ft.push(e)}function dv(e){Uo=!0,am(e)}function Tr(){if(!Ta&&Ft!==null){Ta=!0;var e=0,t=J;try{var r=Ft;for(J=1;e>=o,s-=o,It=1<<32-xt(t)+s|r<P?(V=N,N=null):V=N.sibling;var T=u(v,N,x[P],b);if(T===null){N===null&&(N=V);break}e&&N&&T.alternate===null&&t(v,N),y=i(T,y,P),C===null?k=T:C.sibling=T,C=T,N=V}if(P===x.length)return r(v,N),ue&&Fr(v,P),k;if(N===null){for(;PP?(V=N,N=null):V=N.sibling;var O=u(v,N,T.value,b);if(O===null){N===null&&(N=V);break}e&&N&&O.alternate===null&&t(v,N),y=i(O,y,P),C===null?k=O:C.sibling=O,C=O,N=V}if(T.done)return r(v,N),ue&&Fr(v,P),k;if(N===null){for(;!T.done;P++,T=x.next())T=f(v,T.value,b),T!==null&&(y=i(T,y,P),C===null?k=T:C.sibling=T,C=T);return ue&&Fr(v,P),k}for(N=n(v,N);!T.done;P++,T=x.next())T=p(N,v,P,T.value,b),T!==null&&(e&&T.alternate!==null&&N.delete(T.key===null?P:T.key),y=i(T,y,P),C===null?k=T:C.sibling=T,C=T);return e&&N.forEach(function(j){return t(v,j)}),ue&&Fr(v,P),k}function w(v,y,x,b){if(typeof x=="object"&&x!==null&&x.type===cn&&x.key===null&&(x=x.props.children),typeof x=="object"&&x!==null){switch(x.$$typeof){case gi:e:{for(var k=x.key,C=y;C!==null;){if(C.key===k){if(k=x.type,k===cn){if(C.tag===7){r(v,C.sibling),y=s(C,x.props.children),y.return=v,v=y;break e}}else if(C.elementType===k||typeof k=="object"&&k!==null&&k.$$typeof===nr&&Vd(k)===C.type){r(v,C.sibling),y=s(C,x.props),y.ref=is(v,C,x),y.return=v,v=y;break e}r(v,C);break}else t(v,C);C=C.sibling}x.type===cn?(y=Gr(x.props.children,v.mode,b,x.key),y.return=v,v=y):(b=Ki(x.type,x.key,x.props,null,v.mode,b),b.ref=is(v,y,x),b.return=v,v=b)}return o(v);case un:e:{for(C=x.key;y!==null;){if(y.key===C)if(y.tag===4&&y.stateNode.containerInfo===x.containerInfo&&y.stateNode.implementation===x.implementation){r(v,y.sibling),y=s(y,x.children||[]),y.return=v,v=y;break e}else{r(v,y);break}else t(v,y);y=y.sibling}y=Fa(x,v.mode,b),y.return=v,v=y}return o(v);case nr:return C=x._init,w(v,y,C(x._payload),b)}if(hs(x))return m(v,y,x,b);if(es(x))return g(v,y,x,b);Pi(v,x)}return typeof x=="string"&&x!==""||typeof x=="number"?(x=""+x,y!==null&&y.tag===6?(r(v,y.sibling),y=s(y,x),y.return=v,v=y):(r(v,y),y=Va(x,v.mode,b),y.return=v,v=y),o(v)):r(v,y)}return w}var Vn=dm(!0),fm=dm(!1),po=Er(null),mo=null,vn=null,Wu=null;function Hu(){Wu=vn=mo=null}function qu(e){var t=po.current;ae(po),e._currentValue=t}function Rl(e,t,r){for(;e!==null;){var n=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,n!==null&&(n.childLanes|=t)):n!==null&&(n.childLanes&t)!==t&&(n.childLanes|=t),e===r)break;e=e.return}}function Tn(e,t){mo=e,Wu=vn=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&t&&(He=!0),e.firstContext=null)}function ft(e){var t=e._currentValue;if(Wu!==e)if(e={context:e,memoizedValue:t,next:null},vn===null){if(mo===null)throw Error(L(308));vn=e,mo.dependencies={lanes:0,firstContext:e}}else vn=vn.next=e;return t}var Ur=null;function Gu(e){Ur===null?Ur=[e]:Ur.push(e)}function hm(e,t,r,n){var s=t.interleaved;return s===null?(r.next=r,Gu(t)):(r.next=s.next,s.next=r),t.interleaved=r,qt(e,n)}function qt(e,t){e.lanes|=t;var r=e.alternate;for(r!==null&&(r.lanes|=t),r=e,e=e.return;e!==null;)e.childLanes|=t,r=e.alternate,r!==null&&(r.childLanes|=t),r=e,e=e.return;return r.tag===3?r.stateNode:null}var sr=!1;function Yu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function pm(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function $t(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function gr(e,t,r){var n=e.updateQueue;if(n===null)return null;if(n=n.shared,Q&2){var s=n.pending;return s===null?t.next=t:(t.next=s.next,s.next=t),n.pending=t,qt(e,r)}return s=n.interleaved,s===null?(t.next=t,Gu(n)):(t.next=s.next,s.next=t),n.interleaved=t,qt(e,r)}function Ui(e,t,r){if(t=t.updateQueue,t!==null&&(t=t.shared,(r&4194240)!==0)){var n=t.lanes;n&=e.pendingLanes,r|=n,t.lanes=r,Lu(e,r)}}function Fd(e,t){var r=e.updateQueue,n=e.alternate;if(n!==null&&(n=n.updateQueue,r===n)){var s=null,i=null;if(r=r.firstBaseUpdate,r!==null){do{var o={eventTime:r.eventTime,lane:r.lane,tag:r.tag,payload:r.payload,callback:r.callback,next:null};i===null?s=i=o:i=i.next=o,r=r.next}while(r!==null);i===null?s=i=t:i=i.next=t}else s=i=t;r={baseState:n.baseState,firstBaseUpdate:s,lastBaseUpdate:i,shared:n.shared,effects:n.effects},e.updateQueue=r;return}e=r.lastBaseUpdate,e===null?r.firstBaseUpdate=t:e.next=t,r.lastBaseUpdate=t}function go(e,t,r,n){var s=e.updateQueue;sr=!1;var i=s.firstBaseUpdate,o=s.lastBaseUpdate,a=s.shared.pending;if(a!==null){s.shared.pending=null;var l=a,c=l.next;l.next=null,o===null?i=c:o.next=c,o=l;var d=e.alternate;d!==null&&(d=d.updateQueue,a=d.lastBaseUpdate,a!==o&&(a===null?d.firstBaseUpdate=c:a.next=c,d.lastBaseUpdate=l))}if(i!==null){var f=s.baseState;o=0,d=c=l=null,a=i;do{var u=a.lane,p=a.eventTime;if((n&u)===u){d!==null&&(d=d.next={eventTime:p,lane:0,tag:a.tag,payload:a.payload,callback:a.callback,next:null});e:{var m=e,g=a;switch(u=t,p=r,g.tag){case 1:if(m=g.payload,typeof m=="function"){f=m.call(p,f,u);break e}f=m;break e;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,u=typeof m=="function"?m.call(p,f,u):m,u==null)break e;f=pe({},f,u);break e;case 2:sr=!0}}a.callback!==null&&a.lane!==0&&(e.flags|=64,u=s.effects,u===null?s.effects=[a]:u.push(a))}else p={eventTime:p,lane:u,tag:a.tag,payload:a.payload,callback:a.callback,next:null},d===null?(c=d=p,l=f):d=d.next=p,o|=u;if(a=a.next,a===null){if(a=s.shared.pending,a===null)break;u=a,a=u.next,u.next=null,s.lastBaseUpdate=u,s.shared.pending=null}}while(!0);if(d===null&&(l=f),s.baseState=l,s.firstBaseUpdate=c,s.lastBaseUpdate=d,t=s.shared.interleaved,t!==null){s=t;do o|=s.lane,s=s.next;while(s!==t)}else i===null&&(s.shared.lanes=0);Zr|=o,e.lanes=o,e.memoizedState=f}}function Id(e,t,r){if(e=t.effects,t.effects=null,e!==null)for(t=0;tr?r:4,e(!0);var n=Aa.transition;Aa.transition={};try{e(!1),t()}finally{J=r,Aa.transition=n}}function Am(){return ht().memoizedState}function mv(e,t,r){var n=vr(e);if(r={lane:n,action:r,hasEagerState:!1,eagerState:null,next:null},_m(e))Lm(t,r);else if(r=hm(e,t,r,n),r!==null){var s=$e();wt(r,e,n,s),Dm(r,t,n)}}function gv(e,t,r){var n=vr(e),s={lane:n,action:r,hasEagerState:!1,eagerState:null,next:null};if(_m(e))Lm(t,s);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var o=t.lastRenderedState,a=i(o,r);if(s.hasEagerState=!0,s.eagerState=a,bt(a,o)){var l=t.interleaved;l===null?(s.next=s,Gu(t)):(s.next=l.next,l.next=s),t.interleaved=s;return}}catch{}finally{}r=hm(e,t,s,n),r!==null&&(s=$e(),wt(r,e,n,s),Dm(r,t,n))}}function _m(e){var t=e.alternate;return e===he||t!==null&&t===he}function Lm(e,t){Ss=vo=!0;var r=e.pending;r===null?t.next=t:(t.next=r.next,r.next=t),e.pending=t}function Dm(e,t,r){if(r&4194240){var n=t.lanes;n&=e.pendingLanes,r|=n,t.lanes=r,Lu(e,r)}}var xo={readContext:ft,useCallback:_e,useContext:_e,useEffect:_e,useImperativeHandle:_e,useInsertionEffect:_e,useLayoutEffect:_e,useMemo:_e,useReducer:_e,useRef:_e,useState:_e,useDebugValue:_e,useDeferredValue:_e,useTransition:_e,useMutableSource:_e,useSyncExternalStore:_e,useId:_e,unstable_isNewReconciler:!1},yv={readContext:ft,useCallback:function(e,t){return Ct().memoizedState=[e,t===void 0?null:t],e},useContext:ft,useEffect:Od,useImperativeHandle:function(e,t,r){return r=r!=null?r.concat([e]):null,Hi(4194308,4,Nm.bind(null,t,e),r)},useLayoutEffect:function(e,t){return Hi(4194308,4,e,t)},useInsertionEffect:function(e,t){return Hi(4,2,e,t)},useMemo:function(e,t){var r=Ct();return t=t===void 0?null:t,e=e(),r.memoizedState=[e,t],e},useReducer:function(e,t,r){var n=Ct();return t=r!==void 0?r(t):t,n.memoizedState=n.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},n.queue=e,e=e.dispatch=mv.bind(null,he,e),[n.memoizedState,e]},useRef:function(e){var t=Ct();return e={current:e},t.memoizedState=e},useState:zd,useDebugValue:rc,useDeferredValue:function(e){return Ct().memoizedState=e},useTransition:function(){var e=zd(!1),t=e[0];return e=pv.bind(null,e[1]),Ct().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,r){var n=he,s=Ct();if(ue){if(r===void 0)throw Error(L(407));r=r()}else{if(r=t(),Ee===null)throw Error(L(349));Qr&30||vm(n,t,r)}s.memoizedState=r;var i={value:r,getSnapshot:t};return s.queue=i,Od(wm.bind(null,n,i,e),[e]),n.flags|=2048,Xs(9,xm.bind(null,n,i,r,t),void 0,null),r},useId:function(){var e=Ct(),t=Ee.identifierPrefix;if(ue){var r=zt,n=It;r=(n&~(1<<32-xt(n)-1)).toString(32)+r,t=":"+t+"R"+r,r=Ys++,0<\/script>",e=e.removeChild(e.firstChild)):typeof n.is=="string"?e=o.createElement(r,{is:n.is}):(e=o.createElement(r),r==="select"&&(o=e,n.multiple?o.multiple=!0:n.size&&(o.size=n.size))):e=o.createElementNS(e,r),e[Nt]=t,e[Hs]=n,Wm(e,t,!1,!1),t.stateNode=e;e:{switch(o=yl(r,n),r){case"dialog":ie("cancel",e),ie("close",e),s=n;break;case"iframe":case"object":case"embed":ie("load",e),s=n;break;case"video":case"audio":for(s=0;szn&&(t.flags|=128,n=!0,os(i,!1),t.lanes=4194304)}else{if(!n)if(e=yo(o),e!==null){if(t.flags|=128,n=!0,r=e.updateQueue,r!==null&&(t.updateQueue=r,t.flags|=4),os(i,!0),i.tail===null&&i.tailMode==="hidden"&&!o.alternate&&!ue)return Le(t),null}else 2*ve()-i.renderingStartTime>zn&&r!==1073741824&&(t.flags|=128,n=!0,os(i,!1),t.lanes=4194304);i.isBackwards?(o.sibling=t.child,t.child=o):(r=i.last,r!==null?r.sibling=o:t.child=o,i.last=o)}return i.tail!==null?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=ve(),t.sibling=null,r=de.current,re(de,n?r&1|2:r&1),t):(Le(t),null);case 22:case 23:return lc(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&t.mode&1?Ze&1073741824&&(Le(t),t.subtreeFlags&6&&(t.flags|=8192)):Le(t),null;case 24:return null;case 25:return null}throw Error(L(156,t.tag))}function Cv(e,t){switch(Bu(t),t.tag){case 1:return Ge(t.type)&&uo(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Fn(),ae(qe),ae(Ve),Qu(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Xu(t),null;case 13:if(ae(de),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(L(340));Rn()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ae(de),null;case 4:return Fn(),null;case 10:return qu(t.type._context),null;case 22:case 23:return lc(),null;case 24:return null;default:return null}}var Ti=!1,Re=!1,Nv=typeof WeakSet=="function"?WeakSet:Set,$=null;function xn(e,t){var r=e.ref;if(r!==null)if(typeof r=="function")try{r(null)}catch(n){ge(e,t,n)}else r.current=null}function Wl(e,t,r){try{r()}catch(n){ge(e,t,n)}}var Qd=!1;function Pv(e,t){if(Pl=io,e=Qp(),Ou(e)){if("selectionStart"in e)var r={start:e.selectionStart,end:e.selectionEnd};else e:{r=(r=e.ownerDocument)&&r.defaultView||window;var n=r.getSelection&&r.getSelection();if(n&&n.rangeCount!==0){r=n.anchorNode;var s=n.anchorOffset,i=n.focusNode;n=n.focusOffset;try{r.nodeType,i.nodeType}catch{r=null;break e}var o=0,a=-1,l=-1,c=0,d=0,f=e,u=null;t:for(;;){for(var p;f!==r||s!==0&&f.nodeType!==3||(a=o+s),f!==i||n!==0&&f.nodeType!==3||(l=o+n),f.nodeType===3&&(o+=f.nodeValue.length),(p=f.firstChild)!==null;)u=f,f=p;for(;;){if(f===e)break t;if(u===r&&++c===s&&(a=o),u===i&&++d===n&&(l=o),(p=f.nextSibling)!==null)break;f=u,u=f.parentNode}f=p}r=a===-1||l===-1?null:{start:a,end:l}}else r=null}r=r||{start:0,end:0}}else r=null;for(El={focusedElem:e,selectionRange:r},io=!1,$=t;$!==null;)if(t=$,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,$=e;else for(;$!==null;){t=$;try{var m=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(m!==null){var g=m.memoizedProps,w=m.memoizedState,v=t.stateNode,y=v.getSnapshotBeforeUpdate(t.elementType===t.type?g:mt(t.type,g),w);v.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var x=t.stateNode.containerInfo;x.nodeType===1?x.textContent="":x.nodeType===9&&x.documentElement&&x.removeChild(x.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(L(163))}}catch(b){ge(t,t.return,b)}if(e=t.sibling,e!==null){e.return=t.return,$=e;break}$=t.return}return m=Qd,Qd=!1,m}function ks(e,t,r){var n=t.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var s=n=n.next;do{if((s.tag&e)===e){var i=s.destroy;s.destroy=void 0,i!==void 0&&Wl(t,r,i)}s=s.next}while(s!==n)}}function qo(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var r=t=t.next;do{if((r.tag&e)===e){var n=r.create;r.destroy=n()}r=r.next}while(r!==t)}}function Hl(e){var t=e.ref;if(t!==null){var r=e.stateNode;switch(e.tag){case 5:e=r;break;default:e=r}typeof t=="function"?t(e):t.current=e}}function Gm(e){var t=e.alternate;t!==null&&(e.alternate=null,Gm(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Nt],delete t[Hs],delete t[Al],delete t[uv],delete t[cv])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Ym(e){return e.tag===5||e.tag===3||e.tag===4}function Zd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Ym(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function ql(e,t,r){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?r.nodeType===8?r.parentNode.insertBefore(e,t):r.insertBefore(e,t):(r.nodeType===8?(t=r.parentNode,t.insertBefore(e,r)):(t=r,t.appendChild(e)),r=r._reactRootContainer,r!=null||t.onclick!==null||(t.onclick=lo));else if(n!==4&&(e=e.child,e!==null))for(ql(e,t,r),e=e.sibling;e!==null;)ql(e,t,r),e=e.sibling}function Gl(e,t,r){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?r.insertBefore(e,t):r.appendChild(e);else if(n!==4&&(e=e.child,e!==null))for(Gl(e,t,r),e=e.sibling;e!==null;)Gl(e,t,r),e=e.sibling}var Te=null,gt=!1;function Jt(e,t,r){for(r=r.child;r!==null;)Km(e,t,r),r=r.sibling}function Km(e,t,r){if(Tt&&typeof Tt.onCommitFiberUnmount=="function")try{Tt.onCommitFiberUnmount(Io,r)}catch{}switch(r.tag){case 5:Re||xn(r,t);case 6:var n=Te,s=gt;Te=null,Jt(e,t,r),Te=n,gt=s,Te!==null&&(gt?(e=Te,r=r.stateNode,e.nodeType===8?e.parentNode.removeChild(r):e.removeChild(r)):Te.removeChild(r.stateNode));break;case 18:Te!==null&&(gt?(e=Te,r=r.stateNode,e.nodeType===8?Ea(e.parentNode,r):e.nodeType===1&&Ea(e,r),Os(e)):Ea(Te,r.stateNode));break;case 4:n=Te,s=gt,Te=r.stateNode.containerInfo,gt=!0,Jt(e,t,r),Te=n,gt=s;break;case 0:case 11:case 14:case 15:if(!Re&&(n=r.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){s=n=n.next;do{var i=s,o=i.destroy;i=i.tag,o!==void 0&&(i&2||i&4)&&Wl(r,t,o),s=s.next}while(s!==n)}Jt(e,t,r);break;case 1:if(!Re&&(xn(r,t),n=r.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=r.memoizedProps,n.state=r.memoizedState,n.componentWillUnmount()}catch(a){ge(r,t,a)}Jt(e,t,r);break;case 21:Jt(e,t,r);break;case 22:r.mode&1?(Re=(n=Re)||r.memoizedState!==null,Jt(e,t,r),Re=n):Jt(e,t,r);break;default:Jt(e,t,r)}}function Jd(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var r=e.stateNode;r===null&&(r=e.stateNode=new Nv),t.forEach(function(n){var s=Vv.bind(null,e,n);r.has(n)||(r.add(n),n.then(s,s))})}}function pt(e,t){var r=t.deletions;if(r!==null)for(var n=0;ns&&(s=o),n&=~i}if(n=s,n=ve()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Tv(n/1960))-n,10e?16:e,cr===null)var n=!1;else{if(e=cr,cr=null,So=0,Q&6)throw Error(L(331));var s=Q;for(Q|=4,$=e.current;$!==null;){var i=$,o=i.child;if($.flags&16){var a=i.deletions;if(a!==null){for(var l=0;lve()-oc?qr(e,0):ic|=r),Ye(e,t)}function n0(e,t){t===0&&(e.mode&1?(t=wi,wi<<=1,!(wi&130023424)&&(wi=4194304)):t=1);var r=$e();e=qt(e,t),e!==null&&(oi(e,t,r),Ye(e,r))}function Rv(e){var t=e.memoizedState,r=0;t!==null&&(r=t.retryLane),n0(e,r)}function Vv(e,t){var r=0;switch(e.tag){case 13:var n=e.stateNode,s=e.memoizedState;s!==null&&(r=s.retryLane);break;case 19:n=e.stateNode;break;default:throw Error(L(314))}n!==null&&n.delete(t),n0(e,r)}var s0;s0=function(e,t,r){if(e!==null)if(e.memoizedProps!==t.pendingProps||qe.current)He=!0;else{if(!(e.lanes&r)&&!(t.flags&128))return He=!1,kv(e,t,r);He=!!(e.flags&131072)}else He=!1,ue&&t.flags&1048576&&lm(t,ho,t.index);switch(t.lanes=0,t.tag){case 2:var n=t.type;qi(e,t),e=t.pendingProps;var s=Dn(t,Ve.current);Tn(t,r),s=Ju(null,t,n,e,s,r);var i=ec();return t.flags|=1,typeof s=="object"&&s!==null&&typeof s.render=="function"&&s.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Ge(n)?(i=!0,co(t)):i=!1,t.memoizedState=s.state!==null&&s.state!==void 0?s.state:null,Yu(t),s.updater=Ho,t.stateNode=s,s._reactInternals=t,Fl(t,n,e,r),t=Ol(null,t,n,!0,i,r)):(t.tag=0,ue&&i&&$u(t),Oe(null,t,s,r),t=t.child),t;case 16:n=t.elementType;e:{switch(qi(e,t),e=t.pendingProps,s=n._init,n=s(n._payload),t.type=n,s=t.tag=Iv(n),e=mt(n,e),s){case 0:t=zl(null,t,n,e,r);break e;case 1:t=Yd(null,t,n,e,r);break e;case 11:t=qd(null,t,n,e,r);break e;case 14:t=Gd(null,t,n,mt(n.type,e),r);break e}throw Error(L(306,n,""))}return t;case 0:return n=t.type,s=t.pendingProps,s=t.elementType===n?s:mt(n,s),zl(e,t,n,s,r);case 1:return n=t.type,s=t.pendingProps,s=t.elementType===n?s:mt(n,s),Yd(e,t,n,s,r);case 3:e:{if($m(t),e===null)throw Error(L(387));n=t.pendingProps,i=t.memoizedState,s=i.element,pm(e,t),go(t,n,null,r);var o=t.memoizedState;if(n=o.element,i.isDehydrated)if(i={element:n,isDehydrated:!1,cache:o.cache,pendingSuspenseBoundaries:o.pendingSuspenseBoundaries,transitions:o.transitions},t.updateQueue.baseState=i,t.memoizedState=i,t.flags&256){s=In(Error(L(423)),t),t=Kd(e,t,n,r,s);break e}else if(n!==s){s=In(Error(L(424)),t),t=Kd(e,t,n,r,s);break e}else for(Je=mr(t.stateNode.containerInfo.firstChild),tt=t,ue=!0,yt=null,r=fm(t,null,n,r),t.child=r;r;)r.flags=r.flags&-3|4096,r=r.sibling;else{if(Rn(),n===s){t=Gt(e,t,r);break e}Oe(e,t,n,r)}t=t.child}return t;case 5:return mm(t),e===null&&Dl(t),n=t.type,s=t.pendingProps,i=e!==null?e.memoizedProps:null,o=s.children,Tl(n,s)?o=null:i!==null&&Tl(n,i)&&(t.flags|=32),Om(e,t),Oe(e,t,o,r),t.child;case 6:return e===null&&Dl(t),null;case 13:return Bm(e,t,r);case 4:return Ku(t,t.stateNode.containerInfo),n=t.pendingProps,e===null?t.child=Vn(t,null,n,r):Oe(e,t,n,r),t.child;case 11:return n=t.type,s=t.pendingProps,s=t.elementType===n?s:mt(n,s),qd(e,t,n,s,r);case 7:return Oe(e,t,t.pendingProps,r),t.child;case 8:return Oe(e,t,t.pendingProps.children,r),t.child;case 12:return Oe(e,t,t.pendingProps.children,r),t.child;case 10:e:{if(n=t.type._context,s=t.pendingProps,i=t.memoizedProps,o=s.value,re(po,n._currentValue),n._currentValue=o,i!==null)if(bt(i.value,o)){if(i.children===s.children&&!qe.current){t=Gt(e,t,r);break e}}else for(i=t.child,i!==null&&(i.return=t);i!==null;){var a=i.dependencies;if(a!==null){o=i.child;for(var l=a.firstContext;l!==null;){if(l.context===n){if(i.tag===1){l=$t(-1,r&-r),l.tag=2;var c=i.updateQueue;if(c!==null){c=c.shared;var d=c.pending;d===null?l.next=l:(l.next=d.next,d.next=l),c.pending=l}}i.lanes|=r,l=i.alternate,l!==null&&(l.lanes|=r),Rl(i.return,r,t),a.lanes|=r;break}l=l.next}}else if(i.tag===10)o=i.type===t.type?null:i.child;else if(i.tag===18){if(o=i.return,o===null)throw Error(L(341));o.lanes|=r,a=o.alternate,a!==null&&(a.lanes|=r),Rl(o,r,t),o=i.sibling}else o=i.child;if(o!==null)o.return=i;else for(o=i;o!==null;){if(o===t){o=null;break}if(i=o.sibling,i!==null){i.return=o.return,o=i;break}o=o.return}i=o}Oe(e,t,s.children,r),t=t.child}return t;case 9:return s=t.type,n=t.pendingProps.children,Tn(t,r),s=ft(s),n=n(s),t.flags|=1,Oe(e,t,n,r),t.child;case 14:return n=t.type,s=mt(n,t.pendingProps),s=mt(n.type,s),Gd(e,t,n,s,r);case 15:return Im(e,t,t.type,t.pendingProps,r);case 17:return n=t.type,s=t.pendingProps,s=t.elementType===n?s:mt(n,s),qi(e,t),t.tag=1,Ge(n)?(e=!0,co(t)):e=!1,Tn(t,r),Rm(t,n,s),Fl(t,n,s,r),Ol(null,t,n,!0,e,r);case 19:return Um(e,t,r);case 22:return zm(e,t,r)}throw Error(L(156,t.tag))};function i0(e,t){return _p(e,t)}function Fv(e,t,r,n){this.tag=e,this.key=r,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ct(e,t,r,n){return new Fv(e,t,r,n)}function cc(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Iv(e){if(typeof e=="function")return cc(e)?1:0;if(e!=null){if(e=e.$$typeof,e===Tu)return 11;if(e===Mu)return 14}return 2}function xr(e,t){var r=e.alternate;return r===null?(r=ct(e.tag,t,e.key,e.mode),r.elementType=e.elementType,r.type=e.type,r.stateNode=e.stateNode,r.alternate=e,e.alternate=r):(r.pendingProps=t,r.type=e.type,r.flags=0,r.subtreeFlags=0,r.deletions=null),r.flags=e.flags&14680064,r.childLanes=e.childLanes,r.lanes=e.lanes,r.child=e.child,r.memoizedProps=e.memoizedProps,r.memoizedState=e.memoizedState,r.updateQueue=e.updateQueue,t=e.dependencies,r.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},r.sibling=e.sibling,r.index=e.index,r.ref=e.ref,r}function Ki(e,t,r,n,s,i){var o=2;if(n=e,typeof e=="function")cc(e)&&(o=1);else if(typeof e=="string")o=5;else e:switch(e){case cn:return Gr(r.children,s,i,t);case Eu:o=8,s|=8;break;case al:return e=ct(12,r,t,s|2),e.elementType=al,e.lanes=i,e;case ll:return e=ct(13,r,t,s),e.elementType=ll,e.lanes=i,e;case ul:return e=ct(19,r,t,s),e.elementType=ul,e.lanes=i,e;case mp:return Yo(r,s,i,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case hp:o=10;break e;case pp:o=9;break e;case Tu:o=11;break e;case Mu:o=14;break e;case nr:o=16,n=null;break e}throw Error(L(130,e==null?e:typeof e,""))}return t=ct(o,r,t,s),t.elementType=e,t.type=n,t.lanes=i,t}function Gr(e,t,r,n){return e=ct(7,e,n,t),e.lanes=r,e}function Yo(e,t,r,n){return e=ct(22,e,n,t),e.elementType=mp,e.lanes=r,e.stateNode={isHidden:!1},e}function Va(e,t,r){return e=ct(6,e,null,t),e.lanes=r,e}function Fa(e,t,r){return t=ct(4,e.children!==null?e.children:[],e.key,t),t.lanes=r,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function zv(e,t,r,n,s){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ya(0),this.expirationTimes=ya(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ya(0),this.identifierPrefix=n,this.onRecoverableError=s,this.mutableSourceEagerHydrationData=null}function dc(e,t,r,n,s,i,o,a,l){return e=new zv(e,t,r,a,l),t===1?(t=1,i===!0&&(t|=8)):t=0,i=ct(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:n,isDehydrated:r,cache:null,transitions:null,pendingSuspenseBoundaries:null},Yu(i),e}function Ov(e,t,r){var n=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(u0)}catch(e){console.error(e)}}u0(),up.exports=st;var Hv=up.exports,lf=Hv;il.createRoot=lf.createRoot,il.hydrateRoot=lf.hydrateRoot;/** + * @remix-run/router v1.23.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function Zs(){return Zs=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u")throw new Error(t)}function c0(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function Gv(){return Math.random().toString(36).substr(2,8)}function cf(e,t){return{usr:e.state,key:e.key,idx:t}}function Zl(e,t,r,n){return r===void 0&&(r=null),Zs({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?Gn(t):t,{state:r,key:t&&t.key||n||Gv()})}function Co(e){let{pathname:t="/",search:r="",hash:n=""}=e;return r&&r!=="?"&&(t+=r.charAt(0)==="?"?r:"?"+r),n&&n!=="#"&&(t+=n.charAt(0)==="#"?n:"#"+n),t}function Gn(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substr(r),e=e.substr(0,r));let n=e.indexOf("?");n>=0&&(t.search=e.substr(n),e=e.substr(0,n)),e&&(t.pathname=e)}return t}function Yv(e,t,r,n){n===void 0&&(n={});let{window:s=document.defaultView,v5Compat:i=!1}=n,o=s.history,a=dr.Pop,l=null,c=d();c==null&&(c=0,o.replaceState(Zs({},o.state,{idx:c}),""));function d(){return(o.state||{idx:null}).idx}function f(){a=dr.Pop;let w=d(),v=w==null?null:w-c;c=w,l&&l({action:a,location:g.location,delta:v})}function u(w,v){a=dr.Push;let y=Zl(g.location,w,v);c=d()+1;let x=cf(y,c),b=g.createHref(y);try{o.pushState(x,"",b)}catch(k){if(k instanceof DOMException&&k.name==="DataCloneError")throw k;s.location.assign(b)}i&&l&&l({action:a,location:g.location,delta:1})}function p(w,v){a=dr.Replace;let y=Zl(g.location,w,v);c=d();let x=cf(y,c),b=g.createHref(y);o.replaceState(x,"",b),i&&l&&l({action:a,location:g.location,delta:0})}function m(w){let v=s.location.origin!=="null"?s.location.origin:s.location.href,y=typeof w=="string"?w:Co(w);return y=y.replace(/ $/,"%20"),we(v,"No window.location.(origin|href) available to create URL for href: "+y),new URL(y,v)}let g={get action(){return a},get location(){return e(s,o)},listen(w){if(l)throw new Error("A history only accepts one active listener");return s.addEventListener(uf,f),l=w,()=>{s.removeEventListener(uf,f),l=null}},createHref(w){return t(s,w)},createURL:m,encodeLocation(w){let v=m(w);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:u,replace:p,go(w){return o.go(w)}};return g}var df;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(df||(df={}));function Kv(e,t,r){return r===void 0&&(r="/"),Xv(e,t,r)}function Xv(e,t,r,n){let s=typeof t=="string"?Gn(t):t,i=mc(s.pathname||"/",r);if(i==null)return null;let o=d0(e);Qv(o);let a=null;for(let l=0;a==null&&l{let l={relativePath:a===void 0?i.path||"":a,caseSensitive:i.caseSensitive===!0,childrenIndex:o,route:i};l.relativePath.startsWith("/")&&(we(l.relativePath.startsWith(n),'Absolute route path "'+l.relativePath+'" nested under path '+('"'+n+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),l.relativePath=l.relativePath.slice(n.length));let c=wr([n,l.relativePath]),d=r.concat(l);i.children&&i.children.length>0&&(we(i.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+c+'".')),d0(i.children,t,d,c)),!(i.path==null&&!i.index)&&t.push({path:c,score:sx(c,i.index),routesMeta:d})};return e.forEach((i,o)=>{var a;if(i.path===""||!((a=i.path)!=null&&a.includes("?")))s(i,o);else for(let l of f0(i.path))s(i,o,l)}),t}function f0(e){let t=e.split("/");if(t.length===0)return[];let[r,...n]=t,s=r.endsWith("?"),i=r.replace(/\?$/,"");if(n.length===0)return s?[i,""]:[i];let o=f0(n.join("/")),a=[];return a.push(...o.map(l=>l===""?i:[i,l].join("/"))),s&&a.push(...o),a.map(l=>e.startsWith("/")&&l===""?"/":l)}function Qv(e){e.sort((t,r)=>t.score!==r.score?r.score-t.score:ix(t.routesMeta.map(n=>n.childrenIndex),r.routesMeta.map(n=>n.childrenIndex)))}const Zv=/^:[\w-]+$/,Jv=3,ex=2,tx=1,rx=10,nx=-2,ff=e=>e==="*";function sx(e,t){let r=e.split("/"),n=r.length;return r.some(ff)&&(n+=nx),t&&(n+=ex),r.filter(s=>!ff(s)).reduce((s,i)=>s+(Zv.test(i)?Jv:i===""?tx:rx),n)}function ix(e,t){return e.length===t.length&&e.slice(0,-1).every((n,s)=>n===t[s])?e[e.length-1]-t[t.length-1]:0}function ox(e,t,r){let{routesMeta:n}=e,s={},i="/",o=[];for(let a=0;a{let{paramName:u,isOptional:p}=d;if(u==="*"){let g=a[f]||"";o=i.slice(0,i.length-g.length).replace(/(.)\/+$/,"$1")}const m=a[f];return p&&!m?c[u]=void 0:c[u]=(m||"").replace(/%2F/g,"/"),c},{}),pathname:i,pathnameBase:o,pattern:e}}function lx(e,t,r){t===void 0&&(t=!1),r===void 0&&(r=!0),c0(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let n=[],s="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,a,l)=>(n.push({paramName:a,isOptional:l!=null}),l?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(n.push({paramName:"*"}),s+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?s+="\\/*$":e!==""&&e!=="/"&&(s+="(?:(?=\\/|$))"),[new RegExp(s,t?void 0:"i"),n]}function ux(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return c0(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function mc(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,n=e.charAt(r);return n&&n!=="/"?null:e.slice(r)||"/"}function cx(e,t){t===void 0&&(t="/");let{pathname:r,search:n="",hash:s=""}=typeof e=="string"?Gn(e):e;return{pathname:r?r.startsWith("/")?r:dx(r,t):t,search:px(n),hash:mx(s)}}function dx(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(s=>{s===".."?r.length>1&&r.pop():s!=="."&&r.push(s)}),r.length>1?r.join("/"):"/"}function Ia(e,t,r,n){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(n)+"]. Please separate it out to the ")+("`to."+r+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function fx(e){return e.filter((t,r)=>r===0||t.route.path&&t.route.path.length>0)}function gc(e,t){let r=fx(e);return t?r.map((n,s)=>s===r.length-1?n.pathname:n.pathnameBase):r.map(n=>n.pathnameBase)}function yc(e,t,r,n){n===void 0&&(n=!1);let s;typeof e=="string"?s=Gn(e):(s=Zs({},e),we(!s.pathname||!s.pathname.includes("?"),Ia("?","pathname","search",s)),we(!s.pathname||!s.pathname.includes("#"),Ia("#","pathname","hash",s)),we(!s.search||!s.search.includes("#"),Ia("#","search","hash",s)));let i=e===""||s.pathname==="",o=i?"/":s.pathname,a;if(o==null)a=r;else{let f=t.length-1;if(!n&&o.startsWith("..")){let u=o.split("/");for(;u[0]==="..";)u.shift(),f-=1;s.pathname=u.join("/")}a=f>=0?t[f]:"/"}let l=cx(s,a),c=o&&o!=="/"&&o.endsWith("/"),d=(i||o===".")&&r.endsWith("/");return!l.pathname.endsWith("/")&&(c||d)&&(l.pathname+="/"),l}const wr=e=>e.join("/").replace(/\/\/+/g,"/"),hx=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),px=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,mx=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function gx(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const h0=["post","put","patch","delete"];new Set(h0);const yx=["get",...h0];new Set(yx);/** + * React Router v6.30.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function Js(){return Js=Object.assign?Object.assign.bind():function(e){for(var t=1;t{a.current=!0}),S.useCallback(function(c,d){if(d===void 0&&(d={}),!a.current)return;if(typeof c=="number"){n.go(c);return}let f=yc(c,JSON.parse(o),i,d.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:wr([t,f.pathname])),(d.replace?n.replace:n.push)(f,d.state,d)},[t,n,o,i,e])}function g0(e,t){let{relative:r}=t===void 0?{}:t,{future:n}=S.useContext(Mr),{matches:s}=S.useContext(Ar),{pathname:i}=_r(),o=JSON.stringify(gc(s,n.v7_relativeSplatPath));return S.useMemo(()=>yc(e,JSON.parse(o),i,r==="path"),[e,o,i,r])}function bx(e,t){return Sx(e,t)}function Sx(e,t,r,n){Yn()||we(!1);let{navigator:s}=S.useContext(Mr),{matches:i}=S.useContext(Ar),o=i[i.length-1],a=o?o.params:{};o&&o.pathname;let l=o?o.pathnameBase:"/";o&&o.route;let c=_r(),d;if(t){var f;let w=typeof t=="string"?Gn(t):t;l==="/"||(f=w.pathname)!=null&&f.startsWith(l)||we(!1),d=w}else d=c;let u=d.pathname||"/",p=u;if(l!=="/"){let w=l.replace(/^\//,"").split("/");p="/"+u.replace(/^\//,"").split("/").slice(w.length).join("/")}let m=Kv(e,{pathname:p}),g=Px(m&&m.map(w=>Object.assign({},w,{params:Object.assign({},a,w.params),pathname:wr([l,s.encodeLocation?s.encodeLocation(w.pathname).pathname:w.pathname]),pathnameBase:w.pathnameBase==="/"?l:wr([l,s.encodeLocation?s.encodeLocation(w.pathnameBase).pathname:w.pathnameBase])})),i,r,n);return t&&g?S.createElement(Jo.Provider,{value:{location:Js({pathname:"/",search:"",hash:"",state:null,key:"default"},d),navigationType:dr.Pop}},g):g}function kx(){let e=Ax(),t=gx(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),r=e instanceof Error?e.stack:null,s={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return S.createElement(S.Fragment,null,S.createElement("h2",null,"Unexpected Application Error!"),S.createElement("h3",{style:{fontStyle:"italic"}},t),r?S.createElement("pre",{style:s},r):null,null)}const jx=S.createElement(kx,null);class Cx extends S.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,r){return r.location!==t.location||r.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:r.error,location:r.location,revalidation:t.revalidation||r.revalidation}}componentDidCatch(t,r){console.error("React Router caught the following error during render",t,r)}render(){return this.state.error!==void 0?S.createElement(Ar.Provider,{value:this.props.routeContext},S.createElement(p0.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function Nx(e){let{routeContext:t,match:r,children:n}=e,s=S.useContext(vc);return s&&s.static&&s.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=r.route.id),S.createElement(Ar.Provider,{value:t},n)}function Px(e,t,r,n){var s;if(t===void 0&&(t=[]),r===void 0&&(r=null),n===void 0&&(n=null),e==null){var i;if(!r)return null;if(r.errors)e=r.matches;else if((i=n)!=null&&i.v7_partialHydration&&t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let o=e,a=(s=r)==null?void 0:s.errors;if(a!=null){let d=o.findIndex(f=>f.route.id&&(a==null?void 0:a[f.route.id])!==void 0);d>=0||we(!1),o=o.slice(0,Math.min(o.length,d+1))}let l=!1,c=-1;if(r&&n&&n.v7_partialHydration)for(let d=0;d=0?o=o.slice(0,c+1):o=[o[0]];break}}}return o.reduceRight((d,f,u)=>{let p,m=!1,g=null,w=null;r&&(p=a&&f.route.id?a[f.route.id]:void 0,g=f.route.errorElement||jx,l&&(c<0&&u===0?(Lx("route-fallback"),m=!0,w=null):c===u&&(m=!0,w=f.route.hydrateFallbackElement||null)));let v=t.concat(o.slice(0,u+1)),y=()=>{let x;return p?x=g:m?x=w:f.route.Component?x=S.createElement(f.route.Component,null):f.route.element?x=f.route.element:x=d,S.createElement(Nx,{match:f,routeContext:{outlet:d,matches:v,isDataRoute:r!=null},children:x})};return r&&(f.route.ErrorBoundary||f.route.errorElement||u===0)?S.createElement(Cx,{location:r.location,revalidation:r.revalidation,component:g,error:p,children:y(),routeContext:{outlet:null,matches:v,isDataRoute:!0}}):y()},null)}var y0=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(y0||{}),v0=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(v0||{});function Ex(e){let t=S.useContext(vc);return t||we(!1),t}function Tx(e){let t=S.useContext(vx);return t||we(!1),t}function Mx(e){let t=S.useContext(Ar);return t||we(!1),t}function x0(e){let t=Mx(),r=t.matches[t.matches.length-1];return r.route.id||we(!1),r.route.id}function Ax(){var e;let t=S.useContext(p0),r=Tx(),n=x0();return t!==void 0?t:(e=r.errors)==null?void 0:e[n]}function _x(){let{router:e}=Ex(y0.UseNavigateStable),t=x0(v0.UseNavigateStable),r=S.useRef(!1);return m0(()=>{r.current=!0}),S.useCallback(function(s,i){i===void 0&&(i={}),r.current&&(typeof s=="number"?e.navigate(s):e.navigate(s,Js({fromRouteId:t},i)))},[e,t])}const hf={};function Lx(e,t,r){hf[e]||(hf[e]=!0)}function Dx(e,t){e==null||e.v7_startTransition,e==null||e.v7_relativeSplatPath}function Rx(e){let{to:t,replace:r,state:n,relative:s}=e;Yn()||we(!1);let{future:i,static:o}=S.useContext(Mr),{matches:a}=S.useContext(Ar),{pathname:l}=_r(),c=ea(),d=yc(t,gc(a,i.v7_relativeSplatPath),l,s==="path"),f=JSON.stringify(d);return S.useEffect(()=>c(JSON.parse(f),{replace:r,state:n,relative:s}),[c,f,s,r,n]),null}function jt(e){we(!1)}function Vx(e){let{basename:t="/",children:r=null,location:n,navigationType:s=dr.Pop,navigator:i,static:o=!1,future:a}=e;Yn()&&we(!1);let l=t.replace(/^\/*/,"/"),c=S.useMemo(()=>({basename:l,navigator:i,static:o,future:Js({v7_relativeSplatPath:!1},a)}),[l,a,i,o]);typeof n=="string"&&(n=Gn(n));let{pathname:d="/",search:f="",hash:u="",state:p=null,key:m="default"}=n,g=S.useMemo(()=>{let w=mc(d,l);return w==null?null:{location:{pathname:w,search:f,hash:u,state:p,key:m},navigationType:s}},[l,d,f,u,p,m,s]);return g==null?null:S.createElement(Mr.Provider,{value:c},S.createElement(Jo.Provider,{children:r,value:g}))}function Fx(e){let{children:t,location:r}=e;return bx(Jl(t),r)}new Promise(()=>{});function Jl(e,t){t===void 0&&(t=[]);let r=[];return S.Children.forEach(e,(n,s)=>{if(!S.isValidElement(n))return;let i=[...t,s];if(n.type===S.Fragment){r.push.apply(r,Jl(n.props.children,i));return}n.type!==jt&&we(!1),!n.props.index||!n.props.children||we(!1);let o={id:n.props.id||i.join("-"),caseSensitive:n.props.caseSensitive,element:n.props.element,Component:n.props.Component,index:n.props.index,path:n.props.path,loader:n.props.loader,action:n.props.action,errorElement:n.props.errorElement,ErrorBoundary:n.props.ErrorBoundary,hasErrorBoundary:n.props.ErrorBoundary!=null||n.props.errorElement!=null,shouldRevalidate:n.props.shouldRevalidate,handle:n.props.handle,lazy:n.props.lazy};n.props.children&&(o.children=Jl(n.props.children,i)),r.push(o)}),r}/** + * React Router DOM v6.30.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function eu(){return eu=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&(r[s]=e[s]);return r}function zx(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ox(e,t){return e.button===0&&(!t||t==="_self")&&!zx(e)}function tu(e){return e===void 0&&(e=""),new URLSearchParams(typeof e=="string"||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,r)=>{let n=e[r];return t.concat(Array.isArray(n)?n.map(s=>[r,s]):[[r,n]])},[]))}function $x(e,t){let r=tu(e);return t&&t.forEach((n,s)=>{r.has(s)||t.getAll(s).forEach(i=>{r.append(s,i)})}),r}const Bx=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],Ux="6";try{window.__reactRouterVersion=Ux}catch{}const Wx="startTransition",pf=Dy[Wx];function Hx(e){let{basename:t,children:r,future:n,window:s}=e,i=S.useRef();i.current==null&&(i.current=qv({window:s,v5Compat:!0}));let o=i.current,[a,l]=S.useState({action:o.action,location:o.location}),{v7_startTransition:c}=n||{},d=S.useCallback(f=>{c&&pf?pf(()=>l(f)):l(f)},[l,c]);return S.useLayoutEffect(()=>o.listen(d),[o,d]),S.useEffect(()=>Dx(n),[n]),S.createElement(Vx,{basename:t,children:r,location:a.location,navigationType:a.action,navigator:o,future:n})}const qx=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",Gx=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Xi=S.forwardRef(function(t,r){let{onClick:n,relative:s,reloadDocument:i,replace:o,state:a,target:l,to:c,preventScrollReset:d,viewTransition:f}=t,u=Ix(t,Bx),{basename:p}=S.useContext(Mr),m,g=!1;if(typeof c=="string"&&Gx.test(c)&&(m=c,qx))try{let x=new URL(window.location.href),b=c.startsWith("//")?new URL(x.protocol+c):new URL(c),k=mc(b.pathname,p);b.origin===x.origin&&k!=null?c=k+b.search+b.hash:g=!0}catch{}let w=xx(c,{relative:s}),v=Yx(c,{replace:o,state:a,target:l,preventScrollReset:d,relative:s,viewTransition:f});function y(x){n&&n(x),x.defaultPrevented||v(x)}return S.createElement("a",eu({},u,{href:m||w,onClick:g||i?n:y,ref:r,target:l}))});var mf;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(mf||(mf={}));var gf;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(gf||(gf={}));function Yx(e,t){let{target:r,replace:n,state:s,preventScrollReset:i,relative:o,viewTransition:a}=t===void 0?{}:t,l=ea(),c=_r(),d=g0(e,{relative:o});return S.useCallback(f=>{if(Ox(f,r)){f.preventDefault();let u=n!==void 0?n:Co(c)===Co(d);l(e,{replace:u,state:s,preventScrollReset:i,relative:o,viewTransition:a})}},[c,l,d,n,s,r,e,i,o,a])}function Kx(e){let t=S.useRef(tu(e)),r=S.useRef(!1),n=_r(),s=S.useMemo(()=>$x(n.search,r.current?null:t.current),[n.search]),i=ea(),o=S.useCallback((a,l)=>{const c=tu(typeof a=="function"?a(s):a);r.current=!0,i("?"+c,l)},[i,s]);return[s,o]}let Xx={data:""},Qx=e=>{if(typeof window=="object"){let t=(e?e.querySelector("#_goober"):window._goober)||Object.assign(document.createElement("style"),{innerHTML:" ",id:"_goober"});return t.nonce=window.__nonce__,t.parentNode||(e||document.head).appendChild(t),t.firstChild}return e||Xx},Zx=/(?:([\u0080-\uFFFF\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\s*)/g,Jx=/\/\*[^]*?\*\/| +/g,yf=/\n+/g,lr=(e,t)=>{let r="",n="",s="";for(let i in e){let o=e[i];i[0]=="@"?i[1]=="i"?r=i+" "+o+";":n+=i[1]=="f"?lr(o,i):i+"{"+lr(o,i[1]=="k"?"":t)+"}":typeof o=="object"?n+=lr(o,t?t.replace(/([^,])+/g,a=>i.replace(/([^,]*:\S+\([^)]*\))|([^,])+/g,l=>/&/.test(l)?l.replace(/&/g,a):a?a+" "+l:l)):i):o!=null&&(i=/^--/.test(i)?i:i.replace(/[A-Z]/g,"-$&").toLowerCase(),s+=lr.p?lr.p(i,o):i+":"+o+";")}return r+(t&&s?t+"{"+s+"}":s)+n},Dt={},w0=e=>{if(typeof e=="object"){let t="";for(let r in e)t+=r+w0(e[r]);return t}return e},e2=(e,t,r,n,s)=>{let i=w0(e),o=Dt[i]||(Dt[i]=(l=>{let c=0,d=11;for(;c>>0;return"go"+d})(i));if(!Dt[o]){let l=i!==e?e:(c=>{let d,f,u=[{}];for(;d=Zx.exec(c.replace(Jx,""));)d[4]?u.shift():d[3]?(f=d[3].replace(yf," ").trim(),u.unshift(u[0][f]=u[0][f]||{})):u[0][d[1]]=d[2].replace(yf," ").trim();return u[0]})(e);Dt[o]=lr(s?{["@keyframes "+o]:l}:l,r?"":"."+o)}let a=r&&Dt.g?Dt.g:null;return r&&(Dt.g=Dt[o]),((l,c,d,f)=>{f?c.data=c.data.replace(f,l):c.data.indexOf(l)===-1&&(c.data=d?l+c.data:c.data+l)})(Dt[o],t,n,a),o},t2=(e,t,r)=>e.reduce((n,s,i)=>{let o=t[i];if(o&&o.call){let a=o(r),l=a&&a.props&&a.props.className||/^go/.test(a)&&a;o=l?"."+l:a&&typeof a=="object"?a.props?"":lr(a,""):a===!1?"":a}return n+s+(o??"")},"");function ta(e){let t=this||{},r=e.call?e(t.p):e;return e2(r.unshift?r.raw?t2(r,[].slice.call(arguments,1),t.p):r.reduce((n,s)=>Object.assign(n,s&&s.call?s(t.p):s),{}):r,Qx(t.target),t.g,t.o,t.k)}let b0,ru,nu;ta.bind({g:1});let Yt=ta.bind({k:1});function r2(e,t,r,n){lr.p=t,b0=e,ru=r,nu=n}function Lr(e,t){let r=this||{};return function(){let n=arguments;function s(i,o){let a=Object.assign({},i),l=a.className||s.className;r.p=Object.assign({theme:ru&&ru()},a),r.o=/ *go\d+/.test(l),a.className=ta.apply(r,n)+(l?" "+l:"");let c=e;return e[0]&&(c=a.as||e,delete a.as),nu&&c[0]&&nu(a),b0(c,a)}return s}}var n2=e=>typeof e=="function",No=(e,t)=>n2(e)?e(t):e,s2=(()=>{let e=0;return()=>(++e).toString()})(),S0=(()=>{let e;return()=>{if(e===void 0&&typeof window<"u"){let t=matchMedia("(prefers-reduced-motion: reduce)");e=!t||t.matches}return e}})(),i2=20,xc="default",k0=(e,t)=>{let{toastLimit:r}=e.settings;switch(t.type){case 0:return{...e,toasts:[t.toast,...e.toasts].slice(0,r)};case 1:return{...e,toasts:e.toasts.map(o=>o.id===t.toast.id?{...o,...t.toast}:o)};case 2:let{toast:n}=t;return k0(e,{type:e.toasts.find(o=>o.id===n.id)?1:0,toast:n});case 3:let{toastId:s}=t;return{...e,toasts:e.toasts.map(o=>o.id===s||s===void 0?{...o,dismissed:!0,visible:!1}:o)};case 4:return t.toastId===void 0?{...e,toasts:[]}:{...e,toasts:e.toasts.filter(o=>o.id!==t.toastId)};case 5:return{...e,pausedAt:t.time};case 6:let i=t.time-(e.pausedAt||0);return{...e,pausedAt:void 0,toasts:e.toasts.map(o=>({...o,pauseDuration:o.pauseDuration+i}))}}},Qi=[],j0={toasts:[],pausedAt:void 0,settings:{toastLimit:i2}},Pt={},C0=(e,t=xc)=>{Pt[t]=k0(Pt[t]||j0,e),Qi.forEach(([r,n])=>{r===t&&n(Pt[t])})},N0=e=>Object.keys(Pt).forEach(t=>C0(e,t)),o2=e=>Object.keys(Pt).find(t=>Pt[t].toasts.some(r=>r.id===e)),ra=(e=xc)=>t=>{C0(t,e)},a2={blank:4e3,error:4e3,success:2e3,loading:1/0,custom:4e3},l2=(e={},t=xc)=>{let[r,n]=S.useState(Pt[t]||j0),s=S.useRef(Pt[t]);S.useEffect(()=>(s.current!==Pt[t]&&n(Pt[t]),Qi.push([t,n]),()=>{let o=Qi.findIndex(([a])=>a===t);o>-1&&Qi.splice(o,1)}),[t]);let i=r.toasts.map(o=>{var a,l,c;return{...e,...e[o.type],...o,removeDelay:o.removeDelay||((a=e[o.type])==null?void 0:a.removeDelay)||(e==null?void 0:e.removeDelay),duration:o.duration||((l=e[o.type])==null?void 0:l.duration)||(e==null?void 0:e.duration)||a2[o.type],style:{...e.style,...(c=e[o.type])==null?void 0:c.style,...o.style}}});return{...r,toasts:i}},u2=(e,t="blank",r)=>({createdAt:Date.now(),visible:!0,dismissed:!1,type:t,ariaProps:{role:"status","aria-live":"polite"},message:e,pauseDuration:0,...r,id:(r==null?void 0:r.id)||s2()}),ci=e=>(t,r)=>{let n=u2(t,e,r);return ra(n.toasterId||o2(n.id))({type:2,toast:n}),n.id},Ce=(e,t)=>ci("blank")(e,t);Ce.error=ci("error");Ce.success=ci("success");Ce.loading=ci("loading");Ce.custom=ci("custom");Ce.dismiss=(e,t)=>{let r={type:3,toastId:e};t?ra(t)(r):N0(r)};Ce.dismissAll=e=>Ce.dismiss(void 0,e);Ce.remove=(e,t)=>{let r={type:4,toastId:e};t?ra(t)(r):N0(r)};Ce.removeAll=e=>Ce.remove(void 0,e);Ce.promise=(e,t,r)=>{let n=Ce.loading(t.loading,{...r,...r==null?void 0:r.loading});return typeof e=="function"&&(e=e()),e.then(s=>{let i=t.success?No(t.success,s):void 0;return i?Ce.success(i,{id:n,...r,...r==null?void 0:r.success}):Ce.dismiss(n),s}).catch(s=>{let i=t.error?No(t.error,s):void 0;i?Ce.error(i,{id:n,...r,...r==null?void 0:r.error}):Ce.dismiss(n)}),e};var c2=1e3,d2=(e,t="default")=>{let{toasts:r,pausedAt:n}=l2(e,t),s=S.useRef(new Map).current,i=S.useCallback((f,u=c2)=>{if(s.has(f))return;let p=setTimeout(()=>{s.delete(f),o({type:4,toastId:f})},u);s.set(f,p)},[]);S.useEffect(()=>{if(n)return;let f=Date.now(),u=r.map(p=>{if(p.duration===1/0)return;let m=(p.duration||0)+p.pauseDuration-(f-p.createdAt);if(m<0){p.visible&&Ce.dismiss(p.id);return}return setTimeout(()=>Ce.dismiss(p.id,t),m)});return()=>{u.forEach(p=>p&&clearTimeout(p))}},[r,n,t]);let o=S.useCallback(ra(t),[t]),a=S.useCallback(()=>{o({type:5,time:Date.now()})},[o]),l=S.useCallback((f,u)=>{o({type:1,toast:{id:f,height:u}})},[o]),c=S.useCallback(()=>{n&&o({type:6,time:Date.now()})},[n,o]),d=S.useCallback((f,u)=>{let{reverseOrder:p=!1,gutter:m=8,defaultPosition:g}=u||{},w=r.filter(x=>(x.position||g)===(f.position||g)&&x.height),v=w.findIndex(x=>x.id===f.id),y=w.filter((x,b)=>bx.visible).slice(...p?[y+1]:[0,y]).reduce((x,b)=>x+(b.height||0)+m,0)},[r]);return S.useEffect(()=>{r.forEach(f=>{if(f.dismissed)i(f.id,f.removeDelay);else{let u=s.get(f.id);u&&(clearTimeout(u),s.delete(f.id))}})},[r,i]),{toasts:r,handlers:{updateHeight:l,startPause:a,endPause:c,calculateOffset:d}}},f2=Yt` +from { + transform: scale(0) rotate(45deg); + opacity: 0; +} +to { + transform: scale(1) rotate(45deg); + opacity: 1; +}`,h2=Yt` +from { + transform: scale(0); + opacity: 0; +} +to { + transform: scale(1); + opacity: 1; +}`,p2=Yt` +from { + transform: scale(0) rotate(90deg); + opacity: 0; +} +to { + transform: scale(1) rotate(90deg); + opacity: 1; +}`,m2=Lr("div")` + width: 20px; + opacity: 0; + height: 20px; + border-radius: 10px; + background: ${e=>e.primary||"#ff4b4b"}; + position: relative; + transform: rotate(45deg); + + animation: ${f2} 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) + forwards; + animation-delay: 100ms; + + &:after, + &:before { + content: ''; + animation: ${h2} 0.15s ease-out forwards; + animation-delay: 150ms; + position: absolute; + border-radius: 3px; + opacity: 0; + background: ${e=>e.secondary||"#fff"}; + bottom: 9px; + left: 4px; + height: 2px; + width: 12px; + } + + &:before { + animation: ${p2} 0.15s ease-out forwards; + animation-delay: 180ms; + transform: rotate(90deg); + } +`,g2=Yt` + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +`,y2=Lr("div")` + width: 12px; + height: 12px; + box-sizing: border-box; + border: 2px solid; + border-radius: 100%; + border-color: ${e=>e.secondary||"#e0e0e0"}; + border-right-color: ${e=>e.primary||"#616161"}; + animation: ${g2} 1s linear infinite; +`,v2=Yt` +from { + transform: scale(0) rotate(45deg); + opacity: 0; +} +to { + transform: scale(1) rotate(45deg); + opacity: 1; +}`,x2=Yt` +0% { + height: 0; + width: 0; + opacity: 0; +} +40% { + height: 0; + width: 6px; + opacity: 1; +} +100% { + opacity: 1; + height: 10px; +}`,w2=Lr("div")` + width: 20px; + opacity: 0; + height: 20px; + border-radius: 10px; + background: ${e=>e.primary||"#61d345"}; + position: relative; + transform: rotate(45deg); + + animation: ${v2} 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) + forwards; + animation-delay: 100ms; + &:after { + content: ''; + box-sizing: border-box; + animation: ${x2} 0.2s ease-out forwards; + opacity: 0; + animation-delay: 200ms; + position: absolute; + border-right: 2px solid; + border-bottom: 2px solid; + border-color: ${e=>e.secondary||"#fff"}; + bottom: 6px; + left: 6px; + height: 10px; + width: 6px; + } +`,b2=Lr("div")` + position: absolute; +`,S2=Lr("div")` + position: relative; + display: flex; + justify-content: center; + align-items: center; + min-width: 20px; + min-height: 20px; +`,k2=Yt` +from { + transform: scale(0.6); + opacity: 0.4; +} +to { + transform: scale(1); + opacity: 1; +}`,j2=Lr("div")` + position: relative; + transform: scale(0.6); + opacity: 0.4; + min-width: 20px; + animation: ${k2} 0.3s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275) + forwards; +`,C2=({toast:e})=>{let{icon:t,type:r,iconTheme:n}=e;return t!==void 0?typeof t=="string"?S.createElement(j2,null,t):t:r==="blank"?null:S.createElement(S2,null,S.createElement(y2,{...n}),r!=="loading"&&S.createElement(b2,null,r==="error"?S.createElement(m2,{...n}):S.createElement(w2,{...n})))},N2=e=>` +0% {transform: translate3d(0,${e*-200}%,0) scale(.6); opacity:.5;} +100% {transform: translate3d(0,0,0) scale(1); opacity:1;} +`,P2=e=>` +0% {transform: translate3d(0,0,-1px) scale(1); opacity:1;} +100% {transform: translate3d(0,${e*-150}%,-1px) scale(.6); opacity:0;} +`,E2="0%{opacity:0;} 100%{opacity:1;}",T2="0%{opacity:1;} 100%{opacity:0;}",M2=Lr("div")` + display: flex; + align-items: center; + background: #fff; + color: #363636; + line-height: 1.3; + will-change: transform; + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05); + max-width: 350px; + pointer-events: auto; + padding: 8px 10px; + border-radius: 8px; +`,A2=Lr("div")` + display: flex; + justify-content: center; + margin: 4px 10px; + color: inherit; + flex: 1 1 auto; + white-space: pre-line; +`,_2=(e,t)=>{let r=e.includes("top")?1:-1,[n,s]=S0()?[E2,T2]:[N2(r),P2(r)];return{animation:t?`${Yt(n)} 0.35s cubic-bezier(.21,1.02,.73,1) forwards`:`${Yt(s)} 0.4s forwards cubic-bezier(.06,.71,.55,1)`}},L2=S.memo(({toast:e,position:t,style:r,children:n})=>{let s=e.height?_2(e.position||t||"top-center",e.visible):{opacity:0},i=S.createElement(C2,{toast:e}),o=S.createElement(A2,{...e.ariaProps},No(e.message,e));return S.createElement(M2,{className:e.className,style:{...s,...r,...e.style}},typeof n=="function"?n({icon:i,message:o}):S.createElement(S.Fragment,null,i,o))});r2(S.createElement);var D2=({id:e,className:t,style:r,onHeightUpdate:n,children:s})=>{let i=S.useCallback(o=>{if(o){let a=()=>{let l=o.getBoundingClientRect().height;n(e,l)};a(),new MutationObserver(a).observe(o,{subtree:!0,childList:!0,characterData:!0})}},[e,n]);return S.createElement("div",{ref:i,className:t,style:r},s)},R2=(e,t)=>{let r=e.includes("top"),n=r?{top:0}:{bottom:0},s=e.includes("center")?{justifyContent:"center"}:e.includes("right")?{justifyContent:"flex-end"}:{};return{left:0,right:0,display:"flex",position:"absolute",transition:S0()?void 0:"all 230ms cubic-bezier(.21,1.02,.73,1)",transform:`translateY(${t*(r?1:-1)}px)`,...n,...s}},V2=ta` + z-index: 9999; + > * { + pointer-events: auto; + } +`,_i=16,F2=({reverseOrder:e,position:t="top-center",toastOptions:r,gutter:n,children:s,toasterId:i,containerStyle:o,containerClassName:a})=>{let{toasts:l,handlers:c}=d2(r,i);return S.createElement("div",{"data-rht-toaster":i||"",style:{position:"fixed",zIndex:9999,top:_i,left:_i,right:_i,bottom:_i,pointerEvents:"none",...o},className:a,onMouseEnter:c.startPause,onMouseLeave:c.endPause},l.map(d=>{let f=d.position||t,u=c.calculateOffset(d,{reverseOrder:e,gutter:n,defaultPosition:t}),p=R2(f,u);return S.createElement(D2,{id:d.id,key:d.id,onHeightUpdate:c.updateHeight,className:d.visible?V2:"",style:p},d.type==="custom"?No(d.message,d):s?s(d):S.createElement(L2,{toast:d,position:f}))}))},ce=Ce;const P0=S.createContext({transformPagePoint:e=>e,isStatic:!1,reducedMotion:"never"}),na=S.createContext({}),sa=S.createContext(null),ia=typeof document<"u",wc=ia?S.useLayoutEffect:S.useEffect,E0=S.createContext({strict:!1}),bc=e=>e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),I2="framerAppearId",T0="data-"+bc(I2);function z2(e,t,r,n){const{visualElement:s}=S.useContext(na),i=S.useContext(E0),o=S.useContext(sa),a=S.useContext(P0).reducedMotion,l=S.useRef();n=n||i.renderer,!l.current&&n&&(l.current=n(e,{visualState:t,parent:s,props:r,presenceContext:o,blockInitialAnimation:o?o.initial===!1:!1,reducedMotionConfig:a}));const c=l.current;S.useInsertionEffect(()=>{c&&c.update(r,o)});const d=S.useRef(!!(r[T0]&&!window.HandoffComplete));return wc(()=>{c&&(c.render(),d.current&&c.animationState&&c.animationState.animateChanges())}),S.useEffect(()=>{c&&(c.updateFeatures(),!d.current&&c.animationState&&c.animationState.animateChanges(),d.current&&(d.current=!1,window.HandoffComplete=!0))}),c}function bn(e){return e&&typeof e=="object"&&Object.prototype.hasOwnProperty.call(e,"current")}function O2(e,t,r){return S.useCallback(n=>{n&&e.mount&&e.mount(n),t&&(n?t.mount(n):t.unmount()),r&&(typeof r=="function"?r(n):bn(r)&&(r.current=n))},[t])}function ei(e){return typeof e=="string"||Array.isArray(e)}function oa(e){return e!==null&&typeof e=="object"&&typeof e.start=="function"}const Sc=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],kc=["initial",...Sc];function aa(e){return oa(e.animate)||kc.some(t=>ei(e[t]))}function M0(e){return!!(aa(e)||e.variants)}function $2(e,t){if(aa(e)){const{initial:r,animate:n}=e;return{initial:r===!1||ei(r)?r:void 0,animate:ei(n)?n:void 0}}return e.inherit!==!1?t:{}}function B2(e){const{initial:t,animate:r}=$2(e,S.useContext(na));return S.useMemo(()=>({initial:t,animate:r}),[vf(t),vf(r)])}function vf(e){return Array.isArray(e)?e.join(" "):e}const xf={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]},ti={};for(const e in xf)ti[e]={isEnabled:t=>xf[e].some(r=>!!t[r])};function U2(e){for(const t in e)ti[t]={...ti[t],...e[t]}}const jc=S.createContext({}),A0=S.createContext({}),W2=Symbol.for("motionComponentSymbol");function H2({preloadedFeatures:e,createVisualElement:t,useRender:r,useVisualState:n,Component:s}){e&&U2(e);function i(a,l){let c;const d={...S.useContext(P0),...a,layoutId:q2(a)},{isStatic:f}=d,u=B2(a),p=n(a,f);if(!f&&ia){u.visualElement=z2(s,p,d,t);const m=S.useContext(A0),g=S.useContext(E0).strict;u.visualElement&&(c=u.visualElement.loadFeatures(d,g,e,m))}return S.createElement(na.Provider,{value:u},c&&u.visualElement?S.createElement(c,{visualElement:u.visualElement,...d}):null,r(s,a,O2(p,u.visualElement,l),p,f,u.visualElement))}const o=S.forwardRef(i);return o[W2]=s,o}function q2({layoutId:e}){const t=S.useContext(jc).id;return t&&e!==void 0?t+"-"+e:e}function G2(e){function t(n,s={}){return H2(e(n,s))}if(typeof Proxy>"u")return t;const r=new Map;return new Proxy(t,{get:(n,s)=>(r.has(s)||r.set(s,t(s)),r.get(s))})}const Y2=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function Cc(e){return typeof e!="string"||e.includes("-")?!1:!!(Y2.indexOf(e)>-1||/[A-Z]/.test(e))}const Po={};function K2(e){Object.assign(Po,e)}const di=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],nn=new Set(di);function _0(e,{layout:t,layoutId:r}){return nn.has(e)||e.startsWith("origin")||(t||r!==void 0)&&(!!Po[e]||e==="opacity")}const Xe=e=>!!(e&&e.getVelocity),X2={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},Q2=di.length;function Z2(e,{enableHardwareAcceleration:t=!0,allowTransformNone:r=!0},n,s){let i="";for(let o=0;ot=>typeof t=="string"&&t.startsWith(e),D0=L0("--"),su=L0("var(--"),J2=/var\s*\(\s*--[\w-]+(\s*,\s*(?:(?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)+)?\s*\)/g,ew=(e,t)=>t&&typeof e=="number"?t.transform(e):e,jr=(e,t,r)=>Math.min(Math.max(r,e),t),sn={test:e=>typeof e=="number",parse:parseFloat,transform:e=>e},Ns={...sn,transform:e=>jr(0,1,e)},Li={...sn,default:1},Ps=e=>Math.round(e*1e5)/1e5,la=/(-)?([\d]*\.?[\d])+/g,R0=/(#[0-9a-f]{3,8}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))/gi,tw=/^(#[0-9a-f]{3,8}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))$/i;function fi(e){return typeof e=="string"}const hi=e=>({test:t=>fi(t)&&t.endsWith(e)&&t.split(" ").length===1,parse:parseFloat,transform:t=>`${t}${e}`}),rr=hi("deg"),At=hi("%"),U=hi("px"),rw=hi("vh"),nw=hi("vw"),wf={...At,parse:e=>At.parse(e)/100,transform:e=>At.transform(e*100)},bf={...sn,transform:Math.round},V0={borderWidth:U,borderTopWidth:U,borderRightWidth:U,borderBottomWidth:U,borderLeftWidth:U,borderRadius:U,radius:U,borderTopLeftRadius:U,borderTopRightRadius:U,borderBottomRightRadius:U,borderBottomLeftRadius:U,width:U,maxWidth:U,height:U,maxHeight:U,size:U,top:U,right:U,bottom:U,left:U,padding:U,paddingTop:U,paddingRight:U,paddingBottom:U,paddingLeft:U,margin:U,marginTop:U,marginRight:U,marginBottom:U,marginLeft:U,rotate:rr,rotateX:rr,rotateY:rr,rotateZ:rr,scale:Li,scaleX:Li,scaleY:Li,scaleZ:Li,skew:rr,skewX:rr,skewY:rr,distance:U,translateX:U,translateY:U,translateZ:U,x:U,y:U,z:U,perspective:U,transformPerspective:U,opacity:Ns,originX:wf,originY:wf,originZ:U,zIndex:bf,fillOpacity:Ns,strokeOpacity:Ns,numOctaves:bf};function Nc(e,t,r,n){const{style:s,vars:i,transform:o,transformOrigin:a}=e;let l=!1,c=!1,d=!0;for(const f in t){const u=t[f];if(D0(f)){i[f]=u;continue}const p=V0[f],m=ew(u,p);if(nn.has(f)){if(l=!0,o[f]=m,!d)continue;u!==(p.default||0)&&(d=!1)}else f.startsWith("origin")?(c=!0,a[f]=m):s[f]=m}if(t.transform||(l||n?s.transform=Z2(e.transform,r,d,n):s.transform&&(s.transform="none")),c){const{originX:f="50%",originY:u="50%",originZ:p=0}=a;s.transformOrigin=`${f} ${u} ${p}`}}const Pc=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function F0(e,t,r){for(const n in t)!Xe(t[n])&&!_0(n,r)&&(e[n]=t[n])}function sw({transformTemplate:e},t,r){return S.useMemo(()=>{const n=Pc();return Nc(n,t,{enableHardwareAcceleration:!r},e),Object.assign({},n.vars,n.style)},[t])}function iw(e,t,r){const n=e.style||{},s={};return F0(s,n,e),Object.assign(s,sw(e,t,r)),e.transformValues?e.transformValues(s):s}function ow(e,t,r){const n={},s=iw(e,t,r);return e.drag&&e.dragListener!==!1&&(n.draggable=!1,s.userSelect=s.WebkitUserSelect=s.WebkitTouchCallout="none",s.touchAction=e.drag===!0?"none":`pan-${e.drag==="x"?"y":"x"}`),e.tabIndex===void 0&&(e.onTap||e.onTapStart||e.whileTap)&&(n.tabIndex=0),n.style=s,n}const aw=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","transformValues","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","ignoreStrict","viewport"]);function Eo(e){return e.startsWith("while")||e.startsWith("drag")&&e!=="draggable"||e.startsWith("layout")||e.startsWith("onTap")||e.startsWith("onPan")||e.startsWith("onLayout")||aw.has(e)}let I0=e=>!Eo(e);function lw(e){e&&(I0=t=>t.startsWith("on")?!Eo(t):e(t))}try{lw(require("@emotion/is-prop-valid").default)}catch{}function uw(e,t,r){const n={};for(const s in e)s==="values"&&typeof e.values=="object"||(I0(s)||r===!0&&Eo(s)||!t&&!Eo(s)||e.draggable&&s.startsWith("onDrag"))&&(n[s]=e[s]);return n}function Sf(e,t,r){return typeof e=="string"?e:U.transform(t+r*e)}function cw(e,t,r){const n=Sf(t,e.x,e.width),s=Sf(r,e.y,e.height);return`${n} ${s}`}const dw={offset:"stroke-dashoffset",array:"stroke-dasharray"},fw={offset:"strokeDashoffset",array:"strokeDasharray"};function hw(e,t,r=1,n=0,s=!0){e.pathLength=1;const i=s?dw:fw;e[i.offset]=U.transform(-n);const o=U.transform(t),a=U.transform(r);e[i.array]=`${o} ${a}`}function Ec(e,{attrX:t,attrY:r,attrScale:n,originX:s,originY:i,pathLength:o,pathSpacing:a=1,pathOffset:l=0,...c},d,f,u){if(Nc(e,c,d,u),f){e.style.viewBox&&(e.attrs.viewBox=e.style.viewBox);return}e.attrs=e.style,e.style={};const{attrs:p,style:m,dimensions:g}=e;p.transform&&(g&&(m.transform=p.transform),delete p.transform),g&&(s!==void 0||i!==void 0||m.transform)&&(m.transformOrigin=cw(g,s!==void 0?s:.5,i!==void 0?i:.5)),t!==void 0&&(p.x=t),r!==void 0&&(p.y=r),n!==void 0&&(p.scale=n),o!==void 0&&hw(p,o,a,l,!1)}const z0=()=>({...Pc(),attrs:{}}),Tc=e=>typeof e=="string"&&e.toLowerCase()==="svg";function pw(e,t,r,n){const s=S.useMemo(()=>{const i=z0();return Ec(i,t,{enableHardwareAcceleration:!1},Tc(n),e.transformTemplate),{...i.attrs,style:{...i.style}}},[t]);if(e.style){const i={};F0(i,e.style,e),s.style={...i,...s.style}}return s}function mw(e=!1){return(r,n,s,{latestValues:i},o)=>{const l=(Cc(r)?pw:ow)(n,i,o,r),d={...uw(n,typeof r=="string",e),...l,ref:s},{children:f}=n,u=S.useMemo(()=>Xe(f)?f.get():f,[f]);return S.createElement(r,{...d,children:u})}}function O0(e,{style:t,vars:r},n,s){Object.assign(e.style,t,s&&s.getProjectionStyles(n));for(const i in r)e.style.setProperty(i,r[i])}const $0=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]);function B0(e,t,r,n){O0(e,t,void 0,n);for(const s in t.attrs)e.setAttribute($0.has(s)?s:bc(s),t.attrs[s])}function Mc(e,t){const{style:r}=e,n={};for(const s in r)(Xe(r[s])||t.style&&Xe(t.style[s])||_0(s,e))&&(n[s]=r[s]);return n}function U0(e,t){const r=Mc(e,t);for(const n in e)if(Xe(e[n])||Xe(t[n])){const s=di.indexOf(n)!==-1?"attr"+n.charAt(0).toUpperCase()+n.substring(1):n;r[s]=e[n]}return r}function Ac(e,t,r,n={},s={}){return typeof t=="function"&&(t=t(r!==void 0?r:e.custom,n,s)),typeof t=="string"&&(t=e.variants&&e.variants[t]),typeof t=="function"&&(t=t(r!==void 0?r:e.custom,n,s)),t}function W0(e){const t=S.useRef(null);return t.current===null&&(t.current=e()),t.current}const To=e=>Array.isArray(e),gw=e=>!!(e&&typeof e=="object"&&e.mix&&e.toValue),yw=e=>To(e)?e[e.length-1]||0:e;function Zi(e){const t=Xe(e)?e.get():e;return gw(t)?t.toValue():t}function vw({scrapeMotionValuesFromProps:e,createRenderState:t,onMount:r},n,s,i){const o={latestValues:xw(n,s,i,e),renderState:t()};return r&&(o.mount=a=>r(n,a,o)),o}const H0=e=>(t,r)=>{const n=S.useContext(na),s=S.useContext(sa),i=()=>vw(e,t,n,s);return r?i():W0(i)};function xw(e,t,r,n){const s={},i=n(e,{});for(const u in i)s[u]=Zi(i[u]);let{initial:o,animate:a}=e;const l=aa(e),c=M0(e);t&&c&&!l&&e.inherit!==!1&&(o===void 0&&(o=t.initial),a===void 0&&(a=t.animate));let d=r?r.initial===!1:!1;d=d||o===!1;const f=d?a:o;return f&&typeof f!="boolean"&&!oa(f)&&(Array.isArray(f)?f:[f]).forEach(p=>{const m=Ac(e,p);if(!m)return;const{transitionEnd:g,transition:w,...v}=m;for(const y in v){let x=v[y];if(Array.isArray(x)){const b=d?x.length-1:0;x=x[b]}x!==null&&(s[y]=x)}for(const y in g)s[y]=g[y]}),s}const xe=e=>e;class kf{constructor(){this.order=[],this.scheduled=new Set}add(t){if(!this.scheduled.has(t))return this.scheduled.add(t),this.order.push(t),!0}remove(t){const r=this.order.indexOf(t);r!==-1&&(this.order.splice(r,1),this.scheduled.delete(t))}clear(){this.order.length=0,this.scheduled.clear()}}function ww(e){let t=new kf,r=new kf,n=0,s=!1,i=!1;const o=new WeakSet,a={schedule:(l,c=!1,d=!1)=>{const f=d&&s,u=f?t:r;return c&&o.add(l),u.add(l)&&f&&s&&(n=t.order.length),l},cancel:l=>{r.remove(l),o.delete(l)},process:l=>{if(s){i=!0;return}if(s=!0,[t,r]=[r,t],r.clear(),n=t.order.length,n)for(let c=0;c(f[u]=ww(()=>r=!0),f),{}),o=f=>i[f].process(s),a=()=>{const f=performance.now();r=!1,s.delta=n?1e3/60:Math.max(Math.min(f-s.timestamp,bw),1),s.timestamp=f,s.isProcessing=!0,Di.forEach(o),s.isProcessing=!1,r&&t&&(n=!1,e(a))},l=()=>{r=!0,n=!0,s.isProcessing||e(a)};return{schedule:Di.reduce((f,u)=>{const p=i[u];return f[u]=(m,g=!1,w=!1)=>(r||l(),p.schedule(m,g,w)),f},{}),cancel:f=>Di.forEach(u=>i[u].cancel(f)),state:s,steps:i}}const{schedule:ne,cancel:Kt,state:De,steps:za}=Sw(typeof requestAnimationFrame<"u"?requestAnimationFrame:xe,!0),kw={useVisualState:H0({scrapeMotionValuesFromProps:U0,createRenderState:z0,onMount:(e,t,{renderState:r,latestValues:n})=>{ne.read(()=>{try{r.dimensions=typeof t.getBBox=="function"?t.getBBox():t.getBoundingClientRect()}catch{r.dimensions={x:0,y:0,width:0,height:0}}}),ne.render(()=>{Ec(r,n,{enableHardwareAcceleration:!1},Tc(t.tagName),e.transformTemplate),B0(t,r)})}})},jw={useVisualState:H0({scrapeMotionValuesFromProps:Mc,createRenderState:Pc})};function Cw(e,{forwardMotionProps:t=!1},r,n){return{...Cc(e)?kw:jw,preloadedFeatures:r,useRender:mw(t),createVisualElement:n,Component:e}}function Ot(e,t,r,n={passive:!0}){return e.addEventListener(t,r,n),()=>e.removeEventListener(t,r)}const q0=e=>e.pointerType==="mouse"?typeof e.button!="number"||e.button<=0:e.isPrimary!==!1;function ua(e,t="page"){return{point:{x:e[t+"X"],y:e[t+"Y"]}}}const Nw=e=>t=>q0(t)&&e(t,ua(t));function Bt(e,t,r,n){return Ot(e,t,Nw(r),n)}const Pw=(e,t)=>r=>t(e(r)),br=(...e)=>e.reduce(Pw);function G0(e){let t=null;return()=>{const r=()=>{t=null};return t===null?(t=e,r):!1}}const jf=G0("dragHorizontal"),Cf=G0("dragVertical");function Y0(e){let t=!1;if(e==="y")t=Cf();else if(e==="x")t=jf();else{const r=jf(),n=Cf();r&&n?t=()=>{r(),n()}:(r&&r(),n&&n())}return t}function K0(){const e=Y0(!0);return e?(e(),!1):!0}class Dr{constructor(t){this.isMounted=!1,this.node=t}update(){}}function Nf(e,t){const r="pointer"+(t?"enter":"leave"),n="onHover"+(t?"Start":"End"),s=(i,o)=>{if(i.pointerType==="touch"||K0())return;const a=e.getProps();e.animationState&&a.whileHover&&e.animationState.setActive("whileHover",t),a[n]&&ne.update(()=>a[n](i,o))};return Bt(e.current,r,s,{passive:!e.getProps()[n]})}class Ew extends Dr{mount(){this.unmount=br(Nf(this.node,!0),Nf(this.node,!1))}unmount(){}}class Tw extends Dr{constructor(){super(...arguments),this.isActive=!1}onFocus(){let t=!1;try{t=this.node.current.matches(":focus-visible")}catch{t=!0}!t||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=br(Ot(this.node.current,"focus",()=>this.onFocus()),Ot(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}const X0=(e,t)=>t?e===t?!0:X0(e,t.parentElement):!1;function Oa(e,t){if(!t)return;const r=new PointerEvent("pointer"+e);t(r,ua(r))}class Mw extends Dr{constructor(){super(...arguments),this.removeStartListeners=xe,this.removeEndListeners=xe,this.removeAccessibleListeners=xe,this.startPointerPress=(t,r)=>{if(this.isPressing)return;this.removeEndListeners();const n=this.node.getProps(),i=Bt(window,"pointerup",(a,l)=>{if(!this.checkPressEnd())return;const{onTap:c,onTapCancel:d,globalTapTarget:f}=this.node.getProps();ne.update(()=>{!f&&!X0(this.node.current,a.target)?d&&d(a,l):c&&c(a,l)})},{passive:!(n.onTap||n.onPointerUp)}),o=Bt(window,"pointercancel",(a,l)=>this.cancelPress(a,l),{passive:!(n.onTapCancel||n.onPointerCancel)});this.removeEndListeners=br(i,o),this.startPress(t,r)},this.startAccessiblePress=()=>{const t=i=>{if(i.key!=="Enter"||this.isPressing)return;const o=a=>{a.key!=="Enter"||!this.checkPressEnd()||Oa("up",(l,c)=>{const{onTap:d}=this.node.getProps();d&&ne.update(()=>d(l,c))})};this.removeEndListeners(),this.removeEndListeners=Ot(this.node.current,"keyup",o),Oa("down",(a,l)=>{this.startPress(a,l)})},r=Ot(this.node.current,"keydown",t),n=()=>{this.isPressing&&Oa("cancel",(i,o)=>this.cancelPress(i,o))},s=Ot(this.node.current,"blur",n);this.removeAccessibleListeners=br(r,s)}}startPress(t,r){this.isPressing=!0;const{onTapStart:n,whileTap:s}=this.node.getProps();s&&this.node.animationState&&this.node.animationState.setActive("whileTap",!0),n&&ne.update(()=>n(t,r))}checkPressEnd(){return this.removeEndListeners(),this.isPressing=!1,this.node.getProps().whileTap&&this.node.animationState&&this.node.animationState.setActive("whileTap",!1),!K0()}cancelPress(t,r){if(!this.checkPressEnd())return;const{onTapCancel:n}=this.node.getProps();n&&ne.update(()=>n(t,r))}mount(){const t=this.node.getProps(),r=Bt(t.globalTapTarget?window:this.node.current,"pointerdown",this.startPointerPress,{passive:!(t.onTapStart||t.onPointerStart)}),n=Ot(this.node.current,"focus",this.startAccessiblePress);this.removeStartListeners=br(r,n)}unmount(){this.removeStartListeners(),this.removeEndListeners(),this.removeAccessibleListeners()}}const iu=new WeakMap,$a=new WeakMap,Aw=e=>{const t=iu.get(e.target);t&&t(e)},_w=e=>{e.forEach(Aw)};function Lw({root:e,...t}){const r=e||document;$a.has(r)||$a.set(r,{});const n=$a.get(r),s=JSON.stringify(t);return n[s]||(n[s]=new IntersectionObserver(_w,{root:e,...t})),n[s]}function Dw(e,t,r){const n=Lw(t);return iu.set(e,r),n.observe(e),()=>{iu.delete(e),n.unobserve(e)}}const Rw={some:0,all:1};class Vw extends Dr{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.unmount();const{viewport:t={}}=this.node.getProps(),{root:r,margin:n,amount:s="some",once:i}=t,o={root:r?r.current:void 0,rootMargin:n,threshold:typeof s=="number"?s:Rw[s]},a=l=>{const{isIntersecting:c}=l;if(this.isInView===c||(this.isInView=c,i&&!c&&this.hasEnteredView))return;c&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",c);const{onViewportEnter:d,onViewportLeave:f}=this.node.getProps(),u=c?d:f;u&&u(l)};return Dw(this.node.current,o,a)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:t,prevProps:r}=this.node;["amount","margin","root"].some(Fw(t,r))&&this.startObserver()}unmount(){}}function Fw({viewport:e={}},{viewport:t={}}={}){return r=>e[r]!==t[r]}const Iw={inView:{Feature:Vw},tap:{Feature:Mw},focus:{Feature:Tw},hover:{Feature:Ew}};function Q0(e,t){if(!Array.isArray(t))return!1;const r=t.length;if(r!==e.length)return!1;for(let n=0;nt[n]=r.get()),t}function Ow(e){const t={};return e.values.forEach((r,n)=>t[n]=r.getVelocity()),t}function ca(e,t,r){const n=e.getProps();return Ac(n,t,r!==void 0?r:n.custom,zw(e),Ow(e))}let _c=xe;const Yr=e=>e*1e3,Ut=e=>e/1e3,$w={current:!1},Z0=e=>Array.isArray(e)&&typeof e[0]=="number";function J0(e){return!!(!e||typeof e=="string"&&eg[e]||Z0(e)||Array.isArray(e)&&e.every(J0))}const gs=([e,t,r,n])=>`cubic-bezier(${e}, ${t}, ${r}, ${n})`,eg={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:gs([0,.65,.55,1]),circOut:gs([.55,0,1,.45]),backIn:gs([.31,.01,.66,-.59]),backOut:gs([.33,1.53,.69,.99])};function tg(e){if(e)return Z0(e)?gs(e):Array.isArray(e)?e.map(tg):eg[e]}function Bw(e,t,r,{delay:n=0,duration:s,repeat:i=0,repeatType:o="loop",ease:a,times:l}={}){const c={[t]:r};l&&(c.offset=l);const d=tg(a);return Array.isArray(d)&&(c.easing=d),e.animate(c,{delay:n,duration:s,easing:Array.isArray(d)?"linear":d,fill:"both",iterations:i+1,direction:o==="reverse"?"alternate":"normal"})}function Uw(e,{repeat:t,repeatType:r="loop"}){const n=t&&r!=="loop"&&t%2===1?0:e.length-1;return e[n]}const rg=(e,t,r)=>(((1-3*r+3*t)*e+(3*r-6*t))*e+3*t)*e,Ww=1e-7,Hw=12;function qw(e,t,r,n,s){let i,o,a=0;do o=t+(r-t)/2,i=rg(o,n,s)-e,i>0?r=o:t=o;while(Math.abs(i)>Ww&&++aqw(i,0,1,e,r);return i=>i===0||i===1?i:rg(s(i),t,n)}const Gw=pi(.42,0,1,1),Yw=pi(0,0,.58,1),ng=pi(.42,0,.58,1),Kw=e=>Array.isArray(e)&&typeof e[0]!="number",sg=e=>t=>t<=.5?e(2*t)/2:(2-e(2*(1-t)))/2,ig=e=>t=>1-e(1-t),Lc=e=>1-Math.sin(Math.acos(e)),og=ig(Lc),Xw=sg(Lc),ag=pi(.33,1.53,.69,.99),Dc=ig(ag),Qw=sg(Dc),Zw=e=>(e*=2)<1?.5*Dc(e):.5*(2-Math.pow(2,-10*(e-1))),Jw={linear:xe,easeIn:Gw,easeInOut:ng,easeOut:Yw,circIn:Lc,circInOut:Xw,circOut:og,backIn:Dc,backInOut:Qw,backOut:ag,anticipate:Zw},Pf=e=>{if(Array.isArray(e)){_c(e.length===4);const[t,r,n,s]=e;return pi(t,r,n,s)}else if(typeof e=="string")return Jw[e];return e},Rc=(e,t)=>r=>!!(fi(r)&&tw.test(r)&&r.startsWith(e)||t&&Object.prototype.hasOwnProperty.call(r,t)),lg=(e,t,r)=>n=>{if(!fi(n))return n;const[s,i,o,a]=n.match(la);return{[e]:parseFloat(s),[t]:parseFloat(i),[r]:parseFloat(o),alpha:a!==void 0?parseFloat(a):1}},e5=e=>jr(0,255,e),Ba={...sn,transform:e=>Math.round(e5(e))},Hr={test:Rc("rgb","red"),parse:lg("red","green","blue"),transform:({red:e,green:t,blue:r,alpha:n=1})=>"rgba("+Ba.transform(e)+", "+Ba.transform(t)+", "+Ba.transform(r)+", "+Ps(Ns.transform(n))+")"};function t5(e){let t="",r="",n="",s="";return e.length>5?(t=e.substring(1,3),r=e.substring(3,5),n=e.substring(5,7),s=e.substring(7,9)):(t=e.substring(1,2),r=e.substring(2,3),n=e.substring(3,4),s=e.substring(4,5),t+=t,r+=r,n+=n,s+=s),{red:parseInt(t,16),green:parseInt(r,16),blue:parseInt(n,16),alpha:s?parseInt(s,16)/255:1}}const ou={test:Rc("#"),parse:t5,transform:Hr.transform},Sn={test:Rc("hsl","hue"),parse:lg("hue","saturation","lightness"),transform:({hue:e,saturation:t,lightness:r,alpha:n=1})=>"hsla("+Math.round(e)+", "+At.transform(Ps(t))+", "+At.transform(Ps(r))+", "+Ps(Ns.transform(n))+")"},ze={test:e=>Hr.test(e)||ou.test(e)||Sn.test(e),parse:e=>Hr.test(e)?Hr.parse(e):Sn.test(e)?Sn.parse(e):ou.parse(e),transform:e=>fi(e)?e:e.hasOwnProperty("red")?Hr.transform(e):Sn.transform(e)},fe=(e,t,r)=>-r*e+r*t+e;function Ua(e,t,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?e+(t-e)*6*r:r<1/2?t:r<2/3?e+(t-e)*(2/3-r)*6:e}function r5({hue:e,saturation:t,lightness:r,alpha:n}){e/=360,t/=100,r/=100;let s=0,i=0,o=0;if(!t)s=i=o=r;else{const a=r<.5?r*(1+t):r+t-r*t,l=2*r-a;s=Ua(l,a,e+1/3),i=Ua(l,a,e),o=Ua(l,a,e-1/3)}return{red:Math.round(s*255),green:Math.round(i*255),blue:Math.round(o*255),alpha:n}}const Wa=(e,t,r)=>{const n=e*e;return Math.sqrt(Math.max(0,r*(t*t-n)+n))},n5=[ou,Hr,Sn],s5=e=>n5.find(t=>t.test(e));function Ef(e){const t=s5(e);let r=t.parse(e);return t===Sn&&(r=r5(r)),r}const ug=(e,t)=>{const r=Ef(e),n=Ef(t),s={...r};return i=>(s.red=Wa(r.red,n.red,i),s.green=Wa(r.green,n.green,i),s.blue=Wa(r.blue,n.blue,i),s.alpha=fe(r.alpha,n.alpha,i),Hr.transform(s))};function i5(e){var t,r;return isNaN(e)&&fi(e)&&(((t=e.match(la))===null||t===void 0?void 0:t.length)||0)+(((r=e.match(R0))===null||r===void 0?void 0:r.length)||0)>0}const cg={regex:J2,countKey:"Vars",token:"${v}",parse:xe},dg={regex:R0,countKey:"Colors",token:"${c}",parse:ze.parse},fg={regex:la,countKey:"Numbers",token:"${n}",parse:sn.parse};function Ha(e,{regex:t,countKey:r,token:n,parse:s}){const i=e.tokenised.match(t);i&&(e["num"+r]=i.length,e.tokenised=e.tokenised.replace(t,n),e.values.push(...i.map(s)))}function Mo(e){const t=e.toString(),r={value:t,tokenised:t,values:[],numVars:0,numColors:0,numNumbers:0};return r.value.includes("var(--")&&Ha(r,cg),Ha(r,dg),Ha(r,fg),r}function hg(e){return Mo(e).values}function pg(e){const{values:t,numColors:r,numVars:n,tokenised:s}=Mo(e),i=t.length;return o=>{let a=s;for(let l=0;ltypeof e=="number"?0:e;function a5(e){const t=hg(e);return pg(e)(t.map(o5))}const Cr={test:i5,parse:hg,createTransformer:pg,getAnimatableNone:a5},mg=(e,t)=>r=>`${r>0?t:e}`;function gg(e,t){return typeof e=="number"?r=>fe(e,t,r):ze.test(e)?ug(e,t):e.startsWith("var(")?mg(e,t):vg(e,t)}const yg=(e,t)=>{const r=[...e],n=r.length,s=e.map((i,o)=>gg(i,t[o]));return i=>{for(let o=0;o{const r={...e,...t},n={};for(const s in r)e[s]!==void 0&&t[s]!==void 0&&(n[s]=gg(e[s],t[s]));return s=>{for(const i in n)r[i]=n[i](s);return r}},vg=(e,t)=>{const r=Cr.createTransformer(t),n=Mo(e),s=Mo(t);return n.numVars===s.numVars&&n.numColors===s.numColors&&n.numNumbers>=s.numNumbers?br(yg(n.values,s.values),r):mg(e,t)},ri=(e,t,r)=>{const n=t-e;return n===0?1:(r-e)/n},Tf=(e,t)=>r=>fe(e,t,r);function u5(e){return typeof e=="number"?Tf:typeof e=="string"?ze.test(e)?ug:vg:Array.isArray(e)?yg:typeof e=="object"?l5:Tf}function c5(e,t,r){const n=[],s=r||u5(e[0]),i=e.length-1;for(let o=0;ot[0];e[0]>e[i-1]&&(e=[...e].reverse(),t=[...t].reverse());const o=c5(t,n,s),a=o.length,l=c=>{let d=0;if(a>1)for(;dl(jr(e[0],e[i-1],c)):l}function d5(e,t){const r=e[e.length-1];for(let n=1;n<=t;n++){const s=ri(0,t,n);e.push(fe(r,1,s))}}function f5(e){const t=[0];return d5(t,e.length-1),t}function h5(e,t){return e.map(r=>r*t)}function p5(e,t){return e.map(()=>t||ng).splice(0,e.length-1)}function Ao({duration:e=300,keyframes:t,times:r,ease:n="easeInOut"}){const s=Kw(n)?n.map(Pf):Pf(n),i={done:!1,value:t[0]},o=h5(r&&r.length===t.length?r:f5(t),e),a=xg(o,t,{ease:Array.isArray(s)?s:p5(t,s)});return{calculatedDuration:e,next:l=>(i.value=a(l),i.done=l>=e,i)}}function wg(e,t){return t?e*(1e3/t):0}const m5=5;function bg(e,t,r){const n=Math.max(t-m5,0);return wg(r-e(n),t-n)}const qa=.001,g5=.01,y5=10,v5=.05,x5=1;function w5({duration:e=800,bounce:t=.25,velocity:r=0,mass:n=1}){let s,i,o=1-t;o=jr(v5,x5,o),e=jr(g5,y5,Ut(e)),o<1?(s=c=>{const d=c*o,f=d*e,u=d-r,p=au(c,o),m=Math.exp(-f);return qa-u/p*m},i=c=>{const f=c*o*e,u=f*r+r,p=Math.pow(o,2)*Math.pow(c,2)*e,m=Math.exp(-f),g=au(Math.pow(c,2),o);return(-s(c)+qa>0?-1:1)*((u-p)*m)/g}):(s=c=>{const d=Math.exp(-c*e),f=(c-r)*e+1;return-qa+d*f},i=c=>{const d=Math.exp(-c*e),f=(r-c)*(e*e);return d*f});const a=5/e,l=S5(s,i,a);if(e=Yr(e),isNaN(l))return{stiffness:100,damping:10,duration:e};{const c=Math.pow(l,2)*n;return{stiffness:c,damping:o*2*Math.sqrt(n*c),duration:e}}}const b5=12;function S5(e,t,r){let n=r;for(let s=1;se[r]!==void 0)}function C5(e){let t={velocity:0,stiffness:100,damping:10,mass:1,isResolvedFromDuration:!1,...e};if(!Mf(e,j5)&&Mf(e,k5)){const r=w5(e);t={...t,...r,mass:1},t.isResolvedFromDuration=!0}return t}function Sg({keyframes:e,restDelta:t,restSpeed:r,...n}){const s=e[0],i=e[e.length-1],o={done:!1,value:s},{stiffness:a,damping:l,mass:c,duration:d,velocity:f,isResolvedFromDuration:u}=C5({...n,velocity:-Ut(n.velocity||0)}),p=f||0,m=l/(2*Math.sqrt(a*c)),g=i-s,w=Ut(Math.sqrt(a/c)),v=Math.abs(g)<5;r||(r=v?.01:2),t||(t=v?.005:.5);let y;if(m<1){const x=au(w,m);y=b=>{const k=Math.exp(-m*w*b);return i-k*((p+m*w*g)/x*Math.sin(x*b)+g*Math.cos(x*b))}}else if(m===1)y=x=>i-Math.exp(-w*x)*(g+(p+w*g)*x);else{const x=w*Math.sqrt(m*m-1);y=b=>{const k=Math.exp(-m*w*b),C=Math.min(x*b,300);return i-k*((p+m*w*g)*Math.sinh(C)+x*g*Math.cosh(C))/x}}return{calculatedDuration:u&&d||null,next:x=>{const b=y(x);if(u)o.done=x>=d;else{let k=p;x!==0&&(m<1?k=bg(y,x,b):k=0);const C=Math.abs(k)<=r,N=Math.abs(i-b)<=t;o.done=C&&N}return o.value=o.done?i:b,o}}}function Af({keyframes:e,velocity:t=0,power:r=.8,timeConstant:n=325,bounceDamping:s=10,bounceStiffness:i=500,modifyTarget:o,min:a,max:l,restDelta:c=.5,restSpeed:d}){const f=e[0],u={done:!1,value:f},p=P=>a!==void 0&&Pl,m=P=>a===void 0?l:l===void 0||Math.abs(a-P)-g*Math.exp(-P/n),x=P=>v+y(P),b=P=>{const V=y(P),T=x(P);u.done=Math.abs(V)<=c,u.value=u.done?v:T};let k,C;const N=P=>{p(u.value)&&(k=P,C=Sg({keyframes:[u.value,m(u.value)],velocity:bg(x,P,u.value),damping:s,stiffness:i,restDelta:c,restSpeed:d}))};return N(0),{calculatedDuration:null,next:P=>{let V=!1;return!C&&k===void 0&&(V=!0,b(P),N(P)),k!==void 0&&P>k?C.next(P-k):(!V&&b(P),u)}}}const N5=e=>{const t=({timestamp:r})=>e(r);return{start:()=>ne.update(t,!0),stop:()=>Kt(t),now:()=>De.isProcessing?De.timestamp:performance.now()}},_f=2e4;function Lf(e){let t=0;const r=50;let n=e.next(t);for(;!n.done&&t<_f;)t+=r,n=e.next(t);return t>=_f?1/0:t}const P5={decay:Af,inertia:Af,tween:Ao,keyframes:Ao,spring:Sg};function _o({autoplay:e=!0,delay:t=0,driver:r=N5,keyframes:n,type:s="keyframes",repeat:i=0,repeatDelay:o=0,repeatType:a="loop",onPlay:l,onStop:c,onComplete:d,onUpdate:f,...u}){let p=1,m=!1,g,w;const v=()=>{w=new Promise(R=>{g=R})};v();let y;const x=P5[s]||Ao;let b;x!==Ao&&typeof n[0]!="number"&&(b=xg([0,100],n,{clamp:!1}),n=[0,100]);const k=x({...u,keyframes:n});let C;a==="mirror"&&(C=x({...u,keyframes:[...n].reverse(),velocity:-(u.velocity||0)}));let N="idle",P=null,V=null,T=null;k.calculatedDuration===null&&i&&(k.calculatedDuration=Lf(k));const{calculatedDuration:O}=k;let j=1/0,F=1/0;O!==null&&(j=O+o,F=j*(i+1)-o);let D=0;const G=R=>{if(V===null)return;p>0&&(V=Math.min(V,R)),p<0&&(V=Math.min(R-F/p,V)),P!==null?D=P:D=Math.round(R-V)*p;const E=D-t*(p>=0?1:-1),H=p>=0?E<0:E>F;D=Math.max(E,0),N==="finished"&&P===null&&(D=F);let X=D,ee=k;if(i){const _t=Math.min(D,F)/j;let St=Math.floor(_t),Qe=_t%1;!Qe&&_t>=1&&(Qe=1),Qe===1&&St--,St=Math.min(St,i+1),!!(St%2)&&(a==="reverse"?(Qe=1-Qe,o&&(Qe-=o/j)):a==="mirror"&&(ee=C)),X=jr(0,1,Qe)*j}const q=H?{done:!1,value:n[0]}:ee.next(X);b&&(q.value=b(q.value));let{done:me}=q;!H&&O!==null&&(me=p>=0?D>=F:D<=0);const Rr=P===null&&(N==="finished"||N==="running"&&me);return f&&f(q.value),Rr&&_(),q},M=()=>{y&&y.stop(),y=void 0},W=()=>{N="idle",M(),g(),v(),V=T=null},_=()=>{N="finished",d&&d(),M(),g()},A=()=>{if(m)return;y||(y=r(G));const R=y.now();l&&l(),P!==null?V=R-P:(!V||N==="finished")&&(V=R),N==="finished"&&v(),T=V,P=null,N="running",y.start()};e&&A();const I={then(R,E){return w.then(R,E)},get time(){return Ut(D)},set time(R){R=Yr(R),D=R,P!==null||!y||p===0?P=R:V=y.now()-R/p},get duration(){const R=k.calculatedDuration===null?Lf(k):k.calculatedDuration;return Ut(R)},get speed(){return p},set speed(R){R===p||!y||(p=R,I.time=Ut(D))},get state(){return N},play:A,pause:()=>{N="paused",P=D},stop:()=>{m=!0,N!=="idle"&&(N="idle",c&&c(),W())},cancel:()=>{T!==null&&G(T),W()},complete:()=>{N="finished"},sample:R=>(V=0,G(R))};return I}function E5(e){let t;return()=>(t===void 0&&(t=e()),t)}const T5=E5(()=>Object.hasOwnProperty.call(Element.prototype,"animate")),M5=new Set(["opacity","clipPath","filter","transform","backgroundColor"]),Ri=10,A5=2e4,_5=(e,t)=>t.type==="spring"||e==="backgroundColor"||!J0(t.ease);function L5(e,t,{onUpdate:r,onComplete:n,...s}){if(!(T5()&&M5.has(t)&&!s.repeatDelay&&s.repeatType!=="mirror"&&s.damping!==0&&s.type!=="inertia"))return!1;let o=!1,a,l,c=!1;const d=()=>{l=new Promise(x=>{a=x})};d();let{keyframes:f,duration:u=300,ease:p,times:m}=s;if(_5(t,s)){const x=_o({...s,repeat:0,delay:0});let b={done:!1,value:f[0]};const k=[];let C=0;for(;!b.done&&C{c=!1,g.cancel()},v=()=>{c=!0,ne.update(w),a(),d()};return g.onfinish=()=>{c||(e.set(Uw(f,s)),n&&n(),v())},{then(x,b){return l.then(x,b)},attachTimeline(x){return g.timeline=x,g.onfinish=null,xe},get time(){return Ut(g.currentTime||0)},set time(x){g.currentTime=Yr(x)},get speed(){return g.playbackRate},set speed(x){g.playbackRate=x},get duration(){return Ut(u)},play:()=>{o||(g.play(),Kt(w))},pause:()=>g.pause(),stop:()=>{if(o=!0,g.playState==="idle")return;const{currentTime:x}=g;if(x){const b=_o({...s,autoplay:!1});e.setWithVelocity(b.sample(x-Ri).value,b.sample(x).value,Ri)}v()},complete:()=>{c||g.finish()},cancel:v}}function D5({keyframes:e,delay:t,onUpdate:r,onComplete:n}){const s=()=>(r&&r(e[e.length-1]),n&&n(),{time:0,speed:1,duration:0,play:xe,pause:xe,stop:xe,then:i=>(i(),Promise.resolve()),cancel:xe,complete:xe});return t?_o({keyframes:[0,1],duration:0,delay:t,onComplete:s}):s()}const R5={type:"spring",stiffness:500,damping:25,restSpeed:10},V5=e=>({type:"spring",stiffness:550,damping:e===0?2*Math.sqrt(550):30,restSpeed:10}),F5={type:"keyframes",duration:.8},I5={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},z5=(e,{keyframes:t})=>t.length>2?F5:nn.has(e)?e.startsWith("scale")?V5(t[1]):R5:I5,lu=(e,t)=>e==="zIndex"?!1:!!(typeof t=="number"||Array.isArray(t)||typeof t=="string"&&(Cr.test(t)||t==="0")&&!t.startsWith("url(")),O5=new Set(["brightness","contrast","saturate","opacity"]);function $5(e){const[t,r]=e.slice(0,-1).split("(");if(t==="drop-shadow")return e;const[n]=r.match(la)||[];if(!n)return e;const s=r.replace(n,"");let i=O5.has(t)?1:0;return n!==r&&(i*=100),t+"("+i+s+")"}const B5=/([a-z-]*)\(.*?\)/g,uu={...Cr,getAnimatableNone:e=>{const t=e.match(B5);return t?t.map($5).join(" "):e}},U5={...V0,color:ze,backgroundColor:ze,outlineColor:ze,fill:ze,stroke:ze,borderColor:ze,borderTopColor:ze,borderRightColor:ze,borderBottomColor:ze,borderLeftColor:ze,filter:uu,WebkitFilter:uu},Vc=e=>U5[e];function kg(e,t){let r=Vc(e);return r!==uu&&(r=Cr),r.getAnimatableNone?r.getAnimatableNone(t):void 0}const jg=e=>/^0[^.\s]+$/.test(e);function W5(e){if(typeof e=="number")return e===0;if(e!==null)return e==="none"||e==="0"||jg(e)}function H5(e,t,r,n){const s=lu(t,r);let i;Array.isArray(r)?i=[...r]:i=[null,r];const o=n.from!==void 0?n.from:e.get();let a;const l=[];for(let c=0;cs=>{const i=Fc(n,e)||{},o=i.delay||n.delay||0;let{elapsed:a=0}=n;a=a-Yr(o);const l=H5(t,e,r,i),c=l[0],d=l[l.length-1],f=lu(e,c),u=lu(e,d);let p={keyframes:l,velocity:t.getVelocity(),ease:"easeOut",...i,delay:-a,onUpdate:m=>{t.set(m),i.onUpdate&&i.onUpdate(m)},onComplete:()=>{s(),i.onComplete&&i.onComplete()}};if(q5(i)||(p={...p,...z5(e,p)}),p.duration&&(p.duration=Yr(p.duration)),p.repeatDelay&&(p.repeatDelay=Yr(p.repeatDelay)),!f||!u||$w.current||i.type===!1||G5.skipAnimations)return D5(p);if(!n.isHandoff&&t.owner&&t.owner.current instanceof HTMLElement&&!t.owner.getProps().onUpdate){const m=L5(t,e,p);if(m)return m}return _o(p)};function Lo(e){return!!(Xe(e)&&e.add)}const Cg=e=>/^\-?\d*\.?\d+$/.test(e);function zc(e,t){e.indexOf(t)===-1&&e.push(t)}function Oc(e,t){const r=e.indexOf(t);r>-1&&e.splice(r,1)}class $c{constructor(){this.subscriptions=[]}add(t){return zc(this.subscriptions,t),()=>Oc(this.subscriptions,t)}notify(t,r,n){const s=this.subscriptions.length;if(s)if(s===1)this.subscriptions[0](t,r,n);else for(let i=0;i!isNaN(parseFloat(e));class K5{constructor(t,r={}){this.version="10.18.0",this.timeDelta=0,this.lastUpdated=0,this.canTrackVelocity=!1,this.events={},this.updateAndNotify=(n,s=!0)=>{this.prev=this.current,this.current=n;const{delta:i,timestamp:o}=De;this.lastUpdated!==o&&(this.timeDelta=i,this.lastUpdated=o,ne.postRender(this.scheduleVelocityCheck)),this.prev!==this.current&&this.events.change&&this.events.change.notify(this.current),this.events.velocityChange&&this.events.velocityChange.notify(this.getVelocity()),s&&this.events.renderRequest&&this.events.renderRequest.notify(this.current)},this.scheduleVelocityCheck=()=>ne.postRender(this.velocityCheck),this.velocityCheck=({timestamp:n})=>{n!==this.lastUpdated&&(this.prev=this.current,this.events.velocityChange&&this.events.velocityChange.notify(this.getVelocity()))},this.hasAnimated=!1,this.prev=this.current=t,this.canTrackVelocity=Y5(this.current),this.owner=r.owner}onChange(t){return this.on("change",t)}on(t,r){this.events[t]||(this.events[t]=new $c);const n=this.events[t].add(r);return t==="change"?()=>{n(),ne.read(()=>{this.events.change.getSize()||this.stop()})}:n}clearListeners(){for(const t in this.events)this.events[t].clear()}attach(t,r){this.passiveEffect=t,this.stopPassiveEffect=r}set(t,r=!0){!r||!this.passiveEffect?this.updateAndNotify(t,r):this.passiveEffect(t,this.updateAndNotify)}setWithVelocity(t,r,n){this.set(r),this.prev=t,this.timeDelta=n}jump(t){this.updateAndNotify(t),this.prev=t,this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}get(){return this.current}getPrevious(){return this.prev}getVelocity(){return this.canTrackVelocity?wg(parseFloat(this.current)-parseFloat(this.prev),this.timeDelta):0}start(t){return this.stop(),new Promise(r=>{this.hasAnimated=!0,this.animation=t(r),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function On(e,t){return new K5(e,t)}const Ng=e=>t=>t.test(e),X5={test:e=>e==="auto",parse:e=>e},Pg=[sn,U,At,rr,nw,rw,X5],ls=e=>Pg.find(Ng(e)),Q5=[...Pg,ze,Cr],Z5=e=>Q5.find(Ng(e));function J5(e,t,r){e.hasValue(t)?e.getValue(t).set(r):e.addValue(t,On(r))}function eb(e,t){const r=ca(e,t);let{transitionEnd:n={},transition:s={},...i}=r?e.makeTargetAnimatable(r,!1):{};i={...i,...n};for(const o in i){const a=yw(i[o]);J5(e,o,a)}}function tb(e,t,r){var n,s;const i=Object.keys(t).filter(a=>!e.hasValue(a)),o=i.length;if(o)for(let a=0;al.remove(f))),c.push(w)}return o&&Promise.all(c).then(()=>{o&&eb(e,o)}),c}function cu(e,t,r={}){const n=ca(e,t,r.custom);let{transition:s=e.getDefaultTransition()||{}}=n||{};r.transitionOverride&&(s=r.transitionOverride);const i=n?()=>Promise.all(Eg(e,n,r)):()=>Promise.resolve(),o=e.variantChildren&&e.variantChildren.size?(l=0)=>{const{delayChildren:c=0,staggerChildren:d,staggerDirection:f}=s;return ob(e,t,c+l,d,f,r)}:()=>Promise.resolve(),{when:a}=s;if(a){const[l,c]=a==="beforeChildren"?[i,o]:[o,i];return l().then(()=>c())}else return Promise.all([i(),o(r.delay)])}function ob(e,t,r=0,n=0,s=1,i){const o=[],a=(e.variantChildren.size-1)*n,l=s===1?(c=0)=>c*n:(c=0)=>a-c*n;return Array.from(e.variantChildren).sort(ab).forEach((c,d)=>{c.notify("AnimationStart",t),o.push(cu(c,t,{...i,delay:r+l(d)}).then(()=>c.notify("AnimationComplete",t)))}),Promise.all(o)}function ab(e,t){return e.sortNodePosition(t)}function lb(e,t,r={}){e.notify("AnimationStart",t);let n;if(Array.isArray(t)){const s=t.map(i=>cu(e,i,r));n=Promise.all(s)}else if(typeof t=="string")n=cu(e,t,r);else{const s=typeof t=="function"?ca(e,t,r.custom):t;n=Promise.all(Eg(e,s,r))}return n.then(()=>e.notify("AnimationComplete",t))}const ub=[...Sc].reverse(),cb=Sc.length;function db(e){return t=>Promise.all(t.map(({animation:r,options:n})=>lb(e,r,n)))}function fb(e){let t=db(e);const r=pb();let n=!0;const s=(l,c)=>{const d=ca(e,c);if(d){const{transition:f,transitionEnd:u,...p}=d;l={...l,...p,...u}}return l};function i(l){t=l(e)}function o(l,c){const d=e.getProps(),f=e.getVariantContext(!0)||{},u=[],p=new Set;let m={},g=1/0;for(let v=0;vg&&k,T=!1;const O=Array.isArray(b)?b:[b];let j=O.reduce(s,{});C===!1&&(j={});const{prevResolvedValues:F={}}=x,D={...F,...j},G=M=>{V=!0,p.has(M)&&(T=!0,p.delete(M)),x.needsAnimating[M]=!0};for(const M in D){const W=j[M],_=F[M];if(m.hasOwnProperty(M))continue;let A=!1;To(W)&&To(_)?A=!Q0(W,_):A=W!==_,A?W!==void 0?G(M):p.add(M):W!==void 0&&p.has(M)?G(M):x.protectedKeys[M]=!0}x.prevProp=b,x.prevResolvedValues=j,x.isActive&&(m={...m,...j}),n&&e.blockInitialAnimation&&(V=!1),V&&(!N||T)&&u.push(...O.map(M=>({animation:M,options:{type:y,...l}})))}if(p.size){const v={};p.forEach(y=>{const x=e.getBaseTarget(y);x!==void 0&&(v[y]=x)}),u.push({animation:v})}let w=!!u.length;return n&&(d.initial===!1||d.initial===d.animate)&&!e.manuallyAnimateOnMount&&(w=!1),n=!1,w?t(u):Promise.resolve()}function a(l,c,d){var f;if(r[l].isActive===c)return Promise.resolve();(f=e.variantChildren)===null||f===void 0||f.forEach(p=>{var m;return(m=p.animationState)===null||m===void 0?void 0:m.setActive(l,c)}),r[l].isActive=c;const u=o(d,l);for(const p in r)r[p].protectedKeys={};return u}return{animateChanges:o,setActive:a,setAnimateFunction:i,getState:()=>r}}function hb(e,t){return typeof t=="string"?t!==e:Array.isArray(t)?!Q0(t,e):!1}function Vr(e=!1){return{isActive:e,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function pb(){return{animate:Vr(!0),whileInView:Vr(),whileHover:Vr(),whileTap:Vr(),whileDrag:Vr(),whileFocus:Vr(),exit:Vr()}}class mb extends Dr{constructor(t){super(t),t.animationState||(t.animationState=fb(t))}updateAnimationControlsSubscription(){const{animate:t}=this.node.getProps();this.unmount(),oa(t)&&(this.unmount=t.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:t}=this.node.getProps(),{animate:r}=this.node.prevProps||{};t!==r&&this.updateAnimationControlsSubscription()}unmount(){}}let gb=0;class yb extends Dr{constructor(){super(...arguments),this.id=gb++}update(){if(!this.node.presenceContext)return;const{isPresent:t,onExitComplete:r,custom:n}=this.node.presenceContext,{isPresent:s}=this.node.prevPresenceContext||{};if(!this.node.animationState||t===s)return;const i=this.node.animationState.setActive("exit",!t,{custom:n??this.node.getProps().custom});r&&!t&&i.then(()=>r(this.id))}mount(){const{register:t}=this.node.presenceContext||{};t&&(this.unmount=t(this.id))}unmount(){}}const vb={animation:{Feature:mb},exit:{Feature:yb}},Df=(e,t)=>Math.abs(e-t);function xb(e,t){const r=Df(e.x,t.x),n=Df(e.y,t.y);return Math.sqrt(r**2+n**2)}class Tg{constructor(t,r,{transformPagePoint:n,contextWindow:s,dragSnapToOrigin:i=!1}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const f=Ya(this.lastMoveEventInfo,this.history),u=this.startEvent!==null,p=xb(f.offset,{x:0,y:0})>=3;if(!u&&!p)return;const{point:m}=f,{timestamp:g}=De;this.history.push({...m,timestamp:g});const{onStart:w,onMove:v}=this.handlers;u||(w&&w(this.lastMoveEvent,f),this.startEvent=this.lastMoveEvent),v&&v(this.lastMoveEvent,f)},this.handlePointerMove=(f,u)=>{this.lastMoveEvent=f,this.lastMoveEventInfo=Ga(u,this.transformPagePoint),ne.update(this.updatePoint,!0)},this.handlePointerUp=(f,u)=>{this.end();const{onEnd:p,onSessionEnd:m,resumeAnimation:g}=this.handlers;if(this.dragSnapToOrigin&&g&&g(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const w=Ya(f.type==="pointercancel"?this.lastMoveEventInfo:Ga(u,this.transformPagePoint),this.history);this.startEvent&&p&&p(f,w),m&&m(f,w)},!q0(t))return;this.dragSnapToOrigin=i,this.handlers=r,this.transformPagePoint=n,this.contextWindow=s||window;const o=ua(t),a=Ga(o,this.transformPagePoint),{point:l}=a,{timestamp:c}=De;this.history=[{...l,timestamp:c}];const{onSessionStart:d}=r;d&&d(t,Ya(a,this.history)),this.removeListeners=br(Bt(this.contextWindow,"pointermove",this.handlePointerMove),Bt(this.contextWindow,"pointerup",this.handlePointerUp),Bt(this.contextWindow,"pointercancel",this.handlePointerUp))}updateHandlers(t){this.handlers=t}end(){this.removeListeners&&this.removeListeners(),Kt(this.updatePoint)}}function Ga(e,t){return t?{point:t(e.point)}:e}function Rf(e,t){return{x:e.x-t.x,y:e.y-t.y}}function Ya({point:e},t){return{point:e,delta:Rf(e,Mg(t)),offset:Rf(e,wb(t)),velocity:bb(t,.1)}}function wb(e){return e[0]}function Mg(e){return e[e.length-1]}function bb(e,t){if(e.length<2)return{x:0,y:0};let r=e.length-1,n=null;const s=Mg(e);for(;r>=0&&(n=e[r],!(s.timestamp-n.timestamp>Yr(t)));)r--;if(!n)return{x:0,y:0};const i=Ut(s.timestamp-n.timestamp);if(i===0)return{x:0,y:0};const o={x:(s.x-n.x)/i,y:(s.y-n.y)/i};return o.x===1/0&&(o.x=0),o.y===1/0&&(o.y=0),o}function nt(e){return e.max-e.min}function du(e,t=0,r=.01){return Math.abs(e-t)<=r}function Vf(e,t,r,n=.5){e.origin=n,e.originPoint=fe(t.min,t.max,e.origin),e.scale=nt(r)/nt(t),(du(e.scale,1,1e-4)||isNaN(e.scale))&&(e.scale=1),e.translate=fe(r.min,r.max,e.origin)-e.originPoint,(du(e.translate)||isNaN(e.translate))&&(e.translate=0)}function Es(e,t,r,n){Vf(e.x,t.x,r.x,n?n.originX:void 0),Vf(e.y,t.y,r.y,n?n.originY:void 0)}function Ff(e,t,r){e.min=r.min+t.min,e.max=e.min+nt(t)}function Sb(e,t,r){Ff(e.x,t.x,r.x),Ff(e.y,t.y,r.y)}function If(e,t,r){e.min=t.min-r.min,e.max=e.min+nt(t)}function Ts(e,t,r){If(e.x,t.x,r.x),If(e.y,t.y,r.y)}function kb(e,{min:t,max:r},n){return t!==void 0&&er&&(e=n?fe(r,e,n.max):Math.min(e,r)),e}function zf(e,t,r){return{min:t!==void 0?e.min+t:void 0,max:r!==void 0?e.max+r-(e.max-e.min):void 0}}function jb(e,{top:t,left:r,bottom:n,right:s}){return{x:zf(e.x,r,s),y:zf(e.y,t,n)}}function Of(e,t){let r=t.min-e.min,n=t.max-e.max;return t.max-t.minn?r=ri(t.min,t.max-n,e.min):n>s&&(r=ri(e.min,e.max-s,t.min)),jr(0,1,r)}function Pb(e,t){const r={};return t.min!==void 0&&(r.min=t.min-e.min),t.max!==void 0&&(r.max=t.max-e.min),r}const fu=.35;function Eb(e=fu){return e===!1?e=0:e===!0&&(e=fu),{x:$f(e,"left","right"),y:$f(e,"top","bottom")}}function $f(e,t,r){return{min:Bf(e,t),max:Bf(e,r)}}function Bf(e,t){return typeof e=="number"?e:e[t]||0}const Uf=()=>({translate:0,scale:1,origin:0,originPoint:0}),kn=()=>({x:Uf(),y:Uf()}),Wf=()=>({min:0,max:0}),Se=()=>({x:Wf(),y:Wf()});function at(e){return[e("x"),e("y")]}function Ag({top:e,left:t,right:r,bottom:n}){return{x:{min:t,max:r},y:{min:e,max:n}}}function Tb({x:e,y:t}){return{top:t.min,right:e.max,bottom:t.max,left:e.min}}function Mb(e,t){if(!t)return e;const r=t({x:e.left,y:e.top}),n=t({x:e.right,y:e.bottom});return{top:r.y,left:r.x,bottom:n.y,right:n.x}}function Ka(e){return e===void 0||e===1}function hu({scale:e,scaleX:t,scaleY:r}){return!Ka(e)||!Ka(t)||!Ka(r)}function zr(e){return hu(e)||_g(e)||e.z||e.rotate||e.rotateX||e.rotateY}function _g(e){return Hf(e.x)||Hf(e.y)}function Hf(e){return e&&e!=="0%"}function Do(e,t,r){const n=e-r,s=t*n;return r+s}function qf(e,t,r,n,s){return s!==void 0&&(e=Do(e,s,n)),Do(e,r,n)+t}function pu(e,t=0,r=1,n,s){e.min=qf(e.min,t,r,n,s),e.max=qf(e.max,t,r,n,s)}function Lg(e,{x:t,y:r}){pu(e.x,t.translate,t.scale,t.originPoint),pu(e.y,r.translate,r.scale,r.originPoint)}function Ab(e,t,r,n=!1){const s=r.length;if(!s)return;t.x=t.y=1;let i,o;for(let a=0;a1.0000000000001||e<.999999999999?e:1}function ir(e,t){e.min=e.min+t,e.max=e.max+t}function Yf(e,t,[r,n,s]){const i=t[s]!==void 0?t[s]:.5,o=fe(e.min,e.max,i);pu(e,t[r],t[n],o,t.scale)}const _b=["x","scaleX","originX"],Lb=["y","scaleY","originY"];function jn(e,t){Yf(e.x,t,_b),Yf(e.y,t,Lb)}function Dg(e,t){return Ag(Mb(e.getBoundingClientRect(),t))}function Db(e,t,r){const n=Dg(e,r),{scroll:s}=t;return s&&(ir(n.x,s.offset.x),ir(n.y,s.offset.y)),n}const Rg=({current:e})=>e?e.ownerDocument.defaultView:null,Rb=new WeakMap;class Vb{constructor(t){this.openGlobalLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=Se(),this.visualElement=t}start(t,{snapToCursor:r=!1}={}){const{presenceContext:n}=this.visualElement;if(n&&n.isPresent===!1)return;const s=d=>{const{dragSnapToOrigin:f}=this.getProps();f?this.pauseAnimation():this.stopAnimation(),r&&this.snapToCursor(ua(d,"page").point)},i=(d,f)=>{const{drag:u,dragPropagation:p,onDragStart:m}=this.getProps();if(u&&!p&&(this.openGlobalLock&&this.openGlobalLock(),this.openGlobalLock=Y0(u),!this.openGlobalLock))return;this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),at(w=>{let v=this.getAxisMotionValue(w).get()||0;if(At.test(v)){const{projection:y}=this.visualElement;if(y&&y.layout){const x=y.layout.layoutBox[w];x&&(v=nt(x)*(parseFloat(v)/100))}}this.originPoint[w]=v}),m&&ne.update(()=>m(d,f),!1,!0);const{animationState:g}=this.visualElement;g&&g.setActive("whileDrag",!0)},o=(d,f)=>{const{dragPropagation:u,dragDirectionLock:p,onDirectionLock:m,onDrag:g}=this.getProps();if(!u&&!this.openGlobalLock)return;const{offset:w}=f;if(p&&this.currentDirection===null){this.currentDirection=Fb(w),this.currentDirection!==null&&m&&m(this.currentDirection);return}this.updateAxis("x",f.point,w),this.updateAxis("y",f.point,w),this.visualElement.render(),g&&g(d,f)},a=(d,f)=>this.stop(d,f),l=()=>at(d=>{var f;return this.getAnimationState(d)==="paused"&&((f=this.getAxisMotionValue(d).animation)===null||f===void 0?void 0:f.play())}),{dragSnapToOrigin:c}=this.getProps();this.panSession=new Tg(t,{onSessionStart:s,onStart:i,onMove:o,onSessionEnd:a,resumeAnimation:l},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:c,contextWindow:Rg(this.visualElement)})}stop(t,r){const n=this.isDragging;if(this.cancel(),!n)return;const{velocity:s}=r;this.startAnimation(s);const{onDragEnd:i}=this.getProps();i&&ne.update(()=>i(t,r))}cancel(){this.isDragging=!1;const{projection:t,animationState:r}=this.visualElement;t&&(t.isAnimationBlocked=!1),this.panSession&&this.panSession.end(),this.panSession=void 0;const{dragPropagation:n}=this.getProps();!n&&this.openGlobalLock&&(this.openGlobalLock(),this.openGlobalLock=null),r&&r.setActive("whileDrag",!1)}updateAxis(t,r,n){const{drag:s}=this.getProps();if(!n||!Vi(t,s,this.currentDirection))return;const i=this.getAxisMotionValue(t);let o=this.originPoint[t]+n[t];this.constraints&&this.constraints[t]&&(o=kb(o,this.constraints[t],this.elastic[t])),i.set(o)}resolveConstraints(){var t;const{dragConstraints:r,dragElastic:n}=this.getProps(),s=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):(t=this.visualElement.projection)===null||t===void 0?void 0:t.layout,i=this.constraints;r&&bn(r)?this.constraints||(this.constraints=this.resolveRefConstraints()):r&&s?this.constraints=jb(s.layoutBox,r):this.constraints=!1,this.elastic=Eb(n),i!==this.constraints&&s&&this.constraints&&!this.hasMutatedConstraints&&at(o=>{this.getAxisMotionValue(o)&&(this.constraints[o]=Pb(s.layoutBox[o],this.constraints[o]))})}resolveRefConstraints(){const{dragConstraints:t,onMeasureDragConstraints:r}=this.getProps();if(!t||!bn(t))return!1;const n=t.current,{projection:s}=this.visualElement;if(!s||!s.layout)return!1;const i=Db(n,s.root,this.visualElement.getTransformPagePoint());let o=Cb(s.layout.layoutBox,i);if(r){const a=r(Tb(o));this.hasMutatedConstraints=!!a,a&&(o=Ag(a))}return o}startAnimation(t){const{drag:r,dragMomentum:n,dragElastic:s,dragTransition:i,dragSnapToOrigin:o,onDragTransitionEnd:a}=this.getProps(),l=this.constraints||{},c=at(d=>{if(!Vi(d,r,this.currentDirection))return;let f=l&&l[d]||{};o&&(f={min:0,max:0});const u=s?200:1e6,p=s?40:1e7,m={type:"inertia",velocity:n?t[d]:0,bounceStiffness:u,bounceDamping:p,timeConstant:750,restDelta:1,restSpeed:10,...i,...f};return this.startAxisValueAnimation(d,m)});return Promise.all(c).then(a)}startAxisValueAnimation(t,r){const n=this.getAxisMotionValue(t);return n.start(Ic(t,n,0,r))}stopAnimation(){at(t=>this.getAxisMotionValue(t).stop())}pauseAnimation(){at(t=>{var r;return(r=this.getAxisMotionValue(t).animation)===null||r===void 0?void 0:r.pause()})}getAnimationState(t){var r;return(r=this.getAxisMotionValue(t).animation)===null||r===void 0?void 0:r.state}getAxisMotionValue(t){const r="_drag"+t.toUpperCase(),n=this.visualElement.getProps(),s=n[r];return s||this.visualElement.getValue(t,(n.initial?n.initial[t]:void 0)||0)}snapToCursor(t){at(r=>{const{drag:n}=this.getProps();if(!Vi(r,n,this.currentDirection))return;const{projection:s}=this.visualElement,i=this.getAxisMotionValue(r);if(s&&s.layout){const{min:o,max:a}=s.layout.layoutBox[r];i.set(t[r]-fe(o,a,.5))}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:t,dragConstraints:r}=this.getProps(),{projection:n}=this.visualElement;if(!bn(r)||!n||!this.constraints)return;this.stopAnimation();const s={x:0,y:0};at(o=>{const a=this.getAxisMotionValue(o);if(a){const l=a.get();s[o]=Nb({min:l,max:l},this.constraints[o])}});const{transformTemplate:i}=this.visualElement.getProps();this.visualElement.current.style.transform=i?i({},""):"none",n.root&&n.root.updateScroll(),n.updateLayout(),this.resolveConstraints(),at(o=>{if(!Vi(o,t,null))return;const a=this.getAxisMotionValue(o),{min:l,max:c}=this.constraints[o];a.set(fe(l,c,s[o]))})}addListeners(){if(!this.visualElement.current)return;Rb.set(this.visualElement,this);const t=this.visualElement.current,r=Bt(t,"pointerdown",l=>{const{drag:c,dragListener:d=!0}=this.getProps();c&&d&&this.start(l)}),n=()=>{const{dragConstraints:l}=this.getProps();bn(l)&&(this.constraints=this.resolveRefConstraints())},{projection:s}=this.visualElement,i=s.addEventListener("measure",n);s&&!s.layout&&(s.root&&s.root.updateScroll(),s.updateLayout()),n();const o=Ot(window,"resize",()=>this.scalePositionWithinConstraints()),a=s.addEventListener("didUpdate",({delta:l,hasLayoutChanged:c})=>{this.isDragging&&c&&(at(d=>{const f=this.getAxisMotionValue(d);f&&(this.originPoint[d]+=l[d].translate,f.set(f.get()+l[d].translate))}),this.visualElement.render())});return()=>{o(),r(),i(),a&&a()}}getProps(){const t=this.visualElement.getProps(),{drag:r=!1,dragDirectionLock:n=!1,dragPropagation:s=!1,dragConstraints:i=!1,dragElastic:o=fu,dragMomentum:a=!0}=t;return{...t,drag:r,dragDirectionLock:n,dragPropagation:s,dragConstraints:i,dragElastic:o,dragMomentum:a}}}function Vi(e,t,r){return(t===!0||t===e)&&(r===null||r===e)}function Fb(e,t=10){let r=null;return Math.abs(e.y)>t?r="y":Math.abs(e.x)>t&&(r="x"),r}class Ib extends Dr{constructor(t){super(t),this.removeGroupControls=xe,this.removeListeners=xe,this.controls=new Vb(t)}mount(){const{dragControls:t}=this.node.getProps();t&&(this.removeGroupControls=t.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||xe}unmount(){this.removeGroupControls(),this.removeListeners()}}const Kf=e=>(t,r)=>{e&&ne.update(()=>e(t,r))};class zb extends Dr{constructor(){super(...arguments),this.removePointerDownListener=xe}onPointerDown(t){this.session=new Tg(t,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:Rg(this.node)})}createPanHandlers(){const{onPanSessionStart:t,onPanStart:r,onPan:n,onPanEnd:s}=this.node.getProps();return{onSessionStart:Kf(t),onStart:Kf(r),onMove:n,onEnd:(i,o)=>{delete this.session,s&&ne.update(()=>s(i,o))}}}mount(){this.removePointerDownListener=Bt(this.node.current,"pointerdown",t=>this.onPointerDown(t))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}function Ob(){const e=S.useContext(sa);if(e===null)return[!0,null];const{isPresent:t,onExitComplete:r,register:n}=e,s=S.useId();return S.useEffect(()=>n(s),[]),!t&&r?[!1,()=>r&&r(s)]:[!0]}const Ji={hasAnimatedSinceResize:!0,hasEverUpdated:!1};function Xf(e,t){return t.max===t.min?0:e/(t.max-t.min)*100}const us={correct:(e,t)=>{if(!t.target)return e;if(typeof e=="string")if(U.test(e))e=parseFloat(e);else return e;const r=Xf(e,t.target.x),n=Xf(e,t.target.y);return`${r}% ${n}%`}},$b={correct:(e,{treeScale:t,projectionDelta:r})=>{const n=e,s=Cr.parse(e);if(s.length>5)return n;const i=Cr.createTransformer(e),o=typeof s[0]!="number"?1:0,a=r.x.scale*t.x,l=r.y.scale*t.y;s[0+o]/=a,s[1+o]/=l;const c=fe(a,l,.5);return typeof s[2+o]=="number"&&(s[2+o]/=c),typeof s[3+o]=="number"&&(s[3+o]/=c),i(s)}};class Bb extends ii.Component{componentDidMount(){const{visualElement:t,layoutGroup:r,switchLayoutGroup:n,layoutId:s}=this.props,{projection:i}=t;K2(Ub),i&&(r.group&&r.group.add(i),n&&n.register&&s&&n.register(i),i.root.didUpdate(),i.addEventListener("animationComplete",()=>{this.safeToRemove()}),i.setOptions({...i.options,onExitComplete:()=>this.safeToRemove()})),Ji.hasEverUpdated=!0}getSnapshotBeforeUpdate(t){const{layoutDependency:r,visualElement:n,drag:s,isPresent:i}=this.props,o=n.projection;return o&&(o.isPresent=i,s||t.layoutDependency!==r||r===void 0?o.willUpdate():this.safeToRemove(),t.isPresent!==i&&(i?o.promote():o.relegate()||ne.postRender(()=>{const a=o.getStack();(!a||!a.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{projection:t}=this.props.visualElement;t&&(t.root.didUpdate(),queueMicrotask(()=>{!t.currentAnimation&&t.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:t,layoutGroup:r,switchLayoutGroup:n}=this.props,{projection:s}=t;s&&(s.scheduleCheckAfterUnmount(),r&&r.group&&r.group.remove(s),n&&n.deregister&&n.deregister(s))}safeToRemove(){const{safeToRemove:t}=this.props;t&&t()}render(){return null}}function Vg(e){const[t,r]=Ob(),n=S.useContext(jc);return ii.createElement(Bb,{...e,layoutGroup:n,switchLayoutGroup:S.useContext(A0),isPresent:t,safeToRemove:r})}const Ub={borderRadius:{...us,applyTo:["borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"]},borderTopLeftRadius:us,borderTopRightRadius:us,borderBottomLeftRadius:us,borderBottomRightRadius:us,boxShadow:$b},Fg=["TopLeft","TopRight","BottomLeft","BottomRight"],Wb=Fg.length,Qf=e=>typeof e=="string"?parseFloat(e):e,Zf=e=>typeof e=="number"||U.test(e);function Hb(e,t,r,n,s,i){s?(e.opacity=fe(0,r.opacity!==void 0?r.opacity:1,qb(n)),e.opacityExit=fe(t.opacity!==void 0?t.opacity:1,0,Gb(n))):i&&(e.opacity=fe(t.opacity!==void 0?t.opacity:1,r.opacity!==void 0?r.opacity:1,n));for(let o=0;ont?1:r(ri(e,t,n))}function eh(e,t){e.min=t.min,e.max=t.max}function ot(e,t){eh(e.x,t.x),eh(e.y,t.y)}function th(e,t,r,n,s){return e-=t,e=Do(e,1/r,n),s!==void 0&&(e=Do(e,1/s,n)),e}function Yb(e,t=0,r=1,n=.5,s,i=e,o=e){if(At.test(t)&&(t=parseFloat(t),t=fe(o.min,o.max,t/100)-o.min),typeof t!="number")return;let a=fe(i.min,i.max,n);e===i&&(a-=t),e.min=th(e.min,t,r,a,s),e.max=th(e.max,t,r,a,s)}function rh(e,t,[r,n,s],i,o){Yb(e,t[r],t[n],t[s],t.scale,i,o)}const Kb=["x","scaleX","originX"],Xb=["y","scaleY","originY"];function nh(e,t,r,n){rh(e.x,t,Kb,r?r.x:void 0,n?n.x:void 0),rh(e.y,t,Xb,r?r.y:void 0,n?n.y:void 0)}function sh(e){return e.translate===0&&e.scale===1}function zg(e){return sh(e.x)&&sh(e.y)}function Qb(e,t){return e.x.min===t.x.min&&e.x.max===t.x.max&&e.y.min===t.y.min&&e.y.max===t.y.max}function Og(e,t){return Math.round(e.x.min)===Math.round(t.x.min)&&Math.round(e.x.max)===Math.round(t.x.max)&&Math.round(e.y.min)===Math.round(t.y.min)&&Math.round(e.y.max)===Math.round(t.y.max)}function ih(e){return nt(e.x)/nt(e.y)}class Zb{constructor(){this.members=[]}add(t){zc(this.members,t),t.scheduleRender()}remove(t){if(Oc(this.members,t),t===this.prevLead&&(this.prevLead=void 0),t===this.lead){const r=this.members[this.members.length-1];r&&this.promote(r)}}relegate(t){const r=this.members.findIndex(s=>t===s);if(r===0)return!1;let n;for(let s=r;s>=0;s--){const i=this.members[s];if(i.isPresent!==!1){n=i;break}}return n?(this.promote(n),!0):!1}promote(t,r){const n=this.lead;if(t!==n&&(this.prevLead=n,this.lead=t,t.show(),n)){n.instance&&n.scheduleRender(),t.scheduleRender(),t.resumeFrom=n,r&&(t.resumeFrom.preserveOpacity=!0),n.snapshot&&(t.snapshot=n.snapshot,t.snapshot.latestValues=n.animationValues||n.latestValues),t.root&&t.root.isUpdating&&(t.isLayoutDirty=!0);const{crossfade:s}=t.options;s===!1&&n.hide()}}exitAnimationComplete(){this.members.forEach(t=>{const{options:r,resumingFrom:n}=t;r.onExitComplete&&r.onExitComplete(),n&&n.options.onExitComplete&&n.options.onExitComplete()})}scheduleRender(){this.members.forEach(t=>{t.instance&&t.scheduleRender(!1)})}removeLeadSnapshot(){this.lead&&this.lead.snapshot&&(this.lead.snapshot=void 0)}}function oh(e,t,r){let n="";const s=e.x.translate/t.x,i=e.y.translate/t.y;if((s||i)&&(n=`translate3d(${s}px, ${i}px, 0) `),(t.x!==1||t.y!==1)&&(n+=`scale(${1/t.x}, ${1/t.y}) `),r){const{rotate:l,rotateX:c,rotateY:d}=r;l&&(n+=`rotate(${l}deg) `),c&&(n+=`rotateX(${c}deg) `),d&&(n+=`rotateY(${d}deg) `)}const o=e.x.scale*t.x,a=e.y.scale*t.y;return(o!==1||a!==1)&&(n+=`scale(${o}, ${a})`),n||"none"}const Jb=(e,t)=>e.depth-t.depth;class e4{constructor(){this.children=[],this.isDirty=!1}add(t){zc(this.children,t),this.isDirty=!0}remove(t){Oc(this.children,t),this.isDirty=!0}forEach(t){this.isDirty&&this.children.sort(Jb),this.isDirty=!1,this.children.forEach(t)}}function t4(e,t){const r=performance.now(),n=({timestamp:s})=>{const i=s-r;i>=t&&(Kt(n),e(i-t))};return ne.read(n,!0),()=>Kt(n)}function r4(e){window.MotionDebug&&window.MotionDebug.record(e)}function n4(e){return e instanceof SVGElement&&e.tagName!=="svg"}function s4(e,t,r){const n=Xe(e)?e:On(e);return n.start(Ic("",n,t,r)),n.animation}const ah=["","X","Y","Z"],i4={visibility:"hidden"},lh=1e3;let o4=0;const Or={type:"projectionFrame",totalNodes:0,resolvedTargetDeltas:0,recalculatedProjection:0};function $g({attachResizeListener:e,defaultParent:t,measureScroll:r,checkIsScrollRoot:n,resetTransform:s}){return class{constructor(o={},a=t==null?void 0:t()){this.id=o4++,this.animationId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.updateScheduled=!1,this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,Or.totalNodes=Or.resolvedTargetDeltas=Or.recalculatedProjection=0,this.nodes.forEach(u4),this.nodes.forEach(p4),this.nodes.forEach(m4),this.nodes.forEach(c4),r4(Or)},this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=o,this.root=a?a.root||a:this,this.path=a?[...a.path,a]:[],this.parent=a,this.depth=a?a.depth+1:0;for(let l=0;lthis.root.updateBlockedByResize=!1;e(o,()=>{this.root.updateBlockedByResize=!0,f&&f(),f=t4(u,250),Ji.hasAnimatedSinceResize&&(Ji.hasAnimatedSinceResize=!1,this.nodes.forEach(ch))})}l&&this.root.registerSharedNode(l,this),this.options.animate!==!1&&d&&(l||c)&&this.addEventListener("didUpdate",({delta:f,hasLayoutChanged:u,hasRelativeTargetChanged:p,layout:m})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const g=this.options.transition||d.getDefaultTransition()||w4,{onLayoutAnimationStart:w,onLayoutAnimationComplete:v}=d.getProps(),y=!this.targetLayout||!Og(this.targetLayout,m)||p,x=!u&&p;if(this.options.layoutRoot||this.resumeFrom&&this.resumeFrom.instance||x||u&&(y||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0),this.setAnimationOrigin(f,x);const b={...Fc(g,"layout"),onPlay:w,onComplete:v};(d.shouldReduceMotion||this.options.layoutRoot)&&(b.delay=0,b.type=!1),this.startAnimation(b)}else u||ch(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=m})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const o=this.getStack();o&&o.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,Kt(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(g4),this.animationId++)}getTransformTemplate(){const{visualElement:o}=this.options;return o&&o.getProps().transformTemplate}willUpdate(o=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let d=0;dthis.update()))}clearAllSnapshots(){this.nodes.forEach(d4),this.sharedNodes.forEach(y4)}scheduleUpdateProjection(){this.projectionUpdateScheduled||(this.projectionUpdateScheduled=!0,ne.preRender(this.updateProjection,!1,!0))}scheduleCheckAfterUnmount(){ne.postRender(()=>{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure())}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let l=0;l{const k=b/1e3;dh(f.x,o.x,k),dh(f.y,o.y,k),this.setTargetDelta(f),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(Ts(u,this.layout.layoutBox,this.relativeParent.layout.layoutBox),v4(this.relativeTarget,this.relativeTargetOrigin,u,k),x&&Qb(this.relativeTarget,x)&&(this.isProjectionDirty=!1),x||(x=Se()),ot(x,this.relativeTarget)),g&&(this.animationValues=d,Hb(d,c,this.latestValues,k,y,v)),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=k},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(o){this.notifyListeners("animationStart"),this.currentAnimation&&this.currentAnimation.stop(),this.resumingFrom&&this.resumingFrom.currentAnimation&&this.resumingFrom.currentAnimation.stop(),this.pendingAnimation&&(Kt(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=ne.update(()=>{Ji.hasAnimatedSinceResize=!0,this.currentAnimation=s4(0,lh,{...o,onUpdate:a=>{this.mixTargetDelta(a),o.onUpdate&&o.onUpdate(a)},onComplete:()=>{o.onComplete&&o.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const o=this.getStack();o&&o.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(lh),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const o=this.getLead();let{targetWithTransforms:a,target:l,layout:c,latestValues:d}=o;if(!(!a||!l||!c)){if(this!==o&&this.layout&&c&&Bg(this.options.animationType,this.layout.layoutBox,c.layoutBox)){l=this.target||Se();const f=nt(this.layout.layoutBox.x);l.x.min=o.target.x.min,l.x.max=l.x.min+f;const u=nt(this.layout.layoutBox.y);l.y.min=o.target.y.min,l.y.max=l.y.min+u}ot(a,l),jn(a,d),Es(this.projectionDeltaWithTransform,this.layoutCorrected,a,d)}}registerSharedNode(o,a){this.sharedNodes.has(o)||this.sharedNodes.set(o,new Zb),this.sharedNodes.get(o).add(a);const c=a.options.initialPromotionConfig;a.promote({transition:c?c.transition:void 0,preserveFollowOpacity:c&&c.shouldPreserveFollowOpacity?c.shouldPreserveFollowOpacity(a):void 0})}isLead(){const o=this.getStack();return o?o.lead===this:!0}getLead(){var o;const{layoutId:a}=this.options;return a?((o=this.getStack())===null||o===void 0?void 0:o.lead)||this:this}getPrevLead(){var o;const{layoutId:a}=this.options;return a?(o=this.getStack())===null||o===void 0?void 0:o.prevLead:void 0}getStack(){const{layoutId:o}=this.options;if(o)return this.root.sharedNodes.get(o)}promote({needsReset:o,transition:a,preserveFollowOpacity:l}={}){const c=this.getStack();c&&c.promote(this,l),o&&(this.projectionDelta=void 0,this.needsReset=!0),a&&this.setOptions({transition:a})}relegate(){const o=this.getStack();return o?o.relegate(this):!1}resetRotation(){const{visualElement:o}=this.options;if(!o)return;let a=!1;const{latestValues:l}=o;if((l.rotate||l.rotateX||l.rotateY||l.rotateZ)&&(a=!0),!a)return;const c={};for(let d=0;d{var a;return(a=o.currentAnimation)===null||a===void 0?void 0:a.stop()}),this.root.nodes.forEach(uh),this.root.sharedNodes.clear()}}}function a4(e){e.updateLayout()}function l4(e){var t;const r=((t=e.resumeFrom)===null||t===void 0?void 0:t.snapshot)||e.snapshot;if(e.isLead()&&e.layout&&r&&e.hasListeners("didUpdate")){const{layoutBox:n,measuredBox:s}=e.layout,{animationType:i}=e.options,o=r.source!==e.layout.source;i==="size"?at(f=>{const u=o?r.measuredBox[f]:r.layoutBox[f],p=nt(u);u.min=n[f].min,u.max=u.min+p}):Bg(i,r.layoutBox,n)&&at(f=>{const u=o?r.measuredBox[f]:r.layoutBox[f],p=nt(n[f]);u.max=u.min+p,e.relativeTarget&&!e.currentAnimation&&(e.isProjectionDirty=!0,e.relativeTarget[f].max=e.relativeTarget[f].min+p)});const a=kn();Es(a,n,r.layoutBox);const l=kn();o?Es(l,e.applyTransform(s,!0),r.measuredBox):Es(l,n,r.layoutBox);const c=!zg(a);let d=!1;if(!e.resumeFrom){const f=e.getClosestProjectingParent();if(f&&!f.resumeFrom){const{snapshot:u,layout:p}=f;if(u&&p){const m=Se();Ts(m,r.layoutBox,u.layoutBox);const g=Se();Ts(g,n,p.layoutBox),Og(m,g)||(d=!0),f.options.layoutRoot&&(e.relativeTarget=g,e.relativeTargetOrigin=m,e.relativeParent=f)}}}e.notifyListeners("didUpdate",{layout:n,snapshot:r,delta:l,layoutDelta:a,hasLayoutChanged:c,hasRelativeTargetChanged:d})}else if(e.isLead()){const{onExitComplete:n}=e.options;n&&n()}e.options.transition=void 0}function u4(e){Or.totalNodes++,e.parent&&(e.isProjecting()||(e.isProjectionDirty=e.parent.isProjectionDirty),e.isSharedProjectionDirty||(e.isSharedProjectionDirty=!!(e.isProjectionDirty||e.parent.isProjectionDirty||e.parent.isSharedProjectionDirty)),e.isTransformDirty||(e.isTransformDirty=e.parent.isTransformDirty))}function c4(e){e.isProjectionDirty=e.isSharedProjectionDirty=e.isTransformDirty=!1}function d4(e){e.clearSnapshot()}function uh(e){e.clearMeasurements()}function f4(e){e.isLayoutDirty=!1}function h4(e){const{visualElement:t}=e.options;t&&t.getProps().onBeforeLayoutMeasure&&t.notify("BeforeLayoutMeasure"),e.resetTransform()}function ch(e){e.finishAnimation(),e.targetDelta=e.relativeTarget=e.target=void 0,e.isProjectionDirty=!0}function p4(e){e.resolveTargetDelta()}function m4(e){e.calcProjection()}function g4(e){e.resetRotation()}function y4(e){e.removeLeadSnapshot()}function dh(e,t,r){e.translate=fe(t.translate,0,r),e.scale=fe(t.scale,1,r),e.origin=t.origin,e.originPoint=t.originPoint}function fh(e,t,r,n){e.min=fe(t.min,r.min,n),e.max=fe(t.max,r.max,n)}function v4(e,t,r,n){fh(e.x,t.x,r.x,n),fh(e.y,t.y,r.y,n)}function x4(e){return e.animationValues&&e.animationValues.opacityExit!==void 0}const w4={duration:.45,ease:[.4,0,.1,1]},hh=e=>typeof navigator<"u"&&navigator.userAgent.toLowerCase().includes(e),ph=hh("applewebkit/")&&!hh("chrome/")?Math.round:xe;function mh(e){e.min=ph(e.min),e.max=ph(e.max)}function b4(e){mh(e.x),mh(e.y)}function Bg(e,t,r){return e==="position"||e==="preserve-aspect"&&!du(ih(t),ih(r),.2)}const S4=$g({attachResizeListener:(e,t)=>Ot(e,"resize",t),measureScroll:()=>({x:document.documentElement.scrollLeft||document.body.scrollLeft,y:document.documentElement.scrollTop||document.body.scrollTop}),checkIsScrollRoot:()=>!0}),Xa={current:void 0},Ug=$g({measureScroll:e=>({x:e.scrollLeft,y:e.scrollTop}),defaultParent:()=>{if(!Xa.current){const e=new S4({});e.mount(window),e.setOptions({layoutScroll:!0}),Xa.current=e}return Xa.current},resetTransform:(e,t)=>{e.style.transform=t!==void 0?t:"none"},checkIsScrollRoot:e=>window.getComputedStyle(e).position==="fixed"}),k4={pan:{Feature:zb},drag:{Feature:Ib,ProjectionNode:Ug,MeasureLayout:Vg}},j4=/var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;function C4(e){const t=j4.exec(e);if(!t)return[,];const[,r,n]=t;return[r,n]}function mu(e,t,r=1){const[n,s]=C4(e);if(!n)return;const i=window.getComputedStyle(t).getPropertyValue(n);if(i){const o=i.trim();return Cg(o)?parseFloat(o):o}else return su(s)?mu(s,t,r+1):s}function N4(e,{...t},r){const n=e.current;if(!(n instanceof Element))return{target:t,transitionEnd:r};r&&(r={...r}),e.values.forEach(s=>{const i=s.get();if(!su(i))return;const o=mu(i,n);o&&s.set(o)});for(const s in t){const i=t[s];if(!su(i))continue;const o=mu(i,n);o&&(t[s]=o,r||(r={}),r[s]===void 0&&(r[s]=i))}return{target:t,transitionEnd:r}}const P4=new Set(["width","height","top","left","right","bottom","x","y","translateX","translateY"]),Wg=e=>P4.has(e),E4=e=>Object.keys(e).some(Wg),gh=e=>e===sn||e===U,yh=(e,t)=>parseFloat(e.split(", ")[t]),vh=(e,t)=>(r,{transform:n})=>{if(n==="none"||!n)return 0;const s=n.match(/^matrix3d\((.+)\)$/);if(s)return yh(s[1],t);{const i=n.match(/^matrix\((.+)\)$/);return i?yh(i[1],e):0}},T4=new Set(["x","y","z"]),M4=di.filter(e=>!T4.has(e));function A4(e){const t=[];return M4.forEach(r=>{const n=e.getValue(r);n!==void 0&&(t.push([r,n.get()]),n.set(r.startsWith("scale")?1:0))}),t.length&&e.render(),t}const $n={width:({x:e},{paddingLeft:t="0",paddingRight:r="0"})=>e.max-e.min-parseFloat(t)-parseFloat(r),height:({y:e},{paddingTop:t="0",paddingBottom:r="0"})=>e.max-e.min-parseFloat(t)-parseFloat(r),top:(e,{top:t})=>parseFloat(t),left:(e,{left:t})=>parseFloat(t),bottom:({y:e},{top:t})=>parseFloat(t)+(e.max-e.min),right:({x:e},{left:t})=>parseFloat(t)+(e.max-e.min),x:vh(4,13),y:vh(5,14)};$n.translateX=$n.x;$n.translateY=$n.y;const _4=(e,t,r)=>{const n=t.measureViewportBox(),s=t.current,i=getComputedStyle(s),{display:o}=i,a={};o==="none"&&t.setStaticValue("display",e.display||"block"),r.forEach(c=>{a[c]=$n[c](n,i)}),t.render();const l=t.measureViewportBox();return r.forEach(c=>{const d=t.getValue(c);d&&d.jump(a[c]),e[c]=$n[c](l,i)}),e},L4=(e,t,r={},n={})=>{t={...t},n={...n};const s=Object.keys(t).filter(Wg);let i=[],o=!1;const a=[];if(s.forEach(l=>{const c=e.getValue(l);if(!e.hasValue(l))return;let d=r[l],f=ls(d);const u=t[l];let p;if(To(u)){const m=u.length,g=u[0]===null?1:0;d=u[g],f=ls(d);for(let w=g;w=0?window.pageYOffset:null,c=_4(t,e,a);return i.length&&i.forEach(([d,f])=>{e.getValue(d).set(f)}),e.render(),ia&&l!==null&&window.scrollTo({top:l}),{target:c,transitionEnd:n}}else return{target:t,transitionEnd:n}};function D4(e,t,r,n){return E4(t)?L4(e,t,r,n):{target:t,transitionEnd:n}}const R4=(e,t,r,n)=>{const s=N4(e,t,n);return t=s.target,n=s.transitionEnd,D4(e,t,r,n)},gu={current:null},Hg={current:!1};function V4(){if(Hg.current=!0,!!ia)if(window.matchMedia){const e=window.matchMedia("(prefers-reduced-motion)"),t=()=>gu.current=e.matches;e.addListener(t),t()}else gu.current=!1}function F4(e,t,r){const{willChange:n}=t;for(const s in t){const i=t[s],o=r[s];if(Xe(i))e.addValue(s,i),Lo(n)&&n.add(s);else if(Xe(o))e.addValue(s,On(i,{owner:e})),Lo(n)&&n.remove(s);else if(o!==i)if(e.hasValue(s)){const a=e.getValue(s);!a.hasAnimated&&a.set(i)}else{const a=e.getStaticValue(s);e.addValue(s,On(a!==void 0?a:i,{owner:e}))}}for(const s in r)t[s]===void 0&&e.removeValue(s);return t}const xh=new WeakMap,qg=Object.keys(ti),I4=qg.length,wh=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"],z4=kc.length;class O4{constructor({parent:t,props:r,presenceContext:n,reducedMotionConfig:s,visualState:i},o={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.values=new Map,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.scheduleRender=()=>ne.render(this.render,!1,!0);const{latestValues:a,renderState:l}=i;this.latestValues=a,this.baseTarget={...a},this.initialValues=r.initial?{...a}:{},this.renderState=l,this.parent=t,this.props=r,this.presenceContext=n,this.depth=t?t.depth+1:0,this.reducedMotionConfig=s,this.options=o,this.isControllingVariants=aa(r),this.isVariantNode=M0(r),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(t&&t.current);const{willChange:c,...d}=this.scrapeMotionValuesFromProps(r,{});for(const f in d){const u=d[f];a[f]!==void 0&&Xe(u)&&(u.set(a[f],!1),Lo(c)&&c.add(f))}}scrapeMotionValuesFromProps(t,r){return{}}mount(t){this.current=t,xh.set(t,this),this.projection&&!this.projection.instance&&this.projection.mount(t),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach((r,n)=>this.bindToMotionValue(n,r)),Hg.current||V4(),this.shouldReduceMotion=this.reducedMotionConfig==="never"?!1:this.reducedMotionConfig==="always"?!0:gu.current,this.parent&&this.parent.children.add(this),this.update(this.props,this.presenceContext)}unmount(){xh.delete(this.current),this.projection&&this.projection.unmount(),Kt(this.notifyUpdate),Kt(this.render),this.valueSubscriptions.forEach(t=>t()),this.removeFromVariantTree&&this.removeFromVariantTree(),this.parent&&this.parent.children.delete(this);for(const t in this.events)this.events[t].clear();for(const t in this.features)this.features[t].unmount();this.current=null}bindToMotionValue(t,r){const n=nn.has(t),s=r.on("change",o=>{this.latestValues[t]=o,this.props.onUpdate&&ne.update(this.notifyUpdate,!1,!0),n&&this.projection&&(this.projection.isTransformDirty=!0)}),i=r.on("renderRequest",this.scheduleRender);this.valueSubscriptions.set(t,()=>{s(),i()})}sortNodePosition(t){return!this.current||!this.sortInstanceNodePosition||this.type!==t.type?0:this.sortInstanceNodePosition(this.current,t.current)}loadFeatures({children:t,...r},n,s,i){let o,a;for(let l=0;lthis.scheduleRender(),animationType:typeof c=="string"?c:"both",initialPromotionConfig:i,layoutScroll:u,layoutRoot:p})}return a}updateFeatures(){for(const t in this.features){const r=this.features[t];r.isMounted?r.update():(r.mount(),r.isMounted=!0)}}triggerBuild(){this.build(this.renderState,this.latestValues,this.options,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):Se()}getStaticValue(t){return this.latestValues[t]}setStaticValue(t,r){this.latestValues[t]=r}makeTargetAnimatable(t,r=!0){return this.makeTargetAnimatableFromInstance(t,this.props,r)}update(t,r){(t.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=t,this.prevPresenceContext=this.presenceContext,this.presenceContext=r;for(let n=0;nr.variantChildren.delete(t)}addValue(t,r){r!==this.values.get(t)&&(this.removeValue(t),this.bindToMotionValue(t,r)),this.values.set(t,r),this.latestValues[t]=r.get()}removeValue(t){this.values.delete(t);const r=this.valueSubscriptions.get(t);r&&(r(),this.valueSubscriptions.delete(t)),delete this.latestValues[t],this.removeValueFromRenderState(t,this.renderState)}hasValue(t){return this.values.has(t)}getValue(t,r){if(this.props.values&&this.props.values[t])return this.props.values[t];let n=this.values.get(t);return n===void 0&&r!==void 0&&(n=On(r,{owner:this}),this.addValue(t,n)),n}readValue(t){var r;return this.latestValues[t]!==void 0||!this.current?this.latestValues[t]:(r=this.getBaseTargetFromProps(this.props,t))!==null&&r!==void 0?r:this.readValueFromInstance(this.current,t,this.options)}setBaseTarget(t,r){this.baseTarget[t]=r}getBaseTarget(t){var r;const{initial:n}=this.props,s=typeof n=="string"||typeof n=="object"?(r=Ac(this.props,n))===null||r===void 0?void 0:r[t]:void 0;if(n&&s!==void 0)return s;const i=this.getBaseTargetFromProps(this.props,t);return i!==void 0&&!Xe(i)?i:this.initialValues[t]!==void 0&&s===void 0?void 0:this.baseTarget[t]}on(t,r){return this.events[t]||(this.events[t]=new $c),this.events[t].add(r)}notify(t,...r){this.events[t]&&this.events[t].notify(...r)}}class Gg extends O4{sortInstanceNodePosition(t,r){return t.compareDocumentPosition(r)&2?1:-1}getBaseTargetFromProps(t,r){return t.style?t.style[r]:void 0}removeValueFromRenderState(t,{vars:r,style:n}){delete r[t],delete n[t]}makeTargetAnimatableFromInstance({transition:t,transitionEnd:r,...n},{transformValues:s},i){let o=nb(n,t||{},this);if(s&&(r&&(r=s(r)),n&&(n=s(n)),o&&(o=s(o))),i){tb(this,n,o);const a=R4(this,n,o,r);r=a.transitionEnd,n=a.target}return{transition:t,transitionEnd:r,...n}}}function $4(e){return window.getComputedStyle(e)}class B4 extends Gg{constructor(){super(...arguments),this.type="html"}readValueFromInstance(t,r){if(nn.has(r)){const n=Vc(r);return n&&n.default||0}else{const n=$4(t),s=(D0(r)?n.getPropertyValue(r):n[r])||0;return typeof s=="string"?s.trim():s}}measureInstanceViewportBox(t,{transformPagePoint:r}){return Dg(t,r)}build(t,r,n,s){Nc(t,r,n,s.transformTemplate)}scrapeMotionValuesFromProps(t,r){return Mc(t,r)}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:t}=this.props;Xe(t)&&(this.childSubscription=t.on("change",r=>{this.current&&(this.current.textContent=`${r}`)}))}renderInstance(t,r,n,s){O0(t,r,n,s)}}class U4 extends Gg{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1}getBaseTargetFromProps(t,r){return t[r]}readValueFromInstance(t,r){if(nn.has(r)){const n=Vc(r);return n&&n.default||0}return r=$0.has(r)?r:bc(r),t.getAttribute(r)}measureInstanceViewportBox(){return Se()}scrapeMotionValuesFromProps(t,r){return U0(t,r)}build(t,r,n,s){Ec(t,r,n,this.isSVGTag,s.transformTemplate)}renderInstance(t,r,n,s){B0(t,r,n,s)}mount(t){this.isSVGTag=Tc(t.tagName),super.mount(t)}}const W4=(e,t)=>Cc(e)?new U4(t,{enableHardwareAcceleration:!1}):new B4(t,{enableHardwareAcceleration:!0}),H4={layout:{ProjectionNode:Ug,MeasureLayout:Vg}},q4={...vb,...Iw,...k4,...H4},z=G2((e,t)=>Cw(e,t,q4,W4));function Yg(){const e=S.useRef(!1);return wc(()=>(e.current=!0,()=>{e.current=!1}),[]),e}function G4(){const e=Yg(),[t,r]=S.useState(0),n=S.useCallback(()=>{e.current&&r(t+1)},[t]);return[S.useCallback(()=>ne.postRender(n),[n]),t]}class Y4 extends S.Component{getSnapshotBeforeUpdate(t){const r=this.props.childRef.current;if(r&&t.isPresent&&!this.props.isPresent){const n=this.props.sizeRef.current;n.height=r.offsetHeight||0,n.width=r.offsetWidth||0,n.top=r.offsetTop,n.left=r.offsetLeft}return null}componentDidUpdate(){}render(){return this.props.children}}function K4({children:e,isPresent:t}){const r=S.useId(),n=S.useRef(null),s=S.useRef({width:0,height:0,top:0,left:0});return S.useInsertionEffect(()=>{const{width:i,height:o,top:a,left:l}=s.current;if(t||!n.current||!i||!o)return;n.current.dataset.motionPopId=r;const c=document.createElement("style");return document.head.appendChild(c),c.sheet&&c.sheet.insertRule(` + [data-motion-pop-id="${r}"] { + position: absolute !important; + width: ${i}px !important; + height: ${o}px !important; + top: ${a}px !important; + left: ${l}px !important; + } + `),()=>{document.head.removeChild(c)}},[t]),S.createElement(Y4,{isPresent:t,childRef:n,sizeRef:s},S.cloneElement(e,{ref:n}))}const Qa=({children:e,initial:t,isPresent:r,onExitComplete:n,custom:s,presenceAffectsLayout:i,mode:o})=>{const a=W0(X4),l=S.useId(),c=S.useMemo(()=>({id:l,initial:t,isPresent:r,custom:s,onExitComplete:d=>{a.set(d,!0);for(const f of a.values())if(!f)return;n&&n()},register:d=>(a.set(d,!1),()=>a.delete(d))}),i?void 0:[r]);return S.useMemo(()=>{a.forEach((d,f)=>a.set(f,!1))},[r]),S.useEffect(()=>{!r&&!a.size&&n&&n()},[r]),o==="popLayout"&&(e=S.createElement(K4,{isPresent:r},e)),S.createElement(sa.Provider,{value:c},e)};function X4(){return new Map}function Q4(e){return S.useEffect(()=>()=>e(),[])}const $r=e=>e.key||"";function Z4(e,t){e.forEach(r=>{const n=$r(r);t.set(n,r)})}function J4(e){const t=[];return S.Children.forEach(e,r=>{S.isValidElement(r)&&t.push(r)}),t}const e3=({children:e,custom:t,initial:r=!0,onExitComplete:n,exitBeforeEnter:s,presenceAffectsLayout:i=!0,mode:o="sync"})=>{const a=S.useContext(jc).forceRender||G4()[0],l=Yg(),c=J4(e);let d=c;const f=S.useRef(new Map).current,u=S.useRef(d),p=S.useRef(new Map).current,m=S.useRef(!0);if(wc(()=>{m.current=!1,Z4(c,p),u.current=d}),Q4(()=>{m.current=!0,p.clear(),f.clear()}),m.current)return S.createElement(S.Fragment,null,d.map(y=>S.createElement(Qa,{key:$r(y),isPresent:!0,initial:r?void 0:!1,presenceAffectsLayout:i,mode:o},y)));d=[...d];const g=u.current.map($r),w=c.map($r),v=g.length;for(let y=0;y{if(w.indexOf(x)!==-1)return;const b=p.get(x);if(!b)return;const k=g.indexOf(x);let C=y;if(!C){const N=()=>{f.delete(x);const P=Array.from(p.keys()).filter(V=>!w.includes(V));if(P.forEach(V=>p.delete(V)),u.current=c.filter(V=>{const T=$r(V);return T===x||P.includes(T)}),!f.size){if(l.current===!1)return;a(),n&&n()}};C=S.createElement(Qa,{key:$r(b),isPresent:!1,onExitComplete:N,custom:t,presenceAffectsLayout:i,mode:o},b),f.set(x,C)}d.splice(k,0,C)}),d=d.map(y=>{const x=y.key;return f.has(x)?y:S.createElement(Qa,{key:$r(y),isPresent:!0,presenceAffectsLayout:i,mode:o},y)}),S.createElement(S.Fragment,null,f.size?d:d.map(y=>S.cloneElement(y)))},t3={},bh=e=>{let t;const r=new Set,n=(d,f)=>{const u=typeof d=="function"?d(t):d;if(!Object.is(u,t)){const p=t;t=f??(typeof u!="object"||u===null)?u:Object.assign({},t,u),r.forEach(m=>m(t,p))}},s=()=>t,l={setState:n,getState:s,getInitialState:()=>c,subscribe:d=>(r.add(d),()=>r.delete(d)),destroy:()=>{(t3?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),r.clear()}},c=t=e(n,s,l);return l},r3=e=>e?bh(e):bh;var Kg={exports:{}},Xg={},Qg={exports:{}},Zg={};/** + * @license React + * use-sync-external-store-shim.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Bn=S;function n3(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var s3=typeof Object.is=="function"?Object.is:n3,i3=Bn.useState,o3=Bn.useEffect,a3=Bn.useLayoutEffect,l3=Bn.useDebugValue;function u3(e,t){var r=t(),n=i3({inst:{value:r,getSnapshot:t}}),s=n[0].inst,i=n[1];return a3(function(){s.value=r,s.getSnapshot=t,Za(s)&&i({inst:s})},[e,r,t]),o3(function(){return Za(s)&&i({inst:s}),e(function(){Za(s)&&i({inst:s})})},[e]),l3(r),r}function Za(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!s3(e,r)}catch{return!0}}function c3(e,t){return t()}var d3=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?c3:u3;Zg.useSyncExternalStore=Bn.useSyncExternalStore!==void 0?Bn.useSyncExternalStore:d3;Qg.exports=Zg;var f3=Qg.exports;/** + * @license React + * use-sync-external-store-shim/with-selector.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var da=S,h3=f3;function p3(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var m3=typeof Object.is=="function"?Object.is:p3,g3=h3.useSyncExternalStore,y3=da.useRef,v3=da.useEffect,x3=da.useMemo,w3=da.useDebugValue;Xg.useSyncExternalStoreWithSelector=function(e,t,r,n,s){var i=y3(null);if(i.current===null){var o={hasValue:!1,value:null};i.current=o}else o=i.current;i=x3(function(){function l(p){if(!c){if(c=!0,d=p,p=n(p),s!==void 0&&o.hasValue){var m=o.value;if(s(m,p))return f=m}return f=p}if(m=f,m3(d,p))return m;var g=n(p);return s!==void 0&&s(m,g)?(d=p,m):(d=p,f=g)}var c=!1,d,f,u=r===void 0?null:r;return[function(){return l(t())},u===null?void 0:function(){return l(u())}]},[t,r,n,s]);var a=g3(e,i[0],i[1]);return v3(function(){o.hasValue=!0,o.value=a},[a]),w3(a),a};Kg.exports=Xg;var b3=Kg.exports;const S3=wu(b3),Jg={},{useDebugValue:k3}=ii,{useSyncExternalStoreWithSelector:j3}=S3;let Sh=!1;const C3=e=>e;function N3(e,t=C3,r){(Jg?"production":void 0)!=="production"&&r&&!Sh&&(console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"),Sh=!0);const n=j3(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,r);return k3(n),n}const P3=e=>{(Jg?"production":void 0)!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?r3(e):e,r=(n,s)=>N3(t,n,s);return Object.assign(r,t),r},E3=e=>P3,T3={};function M3(e,t){let r;try{r=e()}catch{return}return{getItem:s=>{var i;const o=l=>l===null?null:JSON.parse(l,void 0),a=(i=r.getItem(s))!=null?i:null;return a instanceof Promise?a.then(o):o(a)},setItem:(s,i)=>r.setItem(s,JSON.stringify(i,void 0)),removeItem:s=>r.removeItem(s)}}const ni=e=>t=>{try{const r=e(t);return r instanceof Promise?r:{then(n){return ni(n)(r)},catch(n){return this}}}catch(r){return{then(n){return this},catch(n){return ni(n)(r)}}}},A3=(e,t)=>(r,n,s)=>{let i={getStorage:()=>localStorage,serialize:JSON.stringify,deserialize:JSON.parse,partialize:w=>w,version:0,merge:(w,v)=>({...v,...w}),...t},o=!1;const a=new Set,l=new Set;let c;try{c=i.getStorage()}catch{}if(!c)return e((...w)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),r(...w)},n,s);const d=ni(i.serialize),f=()=>{const w=i.partialize({...n()});let v;const y=d({state:w,version:i.version}).then(x=>c.setItem(i.name,x)).catch(x=>{v=x});if(v)throw v;return y},u=s.setState;s.setState=(w,v)=>{u(w,v),f()};const p=e((...w)=>{r(...w),f()},n,s);let m;const g=()=>{var w;if(!c)return;o=!1,a.forEach(y=>y(n()));const v=((w=i.onRehydrateStorage)==null?void 0:w.call(i,n()))||void 0;return ni(c.getItem.bind(c))(i.name).then(y=>{if(y)return i.deserialize(y)}).then(y=>{if(y)if(typeof y.version=="number"&&y.version!==i.version){if(i.migrate)return i.migrate(y.state,y.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return y.state}).then(y=>{var x;return m=i.merge(y,(x=n())!=null?x:p),r(m,!0),f()}).then(()=>{v==null||v(m,void 0),o=!0,l.forEach(y=>y(m))}).catch(y=>{v==null||v(void 0,y)})};return s.persist={setOptions:w=>{i={...i,...w},w.getStorage&&(c=w.getStorage())},clearStorage:()=>{c==null||c.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>g(),hasHydrated:()=>o,onHydrate:w=>(a.add(w),()=>{a.delete(w)}),onFinishHydration:w=>(l.add(w),()=>{l.delete(w)})},g(),m||p},_3=(e,t)=>(r,n,s)=>{let i={storage:M3(()=>localStorage),partialize:g=>g,version:0,merge:(g,w)=>({...w,...g}),...t},o=!1;const a=new Set,l=new Set;let c=i.storage;if(!c)return e((...g)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),r(...g)},n,s);const d=()=>{const g=i.partialize({...n()});return c.setItem(i.name,{state:g,version:i.version})},f=s.setState;s.setState=(g,w)=>{f(g,w),d()};const u=e((...g)=>{r(...g),d()},n,s);s.getInitialState=()=>u;let p;const m=()=>{var g,w;if(!c)return;o=!1,a.forEach(y=>{var x;return y((x=n())!=null?x:u)});const v=((w=i.onRehydrateStorage)==null?void 0:w.call(i,(g=n())!=null?g:u))||void 0;return ni(c.getItem.bind(c))(i.name).then(y=>{if(y)if(typeof y.version=="number"&&y.version!==i.version){if(i.migrate)return[!0,i.migrate(y.state,y.version)];console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,y.state];return[!1,void 0]}).then(y=>{var x;const[b,k]=y;if(p=i.merge(k,(x=n())!=null?x:u),r(p,!0),b)return d()}).then(()=>{v==null||v(p,void 0),p=n(),o=!0,l.forEach(y=>y(p))}).catch(y=>{v==null||v(void 0,y)})};return s.persist={setOptions:g=>{i={...i,...g},g.storage&&(c=g.storage)},clearStorage:()=>{c==null||c.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>m(),hasHydrated:()=>o,onHydrate:g=>(a.add(g),()=>{a.delete(g)}),onFinishHydration:g=>(l.add(g),()=>{l.delete(g)})},i.skipHydration||m(),p||u},L3=(e,t)=>"getStorage"in t||"serialize"in t||"deserialize"in t?((T3?"production":void 0)!=="production"&&console.warn("[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."),A3(e,t)):_3(e,t),D3=L3,kh={currentUser:null,partnerUser:null,isLoading:!1,error:null,currentTrack:null,isPlaying:!1},oe=E3()(D3(e=>({...kh,mixedPlaylists:[],memoryLane:[],theme:"green",setCurrentUser:t=>e({currentUser:t}),setPartnerUser:t=>e({partnerUser:t}),logout:()=>e({currentUser:null,partnerUser:null,currentTrack:null,isPlaying:!1,mixedPlaylists:[],memoryLane:[],error:null}),setLoading:t=>e({isLoading:t}),setError:t=>e({error:t}),setCurrentTrack:t=>e({currentTrack:t}),setIsPlaying:t=>e({isPlaying:t}),addMixedPlaylist:t=>e(r=>({mixedPlaylists:[...r.mixedPlaylists,t]})),removeMixedPlaylist:t=>e(r=>({mixedPlaylists:r.mixedPlaylists.filter(n=>n.id!==t)})),setMixedPlaylists:t=>e({mixedPlaylists:t}),addMemoryLaneItem:t=>e(r=>({memoryLane:[...r.memoryLane,t].sort((n,s)=>new Date(s.date).getTime()-new Date(n.date).getTime())})),removeMemoryLaneItem:t=>e(r=>({memoryLane:r.memoryLane.filter(n=>n.id!==t)})),setTheme:t=>e({theme:t}),clearAllData:()=>e({...kh,mixedPlaylists:[],memoryLane:[]})}),{name:"spotify-app-settings",partialize:e=>({theme:e.theme})}));function R3(){{const e="/api";try{const t=typeof window<"u"&&window.location.protocol==="https:",r=new URL(e,window.location.origin);if(t&&r.protocol==="http:"&&r.hostname==="159.195.9.107"&&(r.port==="8081"||r.port===""))return"https://159.195.9.107:3443"}catch{}return e}}const Kn=R3();function Xt(){try{const e=localStorage.getItem("spotify-user");if(!e)return null;const t=JSON.parse(e);return(t==null?void 0:t.jwt)||(t==null?void 0:t.token)||null}catch{return null}}async function Et(e,t,r){const n=await fetch(`${Kn}${e}`,{method:"POST",headers:{"Content-Type":"application/json",...r?{Authorization:`Bearer ${r}`}:Xt()?{Authorization:`Bearer ${Xt()}`}:{}},body:t?JSON.stringify(t):void 0});if(!n.ok){const s=await n.text();throw new Error(s||`Request failed: ${n.status}`)}return n.json()}async function te(e,t){const r=await fetch(`${Kn}${e}`,{headers:{...t?{Authorization:`Bearer ${t}`}:Xt()?{Authorization:`Bearer ${Xt()}`}:{}}});if(!r.ok){const n=await r.text();throw new Error(n||`Request failed: ${r.status}`)}return r.json()}function V3(e){const t=Xt(),r=new URL(`${Kn}${e}`,window.location.origin);return t&&r.searchParams.set("token",t),new EventSource(r.toString())}async function F3(e,t,r){const n=await fetch(`${Kn}${e}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",...Xt()?{Authorization:`Bearer ${Xt()}`}:{}},body:new URLSearchParams(t).toString()});if(!n.ok){const s=await n.text();throw new Error(s||`Request failed: ${n.status}`)}return n.json()}async function I3(e,t){const r=await fetch(`${Kn}${e}`,{method:"DELETE",headers:{...t?{Authorization:`Bearer ${t}`}:Xt()?{Authorization:`Bearer ${Xt()}`}:{}}});if(!r.ok){const n=await r.text();throw new Error(n||`Request failed: ${r.status}`)}return r.json()}const en=e=>{const t={green:{primary:"bg-theme-green-primary text-white",secondary:"bg-theme-green-secondary text-white",accent:"bg-theme-green-accent text-white",border:"border-theme-green-primary",text:"text-theme-green-primary",gradient:"from-theme-green-primary to-theme-green-secondary",glass:"bg-theme-green-primary/10 border-theme-green-primary/30",hover:"hover:bg-theme-green-primary/20",cssVars:{primary:"#1db954",secondary:"#1ed760",accent:"#00e676"}},pink:{primary:"bg-theme-pink-primary text-white",secondary:"bg-theme-pink-secondary text-white",accent:"bg-theme-pink-accent text-white",border:"border-theme-pink-primary",text:"text-theme-pink-primary",gradient:"from-theme-pink-primary to-theme-pink-secondary",glass:"bg-theme-pink-primary/10 border-theme-pink-primary/30",hover:"hover:bg-theme-pink-primary/20",cssVars:{primary:"#ec4899",secondary:"#f472b6",accent:"#fb7185"}},blue:{primary:"bg-theme-blue-primary text-white",secondary:"bg-theme-blue-secondary text-white",accent:"bg-theme-blue-accent text-white",border:"border-theme-blue-primary",text:"text-theme-blue-primary",gradient:"from-theme-blue-primary to-theme-blue-secondary",glass:"bg-theme-blue-primary/10 border-theme-blue-primary/30",hover:"hover:bg-theme-blue-primary/20",cssVars:{primary:"#3b82f6",secondary:"#60a5fa",accent:"#93c5fd"}},red:{primary:"bg-theme-red-primary text-white",secondary:"bg-theme-red-secondary text-white",accent:"bg-theme-red-accent text-white",border:"border-theme-red-primary",text:"text-theme-red-primary",gradient:"from-theme-red-primary to-theme-red-secondary",glass:"bg-theme-red-primary/10 border-theme-red-primary/30",hover:"hover:bg-theme-red-primary/20",cssVars:{primary:"#dc2626",secondary:"#ef4444",accent:"#f87171"}},purple:{primary:"bg-theme-purple-primary text-white",secondary:"bg-theme-purple-secondary text-white",accent:"bg-theme-purple-accent text-white",border:"border-theme-purple-primary",text:"text-theme-purple-primary",gradient:"from-theme-purple-primary to-theme-purple-secondary",glass:"bg-theme-purple-primary/10 border-theme-purple-primary/30",hover:"hover:bg-theme-purple-primary/20",cssVars:{primary:"#8b5cf6",secondary:"#a78bfa",accent:"#c4b5fd"}},yellow:{primary:"bg-theme-yellow-primary text-black",secondary:"bg-theme-yellow-secondary text-black",accent:"bg-theme-yellow-accent text-black",border:"border-theme-yellow-primary",text:"text-theme-yellow-primary",gradient:"from-theme-yellow-primary to-theme-yellow-secondary",glass:"bg-theme-yellow-primary/10 border-theme-yellow-primary/30",hover:"hover:bg-theme-yellow-primary/20",cssVars:{primary:"#eab308",secondary:"#f59e0b",accent:"#fbbf24"}},turquoise:{primary:"bg-theme-turquoise-primary text-white",secondary:"bg-theme-turquoise-secondary text-white",accent:"bg-theme-turquoise-accent text-white",border:"border-theme-turquoise-primary",text:"text-theme-turquoise-primary",gradient:"from-theme-turquoise-primary to-theme-turquoise-secondary",glass:"bg-theme-turquoise-primary/10 border-theme-turquoise-primary/30",hover:"hover:bg-theme-turquoise-primary/20",cssVars:{primary:"#06b6d4",secondary:"#22d3ee",accent:"#67e8f9"}}},r=t[e]||t.green;if(typeof document<"u"){const n=document.documentElement;n.style.setProperty("--theme-primary",r.cssVars.primary),n.style.setProperty("--theme-secondary",r.cssVars.secondary),n.style.setProperty("--theme-accent",r.cssVars.accent)}return r},Ms=e=>({green:120,pink:300,blue:360,red:245,purple:280,yellow:200,turquoise:40})[e]||120;function As(e){let t=e[0],r=e[1],n=e[2];return Math.sqrt(t*t+r*r+n*n)}function yu(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}function z3(e,t,r,n){return e[0]=t,e[1]=r,e[2]=n,e}function jh(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e}function Ch(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e}function O3(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e[2]=t[2]*r[2],e}function $3(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e[2]=t[2]/r[2],e}function Ja(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e}function B3(e,t){let r=t[0]-e[0],n=t[1]-e[1],s=t[2]-e[2];return Math.sqrt(r*r+n*n+s*s)}function U3(e,t){let r=t[0]-e[0],n=t[1]-e[1],s=t[2]-e[2];return r*r+n*n+s*s}function Nh(e){let t=e[0],r=e[1],n=e[2];return t*t+r*r+n*n}function W3(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e}function H3(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e}function vu(e,t){let r=t[0],n=t[1],s=t[2],i=r*r+n*n+s*s;return i>0&&(i=1/Math.sqrt(i)),e[0]=t[0]*i,e[1]=t[1]*i,e[2]=t[2]*i,e}function ey(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function Ph(e,t,r){let n=t[0],s=t[1],i=t[2],o=r[0],a=r[1],l=r[2];return e[0]=s*l-i*a,e[1]=i*o-n*l,e[2]=n*a-s*o,e}function q3(e,t,r,n){let s=t[0],i=t[1],o=t[2];return e[0]=s+n*(r[0]-s),e[1]=i+n*(r[1]-i),e[2]=o+n*(r[2]-o),e}function G3(e,t,r,n,s){const i=Math.exp(-n*s);let o=t[0],a=t[1],l=t[2];return e[0]=r[0]+(o-r[0])*i,e[1]=r[1]+(a-r[1])*i,e[2]=r[2]+(l-r[2])*i,e}function Y3(e,t,r){let n=t[0],s=t[1],i=t[2],o=r[3]*n+r[7]*s+r[11]*i+r[15];return o=o||1,e[0]=(r[0]*n+r[4]*s+r[8]*i+r[12])/o,e[1]=(r[1]*n+r[5]*s+r[9]*i+r[13])/o,e[2]=(r[2]*n+r[6]*s+r[10]*i+r[14])/o,e}function K3(e,t,r){let n=t[0],s=t[1],i=t[2],o=r[3]*n+r[7]*s+r[11]*i+r[15];return o=o||1,e[0]=(r[0]*n+r[4]*s+r[8]*i)/o,e[1]=(r[1]*n+r[5]*s+r[9]*i)/o,e[2]=(r[2]*n+r[6]*s+r[10]*i)/o,e}function X3(e,t,r){let n=t[0],s=t[1],i=t[2];return e[0]=n*r[0]+s*r[3]+i*r[6],e[1]=n*r[1]+s*r[4]+i*r[7],e[2]=n*r[2]+s*r[5]+i*r[8],e}function Q3(e,t,r){let n=t[0],s=t[1],i=t[2],o=r[0],a=r[1],l=r[2],c=r[3],d=a*i-l*s,f=l*n-o*i,u=o*s-a*n,p=a*u-l*f,m=l*d-o*u,g=o*f-a*d,w=c*2;return d*=w,f*=w,u*=w,p*=2,m*=2,g*=2,e[0]=n+d+p,e[1]=s+f+m,e[2]=i+u+g,e}const Z3=function(){const e=[0,0,0],t=[0,0,0];return function(r,n){yu(e,r),yu(t,n),vu(e,e),vu(t,t);let s=ey(e,t);return s>1?0:s<-1?Math.PI:Math.acos(s)}}();function J3(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]}class vt extends Array{constructor(t=0,r=t,n=t){return super(t,r,n),this}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}set x(t){this[0]=t}set y(t){this[1]=t}set z(t){this[2]=t}set(t,r=t,n=t){return t.length?this.copy(t):(z3(this,t,r,n),this)}copy(t){return yu(this,t),this}add(t,r){return r?jh(this,t,r):jh(this,this,t),this}sub(t,r){return r?Ch(this,t,r):Ch(this,this,t),this}multiply(t){return t.length?O3(this,this,t):Ja(this,this,t),this}divide(t){return t.length?$3(this,this,t):Ja(this,this,1/t),this}inverse(t=this){return H3(this,t),this}len(){return As(this)}distance(t){return t?B3(this,t):As(this)}squaredLen(){return Nh(this)}squaredDistance(t){return t?U3(this,t):Nh(this)}negate(t=this){return W3(this,t),this}cross(t,r){return r?Ph(this,t,r):Ph(this,this,t),this}scale(t){return Ja(this,this,t),this}normalize(){return vu(this,this),this}dot(t){return ey(this,t)}equals(t){return J3(this,t)}applyMatrix3(t){return X3(this,this,t),this}applyMatrix4(t){return Y3(this,this,t),this}scaleRotateMatrix4(t){return K3(this,this,t),this}applyQuaternion(t){return Q3(this,this,t),this}angle(t){return Z3(this,t)}lerp(t,r){return q3(this,this,t,r),this}smoothLerp(t,r,n){return G3(this,this,t,r,n),this}clone(){return new vt(this[0],this[1],this[2])}fromArray(t,r=0){return this[0]=t[r],this[1]=t[r+1],this[2]=t[r+2],this}toArray(t=[],r=0){return t[r]=this[0],t[r+1]=this[1],t[r+2]=this[2],t}transformDirection(t){const r=this[0],n=this[1],s=this[2];return this[0]=t[0]*r+t[4]*n+t[8]*s,this[1]=t[1]*r+t[5]*n+t[9]*s,this[2]=t[2]*r+t[6]*n+t[10]*s,this.normalize()}}const Eh=new vt;let eS=1,tS=1,Th=!1;class rS{constructor(t,r={}){t.canvas||console.error("gl not passed as first argument to Geometry"),this.gl=t,this.attributes=r,this.id=eS++,this.VAOs={},this.drawRange={start:0,count:0},this.instancedCount=0,this.gl.renderer.bindVertexArray(null),this.gl.renderer.currentGeometry=null,this.glState=this.gl.renderer.state;for(let n in r)this.addAttribute(n,r[n])}addAttribute(t,r){if(this.attributes[t]=r,r.id=tS++,r.size=r.size||1,r.type=r.type||(r.data.constructor===Float32Array?this.gl.FLOAT:r.data.constructor===Uint16Array?this.gl.UNSIGNED_SHORT:this.gl.UNSIGNED_INT),r.target=t==="index"?this.gl.ELEMENT_ARRAY_BUFFER:this.gl.ARRAY_BUFFER,r.normalized=r.normalized||!1,r.stride=r.stride||0,r.offset=r.offset||0,r.count=r.count||(r.stride?r.data.byteLength/r.stride:r.data.length/r.size),r.divisor=r.instanced||0,r.needsUpdate=!1,r.usage=r.usage||this.gl.STATIC_DRAW,r.buffer||this.updateAttribute(r),r.divisor){if(this.isInstanced=!0,this.instancedCount&&this.instancedCount!==r.count*r.divisor)return console.warn("geometry has multiple instanced buffers of different length"),this.instancedCount=Math.min(this.instancedCount,r.count*r.divisor);this.instancedCount=r.count*r.divisor}else t==="index"?this.drawRange.count=r.count:this.attributes.index||(this.drawRange.count=Math.max(this.drawRange.count,r.count))}updateAttribute(t){const r=!t.buffer;r&&(t.buffer=this.gl.createBuffer()),this.glState.boundBuffer!==t.buffer&&(this.gl.bindBuffer(t.target,t.buffer),this.glState.boundBuffer=t.buffer),r?this.gl.bufferData(t.target,t.data,t.usage):this.gl.bufferSubData(t.target,0,t.data),t.needsUpdate=!1}setIndex(t){this.addAttribute("index",t)}setDrawRange(t,r){this.drawRange.start=t,this.drawRange.count=r}setInstancedCount(t){this.instancedCount=t}createVAO(t){this.VAOs[t.attributeOrder]=this.gl.renderer.createVertexArray(),this.gl.renderer.bindVertexArray(this.VAOs[t.attributeOrder]),this.bindAttributes(t)}bindAttributes(t){t.attributeLocations.forEach((r,{name:n,type:s})=>{if(!this.attributes[n]){console.warn(`active attribute ${n} not being supplied`);return}const i=this.attributes[n];this.gl.bindBuffer(i.target,i.buffer),this.glState.boundBuffer=i.buffer;let o=1;s===35674&&(o=2),s===35675&&(o=3),s===35676&&(o=4);const a=i.size/o,l=o===1?0:o*o*4,c=o===1?0:o*4;for(let d=0;d{const a=this.attributes[o];a.needsUpdate&&this.updateAttribute(a)});let n=2;((s=this.attributes.index)==null?void 0:s.type)===this.gl.UNSIGNED_INT&&(n=4),this.isInstanced?this.attributes.index?this.gl.renderer.drawElementsInstanced(r,this.drawRange.count,this.attributes.index.type,this.attributes.index.offset+this.drawRange.start*n,this.instancedCount):this.gl.renderer.drawArraysInstanced(r,this.drawRange.start,this.drawRange.count,this.instancedCount):this.attributes.index?this.gl.drawElements(r,this.drawRange.count,this.attributes.index.type,this.attributes.index.offset+this.drawRange.start*n):this.gl.drawArrays(r,this.drawRange.start,this.drawRange.count)}getPosition(){const t=this.attributes.position;if(t.data)return t;if(!Th)return console.warn("No position buffer data found to compute bounds"),Th=!0}computeBoundingBox(t){t||(t=this.getPosition());const r=t.data,n=t.size;this.bounds||(this.bounds={min:new vt,max:new vt,center:new vt,scale:new vt,radius:1/0});const s=this.bounds.min,i=this.bounds.max,o=this.bounds.center,a=this.bounds.scale;s.set(1/0),i.set(-1/0);for(let l=0,c=r.length;l{let o=this.uniforms[i.uniformName];for(const a of i.nameComponents){if(!o)break;if(a in o)o=o[a];else{if(Array.isArray(o.value))break;o=void 0;break}}if(!o)return _h(`Active uniform ${i.name} has not been supplied`);if(o&&o.value===void 0)return _h(`${i.name} uniform is missing a value parameter`);if(o.value.texture)return r=r+1,o.value.update(r),el(this.gl,i.type,s,r);if(o.value.length&&o.value[0].texture){const a=[];return o.value.forEach(l=>{r=r+1,l.update(r),a.push(r)}),el(this.gl,i.type,s,a)}el(this.gl,i.type,s,o.value)}),this.applyState(),t&&this.gl.renderer.setFrontFace(this.frontFace===this.gl.CCW?this.gl.CW:this.gl.CCW)}remove(){this.gl.deleteProgram(this.program)}}function el(e,t,r,n){n=n.length?iS(n):n;const s=e.renderer.state.uniformLocations.get(r);if(n.length)if(s===void 0||s.length!==n.length)e.renderer.state.uniformLocations.set(r,n.slice(0));else{if(oS(s,n))return;s.set?s.set(n):aS(s,n),e.renderer.state.uniformLocations.set(r,s)}else{if(s===n)return;e.renderer.state.uniformLocations.set(r,n)}switch(t){case 5126:return n.length?e.uniform1fv(r,n):e.uniform1f(r,n);case 35664:return e.uniform2fv(r,n);case 35665:return e.uniform3fv(r,n);case 35666:return e.uniform4fv(r,n);case 35670:case 5124:case 35678:case 36306:case 35680:case 36289:return n.length?e.uniform1iv(r,n):e.uniform1i(r,n);case 35671:case 35667:return e.uniform2iv(r,n);case 35672:case 35668:return e.uniform3iv(r,n);case 35673:case 35669:return e.uniform4iv(r,n);case 35674:return e.uniformMatrix2fv(r,!1,n);case 35675:return e.uniformMatrix3fv(r,!1,n);case 35676:return e.uniformMatrix4fv(r,!1,n)}}function Ah(e){let t=e.split(` +`);for(let r=0;r100||(console.warn(e),tl++,tl>100&&console.warn("More than 100 program warnings - stopping logs."))}const rl=new vt;let lS=1;class uS{constructor({canvas:t=document.createElement("canvas"),width:r=300,height:n=150,dpr:s=1,alpha:i=!1,depth:o=!0,stencil:a=!1,antialias:l=!1,premultipliedAlpha:c=!1,preserveDrawingBuffer:d=!1,powerPreference:f="default",autoClear:u=!0,webgl:p=2}={}){const m={alpha:i,depth:o,stencil:a,antialias:l,premultipliedAlpha:c,preserveDrawingBuffer:d,powerPreference:f};this.dpr=s,this.alpha=i,this.color=!0,this.depth=o,this.stencil=a,this.premultipliedAlpha=c,this.autoClear=u,this.id=lS++,p===2&&(this.gl=t.getContext("webgl2",m)),this.isWebgl2=!!this.gl,this.gl||(this.gl=t.getContext("webgl",m)),this.gl||console.error("unable to create webgl context"),this.gl.renderer=this,this.setSize(r,n),this.state={},this.state.blendFunc={src:this.gl.ONE,dst:this.gl.ZERO},this.state.blendEquation={modeRGB:this.gl.FUNC_ADD},this.state.cullFace=!1,this.state.frontFace=this.gl.CCW,this.state.depthMask=!0,this.state.depthFunc=this.gl.LEQUAL,this.state.premultiplyAlpha=!1,this.state.flipY=!1,this.state.unpackAlignment=4,this.state.framebuffer=null,this.state.viewport={x:0,y:0,width:null,height:null},this.state.textureUnits=[],this.state.activeTextureUnit=0,this.state.boundBuffer=null,this.state.uniformLocations=new Map,this.state.currentProgram=null,this.extensions={},this.isWebgl2?(this.getExtension("EXT_color_buffer_float"),this.getExtension("OES_texture_float_linear")):(this.getExtension("OES_texture_float"),this.getExtension("OES_texture_float_linear"),this.getExtension("OES_texture_half_float"),this.getExtension("OES_texture_half_float_linear"),this.getExtension("OES_element_index_uint"),this.getExtension("OES_standard_derivatives"),this.getExtension("EXT_sRGB"),this.getExtension("WEBGL_depth_texture"),this.getExtension("WEBGL_draw_buffers")),this.getExtension("WEBGL_compressed_texture_astc"),this.getExtension("EXT_texture_compression_bptc"),this.getExtension("WEBGL_compressed_texture_s3tc"),this.getExtension("WEBGL_compressed_texture_etc1"),this.getExtension("WEBGL_compressed_texture_pvrtc"),this.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),this.vertexAttribDivisor=this.getExtension("ANGLE_instanced_arrays","vertexAttribDivisor","vertexAttribDivisorANGLE"),this.drawArraysInstanced=this.getExtension("ANGLE_instanced_arrays","drawArraysInstanced","drawArraysInstancedANGLE"),this.drawElementsInstanced=this.getExtension("ANGLE_instanced_arrays","drawElementsInstanced","drawElementsInstancedANGLE"),this.createVertexArray=this.getExtension("OES_vertex_array_object","createVertexArray","createVertexArrayOES"),this.bindVertexArray=this.getExtension("OES_vertex_array_object","bindVertexArray","bindVertexArrayOES"),this.deleteVertexArray=this.getExtension("OES_vertex_array_object","deleteVertexArray","deleteVertexArrayOES"),this.drawBuffers=this.getExtension("WEBGL_draw_buffers","drawBuffers","drawBuffersWEBGL"),this.parameters={},this.parameters.maxTextureUnits=this.gl.getParameter(this.gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),this.parameters.maxAnisotropy=this.getExtension("EXT_texture_filter_anisotropic")?this.gl.getParameter(this.getExtension("EXT_texture_filter_anisotropic").MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}setSize(t,r){this.width=t,this.height=r,this.gl.canvas.width=t*this.dpr,this.gl.canvas.height=r*this.dpr,this.gl.canvas.style&&Object.assign(this.gl.canvas.style,{width:t+"px",height:r+"px"})}setViewport(t,r,n=0,s=0){this.state.viewport.width===t&&this.state.viewport.height===r||(this.state.viewport.width=t,this.state.viewport.height=r,this.state.viewport.x=n,this.state.viewport.y=s,this.gl.viewport(n,s,t,r))}setScissor(t,r,n=0,s=0){this.gl.scissor(n,s,t,r)}enable(t){this.state[t]!==!0&&(this.gl.enable(t),this.state[t]=!0)}disable(t){this.state[t]!==!1&&(this.gl.disable(t),this.state[t]=!1)}setBlendFunc(t,r,n,s){this.state.blendFunc.src===t&&this.state.blendFunc.dst===r&&this.state.blendFunc.srcAlpha===n&&this.state.blendFunc.dstAlpha===s||(this.state.blendFunc.src=t,this.state.blendFunc.dst=r,this.state.blendFunc.srcAlpha=n,this.state.blendFunc.dstAlpha=s,n!==void 0?this.gl.blendFuncSeparate(t,r,n,s):this.gl.blendFunc(t,r))}setBlendEquation(t,r){t=t||this.gl.FUNC_ADD,!(this.state.blendEquation.modeRGB===t&&this.state.blendEquation.modeAlpha===r)&&(this.state.blendEquation.modeRGB=t,this.state.blendEquation.modeAlpha=r,r!==void 0?this.gl.blendEquationSeparate(t,r):this.gl.blendEquation(t))}setCullFace(t){this.state.cullFace!==t&&(this.state.cullFace=t,this.gl.cullFace(t))}setFrontFace(t){this.state.frontFace!==t&&(this.state.frontFace=t,this.gl.frontFace(t))}setDepthMask(t){this.state.depthMask!==t&&(this.state.depthMask=t,this.gl.depthMask(t))}setDepthFunc(t){this.state.depthFunc!==t&&(this.state.depthFunc=t,this.gl.depthFunc(t))}setStencilMask(t){this.state.stencilMask!==t&&(this.state.stencilMask=t,this.gl.stencilMask(t))}setStencilFunc(t,r,n){this.state.stencilFunc===t&&this.state.stencilRef===r&&this.state.stencilFuncMask===n||(this.state.stencilFunc=t||this.gl.ALWAYS,this.state.stencilRef=r||0,this.state.stencilFuncMask=n||0,this.gl.stencilFunc(t||this.gl.ALWAYS,r||0,n||0))}setStencilOp(t,r,n){this.state.stencilFail===t&&this.state.stencilDepthFail===r&&this.state.stencilDepthPass===n||(this.state.stencilFail=t,this.state.stencilDepthFail=r,this.state.stencilDepthPass=n,this.gl.stencilOp(t,r,n))}activeTexture(t){this.state.activeTextureUnit!==t&&(this.state.activeTextureUnit=t,this.gl.activeTexture(this.gl.TEXTURE0+t))}bindFramebuffer({target:t=this.gl.FRAMEBUFFER,buffer:r=null}={}){this.state.framebuffer!==r&&(this.state.framebuffer=r,this.gl.bindFramebuffer(t,r))}getExtension(t,r,n){return r&&this.gl[r]?this.gl[r].bind(this.gl):(this.extensions[t]||(this.extensions[t]=this.gl.getExtension(t)),r?this.extensions[t]?this.extensions[t][n].bind(this.extensions[t]):null:this.extensions[t])}sortOpaque(t,r){return t.renderOrder!==r.renderOrder?t.renderOrder-r.renderOrder:t.program.id!==r.program.id?t.program.id-r.program.id:t.zDepth!==r.zDepth?t.zDepth-r.zDepth:r.id-t.id}sortTransparent(t,r){return t.renderOrder!==r.renderOrder?t.renderOrder-r.renderOrder:t.zDepth!==r.zDepth?r.zDepth-t.zDepth:r.id-t.id}sortUI(t,r){return t.renderOrder!==r.renderOrder?t.renderOrder-r.renderOrder:t.program.id!==r.program.id?t.program.id-r.program.id:r.id-t.id}getRenderList({scene:t,camera:r,frustumCull:n,sort:s}){let i=[];if(r&&n&&r.updateFrustum(),t.traverse(o=>{if(!o.visible)return!0;o.draw&&(n&&o.frustumCulled&&r&&!r.frustumIntersectsMesh(o)||i.push(o))}),s){const o=[],a=[],l=[];i.forEach(c=>{c.program.transparent?c.program.depthTest?a.push(c):l.push(c):o.push(c),c.zDepth=0,!(c.renderOrder!==0||!c.program.depthTest||!r)&&(c.worldMatrix.getTranslation(rl),rl.applyMatrix4(r.projectionViewMatrix),c.zDepth=rl.z)}),o.sort(this.sortOpaque),a.sort(this.sortTransparent),l.sort(this.sortUI),i=o.concat(a,l)}return i}render({scene:t,camera:r,target:n=null,update:s=!0,sort:i=!0,frustumCull:o=!0,clear:a}){n===null?(this.bindFramebuffer(),this.setViewport(this.width*this.dpr,this.height*this.dpr)):(this.bindFramebuffer(n),this.setViewport(n.width,n.height)),(a||this.autoClear&&a!==!1)&&(this.depth&&(!n||n.depth)&&(this.enable(this.gl.DEPTH_TEST),this.setDepthMask(!0)),(this.stencil||!n||n.stencil)&&(this.enable(this.gl.STENCIL_TEST),this.setStencilMask(255)),this.gl.clear((this.color?this.gl.COLOR_BUFFER_BIT:0)|(this.depth?this.gl.DEPTH_BUFFER_BIT:0)|(this.stencil?this.gl.STENCIL_BUFFER_BIT:0))),s&&t.updateMatrixWorld(),r&&r.updateMatrixWorld(),this.getRenderList({scene:t,camera:r,frustumCull:o,sort:i}).forEach(c=>{c.draw({camera:r})})}}function cS(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}function dS(e,t,r,n,s){return e[0]=t,e[1]=r,e[2]=n,e[3]=s,e}function fS(e,t){let r=t[0],n=t[1],s=t[2],i=t[3],o=r*r+n*n+s*s+i*i;return o>0&&(o=1/Math.sqrt(o)),e[0]=r*o,e[1]=n*o,e[2]=s*o,e[3]=i*o,e}function hS(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]}function pS(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}function mS(e,t,r){r=r*.5;let n=Math.sin(r);return e[0]=n*t[0],e[1]=n*t[1],e[2]=n*t[2],e[3]=Math.cos(r),e}function Lh(e,t,r){let n=t[0],s=t[1],i=t[2],o=t[3],a=r[0],l=r[1],c=r[2],d=r[3];return e[0]=n*d+o*a+s*c-i*l,e[1]=s*d+o*l+i*a-n*c,e[2]=i*d+o*c+n*l-s*a,e[3]=o*d-n*a-s*l-i*c,e}function gS(e,t,r){r*=.5;let n=t[0],s=t[1],i=t[2],o=t[3],a=Math.sin(r),l=Math.cos(r);return e[0]=n*l+o*a,e[1]=s*l+i*a,e[2]=i*l-s*a,e[3]=o*l-n*a,e}function yS(e,t,r){r*=.5;let n=t[0],s=t[1],i=t[2],o=t[3],a=Math.sin(r),l=Math.cos(r);return e[0]=n*l-i*a,e[1]=s*l+o*a,e[2]=i*l+n*a,e[3]=o*l-s*a,e}function vS(e,t,r){r*=.5;let n=t[0],s=t[1],i=t[2],o=t[3],a=Math.sin(r),l=Math.cos(r);return e[0]=n*l+s*a,e[1]=s*l-n*a,e[2]=i*l+o*a,e[3]=o*l-i*a,e}function xS(e,t,r,n){let s=t[0],i=t[1],o=t[2],a=t[3],l=r[0],c=r[1],d=r[2],f=r[3],u,p,m,g,w;return p=s*l+i*c+o*d+a*f,p<0&&(p=-p,l=-l,c=-c,d=-d,f=-f),1-p>1e-6?(u=Math.acos(p),m=Math.sin(u),g=Math.sin((1-n)*u)/m,w=Math.sin(n*u)/m):(g=1-n,w=n),e[0]=g*s+w*l,e[1]=g*i+w*c,e[2]=g*o+w*d,e[3]=g*a+w*f,e}function wS(e,t){let r=t[0],n=t[1],s=t[2],i=t[3],o=r*r+n*n+s*s+i*i,a=o?1/o:0;return e[0]=-r*a,e[1]=-n*a,e[2]=-s*a,e[3]=i*a,e}function bS(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e}function SS(e,t){let r=t[0]+t[4]+t[8],n;if(r>0)n=Math.sqrt(r+1),e[3]=.5*n,n=.5/n,e[0]=(t[5]-t[7])*n,e[1]=(t[6]-t[2])*n,e[2]=(t[1]-t[3])*n;else{let s=0;t[4]>t[0]&&(s=1),t[8]>t[s*3+s]&&(s=2);let i=(s+1)%3,o=(s+2)%3;n=Math.sqrt(t[s*3+s]-t[i*3+i]-t[o*3+o]+1),e[s]=.5*n,n=.5/n,e[3]=(t[i*3+o]-t[o*3+i])*n,e[i]=(t[i*3+s]+t[s*3+i])*n,e[o]=(t[o*3+s]+t[s*3+o])*n}return e}function kS(e,t,r="YXZ"){let n=Math.sin(t[0]*.5),s=Math.cos(t[0]*.5),i=Math.sin(t[1]*.5),o=Math.cos(t[1]*.5),a=Math.sin(t[2]*.5),l=Math.cos(t[2]*.5);return r==="XYZ"?(e[0]=n*o*l+s*i*a,e[1]=s*i*l-n*o*a,e[2]=s*o*a+n*i*l,e[3]=s*o*l-n*i*a):r==="YXZ"?(e[0]=n*o*l+s*i*a,e[1]=s*i*l-n*o*a,e[2]=s*o*a-n*i*l,e[3]=s*o*l+n*i*a):r==="ZXY"?(e[0]=n*o*l-s*i*a,e[1]=s*i*l+n*o*a,e[2]=s*o*a+n*i*l,e[3]=s*o*l-n*i*a):r==="ZYX"?(e[0]=n*o*l-s*i*a,e[1]=s*i*l+n*o*a,e[2]=s*o*a-n*i*l,e[3]=s*o*l+n*i*a):r==="YZX"?(e[0]=n*o*l+s*i*a,e[1]=s*i*l+n*o*a,e[2]=s*o*a-n*i*l,e[3]=s*o*l-n*i*a):r==="XZY"&&(e[0]=n*o*l-s*i*a,e[1]=s*i*l-n*o*a,e[2]=s*o*a+n*i*l,e[3]=s*o*l+n*i*a),e}const jS=cS,CS=dS,NS=hS,PS=fS;class ES extends Array{constructor(t=0,r=0,n=0,s=1){super(t,r,n,s),this.onChange=()=>{},this._target=this;const i=["0","1","2","3"];return new Proxy(this,{set(o,a){const l=Reflect.set(...arguments);return l&&i.includes(a)&&o.onChange(),l}})}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}get w(){return this[3]}set x(t){this._target[0]=t,this.onChange()}set y(t){this._target[1]=t,this.onChange()}set z(t){this._target[2]=t,this.onChange()}set w(t){this._target[3]=t,this.onChange()}identity(){return pS(this._target),this.onChange(),this}set(t,r,n,s){return t.length?this.copy(t):(CS(this._target,t,r,n,s),this.onChange(),this)}rotateX(t){return gS(this._target,this._target,t),this.onChange(),this}rotateY(t){return yS(this._target,this._target,t),this.onChange(),this}rotateZ(t){return vS(this._target,this._target,t),this.onChange(),this}inverse(t=this._target){return wS(this._target,t),this.onChange(),this}conjugate(t=this._target){return bS(this._target,t),this.onChange(),this}copy(t){return jS(this._target,t),this.onChange(),this}normalize(t=this._target){return PS(this._target,t),this.onChange(),this}multiply(t,r){return r?Lh(this._target,t,r):Lh(this._target,this._target,t),this.onChange(),this}dot(t){return NS(this._target,t)}fromMatrix3(t){return SS(this._target,t),this.onChange(),this}fromEuler(t,r){return kS(this._target,t,t.order),r||this.onChange(),this}fromAxisAngle(t,r){return mS(this._target,t,r),this.onChange(),this}slerp(t,r){return xS(this._target,this._target,t,r),this.onChange(),this}fromArray(t,r=0){return this._target[0]=t[r],this._target[1]=t[r+1],this._target[2]=t[r+2],this._target[3]=t[r+3],this.onChange(),this}toArray(t=[],r=0){return t[r]=this[0],t[r+1]=this[1],t[r+2]=this[2],t[r+3]=this[3],t}}const TS=1e-6;function MS(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function AS(e,t,r,n,s,i,o,a,l,c,d,f,u,p,m,g,w){return e[0]=t,e[1]=r,e[2]=n,e[3]=s,e[4]=i,e[5]=o,e[6]=a,e[7]=l,e[8]=c,e[9]=d,e[10]=f,e[11]=u,e[12]=p,e[13]=m,e[14]=g,e[15]=w,e}function _S(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function LS(e,t){let r=t[0],n=t[1],s=t[2],i=t[3],o=t[4],a=t[5],l=t[6],c=t[7],d=t[8],f=t[9],u=t[10],p=t[11],m=t[12],g=t[13],w=t[14],v=t[15],y=r*a-n*o,x=r*l-s*o,b=r*c-i*o,k=n*l-s*a,C=n*c-i*a,N=s*c-i*l,P=d*g-f*m,V=d*w-u*m,T=d*v-p*m,O=f*w-u*g,j=f*v-p*g,F=u*v-p*w,D=y*F-x*j+b*O+k*T-C*V+N*P;return D?(D=1/D,e[0]=(a*F-l*j+c*O)*D,e[1]=(s*j-n*F-i*O)*D,e[2]=(g*N-w*C+v*k)*D,e[3]=(u*C-f*N-p*k)*D,e[4]=(l*T-o*F-c*V)*D,e[5]=(r*F-s*T+i*V)*D,e[6]=(w*b-m*N-v*x)*D,e[7]=(d*N-u*b+p*x)*D,e[8]=(o*j-a*T+c*P)*D,e[9]=(n*T-r*j-i*P)*D,e[10]=(m*C-g*b+v*y)*D,e[11]=(f*b-d*C-p*y)*D,e[12]=(a*V-o*O-l*P)*D,e[13]=(r*O-n*V+s*P)*D,e[14]=(g*x-m*k-w*y)*D,e[15]=(d*k-f*x+u*y)*D,e):null}function ty(e){let t=e[0],r=e[1],n=e[2],s=e[3],i=e[4],o=e[5],a=e[6],l=e[7],c=e[8],d=e[9],f=e[10],u=e[11],p=e[12],m=e[13],g=e[14],w=e[15],v=t*o-r*i,y=t*a-n*i,x=t*l-s*i,b=r*a-n*o,k=r*l-s*o,C=n*l-s*a,N=c*m-d*p,P=c*g-f*p,V=c*w-u*p,T=d*g-f*m,O=d*w-u*m,j=f*w-u*g;return v*j-y*O+x*T+b*V-k*P+C*N}function Dh(e,t,r){let n=t[0],s=t[1],i=t[2],o=t[3],a=t[4],l=t[5],c=t[6],d=t[7],f=t[8],u=t[9],p=t[10],m=t[11],g=t[12],w=t[13],v=t[14],y=t[15],x=r[0],b=r[1],k=r[2],C=r[3];return e[0]=x*n+b*a+k*f+C*g,e[1]=x*s+b*l+k*u+C*w,e[2]=x*i+b*c+k*p+C*v,e[3]=x*o+b*d+k*m+C*y,x=r[4],b=r[5],k=r[6],C=r[7],e[4]=x*n+b*a+k*f+C*g,e[5]=x*s+b*l+k*u+C*w,e[6]=x*i+b*c+k*p+C*v,e[7]=x*o+b*d+k*m+C*y,x=r[8],b=r[9],k=r[10],C=r[11],e[8]=x*n+b*a+k*f+C*g,e[9]=x*s+b*l+k*u+C*w,e[10]=x*i+b*c+k*p+C*v,e[11]=x*o+b*d+k*m+C*y,x=r[12],b=r[13],k=r[14],C=r[15],e[12]=x*n+b*a+k*f+C*g,e[13]=x*s+b*l+k*u+C*w,e[14]=x*i+b*c+k*p+C*v,e[15]=x*o+b*d+k*m+C*y,e}function DS(e,t,r){let n=r[0],s=r[1],i=r[2],o,a,l,c,d,f,u,p,m,g,w,v;return t===e?(e[12]=t[0]*n+t[4]*s+t[8]*i+t[12],e[13]=t[1]*n+t[5]*s+t[9]*i+t[13],e[14]=t[2]*n+t[6]*s+t[10]*i+t[14],e[15]=t[3]*n+t[7]*s+t[11]*i+t[15]):(o=t[0],a=t[1],l=t[2],c=t[3],d=t[4],f=t[5],u=t[6],p=t[7],m=t[8],g=t[9],w=t[10],v=t[11],e[0]=o,e[1]=a,e[2]=l,e[3]=c,e[4]=d,e[5]=f,e[6]=u,e[7]=p,e[8]=m,e[9]=g,e[10]=w,e[11]=v,e[12]=o*n+d*s+m*i+t[12],e[13]=a*n+f*s+g*i+t[13],e[14]=l*n+u*s+w*i+t[14],e[15]=c*n+p*s+v*i+t[15]),e}function RS(e,t,r){let n=r[0],s=r[1],i=r[2];return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e[4]=t[4]*s,e[5]=t[5]*s,e[6]=t[6]*s,e[7]=t[7]*s,e[8]=t[8]*i,e[9]=t[9]*i,e[10]=t[10]*i,e[11]=t[11]*i,e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function VS(e,t,r,n){let s=n[0],i=n[1],o=n[2],a=Math.hypot(s,i,o),l,c,d,f,u,p,m,g,w,v,y,x,b,k,C,N,P,V,T,O,j,F,D,G;return Math.abs(a)0?(v=Math.sqrt(w+1)*2,t[3]=.25*v,t[0]=(u-m)/v,t[1]=(p-c)/v,t[2]=(l-d)/v):a>f&&a>g?(v=Math.sqrt(1+a-f-g)*2,t[3]=(u-m)/v,t[0]=.25*v,t[1]=(l+d)/v,t[2]=(p+c)/v):f>g?(v=Math.sqrt(1+f-a-g)*2,t[3]=(p-c)/v,t[0]=(l+d)/v,t[1]=.25*v,t[2]=(u+m)/v):(v=Math.sqrt(1+g-a-f)*2,t[3]=(l-d)/v,t[0]=(p+c)/v,t[1]=(u+m)/v,t[2]=.25*v),t}}();function zS(e,t,r,n){let s=As([e[0],e[1],e[2]]);const i=As([e[4],e[5],e[6]]),o=As([e[8],e[9],e[10]]);ty(e)<0&&(s=-s),r[0]=e[12],r[1]=e[13],r[2]=e[14];const l=e.slice(),c=1/s,d=1/i,f=1/o;l[0]*=c,l[1]*=c,l[2]*=c,l[4]*=d,l[5]*=d,l[6]*=d,l[8]*=f,l[9]*=f,l[10]*=f,ny(t,l),n[0]=s,n[1]=i,n[2]=o}function OS(e,t,r,n){const s=e,i=t[0],o=t[1],a=t[2],l=t[3],c=i+i,d=o+o,f=a+a,u=i*c,p=i*d,m=i*f,g=o*d,w=o*f,v=a*f,y=l*c,x=l*d,b=l*f,k=n[0],C=n[1],N=n[2];return s[0]=(1-(g+v))*k,s[1]=(p+b)*k,s[2]=(m-x)*k,s[3]=0,s[4]=(p-b)*C,s[5]=(1-(u+v))*C,s[6]=(w+y)*C,s[7]=0,s[8]=(m+x)*N,s[9]=(w-y)*N,s[10]=(1-(u+g))*N,s[11]=0,s[12]=r[0],s[13]=r[1],s[14]=r[2],s[15]=1,s}function $S(e,t){let r=t[0],n=t[1],s=t[2],i=t[3],o=r+r,a=n+n,l=s+s,c=r*o,d=n*o,f=n*a,u=s*o,p=s*a,m=s*l,g=i*o,w=i*a,v=i*l;return e[0]=1-f-m,e[1]=d+v,e[2]=u-w,e[3]=0,e[4]=d-v,e[5]=1-c-m,e[6]=p+g,e[7]=0,e[8]=u+w,e[9]=p-g,e[10]=1-c-f,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function BS(e,t,r,n,s){let i=1/Math.tan(t/2),o=1/(n-s);return e[0]=i/r,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=(s+n)*o,e[11]=-1,e[12]=0,e[13]=0,e[14]=2*s*n*o,e[15]=0,e}function US(e,t,r,n,s,i,o){let a=1/(t-r),l=1/(n-s),c=1/(i-o);return e[0]=-2*a,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*c,e[11]=0,e[12]=(t+r)*a,e[13]=(s+n)*l,e[14]=(o+i)*c,e[15]=1,e}function WS(e,t,r,n){let s=t[0],i=t[1],o=t[2],a=n[0],l=n[1],c=n[2],d=s-r[0],f=i-r[1],u=o-r[2],p=d*d+f*f+u*u;p===0?u=1:(p=1/Math.sqrt(p),d*=p,f*=p,u*=p);let m=l*u-c*f,g=c*d-a*u,w=a*f-l*d;return p=m*m+g*g+w*w,p===0&&(c?a+=1e-6:l?c+=1e-6:l+=1e-6,m=l*u-c*f,g=c*d-a*u,w=a*f-l*d,p=m*m+g*g+w*w),p=1/Math.sqrt(p),m*=p,g*=p,w*=p,e[0]=m,e[1]=g,e[2]=w,e[3]=0,e[4]=f*w-u*g,e[5]=u*m-d*w,e[6]=d*g-f*m,e[7]=0,e[8]=d,e[9]=f,e[10]=u,e[11]=0,e[12]=s,e[13]=i,e[14]=o,e[15]=1,e}function Rh(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e[4]=t[4]+r[4],e[5]=t[5]+r[5],e[6]=t[6]+r[6],e[7]=t[7]+r[7],e[8]=t[8]+r[8],e[9]=t[9]+r[9],e[10]=t[10]+r[10],e[11]=t[11]+r[11],e[12]=t[12]+r[12],e[13]=t[13]+r[13],e[14]=t[14]+r[14],e[15]=t[15]+r[15],e}function Vh(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e[3]=t[3]-r[3],e[4]=t[4]-r[4],e[5]=t[5]-r[5],e[6]=t[6]-r[6],e[7]=t[7]-r[7],e[8]=t[8]-r[8],e[9]=t[9]-r[9],e[10]=t[10]-r[10],e[11]=t[11]-r[11],e[12]=t[12]-r[12],e[13]=t[13]-r[13],e[14]=t[14]-r[14],e[15]=t[15]-r[15],e}function HS(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*r,e[5]=t[5]*r,e[6]=t[6]*r,e[7]=t[7]*r,e[8]=t[8]*r,e[9]=t[9]*r,e[10]=t[10]*r,e[11]=t[11]*r,e[12]=t[12]*r,e[13]=t[13]*r,e[14]=t[14]*r,e[15]=t[15]*r,e}class Ro extends Array{constructor(t=1,r=0,n=0,s=0,i=0,o=1,a=0,l=0,c=0,d=0,f=1,u=0,p=0,m=0,g=0,w=1){return super(t,r,n,s,i,o,a,l,c,d,f,u,p,m,g,w),this}get x(){return this[12]}get y(){return this[13]}get z(){return this[14]}get w(){return this[15]}set x(t){this[12]=t}set y(t){this[13]=t}set z(t){this[14]=t}set w(t){this[15]=t}set(t,r,n,s,i,o,a,l,c,d,f,u,p,m,g,w){return t.length?this.copy(t):(AS(this,t,r,n,s,i,o,a,l,c,d,f,u,p,m,g,w),this)}translate(t,r=this){return DS(this,r,t),this}rotate(t,r,n=this){return VS(this,n,t,r),this}scale(t,r=this){return RS(this,r,typeof t=="number"?[t,t,t]:t),this}add(t,r){return r?Rh(this,t,r):Rh(this,this,t),this}sub(t,r){return r?Vh(this,t,r):Vh(this,this,t),this}multiply(t,r){return t.length?r?Dh(this,t,r):Dh(this,this,t):HS(this,this,t),this}identity(){return _S(this),this}copy(t){return MS(this,t),this}fromPerspective({fov:t,aspect:r,near:n,far:s}={}){return BS(this,t,r,n,s),this}fromOrthogonal({left:t,right:r,bottom:n,top:s,near:i,far:o}){return US(this,t,r,n,s,i,o),this}fromQuaternion(t){return $S(this,t),this}setPosition(t){return this.x=t[0],this.y=t[1],this.z=t[2],this}inverse(t=this){return LS(this,t),this}compose(t,r,n){return OS(this,t,r,n),this}decompose(t,r,n){return zS(this,t,r,n),this}getRotation(t){return ny(t,this),this}getTranslation(t){return FS(t,this),this}getScaling(t){return ry(t,this),this}getMaxScaleOnAxis(){return IS(this)}lookAt(t,r,n){return WS(this,t,r,n),this}determinant(){return ty(this)}fromArray(t,r=0){return this[0]=t[r],this[1]=t[r+1],this[2]=t[r+2],this[3]=t[r+3],this[4]=t[r+4],this[5]=t[r+5],this[6]=t[r+6],this[7]=t[r+7],this[8]=t[r+8],this[9]=t[r+9],this[10]=t[r+10],this[11]=t[r+11],this[12]=t[r+12],this[13]=t[r+13],this[14]=t[r+14],this[15]=t[r+15],this}toArray(t=[],r=0){return t[r]=this[0],t[r+1]=this[1],t[r+2]=this[2],t[r+3]=this[3],t[r+4]=this[4],t[r+5]=this[5],t[r+6]=this[6],t[r+7]=this[7],t[r+8]=this[8],t[r+9]=this[9],t[r+10]=this[10],t[r+11]=this[11],t[r+12]=this[12],t[r+13]=this[13],t[r+14]=this[14],t[r+15]=this[15],t}}function qS(e,t,r="YXZ"){return r==="XYZ"?(e[1]=Math.asin(Math.min(Math.max(t[8],-1),1)),Math.abs(t[8])<.99999?(e[0]=Math.atan2(-t[9],t[10]),e[2]=Math.atan2(-t[4],t[0])):(e[0]=Math.atan2(t[6],t[5]),e[2]=0)):r==="YXZ"?(e[0]=Math.asin(-Math.min(Math.max(t[9],-1),1)),Math.abs(t[9])<.99999?(e[1]=Math.atan2(t[8],t[10]),e[2]=Math.atan2(t[1],t[5])):(e[1]=Math.atan2(-t[2],t[0]),e[2]=0)):r==="ZXY"?(e[0]=Math.asin(Math.min(Math.max(t[6],-1),1)),Math.abs(t[6])<.99999?(e[1]=Math.atan2(-t[2],t[10]),e[2]=Math.atan2(-t[4],t[5])):(e[1]=0,e[2]=Math.atan2(t[1],t[0]))):r==="ZYX"?(e[1]=Math.asin(-Math.min(Math.max(t[2],-1),1)),Math.abs(t[2])<.99999?(e[0]=Math.atan2(t[6],t[10]),e[2]=Math.atan2(t[1],t[0])):(e[0]=0,e[2]=Math.atan2(-t[4],t[5]))):r==="YZX"?(e[2]=Math.asin(Math.min(Math.max(t[1],-1),1)),Math.abs(t[1])<.99999?(e[0]=Math.atan2(-t[9],t[5]),e[1]=Math.atan2(-t[2],t[0])):(e[0]=0,e[1]=Math.atan2(t[8],t[10]))):r==="XZY"&&(e[2]=Math.asin(-Math.min(Math.max(t[4],-1),1)),Math.abs(t[4])<.99999?(e[0]=Math.atan2(t[6],t[5]),e[1]=Math.atan2(t[8],t[0])):(e[0]=Math.atan2(-t[9],t[10]),e[1]=0)),e}const Fh=new Ro;class GS extends Array{constructor(t=0,r=t,n=t,s="YXZ"){super(t,r,n),this.order=s,this.onChange=()=>{},this._target=this;const i=["0","1","2"];return new Proxy(this,{set(o,a){const l=Reflect.set(...arguments);return l&&i.includes(a)&&o.onChange(),l}})}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}set x(t){this._target[0]=t,this.onChange()}set y(t){this._target[1]=t,this.onChange()}set z(t){this._target[2]=t,this.onChange()}set(t,r=t,n=t){return t.length?this.copy(t):(this._target[0]=t,this._target[1]=r,this._target[2]=n,this.onChange(),this)}copy(t){return this._target[0]=t[0],this._target[1]=t[1],this._target[2]=t[2],this.onChange(),this}reorder(t){return this._target.order=t,this.onChange(),this}fromRotationMatrix(t,r=this.order){return qS(this._target,t,r),this.onChange(),this}fromQuaternion(t,r=this.order,n){return Fh.fromQuaternion(t),this._target.fromRotationMatrix(Fh,r),n||this.onChange(),this}fromArray(t,r=0){return this._target[0]=t[r],this._target[1]=t[r+1],this._target[2]=t[r+2],this}toArray(t=[],r=0){return t[r]=this[0],t[r+1]=this[1],t[r+2]=this[2],t}}class YS{constructor(){this.parent=null,this.children=[],this.visible=!0,this.matrix=new Ro,this.worldMatrix=new Ro,this.matrixAutoUpdate=!0,this.worldMatrixNeedsUpdate=!1,this.position=new vt,this.quaternion=new ES,this.scale=new vt(1),this.rotation=new GS,this.up=new vt(0,1,0),this.rotation._target.onChange=()=>this.quaternion.fromEuler(this.rotation,!0),this.quaternion._target.onChange=()=>this.rotation.fromQuaternion(this.quaternion,void 0,!0)}setParent(t,r=!0){this.parent&&t!==this.parent&&this.parent.removeChild(this,!1),this.parent=t,r&&t&&t.addChild(this,!1)}addChild(t,r=!0){~this.children.indexOf(t)||this.children.push(t),r&&t.setParent(this,!1)}removeChild(t,r=!0){~this.children.indexOf(t)&&this.children.splice(this.children.indexOf(t),1),r&&t.setParent(null,!1)}updateMatrixWorld(t){this.matrixAutoUpdate&&this.updateMatrix(),(this.worldMatrixNeedsUpdate||t)&&(this.parent===null?this.worldMatrix.copy(this.matrix):this.worldMatrix.multiply(this.parent.worldMatrix,this.matrix),this.worldMatrixNeedsUpdate=!1,t=!0);for(let r=0,n=this.children.length;rn&&n({mesh:this,camera:t}));let r=this.program.cullFace&&this.worldMatrix.determinant()<0;this.program.use({flipFaces:r}),this.geometry.draw({mode:this.mode,program:this.program}),this.afterRenderCallbacks.forEach(n=>n&&n({mesh:this,camera:t}))}}function lk(e,t){return e[0]=t[0],e[1]=t[1],e}function uk(e,t,r){return e[0]=t,e[1]=r,e}function zh(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e}function Oh(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e}function ck(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e}function dk(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e}function nl(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e}function fk(e,t){var r=t[0]-e[0],n=t[1]-e[1];return Math.sqrt(r*r+n*n)}function hk(e,t){var r=t[0]-e[0],n=t[1]-e[1];return r*r+n*n}function $h(e){var t=e[0],r=e[1];return Math.sqrt(t*t+r*r)}function pk(e){var t=e[0],r=e[1];return t*t+r*r}function mk(e,t){return e[0]=-t[0],e[1]=-t[1],e}function gk(e,t){return e[0]=1/t[0],e[1]=1/t[1],e}function yk(e,t){var r=t[0],n=t[1],s=r*r+n*n;return s>0&&(s=1/Math.sqrt(s)),e[0]=t[0]*s,e[1]=t[1]*s,e}function vk(e,t){return e[0]*t[0]+e[1]*t[1]}function Bh(e,t){return e[0]*t[1]-e[1]*t[0]}function xk(e,t,r,n){var s=t[0],i=t[1];return e[0]=s+n*(r[0]-s),e[1]=i+n*(r[1]-i),e}function wk(e,t,r,n,s){const i=Math.exp(-n*s);let o=t[0],a=t[1];return e[0]=r[0]+(o-r[0])*i,e[1]=r[1]+(a-r[1])*i,e}function bk(e,t,r){var n=t[0],s=t[1];return e[0]=r[0]*n+r[3]*s+r[6],e[1]=r[1]*n+r[4]*s+r[7],e}function Sk(e,t,r){let n=t[0],s=t[1];return e[0]=r[0]*n+r[4]*s+r[12],e[1]=r[1]*n+r[5]*s+r[13],e}function kk(e,t){return e[0]===t[0]&&e[1]===t[1]}class Bc extends Array{constructor(t=0,r=t){return super(t,r),this}get x(){return this[0]}get y(){return this[1]}set x(t){this[0]=t}set y(t){this[1]=t}set(t,r=t){return t.length?this.copy(t):(uk(this,t,r),this)}copy(t){return lk(this,t),this}add(t,r){return r?zh(this,t,r):zh(this,this,t),this}sub(t,r){return r?Oh(this,t,r):Oh(this,this,t),this}multiply(t){return t.length?ck(this,this,t):nl(this,this,t),this}divide(t){return t.length?dk(this,this,t):nl(this,this,1/t),this}inverse(t=this){return gk(this,t),this}len(){return $h(this)}distance(t){return t?fk(this,t):$h(this)}squaredLen(){return this.squaredDistance()}squaredDistance(t){return t?hk(this,t):pk(this)}negate(t=this){return mk(this,t),this}cross(t,r){return r?Bh(t,r):Bh(this,t)}scale(t){return nl(this,this,t),this}normalize(){return yk(this,this),this}dot(t){return vk(this,t)}equals(t){return kk(this,t)}applyMatrix3(t){return bk(this,this,t),this}applyMatrix4(t){return Sk(this,this,t),this}lerp(t,r){return xk(this,this,t,r),this}smoothLerp(t,r,n){return wk(this,this,t,r,n),this}clone(){return new Bc(this[0],this[1])}fromArray(t,r=0){return this[0]=t[r],this[1]=t[r+1],this}toArray(t=[],r=0){return t[r]=this[0],t[r+1]=this[1],t}}class jk extends rS{constructor(t,{attributes:r={}}={}){Object.assign(r,{position:{size:2,data:new Float32Array([-1,-1,3,-1,-1,3])},uv:{size:2,data:new Float32Array([0,0,2,0,0,2])}}),super(t,r)}}const Ck=` +attribute vec2 position; +void main(){gl_Position=vec4(position,0.0,1.0);} +`,Nk=` +#ifdef GL_ES +precision lowp float; +#endif +uniform vec2 uResolution; +uniform float uTime; +uniform float uHueShift; +uniform float uNoise; +uniform float uScan; +uniform float uScanFreq; +uniform float uWarp; +#define iTime uTime +#define iResolution uResolution + +vec4 buf[8]; +float rand(vec2 c){return fract(sin(dot(c,vec2(12.9898,78.233)))*43758.5453);} + +mat3 rgb2yiq=mat3(0.299,0.587,0.114,0.596,-0.274,-0.322,0.211,-0.523,0.312); +mat3 yiq2rgb=mat3(1.0,0.956,0.621,1.0,-0.272,-0.647,1.0,-1.106,1.703); + +vec3 hueShiftRGB(vec3 col,float deg){ + vec3 yiq=rgb2yiq*col; + float rad=radians(deg); + float cosh=cos(rad),sinh=sin(rad); + vec3 yiqShift=vec3(yiq.x,yiq.y*cosh-yiq.z*sinh,yiq.y*sinh+yiq.z*cosh); + return clamp(yiq2rgb*yiqShift,0.0,1.0); +} + +vec4 sigmoid(vec4 x){return 1./(1.+exp(-x));} + +vec4 cppn_fn(vec2 coordinate,float in0,float in1,float in2){ + buf[6]=vec4(coordinate.x,coordinate.y,0.3948333106474662+in0,0.36+in1); + buf[7]=vec4(0.14+in2,sqrt(coordinate.x*coordinate.x+coordinate.y*coordinate.y),0.,0.); + buf[0]=mat4(vec4(6.5404263,-3.6126034,0.7590882,-1.13613),vec4(2.4582713,3.1660357,1.2219609,0.06276096),vec4(-5.478085,-6.159632,1.8701609,-4.7742867),vec4(6.039214,-5.542865,-0.90925294,3.251348))*buf[6]+mat4(vec4(0.8473259,-5.722911,3.975766,1.6522468),vec4(-0.24321538,0.5839259,-1.7661959,-5.350116),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(0.21808943,1.1243913,-1.7969975,5.0294676); + buf[1]=mat4(vec4(-3.3522482,-6.0612736,0.55641043,-4.4719114),vec4(0.8631464,1.7432913,5.643898,1.6106541),vec4(2.4941394,-3.5012043,1.7184316,6.357333),vec4(3.310376,8.209261,1.1355612,-1.165539))*buf[6]+mat4(vec4(5.24046,-13.034365,0.009859298,15.870829),vec4(2.987511,3.129433,-0.89023495,-1.6822904),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(-5.9457836,-6.573602,-0.8812491,1.5436668); + buf[0]=sigmoid(buf[0]);buf[1]=sigmoid(buf[1]); + buf[2]=mat4(vec4(-15.219568,8.095543,-2.429353,-1.9381982),vec4(-5.951362,4.3115187,2.6393783,1.274315),vec4(-7.3145227,6.7297835,5.2473326,5.9411426),vec4(5.0796127,8.979051,-1.7278991,-1.158976))*buf[6]+mat4(vec4(-11.967154,-11.608155,6.1486754,11.237008),vec4(2.124141,-6.263192,-1.7050359,-0.7021966),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(-4.17164,-3.2281182,-4.576417,-3.6401186); + buf[3]=mat4(vec4(3.1832156,-13.738922,1.879223,3.233465),vec4(0.64300746,12.768129,1.9141049,0.50990224),vec4(-0.049295485,4.4807224,1.4733979,1.801449),vec4(5.0039253,13.000481,3.3991797,-4.5561905))*buf[6]+mat4(vec4(-0.1285731,7.720628,-3.1425676,4.742367),vec4(0.6393625,3.714393,-0.8108378,-0.39174938),vec4(0.,0.,0.,0.),vec4(0.,0.,0.,0.))*buf[7]+vec4(-1.1811101,-21.621881,0.7851888,1.2329718); + buf[2]=sigmoid(buf[2]);buf[3]=sigmoid(buf[3]); + buf[4]=mat4(vec4(5.214916,-7.183024,2.7228765,2.6592617),vec4(-5.601878,-25.3591,4.067988,0.4602802),vec4(-10.57759,24.286327,21.102104,37.546658),vec4(4.3024497,-1.9625226,2.3458803,-1.372816))*buf[0]+mat4(vec4(-17.6526,-10.507558,2.2587414,12.462782),vec4(6.265566,-502.75443,-12.642513,0.9112289),vec4(-10.983244,20.741234,-9.701768,-0.7635988),vec4(5.383626,1.4819539,-4.1911616,-4.8444734))*buf[1]+mat4(vec4(12.785233,-16.345072,-0.39901125,1.7955981),vec4(-30.48365,-1.8345358,1.4542528,-1.1118771),vec4(19.872723,-7.337935,-42.941723,-98.52709),vec4(8.337645,-2.7312303,-2.2927687,-36.142323))*buf[2]+mat4(vec4(-16.298317,3.5471997,-0.44300047,-9.444417),vec4(57.5077,-35.609753,16.163465,-4.1534753),vec4(-0.07470326,-3.8656476,-7.0901804,3.1523974),vec4(-12.559385,-7.077619,1.490437,-0.8211543))*buf[3]+vec4(-7.67914,15.927437,1.3207729,-1.6686112); + buf[5]=mat4(vec4(-1.4109162,-0.372762,-3.770383,-21.367174),vec4(-6.2103205,-9.35908,0.92529047,8.82561),vec4(11.460242,-22.348068,13.625772,-18.693201),vec4(-0.3429052,-3.9905605,-2.4626114,-0.45033523))*buf[0]+mat4(vec4(7.3481627,-4.3661838,-6.3037653,-3.868115),vec4(1.5462853,6.5488915,1.9701879,-0.58291394),vec4(6.5858274,-2.2180402,3.7127688,-1.3730392),vec4(-5.7973905,10.134961,-2.3395722,-5.965605))*buf[1]+mat4(vec4(-2.5132585,-6.6685553,-1.4029363,-0.16285264),vec4(-0.37908727,0.53738135,4.389061,-1.3024765),vec4(-0.70647055,2.0111287,-5.1659346,-3.728635),vec4(-13.562562,10.487719,-0.9173751,-2.6487076))*buf[2]+mat4(vec4(-8.645013,6.5546675,-6.3944063,-5.5933375),vec4(-0.57783127,-1.077275,36.91025,5.736769),vec4(14.283112,3.7146652,7.1452246,-4.5958776),vec4(2.7192075,3.6021907,-4.366337,-2.3653464))*buf[3]+vec4(-5.9000807,-4.329569,1.2427121,8.59503); + buf[4]=sigmoid(buf[4]);buf[5]=sigmoid(buf[5]); + buf[6]=mat4(vec4(-1.61102,0.7970257,1.4675229,0.20917463),vec4(-28.793737,-7.1390953,1.5025433,4.656581),vec4(-10.94861,39.66238,0.74318546,-10.095605),vec4(-0.7229728,-1.5483948,0.7301322,2.1687684))*buf[0]+mat4(vec4(3.2547753,21.489103,-1.0194173,-3.3100595),vec4(-3.7316632,-3.3792162,-7.223193,-0.23685838),vec4(13.1804495,0.7916005,5.338587,5.687114),vec4(-4.167605,-17.798311,-6.815736,-1.6451967))*buf[1]+mat4(vec4(0.604885,-7.800309,-7.213122,-2.741014),vec4(-3.522382,-0.12359311,-0.5258442,0.43852118),vec4(9.6752825,-22.853785,2.062431,0.099892326),vec4(-4.3196306,-17.730087,2.5184598,5.30267))*buf[2]+mat4(vec4(-6.545563,-15.790176,-6.0438633,-5.415399),vec4(-43.591583,28.551912,-16.00161,18.84728),vec4(4.212382,8.394307,3.0958717,8.657522),vec4(-5.0237565,-4.450633,-4.4768,-5.5010443))*buf[3]+mat4(vec4(1.6985557,-67.05806,6.897715,1.9004834),vec4(1.8680354,2.3915145,2.5231109,4.081538),vec4(11.158006,1.7294737,2.0738268,7.386411),vec4(-4.256034,-306.24686,8.258898,-17.132736))*buf[4]+mat4(vec4(1.6889864,-4.5852966,3.8534803,-6.3482175),vec4(1.3543309,-1.2640043,9.932754,2.9079645),vec4(-5.2770967,0.07150358,-0.13962056,3.3269649),vec4(28.34703,-4.918278,6.1044083,4.085355))*buf[5]+vec4(6.6818056,12.522166,-3.7075126,-4.104386); + buf[7]=mat4(vec4(-8.265602,-4.7027016,5.098234,0.7509808),vec4(8.6507845,-17.15949,16.51939,-8.884479),vec4(-4.036479,-2.3946867,-2.6055532,-1.9866527),vec4(-2.2167742,-1.8135649,-5.9759874,4.8846445))*buf[0]+mat4(vec4(6.7790847,3.5076547,-2.8191125,-2.7028968),vec4(-5.743024,-0.27844876,1.4958696,-5.0517144),vec4(13.122226,15.735168,-2.9397483,-4.101023),vec4(-14.375265,-5.030483,-6.2599335,2.9848232))*buf[1]+mat4(vec4(4.0950394,-0.94011575,-5.674733,4.755022),vec4(4.3809423,4.8310084,1.7425908,-3.437416),vec4(2.117492,0.16342592,-104.56341,16.949184),vec4(-5.22543,-2.994248,3.8350096,-1.9364246))*buf[2]+mat4(vec4(-5.900337,1.7946124,-13.604192,-3.8060522),vec4(6.6583457,31.911177,25.164474,91.81147),vec4(11.840538,4.1503043,-0.7314397,6.768467),vec4(-6.3967767,4.034772,6.1714606,-0.32874924))*buf[3]+mat4(vec4(3.4992442,-196.91893,-8.923708,2.8142626),vec4(3.4806502,-3.1846354,5.1725626,5.1804223),vec4(-2.4009497,15.585794,1.2863957,2.0252278),vec4(-71.25271,-62.441242,-8.138444,0.50670296))*buf[4]+mat4(vec4(-12.291733,-11.176166,-7.3474145,4.390294),vec4(10.805477,5.6337385,-0.9385842,-4.7348723),vec4(-12.869276,-7.039391,5.3029537,7.5436664),vec4(1.4593618,8.91898,3.5101583,5.840625))*buf[5]+vec4(2.2415268,-6.705987,-0.98861027,-2.117676); + buf[6]=sigmoid(buf[6]);buf[7]=sigmoid(buf[7]); + buf[0]=mat4(vec4(1.6794263,1.3817469,2.9625452,0.),vec4(-1.8834411,-1.4806935,-3.5924516,0.),vec4(-1.3279216,-1.0918057,-2.3124623,0.),vec4(0.2662234,0.23235129,0.44178495,0.))*buf[0]+mat4(vec4(-0.6299101,-0.5945583,-0.9125601,0.),vec4(0.17828953,0.18300213,0.18182953,0.),vec4(-2.96544,-2.5819945,-4.9001055,0.),vec4(1.4195864,1.1868085,2.5176322,0.))*buf[1]+mat4(vec4(-1.2584374,-1.0552157,-2.1688404,0.),vec4(-0.7200217,-0.52666044,-1.438251,0.),vec4(0.15345335,0.15196142,0.272854,0.),vec4(0.945728,0.8861938,1.2766753,0.))*buf[2]+mat4(vec4(-2.4218085,-1.968602,-4.35166,0.),vec4(-22.683098,-18.0544,-41.954372,0.),vec4(0.63792,0.5470648,1.1078634,0.),vec4(-1.5489894,-1.3075932,-2.6444845,0.))*buf[3]+mat4(vec4(-0.49252132,-0.39877754,-0.91366625,0.),vec4(0.95609266,0.7923952,1.640221,0.),vec4(0.30616966,0.15693925,0.8639857,0.),vec4(1.1825981,0.94504964,2.176963,0.))*buf[4]+mat4(vec4(0.35446745,0.3293795,0.59547555,0.),vec4(-0.58784515,-0.48177817,-1.0614829,0.),vec4(2.5271258,1.9991658,4.6846647,0.),vec4(0.13042648,0.08864098,0.30187556,0.))*buf[5]+mat4(vec4(-1.7718065,-1.4033192,-3.3355875,0.),vec4(3.1664357,2.638297,5.378702,0.),vec4(-3.1724713,-2.6107926,-5.549295,0.),vec4(-2.851368,-2.249092,-5.3013067,0.))*buf[6]+mat4(vec4(1.5203838,1.2212278,2.8404984,0.),vec4(1.5210563,1.2651345,2.683903,0.),vec4(2.9789467,2.4364579,5.2347264,0.),vec4(2.2270417,1.8825914,3.8028636,0.))*buf[7]+vec4(-1.5468478,-3.6171484,0.24762098,0.); + buf[0]=sigmoid(buf[0]); + return vec4(buf[0].x,buf[0].y,buf[0].z,1.); +} + +void mainImage(out vec4 fragColor,in vec2 fragCoord){ + vec2 uv=fragCoord/uResolution.xy*2.-1.; + uv.y*=-1.; + uv+=uWarp*vec2(sin(uv.y*6.283+uTime*0.5),cos(uv.x*6.283+uTime*0.5))*0.05; + fragColor=cppn_fn(uv,0.1*sin(0.3*uTime),0.1*sin(0.69*uTime),0.1*sin(0.44*uTime)); +} + +void main(){ + vec4 col;mainImage(col,gl_FragCoord.xy); + col.rgb=hueShiftRGB(col.rgb,uHueShift); + float scanline_val=sin(gl_FragCoord.y*uScanFreq)*0.5+0.5; + col.rgb*=1.-(scanline_val*scanline_val)*uScan; + col.rgb+=(rand(gl_FragCoord.xy+uTime)-0.5)*uNoise; + gl_FragColor=vec4(clamp(col.rgb,0.0,1.0),1.0); +} +`;class Pk extends S.Component{constructor(t){super(t),this.state={hasError:!1}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,r){console.error("ErrorBoundary caught an error:",t,r)}render(){return this.state.hasError?this.props.fallback||h.jsx("div",{style:{position:"fixed",top:0,left:0,width:"100%",height:"100%",background:"radial-gradient(circle at center, rgba(0,0,0,0.8) 0%, rgba(0,0,0,1) 100%)",zIndex:-1,pointerEvents:"none"}}):this.props.children}}function Ek({hueShift:e=60,noiseIntensity:t=.03,scanlineIntensity:r=.08,speed:n=.4,scanlineFrequency:s=.6,warpAmount:i=.15,resolutionScale:o=1}){const a=S.useRef(null);return S.useEffect(()=>{const l=a.current;if(!l){console.error("DarkVeil: Canvas not found");return}let c,d,f;try{c=new uS({dpr:Math.min(window.devicePixelRatio,2),canvas:l});const w=c.gl;if(!w){console.error("DarkVeil: WebGL context not available");return}const v=new jk(w);d=new sS(w,{vertex:Ck,fragment:Nk,uniforms:{uTime:{value:0},uResolution:{value:new Bc},uHueShift:{value:e},uNoise:{value:t},uScan:{value:r},uScanFreq:{value:s},uWarp:{value:i}}}),f=new ak(w,{geometry:v,program:d}),console.log("DarkVeil: Successfully initialized")}catch(w){console.error("DarkVeil: Initialization error:",w);return}const u=()=>{const w=window.innerWidth,v=window.innerHeight;c.setSize(w*o,v*o),d.uniforms.uResolution.value.set(w,v)};window.addEventListener("resize",u),u();const p=performance.now();let m=0;const g=()=>{d.uniforms.uTime.value=(performance.now()-p)/1e3*n,d.uniforms.uHueShift.value=e,d.uniforms.uNoise.value=t,d.uniforms.uScan.value=r,d.uniforms.uScanFreq.value=s,d.uniforms.uWarp.value=i,c.render({scene:f}),m=requestAnimationFrame(g)};return g(),()=>{cancelAnimationFrame(m),window.removeEventListener("resize",u)}},[e,t,r,n,s,i,o]),h.jsxs(h.Fragment,{children:[h.jsx("div",{style:{position:"fixed",top:0,left:0,width:"100vw",height:"100vh",background:"radial-gradient(circle at center, rgba(50,20,80,0.8) 0%, rgba(20,10,40,0.9) 50%, rgba(0,0,0,1) 100%)",zIndex:-10,pointerEvents:"none"}}),h.jsx("canvas",{ref:a,style:{position:"fixed",top:0,left:0,width:"100vw",height:"100vh",zIndex:-5,pointerEvents:"none",display:"block"}})]})}function _s(e){return h.jsx(Pk,{children:h.jsx(Ek,{...e})})}/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */var Tk={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Mk=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase().trim(),Z=(e,t)=>{const r=S.forwardRef(({color:n="currentColor",size:s=24,strokeWidth:i=2,absoluteStrokeWidth:o,className:a="",children:l,...c},d)=>S.createElement("svg",{ref:d,...Tk,width:s,height:s,stroke:n,strokeWidth:o?Number(i)*24/Number(s):i,className:["lucide",`lucide-${Mk(e)}`,a].join(" "),...c},[...t.map(([f,u])=>S.createElement(f,u)),...Array.isArray(l)?l:[l]]));return r.displayName=`${e}`,r};/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ak=Z("Activity",[["path",{d:"M22 12h-4l-3 9L9 3l-3 9H2",key:"d5dnw9"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const _k=Z("ArrowRight",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Lk=Z("Award",[["circle",{cx:"12",cy:"8",r:"6",key:"1vp47v"}],["path",{d:"M15.477 12.89 17 22l-5-3-5 3 1.523-9.11",key:"em7aur"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const sy=Z("Calendar",[["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",ry:"2",key:"eu3xkr"}],["line",{x1:"16",x2:"16",y1:"2",y2:"6",key:"m3sa8f"}],["line",{x1:"8",x2:"8",y1:"2",y2:"6",key:"18kwsl"}],["line",{x1:"3",x2:"21",y1:"10",y2:"10",key:"xt86sb"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Dk=Z("Camera",[["path",{d:"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z",key:"1tc9qg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Rk=Z("CheckCircle",[["path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14",key:"g774vq"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Vk=Z("ChevronLeft",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Fk=Z("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Un=Z("Clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const iy=Z("ExternalLink",[["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}],["polyline",{points:"15 3 21 3 21 9",key:"mznyad"}],["line",{x1:"10",x2:"21",y1:"14",y2:"3",key:"18c3s4"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const et=Z("Heart",[["path",{d:"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z",key:"c3ymky"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ik=Z("Loader2",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Uh=Z("LogOut",[["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}],["polyline",{points:"16 17 21 12 16 7",key:"1gabdz"}],["line",{x1:"21",x2:"9",y1:"12",y2:"12",key:"1uyos4"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const zk=Z("Menu",[["line",{x1:"4",x2:"20",y1:"12",y2:"12",key:"1e0a9i"}],["line",{x1:"4",x2:"20",y1:"6",y2:"6",key:"1owob3"}],["line",{x1:"4",x2:"20",y1:"18",y2:"18",key:"yk5zj1"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ok=Z("Moon",[["path",{d:"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z",key:"a7tn18"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ke=Z("Music",[["path",{d:"M9 18V5l12-2v13",key:"1jmyc2"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["circle",{cx:"18",cy:"16",r:"3",key:"1hluhg"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const $k=Z("Pause",[["rect",{width:"4",height:"16",x:"6",y:"4",key:"iffhe4"}],["rect",{width:"4",height:"16",x:"14",y:"4",key:"sjin7j"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const oy=Z("PlayCircle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polygon",{points:"10 8 16 12 10 16 10 8",key:"1cimsy"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Wh=Z("Play",[["polygon",{points:"5 3 19 12 5 21 5 3",key:"191637"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Uc=Z("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Hh=Z("Settings",[["path",{d:"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z",key:"1qme2f"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Nr=Z("Sparkles",[["path",{d:"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z",key:"17u4zn"}],["path",{d:"M5 3v4",key:"bklmnn"}],["path",{d:"M19 17v4",key:"iiml17"}],["path",{d:"M3 5h4",key:"nem4j1"}],["path",{d:"M17 19h4",key:"lbex7p"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const ay=Z("Star",[["polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2",key:"8f66p6"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Bk=Z("Sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const ly=Z("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const uy=Z("TrendingUp",[["polyline",{points:"22 7 13.5 15.5 8.5 10.5 2 17",key:"126l90"}],["polyline",{points:"16 7 22 7 22 13",key:"kwv8wd"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ls=Z("User",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Wc=Z("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Uk=Z("Volume2",[["polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5",key:"16drj5"}],["path",{d:"M15.54 8.46a5 5 0 0 1 0 7.07",key:"ltjumu"}],["path",{d:"M19.07 4.93a10 10 0 0 1 0 14.14",key:"1kegas"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Wk=Z("Wand2",[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72Z",key:"1bcowg"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Hk=Z("XCircle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const qh=Z("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const qk=Z("Zap",[["polygon",{points:"13 2 3 14 12 14 11 22 21 10 12 10 13 2",key:"45s27k"}]]);function cy(e){var t,r,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var s=e.length;for(t=0;t{const t=Xk(e),{conflictingClassGroups:r,conflictingClassGroupModifiers:n}=e;return{getClassGroupId:o=>{const a=o.split(Hc);return a[0]===""&&a.length!==1&&a.shift(),dy(a,t)||Kk(o)},getConflictingClassGroupIds:(o,a)=>{const l=r[o]||[];return a&&n[o]?[...l,...n[o]]:l}}},dy=(e,t)=>{var o;if(e.length===0)return t.classGroupId;const r=e[0],n=t.nextPart.get(r),s=n?dy(e.slice(1),n):void 0;if(s)return s;if(t.validators.length===0)return;const i=e.join(Hc);return(o=t.validators.find(({validator:a})=>a(i)))==null?void 0:o.classGroupId},Gh=/^\[(.+)\]$/,Kk=e=>{if(Gh.test(e)){const t=Gh.exec(e)[1],r=t==null?void 0:t.substring(0,t.indexOf(":"));if(r)return"arbitrary.."+r}},Xk=e=>{const{theme:t,prefix:r}=e,n={nextPart:new Map,validators:[]};return Zk(Object.entries(e.classGroups),r).forEach(([i,o])=>{xu(o,n,i,t)}),n},xu=(e,t,r,n)=>{e.forEach(s=>{if(typeof s=="string"){const i=s===""?t:Yh(t,s);i.classGroupId=r;return}if(typeof s=="function"){if(Qk(s)){xu(s(n),t,r,n);return}t.validators.push({validator:s,classGroupId:r});return}Object.entries(s).forEach(([i,o])=>{xu(o,Yh(t,i),r,n)})})},Yh=(e,t)=>{let r=e;return t.split(Hc).forEach(n=>{r.nextPart.has(n)||r.nextPart.set(n,{nextPart:new Map,validators:[]}),r=r.nextPart.get(n)}),r},Qk=e=>e.isThemeGetter,Zk=(e,t)=>t?e.map(([r,n])=>{const s=n.map(i=>typeof i=="string"?t+i:typeof i=="object"?Object.fromEntries(Object.entries(i).map(([o,a])=>[t+o,a])):i);return[r,s]}):e,Jk=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,r=new Map,n=new Map;const s=(i,o)=>{r.set(i,o),t++,t>e&&(t=0,n=r,r=new Map)};return{get(i){let o=r.get(i);if(o!==void 0)return o;if((o=n.get(i))!==void 0)return s(i,o),o},set(i,o){r.has(i)?r.set(i,o):s(i,o)}}},fy="!",ej=e=>{const{separator:t,experimentalParseClassName:r}=e,n=t.length===1,s=t[0],i=t.length,o=a=>{const l=[];let c=0,d=0,f;for(let w=0;wd?f-d:void 0;return{modifiers:l,hasImportantModifier:p,baseClassName:m,maybePostfixModifierPosition:g}};return r?a=>r({className:a,parseClassName:o}):o},tj=e=>{if(e.length<=1)return e;const t=[];let r=[];return e.forEach(n=>{n[0]==="["?(t.push(...r.sort(),n),r=[]):r.push(n)}),t.push(...r.sort()),t},rj=e=>({cache:Jk(e.cacheSize),parseClassName:ej(e),...Yk(e)}),nj=/\s+/,sj=(e,t)=>{const{parseClassName:r,getClassGroupId:n,getConflictingClassGroupIds:s}=t,i=[],o=e.trim().split(nj);let a="";for(let l=o.length-1;l>=0;l-=1){const c=o[l],{modifiers:d,hasImportantModifier:f,baseClassName:u,maybePostfixModifierPosition:p}=r(c);let m=!!p,g=n(m?u.substring(0,p):u);if(!g){if(!m){a=c+(a.length>0?" "+a:a);continue}if(g=n(u),!g){a=c+(a.length>0?" "+a:a);continue}m=!1}const w=tj(d).join(":"),v=f?w+fy:w,y=v+g;if(i.includes(y))continue;i.push(y);const x=s(g,m);for(let b=0;b0?" "+a:a)}return a};function ij(){let e=0,t,r,n="";for(;e{if(typeof e=="string")return e;let t,r="";for(let n=0;nf(d),e());return r=rj(c),n=r.cache.get,s=r.cache.set,i=a,a(l)}function a(l){const c=n(l);if(c)return c;const d=sj(l,r);return s(l,d),d}return function(){return i(ij.apply(null,arguments))}}const se=e=>{const t=r=>r[e]||[];return t.isThemeGetter=!0,t},py=/^\[(?:([a-z-]+):)?(.+)\]$/i,aj=/^\d+\/\d+$/,lj=new Set(["px","full","screen"]),uj=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,cj=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,dj=/^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/,fj=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,hj=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Rt=e=>An(e)||lj.has(e)||aj.test(e),er=e=>Xn(e,"length",bj),An=e=>!!e&&!Number.isNaN(Number(e)),sl=e=>Xn(e,"number",An),cs=e=>!!e&&Number.isInteger(Number(e)),pj=e=>e.endsWith("%")&&An(e.slice(0,-1)),Y=e=>py.test(e),tr=e=>uj.test(e),mj=new Set(["length","size","percentage"]),gj=e=>Xn(e,mj,my),yj=e=>Xn(e,"position",my),vj=new Set(["image","url"]),xj=e=>Xn(e,vj,kj),wj=e=>Xn(e,"",Sj),ds=()=>!0,Xn=(e,t,r)=>{const n=py.exec(e);return n?n[1]?typeof t=="string"?n[1]===t:t.has(n[1]):r(n[2]):!1},bj=e=>cj.test(e)&&!dj.test(e),my=()=>!1,Sj=e=>fj.test(e),kj=e=>hj.test(e),jj=()=>{const e=se("colors"),t=se("spacing"),r=se("blur"),n=se("brightness"),s=se("borderColor"),i=se("borderRadius"),o=se("borderSpacing"),a=se("borderWidth"),l=se("contrast"),c=se("grayscale"),d=se("hueRotate"),f=se("invert"),u=se("gap"),p=se("gradientColorStops"),m=se("gradientColorStopPositions"),g=se("inset"),w=se("margin"),v=se("opacity"),y=se("padding"),x=se("saturate"),b=se("scale"),k=se("sepia"),C=se("skew"),N=se("space"),P=se("translate"),V=()=>["auto","contain","none"],T=()=>["auto","hidden","clip","visible","scroll"],O=()=>["auto",Y,t],j=()=>[Y,t],F=()=>["",Rt,er],D=()=>["auto",An,Y],G=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],M=()=>["solid","dashed","dotted","double","none"],W=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],_=()=>["start","end","center","between","around","evenly","stretch"],A=()=>["","0",Y],I=()=>["auto","avoid","all","avoid-page","page","left","right","column"],R=()=>[An,Y];return{cacheSize:500,separator:":",theme:{colors:[ds],spacing:[Rt,er],blur:["none","",tr,Y],brightness:R(),borderColor:[e],borderRadius:["none","","full",tr,Y],borderSpacing:j(),borderWidth:F(),contrast:R(),grayscale:A(),hueRotate:R(),invert:A(),gap:j(),gradientColorStops:[e],gradientColorStopPositions:[pj,er],inset:O(),margin:O(),opacity:R(),padding:j(),saturate:R(),scale:R(),sepia:A(),skew:R(),space:j(),translate:j()},classGroups:{aspect:[{aspect:["auto","square","video",Y]}],container:["container"],columns:[{columns:[tr]}],"break-after":[{"break-after":I()}],"break-before":[{"break-before":I()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...G(),Y]}],overflow:[{overflow:T()}],"overflow-x":[{"overflow-x":T()}],"overflow-y":[{"overflow-y":T()}],overscroll:[{overscroll:V()}],"overscroll-x":[{"overscroll-x":V()}],"overscroll-y":[{"overscroll-y":V()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[g]}],"inset-x":[{"inset-x":[g]}],"inset-y":[{"inset-y":[g]}],start:[{start:[g]}],end:[{end:[g]}],top:[{top:[g]}],right:[{right:[g]}],bottom:[{bottom:[g]}],left:[{left:[g]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",cs,Y]}],basis:[{basis:O()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",Y]}],grow:[{grow:A()}],shrink:[{shrink:A()}],order:[{order:["first","last","none",cs,Y]}],"grid-cols":[{"grid-cols":[ds]}],"col-start-end":[{col:["auto",{span:["full",cs,Y]},Y]}],"col-start":[{"col-start":D()}],"col-end":[{"col-end":D()}],"grid-rows":[{"grid-rows":[ds]}],"row-start-end":[{row:["auto",{span:[cs,Y]},Y]}],"row-start":[{"row-start":D()}],"row-end":[{"row-end":D()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",Y]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",Y]}],gap:[{gap:[u]}],"gap-x":[{"gap-x":[u]}],"gap-y":[{"gap-y":[u]}],"justify-content":[{justify:["normal",..._()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",..._(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[..._(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[y]}],px:[{px:[y]}],py:[{py:[y]}],ps:[{ps:[y]}],pe:[{pe:[y]}],pt:[{pt:[y]}],pr:[{pr:[y]}],pb:[{pb:[y]}],pl:[{pl:[y]}],m:[{m:[w]}],mx:[{mx:[w]}],my:[{my:[w]}],ms:[{ms:[w]}],me:[{me:[w]}],mt:[{mt:[w]}],mr:[{mr:[w]}],mb:[{mb:[w]}],ml:[{ml:[w]}],"space-x":[{"space-x":[N]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[N]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",Y,t]}],"min-w":[{"min-w":[Y,t,"min","max","fit"]}],"max-w":[{"max-w":[Y,t,"none","full","min","max","fit","prose",{screen:[tr]},tr]}],h:[{h:[Y,t,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[Y,t,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[Y,t,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[Y,t,"auto","min","max","fit"]}],"font-size":[{text:["base",tr,er]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",sl]}],"font-family":[{font:[ds]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",Y]}],"line-clamp":[{"line-clamp":["none",An,sl]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",Rt,Y]}],"list-image":[{"list-image":["none",Y]}],"list-style-type":[{list:["none","disc","decimal",Y]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[e]}],"placeholder-opacity":[{"placeholder-opacity":[v]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[e]}],"text-opacity":[{"text-opacity":[v]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...M(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",Rt,er]}],"underline-offset":[{"underline-offset":["auto",Rt,Y]}],"text-decoration-color":[{decoration:[e]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:j()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",Y]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",Y]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[v]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...G(),yj]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",gj]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},xj]}],"bg-color":[{bg:[e]}],"gradient-from-pos":[{from:[m]}],"gradient-via-pos":[{via:[m]}],"gradient-to-pos":[{to:[m]}],"gradient-from":[{from:[p]}],"gradient-via":[{via:[p]}],"gradient-to":[{to:[p]}],rounded:[{rounded:[i]}],"rounded-s":[{"rounded-s":[i]}],"rounded-e":[{"rounded-e":[i]}],"rounded-t":[{"rounded-t":[i]}],"rounded-r":[{"rounded-r":[i]}],"rounded-b":[{"rounded-b":[i]}],"rounded-l":[{"rounded-l":[i]}],"rounded-ss":[{"rounded-ss":[i]}],"rounded-se":[{"rounded-se":[i]}],"rounded-ee":[{"rounded-ee":[i]}],"rounded-es":[{"rounded-es":[i]}],"rounded-tl":[{"rounded-tl":[i]}],"rounded-tr":[{"rounded-tr":[i]}],"rounded-br":[{"rounded-br":[i]}],"rounded-bl":[{"rounded-bl":[i]}],"border-w":[{border:[a]}],"border-w-x":[{"border-x":[a]}],"border-w-y":[{"border-y":[a]}],"border-w-s":[{"border-s":[a]}],"border-w-e":[{"border-e":[a]}],"border-w-t":[{"border-t":[a]}],"border-w-r":[{"border-r":[a]}],"border-w-b":[{"border-b":[a]}],"border-w-l":[{"border-l":[a]}],"border-opacity":[{"border-opacity":[v]}],"border-style":[{border:[...M(),"hidden"]}],"divide-x":[{"divide-x":[a]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[a]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[v]}],"divide-style":[{divide:M()}],"border-color":[{border:[s]}],"border-color-x":[{"border-x":[s]}],"border-color-y":[{"border-y":[s]}],"border-color-s":[{"border-s":[s]}],"border-color-e":[{"border-e":[s]}],"border-color-t":[{"border-t":[s]}],"border-color-r":[{"border-r":[s]}],"border-color-b":[{"border-b":[s]}],"border-color-l":[{"border-l":[s]}],"divide-color":[{divide:[s]}],"outline-style":[{outline:["",...M()]}],"outline-offset":[{"outline-offset":[Rt,Y]}],"outline-w":[{outline:[Rt,er]}],"outline-color":[{outline:[e]}],"ring-w":[{ring:F()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[e]}],"ring-opacity":[{"ring-opacity":[v]}],"ring-offset-w":[{"ring-offset":[Rt,er]}],"ring-offset-color":[{"ring-offset":[e]}],shadow:[{shadow:["","inner","none",tr,wj]}],"shadow-color":[{shadow:[ds]}],opacity:[{opacity:[v]}],"mix-blend":[{"mix-blend":[...W(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":W()}],filter:[{filter:["","none"]}],blur:[{blur:[r]}],brightness:[{brightness:[n]}],contrast:[{contrast:[l]}],"drop-shadow":[{"drop-shadow":["","none",tr,Y]}],grayscale:[{grayscale:[c]}],"hue-rotate":[{"hue-rotate":[d]}],invert:[{invert:[f]}],saturate:[{saturate:[x]}],sepia:[{sepia:[k]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[r]}],"backdrop-brightness":[{"backdrop-brightness":[n]}],"backdrop-contrast":[{"backdrop-contrast":[l]}],"backdrop-grayscale":[{"backdrop-grayscale":[c]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[d]}],"backdrop-invert":[{"backdrop-invert":[f]}],"backdrop-opacity":[{"backdrop-opacity":[v]}],"backdrop-saturate":[{"backdrop-saturate":[x]}],"backdrop-sepia":[{"backdrop-sepia":[k]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[o]}],"border-spacing-x":[{"border-spacing-x":[o]}],"border-spacing-y":[{"border-spacing-y":[o]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",Y]}],duration:[{duration:R()}],ease:[{ease:["linear","in","out","in-out",Y]}],delay:[{delay:R()}],animate:[{animate:["none","spin","ping","pulse","bounce",Y]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[b]}],"scale-x":[{"scale-x":[b]}],"scale-y":[{"scale-y":[b]}],rotate:[{rotate:[cs,Y]}],"translate-x":[{"translate-x":[P]}],"translate-y":[{"translate-y":[P]}],"skew-x":[{"skew-x":[C]}],"skew-y":[{"skew-y":[C]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",Y]}],accent:[{accent:["auto",e]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",Y]}],"caret-color":[{caret:[e]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":j()}],"scroll-mx":[{"scroll-mx":j()}],"scroll-my":[{"scroll-my":j()}],"scroll-ms":[{"scroll-ms":j()}],"scroll-me":[{"scroll-me":j()}],"scroll-mt":[{"scroll-mt":j()}],"scroll-mr":[{"scroll-mr":j()}],"scroll-mb":[{"scroll-mb":j()}],"scroll-ml":[{"scroll-ml":j()}],"scroll-p":[{"scroll-p":j()}],"scroll-px":[{"scroll-px":j()}],"scroll-py":[{"scroll-py":j()}],"scroll-ps":[{"scroll-ps":j()}],"scroll-pe":[{"scroll-pe":j()}],"scroll-pt":[{"scroll-pt":j()}],"scroll-pr":[{"scroll-pr":j()}],"scroll-pb":[{"scroll-pb":j()}],"scroll-pl":[{"scroll-pl":j()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",Y]}],fill:[{fill:[e,"none"]}],"stroke-w":[{stroke:[Rt,er,sl]}],stroke:[{stroke:[e,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},Cj=oj(jj);function Kh(...e){return Cj(Gk(e))}function Ds(e){const t=Math.floor(e/6e4),r=Math.floor(e%6e4/1e3);return`${t}:${r.toString().padStart(2,"0")}`}function _n(e){const t=new Date(e),n=(new Date().getTime()-t.getTime())/(1e3*60*60);return n<1?`${Math.floor(n*60)}m ago`:n<24?`${Math.floor(n)}h ago`:`${Math.floor(n/24)}d ago`}const Nj=()=>{var j,F,D,G,M,W,_,A,I,R;const[e,t]=S.useState(!1),[r,n]=S.useState(!1),[s,i]=S.useState({x:0,y:0}),[o,a]=S.useState(!1),[l,c]=S.useState({x:0,y:0}),{currentUser:d,partnerUser:f,logout:u,theme:p,setTheme:m,setPartnerUser:g}=oe(),[w,v]=S.useState(""),[y,x]=S.useState(!1),[b,k]=S.useState(!1),C=_r(),N=[{name:"Dashboard",href:"/",icon:et},{name:"Last Listened",href:"/last-listened",icon:Ke},{name:"Mixed Playlist",href:"/mixed-playlist",icon:oy},{name:"Memory Lane",href:"/memory-lane",icon:Nr},{name:"Wrapped",href:"/wrapped",icon:Lk}],P=()=>{u(),localStorage.removeItem("spotify-user"),localStorage.removeItem("spotify-partner")},V=async()=>{var E,H;if(!(!((E=d==null?void 0:d.user)!=null&&E.id)||!((H=f==null?void 0:f.user)!=null&&H.id))&&confirm(`Are you sure you want to remove ${f.user.display_name} as your partner?`)){k(!0);try{await Et("/partners/remove",{partnerId:f.user.id})}catch(X){try{await Et("/partners/clear",{userId:d.user.id})}catch(ee){console.error("Failed to remove partner:",X,ee)}}finally{g(null),localStorage.removeItem("spotify-partner"),k(!1)}}},T=en(p);S.useEffect(()=>{en(p)},[p]),S.useEffect(()=>{if(r){const E=Math.min(600,window.innerWidth-40),H=Math.min(window.innerHeight*.9,800),X=(window.innerWidth-E)/2,ee=(window.innerHeight-H)/2;i({x:X,y:ee})}},[r]),S.useEffect(()=>{const E=X=>{o&&i({x:X.clientX-l.x,y:X.clientY-l.y})},H=()=>{a(!1)};return o&&(document.addEventListener("mousemove",E),document.addEventListener("mouseup",H)),()=>{document.removeEventListener("mousemove",E),document.removeEventListener("mouseup",H)}},[o,l]);const O=E=>{a(!0),c({x:E.clientX-s.x,y:E.clientY-s.y})};return h.jsxs(z.nav,{initial:{y:-100,opacity:0},animate:{y:0,opacity:1},className:"sticky top-0 z-50",style:{background:"rgba(0, 0, 0, 0.8)",backdropFilter:"blur(20px)",borderBottom:"1px solid rgba(255, 255, 255, 0.05)"},children:[h.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:[h.jsxs("div",{className:"flex justify-between items-center h-16",children:[h.jsxs(Xi,{to:"/",className:"flex items-center space-x-2",children:[h.jsx(z.div,{whileHover:{scale:1.1,rotate:5},className:"w-8 h-8 rounded-full flex items-center justify-center",style:{background:`linear-gradient(135deg, ${((j=T.cssVars)==null?void 0:j.primary)||"#1db954"} 0%, ${((F=T.cssVars)==null?void 0:F.secondary)||"#1ed760"} 100%)`},children:h.jsx(et,{className:"w-5 h-5 text-white"})}),h.jsx("span",{className:"text-xl font-bold gradient-text",children:"Our Musical Journey"})]}),h.jsx("div",{className:"hidden md:flex items-center space-x-1",children:N.map(E=>{var X,ee,q,me;const H=C.pathname===E.href;return h.jsxs(Xi,{to:E.href,className:Kh("flex items-center space-x-2 px-4 py-2 rounded-xl transition-all duration-300",H?"text-white":"text-white/60 hover:text-white hover:bg-white/5"),style:H?{background:`linear-gradient(135deg, ${((X=T.cssVars)==null?void 0:X.primary)||"#1db954"}15 0%, ${((ee=T.cssVars)==null?void 0:ee.secondary)||"#1ed760"}10 100%)`,border:`1px solid ${((q=T.cssVars)==null?void 0:q.primary)||"#1db954"}30`}:{},children:[h.jsx(E.icon,{className:"w-4 h-4",style:{color:H?(me=T.cssVars)==null?void 0:me.primary:void 0}}),h.jsx("span",{className:"font-medium",children:E.name})]},E.name)})}),h.jsxs("div",{className:"hidden md:flex items-center space-x-4",children:[!f&&h.jsxs("div",{className:"flex items-center space-x-2",children:[h.jsx("input",{value:w,onChange:E=>v(E.target.value),placeholder:"Partner Spotify ID",className:"bg-white/10 text-white text-sm px-2 py-1 rounded"}),h.jsx("button",{disabled:y||!w,onClick:async()=>{var E;if(!(!((E=d==null?void 0:d.user)!=null&&E.id)||!w)){x(!0);try{await Et("/partners/request",{toUid:w})}finally{x(!1)}}},className:`${T.primary} ${T.hover} text-white px-3 py-1 rounded text-sm disabled:opacity-50`,children:y?"Sending...":"Send Request"})]}),f&&h.jsxs(z.div,{initial:{scale:0},animate:{scale:1},className:"flex items-center space-x-2 text-sm text-white/70",children:[h.jsx(Ls,{className:"w-4 h-4"}),h.jsxs("span",{children:["+ ",(D=f.user)==null?void 0:D.display_name]})]}),h.jsxs(z.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>n(!0),className:"flex items-center space-x-2 px-3 py-2 rounded-xl text-white/60 hover:text-white transition-all duration-300",style:{color:(G=T.cssVars)==null?void 0:G.primary},onMouseEnter:E=>{E.currentTarget.style.background="rgba(255, 255, 255, 0.05)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[h.jsx(Hh,{className:"w-4 h-4"}),h.jsx("span",{className:"hidden lg:block",children:"Settings"})]}),h.jsxs(z.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:P,className:"flex items-center space-x-2 px-3 py-2 rounded-xl text-white/60 hover:text-white transition-all duration-300",onMouseEnter:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.1)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[h.jsx(Uh,{className:"w-4 h-4"}),h.jsx("span",{className:"hidden lg:block",children:"Logout"})]})]}),h.jsx("button",{onClick:()=>t(!e),className:"md:hidden p-2 rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-all duration-300",children:e?h.jsx(qh,{className:"w-6 h-6"}):h.jsx(zk,{className:"w-6 h-6"})})]}),e&&h.jsx(z.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},className:"md:hidden py-4 border-t border-white/10",children:h.jsxs("div",{className:"space-y-2",children:[N.map(E=>{var X,ee,q,me;const H=C.pathname===E.href;return h.jsxs(Xi,{to:E.href,onClick:()=>t(!1),className:Kh("flex items-center space-x-3 px-4 py-3 rounded-xl transition-all duration-300",H?"text-white":"text-white/60 hover:text-white hover:bg-white/5"),style:H?{background:`linear-gradient(135deg, ${((X=T.cssVars)==null?void 0:X.primary)||"#1db954"}15 0%, ${((ee=T.cssVars)==null?void 0:ee.secondary)||"#1ed760"}10 100%)`,border:`1px solid ${((q=T.cssVars)==null?void 0:q.primary)||"#1db954"}30`}:{},children:[h.jsx(E.icon,{className:"w-5 h-5",style:{color:H?(me=T.cssVars)==null?void 0:me.primary:void 0}}),h.jsx("span",{className:"font-medium",children:E.name})]},E.name)}),h.jsxs("div",{className:"pt-4 border-t border-white/10",children:[f&&h.jsxs("div",{className:"flex items-center space-x-3 px-4 py-2 text-sm text-white/70",children:[h.jsx(Ls,{className:"w-4 h-4"}),h.jsxs("span",{children:["Connected with ",(M=f.user)==null?void 0:M.display_name]})]}),h.jsxs("button",{onClick:()=>{n(!0),t(!1)},className:"w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-white/60 hover:text-white transition-all duration-300",style:{color:(W=T.cssVars)==null?void 0:W.primary},onMouseEnter:E=>{E.currentTarget.style.background="rgba(255, 255, 255, 0.05)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[h.jsx(Hh,{className:"w-5 h-5"}),h.jsx("span",{className:"font-medium",children:"Settings"})]}),h.jsxs("button",{onClick:P,className:"w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-white/60 hover:text-white transition-all duration-300",onMouseEnter:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.1)"},onMouseLeave:E=>{E.currentTarget.style.background="transparent"},children:[h.jsx(Uh,{className:"w-5 h-5"}),h.jsx("span",{className:"font-medium",children:"Logout"})]})]})]})})]}),r&&h.jsxs(h.Fragment,{children:[h.jsx(z.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 bg-black/50 backdrop-blur-md z-40",onClick:()=>n(!1)}),h.jsxs(z.div,{initial:{opacity:0,scale:.8,y:30},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.8,y:30},className:"fixed z-50 overflow-hidden",style:{left:s.x,top:s.y,width:Math.min(600,window.innerWidth-40),height:Math.min(window.innerHeight*.9,800),background:"linear-gradient(135deg, rgba(0,0,0,0.9) 0%, rgba(20,20,20,0.95) 50%, rgba(0,0,0,0.9) 100%)",backdropFilter:"blur(24px) saturate(180%)",WebkitBackdropFilter:"blur(24px) saturate(180%)",border:"1px solid rgba(255,255,255,0.2)",borderRadius:"16px",boxShadow:"0 25px 50px rgba(0,0,0,0.5)",cursor:o?"grabbing":"default"},children:[h.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-white/20 cursor-grab active:cursor-grabbing select-none",onMouseDown:O,style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:[h.jsxs("div",{className:"flex items-center space-x-3",children:[h.jsxs("div",{className:"flex space-x-2",children:[h.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),h.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),h.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"})]}),h.jsx("h2",{className:"text-lg font-semibold text-white",children:"Settings"})]}),h.jsx("button",{onClick:()=>n(!1),className:"text-white/70 hover:text-white hover:bg-white/10 p-2 rounded-lg transition-all duration-200",children:h.jsx(qh,{className:"w-5 h-5"})})]}),h.jsx("div",{className:"overflow-y-auto p-4 sm:p-6",style:{height:"calc(100% - 60px)"},children:h.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[(d==null?void 0:d.user)&&h.jsxs("div",{children:[h.jsx("h3",{className:"text-lg font-semibold text-white mb-4 drop-shadow-md",children:"Your Account"}),h.jsxs("div",{className:"rounded-xl p-4 border border-white/20 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:[h.jsx("div",{className:"text-sm text-white/70 mb-2 font-medium",children:"Spotify ID"}),h.jsx("div",{className:"text-white font-mono text-sm break-all rounded-lg p-3 mb-3",style:{background:"rgba(0,0,0,0.4)",border:"1px solid rgba(255,255,255,0.1)"},children:d.user.id}),h.jsxs("div",{className:"text-sm text-white/80",children:["Display Name: ",h.jsx("span",{className:"text-white font-medium",children:d.user.display_name})]})]})]}),h.jsxs("div",{children:[h.jsx("h3",{className:"text-lg font-semibold text-white mb-4 drop-shadow-md",children:"Partner"}),f?h.jsx("div",{className:"rounded-xl p-4 border border-white/20 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:h.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between space-y-3 sm:space-y-0",children:[h.jsxs("div",{className:"flex items-center space-x-3 sm:space-x-4",children:[h.jsx("div",{className:"w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-purple-500 to-pink-500 rounded-full flex items-center justify-center shadow-lg",children:h.jsx(Ls,{className:"w-5 h-5 sm:w-6 sm:h-6 text-white"})}),h.jsxs("div",{className:"flex-1 min-w-0",children:[h.jsx("div",{className:"text-white font-semibold text-base sm:text-lg truncate",children:(_=f.user)==null?void 0:_.display_name}),h.jsx("div",{className:"text-xs text-white/70 break-all rounded px-2 py-1 mt-1 inline-block",style:{background:"rgba(0,0,0,0.3)",border:"1px solid rgba(255,255,255,0.1)"},children:(A=f.user)==null?void 0:A.id}),h.jsx("div",{className:"text-sm text-green-400 font-medium mt-2",children:"✓ Connected"})]})]}),h.jsxs("button",{onClick:V,disabled:b,className:"flex items-center space-x-2 p-2 sm:p-3 text-red-400 hover:text-red-300 rounded-xl transition-all duration-200 disabled:opacity-50 self-start sm:self-auto",style:{background:"rgba(239, 68, 68, 0.1)"},onMouseEnter:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.2)"},onMouseLeave:E=>{E.currentTarget.style.background="rgba(239, 68, 68, 0.1)"},children:[h.jsx(ly,{className:"w-4 h-4 sm:w-5 sm:h-5"}),h.jsx("span",{className:"text-sm sm:hidden",children:"Remove"})]})]})}):h.jsxs("div",{className:"rounded-xl p-4 border border-white/20 space-y-4 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:[h.jsxs("div",{children:[h.jsx("label",{className:"text-sm text-white/70 mb-2 block font-medium",children:"Partner Spotify ID"}),h.jsx("input",{value:w,onChange:E=>v(E.target.value),placeholder:"Enter partner's Spotify ID...",className:"w-full text-white text-sm px-4 py-3 rounded-xl placeholder-white/50 border focus:outline-none transition-all",style:{background:"rgba(0,0,0,0.4)",border:"1px solid rgba(255,255,255,0.2)"},onFocus:E=>{E.target.style.border="1px solid rgba(255,255,255,0.4)"},onBlur:E=>{E.target.style.border="1px solid rgba(255,255,255,0.2)"}})]}),h.jsx("button",{disabled:y||!w,onClick:async()=>{var E;if(!(!((E=d==null?void 0:d.user)!=null&&E.id)||!w)){x(!0);try{await Et("/partners/request",{toUid:w}),v("")}finally{x(!1)}}},className:"w-full text-white px-4 py-3 rounded-xl text-sm disabled:opacity-50 transition-all duration-200 font-medium",style:{background:`linear-gradient(135deg, ${((I=T.cssVars)==null?void 0:I.primary)||"#1db954"} 0%, ${((R=T.cssVars)==null?void 0:R.secondary)||"#1ed760"} 100%)`},onMouseEnter:E=>{var H;E.currentTarget.style.transform="translateY(-1px)",E.currentTarget.style.boxShadow=`0 8px 25px ${((H=T.cssVars)==null?void 0:H.primary)||"#1db954"}40`},onMouseLeave:E=>{E.currentTarget.style.transform="translateY(0)",E.currentTarget.style.boxShadow="none"},children:y?"Sending...":"Send Partner Request"})]})]}),h.jsxs("div",{children:[h.jsx("h3",{className:"text-lg font-semibold text-white mb-4 drop-shadow-md",children:"Color Theme"}),h.jsx("div",{className:"rounded-xl p-4 border border-white/20 transition-all duration-300 hover:border-white/30 hover:shadow-lg hover:shadow-white/5",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)"},onMouseEnter:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.04) 100%)"},onMouseLeave:E=>{E.currentTarget.style.background="linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)"},children:h.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-3",children:[{name:"Green",value:"green",color:"from-green-500 to-emerald-500"},{name:"Pink",value:"pink",color:"from-pink-500 to-rose-500"},{name:"Blue",value:"blue",color:"from-blue-400 to-cyan-400"},{name:"Red",value:"red",color:"from-red-600 to-red-800"},{name:"Purple",value:"purple",color:"from-purple-500 to-violet-600"},{name:"Yellow",value:"yellow",color:"from-yellow-400 to-orange-500"},{name:"Turquoise",value:"turquoise",color:"from-cyan-400 to-blue-500"}].map(E=>{var H,X,ee;return h.jsxs("button",{onClick:()=>m(E.value),className:"flex items-center space-x-3 p-3 rounded-xl border transition-all duration-200",style:{border:p===E.value?`2px solid ${((H=T.cssVars)==null?void 0:H.primary)||"#1db954"}`:"1px solid rgba(255,255,255,0.2)",background:p===E.value?`linear-gradient(135deg, ${((X=T.cssVars)==null?void 0:X.primary)||"#1db954"}15 0%, ${((ee=T.cssVars)==null?void 0:ee.secondary)||"#1ed760"}10 100%)`:"rgba(255,255,255,0.02)"},onMouseEnter:q=>{var me;p!==E.value?(q.currentTarget.style.background="rgba(255,255,255,0.08)",q.currentTarget.style.border="1px solid rgba(255,255,255,0.4)",q.currentTarget.style.transform="translateY(-2px)",q.currentTarget.style.boxShadow="0 4px 12px rgba(0,0,0,0.3)"):(q.currentTarget.style.transform="translateY(-1px)",q.currentTarget.style.boxShadow=`0 6px 20px ${((me=T.cssVars)==null?void 0:me.primary)||"#1db954"}30`)},onMouseLeave:q=>{p!==E.value?(q.currentTarget.style.background="rgba(255,255,255,0.02)",q.currentTarget.style.border="1px solid rgba(255,255,255,0.2)",q.currentTarget.style.transform="translateY(0)",q.currentTarget.style.boxShadow="none"):(q.currentTarget.style.transform="translateY(0)",q.currentTarget.style.boxShadow="none")},children:[h.jsx("div",{className:`w-5 h-5 rounded-full bg-gradient-to-r ${E.color} shadow-sm`}),h.jsx("span",{className:"text-white text-sm font-medium",children:E.name})]},E.value)})})})]})]})})]})]})]})};var gy={exports:{}};(function(e){var t=function(){var r="https://api.spotify.com/v1",n=null,s=null,i=function(u,p){return u.abort=p,u},o=function(u,p){var m;if(s!==null){var g=s.defer();u(function(w){g.resolve(w)},function(w){g.reject(w)}),m=g.promise}else window.Promise&&(m=new window.Promise(u));return m?new i(m,p):null},a=function(){var u=Array.prototype.slice.call(arguments),p=u[0],m=u.slice(1);return p=p||{},m.forEach(function(g){for(var w in g)g.hasOwnProperty(w)&&(p[w]=g[w])}),p},l=function(u,p){var m="";for(var g in p)if(p.hasOwnProperty(g)){var w=p[g];m+=encodeURIComponent(g)+"="+encodeURIComponent(w)+"&"}return m.length>0&&(m=m.substring(0,m.length-1),u=u+"?"+m),u},c=function(u,p){var m=new XMLHttpRequest,g=function(w,v){function y(C){w&&w(C),p&&p(null,C)}function x(){v&&v(m),p&&p(m,null)}var b=u.type||"GET";if(m.open(b,l(u.url,u.params)),n&&m.setRequestHeader("Authorization","Bearer "+n),m.onreadystatechange=function(){if(m.readyState===4){var C=null;try{C=m.responseText?JSON.parse(m.responseText):""}catch(N){console.error(N)}m.status>=200&&m.status<300?y(C):x()}},b==="GET")m.send(null);else{var k=null;u.postData&&(u.contentType==="image/jpeg"?(k=u.postData,m.setRequestHeader("Content-Type",u.contentType)):(k=JSON.stringify(u.postData),m.setRequestHeader("Content-Type","application/json"))),m.send(k)}};return p?(g(),null):o(g,function(){m.abort()})},d=function(u,p,m,g){var w={},v=null;typeof p=="object"?(w=p,v=m):typeof p=="function"&&(v=p);var y=u.type||"GET";return y!=="GET"&&u.postData&&!g?u.postData=a(u.postData,w):u.params=a(u.params,w),c(u,v)},f=function(){};return f.prototype={constructor:t},f.prototype.getGeneric=function(u,p){var m={url:u};return d(m,p)},f.prototype.getMe=function(u,p){var m={url:r+"/me"};return d(m,u,p)},f.prototype.getMySavedTracks=function(u,p){var m={url:r+"/me/tracks"};return d(m,u,p)},f.prototype.addToMySavedTracks=function(u,p,m){var g={url:r+"/me/tracks",type:"PUT",postData:u};return d(g,p,m)},f.prototype.removeFromMySavedTracks=function(u,p,m){var g={url:r+"/me/tracks",type:"DELETE",postData:u};return d(g,p,m)},f.prototype.containsMySavedTracks=function(u,p,m){var g={url:r+"/me/tracks/contains",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getMySavedAlbums=function(u,p){var m={url:r+"/me/albums"};return d(m,u,p)},f.prototype.addToMySavedAlbums=function(u,p,m){var g={url:r+"/me/albums",type:"PUT",postData:u};return d(g,p,m)},f.prototype.removeFromMySavedAlbums=function(u,p,m){var g={url:r+"/me/albums",type:"DELETE",postData:u};return d(g,p,m)},f.prototype.containsMySavedAlbums=function(u,p,m){var g={url:r+"/me/albums/contains",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getMyTopArtists=function(u,p){var m={url:r+"/me/top/artists"};return d(m,u,p)},f.prototype.getMyTopTracks=function(u,p){var m={url:r+"/me/top/tracks"};return d(m,u,p)},f.prototype.getMyRecentlyPlayedTracks=function(u,p){var m={url:r+"/me/player/recently-played"};return d(m,u,p)},f.prototype.followUsers=function(u,p){var m={url:r+"/me/following/",type:"PUT",params:{ids:u.join(","),type:"user"}};return d(m,p)},f.prototype.followArtists=function(u,p){var m={url:r+"/me/following/",type:"PUT",params:{ids:u.join(","),type:"artist"}};return d(m,p)},f.prototype.followPlaylist=function(u,p,m){var g={url:r+"/playlists/"+u+"/followers",type:"PUT",postData:{}};return d(g,p,m)},f.prototype.unfollowUsers=function(u,p){var m={url:r+"/me/following/",type:"DELETE",params:{ids:u.join(","),type:"user"}};return d(m,p)},f.prototype.unfollowArtists=function(u,p){var m={url:r+"/me/following/",type:"DELETE",params:{ids:u.join(","),type:"artist"}};return d(m,p)},f.prototype.unfollowPlaylist=function(u,p){var m={url:r+"/playlists/"+u+"/followers",type:"DELETE"};return d(m,p)},f.prototype.isFollowingUsers=function(u,p){var m={url:r+"/me/following/contains",type:"GET",params:{ids:u.join(","),type:"user"}};return d(m,p)},f.prototype.isFollowingArtists=function(u,p){var m={url:r+"/me/following/contains",type:"GET",params:{ids:u.join(","),type:"artist"}};return d(m,p)},f.prototype.areFollowingPlaylist=function(u,p,m){var g={url:r+"/playlists/"+u+"/followers/contains",type:"GET",params:{ids:p.join(",")}};return d(g,m)},f.prototype.getFollowedArtists=function(u,p){var m={url:r+"/me/following",type:"GET",params:{type:"artist"}};return d(m,u,p)},f.prototype.getUser=function(u,p,m){var g={url:r+"/users/"+encodeURIComponent(u)};return d(g,p,m)},f.prototype.getUserPlaylists=function(u,p,m){var g;return typeof u=="string"?g={url:r+"/users/"+encodeURIComponent(u)+"/playlists"}:(g={url:r+"/me/playlists"},m=p,p=u),d(g,p,m)},f.prototype.getPlaylist=function(u,p,m){var g={url:r+"/playlists/"+u};return d(g,p,m)},f.prototype.getPlaylistTracks=function(u,p,m){var g={url:r+"/playlists/"+u+"/tracks"};return d(g,p,m)},f.prototype.getPlaylistCoverImage=function(u,p){var m={url:r+"/playlists/"+u+"/images"};return d(m,p)},f.prototype.createPlaylist=function(u,p,m){var g={url:r+"/users/"+encodeURIComponent(u)+"/playlists",type:"POST",postData:p};return d(g,p,m)},f.prototype.changePlaylistDetails=function(u,p,m){var g={url:r+"/playlists/"+u,type:"PUT",postData:p};return d(g,p,m)},f.prototype.addTracksToPlaylist=function(u,p,m,g){var w={url:r+"/playlists/"+u+"/tracks",type:"POST",postData:{uris:p}};return d(w,m,g,!0)},f.prototype.replaceTracksInPlaylist=function(u,p,m){var g={url:r+"/playlists/"+u+"/tracks",type:"PUT",postData:{uris:p}};return d(g,{},m)},f.prototype.reorderTracksInPlaylist=function(u,p,m,g,w){var v={url:r+"/playlists/"+u+"/tracks",type:"PUT",postData:{range_start:p,insert_before:m}};return d(v,g,w)},f.prototype.removeTracksFromPlaylist=function(u,p,m){var g=p.map(function(v){return typeof v=="string"?{uri:v}:v}),w={url:r+"/playlists/"+u+"/tracks",type:"DELETE",postData:{tracks:g}};return d(w,{},m)},f.prototype.removeTracksFromPlaylistWithSnapshotId=function(u,p,m,g){var w=p.map(function(y){return typeof y=="string"?{uri:y}:y}),v={url:r+"/playlists/"+u+"/tracks",type:"DELETE",postData:{tracks:w,snapshot_id:m}};return d(v,{},g)},f.prototype.removeTracksFromPlaylistInPositions=function(u,p,m,g){var w={url:r+"/playlists/"+u+"/tracks",type:"DELETE",postData:{positions:p,snapshot_id:m}};return d(w,{},g)},f.prototype.uploadCustomPlaylistCoverImage=function(u,p,m){var g={url:r+"/playlists/"+u+"/images",type:"PUT",postData:p.replace(/^data:image\/jpeg;base64,/,""),contentType:"image/jpeg"};return d(g,{},m)},f.prototype.getAlbum=function(u,p,m){var g={url:r+"/albums/"+u};return d(g,p,m)},f.prototype.getAlbumTracks=function(u,p,m){var g={url:r+"/albums/"+u+"/tracks"};return d(g,p,m)},f.prototype.getAlbums=function(u,p,m){var g={url:r+"/albums/",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getTrack=function(u,p,m){var g={};return g.url=r+"/tracks/"+u,d(g,p,m)},f.prototype.getTracks=function(u,p,m){var g={url:r+"/tracks/",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getArtist=function(u,p,m){var g={url:r+"/artists/"+u};return d(g,p,m)},f.prototype.getArtists=function(u,p,m){var g={url:r+"/artists/",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getArtistAlbums=function(u,p,m){var g={url:r+"/artists/"+u+"/albums"};return d(g,p,m)},f.prototype.getArtistTopTracks=function(u,p,m,g){var w={url:r+"/artists/"+u+"/top-tracks",params:{country:p}};return d(w,m,g)},f.prototype.getArtistRelatedArtists=function(u,p,m){var g={url:r+"/artists/"+u+"/related-artists"};return d(g,p,m)},f.prototype.getFeaturedPlaylists=function(u,p){var m={url:r+"/browse/featured-playlists"};return d(m,u,p)},f.prototype.getNewReleases=function(u,p){var m={url:r+"/browse/new-releases"};return d(m,u,p)},f.prototype.getCategories=function(u,p){var m={url:r+"/browse/categories"};return d(m,u,p)},f.prototype.getCategory=function(u,p,m){var g={url:r+"/browse/categories/"+u};return d(g,p,m)},f.prototype.getCategoryPlaylists=function(u,p,m){var g={url:r+"/browse/categories/"+u+"/playlists"};return d(g,p,m)},f.prototype.search=function(u,p,m,g){var w={url:r+"/search/",params:{q:u,type:p.join(",")}};return d(w,m,g)},f.prototype.searchAlbums=function(u,p,m){return this.search(u,["album"],p,m)},f.prototype.searchArtists=function(u,p,m){return this.search(u,["artist"],p,m)},f.prototype.searchTracks=function(u,p,m){return this.search(u,["track"],p,m)},f.prototype.searchPlaylists=function(u,p,m){return this.search(u,["playlist"],p,m)},f.prototype.searchShows=function(u,p,m){return this.search(u,["show"],p,m)},f.prototype.searchEpisodes=function(u,p,m){return this.search(u,["episode"],p,m)},f.prototype.getAudioFeaturesForTrack=function(u,p){var m={};return m.url=r+"/audio-features/"+u,d(m,{},p)},f.prototype.getAudioFeaturesForTracks=function(u,p){var m={url:r+"/audio-features",params:{ids:u}};return d(m,{},p)},f.prototype.getAudioAnalysisForTrack=function(u,p){var m={};return m.url=r+"/audio-analysis/"+u,d(m,{},p)},f.prototype.getRecommendations=function(u,p){var m={url:r+"/recommendations"};return d(m,u,p)},f.prototype.getAvailableGenreSeeds=function(u){var p={url:r+"/recommendations/available-genre-seeds"};return d(p,{},u)},f.prototype.getMyDevices=function(u){var p={url:r+"/me/player/devices"};return d(p,{},u)},f.prototype.getMyCurrentPlaybackState=function(u,p){var m={url:r+"/me/player"};return d(m,u,p)},f.prototype.getMyCurrentPlayingTrack=function(u,p){var m={url:r+"/me/player/currently-playing"};return d(m,u,p)},f.prototype.transferMyPlayback=function(u,p,m){var g=p||{};g.device_ids=u;var w={type:"PUT",url:r+"/me/player",postData:g};return d(w,p,m)},f.prototype.play=function(u,p){u=u||{};var m="device_id"in u?{device_id:u.device_id}:null,g={};["context_uri","uris","offset","position_ms"].forEach(function(y){y in u&&(g[y]=u[y])});var w={type:"PUT",url:r+"/me/player/play",params:m,postData:g},v=typeof u=="function"?u:{};return d(w,v,p)},f.prototype.queue=function(u,p,m){p=p||{};var g="device_id"in p?{uri:u,device_id:p.device_id}:{uri:u},w={type:"POST",url:r+"/me/player/queue",params:g};return d(w,p,m)},f.prototype.pause=function(u,p){u=u||{};var m="device_id"in u?{device_id:u.device_id}:null,g={type:"PUT",url:r+"/me/player/pause",params:m};return d(g,u,p)},f.prototype.skipToNext=function(u,p){u=u||{};var m="device_id"in u?{device_id:u.device_id}:null,g={type:"POST",url:r+"/me/player/next",params:m};return d(g,u,p)},f.prototype.skipToPrevious=function(u,p){u=u||{};var m="device_id"in u?{device_id:u.device_id}:null,g={type:"POST",url:r+"/me/player/previous",params:m};return d(g,u,p)},f.prototype.seek=function(u,p,m){p=p||{};var g={position_ms:u};"device_id"in p&&(g.device_id=p.device_id);var w={type:"PUT",url:r+"/me/player/seek",params:g};return d(w,p,m)},f.prototype.setRepeat=function(u,p,m){p=p||{};var g={state:u};"device_id"in p&&(g.device_id=p.device_id);var w={type:"PUT",url:r+"/me/player/repeat",params:g};return d(w,p,m)},f.prototype.setVolume=function(u,p,m){p=p||{};var g={volume_percent:u};"device_id"in p&&(g.device_id=p.device_id);var w={type:"PUT",url:r+"/me/player/volume",params:g};return d(w,p,m)},f.prototype.setShuffle=function(u,p,m){p=p||{};var g={state:u};"device_id"in p&&(g.device_id=p.device_id);var w={type:"PUT",url:r+"/me/player/shuffle",params:g};return d(w,p,m)},f.prototype.getShow=function(u,p,m){var g={};return g.url=r+"/shows/"+u,d(g,p,m)},f.prototype.getShows=function(u,p,m){var g={url:r+"/shows/",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getMySavedShows=function(u,p){var m={url:r+"/me/shows"};return d(m,u,p)},f.prototype.addToMySavedShows=function(u,p,m){var g={url:r+"/me/shows",type:"PUT",postData:u};return d(g,p,m)},f.prototype.removeFromMySavedShows=function(u,p,m){var g={url:r+"/me/shows",type:"DELETE",postData:u};return d(g,p,m)},f.prototype.containsMySavedShows=function(u,p,m){var g={url:r+"/me/shows/contains",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getShowEpisodes=function(u,p,m){var g={url:r+"/shows/"+u+"/episodes"};return d(g,p,m)},f.prototype.getEpisode=function(u,p,m){var g={};return g.url=r+"/episodes/"+u,d(g,p,m)},f.prototype.getEpisodes=function(u,p,m){var g={url:r+"/episodes/",params:{ids:u.join(",")}};return d(g,p,m)},f.prototype.getAccessToken=function(){return n},f.prototype.setAccessToken=function(u){n=u},f.prototype.setPromiseImplementation=function(u){var p=!1;try{var m=new u(function(g){g()});typeof m.then=="function"&&typeof m.catch=="function"&&(p=!0)}catch(g){console.error(g)}if(p)s=u;else throw new Error("Unsupported implementation of Promises/A+")},f}();e.exports=t})(gy);var Pj=gy.exports;const Ej=wu(Pj),Tj="7cab80d02df44a5bb96725be60a45875",yy="https://159.195.9.107:3443/callback.html";console.log("🔍 Debug - Current redirect URI:",yy);console.log("🔍 Debug - Environment VITE_REDIRECT_URI:","https://159.195.9.107:3443/callback.html");const Vo=new Ej,Mj=e=>{const t=(e==null?void 0:e.forceDialog)??!0,r=["user-read-private","user-read-email","user-read-recently-played","user-top-read","playlist-read-private","playlist-read-collaborative","playlist-modify-public","playlist-modify-private","user-read-playback-state","user-modify-playback-state","user-read-currently-playing","ugc-image-upload"].join(" "),s=`https://accounts.spotify.com/authorize?${new URLSearchParams({client_id:Tj,response_type:"code",redirect_uri:yy,scope:r,show_dialog:t?"true":"false"}).toString()}`;return console.log("🔍 Debug - Generated Spotify Auth URL:",s),s},Aj=async(e,t)=>{Vo.setAccessToken(e),await Vo.play({uris:[t]})},_j=async e=>{Vo.setAccessToken(e),await Vo.pause()},Lj=()=>{const[e,t]=S.useState(!1),[r,n]=S.useState(!1),[s,i]=S.useState(null),o=()=>{t(!0);const l=navigator.userAgent||navigator.vendor||window.opera,c=/iPad|iPhone|iPod/.test(l)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1,d=/Android/.test(l),u=Mj({forceDialog:!(c||d)});window.location.href=u},a=[{icon:Ke,title:"Last Listened",description:"Discover what your partner is listening to right now and play it instantly"},{icon:Nr,title:"Mixed Playlist",description:"AI-powered playlists that blend your musical tastes perfectly"},{icon:et,title:"Memory Lane",description:"Create beautiful musical memories and shared experiences together"}];return h.jsxs("div",{className:"min-h-screen flex items-center justify-center px-4 bg-black",children:[h.jsxs("div",{className:"max-w-4xl w-full relative",children:[h.jsxs(z.div,{initial:{opacity:0,y:50},animate:{opacity:1,y:0},transition:{duration:.8},className:"text-center mb-12",children:[h.jsx(z.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring",stiffness:200},className:"w-20 h-20 mx-auto mb-6 bg-gradient-to-br from-pink-500 to-red-500 rounded-full flex items-center justify-center",children:h.jsx(et,{className:"w-10 h-10 text-white"})}),h.jsxs("h1",{className:"text-5xl md:text-6xl font-bold mb-4",children:[h.jsx("span",{className:"gradient-text",children:"Our Musical"}),h.jsx("br",{}),h.jsx("span",{className:"text-white",children:"Journey"})]}),h.jsx("p",{className:"text-xl text-white/70 max-w-2xl mx-auto leading-relaxed",children:"A private space where two hearts connect through music. Discover, share, and create beautiful musical memories together."})]}),h.jsx(z.div,{initial:{opacity:0,y:30},animate:{opacity:1,y:0},transition:{delay:.4,duration:.8},className:"grid md:grid-cols-3 gap-6 mb-12",children:a.map((l,c)=>h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5+c*.1},whileHover:{y:-8,scale:1.03},className:"glass-bubble rounded-3xl p-8 text-center group cursor-pointer",children:[h.jsx(z.div,{whileHover:{rotate:15,scale:1.15},className:"w-16 h-16 mx-auto mb-6 bg-gradient-to-br from-purple-500/30 via-blue-500/30 to-pink-500/30 rounded-2xl flex items-center justify-center backdrop-blur-sm",children:h.jsx(l.icon,{className:"w-8 h-8 text-white"})}),h.jsx("h3",{className:"text-2xl font-bold text-white mb-3",children:l.title}),h.jsx("p",{className:"text-white/70 text-sm leading-relaxed",children:l.description})]},l.title))}),h.jsxs(z.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},transition:{delay:.8,duration:.6},className:"glass-fluid rounded-3xl p-10 max-w-lg mx-auto",children:[h.jsxs("div",{className:"text-center mb-8",children:[h.jsx(z.div,{initial:{scale:0},animate:{scale:1},transition:{delay:1,type:"spring",stiffness:200},className:"w-20 h-20 mx-auto mb-6 bg-gradient-to-br from-purple-500/30 via-blue-500/30 to-pink-500/30 rounded-2xl flex items-center justify-center backdrop-blur-sm",children:h.jsx(Wc,{className:"w-10 h-10 text-white"})}),h.jsx("h2",{className:"text-3xl font-bold text-white mb-3",children:"Begin Your Journey"}),h.jsx("p",{className:"text-white/70 text-lg",children:"Connect your Spotify account to start your musical love story"})]}),h.jsx(z.button,{whileHover:{scale:1.05,boxShadow:"0 15px 40px rgba(147, 51, 234, 0.4)"},whileTap:{scale:.95},onClick:o,disabled:e,className:"w-full bg-gradient-to-r from-purple-600 via-blue-600 to-pink-600 hover:from-purple-700 hover:via-blue-700 hover:to-pink-700 text-white font-bold py-5 px-8 rounded-2xl transition-all duration-300 flex items-center justify-center space-x-3 disabled:opacity-50 shadow-2xl",children:e?h.jsx("div",{className:"w-6 h-6 border-2 border-white border-t-transparent rounded-full animate-spin"}):h.jsxs(h.Fragment,{children:[h.jsx("span",{className:"text-lg",children:"Connect with Spotify"}),h.jsx(_k,{className:"w-6 h-6"})]})}),h.jsx("p",{className:"text-sm text-white/60 text-center mt-6 leading-relaxed",children:"We'll only access your listening history and playlist data to create your personalized musical journey"})]}),h.jsx(z.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:1,duration:.6},className:"text-center mt-12",children:h.jsx("p",{className:"text-white/40 text-sm",children:"Made with 💕 for a special someone"})})]}),h.jsx(Dj,{open:r,onClose:()=>n(!1),authUrl:s})]})};function Dj({open:e,onClose:t,authUrl:r}){if(!e||!r)return null;const n=()=>{window.open(r,"_blank","noopener,noreferrer")||(window.location.href=r)},s=async()=>{try{await navigator.clipboard.writeText(r),alert("Link copied. Paste in Safari/Chrome to continue.")}catch{}};return h.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center px-4",children:[h.jsx("div",{className:"absolute inset-0 bg-black/70",onClick:t}),h.jsxs("div",{className:"relative z-10 w-full max-w-md glass-fluid rounded-2xl p-6 text-white",children:[h.jsx("h3",{className:"text-xl font-bold mb-2",children:"Open Spotify Login"}),h.jsx("p",{className:"text-white/80 text-sm mb-4",children:"If this opened inside another app (Instagram, Facebook, Twitter), use your system browser to avoid password overlays."}),h.jsxs("div",{className:"grid grid-cols-1 gap-3",children:[h.jsx("button",{onClick:n,className:"w-full bg-white/10 hover:bg-white/20 border border-white/20 rounded-xl py-3 font-medium",children:"Open in new tab"}),h.jsx("button",{onClick:s,className:"w-full bg-white/10 hover:bg-white/20 border border-white/20 rounded-xl py-3 font-medium",children:"Copy link"}),h.jsx("button",{onClick:t,className:"w-full bg-transparent text-white/70 underline py-2",children:"Cancel"})]})]})]})}const Rj=()=>{var N,P,V,T,O,j,F,D,G,M,W,_,A,I,R,E,H,X,ee,q,me,Rr,_t,St,Qe,on,Qn;const{currentUser:e,partnerUser:t,theme:r}=oe(),n=en(r),[s,i]=S.useState([]),[o,a]=S.useState(!1),[l,c]=S.useState(null),[d,f]=S.useState(""),[u,p]=S.useState(!1),[m,g]=S.useState(null),[w,v]=S.useState(null);S.useEffect(()=>{let B;const le=async()=>{var ye,be,Fe;try{const Lt=(ye=e==null?void 0:e.user)==null?void 0:ye.id;if(Lt){const an=await te(`/users/${Lt}/recently-played`),Zt=oe.getState().currentUser;Zt&&oe.getState().setCurrentUser({...Zt,recentlyPlayed:an})}const Zn=(Fe=(be=oe.getState().partnerUser)==null?void 0:be.user)==null?void 0:Fe.id;if(Zn){const an=await te(`/users/${Zn}/recently-played`),Zt=oe.getState().partnerUser;Zt&&oe.getState().setPartnerUser({...Zt,recentlyPlayed:an})}}catch{}B=setTimeout(le,3e4)};return le(),()=>clearTimeout(B)},[(N=e==null?void 0:e.user)==null?void 0:N.id,(P=t==null?void 0:t.user)==null?void 0:P.id]),S.useEffect(()=>{(async()=>{var le;if((le=e==null?void 0:e.user)!=null&&le.id){a(!0);try{const ye=await te(`/partners/requests/${e.user.id}`);i(ye)}catch{i([])}finally{a(!1)}}})()},[(V=e==null?void 0:e.user)==null?void 0:V.id]),S.useEffect(()=>{let B;const le=async()=>{var be;if((be=e==null?void 0:e.user)!=null&&be.id)try{const Fe=await te(`/users/${e.user.id}/status`);c(Fe)}catch{}},ye=()=>{if(!(l!=null&&l.nextSyncAt)){f("");return}const be=l.nextSyncAt-Date.now();if(be<=0){f("now");return}const Fe=Math.floor(be/6e4),Lt=Math.floor(be%6e4/1e3);f(`${Fe}m ${Lt}s`)};return le(),B=setInterval(()=>{ye()},1e3),()=>clearInterval(B)},[(T=e==null?void 0:e.user)==null?void 0:T.id,l==null?void 0:l.nextSyncAt]),S.useEffect(()=>{let B;const le=async()=>{var ye,be;try{const Fe=(ye=e==null?void 0:e.user)==null?void 0:ye.id;Fe&&(g(await te(`/users/${Fe}/now-playing`)),(be=t==null?void 0:t.user)!=null&&be.id?v(await te(`/users/${t.user.id}/now-playing`)):v(null))}catch{}B=setTimeout(le,8e3)};return le(),()=>clearTimeout(B)},[(O=e==null?void 0:e.user)==null?void 0:O.id,(j=t==null?void 0:t.user)==null?void 0:j.id]);const y=async()=>{var B;if((B=e==null?void 0:e.user)!=null&&B.id){p(!0);try{await Et(`/users/${e.user.id}/sync`);const le=await te(`/users/${e.user.id}/status`);c(le);const[ye,be]=await Promise.all([te(`/users/${e.user.id}/recently-played`),te(`/users/${e.user.id}/top-tracks?time_range=short_term`)]),Fe=oe.getState().currentUser;Fe&&oe.getState().setCurrentUser({...Fe,recentlyPlayed:ye,topTracks:be.map(Lt=>Lt.track)}),ce.success("Synced latest data")}catch{ce.error("Failed to sync")}finally{p(!1)}}},x=async B=>{await Et(`/partners/requests/${B}/accept`),i(le=>le.filter(ye=>ye.id!==B))},b=async B=>{await Et(`/partners/requests/${B}/decline`),i(le=>le.filter(ye=>ye.id!==B))},k=[{title:"Last Listened",description:"See what your partner is listening to right now",icon:Ke,href:"/last-listened",primaryColor:((F=n.cssVars)==null?void 0:F.primary)||"#1db954",secondaryColor:((D=n.cssVars)==null?void 0:D.secondary)||"#1ed760",accentColor:((G=n.cssVars)==null?void 0:G.accent)||"#00e676"},{title:"Mixed Playlist",description:"Create AI-powered playlists blending both your tastes",icon:oy,href:"/mixed-playlist",primaryColor:((M=n.cssVars)==null?void 0:M.secondary)||"#1ed760",secondaryColor:((W=n.cssVars)==null?void 0:W.accent)||"#00e676",accentColor:((_=n.cssVars)==null?void 0:_.primary)||"#1db954"},{title:"Memory Lane",description:"Your shared musical journey and memories",icon:Nr,href:"/memory-lane",primaryColor:((A=n.cssVars)==null?void 0:A.accent)||"#00e676",secondaryColor:((I=n.cssVars)==null?void 0:I.primary)||"#1db954",accentColor:((R=n.cssVars)==null?void 0:R.secondary)||"#1ed760"}],C=()=>{var B;return(B=e==null?void 0:e.recentlyPlayed)!=null&&B[0]?_n(e.recentlyPlayed[0].played_at):null};return h.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[h.jsxs("h1",{className:"text-4xl font-bold text-white mb-2",children:["Welcome back, ",h.jsx("span",{className:"gradient-text",children:(E=e==null?void 0:e.user)==null?void 0:E.display_name})]}),h.jsx("p",{className:"text-white/70 text-lg",children:"Ready to explore your musical connection together?"})]}),h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"grid md:grid-cols-2 gap-6 mb-8",children:[h.jsxs("div",{className:"glass rounded-2xl p-6",children:[h.jsx("div",{className:"text-white/70 mb-2",children:"You"}),m!=null&&m.is_playing&&(m!=null&&m.item)?h.jsxs("div",{className:"flex items-center gap-4",children:[h.jsx("img",{src:((ee=(X=(H=m.item.album)==null?void 0:H.images)==null?void 0:X[0])==null?void 0:ee.url)||"/placeholder-album.png",className:"w-14 h-14 rounded"}),h.jsxs("div",{className:"min-w-0",children:[h.jsx("div",{className:"text-white font-semibold truncate",children:m.item.name}),h.jsx("div",{className:"text-white/70 text-sm truncate",children:(q=m.item.artists)==null?void 0:q.map(B=>B.name).join(", ")})]})]}):h.jsx("div",{className:"text-white/50",children:"Not playing"})]}),h.jsxs("div",{className:"glass rounded-2xl p-6",children:[h.jsx("div",{className:"text-white/70 mb-2",children:"Partner"}),w!=null&&w.is_playing&&(w!=null&&w.item)?h.jsxs("div",{className:"flex items-center gap-4",children:[h.jsx("img",{src:((_t=(Rr=(me=w.item.album)==null?void 0:me.images)==null?void 0:Rr[0])==null?void 0:_t.url)||"/placeholder-album.png",className:"w-14 h-14 rounded"}),h.jsxs("div",{className:"min-w-0",children:[h.jsx("div",{className:"text-white font-semibold truncate",children:w.item.name}),h.jsx("div",{className:"text-white/70 text-sm truncate",children:(St=w.item.artists)==null?void 0:St.map(B=>B.name).join(", ")})]})]}):h.jsx("div",{className:"text-white/50",children:"Not playing"})]})]}),h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:"mb-8",children:[h.jsxs("div",{className:"flex items-center justify-between mb-4",children:[h.jsx("div",{className:"text-white/70 text-sm",children:(l==null?void 0:l.lastSyncedAt)&&h.jsxs("span",{children:["Last sync: ",new Date(l.lastSyncedAt).toLocaleTimeString()," • Next in: ",d||"—"]})}),h.jsx("button",{onClick:y,disabled:u,className:"bg-white/10 hover:bg-white/20 text-white px-4 py-2 rounded-lg text-sm disabled:opacity-50",children:u?"Refreshing…":"Hard Refresh"})]}),t?h.jsx("div",{className:"glass-bubble rounded-3xl p-8 border border-spotify-green/30 glow",children:h.jsxs("div",{className:"flex items-center space-x-6",children:[h.jsx("div",{className:"w-16 h-16 bg-gradient-to-br from-spotify-green to-green-600 rounded-2xl flex items-center justify-center",children:h.jsx(et,{className:"w-8 h-8 text-white"})}),h.jsxs("div",{children:[h.jsxs("h3",{className:"text-xl font-semibold text-white",children:["Connected with ",(Qe=t.user)==null?void 0:Qe.display_name]}),h.jsx("p",{className:"text-white/70",children:"Your musical journey is ready to begin! 💕"})]})]})}):h.jsx("div",{className:"glass-bubble rounded-3xl p-8 border border-orange-500/30",children:h.jsxs("div",{className:"flex items-center space-x-6",children:[h.jsx("div",{className:"w-16 h-16 bg-gradient-to-br from-orange-500 to-red-500 rounded-2xl flex items-center justify-center",children:h.jsx(Uc,{className:"w-8 h-8 text-white"})}),h.jsxs("div",{children:[h.jsx("h3",{className:"text-xl font-semibold text-white",children:"Invite your partner"}),h.jsx("p",{className:"text-white/70 mb-2",children:"Ask your partner to search you in the app and send a request."}),o?h.jsx("div",{className:"text-white/60",children:"Loading requests..."}):s.length>0?h.jsx("div",{className:"space-y-3",children:s.map(B=>h.jsxs("div",{className:"flex items-center justify-between bg-white/5 rounded-lg p-3",children:[h.jsxs("div",{className:"text-white/80 text-sm",children:["Request from ",B.from_user_id]}),h.jsxs("div",{className:"space-x-2",children:[h.jsx("button",{onClick:()=>x(B.id),className:"bg-spotify-green hover:bg-spotify-green/90 text-white px-3 py-1 rounded-md text-sm",children:"Accept"}),h.jsx("button",{onClick:()=>b(B.id),className:"bg-white/10 hover:bg-white/20 text-white px-3 py-1 rounded-md text-sm",children:"Decline"})]})]},B.id))}):h.jsx("div",{className:"text-white/60 text-sm",children:"No incoming requests yet"})]})]})})]}),h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.2},className:"grid grid-cols-1 md:grid-cols-3 gap-6 mb-8",children:[h.jsx("div",{className:"glass-bubble rounded-2xl p-6",children:h.jsxs("div",{className:"flex items-center space-x-4",children:[h.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-blue-500/30 to-cyan-500/30 rounded-xl flex items-center justify-center",children:h.jsx(Un,{className:"w-6 h-6 text-blue-400"})}),h.jsxs("div",{children:[h.jsx("p",{className:"text-white/70 text-sm",children:"Your last played"}),h.jsx("p",{className:"text-white font-semibold",children:C()||"No recent plays"})]})]})}),h.jsx("div",{className:"glass-bubble rounded-2xl p-6",children:h.jsxs("div",{className:"flex items-center space-x-4",children:[h.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-green-500/30 to-emerald-500/30 rounded-xl flex items-center justify-center",children:h.jsx(uy,{className:"w-6 h-6 text-green-400"})}),h.jsxs("div",{children:[h.jsx("p",{className:"text-white/70 text-sm",children:"Top tracks analyzed"}),h.jsxs("p",{className:"text-white font-semibold",children:[((on=e==null?void 0:e.topTracks)==null?void 0:on.length)||0," songs"]})]})]})}),h.jsx("div",{className:"glass-bubble rounded-2xl p-6",children:h.jsxs("div",{className:"flex items-center space-x-4",children:[h.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-purple-500/30 to-pink-500/30 rounded-xl flex items-center justify-center",children:h.jsx(Ls,{className:"w-6 h-6 text-purple-400"})}),h.jsxs("div",{children:[h.jsx("p",{className:"text-white/70 text-sm",children:"Recently played"}),h.jsxs("p",{className:"text-white font-semibold",children:[((Qn=e==null?void 0:e.recentlyPlayed)==null?void 0:Qn.length)||0," tracks"]})]})]})})]}),h.jsx(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},className:"grid md:grid-cols-3 gap-6",children:k.map((B,le)=>h.jsx(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.4+le*.1},whileHover:{y:-5,scale:1.02},children:h.jsx(Xi,{to:B.href,children:h.jsxs("div",{className:`glass rounded-2xl p-6 h-full border ${B.borderColor} group cursor-pointer transition-all duration-300 hover:shadow-xl`,children:[h.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center mb-4 group-hover:scale-110 transition-transform duration-300",style:{background:`linear-gradient(135deg, ${B.primaryColor}20 0%, ${B.secondaryColor}10 100%)`,border:`1px solid ${B.primaryColor}30`},children:h.jsx(B.icon,{className:"w-6 h-6",style:{color:B.primaryColor}})}),h.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:B.title}),h.jsx("p",{className:"text-white/70 text-sm leading-relaxed mb-4",children:B.description}),h.jsx("div",{className:"w-full h-1 rounded-full opacity-0 group-hover:opacity-100 transition-opacity duration-300",style:{background:`linear-gradient(90deg, ${B.primaryColor} 0%, ${B.secondaryColor} 100%)`}})]})})},B.title))}),(e==null?void 0:e.recentlyPlayed)&&e.recentlyPlayed.length>0&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.6},className:"mt-8",children:[h.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"Your Recent Activity"}),h.jsx("div",{className:"glass rounded-2xl p-6",children:h.jsx("div",{className:"space-y-4",children:e.recentlyPlayed.slice(0,3).map((B,le)=>{var ye,be;return h.jsxs(z.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.7+le*.1},className:"flex items-center space-x-4 p-3 rounded-lg hover:bg-white/5 transition-colors",children:[h.jsx("img",{src:((ye=B.track.album.images[0])==null?void 0:ye.url)||"/placeholder-album.png",alt:B.track.album.name,className:"w-12 h-12 rounded-lg object-cover"}),h.jsxs("div",{className:"flex-1",children:[h.jsx("h4",{className:"text-white font-medium",children:B.track.name}),h.jsx("p",{className:"text-white/70 text-sm",children:(be=B.track.artists[0])==null?void 0:be.name})]}),h.jsx("div",{className:"text-white/50 text-sm",children:_n(B.played_at)})]},B.track.id)})})})]})]})};let Fi=!1;const Xh=()=>{const[e]=Kx(),t=ea(),{setCurrentUser:r,setPartnerUser:n,currentUser:s}=oe(),[i,o]=S.useState("loading"),[a,l]=S.useState("");S.useEffect(()=>{(async()=>{if(Fi){console.log("🔍 CallbackPage - Already processing globally, skipping...");return}Fi=!0,console.log("🔍 CallbackPage - Global processing flag set to TRUE");try{const u=e.get("code"),p=e.get("error");if(console.log("🔍 CallbackPage - Code:",u),console.log("🔍 CallbackPage - Error:",p),p)throw new Error("Spotify authorization was denied");if(!u)throw new Error("No authorization code received");l("Exchanging authorization code..."),console.log("🔍 CallbackPage - Exchanging code with backend...");const m=await F3("/auth/exchange",{code:u});l("Syncing your music data..."),await Et(`/users/${m.uid}/sync`,void 0,m.token),l("Loading your profile...");const[g,w,v]=await Promise.all([te(`/users/${m.uid}`),te(`/users/${m.uid}/recently-played`),te(`/users/${m.uid}/top-tracks?time_range=short_term`)]),y={user:g,accessToken:m.access_token,refreshToken:m.refresh_token,isAuthenticated:!0,recentlyPlayed:w,topTracks:v.map(x=>x.track),topArtists:[],jwt:m.token};localStorage.setItem("spotify-user",JSON.stringify(y)),s?(n(y),localStorage.setItem("spotify-partner",JSON.stringify(y)),l("Partner connected! Your musical journey begins...")):(r(y),l("Welcome! Setting up your musical journey...")),o("success"),ce.success(s?"Partner connected successfully!":"Successfully connected to Spotify!",{duration:3e3}),setTimeout(()=>{t("/"),setTimeout(()=>{Fi=!1,console.log("🔍 CallbackPage - Global processing flag set to FALSE (after success)")},1e3)},2e3)}catch(u){console.error("🔍 CallbackPage - ERROR:",u),console.error("🔍 CallbackPage - Error details:",{message:u instanceof Error?u.message:"Unknown error",stack:u instanceof Error?u.stack:void 0}),o("error"),l(u instanceof Error?u.message:"An unexpected error occurred"),ce.error("Failed to connect to Spotify. Please try again."),setTimeout(()=>{t("/"),setTimeout(()=>{Fi=!1,console.log("🔍 CallbackPage - Global processing flag set to FALSE (after error)")},1e3)},3e3)}})()},[e,t,r,n,s]);const c=()=>{switch(i){case"loading":return h.jsx(Ik,{className:"w-12 h-12 text-spotify-green animate-spin"});case"success":return h.jsx(Rk,{className:"w-12 h-12 text-green-400"});case"error":return h.jsx(Hk,{className:"w-12 h-12 text-red-400"})}},d=()=>{switch(i){case"loading":return"border-spotify-green/30";case"success":return"border-green-400/30";case"error":return"border-red-400/30"}};return h.jsx("div",{className:"min-h-screen flex items-center justify-center px-4 bg-black",children:h.jsxs(z.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"glass-fluid rounded-3xl p-10 max-w-md w-full text-center",children:[h.jsx(z.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring",stiffness:200},className:`w-20 h-20 mx-auto mb-6 rounded-full border-2 flex items-center justify-center ${d()}`,children:c()}),h.jsxs(z.h2,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},className:"text-2xl font-bold text-white mb-4",children:[i==="loading"&&"Connecting...",i==="success"&&"Success!",i==="error"&&"Connection Failed"]}),h.jsx(z.p,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.4},className:"text-white/70 mb-6",children:a}),i==="loading"&&h.jsx(z.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.5},className:"w-full bg-white/10 rounded-full h-2 mb-4",children:h.jsx(z.div,{className:"bg-spotify-green h-2 rounded-full",initial:{width:0},animate:{width:"100%"},transition:{duration:3,ease:"easeInOut"}})}),i==="error"&&h.jsx(z.button,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5},whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>t("/"),className:"bg-spotify-green hover:bg-spotify-green/90 text-white font-semibold py-3 px-6 rounded-lg transition-all duration-300",children:"Try Again"}),i==="success"&&h.jsx(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5},className:"text-spotify-green text-sm",children:"Redirecting you to your musical journey..."})]})})},Vj=()=>{var g,w,v;const{currentUser:e,partnerUser:t,currentTrack:r,isPlaying:n,setCurrentTrack:s,setIsPlaying:i,theme:o}=oe(),a=en(o),[l,c]=S.useState(!1),[d,f]=S.useState(null),u=S.useMemo(()=>{const y=((e==null?void 0:e.recentlyPlayed)||[]).map(N=>({who:"you",played_at:new Date(N.played_at).getTime(),track:N.track,key:`you-${N.track.id}-${N.played_at}`})),x=((t==null?void 0:t.recentlyPlayed)||[]).map(N=>({who:"partner",played_at:new Date(N.played_at).getTime(),track:N.track,key:`partner-${N.track.id}-${N.played_at}`})),b=[...y,...x].sort((N,P)=>P.played_at-N.played_at).slice(0,30),k=new Set,C=new Set;return b.forEach(N=>{const P=N.track.id;k.has(P)?C.add(P):k.add(P)}),{items:b,overlaps:C}},[e==null?void 0:e.recentlyPlayed,t==null?void 0:t.recentlyPlayed]),p=async(y,x)=>{var b,k;if(!(e!=null&&e.accessToken)){ce.error("Not authenticated with Spotify");return}try{c(!0),f(x),n&&d===x?(await _j(e.accessToken),i(!1),s(null),f(null)):(await Aj(e.accessToken,y),i(!0),s(((k=(b=e.recentlyPlayed)==null?void 0:b.find(C=>C.track.id===x))==null?void 0:k.track)||null)),ce.success(n&&d===x?"Paused":"Now playing")}catch(C){console.error("Playback error:",C),ce.error("Failed to play track. Make sure Spotify is open on your device.")}finally{c(!1)}},m=({user:y,title:x,isPartner:b=!1})=>{var C,N,P,V,T;if(!((C=y==null?void 0:y.recentlyPlayed)!=null&&C.length))return h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-8 text-center",children:[h.jsx(Ke,{className:"w-16 h-16 mx-auto mb-4 text-white/30"}),h.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"No recent activity"}),h.jsxs("p",{className:"text-white/70",children:[b?"Your partner":"You"," haven't played any music recently"]})]});const k=y.recentlyPlayed[0];return h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-6",children:[h.jsxs("div",{className:"flex items-center space-x-4 mb-6",children:[h.jsx("div",{className:`w-12 h-12 rounded-full flex items-center justify-center ${b?"bg-gradient-to-br from-pink-500 to-purple-600":"bg-gradient-to-br from-blue-500 to-cyan-600"}`,children:h.jsx(Ls,{className:"w-6 h-6 text-white"})}),h.jsxs("div",{children:[h.jsx("h2",{className:"text-2xl font-bold text-white",children:x}),h.jsxs("p",{className:"text-white/70",children:["Last played: ",_n(k.played_at)]})]})]}),h.jsx(z.div,{whileHover:{scale:1.02},className:"bg-white/5 rounded-xl p-6 mb-6 border border-white/10",children:h.jsxs("div",{className:"flex items-center space-x-4 sm:space-x-6",children:[h.jsxs("div",{className:"relative flex-shrink-0",children:[h.jsx("img",{src:((N=k.track.album.images[0])==null?void 0:N.url)||"/placeholder-album.png",alt:k.track.album.name,className:"w-16 h-16 sm:w-20 sm:h-20 rounded-lg object-cover"}),n&&d===k.track.id&&h.jsx("div",{className:"absolute inset-0 rounded-lg flex items-center justify-center",style:{backgroundColor:`${((P=a.cssVars)==null?void 0:P.primary)||"#1db954"}20`},children:h.jsx(Uk,{className:"w-6 h-6",style:{color:((V=a.cssVars)==null?void 0:V.primary)||"#1db954"}})})]}),h.jsxs("div",{className:"flex-1",children:[h.jsx("h3",{className:"text-xl font-semibold text-white mb-1",children:k.track.name}),h.jsx("p",{className:"text-white/70 mb-2",children:k.track.artists.map(O=>O.name).join(", ")}),h.jsxs("p",{className:"text-white/50 text-sm",children:[k.track.album.name," • ",Ds(k.track.duration_ms)]})]}),h.jsxs("div",{className:"flex items-center space-x-3",children:[h.jsx("button",{onClick:()=>p(k.track.external_urls.spotify,k.track.id),disabled:l,className:"w-12 h-12 rounded-full flex items-center justify-center transition-all duration-300 text-white disabled:opacity-50",style:{backgroundColor:n&&d===k.track.id?"#ef4444":((T=a.cssVars)==null?void 0:T.primary)||"#1db954"},onMouseEnter:O=>{l||(O.currentTarget.style.opacity="0.9")},onMouseLeave:O=>{l||(O.currentTarget.style.opacity="1")},children:l&&d===k.track.id?h.jsx("div",{className:"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"}):n&&d===k.track.id?h.jsx($k,{className:"w-5 h-5"}):h.jsx(Wh,{className:"w-5 h-5 ml-0.5"})}),h.jsx("a",{href:k.track.external_urls.spotify,target:"_blank",rel:"noopener noreferrer",className:"w-10 h-10 rounded-full bg-white/10 hover:bg-white/20 flex items-center justify-center transition-colors",children:h.jsx(iy,{className:"w-4 h-4 text-white"})})]})]})}),h.jsxs("div",{children:[h.jsxs("h3",{className:"text-lg font-semibold text-white mb-4 flex items-center space-x-2",children:[h.jsx(Un,{className:"w-5 h-5"}),h.jsx("span",{children:"Recent History"})]}),h.jsx("div",{className:"space-y-3",children:y.recentlyPlayed.slice(0,5).map((O,j)=>{var F,D,G;return h.jsxs(z.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:j*.1},className:"flex items-center space-x-4 p-3 rounded-lg hover:bg-white/5 transition-colors group",children:[h.jsx("img",{src:((F=O.track.album.images[0])==null?void 0:F.url)||"/placeholder-album.png",alt:O.track.album.name,className:"w-12 h-12 rounded-lg object-cover"}),h.jsxs("div",{className:"flex-1",children:[h.jsx("h4",{className:"text-white font-medium group-hover:text-spotify-green transition-colors",children:O.track.name}),h.jsx("p",{className:"text-white/70 text-sm",children:(D=O.track.artists[0])==null?void 0:D.name})]}),h.jsx("div",{className:"text-white/50 text-sm",children:_n(O.played_at)}),h.jsx("button",{onClick:()=>p(O.track.external_urls.spotify,O.track.id),disabled:l,className:"opacity-0 group-hover:opacity-100 w-8 h-8 rounded-full flex items-center justify-center transition-all disabled:opacity-50",style:{backgroundColor:((G=a.cssVars)==null?void 0:G.primary)||"#1db954"},onMouseEnter:M=>{l||(M.currentTarget.style.opacity="0.9")},onMouseLeave:M=>{l||(M.currentTarget.style.opacity="1")},children:h.jsx(Wh,{className:"w-4 h-4 text-white ml-0.5"})})]},O.track.id)})})]})]})};return h.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[h.jsxs("h1",{className:"text-4xl font-bold text-white mb-2 flex items-center space-x-3",children:[h.jsx(et,{className:"w-10 h-10",style:{color:((g=a.cssVars)==null?void 0:g.primary)||"#1db954"}}),h.jsx("span",{children:"What's Playing"})]}),h.jsx("p",{className:"text-white/70 text-lg",children:"Discover what you and your partner are listening to right now"})]}),h.jsxs("div",{className:"grid lg:grid-cols-2 gap-8",children:[e&&h.jsx(m,{user:e,title:`${(w=e.user)==null?void 0:w.display_name}'s Music`,isPartner:!1}),t&&h.jsx(m,{user:t,title:`${(v=t.user)==null?void 0:v.display_name}'s Music`,isPartner:!0}),!t&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-8 text-center",children:[h.jsx(et,{className:"w-16 h-16 mx-auto mb-4 text-pink-400"}),h.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"Waiting for your partner"}),h.jsx("p",{className:"text-white/70 mb-4",children:"Invite your partner to connect their Spotify account to see their music"}),h.jsx("button",{className:"bg-pink-500 hover:bg-pink-600 text-white px-6 py-3 rounded-lg transition-colors",children:"Send Invitation"})]})]}),e&&t&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-8 mt-8",children:[h.jsxs("h3",{className:"text-lg font-semibold text-white mb-4 flex items-center space-x-2",children:[h.jsx(Un,{className:"w-5 h-5"}),h.jsx("span",{children:"Shared Timeline"})]}),h.jsx("div",{className:"space-y-3",children:u.items.map(y=>{var x,b,k,C,N;return h.jsxs("div",{className:"flex items-center gap-4 p-3 rounded-lg bg-white/5",children:[h.jsx("img",{src:((k=(b=(x=y.track.album)==null?void 0:x.images)==null?void 0:b[0])==null?void 0:k.url)||"/placeholder-album.png",alt:((C=y.track.album)==null?void 0:C.name)||"Album",className:"w-10 h-10 rounded"}),h.jsxs("div",{className:"flex-1 min-w-0",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("span",{className:"text-white font-medium text-sm sm:text-base truncate",children:y.track.name}),u.overlaps.has(y.track.id)&&h.jsx("span",{className:"text-pink-400 text-sm flex-shrink-0",children:"💕"})]}),h.jsx("div",{className:"text-white/70 text-xs sm:text-sm truncate",children:(N=y.track.artists)==null?void 0:N.map(P=>P.name).join(", ")})]}),h.jsxs("div",{className:"text-white/50 text-xs w-32 text-right",children:[_n(new Date(y.played_at).toISOString()),h.jsx("div",{className:"text-white/60",children:y.who==="you"?"You":"Partner"})]})]},y.key)})})]})]})},Fj=({imageUrl:e,alt:t,fallbackGradient:r})=>{const[n,s]=S.useState(null),[i,o]=S.useState(!0),[a,l]=S.useState(!1);return S.useEffect(()=>{e.startsWith("http")?(s(e),o(!1)):(async()=>{try{const d=await fetch(`${Kn}${e}`);if(d.ok){const f=await d.json();s(f.dataUrl)}else l(!0)}catch{l(!0)}finally{o(!1)}})()},[e]),i?h.jsx("div",{className:"w-full h-full bg-gradient-to-br from-gray-500 to-gray-600 flex items-center justify-center",children:h.jsx(Ke,{className:"w-8 h-8 text-white animate-pulse"})}):a||!n?h.jsx("div",{className:`w-full h-full flex items-center justify-center ${r}`,children:h.jsx(Ke,{className:"w-8 h-8 text-white"})}):h.jsx("img",{src:n,alt:t,className:"w-full h-full object-cover",onError:()=>l(!0)})};function Qh(e){var n;const t=(n=e.vibe)==null?void 0:n.toLowerCase(),r=e.genres||[];if(t)switch(t){case"energetic":return"bg-gradient-to-br from-red-500 to-orange-500";case"chill":return"bg-gradient-to-br from-blue-500 to-teal-500";case"romantic":return"bg-gradient-to-br from-pink-500 to-rose-500";case"party":return"bg-gradient-to-br from-purple-500 to-pink-500";case"workout":return"bg-gradient-to-br from-green-500 to-lime-500";case"study":return"bg-gradient-to-br from-indigo-500 to-blue-500";case"sad":return"bg-gradient-to-br from-gray-500 to-slate-500";case"happy":return"bg-gradient-to-br from-yellow-500 to-orange-500"}if(r.length>0)switch(r[0].toLowerCase()){case"pop":return"bg-gradient-to-br from-pink-500 to-purple-500";case"rock":return"bg-gradient-to-br from-red-500 to-black";case"hip-hop":case"rap":return"bg-gradient-to-br from-yellow-500 to-red-500";case"electronic":case"edm":return"bg-gradient-to-br from-cyan-500 to-blue-500";case"jazz":return"bg-gradient-to-br from-amber-500 to-orange-500";case"classical":return"bg-gradient-to-br from-slate-500 to-gray-600";case"country":return"bg-gradient-to-br from-green-600 to-yellow-600";case"r&b":return"bg-gradient-to-br from-purple-600 to-pink-600";case"indie":return"bg-gradient-to-br from-teal-500 to-green-500";case"alternative":return"bg-gradient-to-br from-gray-600 to-purple-600"}return"bg-gradient-to-br from-purple-500 to-pink-500"}const Ij=()=>{var j,F,D,G;const{currentUser:e,partnerUser:t,mixedPlaylists:r,addMixedPlaylist:n,removeMixedPlaylist:s,setMixedPlaylists:i,theme:o}=oe(),a=en(o),[l,c]=S.useState(!1),[d,f]=S.useState(!1),[u,p]=S.useState(null),[m,g]=S.useState(""),[w,v]=S.useState(""),[y,x]=S.useState(!0),[b,k]=S.useState(!1),C=w.split(",").map(M=>M.trim()).filter(M=>M.length>0);S.useEffect(()=>{(async()=>{if(e!=null&&e.jwt)try{console.log("Loading playlists from database...");const W=await te("/playlists/mixed",e.jwt);console.log("Loaded playlists:",W.playlists);const _=W.playlists.map(A=>{var R;const I=A.track_uris?JSON.parse(A.track_uris):[];return console.log("Processing playlist:",A.name,"track_uris count:",I.length,"raw track_uris:",((R=A.track_uris)==null?void 0:R.substring(0,100))+"..."),{id:A.id,name:A.name,description:A.description,tracks:[],createdAt:new Date(A.created_at),createdBy:"AI Magic ✨",spotifyId:A.creator_spotify_id,spotifyUrl:A.creator_spotify_url,partnerSpotifyId:A.partner_spotify_id,partnerSpotifyUrl:A.partner_spotify_url,vibe:A.vibe,genres:A.genres?JSON.parse(A.genres):[],trackUris:I,spotifyImageUrl:A.creator_spotify_image_url}});i(_)}catch(W){console.error("Failed to load playlists:",W)}})()},[e==null?void 0:e.jwt]);const N=async()=>{var M,W,_,A,I,R;if(!u||!((M=e==null?void 0:e.user)!=null&&M.id)){ce.error("Unable to create playlist");return}if(!(e!=null&&e.jwt)){ce.error("Please login again");return}f(!0);try{const E={partnerId:((W=t==null?void 0:t.user)==null?void 0:W.id)||e.user.id,createForBoth:!1,includeKnown:!0,name:u.name,description:u.description},H=await Et("/playlists/mixed",E,e.jwt);n({...u,spotifyId:(A=(_=H==null?void 0:H.createdFor)==null?void 0:_.creator)==null?void 0:A.playlistId,spotifyUrl:(R=(I=H==null?void 0:H.createdFor)==null?void 0:I.creator)==null?void 0:R.url}),ce.success("Playlist created on Spotify!"),p(null)}catch(E){console.error("Spotify playlist creation error:",E),ce.error("Failed to create playlist on Spotify")}finally{f(!1)}},P=async()=>{var M,W,_,A;if(!((M=e==null?void 0:e.user)!=null&&M.id)||!((W=t==null?void 0:t.user)!=null&&W.id)){ce.error("Missing users");return}if(!(e!=null&&e.jwt)){ce.error("Please login again");return}f(!0);try{const I={partnerId:t.user.id,createForBoth:b,includeKnown:y,vibe:m||void 0,genres:C.length?C:void 0,description:(u==null?void 0:u.description)||"An AI-blended mix with fresh recommendations"},R=await Et("/playlists/mixed",I,e.jwt);b&&R.createdFor.partnerError?ce.success("Your playlist created! Partner sync failed: "+R.createdFor.partnerError):b&&R.createdFor.partner?ce.success("Enhanced playlist created on both accounts!"):ce.success("Enhanced playlist created!");const E={id:R.id,name:R.name,description:I.description,tracks:[],createdAt:new Date,createdBy:"AI Magic ✨",spotifyId:R.createdFor.creator.playlistId,spotifyUrl:R.createdFor.creator.url,partnerSpotifyId:(_=R.createdFor.partner)==null?void 0:_.playlistId,partnerSpotifyUrl:(A=R.createdFor.partner)==null?void 0:A.url,vibe:I.vibe,genres:I.genres||[],trackUris:R.trackUris||[],spotifyImageUrl:R.spotifyImageUrl};n(E),p(null)}catch(I){console.error(I),ce.error("Failed to create enhanced playlist")}finally{f(!1)}},V=()=>{u&&(n(u),p(null),ce.success("Playlist saved locally!"))},T=({playlist:M,isNew:W=!1})=>{var _;return h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},whileHover:{scale:1.02},className:`glass rounded-2xl p-6 ${W?"border-spotify-green/50":"border-white/10"}`,children:[h.jsxs("div",{className:"flex items-start justify-between mb-4",children:[h.jsxs("div",{className:"flex items-center space-x-4",children:[h.jsxs("div",{className:`w-16 h-16 rounded-xl flex items-center justify-center overflow-hidden flex-shrink-0 ${W?"bg-gradient-to-br from-spotify-green to-green-600":"bg-gradient-to-br from-purple-500 to-pink-500"}`,children:[W?h.jsx(Nr,{className:"w-8 h-8 text-white"}):M.spotifyImageUrl?h.jsx(Fj,{imageUrl:M.spotifyImageUrl,alt:M.name,fallbackGradient:Qh(M)}):null,!W&&h.jsx("div",{className:`w-full h-full flex items-center justify-center ${M.spotifyImageUrl?"bg-gradient-to-br from-purple-500 to-pink-500":Qh(M)}`,style:{display:M.spotifyImageUrl?"none":"flex"},children:h.jsx(Ke,{className:"w-8 h-8 text-white"})})]}),h.jsxs("div",{children:[h.jsx("h3",{className:"text-xl font-semibold text-white",children:M.name}),h.jsx("p",{className:"text-white/70 text-sm",children:M.description}),h.jsxs("div",{className:"flex flex-wrap gap-1 mt-1 mb-1",children:[M.vibe&&h.jsx("span",{className:"px-2 py-0.5 bg-blue-500/20 text-blue-300 text-xs rounded-full",children:M.vibe}),M.genres&&M.genres.length>0&&M.genres.slice(0,2).map((A,I)=>h.jsx("span",{className:"px-2 py-0.5 bg-green-500/20 text-green-300 text-xs rounded-full",children:A},I))]}),h.jsxs("p",{className:"text-white/50 text-xs",children:["Created ",W?"just now":new Date(M.createdAt).toLocaleDateString()," • ",M.tracks.length||((_=M.trackUris)==null?void 0:_.length)||0," tracks"]})]})]}),h.jsxs("div",{className:"flex items-center space-x-2",children:[M.spotifyUrl&&h.jsx("a",{href:M.spotifyUrl,target:"_blank",rel:"noopener noreferrer",className:"w-8 h-8 rounded-full bg-white/10 hover:bg-white/20 flex items-center justify-center transition-colors",title:"Open in Spotify",children:h.jsx(iy,{className:"w-4 h-4 text-white"})}),M.partnerSpotifyUrl&&h.jsx("a",{href:M.partnerSpotifyUrl,target:"_blank",rel:"noopener noreferrer",className:"w-8 h-8 rounded-full bg-pink-500/20 hover:bg-pink-500/30 flex items-center justify-center transition-colors",title:"Partner's playlist in Spotify",children:h.jsx(et,{className:"w-4 h-4 text-pink-400"})}),!W&&h.jsx("button",{onClick:async()=>{try{e!=null&&e.jwt&&await I3(`/playlists/mixed/${M.id}`,e.jwt),s(M.id),ce.success("Playlist deleted successfully")}catch(A){console.error("Failed to delete playlist:",A),ce.error("Failed to delete playlist")}},className:"w-8 h-8 rounded-full bg-red-500/20 hover:bg-red-500/30 flex items-center justify-center transition-colors",children:h.jsx(ly,{className:"w-4 h-4 text-red-400"})})]})]}),h.jsx("div",{className:"space-y-3 max-h-64 overflow-y-auto",children:M.tracks.length>0?h.jsxs(h.Fragment,{children:[M.tracks.slice(0,5).map((A,I)=>{var R,E,H,X,ee,q;return h.jsxs(z.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:I*.1},className:"flex items-center space-x-3 p-2 rounded-lg hover:bg-white/5 transition-colors",children:[h.jsx("img",{src:((H=(E=(R=A.album)==null?void 0:R.images)==null?void 0:E[0])==null?void 0:H.url)||"/placeholder-album.png",alt:((X=A.album)==null?void 0:X.name)||"Unknown Album",className:"w-10 h-10 rounded-lg object-cover"}),h.jsxs("div",{className:"flex-1 min-w-0",children:[h.jsx("h4",{className:"text-white font-medium truncate",children:A.name}),h.jsx("p",{className:"text-white/70 text-sm truncate",children:((q=(ee=A.artists)==null?void 0:ee[0])==null?void 0:q.name)||"Unknown Artist"})]}),h.jsx("div",{className:"text-white/50 text-sm",children:Ds(A.duration_ms)})]},A.id)}),M.tracks.length>5&&h.jsxs("div",{className:"text-center text-white/50 text-sm py-2",children:["+",M.tracks.length-5," more tracks"]})]}):M.trackUris&&M.trackUris.length>0?h.jsx("div",{className:"text-center py-4"}):h.jsx("div",{className:"text-center text-white/50 text-sm py-4",children:"No tracks available"})}),W&&h.jsxs("div",{className:"flex items-center space-x-3 mt-6 pt-4 border-t border-white/10",children:[h.jsx("button",{onClick:N,disabled:d||b,className:"flex-1 bg-spotify-green hover:bg-spotify-green/90 text-white font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center space-x-2 disabled:opacity-50",children:d?h.jsx("div",{className:"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"}):h.jsxs(h.Fragment,{children:[h.jsx(Uc,{className:"w-4 h-4"}),h.jsx("span",{children:b?"Disabled (using Create for both)":"Create on Spotify"})]})}),h.jsx("button",{onClick:V,className:"px-4 py-3 bg-white/10 hover:bg-white/20 text-white rounded-lg transition-colors",children:"Save Locally"})]})]})},O=(e==null?void 0:e.topTracks)&&(t==null?void 0:t.topTracks);return h.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[h.jsxs("h1",{className:"text-4xl font-bold text-white mb-2 flex items-center space-x-3",children:[h.jsx(Nr,{className:"w-10 h-10",style:{color:((j=a.cssVars)==null?void 0:j.primary)||"#1db954"}}),h.jsx("span",{children:"Mixed Playlists"})]}),h.jsx("p",{className:"text-white/70 text-lg",children:"AI-powered playlists that perfectly blend your musical tastes together"})]}),O&&h.jsx(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:"mb-8",children:h.jsxs("div",{className:"glass rounded-2xl p-8 text-center",style:{borderColor:`${((F=a.cssVars)==null?void 0:F.primary)||"#1db954"}30`},children:[h.jsx("div",{className:"w-16 h-16 mx-auto mb-4 rounded-full flex items-center justify-center",style:{background:`linear-gradient(135deg, ${((D=a.cssVars)==null?void 0:D.primary)||"#1db954"} 0%, ${((G=a.cssVars)==null?void 0:G.secondary)||"#1ed760"} 100%)`},children:h.jsx(Wk,{className:"w-8 h-8 text-white"})}),h.jsx("h2",{className:"text-2xl font-bold text-white mb-2",children:"Create Your Perfect Mix"}),h.jsx("p",{className:"text-white/70 mb-6 max-w-2xl mx-auto",children:"Our AI analyzes both your music tastes and creates a playlist that represents your unique musical connection"}),h.jsxs("div",{className:"mt-4 text-white/50 text-sm",children:["Analyzing ",e.topTracks.length+t.topTracks.length," tracks from both users"]}),h.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 text-left mt-8",children:[h.jsxs("div",{children:[h.jsx("label",{className:"block text-white/80 text-sm mb-1",children:"Vibe"}),h.jsxs("select",{className:"w-full bg-white/10 text-white rounded-lg p-2 appearance-none focus:outline-none focus:ring-2 focus:ring-spotify-green",value:m,onChange:M=>g(M.target.value),style:{backgroundColor:"rgba(255, 255, 255, 0.1)",color:"rgba(255, 255, 255, 0.9)"},children:[h.jsx("option",{value:"",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Auto"}),h.jsx("option",{value:"energetic",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Energetic"}),h.jsx("option",{value:"chill",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Chill"}),h.jsx("option",{value:"happy",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Happy"}),h.jsx("option",{value:"sad",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Sad"}),h.jsx("option",{value:"party",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Party"}),h.jsx("option",{value:"focus",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Focus"})]})]}),h.jsxs("div",{children:[h.jsx("label",{className:"block text-white/80 text-sm mb-1",children:"Genres (comma-separated)"}),h.jsx("input",{className:"w-full bg-white/10 text-white rounded-lg p-2 placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-spotify-green",placeholder:"pop, rock, edm",value:w,onChange:M=>v(M.target.value)})]}),h.jsxs("label",{className:"flex items-center space-x-2 text-white/80",children:[h.jsx("input",{type:"checkbox",checked:y,onChange:M=>x(M.target.checked)}),h.jsx("span",{children:"Include songs we already know"})]}),h.jsxs("label",{className:"flex items-center space-x-2 text-white/80",children:[h.jsx("input",{type:"checkbox",checked:b,onChange:M=>k(M.target.checked)}),h.jsx("span",{children:"Create playlist on both accounts"}),b&&h.jsx("span",{className:"text-xs text-pink-400 ml-2",children:"✨ Synced"})]})]}),h.jsx("div",{className:"flex items-center justify-center gap-3 mt-6",children:h.jsx("button",{onClick:P,disabled:d,className:"bg-white/10 hover:bg-white/20 text-white font-semibold py-3 px-4 rounded-lg transition-colors disabled:opacity-50",children:"Create Enhanced Playlist"})})]})}),u&&h.jsxs(z.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"mb-8",children:[h.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"✨ Your New Playlist"}),h.jsx(T,{playlist:u,isNew:!0})]}),r.length>0&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},children:[h.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"Your Mixed Playlists"}),h.jsx("div",{className:"grid gap-6",children:r.map(M=>h.jsx(T,{playlist:M},M.id))})]}),!O&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-12 text-center",children:[h.jsx(et,{className:"w-16 h-16 mx-auto mb-4 text-pink-400"}),h.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:t?"Loading music data":"Waiting for your partner"}),h.jsx("p",{className:"text-white/70",children:t?"We need to analyze both your music tastes to create the perfect mixed playlist":"Invite your partner to connect their Spotify account to start creating mixed playlists"})]}),r.length===0&&O&&!u&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-12 text-center",children:[h.jsx(Ke,{className:"w-16 h-16 mx-auto mb-4 text-white/30"}),h.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"No playlists yet"}),h.jsx("p",{className:"text-white/70",children:"Create your first mixed playlist to start your musical journey together"})]})]})},zj=()=>{const{currentUser:e,partnerUser:t,memoryLane:r,addMemoryLaneItem:n}=oe(),[s,i]=S.useState(!1),[o,a]=S.useState({title:"",description:"",type:"milestone"});S.useEffect(()=>{var u,p,m,g,w,v,y,x,b,k,C,N;e&&t&&r.length===0&&[{id:"1",type:"milestone",title:"First Musical Connection",description:`${(u=e.user)==null?void 0:u.display_name} and ${(p=t.user)==null?void 0:p.display_name} discovered their shared love for music`,date:new Date(Date.now()-6048e5),users:[((m=e.user)==null?void 0:m.id)||"",((g=t.user)==null?void 0:g.id)||""]},{id:"2",type:"shared_track",title:"Shared Love for This Song",description:`Both of you have been listening to "${((v=(w=e.recentlyPlayed)==null?void 0:w[0])==null?void 0:v.track.name)||"Your favorite track"}" recently`,track:(x=(y=e.recentlyPlayed)==null?void 0:y[0])==null?void 0:x.track,date:new Date(Date.now()-2592e5),users:[((b=e.user)==null?void 0:b.id)||"",((k=t.user)==null?void 0:k.id)||""]},{id:"3",type:"playlist_created",title:"Our First Mixed Playlist",description:"Created a beautiful blend of your musical tastes",date:new Date(Date.now()-864e5),users:[((C=e.user)==null?void 0:C.id)||"",((N=t.user)==null?void 0:N.id)||""]}].forEach(V=>{n(V)})},[e,t,r.length,n]);const l=()=>{var p,m;if(!o.title.trim()||!o.description.trim()){ce.error("Please fill in both title and description");return}const u={id:Date.now().toString(),...o,date:new Date,users:[((p=e==null?void 0:e.user)==null?void 0:p.id)||"",((m=t==null?void 0:t.user)==null?void 0:m.id)||""]};n(u),a({title:"",description:"",type:"milestone"}),i(!1),ce.success("Memory added to your journey!")},c=u=>{switch(u){case"shared_track":return h.jsx(Ke,{className:"w-5 h-5"});case"playlist_created":return h.jsx(Nr,{className:"w-5 h-5"});case"milestone":return h.jsx(ay,{className:"w-5 h-5"});default:return h.jsx(et,{className:"w-5 h-5"})}},d=u=>{switch(u){case"shared_track":return"from-blue-500 to-cyan-500";case"playlist_created":return"from-purple-500 to-pink-500";case"milestone":return"from-yellow-500 to-orange-500";default:return"from-pink-500 to-red-500"}},f=({memory:u,index:p})=>{var m,g;return h.jsxs(z.div,{initial:{opacity:0,x:-50},animate:{opacity:1,x:0},transition:{delay:p*.1},className:"relative",children:[pi(!0),className:"bg-gradient-to-r from-pink-500 to-red-500 hover:from-pink-600 hover:to-red-600 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300 flex items-center space-x-2",children:[h.jsx(Uc,{className:"w-5 h-5"}),h.jsx("span",{children:"Add Memory"})]})]})}),s&&h.jsx(z.div,{initial:{opacity:0},animate:{opacity:1},className:"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4",onClick:()=>i(!1),children:h.jsxs(z.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},onClick:u=>u.stopPropagation(),className:"glass rounded-2xl p-8 max-w-md w-full",children:[h.jsx("h3",{className:"text-2xl font-bold text-white mb-6",children:"Add a New Memory"}),h.jsxs("div",{className:"space-y-4",children:[h.jsxs("div",{children:[h.jsx("label",{className:"block text-white/70 text-sm font-medium mb-2",children:"Title"}),h.jsx("input",{type:"text",value:o.title,onChange:u=>a({...o,title:u.target.value}),className:"w-full px-4 py-3 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:border-spotify-green",placeholder:"What's this memory about?"})]}),h.jsxs("div",{children:[h.jsx("label",{className:"block text-white/70 text-sm font-medium mb-2",children:"Description"}),h.jsx("textarea",{value:o.description,onChange:u=>a({...o,description:u.target.value}),className:"w-full px-4 py-3 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:border-spotify-green h-24 resize-none",placeholder:"Tell the story of this memory..."})]}),h.jsxs("div",{children:[h.jsx("label",{className:"block text-white/70 text-sm font-medium mb-2",children:"Type"}),h.jsxs("select",{value:o.type,onChange:u=>a({...o,type:u.target.value}),className:"w-full px-4 py-3 bg-white/10 border border-white/20 rounded-lg text-white focus:outline-none focus:border-spotify-green",style:{backgroundColor:"rgba(255, 255, 255, 0.1)",color:"rgba(255, 255, 255, 0.9)"},children:[h.jsx("option",{value:"milestone",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Milestone"}),h.jsx("option",{value:"shared_track",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Shared Track"}),h.jsx("option",{value:"playlist_created",style:{backgroundColor:"rgba(30, 30, 30, 0.95)",color:"rgba(255, 255, 255, 0.9)"},children:"Playlist Created"})]})]})]}),h.jsxs("div",{className:"flex items-center space-x-3 mt-6",children:[h.jsx("button",{onClick:l,className:"flex-1 bg-spotify-green hover:bg-spotify-green/90 text-white font-semibold py-3 px-4 rounded-lg transition-colors",children:"Add Memory"}),h.jsx("button",{onClick:()=>i(!1),className:"px-4 py-3 bg-white/10 hover:bg-white/20 text-white rounded-lg transition-colors",children:"Cancel"})]})]})}),h.jsx("div",{className:"space-y-8",children:r.length>0?r.map((u,p)=>h.jsx(f,{memory:u,index:p},u.id)):h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-12 text-center",children:[h.jsx(Dk,{className:"w-16 h-16 mx-auto mb-4 text-white/30"}),h.jsx("h3",{className:"text-xl font-semibold text-white mb-2",children:"No memories yet"}),h.jsx("p",{className:"text-white/70 mb-6",children:"Start creating beautiful musical memories together"}),h.jsx("button",{onClick:()=>i(!0),className:"bg-gradient-to-r from-pink-500 to-red-500 hover:from-pink-600 hover:to-red-600 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300",children:"Create First Memory"})]})}),r.length>0&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.5},className:"mt-12 grid grid-cols-1 md:grid-cols-3 gap-6",children:[h.jsxs("div",{className:"glass rounded-2xl p-6 text-center",children:[h.jsx("div",{className:"w-12 h-12 mx-auto mb-3 bg-gradient-to-br from-pink-500 to-red-500 rounded-full flex items-center justify-center",children:h.jsx(et,{className:"w-6 h-6 text-white"})}),h.jsx("h4",{className:"text-2xl font-bold text-white mb-1",children:r.length}),h.jsx("p",{className:"text-white/70 text-sm",children:"Memories Created"})]}),h.jsxs("div",{className:"glass rounded-2xl p-6 text-center",children:[h.jsx("div",{className:"w-12 h-12 mx-auto mb-3 bg-gradient-to-br from-blue-500 to-cyan-500 rounded-full flex items-center justify-center",children:h.jsx(Ke,{className:"w-6 h-6 text-white"})}),h.jsx("h4",{className:"text-2xl font-bold text-white mb-1",children:r.filter(u=>u.type==="shared_track").length}),h.jsx("p",{className:"text-white/70 text-sm",children:"Shared Tracks"})]}),h.jsxs("div",{className:"glass rounded-2xl p-6 text-center",children:[h.jsx("div",{className:"w-12 h-12 mx-auto mb-3 bg-gradient-to-br from-purple-500 to-pink-500 rounded-full flex items-center justify-center",children:h.jsx(Nr,{className:"w-6 h-6 text-white"})}),h.jsx("h4",{className:"text-2xl font-bold text-white mb-1",children:r.filter(u=>u.type==="playlist_created").length}),h.jsx("p",{className:"text-white/70 text-sm",children:"Playlists Created"})]})]})]})};function Oj(e,t){if(!e||!t)return 0;const r=["energy","valence"];let n=0,s=0;for(const i of r)typeof e[i]=="number"&&typeof t[i]=="number"&&(n+=1-Math.min(1,Math.abs(e[i]-t[i])),s++);return s?Math.round(n/s*100):0}const $j=()=>{var u,p;const{currentUser:e,partnerUser:t}=oe(),[r,n]=S.useState(null),[s,i]=S.useState(null),[o,a]=S.useState(null),[l,c]=S.useState(null);S.useEffect(()=>{let m;const g=async()=>{var w,v,y,x;try{const b=(w=e==null?void 0:e.user)==null?void 0:w.id;if(b){const C=await te(`/users/${b}/now-playing`);n(C);const N=(v=C==null?void 0:C.item)==null?void 0:v.id;if(N){const P=await te(`/users/${b}/audio-features?ids=${N}`);a(((P==null?void 0:P.audio_features)||[])[0]||null)}}const k=(y=t==null?void 0:t.user)==null?void 0:y.id;if(k){const C=await te(`/users/${k}/now-playing`);i(C);const N=(x=C==null?void 0:C.item)==null?void 0:x.id;if(N){const P=await te(`/users/${k}/audio-features?ids=${N}`);c(((P==null?void 0:P.audio_features)||[])[0]||null)}}}catch{}m=setTimeout(g,8e3)};return g(),()=>clearTimeout(m)},[(u=e==null?void 0:e.user)==null?void 0:u.id,(p=t==null?void 0:t.user)==null?void 0:p.id]);const d=S.useMemo(()=>Oj(o,l),[o,l]),f=({data:m,who:g})=>{var v,y,x;if(!(m!=null&&m.is_playing)||!(m!=null&&m.item))return h.jsxs("div",{className:"glass rounded-2xl p-6 text-white/70",children:[g," is not playing"]});const w=m.item;return h.jsxs("div",{className:"glass rounded-2xl p-6 flex items-center gap-4",children:[h.jsx("img",{src:((x=(y=(v=w==null?void 0:w.album)==null?void 0:v.images)==null?void 0:y[0])==null?void 0:x.url)||"/placeholder-album.png",alt:w==null?void 0:w.name,className:"w-16 h-16 rounded"}),h.jsxs("div",{className:"flex-1 min-w-0",children:[h.jsx("div",{className:"text-white font-semibold truncate",children:w==null?void 0:w.name}),h.jsx("div",{className:"text-white/70 text-sm truncate",children:((w==null?void 0:w.artists)||[]).map(b=>b.name).join(", ")})]}),h.jsx("div",{className:"flex gap-1",children:[...Array(12)].map((b,k)=>h.jsx("div",{className:"w-1 bg-spotify-green/60 animate-pulse",style:{height:`${(Math.sin(k)*.5+.5)*32+8}px`,animationDelay:`${k*50}ms`}},k))})]})};return h.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-6",children:[h.jsx("h1",{className:"text-3xl font-bold text-white",children:"Live Dashboard"}),h.jsx("p",{className:"text-white/70",children:"See what you are both playing right now"})]}),h.jsxs("div",{className:"grid md:grid-cols-2 gap-6",children:[h.jsx(f,{data:r,who:"You"}),h.jsx(f,{data:s,who:"Partner"})]}),(r==null?void 0:r.is_playing)&&(s==null?void 0:s.is_playing)&&h.jsxs(z.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"glass rounded-2xl p-6 mt-6 text-center",children:[h.jsx("div",{className:"text-white/80",children:"Harmony Match"}),h.jsxs("div",{className:"text-4xl font-extrabold text-white mt-1",children:[d,"%"]})]})]})},Bj=()=>{var N,P,V,T,O;const{currentUser:e,partnerUser:t,theme:r}=oe(),n=en(r),[s,i]=S.useState(null),[o,a]=S.useState(!1),[l,c]=S.useState(0),[d,f]=S.useState("all"),[u,p]=S.useState({}),g=s?(j=>{var W,_;const F=[],D=new Date(j.dataCollectionStart),G=Math.floor((Date.now()-j.dataCollectionStart)/(1e3*60*60*24)),M=Math.floor(j.totalListeningTime/(1e3*60*60));if(F.push({id:"intro",type:"intro",title:"Your Music Wrapped",subtitle:`${j.timeRange==="all"?"All Time":j.timeRange.charAt(0).toUpperCase()+j.timeRange.slice(1)} Edition`,gradient:"from-purple-500 via-pink-500 to-red-500",data:{totalTracks:j.totalTracks,hoursListened:M,daysSinceStart:G,startDate:D.toLocaleDateString()}}),F.push({id:"dataStart",type:"intro",title:"Your Musical Journey",subtitle:`Started ${D.toLocaleDateString()}`,gradient:"from-blue-500 via-purple-500 to-pink-500",data:{hoursListened:M,daysSinceStart:G,averagePerDay:G>0?Math.round(j.totalTracks/G):0}}),j.topSongs.length>0&&F.push({id:"topSongs",type:"topSongs",title:"Your Top Songs",subtitle:`You played ${((W=j.topSongs[0])==null?void 0:W.playCount)||0} times`,gradient:"from-green-400 via-blue-500 to-purple-600",data:j.topSongs.slice(0,5)}),j.topArtists.length>0&&F.push({id:"topArtists",type:"topArtists",title:"Your Top Artists",subtitle:`${((_=j.topArtists[0])==null?void 0:_.name)||"Unknown"} was your #1`,gradient:"from-yellow-400 via-red-500 to-pink-500",data:j.topArtists.slice(0,5)}),F.push({id:"listeningHabits",type:"listeningPatterns",title:"Your Listening Habits",subtitle:"When you vibe the most",gradient:"from-teal-400 via-green-500 to-blue-500",data:{mostActiveHour:j.listeningPatterns.mostActiveHour,mostActiveDay:j.listeningPatterns.mostActiveDay,listeningStreak:j.listeningPatterns.listeningStreak,lateNight:j.uniqueCategories.lateNightListener,earlyBird:j.uniqueCategories.earlyBird,weekendWarrior:j.uniqueCategories.weekendWarrior}}),F.push({id:"discovery",type:"listeningPatterns",title:"Music Explorer",subtitle:"Your discovery journey",gradient:"from-indigo-500 via-purple-500 to-pink-500",data:{discoveryRate:j.uniqueCategories.discoveryRate,averageSongLength:j.uniqueCategories.averageSongLength,listeningVelocity:j.uniqueCategories.listeningVelocity}}),j.uniqueCategories.longestSession.duration>0&&F.push({id:"longestSession",type:"listeningTime",title:"Your Longest Session",subtitle:"When you couldn't stop listening",gradient:"from-orange-400 via-red-500 to-pink-500",data:{totalTime:j.uniqueCategories.longestSession.duration,totalTracks:Math.floor(j.uniqueCategories.longestSession.duration/(j.uniqueCategories.averageSongLength||18e4)),averagePerTrack:j.uniqueCategories.averageSongLength||18e4}}),j.uniqueCategories.mostDiverseDay.artistCount>0&&F.push({id:"mostDiverseDay",type:"listeningPatterns",title:"Your Most Diverse Day",subtitle:"When you explored the most",gradient:"from-cyan-400 via-blue-500 to-indigo-600",data:{date:j.uniqueCategories.mostDiverseDay.date,artistCount:j.uniqueCategories.mostDiverseDay.artistCount}}),j.partnerData){F.push({id:"partnerComparison",type:"listeningTime",title:"You vs Your Partner",subtitle:"Musical journey together",gradient:"from-pink-400 via-purple-500 to-indigo-500",data:{yourTracks:j.totalTracks,partnerTracks:j.partnerData.totalTracks,yourTime:j.totalListeningTime,partnerTime:j.partnerData.totalListeningTime}});const A=new Set(j.topArtists.slice(0,10).map(E=>E.id)),I=new Set(j.partnerData.topArtists.map(E=>E.id)),R=Array.from(A).filter(E=>I.has(E));R.length>0&&F.push({id:"sharedTaste",type:"topArtists",title:"Your Shared Taste",subtitle:`${R.length} artists you both love`,gradient:"from-green-400 via-teal-500 to-blue-500",data:{sharedArtists:R.length}})}return F.push({id:"listeningTime",type:"listeningTime",title:"Total Listening Time",subtitle:"You've been on a musical journey",gradient:"from-orange-400 via-red-500 to-pink-500",data:{totalTime:j.totalListeningTime,totalTracks:j.totalTracks,averagePerTrack:j.totalTracks>0?j.totalListeningTime/j.totalTracks:0}}),F.push({id:"outro",type:"outro",title:"Thanks for Listening!",subtitle:"Keep discovering amazing music",gradient:"from-purple-500 via-pink-500 to-red-500",data:{generatedAt:j.generatedAt}}),F})(s):[],w=async j=>{var D;if(!((D=e==null?void 0:e.user)!=null&&D.id)||!(e!=null&&e.jwt))return;const F=j.map(async G=>{try{const M=await te(`/users/${e.user.id}/artist/${G.id}`,e.jwt);M.images&&M.images.length>0&&p(W=>({...W,[G.id]:M.images[0].url}))}catch(M){console.error(`Failed to fetch image for artist ${G.name}:`,M)}});await Promise.all(F)},v=async(j="all")=>{var F;if(!(!((F=e==null?void 0:e.user)!=null&&F.id)||!(e!=null&&e.jwt))){a(!0);try{const D=await te(`/users/${e.user.id}/wrapped?range=${j}`,e.jwt);i(D),c(0),D.topArtists&&D.topArtists.length>0&&w(D.topArtists)}catch(D){console.error("Failed to fetch wrapped data:",D),ce.error("Failed to load your music wrapped")}finally{a(!1)}}};S.useEffect(()=>{v(d)},[d,(N=e==null?void 0:e.user)==null?void 0:N.id,e==null?void 0:e.jwt]);const y=()=>{c(j=>(j+1)%g.length)},x=()=>{c(j=>(j-1+g.length)%g.length)},b=j=>{const F=Math.floor(j/36e5),D=Math.floor(j%(1e3*60*60)/(1e3*60));return`${F}h ${D}m`},k=j=>j===0?"12 AM":j<12?`${j} AM`:j===12?"12 PM":`${j-12} PM`,C=j=>{var D,G,M,W,_,A,I,R,E,H,X,ee,q,me,Rr,_t,St,Qe,on,Qn,B,le,ye,be,Fe,Lt,Zn,an,Zt,qc;const F="w-full h-full flex flex-col items-center justify-center text-center p-3 sm:p-6 overflow-y-auto";switch(j.type){case"intro":return h.jsx("div",{className:`${F} relative`,children:h.jsxs(z.div,{initial:{scale:.5,opacity:0},animate:{scale:1,opacity:1},transition:{duration:.8,ease:"easeOut"},className:"relative z-10 space-y-6",children:[h.jsx(Ke,{className:"w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 mx-auto text-white/90"}),h.jsx("h1",{className:"text-3xl sm:text-5xl lg:text-6xl font-bold text-white mb-4",children:j.title}),h.jsx("p",{className:"text-lg sm:text-xl lg:text-2xl text-white/80 mb-8",children:j.subtitle}),((D=j.data)==null?void 0:D.hoursListened)&&h.jsxs("div",{className:"text-2xl sm:text-4xl lg:text-5xl font-bold text-white mb-4",children:[j.data.hoursListened," hours listened"]}),((G=j.data)==null?void 0:G.daysSinceStart)&&h.jsxs("div",{className:"text-lg text-white/70",children:["Since ",j.data.startDate," (",j.data.daysSinceStart," days ago)"]}),((M=j.data)==null?void 0:M.totalTracks)&&h.jsxs("div",{className:"text-2xl text-white/90",children:[j.data.totalTracks," songs played"]})]})});case"topSongs":return h.jsx("div",{className:`${F} relative`,children:h.jsxs(z.div,{initial:{y:50,opacity:0},animate:{y:0,opacity:1},transition:{duration:.6},className:"w-full max-w-3xl relative z-10",children:[h.jsx("h2",{className:"text-3xl sm:text-4xl lg:text-5xl font-bold text-white mb-2",children:j.title}),h.jsx("p",{className:"text-lg sm:text-lg lg:text-xl text-white/80 mb-8",children:j.subtitle}),h.jsx("div",{className:"space-y-3",children:(W=j.data)==null?void 0:W.map((Ie,Jn)=>{var Gc,Yc,Kc,Xc,Qc,Zc;return h.jsxs(z.div,{initial:{x:-100,opacity:0},animate:{x:0,opacity:1},transition:{delay:Jn*.2,duration:.5},className:"flex items-center justify-between bg-white/10 backdrop-blur-md rounded-2xl p-4 border border-white/20",children:[h.jsxs("div",{className:"flex items-center space-x-4",children:[h.jsx("div",{className:"w-10 h-10 bg-white/20 rounded-full flex items-center justify-center text-white font-bold text-lg",children:Jn+1}),h.jsx("img",{src:((Kc=(Yc=(Gc=Ie.album)==null?void 0:Gc.images)==null?void 0:Yc[0])==null?void 0:Kc.url)||"/placeholder-album.png",alt:(Xc=Ie.album)==null?void 0:Xc.name,className:"w-12 h-12 rounded-lg object-cover"}),h.jsxs("div",{className:"text-left",children:[h.jsx("h3",{className:"text-lg font-semibold text-white",children:Ie.name}),h.jsx("p",{className:"text-white/70 text-sm",children:(Zc=(Qc=Ie.artists)==null?void 0:Qc[0])==null?void 0:Zc.name})]})]}),h.jsxs("div",{className:"text-right",children:[h.jsxs("div",{className:"text-white font-bold",children:[Ie.playCount," plays"]}),h.jsx("div",{className:"text-white/70 text-sm",children:Ds(Ie.duration_ms)})]})]},Ie.id)})})]})});case"topArtists":return h.jsx("div",{className:`${F} relative`,children:h.jsxs(z.div,{initial:{y:50,opacity:0},animate:{y:0,opacity:1},transition:{duration:.6},className:"w-full max-w-4xl relative z-10",children:[h.jsx("h2",{className:"text-3xl sm:text-4xl lg:text-5xl font-bold text-white mb-2",children:j.title}),h.jsx("p",{className:"text-lg sm:text-lg lg:text-xl text-white/80 mb-8",children:j.subtitle}),h.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:(_=j.data)==null?void 0:_.map((Ie,Jn)=>h.jsxs(z.div,{initial:{scale:.8,opacity:0},animate:{scale:1,opacity:1},transition:{delay:Jn*.1,duration:.5},className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20",children:[h.jsx("div",{className:"w-20 h-20 mx-auto mb-4 rounded-full overflow-hidden border-2 border-white/20",children:u[Ie.id]?h.jsx("img",{src:u[Ie.id],alt:Ie.name,className:"w-full h-full object-cover"}):h.jsx("div",{className:"w-full h-full bg-white/20 flex items-center justify-center text-white font-bold text-xl",children:Jn+1})}),h.jsx("h3",{className:"text-xl font-bold text-white mb-2",children:Ie.name}),h.jsxs("p",{className:"text-white/70",children:[Ie.playCount," plays"]}),h.jsx("p",{className:"text-white/60 text-sm",children:b(Ie.totalDuration)})]},Ie.id))})]})});case"listeningTime":return h.jsx("div",{className:`${F} relative`,children:h.jsxs(z.div,{initial:{scale:.5,opacity:0},animate:{scale:1,opacity:1},transition:{duration:.8,ease:"easeOut"},className:"space-y-6 relative z-10",children:[h.jsx(Un,{className:"w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 mx-auto text-white/90"}),h.jsx("h2",{className:"text-3xl sm:text-5xl lg:text-6xl font-bold text-white mb-4",children:j.title}),h.jsx("p",{className:"text-lg sm:text-xl lg:text-2xl text-white/80 mb-8",children:j.subtitle}),h.jsx("div",{className:"text-4xl sm:text-6xl lg:text-7xl font-bold text-white mb-8",children:b(((A=j.data)==null?void 0:A.totalTime)||((I=j.data)==null?void 0:I.duration)||0)}),h.jsxs("div",{className:"grid grid-cols-2 gap-6 text-center",children:[h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 border border-white/20",children:[h.jsx("div",{className:"text-3xl font-bold text-white",children:((R=j.data)==null?void 0:R.totalTracks)||0}),h.jsx("div",{className:"text-white/70",children:"Total Songs"})]}),h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 border border-white/20",children:[h.jsx("div",{className:"text-3xl font-bold text-white",children:Ds(((E=j.data)==null?void 0:E.averagePerTrack)||0)}),h.jsx("div",{className:"text-white/70",children:"Avg per Song"})]})]})]})});case"listeningPatterns":return h.jsx("div",{className:`${F} relative`,children:h.jsxs(z.div,{initial:{y:50,opacity:0},animate:{y:0,opacity:1},transition:{duration:.6},className:"w-full max-w-4xl relative z-10",children:[h.jsx("h2",{className:"text-3xl sm:text-4xl lg:text-5xl font-bold text-white mb-2",children:j.title}),h.jsx("p",{className:"text-lg sm:text-lg lg:text-xl text-white/80 mb-8",children:j.subtitle}),h.jsxs("div",{className:`grid gap-6 justify-items-center ${((H=j.data)==null?void 0:H.artistCount)!==void 0&&!((X=j.data)!=null&&X.mostActiveHour)&&!((ee=j.data)!=null&&ee.mostActiveDay)&&!((q=j.data)!=null&&q.listeningStreak)&&!((me=j.data)!=null&&me.lateNight)&&!((Rr=j.data)!=null&&Rr.earlyBird)&&!((_t=j.data)!=null&&_t.weekendWarrior)&&!((St=j.data)!=null&&St.discoveryRate)&&!((Qe=j.data)!=null&&Qe.listeningVelocity)&&!((on=j.data)!=null&&on.averageSongLength)?"grid-cols-1 justify-center":"grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`,children:[((Qn=j.data)==null?void 0:Qn.mostActiveHour)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(Un,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:k(j.data.mostActiveHour)}),h.jsx("div",{className:"text-white/70",children:"Most Active Hour"})]}),((B=j.data)==null?void 0:B.mostActiveDay)&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(sy,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.mostActiveDay}),h.jsx("div",{className:"text-white/70",children:"Most Active Day"})]}),((le=j.data)==null?void 0:le.listeningStreak)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(uy,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.listeningStreak}),h.jsx("div",{className:"text-white/70",children:"Day Streak"})]}),((ye=j.data)==null?void 0:ye.lateNight)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(Ok,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.lateNight}),h.jsx("div",{className:"text-white/70",children:"Late Night Plays"})]}),((be=j.data)==null?void 0:be.earlyBird)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(Bk,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.earlyBird}),h.jsx("div",{className:"text-white/70",children:"Early Bird Plays"})]}),((Fe=j.data)==null?void 0:Fe.weekendWarrior)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(Ak,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.weekendWarrior}),h.jsx("div",{className:"text-white/70",children:"Weekend Plays"})]}),((Lt=j.data)==null?void 0:Lt.discoveryRate)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(ay,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.discoveryRate}),h.jsx("div",{className:"text-white/70",children:"Artists Discovered"})]}),((Zn=j.data)==null?void 0:Zn.listeningVelocity)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(qk,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.listeningVelocity.toFixed(1)}),h.jsx("div",{className:"text-white/70",children:"Songs per Day"})]}),((an=j.data)==null?void 0:an.averageSongLength)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(Ke,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:Ds(j.data.averageSongLength)}),h.jsx("div",{className:"text-white/70",children:"Avg Song Length"})]}),((Zt=j.data)==null?void 0:Zt.artistCount)!==void 0&&h.jsxs("div",{className:"bg-white/10 backdrop-blur-md rounded-2xl p-6 text-center border border-white/20 w-full max-w-xs h-40 flex flex-col justify-center",children:[h.jsx(Wc,{className:"w-12 h-12 mx-auto text-white/90 mb-4"}),h.jsx("div",{className:"text-2xl font-bold text-white mb-2",children:j.data.artistCount}),h.jsxs("div",{className:"text-white/70",children:["Artists on ",j.data.date]})]})]})]})});case"outro":return h.jsx("div",{className:`${F} relative`,children:h.jsxs(z.div,{initial:{scale:.5,opacity:0},animate:{scale:1,opacity:1},transition:{duration:.8,ease:"easeOut"},className:"space-y-6 relative z-10",children:[h.jsx(Nr,{className:"w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 mx-auto text-white/90"}),h.jsx("h1",{className:"text-3xl sm:text-5xl lg:text-6xl font-bold text-white mb-4",children:j.title}),h.jsx("p",{className:"text-lg sm:text-xl lg:text-2xl text-white/80 mb-8",children:j.subtitle}),h.jsxs("div",{className:"text-lg text-white/60",children:["Generated on ",new Date(((qc=j.data)==null?void 0:qc.generatedAt)||Date.now()).toLocaleDateString()]})]})});default:return null}};return o?h.jsxs("div",{className:"min-h-screen flex items-center justify-center relative",children:[h.jsx(_s,{hueShift:Ms(r)}),h.jsxs(z.div,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},className:"glass-fluid rounded-3xl p-10 flex flex-col items-center space-y-6 relative z-20",children:[h.jsx("div",{className:"w-16 h-16 border-4 border-t-transparent rounded-full animate-spin",style:{borderColor:"var(--theme-primary) var(--theme-primary) var(--theme-primary) transparent"}}),h.jsx("p",{className:"text-white font-medium text-lg",children:"Generating your music wrapped..."})]})]}):s?h.jsxs("div",{className:"min-h-screen relative",children:[h.jsx(_s,{hueShift:Ms(r)}),h.jsxs("div",{className:"relative z-20",children:[h.jsx("div",{className:"fixed top-0 left-0 right-0 z-50 p-4 sm:p-6 bg-black/30 backdrop-blur-md border-b border-white/10",children:h.jsx("div",{className:"flex items-center justify-between",children:h.jsxs("div",{className:"flex items-center space-x-4",children:[h.jsx("h1",{className:"text-2xl font-bold text-white",children:"Music Wrapped"}),h.jsxs("select",{value:d,onChange:j=>f(j.target.value),className:"bg-white/10 backdrop-blur-md text-white rounded-lg px-3 py-1 border border-white/20",children:[h.jsx("option",{value:"all",className:"bg-gray-800",children:"All Time"}),h.jsx("option",{value:"year",className:"bg-gray-800",children:"This Year"}),h.jsx("option",{value:"month",className:"bg-gray-800",children:"This Month"}),h.jsx("option",{value:"week",className:"bg-gray-800",children:"This Week"})]})]})})}),h.jsx("div",{className:"relative w-full min-h-screen flex items-center justify-center p-2 sm:p-4 pt-20 sm:pt-24",children:h.jsxs("div",{className:"w-full max-w-2xl sm:max-w-4xl h-[60vh] sm:h-[80vh] relative",children:[h.jsx(e3,{mode:"wait",children:h.jsx(z.div,{initial:{opacity:0,scale:.9,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.9,y:-20},transition:{duration:.5,ease:"easeInOut"},className:"absolute inset-0 rounded-3xl overflow-hidden shadow-2xl overflow-y-auto",style:{background:`linear-gradient(135deg, ${((P=n.cssVars)==null?void 0:P.primary)||"#1db954"}20 0%, ${((V=n.cssVars)==null?void 0:V.secondary)||"#1ed760"}15 100%)`,backdropFilter:"blur(25px) saturate(180%)",WebkitBackdropFilter:"blur(25px) saturate(180%)",border:`1px solid ${((T=n.cssVars)==null?void 0:T.primary)||"#1db954"}40`,boxShadow:`0 25px 50px rgba(0,0,0,0.4), 0 0 0 1px ${((O=n.cssVars)==null?void 0:O.primary)||"#1db954"}30, inset 0 1px 0 rgba(255,255,255,0.1)`},children:C(g[l])},l)}),g.length>1&&h.jsxs(h.Fragment,{children:[h.jsx("button",{onClick:x,className:"absolute left-4 top-1/2 transform -translate-y-1/2 bg-white/10 backdrop-blur-md hover:bg-white/20 text-white p-3 rounded-full transition-colors border border-white/20",children:h.jsx(Vk,{className:"w-6 h-6"})}),h.jsx("button",{onClick:y,className:"absolute right-4 top-1/2 transform -translate-y-1/2 bg-white/10 backdrop-blur-md hover:bg-white/20 text-white p-3 rounded-full transition-colors border border-white/20",children:h.jsx(Fk,{className:"w-6 h-6"})})]}),h.jsx("div",{className:"absolute bottom-6 left-1/2 transform -translate-x-1/2 flex space-x-2",children:g.map((j,F)=>h.jsx("button",{onClick:()=>c(F),className:`w-3 h-3 rounded-full transition-colors ${F===l?"bg-white":"bg-white/30"}`},F))}),h.jsxs("div",{className:"absolute top-6 right-6 text-white/70 text-sm bg-white/10 backdrop-blur-md px-3 py-1 rounded-full border border-white/20",children:[l+1," / ",g.length]})]})})]})]}):h.jsxs("div",{className:"min-h-screen flex items-center justify-center relative",children:[h.jsx(_s,{hueShift:Ms(r)}),h.jsxs("div",{className:"text-center relative z-20",children:[h.jsx(Ke,{className:"w-24 h-24 text-white/50 mx-auto mb-4"}),h.jsx("h2",{className:"text-2xl font-bold text-white mb-2",children:"No Music Data"}),h.jsx("p",{className:"text-white/70 mb-6",children:"Start listening to music to generate your wrapped!"})]})]})};function Uj(){var o,a;const{currentUser:e,partnerUser:t,isLoading:r,theme:n}=oe(),s=_r();console.log("🔍 App - Current location:",s.pathname),S.useEffect(()=>{en(n)},[n]),S.useEffect(()=>{const l=localStorage.getItem("spotify-user"),c=localStorage.getItem("spotify-partner");if(l)try{const d=JSON.parse(l);oe.getState().setCurrentUser(d)}catch(d){console.error("Failed to parse stored user data:",d),localStorage.removeItem("spotify-user")}if(c)try{const d=JSON.parse(c);oe.getState().setPartnerUser(d)}catch(d){console.error("Failed to parse stored partner data:",d),localStorage.removeItem("spotify-partner")}},[]),S.useEffect(()=>{(async()=>{var d,f;const c=(f=(d=oe.getState().currentUser)==null?void 0:d.user)==null?void 0:f.id;if(c&&!oe.getState().partnerUser)try{const u=await te(`/partners/partner/${c}`);if(u.partnerId){const[p,m,g]=await Promise.all([te(`/users/${u.partnerId}`),te(`/users/${u.partnerId}/recently-played`),te(`/users/${u.partnerId}/top-tracks?time_range=short_term`)]);oe.getState().setPartnerUser({user:p,accessToken:null,refreshToken:null,isAuthenticated:!0,recentlyPlayed:m,topTracks:g.map(w=>w.track),topArtists:[]})}}catch{}})()},[(o=e==null?void 0:e.user)==null?void 0:o.id]),S.useEffect(()=>{var d,f;const l=(f=(d=oe.getState().currentUser)==null?void 0:d.user)==null?void 0:f.id;if(!l)return;const c=V3(`/partners/events/${l}`);return c.onmessage=async u=>{var p,m;if(u.data)try{const g=JSON.parse(u.data);if((g==null?void 0:g.type)==="partner:connected"||(g==null?void 0:g.type)==="partner:disconnected"){const w=await te(`/partners/partner/${l}`),v=((m=(p=oe.getState().partnerUser)==null?void 0:p.user)==null?void 0:m.id)||null;if(!(w!=null&&w.partnerId)&&v){oe.getState().setPartnerUser(null),localStorage.removeItem("spotify-partner");return}if(w!=null&&w.partnerId&&w.partnerId!==v)try{const[y,x,b]=await Promise.all([te(`/users/${w.partnerId}`),te(`/users/${w.partnerId}/recently-played`),te(`/users/${w.partnerId}/top-tracks?time_range=short_term`)]);oe.getState().setPartnerUser({user:y,accessToken:null,refreshToken:null,isAuthenticated:!0,recentlyPlayed:x,topTracks:b.map(k=>k.track),topArtists:[]})}catch{}}(g==null?void 0:g.type)==="partner:request"||(g==null||g.type)}catch{}},c.onerror=()=>{try{c.close()}catch{}},()=>{try{c.close()}catch{}}},[(a=e==null?void 0:e.user)==null?void 0:a.id]);const i=(e==null?void 0:e.isAuthenticated)||!1;return r?h.jsxs("div",{className:"min-h-screen flex items-center justify-center relative",children:[h.jsx(_s,{hueShift:Ms(n)}),h.jsxs(z.div,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},className:"glass-fluid rounded-3xl p-10 flex flex-col items-center space-y-6 relative z-20",children:[h.jsx("div",{className:"w-16 h-16 border-4 border-t-transparent rounded-full animate-spin",style:{borderColor:"var(--theme-primary) var(--theme-primary) var(--theme-primary) transparent"}}),h.jsx("p",{className:"text-white font-medium text-lg",children:"Loading your musical journey..."})]})]}):h.jsxs("div",{className:"min-h-screen relative overflow-hidden",children:[h.jsx(_s,{hueShift:Ms(n)}),h.jsxs("div",{className:"relative z-20",children:[i&&h.jsx(Nj,{}),h.jsxs(Fx,{children:[h.jsx(jt,{path:"/",element:i?h.jsx(Rj,{}):h.jsx(Lj,{})}),h.jsx(jt,{path:"/callback",element:h.jsx(Xh,{})}),h.jsx(jt,{path:"/callback.html",element:h.jsx(Xh,{})}),i&&h.jsxs(h.Fragment,{children:[h.jsx(jt,{path:"/last-listened",element:h.jsx(Vj,{})}),h.jsx(jt,{path:"/mixed-playlist",element:h.jsx(Ij,{})}),h.jsx(jt,{path:"/memory-lane",element:h.jsx(zj,{})}),h.jsx(jt,{path:"/live",element:h.jsx($j,{})}),h.jsx(jt,{path:"/wrapped",element:h.jsx(Bj,{})})]}),h.jsx(jt,{path:"*",element:h.jsx(Rx,{to:"/",replace:!0})})]})]})]})}il.createRoot(document.getElementById("root")).render(h.jsx(ii.StrictMode,{children:h.jsxs(Hx,{children:[h.jsx(Uj,{}),h.jsx(F2,{position:"top-right",toastOptions:{duration:4e3,style:{background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.2)",color:"#fff"}}})]})})); diff --git a/dist/assets/index-HYQ6lVkA.css b/dist/assets/index-HYQ6lVkA.css deleted file mode 100644 index 7d74ed3..0000000 --- a/dist/assets/index-HYQ6lVkA.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-20{bottom:5rem}.bottom-32{bottom:8rem}.left-1\/4{left:25%}.left-10{left:2.5rem}.left-8{left:2rem}.right-1\/3{right:33.333333%}.right-20{right:5rem}.top-0{top:0}.top-16{top:4rem}.top-20{top:5rem}.top-40{top:10rem}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0\.5{margin-left:.125rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-20{height:5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-full{height:100%}.max-h-64{max-height:16rem}.min-h-screen{min-height:100vh}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-20{width:5rem}.w-3{width:.75rem}.w-32{width:8rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize{resize:both}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1.5rem * var(--tw-space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-green-400\/30{border-color:#4ade804d}.border-orange-500\/30{border-color:#f973164d}.border-red-400\/30{border-color:#f871714d}.border-spotify-green\/30{border-color:#1db9544d}.border-spotify-green\/50{border-color:#1db95480}.border-theme-blue-primary{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-theme-blue-primary\/30{border-color:#3b82f64d}.border-theme-green-primary{--tw-border-opacity: 1;border-color:rgb(29 185 84 / var(--tw-border-opacity, 1))}.border-theme-green-primary\/30{border-color:#1db9544d}.border-theme-pink-primary{--tw-border-opacity: 1;border-color:rgb(236 72 153 / var(--tw-border-opacity, 1))}.border-theme-pink-primary\/30{border-color:#ec48994d}.border-theme-purple-primary{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1))}.border-theme-purple-primary\/30{border-color:#8b5cf64d}.border-theme-red-primary{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}.border-theme-red-primary\/30{border-color:#dc26264d}.border-theme-turquoise-primary{--tw-border-opacity: 1;border-color:rgb(6 182 212 / var(--tw-border-opacity, 1))}.border-theme-turquoise-primary\/30{border-color:#06b6d44d}.border-theme-yellow-primary{--tw-border-opacity: 1;border-color:rgb(234 179 8 / var(--tw-border-opacity, 1))}.border-theme-yellow-primary\/30{border-color:#eab3084d}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1))}.border-white\/10{border-color:#ffffff1a}.border-white\/20{border-color:#fff3}.border-t-transparent{border-top-color:transparent}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-blue-500\/20{background-color:#3b82f633}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/20{background-color:#22c55e33}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-pink-500\/20{background-color:#ec489933}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/20{background-color:#ef444433}.bg-spotify-green{--tw-bg-opacity: 1;background-color:rgb(29 185 84 / var(--tw-bg-opacity, 1))}.bg-spotify-green\/60{background-color:#1db95499}.bg-theme-blue-accent{--tw-bg-opacity: 1;background-color:rgb(147 197 253 / var(--tw-bg-opacity, 1))}.bg-theme-blue-primary{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-theme-blue-primary\/10{background-color:#3b82f61a}.bg-theme-blue-secondary{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.bg-theme-green-accent{--tw-bg-opacity: 1;background-color:rgb(0 230 118 / var(--tw-bg-opacity, 1))}.bg-theme-green-primary{--tw-bg-opacity: 1;background-color:rgb(29 185 84 / var(--tw-bg-opacity, 1))}.bg-theme-green-primary\/10{background-color:#1db9541a}.bg-theme-green-secondary{--tw-bg-opacity: 1;background-color:rgb(30 215 96 / var(--tw-bg-opacity, 1))}.bg-theme-pink-accent{--tw-bg-opacity: 1;background-color:rgb(251 113 133 / var(--tw-bg-opacity, 1))}.bg-theme-pink-primary{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-theme-pink-primary\/10{background-color:#ec48991a}.bg-theme-pink-secondary{--tw-bg-opacity: 1;background-color:rgb(244 114 182 / var(--tw-bg-opacity, 1))}.bg-theme-purple-accent{--tw-bg-opacity: 1;background-color:rgb(196 181 253 / var(--tw-bg-opacity, 1))}.bg-theme-purple-primary{--tw-bg-opacity: 1;background-color:rgb(139 92 246 / var(--tw-bg-opacity, 1))}.bg-theme-purple-primary\/10{background-color:#8b5cf61a}.bg-theme-purple-secondary{--tw-bg-opacity: 1;background-color:rgb(167 139 250 / var(--tw-bg-opacity, 1))}.bg-theme-red-accent{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-theme-red-primary{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-theme-red-primary\/10{background-color:#dc26261a}.bg-theme-red-secondary{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-theme-turquoise-accent{--tw-bg-opacity: 1;background-color:rgb(103 232 249 / var(--tw-bg-opacity, 1))}.bg-theme-turquoise-primary{--tw-bg-opacity: 1;background-color:rgb(6 182 212 / var(--tw-bg-opacity, 1))}.bg-theme-turquoise-primary\/10{background-color:#06b6d41a}.bg-theme-turquoise-secondary{--tw-bg-opacity: 1;background-color:rgb(34 211 238 / var(--tw-bg-opacity, 1))}.bg-theme-yellow-accent{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-theme-yellow-primary{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-theme-yellow-primary\/10{background-color:#eab3081a}.bg-theme-yellow-secondary{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-white\/10{background-color:#ffffff1a}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-amber-500{--tw-gradient-from: #f59e0b var(--tw-gradient-from-position);--tw-gradient-to: rgb(245 158 11 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-400{--tw-gradient-from: #60a5fa var(--tw-gradient-from-position);--tw-gradient-to: rgb(96 165 250 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-500{--tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-500\/30{--tw-gradient-from: rgb(59 130 246 / .3) var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-cyan-400{--tw-gradient-from: #22d3ee var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 211 238 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-cyan-500{--tw-gradient-from: #06b6d4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-gray-500{--tw-gradient-from: #6b7280 var(--tw-gradient-from-position);--tw-gradient-to: rgb(107 114 128 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-gray-600{--tw-gradient-from: #4b5563 var(--tw-gradient-from-position);--tw-gradient-to: rgb(75 85 99 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-500{--tw-gradient-from: #22c55e var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-500\/30{--tw-gradient-from: rgb(34 197 94 / .3) var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-600{--tw-gradient-from: #16a34a var(--tw-gradient-from-position);--tw-gradient-to: rgb(22 163 74 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-500{--tw-gradient-from: #f97316 var(--tw-gradient-from-position);--tw-gradient-to: rgb(249 115 22 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-pink-500{--tw-gradient-from: #ec4899 var(--tw-gradient-from-position);--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500\/20{--tw-gradient-from: rgb(168 85 247 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500\/30{--tw-gradient-from: rgb(168 85 247 / .3) var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-600{--tw-gradient-from: #9333ea var(--tw-gradient-from-position);--tw-gradient-to: rgb(147 51 234 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-500{--tw-gradient-from: #ef4444 var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 68 68 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-600{--tw-gradient-from: #dc2626 var(--tw-gradient-from-position);--tw-gradient-to: rgb(220 38 38 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-500{--tw-gradient-from: #64748b var(--tw-gradient-from-position);--tw-gradient-to: rgb(100 116 139 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-spotify-green{--tw-gradient-from: #1db954 var(--tw-gradient-from-position);--tw-gradient-to: rgb(29 185 84 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-teal-500{--tw-gradient-from: #14b8a6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(20 184 166 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-blue-primary{--tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-green-primary{--tw-gradient-from: #1db954 var(--tw-gradient-from-position);--tw-gradient-to: rgb(29 185 84 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-pink-primary{--tw-gradient-from: #ec4899 var(--tw-gradient-from-position);--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-purple-primary{--tw-gradient-from: #8b5cf6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(139 92 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-red-primary{--tw-gradient-from: #dc2626 var(--tw-gradient-from-position);--tw-gradient-to: rgb(220 38 38 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-turquoise-primary{--tw-gradient-from: #06b6d4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-theme-yellow-primary{--tw-gradient-from: #eab308 var(--tw-gradient-from-position);--tw-gradient-to: rgb(234 179 8 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-white\/20{--tw-gradient-from: rgb(255 255 255 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-400{--tw-gradient-from: #facc15 var(--tw-gradient-from-position);--tw-gradient-to: rgb(250 204 21 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-500{--tw-gradient-from: #eab308 var(--tw-gradient-from-position);--tw-gradient-to: rgb(234 179 8 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-blue-500\/20{--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(59 130 246 / .2) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-blue-500\/30{--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(59 130 246 / .3) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-blue-600{--tw-gradient-to: rgb(37 99 235 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #2563eb var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-black{--tw-gradient-to: #000 var(--tw-gradient-to-position)}.to-blue-500{--tw-gradient-to: #3b82f6 var(--tw-gradient-to-position)}.to-cyan-400{--tw-gradient-to: #22d3ee var(--tw-gradient-to-position)}.to-cyan-500{--tw-gradient-to: #06b6d4 var(--tw-gradient-to-position)}.to-cyan-500\/30{--tw-gradient-to: rgb(6 182 212 / .3) var(--tw-gradient-to-position)}.to-cyan-600{--tw-gradient-to: #0891b2 var(--tw-gradient-to-position)}.to-emerald-500{--tw-gradient-to: #10b981 var(--tw-gradient-to-position)}.to-emerald-500\/30{--tw-gradient-to: rgb(16 185 129 / .3) var(--tw-gradient-to-position)}.to-gray-600{--tw-gradient-to: #4b5563 var(--tw-gradient-to-position)}.to-green-500{--tw-gradient-to: #22c55e var(--tw-gradient-to-position)}.to-green-600{--tw-gradient-to: #16a34a var(--tw-gradient-to-position)}.to-lime-500{--tw-gradient-to: #84cc16 var(--tw-gradient-to-position)}.to-orange-500{--tw-gradient-to: #f97316 var(--tw-gradient-to-position)}.to-pink-500{--tw-gradient-to: #ec4899 var(--tw-gradient-to-position)}.to-pink-500\/20{--tw-gradient-to: rgb(236 72 153 / .2) var(--tw-gradient-to-position)}.to-pink-500\/30{--tw-gradient-to: rgb(236 72 153 / .3) var(--tw-gradient-to-position)}.to-pink-600{--tw-gradient-to: #db2777 var(--tw-gradient-to-position)}.to-purple-500{--tw-gradient-to: #a855f7 var(--tw-gradient-to-position)}.to-purple-600{--tw-gradient-to: #9333ea var(--tw-gradient-to-position)}.to-red-500{--tw-gradient-to: #ef4444 var(--tw-gradient-to-position)}.to-red-800{--tw-gradient-to: #991b1b var(--tw-gradient-to-position)}.to-rose-500{--tw-gradient-to: #f43f5e var(--tw-gradient-to-position)}.to-slate-500{--tw-gradient-to: #64748b var(--tw-gradient-to-position)}.to-teal-500{--tw-gradient-to: #14b8a6 var(--tw-gradient-to-position)}.to-theme-blue-secondary{--tw-gradient-to: #60a5fa var(--tw-gradient-to-position)}.to-theme-green-secondary{--tw-gradient-to: #1ed760 var(--tw-gradient-to-position)}.to-theme-pink-secondary{--tw-gradient-to: #f472b6 var(--tw-gradient-to-position)}.to-theme-purple-secondary{--tw-gradient-to: #a78bfa var(--tw-gradient-to-position)}.to-theme-red-secondary{--tw-gradient-to: #ef4444 var(--tw-gradient-to-position)}.to-theme-turquoise-secondary{--tw-gradient-to: #22d3ee var(--tw-gradient-to-position)}.to-theme-yellow-secondary{--tw-gradient-to: #f59e0b var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.to-violet-600{--tw-gradient-to: #7c3aed var(--tw-gradient-to-position)}.to-yellow-600{--tw-gradient-to: #ca8a04 var(--tw-gradient-to-position)}.object-cover{-o-object-fit:cover;object-fit:cover}.p-10{padding:2.5rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-relaxed{line-height:1.625}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-pink-400{--tw-text-opacity: 1;color:rgb(244 114 182 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-spotify-green{--tw-text-opacity: 1;color:rgb(29 185 84 / var(--tw-text-opacity, 1))}.text-spotify-green\/20{color:#1db95433}.text-spotify-green\/25{color:#1db95440}.text-spotify-green\/30{color:#1db9544d}.text-theme-blue-primary{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-theme-green-primary{--tw-text-opacity: 1;color:rgb(29 185 84 / var(--tw-text-opacity, 1))}.text-theme-pink-primary{--tw-text-opacity: 1;color:rgb(236 72 153 / var(--tw-text-opacity, 1))}.text-theme-purple-primary{--tw-text-opacity: 1;color:rgb(139 92 246 / var(--tw-text-opacity, 1))}.text-theme-red-primary{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-theme-turquoise-primary{--tw-text-opacity: 1;color:rgb(6 182 212 / var(--tw-text-opacity, 1))}.text-theme-yellow-primary{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/30{color:#ffffff4d}.text-white\/40{color:#fff6}.text-white\/50{color:#ffffff80}.text-white\/60{color:#fff9}.text-white\/70{color:#ffffffb3}.text-white\/80{color:#fffc}.placeholder-white\/50::-moz-placeholder{color:#ffffff80}.placeholder-white\/50::placeholder{color:#ffffff80}.placeholder-white\/60::-moz-placeholder{color:#fff9}.placeholder-white\/60::placeholder{color:#fff9}.opacity-0{opacity:0}.opacity-10{opacity:.1}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_30px_rgba\(147\,51\,234\,0\.3\)\]{--tw-shadow: 0 0 30px rgba(147,51,234,.3);--tw-shadow-colored: 0 0 30px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-md{--tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / .07)) drop-shadow(0 2px 2px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:dark;color:#ffffffde;background:transparent;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%;--theme-primary: #1db954;--theme-secondary: #1ed760;--theme-accent: #00e676}*{box-sizing:border-box}html,body{margin:0;padding:0;height:100%;overflow-x:hidden}body{background:transparent;background-attachment:fixed;min-height:100vh}#root{min-height:100vh;position:relative}.glass{background:#ffffff1a;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #0000004d}.glass-dark{background:#0003;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,.1);box-shadow:0 8px 32px #0006}.glass-theme{background:var(--theme-primary);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid var(--theme-primary);box-shadow:0 8px 32px var(--theme-primary);opacity:.1}.glass-green{background:#1db9541a;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(29,185,84,.3);box-shadow:0 8px 32px #1db95433}::-webkit-scrollbar{width:8px}::-webkit-scrollbar-track{background:#ffffff1a;border-radius:4px}::-webkit-scrollbar-thumb{background:var(--theme-primary);border-radius:4px;opacity:.6}::-webkit-scrollbar-thumb:hover{background:var(--theme-primary);opacity:.8}.particles{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:-1}.particle{position:absolute;background:radial-gradient(circle,var(--theme-primary) 0%,transparent 70%);border-radius:50%;animation:float 20s infinite linear;opacity:.3}@keyframes float{0%{transform:translateY(100vh) rotate(0);opacity:0}10%{opacity:1}90%{opacity:1}to{transform:translateY(-100px) rotate(360deg);opacity:0}}.wave-bubble{position:absolute;border-radius:50%;background:radial-gradient(circle,var(--theme-primary) 0%,var(--theme-secondary) 50%,var(--theme-accent) 100%);filter:blur(40px);animation:wave-flow 8s ease-in-out infinite;opacity:.4}.light-cylinder{position:absolute;top:-30%;transform-origin:top center;width:400px;height:150vh;background:linear-gradient(to bottom,var(--theme-primary) 0%,var(--theme-secondary) 15%,var(--theme-accent) 30%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.2) 70%,rgba(255,255,255,.1) 85%,transparent 100%);border-radius:200px;animation:liquid-flow 40s ease-in-out infinite;filter:blur(80px)}.light-cylinder-1{animation-delay:0s;left:10%;width:600px;height:160vh}.light-cylinder-2{animation-delay:13s;left:45%;width:550px;height:140vh}.light-cylinder-3{animation-delay:26s;left:70%;width:580px;height:150vh}@keyframes liquid-flow{0%{transform:translate(0) translateY(0) rotate(0) scale(1);opacity:.7;filter:blur(80px)}20%{transform:translate(40px) translateY(15px) rotate(2deg) scale(1.05);opacity:.75;filter:blur(85px)}40%{transform:translate(-25px) translateY(-8px) rotate(-1.5deg) scale(.95);opacity:.65;filter:blur(82px)}60%{transform:translate(60px) translateY(25px) rotate(3deg) scale(1.1);opacity:.8;filter:blur(88px)}80%{transform:translate(-15px) translateY(10px) rotate(-1deg) scale(.98);opacity:.75;filter:blur(84px)}to{transform:translate(0) translateY(0) rotate(0) scale(1);opacity:.7;filter:blur(80px)}}.wave-bubble:nth-child(1){width:300px;height:300px;top:10%;left:10%;animation-delay:0s;animation-duration:12s}.wave-bubble:nth-child(2){width:200px;height:200px;top:60%;right:15%;animation-delay:2s;animation-duration:10s}.wave-bubble:nth-child(3){width:250px;height:250px;bottom:20%;left:20%;animation-delay:4s;animation-duration:14s}.wave-bubble:nth-child(4){width:180px;height:180px;top:30%;right:40%;animation-delay:6s;animation-duration:9s}.wave-bubble:nth-child(5){width:320px;height:320px;bottom:40%;right:10%;animation-delay:8s;animation-duration:16s}@keyframes wave-flow{0%,to{transform:translateY(0) translate(0) scale(1);opacity:.3}25%{transform:translateY(-50px) translate(30px) scale(1.1);opacity:.6}50%{transform:translateY(-20px) translate(-20px) scale(.9);opacity:.4}75%{transform:translateY(-80px) translate(40px) scale(1.2);opacity:.7}}.soap-bubble{position:absolute;border-radius:50%;background:radial-gradient(circle at 30% 30%,#fffc,#fff6,#9333ea33,#3b82f64d,#ec489933,#ffffff1a);border:2px solid rgba(255,255,255,.3);box-shadow:inset 0 0 20px #fff3,inset 0 0 40px #9333ea1a,0 0 30px #ffffff1a;animation:bubble-float 8s ease-in-out infinite}.bubble-small{width:20px;height:20px;animation:bubble-rise 3s ease-out forwards}.bubble-medium{width:40px;height:40px;animation:bubble-float 6s ease-in-out infinite}.bubble-large{width:80px;height:80px;animation:bubble-float 10s ease-in-out infinite}@keyframes bubble-float{0%,to{transform:translateY(0) scale(1);opacity:.6}50%{transform:translateY(-20px) scale(1.1);opacity:.8}}@keyframes bubble-rise{0%{transform:translateY(0) scale(1);opacity:.8}to{transform:translateY(-150px) scale(.2);opacity:0}}.glass-fluid{background:#0000004d;-webkit-backdrop-filter:blur(30px);backdrop-filter:blur(30px);border:1px solid rgba(255,255,255,.1);box-shadow:0 8px 32px #00000080,inset 0 1px #ffffff1a}.glass-bubble{background:radial-gradient(circle at 30% 30%,#ffffff26,#ffffff14,#9333ea1a,#3b82f614,#ec48990f,#ffffff08);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,.2);box-shadow:inset 0 0 20px #ffffff1a,inset 0 0 40px #9333ea0d,0 8px 32px #9333ea1a,0 0 20px #ffffff0d;transition:all .3s cubic-bezier(.4,0,.2,1)}.glass-bubble:hover{background:radial-gradient(circle at 30% 30%,#fff3,#ffffff1f,#9333ea26,#3b82f61f,#ec48991a,#ffffff0d);border:1px solid rgba(255,255,255,.3);box-shadow:inset 0 0 25px #ffffff26,inset 0 0 50px #9333ea14,0 12px 40px #9333ea33,0 0 30px #ffffff1a;transform:translateY(-2px)}.spotify-hover{transition:all .3s cubic-bezier(.4,0,.2,1)}.spotify-hover:hover{transform:translateY(-2px);box-shadow:0 12px 40px var(--theme-primary)}.gradient-text{background:linear-gradient(135deg,var(--theme-primary),var(--theme-secondary),var(--theme-primary));background-size:200% 200%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-shift 3s ease infinite}@keyframes gradient-shift{0%,to{background-position:0% 50%}50%{background-position:100% 50%}}.pulse-play{animation:pulse-play 2s infinite}@keyframes pulse-play{0%{box-shadow:0 0 0 0 var(--theme-primary)}70%{box-shadow:0 0 0 10px var(--theme-primary)}to{box-shadow:0 0 0 0 var(--theme-primary)}}.hover\:border-white\/30:hover{border-color:#ffffff4d}.hover\:bg-pink-500\/30:hover{background-color:#ec48994d}.hover\:bg-pink-600:hover{--tw-bg-opacity: 1;background-color:rgb(219 39 119 / var(--tw-bg-opacity, 1))}.hover\:bg-red-500\/30:hover{background-color:#ef44444d}.hover\:bg-spotify-green\/90:hover{background-color:#1db954e6}.hover\:bg-theme-blue-primary\/20:hover{background-color:#3b82f633}.hover\:bg-theme-green-primary\/20:hover{background-color:#1db95433}.hover\:bg-theme-pink-primary\/20:hover{background-color:#ec489933}.hover\:bg-theme-purple-primary\/20:hover{background-color:#8b5cf633}.hover\:bg-theme-red-primary\/20:hover{background-color:#dc262633}.hover\:bg-theme-turquoise-primary\/20:hover{background-color:#06b6d433}.hover\:bg-theme-yellow-primary\/20:hover{background-color:#eab30833}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/20:hover{background-color:#fff3}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:from-pink-600:hover{--tw-gradient-from: #db2777 var(--tw-gradient-from-position);--tw-gradient-to: rgb(219 39 119 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:from-purple-700:hover{--tw-gradient-from: #7e22ce var(--tw-gradient-from-position);--tw-gradient-to: rgb(126 34 206 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:via-blue-700:hover{--tw-gradient-to: rgb(29 78 216 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #1d4ed8 var(--tw-gradient-via-position), var(--tw-gradient-to)}.hover\:to-pink-700:hover{--tw-gradient-to: #be185d var(--tw-gradient-to-position)}.hover\:to-red-600:hover{--tw-gradient-to: #dc2626 var(--tw-gradient-to-position)}.hover\:text-red-300:hover{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-white\/5:hover{--tw-shadow-color: rgb(255 255 255 / .05);--tw-shadow: var(--tw-shadow-colored)}.focus\:border-spotify-green:focus{--tw-border-opacity: 1;border-color:rgb(29 185 84 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-spotify-green:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(29 185 84 / var(--tw-ring-opacity, 1))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-spotify-green{--tw-text-opacity: 1;color:rgb(29 185 84 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:opacity-100{opacity:1}@media (min-width: 640px){.sm\:hidden{display:none}.sm\:h-12{height:3rem}.sm\:h-5{height:1.25rem}.sm\:h-6{height:1.5rem}.sm\:w-12{width:3rem}.sm\:w-5{width:1.25rem}.sm\:w-6{width:1.5rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-3{gap:.75rem}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.sm\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.sm\:self-auto{align-self:auto}.sm\:p-3{padding:.75rem}.sm\:p-6{padding:1.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media (min-width: 768px){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:text-6xl{font-size:3.75rem;line-height:1}}@media (min-width: 1024px){.lg\:block{display:block}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}} diff --git a/dist/index.html b/dist/index.html index b71c8f3..f1067a8 100644 --- a/dist/index.html +++ b/dist/index.html @@ -6,8 +6,8 @@ 💕 Our Musical Journey - - + +
diff --git a/server/dist/routes/users.js b/server/dist/routes/users.js index 7b58d92..97b8563 100644 --- a/server/dist/routes/users.js +++ b/server/dist/routes/users.js @@ -4,6 +4,90 @@ import axios from 'axios'; import { requireAuth } from '../middleware/auth.js'; import { syncUserData } from '../lib/sync.js'; import { ensureValidAccessToken } from '../lib/spotify.js'; +// Helper functions for unique categories +function calculateLongestSession(tracks) { + if (tracks.length === 0) + return { duration: 0, startTime: 0, endTime: 0 }; + const sortedTracks = tracks.sort((a, b) => a.played_at - b.played_at); + let longestSession = { duration: 0, startTime: 0, endTime: 0 }; + let currentSession = { startTime: sortedTracks[0]?.played_at || 0, endTime: sortedTracks[0]?.played_at || 0 }; + for (let i = 1; i < sortedTracks.length; i++) { + const timeDiff = sortedTracks[i].played_at - sortedTracks[i - 1].played_at; + if (timeDiff <= 30 * 60 * 1000) { // 30 minutes gap + currentSession.endTime = sortedTracks[i].played_at; + } + else { + const sessionDuration = currentSession.endTime - currentSession.startTime; + if (sessionDuration > longestSession.duration) { + longestSession = { ...currentSession, duration: sessionDuration }; + } + currentSession = { startTime: sortedTracks[i].played_at, endTime: sortedTracks[i].played_at }; + } + } + // Check the final session + const finalSessionDuration = currentSession.endTime - currentSession.startTime; + if (finalSessionDuration > longestSession.duration) { + longestSession = { ...currentSession, duration: finalSessionDuration }; + } + // If no session is longer than 0, use the first track as a 1-minute session + if (longestSession.duration === 0 && tracks.length > 0) { + const firstTrack = sortedTracks[0]; + longestSession = { + startTime: firstTrack.played_at, + endTime: firstTrack.played_at + 60000, // 1 minute + duration: 60000 + }; + } + return longestSession; +} +function calculateMostDiverseDay(tracks) { + const dayGroups = tracks.reduce((acc, track) => { + const date = new Date(track.played_at).toDateString(); + if (!acc[date]) + acc[date] = new Set(); + track.artists?.forEach((artist) => acc[date].add(artist.id)); + return acc; + }, {}); + let mostDiverse = { date: '', artistCount: 0 }; + Object.entries(dayGroups).forEach(([date, artists]) => { + if (artists.size > mostDiverse.artistCount) { + mostDiverse = { date, artistCount: artists.size }; + } + }); + return mostDiverse; +} +function getMostActiveMonth(tracks) { + const monthGroups = tracks.reduce((acc, track) => { + const date = new Date(track.played_at); + const monthKey = `${date.getFullYear()}-${date.getMonth() + 1}`; + acc[monthKey] = (acc[monthKey] || 0) + 1; + return acc; + }, {}); + let mostActive = { month: '', count: 0 }; + Object.entries(monthGroups).forEach(([month, count]) => { + if (count > mostActive.count) { + mostActive = { month, count: count }; + } + }); + return mostActive; +} +function calculateListeningVelocity(tracks, timeRange) { + if (tracks.length === 0) + return 0; + let daysInRange = 1; + if (timeRange === 'year') + daysInRange = 365; + else if (timeRange === 'month') + daysInRange = 30; + else if (timeRange === 'week') + daysInRange = 7; + else { + const firstTrack = Math.min(...tracks.map(t => t.played_at)); + const lastTrack = Math.max(...tracks.map(t => t.played_at)); + daysInRange = Math.max(1, (lastTrack - firstTrack) / (1000 * 60 * 60 * 24)); + } + return tracks.length / daysInRange; +} export const usersRouter = Router(); // Fetch and store user data (recently played, top tracks/artists) usersRouter.post('/:uid/sync', requireAuth, async (req, res) => { @@ -126,3 +210,263 @@ usersRouter.get('/:uid/audio-features', requireAuth, async (req, res) => { res.status(500).json({ error: 'Failed to fetch audio features', detail: e?.response?.data || e?.message }); } }); +// Wrapped feature - generate personalized music statistics +usersRouter.get('/:uid/wrapped', requireAuth, async (req, res) => { + try { + const { uid } = req.params; + if (!req.user) + return res.status(403).json({ error: 'Forbidden' }); + if (req.user.uid !== uid) { + const paired = db.db.prepare('SELECT 1 FROM friendships WHERE (user_a_id=? AND user_b_id=?) OR (user_a_id=? AND user_b_id=?)').get(req.user.uid, uid, uid, req.user.uid); + if (!paired) + return res.status(403).json({ error: 'Forbidden' }); + } + // Get time range from query (default to all time) + const timeRange = req.query.range || 'all'; + let timeFilter = ''; + let timeParams = [uid]; + if (timeRange === 'year') { + const oneYearAgo = Date.now() - (365 * 24 * 60 * 60 * 1000); + timeFilter = 'AND played_at >= ?'; + timeParams.push(oneYearAgo); + } + else if (timeRange === 'month') { + const oneMonthAgo = Date.now() - (30 * 24 * 60 * 60 * 1000); + timeFilter = 'AND played_at >= ?'; + timeParams.push(oneMonthAgo); + } + else if (timeRange === 'week') { + const oneWeekAgo = Date.now() - (7 * 24 * 60 * 60 * 1000); + timeFilter = 'AND played_at >= ?'; + timeParams.push(oneWeekAgo); + } + // Get all played tracks for analysis + const playedTracks = db.db.prepare(` + SELECT played_at, track_json + FROM recently_played + WHERE user_id = ? ${timeFilter} + ORDER BY played_at DESC + `).all(...timeParams); + if (playedTracks.length === 0) { + return res.json({ + totalTracks: 0, + totalListeningTime: 0, + topSongs: [], + topArtists: [], + topGenres: [], + listeningPatterns: { + mostActiveHour: 0, + mostActiveDay: 'Monday', + listeningStreak: 0 + }, + timeRange, + generatedAt: Date.now() + }); + } + // Parse tracks and calculate statistics + const tracks = playedTracks.map(row => { + const track = JSON.parse(row.track_json); + return { + ...track, + played_at: row.played_at, + duration_ms: track.duration_ms || 0 + }; + }); + // Calculate total listening time + const totalListeningTime = tracks.reduce((sum, track) => sum + (track.duration_ms || 0), 0); + // Top songs (by play count) + const songCounts = new Map(); + tracks.forEach(track => { + const key = track.id; + if (songCounts.has(key)) { + const existing = songCounts.get(key); + existing.count++; + existing.totalDuration += track.duration_ms || 0; + } + else { + songCounts.set(key, { track, count: 1, totalDuration: track.duration_ms || 0 }); + } + }); + const topSongs = Array.from(songCounts.values()) + .sort((a, b) => b.count - a.count) + .slice(0, 10) + .map(item => ({ + ...item.track, + playCount: item.count, + totalDuration: item.totalDuration + })); + // Top artists (by play count) + const artistCounts = new Map(); + tracks.forEach(track => { + track.artists?.forEach((artist) => { + const key = artist.id; + if (artistCounts.has(key)) { + const existing = artistCounts.get(key); + existing.count++; + existing.totalDuration += track.duration_ms || 0; + } + else { + artistCounts.set(key, { artist, count: 1, totalDuration: track.duration_ms || 0 }); + } + }); + }); + const topArtists = Array.from(artistCounts.values()) + .sort((a, b) => b.count - a.count) + .slice(0, 10) + .map(item => ({ + ...item.artist, + playCount: item.count, + totalDuration: item.totalDuration + })); + // Top genres (extract from track data if available) + const genreCounts = new Map(); + tracks.forEach(track => { + // Try to extract genres from track data + if (track.album?.genres) { + track.album.genres.forEach((genre) => { + genreCounts.set(genre, (genreCounts.get(genre) || 0) + 1); + }); + } + }); + const topGenres = Array.from(genreCounts.entries()) + .sort((a, b) => b[1] - a[1]) + .slice(0, 10) + .map(([genre, count]) => ({ genre, count })); + // Listening patterns + const hours = new Array(24).fill(0); + const days = new Array(7).fill(0); + const dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + tracks.forEach(track => { + const date = new Date(track.played_at); + hours[date.getHours()]++; + days[date.getDay()]++; + }); + const mostActiveHour = hours.indexOf(Math.max(...hours)); + const mostActiveDay = dayNames[days.indexOf(Math.max(...days))]; + // Calculate listening streak (consecutive days with at least one play) + const playDates = new Set(tracks.map(track => new Date(track.played_at).toDateString())); + const sortedDates = Array.from(playDates).sort().reverse(); + let streak = 0; + let currentDate = new Date(); + let lastPlayDate = null; + for (let i = 0; i < sortedDates.length; i++) { + const playDate = new Date(sortedDates[i]); + const daysDiff = lastPlayDate ? + Math.floor((lastPlayDate.getTime() - playDate.getTime()) / (1000 * 60 * 60 * 24)) : + Math.floor((currentDate.getTime() - playDate.getTime()) / (1000 * 60 * 60 * 24)); + if (daysDiff === 1 || (i === 0 && daysDiff <= 1)) { + streak++; + lastPlayDate = playDate; + } + else { + break; + } + } + // Get partner data if available + let partnerData = null; + try { + const partner = db.db.prepare('SELECT user_b_id FROM friendships WHERE user_a_id = ? UNION SELECT user_a_id FROM friendships WHERE user_b_id = ?').get(uid, uid); + if (partner?.user_b_id) { + const partnerTracks = db.db.prepare(` + SELECT played_at, track_json + FROM recently_played + WHERE user_id = ? ${timeFilter} + ORDER BY played_at DESC + `).all(...timeParams.slice(0, -1), partner.user_b_id, ...timeParams.slice(-1)); + if (partnerTracks.length > 0) { + const partnerTracksParsed = partnerTracks.map(row => { + const track = JSON.parse(row.track_json); + return { ...track, played_at: row.played_at, duration_ms: track.duration_ms || 0 }; + }); + partnerData = { + totalTracks: partnerTracksParsed.length, + totalListeningTime: partnerTracksParsed.reduce((sum, track) => sum + (track.duration_ms || 0), 0), + topSongs: partnerTracksParsed.slice(0, 5), + topArtists: partnerTracksParsed.slice(0, 5).map(track => track.artists?.[0]).filter(Boolean) + }; + } + } + } + catch (e) { + // Partner data not available + } + // Calculate additional unique categories + const uniqueCategories = { + // Most played song this week + songOfTheWeek: tracks.filter(track => { + const weekAgo = Date.now() - (7 * 24 * 60 * 60 * 1000); + return track.played_at >= weekAgo; + }).reduce((acc, track) => { + acc[track.id] = (acc[track.id] || 0) + 1; + return acc; + }, {}), + // Longest listening session (consecutive plays) + longestSession: calculateLongestSession(tracks), + // Most diverse day (most unique artists in one day) + mostDiverseDay: calculateMostDiverseDay(tracks), + // Late night listener (plays after 11 PM) + lateNightListener: tracks.filter(track => new Date(track.played_at).getHours() >= 23).length, + // Early bird (plays before 6 AM) + earlyBird: tracks.filter(track => new Date(track.played_at).getHours() < 6).length, + // Weekend warrior (plays on weekends) + weekendWarrior: tracks.filter(track => { + const day = new Date(track.played_at).getDay(); + return day === 0 || day === 6; + }).length, + // Discovery rate (new artists discovered) + discoveryRate: new Set(tracks.map(track => track.artists?.[0]?.id).filter(Boolean)).size, + // Average song length + averageSongLength: tracks.length > 0 ? tracks.reduce((sum, track) => sum + (track.duration_ms || 0), 0) / tracks.length : 0, + // Most active month + mostActiveMonth: getMostActiveMonth(tracks), + // Listening velocity (songs per day) + listeningVelocity: calculateListeningVelocity(tracks, timeRange) + }; + // Get data collection start date + const firstPlay = db.db.prepare('SELECT MIN(played_at) as first_play FROM recently_played WHERE user_id = ?').get(uid); + const dataCollectionStart = firstPlay?.first_play || Date.now(); + res.json({ + totalTracks: tracks.length, + totalListeningTime, + topSongs, + topArtists, + topGenres, + listeningPatterns: { + mostActiveHour, + mostActiveDay, + listeningStreak: streak + }, + uniqueCategories, + partnerData, + dataCollectionStart, + timeRange, + generatedAt: Date.now() + }); + } + catch (e) { + console.error('Wrapped generation error:', e); + res.status(500).json({ error: 'Failed to generate wrapped data', detail: e?.message }); + } +}); +// Get artist details with profile picture +usersRouter.get('/:uid/artist/:artistId', requireAuth, async (req, res) => { + try { + const { uid, artistId } = req.params; + if (!req.user) + return res.status(403).json({ error: 'Forbidden' }); + if (req.user.uid !== uid) { + const paired = db.db.prepare('SELECT 1 FROM friendships WHERE (user_a_id=? AND user_b_id=?) OR (user_a_id=? AND user_b_id=?)').get(req.user.uid, uid, uid, req.user.uid); + if (!paired) + return res.status(403).json({ error: 'Forbidden' }); + } + const accessToken = await ensureValidAccessToken(uid); + const response = await axios.get(`https://api.spotify.com/v1/artists/${artistId}`, { + headers: { Authorization: `Bearer ${accessToken}` } + }); + res.json(response.data); + } + catch (e) { + console.error('Artist fetch error:', e); + res.status(500).json({ error: 'Failed to fetch artist data', detail: e?.message }); + } +}); diff --git a/server/node_modules/.package-lock.json b/server/node_modules/.package-lock.json index c725311..60a97f4 100644 --- a/server/node_modules/.package-lock.json +++ b/server/node_modules/.package-lock.json @@ -331,8 +331,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/basic-auth": { "version": "2.0.1", @@ -357,7 +356,6 @@ "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz", "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", "hasInstallScript": true, - "license": "MIT", "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" @@ -367,7 +365,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", "dependencies": { "file-uri-to-path": "1.0.0" } @@ -376,7 +373,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -425,7 +421,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -478,8 +473,7 @@ "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -555,7 +549,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" }, @@ -570,7 +563,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -666,7 +658,6 @@ "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -777,7 +768,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" } @@ -831,8 +821,7 @@ "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "node_modules/finalhandler": { "version": "1.3.1", @@ -909,8 +898,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/function-bind": { "version": "1.1.2", @@ -974,8 +962,7 @@ "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "node_modules/gopd": { "version": "1.2.0", @@ -1082,8 +1069,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/inherits": { "version": "2.0.4", @@ -1094,8 +1080,7 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/ipaddr.js": { "version": "1.9.1", @@ -1270,7 +1255,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -1282,7 +1266,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1290,8 +1273,7 @@ "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/morgan": { "version": "1.10.1", @@ -1330,8 +1312,7 @@ "node_modules/napi-build-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" }, "node_modules/negotiator": { "version": "0.6.3", @@ -1346,7 +1327,6 @@ "version": "3.78.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.78.0.tgz", "integrity": "sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==", - "license": "MIT", "dependencies": { "semver": "^7.3.5" }, @@ -1400,7 +1380,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1424,7 +1403,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "license": "MIT", "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", @@ -1469,7 +1447,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -1518,7 +1495,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -1533,7 +1509,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1782,8 +1757,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/simple-get": { "version": "4.0.1", @@ -1803,7 +1777,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", @@ -1823,7 +1796,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -1832,7 +1804,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1841,7 +1812,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "license": "MIT", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -1853,7 +1823,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -1898,7 +1867,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" }, @@ -1952,8 +1920,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utils-merge": { "version": "1.0.1", @@ -1989,8 +1956,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" } } } diff --git a/server/node_modules/better-sqlite3/build/Makefile b/server/node_modules/better-sqlite3/build/Makefile new file mode 100644 index 0000000..0083862 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Makefile @@ -0,0 +1,339 @@ +# We borrow heavily from the kernel build setup, though we are simpler since +# we don't have Kconfig tweaking settings on us. + +# The implicit make rules have it looking for RCS files, among other things. +# We instead explicitly write all the rules we care about. +# It's even quicker (saves ~200ms) to pass -r on the command line. +MAKEFLAGS=-r + +# The source directory tree. +srcdir := .. +abs_srcdir := $(abspath $(srcdir)) + +# The name of the builddir. +builddir_name ?= . + +# The V=1 flag on command line makes us verbosely print command lines. +ifdef V + quiet= +else + quiet=quiet_ +endif + +# Specify BUILDTYPE=Release on the command line for a release build. +BUILDTYPE ?= Release + +# Directory all our build output goes into. +# Note that this must be two directories beneath src/ for unit tests to pass, +# as they reach into the src/ directory for data with relative paths. +builddir ?= $(builddir_name)/$(BUILDTYPE) +abs_builddir := $(abspath $(builddir)) +depsdir := $(builddir)/.deps + +# Object output directory. +obj := $(builddir)/obj +abs_obj := $(abspath $(obj)) + +# We build up a list of every single one of the targets so we can slurp in the +# generated dependency rule Makefiles in one pass. +all_deps := + + + +CC.target ?= $(CC) +CFLAGS.target ?= $(CPPFLAGS) $(CFLAGS) +CXX.target ?= $(CXX) +CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS) +LINK.target ?= $(LINK) +LDFLAGS.target ?= $(LDFLAGS) +AR.target ?= $(AR) + +# C++ apps need to be linked with g++. +LINK ?= $(CXX.target) + +# TODO(evan): move all cross-compilation logic to gyp-time so we don't need +# to replicate this environment fallback in make as well. +CC.host ?= gcc +CFLAGS.host ?= $(CPPFLAGS_host) $(CFLAGS_host) +CXX.host ?= g++ +CXXFLAGS.host ?= $(CPPFLAGS_host) $(CXXFLAGS_host) +LINK.host ?= $(CXX.host) +LDFLAGS.host ?= $(LDFLAGS_host) +AR.host ?= ar + +# Define a dir function that can handle spaces. +# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions +# "leading spaces cannot appear in the text of the first argument as written. +# These characters can be put into the argument value by variable substitution." +empty := +space := $(empty) $(empty) + +# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces +replace_spaces = $(subst $(space),?,$1) +unreplace_spaces = $(subst ?,$(space),$1) +dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) + +# Flags to make gcc output dependency info. Note that you need to be +# careful here to use the flags that ccache and distcc can understand. +# We write to a dep file on the side first and then rename at the end +# so we can't end up with a broken dep file. +depfile = $(depsdir)/$(call replace_spaces,$@).d +DEPFLAGS = -MMD -MF $(depfile).raw + +# We have to fixup the deps output in a few ways. +# (1) the file output should mention the proper .o file. +# ccache or distcc lose the path to the target, so we convert a rule of +# the form: +# foobar.o: DEP1 DEP2 +# into +# path/to/foobar.o: DEP1 DEP2 +# (2) we want missing files not to cause us to fail to build. +# We want to rewrite +# foobar.o: DEP1 DEP2 \ +# DEP3 +# to +# DEP1: +# DEP2: +# DEP3: +# so if the files are missing, they're just considered phony rules. +# We have to do some pretty insane escaping to get those backslashes +# and dollar signs past make, the shell, and sed at the same time. +# Doesn't work with spaces, but that's fine: .d files have spaces in +# their names replaced with other characters. +define fixup_dep +# The depfile may not exist if the input file didn't have any #includes. +touch $(depfile).raw +# Fixup path as in (1). +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) +# Add extra rules as in (2). +# We remove slashes and replace spaces with new lines; +# remove blank lines; +# delete the first line and append a colon to the remaining lines. +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ + grep -v '^$$' |\ + sed -e 1d -e 's|$$|:|' \ + >> $(depfile) +rm $(depfile).raw +endef + +# Command definitions: +# - cmd_foo is the actual command to run; +# - quiet_cmd_foo is the brief-output summary of the command. + +quiet_cmd_cc = CC($(TOOLSET)) $@ +cmd_cc = $(CC.$(TOOLSET)) -o $@ $< $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c + +quiet_cmd_cxx = CXX($(TOOLSET)) $@ +cmd_cxx = $(CXX.$(TOOLSET)) -o $@ $< $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c + +quiet_cmd_touch = TOUCH $@ +cmd_touch = touch $@ + +quiet_cmd_copy = COPY $@ +# send stderr to /dev/null to ignore messages when linking directories. +cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@") + +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +# Due to circular dependencies between libraries :(, we wrap the +# special "figure out circular dependencies" flags around the entire +# input list during linking. +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) -o $@ $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,--start-group $(LD_INPUTS) $(LIBS) -Wl,--end-group + +# We support two kinds of shared objects (.so): +# 1) shared_library, which is just bundling together many dependent libraries +# into a link line. +# 2) loadable_module, which is generating a module intended for dlopen(). +# +# They differ only slightly: +# In the former case, we want to package all dependent code into the .so. +# In the latter case, we want to package just the API exposed by the +# outermost module. +# This means shared_library uses --whole-archive, while loadable_module doesn't. +# (Note that --whole-archive is incompatible with the --start-group used in +# normal linking.) + +# Other shared-object link notes: +# - Set SONAME to the library filename so our binaries don't reference +# the local, absolute paths used on the link command-line. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -o $@ -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -o $@ -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) + + +# Define an escape_quotes function to escape single quotes. +# This allows us to handle quotes properly as long as we always use +# use single quotes and escape_quotes. +escape_quotes = $(subst ','\'',$(1)) +# This comment is here just to include a ' to unconfuse syntax highlighting. +# Define an escape_vars function to escape '$' variable syntax. +# This allows us to read/write command lines with shell variables (e.g. +# $LD_LIBRARY_PATH), without triggering make substitution. +escape_vars = $(subst $$,$$$$,$(1)) +# Helper that expands to a shell command to echo a string exactly as it is in +# make. This uses printf instead of echo because printf's behaviour with respect +# to escape sequences is more portable than echo's across different shells +# (e.g., dash, bash). +exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' + +# Helper to compare the command we're about to run against the command +# we logged the last time we ran the command. Produces an empty +# string (false) when the commands match. +# Tricky point: Make has no string-equality test function. +# The kernel uses the following, but it seems like it would have false +# positives, where one string reordered its arguments. +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ +# $(filter-out $(cmd_$@), $(cmd_$(1)))) +# We instead substitute each for the empty string into the other, and +# say they're equal if both substitutions produce the empty string. +# .d files contain ? instead of spaces, take that into account. +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) + +# Helper that is non-empty when a prerequisite changes. +# Normally make does this implicitly, but we force rules to always run +# so we can check their command lines. +# $? -- new prerequisites +# $| -- order-only dependencies +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) + +# Helper that executes all postbuilds until one fails. +define do_postbuilds + @E=0;\ + for p in $(POSTBUILDS); do\ + eval $$p;\ + E=$$?;\ + if [ $$E -ne 0 ]; then\ + break;\ + fi;\ + done;\ + if [ $$E -ne 0 ]; then\ + rm -rf "$@";\ + exit $$E;\ + fi +endef + +# do_cmd: run a command via the above cmd_foo names, if necessary. +# Should always run for a given target to handle command-line changes. +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. +# Third argument, if non-zero, makes it do POSTBUILDS processing. +# Note: We intentionally do NOT call dirx for depfile, since it contains ? for +# spaces already and dirx strips the ? characters. +define do_cmd +$(if $(or $(command_changed),$(prereq_changed)), + @$(call exact_echo, $($(quiet)cmd_$(1))) + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" + $(if $(findstring flock,$(word 1,$(cmd_$1))), + @$(cmd_$(1)) + @echo " $(quiet_cmd_$(1)): Finished", + @$(cmd_$(1)) + ) + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) + @$(if $(2),$(fixup_dep)) + $(if $(and $(3), $(POSTBUILDS)), + $(call do_postbuilds) + ) +) +endef + +# Declare the "all" target first so it is the default, +# even though we don't have the deps yet. +.PHONY: all +all: + +# make looks for ways to re-generate included makefiles, but in our case, we +# don't have a direct way. Explicitly telling make that it has nothing to do +# for them makes it go faster. +%.d: ; + +# Use FORCE_DO_CMD to force a target to run. Should be coupled with +# do_cmd. +.PHONY: FORCE_DO_CMD +FORCE_DO_CMD: + +TOOLSET := target +# Suffix rules, putting all outputs into $(obj). +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# Try building from generated source, too. +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) + +$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) + + +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,better_sqlite3.target.mk)))),) + include better_sqlite3.target.mk +endif +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,deps/locate_sqlite3.target.mk)))),) + include deps/locate_sqlite3.target.mk +endif +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,deps/sqlite3.target.mk)))),) + include deps/sqlite3.target.mk +endif +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,test_extension.target.mk)))),) + include test_extension.target.mk +endif + +quiet_cmd_regen_makefile = ACTION Regenerating $@ +cmd_regen_makefile = cd $(srcdir); /usr/share/nodejs/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/usr/include/nodejs" "-Dnode_gyp_dir=/usr/share/nodejs/node-gyp" "-Dnode_lib_file=/usr/include/nodejs/<(target_arch)/node.lib" "-Dmodule_root_dir=/home/pschneid/Gulfslab/projects/spotify/server/node_modules/better-sqlite3" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/home/pschneid/Gulfslab/projects/spotify/server/node_modules/better-sqlite3/build/config.gypi -I/usr/share/nodejs/node-gyp/addon.gypi -I/usr/include/nodejs/common.gypi "--toplevel-dir=." binding.gyp +Makefile: $(srcdir)/build/config.gypi $(srcdir)/deps/sqlite3.gyp $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../usr/share/nodejs/node-gyp/addon.gypi $(srcdir)/../../../../../../../../usr/include/nodejs/common.gypi $(srcdir)/deps/common.gypi $(srcdir)/deps/defines.gypi + $(call do_cmd,regen_makefile) + +# "all" is a concatenation of the "all" targets from all the included +# sub-makefiles. This is just here to clarify. +all: + +# Add in dependency-tracking rules. $(all_deps) is the list of every single +# target in our tree. Only consider the ones with .d (dependency) info: +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) +ifneq ($(d_files),) + include $(d_files) +endif diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/better_sqlite3.node.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/better_sqlite3.node.d new file mode 100644 index 0000000..7069040 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/better_sqlite3.node.d @@ -0,0 +1 @@ +cmd_Release/better_sqlite3.node := ln -f "Release/obj.target/better_sqlite3.node" "Release/better_sqlite3.node" 2>/dev/null || (rm -rf "Release/better_sqlite3.node" && cp -af "Release/obj.target/better_sqlite3.node" "Release/better_sqlite3.node") diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3.node.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3.node.d new file mode 100644 index 0000000..98f8115 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3.node.d @@ -0,0 +1 @@ +cmd_Release/obj.target/better_sqlite3.node := g++ -o Release/obj.target/better_sqlite3.node -shared -pthread -rdynamic -Wl,-Bsymbolic -Wl,--exclude-libs,ALL -m64 -Wl,-soname=better_sqlite3.node -Wl,--start-group Release/obj.target/better_sqlite3/src/better_sqlite3.o Release/obj.target/deps/sqlite3.a -Wl,--end-group -lnode diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3/src/better_sqlite3.o.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3/src/better_sqlite3.o.d new file mode 100644 index 0000000..b9dfc7a --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3/src/better_sqlite3.o.d @@ -0,0 +1,123 @@ +cmd_Release/obj.target/better_sqlite3/src/better_sqlite3.o := g++ -o Release/obj.target/better_sqlite3/src/better_sqlite3.o ../src/better_sqlite3.cpp '-DNODE_GYP_MODULE_NAME=better_sqlite3' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DBUILDING_NODE_EXTENSION' '-DNDEBUG' -I/usr/include/nodejs/include/node -I/usr/include/nodejs/src -I/usr/include/nodejs/deps/openssl/config -I/usr/include/nodejs/deps/openssl/openssl/include -I/usr/include/nodejs/deps/uv/include -I/usr/include/nodejs/deps/zlib -I/usr/include/nodejs/deps/v8/include -I./Release/obj/gen/sqlite3 -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -fPIC -m64 -O3 -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++17 -std=c++17 -MMD -MF ./Release/.deps/Release/obj.target/better_sqlite3/src/better_sqlite3.o.d.raw -c +Release/obj.target/better_sqlite3/src/better_sqlite3.o: \ + ../src/better_sqlite3.cpp ../src/better_sqlite3.hpp \ + Release/obj/gen/sqlite3/sqlite3.h /usr/include/nodejs/src/node.h \ + /usr/include/nodejs/deps/v8/include/v8.h \ + /usr/include/nodejs/deps/v8/include/cppgc/common.h \ + /usr/include/nodejs/deps/v8/include/v8config.h \ + /usr/include/nodejs/deps/v8/include/v8-array-buffer.h \ + /usr/include/nodejs/deps/v8/include/v8-local-handle.h \ + /usr/include/nodejs/deps/v8/include/v8-internal.h \ + /usr/include/nodejs/deps/v8/include/v8-version.h \ + /usr/include/nodejs/deps/v8/include/v8config.h \ + /usr/include/nodejs/deps/v8/include/v8-object.h \ + /usr/include/nodejs/deps/v8/include/v8-maybe.h \ + /usr/include/nodejs/deps/v8/include/v8-persistent-handle.h \ + /usr/include/nodejs/deps/v8/include/v8-weak-callback-info.h \ + /usr/include/nodejs/deps/v8/include/v8-primitive.h \ + /usr/include/nodejs/deps/v8/include/v8-data.h \ + /usr/include/nodejs/deps/v8/include/v8-value.h \ + /usr/include/nodejs/deps/v8/include/v8-traced-handle.h \ + /usr/include/nodejs/deps/v8/include/v8-container.h \ + /usr/include/nodejs/deps/v8/include/v8-context.h \ + /usr/include/nodejs/deps/v8/include/v8-snapshot.h \ + /usr/include/nodejs/deps/v8/include/v8-date.h \ + /usr/include/nodejs/deps/v8/include/v8-debug.h \ + /usr/include/nodejs/deps/v8/include/v8-script.h \ + /usr/include/nodejs/deps/v8/include/v8-message.h \ + /usr/include/nodejs/deps/v8/include/v8-exception.h \ + /usr/include/nodejs/deps/v8/include/v8-extension.h \ + /usr/include/nodejs/deps/v8/include/v8-external.h \ + /usr/include/nodejs/deps/v8/include/v8-function.h \ + /usr/include/nodejs/deps/v8/include/v8-function-callback.h \ + /usr/include/nodejs/deps/v8/include/v8-template.h \ + /usr/include/nodejs/deps/v8/include/v8-memory-span.h \ + /usr/include/nodejs/deps/v8/include/v8-initialization.h \ + /usr/include/nodejs/deps/v8/include/v8-callbacks.h \ + /usr/include/nodejs/deps/v8/include/v8-isolate.h \ + /usr/include/nodejs/deps/v8/include/v8-embedder-heap.h \ + /usr/include/nodejs/deps/v8/include/v8-microtask.h \ + /usr/include/nodejs/deps/v8/include/v8-statistics.h \ + /usr/include/nodejs/deps/v8/include/v8-promise.h \ + /usr/include/nodejs/deps/v8/include/v8-unwinder.h \ + /usr/include/nodejs/deps/v8/include/v8-embedder-state-scope.h \ + /usr/include/nodejs/deps/v8/include/v8-platform.h \ + /usr/include/nodejs/deps/v8/include/v8-json.h \ + /usr/include/nodejs/deps/v8/include/v8-locker.h \ + /usr/include/nodejs/deps/v8/include/v8-microtask-queue.h \ + /usr/include/nodejs/deps/v8/include/v8-primitive-object.h \ + /usr/include/nodejs/deps/v8/include/v8-proxy.h \ + /usr/include/nodejs/deps/v8/include/v8-regexp.h \ + /usr/include/nodejs/deps/v8/include/v8-typed-array.h \ + /usr/include/nodejs/deps/v8/include/v8-value-serializer.h \ + /usr/include/nodejs/deps/v8/include/v8-wasm.h \ + /usr/include/nodejs/deps/v8/include/v8-platform.h \ + /usr/include/nodejs/src/node_version.h \ + /usr/include/nodejs/src/node_api.h \ + /usr/include/nodejs/src/js_native_api.h \ + /usr/include/nodejs/src/js_native_api_types.h \ + /usr/include/nodejs/src/node_api_types.h \ + /usr/include/nodejs/src/node_object_wrap.h \ + /usr/include/nodejs/src/node_buffer.h /usr/include/nodejs/src/node.h +../src/better_sqlite3.cpp: +../src/better_sqlite3.hpp: +Release/obj/gen/sqlite3/sqlite3.h: +/usr/include/nodejs/src/node.h: +/usr/include/nodejs/deps/v8/include/v8.h: +/usr/include/nodejs/deps/v8/include/cppgc/common.h: +/usr/include/nodejs/deps/v8/include/v8config.h: +/usr/include/nodejs/deps/v8/include/v8-array-buffer.h: +/usr/include/nodejs/deps/v8/include/v8-local-handle.h: +/usr/include/nodejs/deps/v8/include/v8-internal.h: +/usr/include/nodejs/deps/v8/include/v8-version.h: +/usr/include/nodejs/deps/v8/include/v8config.h: +/usr/include/nodejs/deps/v8/include/v8-object.h: +/usr/include/nodejs/deps/v8/include/v8-maybe.h: +/usr/include/nodejs/deps/v8/include/v8-persistent-handle.h: +/usr/include/nodejs/deps/v8/include/v8-weak-callback-info.h: +/usr/include/nodejs/deps/v8/include/v8-primitive.h: +/usr/include/nodejs/deps/v8/include/v8-data.h: +/usr/include/nodejs/deps/v8/include/v8-value.h: +/usr/include/nodejs/deps/v8/include/v8-traced-handle.h: +/usr/include/nodejs/deps/v8/include/v8-container.h: +/usr/include/nodejs/deps/v8/include/v8-context.h: +/usr/include/nodejs/deps/v8/include/v8-snapshot.h: +/usr/include/nodejs/deps/v8/include/v8-date.h: +/usr/include/nodejs/deps/v8/include/v8-debug.h: +/usr/include/nodejs/deps/v8/include/v8-script.h: +/usr/include/nodejs/deps/v8/include/v8-message.h: +/usr/include/nodejs/deps/v8/include/v8-exception.h: +/usr/include/nodejs/deps/v8/include/v8-extension.h: +/usr/include/nodejs/deps/v8/include/v8-external.h: +/usr/include/nodejs/deps/v8/include/v8-function.h: +/usr/include/nodejs/deps/v8/include/v8-function-callback.h: +/usr/include/nodejs/deps/v8/include/v8-template.h: +/usr/include/nodejs/deps/v8/include/v8-memory-span.h: +/usr/include/nodejs/deps/v8/include/v8-initialization.h: +/usr/include/nodejs/deps/v8/include/v8-callbacks.h: +/usr/include/nodejs/deps/v8/include/v8-isolate.h: +/usr/include/nodejs/deps/v8/include/v8-embedder-heap.h: +/usr/include/nodejs/deps/v8/include/v8-microtask.h: +/usr/include/nodejs/deps/v8/include/v8-statistics.h: +/usr/include/nodejs/deps/v8/include/v8-promise.h: +/usr/include/nodejs/deps/v8/include/v8-unwinder.h: +/usr/include/nodejs/deps/v8/include/v8-embedder-state-scope.h: +/usr/include/nodejs/deps/v8/include/v8-platform.h: +/usr/include/nodejs/deps/v8/include/v8-json.h: +/usr/include/nodejs/deps/v8/include/v8-locker.h: +/usr/include/nodejs/deps/v8/include/v8-microtask-queue.h: +/usr/include/nodejs/deps/v8/include/v8-primitive-object.h: +/usr/include/nodejs/deps/v8/include/v8-proxy.h: +/usr/include/nodejs/deps/v8/include/v8-regexp.h: +/usr/include/nodejs/deps/v8/include/v8-typed-array.h: +/usr/include/nodejs/deps/v8/include/v8-value-serializer.h: +/usr/include/nodejs/deps/v8/include/v8-wasm.h: +/usr/include/nodejs/deps/v8/include/v8-platform.h: +/usr/include/nodejs/src/node_version.h: +/usr/include/nodejs/src/node_api.h: +/usr/include/nodejs/src/js_native_api.h: +/usr/include/nodejs/src/js_native_api_types.h: +/usr/include/nodejs/src/node_api_types.h: +/usr/include/nodejs/src/node_object_wrap.h: +/usr/include/nodejs/src/node_buffer.h: +/usr/include/nodejs/src/node.h: diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/locate_sqlite3.stamp.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/locate_sqlite3.stamp.d new file mode 100644 index 0000000..a3d358b --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/locate_sqlite3.stamp.d @@ -0,0 +1 @@ +cmd_Release/obj.target/deps/locate_sqlite3.stamp := touch Release/obj.target/deps/locate_sqlite3.stamp diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/sqlite3.a.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/sqlite3.a.d new file mode 100644 index 0000000..91c6b28 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/deps/sqlite3.a.d @@ -0,0 +1 @@ +cmd_Release/obj.target/deps/sqlite3.a := rm -f Release/obj.target/deps/sqlite3.a && ar crs Release/obj.target/deps/sqlite3.a Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o.d new file mode 100644 index 0000000..2f46e7a --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o.d @@ -0,0 +1,4 @@ +cmd_Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o := cc -o Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o Release/obj/gen/sqlite3/sqlite3.c '-DNODE_GYP_MODULE_NAME=sqlite3' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DHAVE_INT16_T=1' '-DHAVE_INT32_T=1' '-DHAVE_INT8_T=1' '-DHAVE_STDINT_H=1' '-DHAVE_UINT16_T=1' '-DHAVE_UINT32_T=1' '-DHAVE_UINT8_T=1' '-DHAVE_USLEEP=1' '-DSQLITE_DEFAULT_CACHE_SIZE=-16000' '-DSQLITE_DEFAULT_FOREIGN_KEYS=1' '-DSQLITE_DEFAULT_MEMSTATUS=0' '-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1' '-DSQLITE_DQS=0' '-DSQLITE_ENABLE_COLUMN_METADATA' '-DSQLITE_ENABLE_DESERIALIZE' '-DSQLITE_ENABLE_FTS3' '-DSQLITE_ENABLE_FTS3_PARENTHESIS' '-DSQLITE_ENABLE_FTS4' '-DSQLITE_ENABLE_FTS5' '-DSQLITE_ENABLE_GEOPOLY' '-DSQLITE_ENABLE_JSON1' '-DSQLITE_ENABLE_MATH_FUNCTIONS' '-DSQLITE_ENABLE_RTREE' '-DSQLITE_ENABLE_STAT4' '-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT' '-DSQLITE_LIKE_DOESNT_MATCH_BLOBS' '-DSQLITE_OMIT_DEPRECATED' '-DSQLITE_OMIT_PROGRESS_CALLBACK' '-DSQLITE_OMIT_SHARED_CACHE' '-DSQLITE_OMIT_TCL_VARIABLE' '-DSQLITE_SOUNDEX' '-DSQLITE_THREADSAFE=2' '-DSQLITE_TRACE_SIZE_LIMIT=32' '-DSQLITE_USE_URI=0' '-DNDEBUG' -I/usr/include/nodejs/include/node -I/usr/include/nodejs/src -I/usr/include/nodejs/deps/openssl/config -I/usr/include/nodejs/deps/openssl/openssl/include -I/usr/include/nodejs/deps/uv/include -I/usr/include/nodejs/deps/zlib -I/usr/include/nodejs/deps/v8/include -I./Release/obj/gen/sqlite3 -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -fPIC -std=c99 -w -m64 -O3 -O3 -fno-omit-frame-pointer -MMD -MF ./Release/.deps/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o.d.raw -c +Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o: \ + Release/obj/gen/sqlite3/sqlite3.c +Release/obj/gen/sqlite3/sqlite3.c: diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension.node.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension.node.d new file mode 100644 index 0000000..1d6c570 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension.node.d @@ -0,0 +1 @@ +cmd_Release/obj.target/test_extension.node := g++ -o Release/obj.target/test_extension.node -shared -pthread -rdynamic -m64 -Wl,-soname=test_extension.node -Wl,--start-group Release/obj.target/test_extension/deps/test_extension.o Release/obj.target/deps/sqlite3.a -Wl,--end-group -lnode diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension/deps/test_extension.o.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension/deps/test_extension.o.d new file mode 100644 index 0000000..09e5b6e --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/test_extension/deps/test_extension.o.d @@ -0,0 +1,7 @@ +cmd_Release/obj.target/test_extension/deps/test_extension.o := cc -o Release/obj.target/test_extension/deps/test_extension.o ../deps/test_extension.c '-DNODE_GYP_MODULE_NAME=test_extension' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DBUILDING_NODE_EXTENSION' '-DNDEBUG' -I/usr/include/nodejs/include/node -I/usr/include/nodejs/src -I/usr/include/nodejs/deps/openssl/config -I/usr/include/nodejs/deps/openssl/openssl/include -I/usr/include/nodejs/deps/uv/include -I/usr/include/nodejs/deps/zlib -I/usr/include/nodejs/deps/v8/include -I./Release/obj/gen/sqlite3 -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -fPIC -m64 -O3 -O3 -fno-omit-frame-pointer -MMD -MF ./Release/.deps/Release/obj.target/test_extension/deps/test_extension.o.d.raw -c +Release/obj.target/test_extension/deps/test_extension.o: \ + ../deps/test_extension.c Release/obj/gen/sqlite3/sqlite3ext.h \ + Release/obj/gen/sqlite3/sqlite3.h +../deps/test_extension.c: +Release/obj/gen/sqlite3/sqlite3ext.h: +Release/obj/gen/sqlite3/sqlite3.h: diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/sqlite3.a.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/sqlite3.a.d new file mode 100644 index 0000000..5508fb1 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/sqlite3.a.d @@ -0,0 +1 @@ +cmd_Release/sqlite3.a := ln -f "Release/obj.target/deps/sqlite3.a" "Release/sqlite3.a" 2>/dev/null || (rm -rf "Release/sqlite3.a" && cp -af "Release/obj.target/deps/sqlite3.a" "Release/sqlite3.a") diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/Release/test_extension.node.d b/server/node_modules/better-sqlite3/build/Release/.deps/Release/test_extension.node.d new file mode 100644 index 0000000..963c074 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/Release/test_extension.node.d @@ -0,0 +1 @@ +cmd_Release/test_extension.node := ln -f "Release/obj.target/test_extension.node" "Release/test_extension.node" 2>/dev/null || (rm -rf "Release/test_extension.node" && cp -af "Release/obj.target/test_extension.node" "Release/test_extension.node") diff --git a/server/node_modules/better-sqlite3/build/Release/.deps/ba23eeee118cd63e16015df367567cb043fed872.intermediate.d b/server/node_modules/better-sqlite3/build/Release/.deps/ba23eeee118cd63e16015df367567cb043fed872.intermediate.d new file mode 100644 index 0000000..067edb4 --- /dev/null +++ b/server/node_modules/better-sqlite3/build/Release/.deps/ba23eeee118cd63e16015df367567cb043fed872.intermediate.d @@ -0,0 +1 @@ +cmd_ba23eeee118cd63e16015df367567cb043fed872.intermediate := LD_LIBRARY_PATH=/home/pschneid/Gulfslab/projects/spotify/server/node_modules/better-sqlite3/build/Release/lib.host:/home/pschneid/Gulfslab/projects/spotify/server/node_modules/better-sqlite3/build/Release/lib.target:$$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; cd ../deps; mkdir -p /home/pschneid/Gulfslab/projects/spotify/server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3; node copy.js "/home/pschneid/Gulfslab/projects/spotify/server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3" "" diff --git a/server/node_modules/better-sqlite3/build/Release/better_sqlite3.node b/server/node_modules/better-sqlite3/build/Release/better_sqlite3.node index 145ddb7bc8589c4910b70b1a82daee02772f791c..7bf2a7010e777fc18b9e3ed4b08d557f945d2f20 100755 GIT binary patch literal 2121056 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

pjFl82Nz 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
-of{sY73R` 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�uyf}{~ubSx2o;*6vF_Z52;T4})OMlL` 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%0D}(17;Y(4YXTt#h%BAan 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�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ª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 QexfRWDJJR-T92Lo2a8C=5dZ)H literal 2038664 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

u8rJ|ymMSzDv?@w z+Nz~5W_3xz7M%-V5~7^B5#D5ClaiewVZlzl>>cj{W4qW5l{()*hFXEt5;dMr;|-vB zrfhz+)%il1ze8hDYns1i!@Sq{R?7|g)|ymu#|rS8jRu!KL9gL) z4O8(u6+zv2|6;{&w2UF!p7@KYzn9LYB}9!I>AxO-836;46uHM0Ts#zh35iL7(%!7H zSG!!?2?H)vD($uI!Iuj%6s6+}@BBpVu#+jZG2mcC$qU}$iEb!Oi9K=;B&6@01eQ?7 zD7DNEh^O;YD58hQn5Vf%&eyRo66wD|tL$(zUUVf>_wz|{`C(=r1QJOIcHuOX z67@Lpg;zu1Uvn#}jItl2ebU0VoJycmMSt@{TUgvj9)NZ0fiW^6A~0SL32+bauvDA8 z)p@CpP8uEQeOI>~8l2t;lVH7TOXnkbqz{$1)Waiq^aWcQQ*ey?oONuMJWp_yBE|<1xOJvaU?VR_=3!%#)Y^4YJaymUCTs)|LvwcNP4n2~ZT>3Vo zHe2(&psMvx)S+nHA9?80XZO-Kx4waP*A@R%pLDQQTOvVHRSk2zs)ih5f#me7kM6en z?O&f(PwV_W&X=SH?S_qtjOp5wC$4rb70yxBrI?O$(czw+4uz(yeV#-zgt+;f|A6tL zPACyfUsTr~@{iQ5Yw|+G`ZRVZdC3#|hH{Q5+)0mbhXz1xh6h_lg}(El2)>l?hpc-m zdYamKyQt~pbaZF)9!dA~Bv(5>pc_Ung7N9Dk zD=bQe(MAt2F?MEvq@HN){E4aOXv))vIG-X$FhoZdrlx2+p(h*5r61}sbJ<=@N z7Oo?#R$?4{y$SVAzm~cbpOMhAqS?N0Dv7U>vMfBrGFKkE+B+T`^tNt%(kZOq)HdrT)Iq-&p!6R{FE*(rLSx(_U?n6Tm(B>k65{O<=Mgj#TE~7LRg&8EIyW;9u42KDq%d6u%YRO-0N)e5 zoM}LxlXPR;bZ099D+UaHgNuc&WNbQ_;#bSuMmL}{B;}o+w1f=6LR%foH#TNfIZ`Tl zb4w)cg2=g;@^Z*D9{Ek=zsG1&R>qKR@R8o7>#pmiix91x&HUJ{H;CQrR_B+jevhSn zMJTjqb9(t+hO0=Qvz2Lc;pS}MF~>wQYfpy*qV4p`ql?IdLUUtAW{&z}E#MEf5an7` zB&Ai=t=RivMCa90>Ce6RSKlQ z5IEKY$63Jf7T|aXa7+Tn#=SWsP*75Xn9m^GEr+E{4s=WDlF{{ypk@VRcgqD#1(?9J zTDAP!B6;hxeB`l&FEZc`rH7UE(2=R&n*#mMUjhh<>3eWcedq(l864-!2(!?*0y2^_ zBMKf-zv||dzoMi#^qS>7N(qGvTxIt>RyMsGM63g=U6?5G zmq`(V$)pH@z+c#?^U8NZe0I#hVa@q92ca%Z9=vxZ+@efFC#P}qD#+LfzS=bI`C`*!45(~`_W z!OxVgySY-Tz5ZJB*ZCGo-&--gr*VMl9i4;r-dk~-FR@7Kx-#ouReb9GXN7CAFp8ab zpF=zq-!ki^Ps_*^8ZjZ-vk4b{)O0Ikat*zNS__nV@kz_%Qw=yJ^W>R`fFQm0zQhVD zO4nBV#qrc$*j%LIQ zZ-JJP`DF_1c%IthI$|M@+$DXW0=76lM@Uz8{b$D}rR8}x>MFoS#)Xc={;!^m5IIxo|N8;;@Q6BZRSq}qU{p|o{R6)&A+*zOso0yHyCLTjERr};qmJL;kyW8I0F4l z2qwPJu;O#zCwC%7wO&7K6Zgp!esnC&j4*7E9N6b+73*-vJN3Q>jBJGJqH3vV>z-qZvxS31fc+W&xy^*h@UTp}a8*lO@ukLDe^~`d0AeukE z2*F{%lOeLy1Q!jgseQ7RM{V+UT>q8JeS(&fGA?~YZW5c5z^+9Bz88gX;ihdUn904Q zd)BA|4e4V&iD#l_{Zy_;V~iQ(A2(bU6xsifxLm&kzw6@r>+)|Yhvrvc_;O3R000u7 zW3=V{5@d~-^f7?WD_6hrYP zN2WGZ@C^j~I9aZnYYy`gGtJrj3H9v6SOojOMBoo#NKbMYX2$gB6#8I|`D(prk=|fU zNsuI;eH;nYTkBo0pfNpiCN1gq8*Yl6N_0Kujz{%RaSI%S<d>LdsB~+FW_>yztQXdb&g145!FvOyFkP)w)&qz@~mQ8d=5TS_g4LivV!A zSmR3bM-Nbzv`5YHmHA60fTE#(1KSthg^04!UUMBRcoG%WuN33J%BuTRrp^nCQvhWE zu|;Y5!r~Raq5+-eqza?f^^TL-vWR<=brO$lu#&-&S22sOcbs1T_vW?L$P+tJz;`__ z=Td5=oabkyY&?c%AOT?4lgt~tqyM&Vy!I5{F8LL_yt@~2nQ~?>%sM@oT}m}fw{8uw zHueMA!Iq<(!QI&g`K4VT2XuFKnt;t{T+^W4-ezp%KzL~6p{9KT)}}XQ zn8u7s1n|21MO%MA#X%>wH7l@1yE$s!(2j-ctBG5Q)V{*31!`yI0@Z~!pl#5N*M%Wn zUoQlqUb4DyR;&>|5Scv=Y-n?wQcl@c6_C&xV;R9LY?s;4Neq*~6VD)?TTgm<6V6gxi zWJdOPJ>tQSb^b3WOJH}h&b!eIb^YF6IR&={*x7JRz1*Bo-88wtR~!WQt}AEk{am{4 z{9N%exbM!yKUlinb*Xmeznc`_@0IU!a9)o|6mg^RA@O$cj~&Smb9|m-iSnF z>Xo7+<$_r>zDI9+t5DCMS2ywF>_Nv@YT5kpcdLrH09Wk%@YBauH!*@ogwagQNMb+DR=6 zGUNMX#&HBK4g#Ayd7+|5=_B^^MqO(xzBStRW??K}FVF0}=S-(l6;6?jV-^fPobsp{ zAfU5R|97s;wc0Op0%6wwT{@iM{!?9Rau=!e`6BvkuO)TVPCD`6#_m_7(GWfdGmX?q z>xq!G9LxFxkrhWACX7(UZ0>Z(iLGb)>;uK>#oYnx|HQE-dH|diE<-? zwiXwGb)6Vi35Q#8G~716Ao;~?ls%L=5ZCLkK@M)!GC!t9y3z^b#KqX`K$*5&$><8e zQ)df4=;lCH$GB0iLJzZy6Sl0IiM(<_DyVIQ!@vc_+|S^aqaFOFRE-;0uMTsdaOJ1( z-6UifX~K0oEN)@@=}4a(Ci|ma zSD`Uut&-Drk}kk+Zs7rk9C*aNZfc!zY*ee*AzNc+e9UxhMcMILt%m+icW|x(=gnd1 zvL3j_Uzu7E^deH#HlA0lTQq2?{|+R%6)uu>QtIu zQCBLwhfU!`(aNYH&r(_XU?by}_EJ}^B0_^y4II*o#`=;+sOGvNMQd-QB4N4IF>({yVVC?@_u>sJY9W;s8k4Ueokouz^D=sg~d znU^WQ4?$3sD;P!TV{Dz|zG(Vb0j{3ZLt$c`dV5&V*&6cNY<9m28|oio(9gz7JvTp% zD?{tZB2<`}i{i`)Sr9dNC;eeuq3QNzsHSFqQ!q4VuO!v#)-Ai>|EJ*x6Pmp`IhTud z_Wo8OC|dJXlyEy+sAc|@3C+nkSu+03%P6h`+>8w7b-I>5MhV&K=lVl2| z7Zs6h=&9NACEK^%Y?+S)3DeJFD7L967Wi0G+g1jU-g|!f*!kGklCECIrjM0#L@7wu z#y6MVOXF&DV~zRY7HS>rHU0x>TulOdwq~+>cqjP=Ni z(g5pVAcDBbM{6CoqH9#1Cahyb`{m4?%etv-S$nvqr$$2f~tLT_6mW)(IE z;g-nn-MvMktukaqderS_>z-n?K~XF0=Z;IH6M5n+;w)@CE%SXU(9<16oIj>zX7PeeW#spO=_i^}!+3HB zTr1qNusF5gYK&CcYlr43lI7e*0R`uD&tkX$f+bu=*80UqOCWIe?WkMH?N^euQ%mkF zUSBs89)l|laFS!n#FsIj>gu;b4{S^fRg2uMZKM?^xS+Yd44m{OFEE$MPMlNUGV>?LKpw1YW|La3QokkesL4x| zK%aAjId^^`bBSV6lnnDF-iV@ef{nban`bIoKIJ3$(Kj$CaQ7i?@ZF|2slHg}R#@Uc zQ;W~_C4ZOA{M!jE+aY3OK_jXFv)sGSq32U&!-ecRTOeE9%a;(IK$DsJ70TaCut+4g z^n%&G#P7Iqvyx%4AjSbr9htw??msqkuD0ZB>fP<+eIK&$j7Ho3A=W8i%Qb<{@lcrnREc>P&08P)ub2r z7(Mcy_#H~VAb}tY3zEaxYAk}vFBg3YV94=zp{>rV!MWV;NT@Mf|66Rw z{yZK^VU_+ne`=N{&X5h7`{jQ1XUx$LM1(#B-aba)x2|OkoX=BF;?5c)QBUqW-P||a ztID&v9#ZFinaG!}^&%%Jy}=Kyji( zyonqgcUdt$>(fsv+-1llea9Ayb6=$hT55E&lGMp(joibCH5EP zv*?D_+1sbEfBT)_eRhBBI-5{iHfY?XOj)%qyG$3GPx=#=hmL02nVmc|AXmPAP8o~t zOQF;{B`+~ZE%OeEg7K~&z(4R-oczKHwWi#8&Ia*Gk%ZE7ox3()519|DA?-{)AHpC< zR%h#?fuy@*TEG5AvWtfEnsIV`v`JROALxl(ha(2cAv=o4#`gRh<@*nX+$Bw1bkccA zd!*>35-XC-(kOV=5hnTzM+9jO+D*2%aGif4)tlce^ZxZXb;-nz5j=#7Hwi$Tuk_`M zni;h%FxmB6gF=i-SJq(93`pu@U3r^voReNL3CIr;weQt3gve{aigC=MSM{iCXn zJp;vx?F&^gF71%sm3#i+(nA-ICPNJUHIF6>aI2kXUWZdX*)G@om)896fUM>RiHYpT z*caddzkh1Mt-fScNFf688OvqwYzE8C;xGh!s5zzD-6RX&{27G>X;5DE?Q3xeS01B4 z1U9-eF+gPH@89Z6JSNv&6W`{>T5+NVr;c7NJCp0BcGvdA8uRku5}#SjDm??g2VK7w zyp#IErmyR-z3XbsK|tQC6x%QM8}s_$O@EzRc?~0ASYwt@A=Pb=Ou|t6=vQ|Co7Kc3 zu{3l~DDkau`-D%${T+p0lvs1|W#y%u1HEouTdu-9=zfp52662S#f`iB& z`g1>N#z)Oc4d?3U+*2wBR>pVA`?4BKb#fy*I&^2asTQRqCi6w)3K{ARHQSAJOX@@0 zW*-how;q&NN|?%w+ts<5>S$i+GY8Zbu*r5AxbtE6^eZC zU7PgnM{pgjSxaWV6U3^pm{i>MRP$aj5UB{DRIE*kEoWr5t^+ZBy?OTuL zkZa47-^7f>dD^gmocRCa6W*5Dq-o6p$*8per8tL~QBV3xA3TOX$~h$As_l5XZ9$up z&%`U7>IfFecUmD!xjgcBtoL`S{0+4S??S>I8stj&&|szf1m#E6gIT^}j(PGd`h{<| zyuN;Q@X75L(NO;%`^2oz`Kg!}0E{RhTIWwEwIbnt3;jcR!F|9=dxR^j50YZ%^=HwDu_XLx4|ef}Tll{#n2?tjc7 zTT2BGljj=UJ*BVn3?J5-g(xe*B?|{}kmX~vU3+tsGprBoiKXfkEO2=42yt=C!=|hy^F2_$>`77~@ma5}Hk}FP0maph@ z(o26K`JD$;wL!@H(p7wr>d=GbR3~4_Pr9sUN&n3$>GGBI?0H*y=}JEMotRLBK638v zr`<>{#s|hrZSS4ue`&`_Y~i>FY4^|xsrkDRD^|gks4a_TkJ{qmhqk_E5Uvphp?pTi z(v}z6am+Yb7jJDl*)M&-Z`E}BPZ}?`_4I2yP>??8w@OatW!F{A9KlA zh8Z)pu=d1H%6W|7xY$_wC^Ka)S;4Q~p>pu#Ga{S0<&_*P4r_neTEpFkH+sypWQv%# z)Zm42bJ&QiL_xbs^q*$Bg_JNp2ix}L;{=ua1iJqi=U}1qe*Q$(aN=h#`^iaEwV_mF zITIJbV`Dv9uDVrWGqMuDC#lBsMPneopMNaE87kuRzBdMJZBcK~59>?x7~`^0p>)r{ z^#i3nEp{^fW`26#2i9ndcVG7oUI!d$do#~1)nJ&de2&InPW@Wy{3K?L7UixliqDL; z1Nn7<54HPeu#c>(`cO=N2bV{+4eXyL&5l_ky^JqL+ukPQ+uHJTRmOKGTO-Q#c>U&> z@$(c_5nwQ1u23&OMEAHmJ<%#D*Ntg&qVes$Nt?4tH6$%u0JBKm8%o{7;d8TJrUAQn zL>lQB9$6=qugL=s+tWh!<)C@9v?3TQybbbFJCfX^d1bz8YrMaT#sk(|1>OOQ5DOrP$wMUsAl>hZBbptQSun*}jQ}qiiQzyMJ zC!w`Q-mD@mX1b67Zgry6xkcJF7tV>rZ|Q}S90iEI1mmAW8Zh8Pf%^f!;I);Ed|G(} zo;w$X@M^jCfl;jQud%;Y?xTA5 z*Si0uQ9aoZK4AvK`%Z_TY93#R`QH=Ey4TTStNkZ?oKaiUMG3dx(ZEq{IsS-yVpW*P z4z5-aI#|aX^UAGz|6Z>0h_hg2EFs_9_UA{z(dF%`%mF;LRy$Af?8)8Hz(?BhAE~tW zV%CUihuh;l_V6+21XTNKzoG1tWY6K!<-GzV<0E!`;%6rCm+j1fw)8%}^0JqgdH2{A zSg?vKVqpeC9iB|_Q+I`Hi!*lsMgR{~i0emX@6m17U-n5))@DarvO)6p+U@N2-rQz> z&6^l&2tCglWyo_^rRuL(|6DJk)K}pc(AUNDFOhv<=|18?8toFE?Hu7tG2?JHsA3kM z57~QvDTX%(?aJ3(=7nNXc=_SbECOwN`)0+S6;Gc3f?2rj40vB_a+>hIeLT}d*Uwcy zdX0LLL!|u-Rd+36K0N!DF=udoGM7~#Lut(!iaa}<%dkkh?dN(_uT>^_MR)arpJ zc9C!1FdpPMYW`5&^_?^C97o(_(+(*Dula{yu&#^E?RUS0Zm0LW!+6O_9m~d3iHg40 zHA0i~1#_HkezOv#k*w=Zw7m~OfLG!aNNb*w&(sJYTNCGsD^?W3Z3pt~F;u1IdO7J) zqn}JYlq6=(#3c#q`CIe_pFc4p*~<29{&4P|U{KI?#)>-g`bw2U_zGB2`>nvPQhS66!HCQ4cWH~@K@XmF#?VUV`Zb8g{ z{s7Onkh{-L(`RXU4t} z#097^_$OSk4?MqUyz(o$LvMRi(gHy@C6APmq@-JMuW)K2in3u`+`~D$s&4u>C{nUS zl%>QSf)Afck_8f^txBy?9EU6M!e<0DJ{}}Rj<>qN#sQ^NLvzhU))9Z zDW5z^ipf-rBW66ImRYmAUO1EzkPjnc)T~uU@p29TQ;rx1BF5VjvFN!;JPo&~ot@d( z>8jU<{An0-kEhj`iR>3VOhmo3>&6 zXh5}KJV$RU)#eQ^%kFUm7FB3tnLKOExHGwbF@!;$F?MjjeHK$9zvnu1|Ep_?|OEvbaKe4(=$r z79lA|IL_5Sdh#b~9@z^kk3cY-%9uG`&sAg~g9_=H3KF{fH)Kw&gyCN<=l&K)5E60S zN)%7crkh2^iRbr)2E33yUj8J&=Cq`4AN-udl*7q=b!M=L`iKi?MsDKVo!#VusrJ~z z@By@NY6U5w){3--+&+QiU4xl#g39CS>u7>Q_c|gMwxU`TGYG;Zc~;u?ui${JhgK2r zcW6)O-)ca&--+&|NG@YrbMj!tle-3G>3X_7PkREL+p*{Oh6Ze2BVBEv&vbV$WLpn( zC--=5Chw=(J|QhhOry<}uBBOadhPm4#2g3tBCFqpxQi!Y!~{<>Ru(oVl;HWH4C9dU zP@q+_&X=_u-yX7bx>ukmi7}}}ui8$msP@p&r?~qodPS5um~rqRwq6B)5GyiG#gq1Q zYZHsR>6#MahKX@Fu{#Kf!6GDpFqLOPsArCf|@yT6ZOf)R{LEuoY{PJ)l5CRJ(Jt zD0iMlr2FnLQQ>rqQ{t*NRQ!y#YD34B@K1RJ<`6yyv5iS1q=T6ofuFji)?nOSOn{aw zK1Ab*3J!)&_ScsF7h~8U`UGD6+LGi)56Khhr-`CS!SKBWI4L};n-gcoj0HtH zf#ZyEGxd0F2?A|7HXxpmDkMMO4qqe}k>{c#tu5IRFLUCGkOVn5U3YS=NbGvL`|7IW zR*j)Q|DJX4)s^W3V!!stpCp*-;Jd89Yc?esjPDma_sbAFYRf4klb7fhO26$-4kkPV zTHsbk?6E~DcV8Uc>^q1~_%0)-t7ryU)TvunNfuAd+H&2TStKTG=bN?6zf5M8JDK~q zJy~;C@?6e4i$(SKM#~In!zuPra}~#XC*Ba5zlFu>YkTk4(Nu7S`u118MaABW8W=zlMF(mle(ae_C9kr-!*_*+!Veg;unKp~ifR12;Bjw#${xJi{wR+!LBS0}#V>wa-o;*= z0rr+(ugZUsTz%!U_#(n?A2F;n>YoYBSkRbnOj{s_y%j!lA(Y)r0Xv*R(jnu7TxxHr z<1re?#+6_PvFwr+!6&|vkU!SwAnW*A5jjDbf|wN>wH;DAYShta)sC)9Wqh&tyvkU7 z0gUZiMRmqU7&lEZM}IImF#5#&D(oKMx%fjM%tIRo?B>*>iRl``n7^A^P(eS|&>PwK z|Bb^fFIVyvwP071BCJM5v8cVt7>{jbn3x1+2@FSEL6>xf1GR~J?@>O3{!K(Z^T#r{ z4FCs?3Sn`Jx`NU_oMFXGLc+|3A`Om;z&gdO>5BPx#Nv0+=_u%MbV{J+{rTr;&3gd` zQV86%8eb2IFQgWX@Fm|%WB9z5yP3TS$%C?Che!3{kZh)0{0S_)Y0>q{9wN>$>f8}% zO%}sN(U=rO{m;gXH)F;-_E|_X>DmN3v-)R%B_?`mMXvmk+z70_NrnddVkD=vBKx5D zv^gVJr$cj8Lj zoHko5y`ctdqid^mb5YSmv!HyUQSg<(q?;B!95zmX;n_0wcjd-Md{TnK$xY$FZ40zz zB6AW&5?@{|O+1>@MuY+{Hr^vn?^?Zu%bnY3{3%4pd0=-mjC&R25CZ)uA){#?AcD8~aZ^(>$-?Tb&1nz=Iygcuq zBX)LXaAaWoNbY{~?Cj?!Yk$_Oj6gh{Cmx9Van4=H-|=~JzWowwuI2|?vuHMuxB104 zvg}tvDt0xS)1%`#kuHdtcb2Ptuh4CA)oF16&8|&E#O4U!Aeuz%!7~CPTqhRuH#p0v zh4sPZlk%2G2WUW~3GedBoZ0xZU0v5v6V#S%CR^$_4}asKW}LQs6Mxr))K}gf=b^Tx zpeAZf@W%p;o!kW@WG%yp#@{g7ys=EqOCA5O#2xV8)bSrA#@NNwkNzr|&Mld2kHs5X zYugKI;0zM~Vs9=PU4fM>^4MMF=H*m_9J^?3%?~`=-$X6Gwex-;=Nk966?Luj=6`az zIjU=CcK*^^f;Ay6*5*u>IXus|rk0*N9E5u7U+M+`Xmb`6DZNyde-o6+J)4?0QqJaY zQpJP7Z9M(KumG=DTs)4n*2T9vw==U|IrGYY`}izhrYHH;u<>$F=_9_9P$(3stuvl1%-+qXz;Udy3be#($ z;Mi}U3&q81CvUi~y+9pKYO8&z8b5-^#(T!sT)$=($|Ak*_0qRKD{?%l%Lvzrm$t0oaTUw@s0u{^UOt z3?AULunrvUO(rP9&h~F-hL)M_3n$wm5!!&XN!tG$Og#tRK9jse2VVJ|tAS3OAfaGbB57xTJpG65jmj zflXTTtx`jLS`oXVB3hufnqrEiD58+(6Gj+PyGQIlACY?NQ2L-MnO2OMfix_oIx^Cf zJTc!9b8v+@2zadG8{8c;h?P9yk3l*T>X|VX%K}NmxandEsHz0CI_vg|qP}`$b}k3Q zV^*+OZi>iyFlGU++M<|sTT#q(>y#l01Cv>{rWSXlg>%-E`i5=nh zk4X=sFzCtV&F>$R@nyu0Nl&ZsQpqo#5_oIPCj=@kKx5`_b5yx<7F!v1BImJ77R6AF zx=x3WGn&MxMiy)i)9~;LeCcbrE5lsNTsRVj%bOS4@-V=89QliFf2H=s!hQr-Earyj zZ9QWxxdzw4wpKuZyu;Ce$3LPAHfoKCeP_9eV8Z8cdd_hOemxGzBT>%Q8w##+W|2)-`Mpld;S+iyOol3 zWe+99lj{Yg8v{Z>cV2tLviy|C$3>I7N0XXTW1sljyj`TRqYyYEEOlLu8b|A)svVwNt>_1#GUyy(A!PYQN2EpabwpAM6WyyDK_5P1)~maBPB#mtPrrb! zHho~Rl0tDW*`I71(w+E^S?|a#b?6uK(p%P>9ThSx+urAucPCWMrZbwVy!-;{RcQS^ z1ah9F>-G#b%wD={4{6OW&#@`8J6O%IKIT(o$|C(COc1^Nu6{)EdpZ8}ZW>o=tEXIl z+FEL#Fq6nv#5{qcER!Q%de{mAujvX2KQe=`RA@Rxq2)g5Uwvz+Bcj+Xci{x2K4ZJA zgYO7hr5E1hOUwEY!`Z8mg5M*T$^dug#aMi6{pOWB!lp z{GXb0XQP8}tHZ!tsL+~_NrYx^L%UzT4N2V7CeOj|f5_Rzj z(>Z&gqaE&!VEzqe>0|ijhos-!Q@WKWgt?#+A!M<*Bwegoqw#0Zhj6%cZ&fH_FFJ~ZO@@haZlqXf9g)qXaQE7gi!27u&5vAtO)JmK@z&oEXH{qMm8h@=iOIsr}1k z7+{nEhh$@V3TX|ZUtCyJ7wFJ3qN7nOLi~v+8H)>~oRM7ihU&cVowGp=kzA6)L=XMS zqEB<^sSJ*Vs>I5(m}|52oBvRlbrnu^dP?u$MYe?E$5X*8>rCp)4squuU&m(3ot z#M#`eCg}eN1yK66Gjbzzv%d!`$*`c_ozdW+w6}p z$zhcd5PY+&Ob%D#oQeNKQFeix-P|a=HeT8F_9+{z?6%eXI;Wob^NTY_7oUOrdvroc zapH2d15r#ydL`${xR+oNUaZH@)Z+__xi^UY`>R9-+Sr z+qyn$%fF)DtFPBp2@;VtC*KwaT~s|*CLYVIqV|HJvPE*A!$a8^_r2u#hdA*c87G2x#EalYplH>4Mp`0mj}pPo}6H}Q(Rn70bA z6u(_x49pe7MJZ^n1r=pH1JbjLFjU>dTFL@02!4&VXEuU7o*?9=^a0SVPeftrv+tCu z(!pYXFTXw|U0pYlgD*ScwRw~1ZRC0$rfk!>rXqaoXL>gyzowWj-4%DbyCIjz%qV}j@U(aL>wkI#0|6bpGCWm;aa<&-&wu*WL7^!4zd2u&Iehug?=Vw zx{vF`v~V&M=*1JMk!T=t@^^<+)Hm7&*FT!fI@cS-z)S|iv?u^xEL@R)c;r5ak=sSV zBKg(jh*A1*MEh2ob9+V_0N%h9R-kWa)f@$^wFITCW zz)g(a90nv5441X*OCw)t?(#CP-E@i-dlsd;Iev z7}TP&Q^Zn{maem0xu@oWWK9T1=f)8%wgSiJj=%{7-MptGOYuNerWRrT4y3bA7T%OoxmkU4N;Wm3%6MZ3xf5?$rtfD1u6Im=(xU#@PmW+^#TlW#ZqL8vr!0;IPKu3 z>8lCAaxojo9HNTc-srP`&-7y$mwfeA9~+=a;YnUk}8;VF~TJHMaTzvWbP zTL1DttAG9fZ~Yr9)q*;>bYklW2b!2#Q0_}W4|R!Li)FNoOnCt2VD5c88A zN3@w6Ws!RbC(C?mmeS<0-TvqGEu=xRp}=eJ9q(!MY!z;u6bYeEBUM)dLS|0yN}GN@ zDAwk7Wh-6Dr7q1Wm(EE&S#nq`-IN7+t4d7CnB4VL$&BAZi^KYd%7KeezNl&GmlEQauD&2r9c8*Gp1>mc!D{_y*y;=825tHd{&nIwcE|iFWSnL5Q!hm(G3XmM36y1c6s;8~L`Y|| zliob1Z{66JoejmSs+BRipWXFHcGbA5bDC85v|E)_Np)R+ar4<9U{j|nk64T$g{c}| zMp&Ayh#^<*l3Wi7K$;E~+%9h|>Ma-G+LCX(_18(xS(4#1pv2b*Nkj9M z`M2P0cC6BnK(cNndF02P;Z-uAM-RCJT6t=NTL7zy9&u@?<8Y~6U&}Fg>;$Pu! z{^24N!zr%g$8BzxG#B!k!vVY?)TP_CB?p)oGS*A(TY&WE!A>S2pX4+7R~U7hsBh&( zeq7LXs<*zXU-hb%T(?N#=S&MpeN`WLNA&|&M@LDH1W=X>5 z%mzsS=NSB{7thrIXUS0iKkm*1JgVw^_?aX?z~Bv-Anwsd1?xf-D`C+Yn1LBc6h*|U zSZg$5-DQU05*VBe%pdz3}+yNEtC0cL`2tvN!d(NFD z2-<#6`~1J>3aJxQXif0?`cKp{Qcq_QGjq0xu&RNR^ zI;n$Fm=_@83f|Q+>UjJoaf?cJR$CugVEeDKciQ!$c2=1t+s16MKXNh`OlCP93~%}L z?H+JGw5GDq{VxiH6|~a?*3~R3`Lp9fjLoJb-N~e}vQ{bV^1pO+sQXLYQCbA6z z%%h#|F94DmMD|nNeYGmCm1TF3)vT7C(+5Rlh4v}jmmj^H^>XMsQ`b7+kyY~jH19IC zX4Je`mlt9J>RMrhZ=nigeFZ9XJd0HG^VFA|c7-6kA82)bqgEGiR(($*Wm3pw-zbYp z@t@K^nLb4_4^-1RdOauSA-U01G*U=@G(m1t^xxK~(wGU0X=ghb3nmMFIS6^<6Xfk8 z)oTR@va0-wDj%R~)Cev}erKcm@742V*&xD1>vknw%8k zigL2T+i&5c>>t8?X?#=+R`FI10Aa9F9OtwdPR4@CkMeZjuK4%_J~neu$mn)*@CQIg zd$@*y0_bF!r32yEALu=wRKpXc!w0CTJ)E)I?ROrxX5fwKJLDDCmGYfaL|T3z_cuum z|M;Z+J#QKd#~{tk4c%eXk3-;l7w2$w|EBbb@qlpdo#Mn~#wlulB-&$EgB%{YG_X<* zL5*m$B#FdV7BU4dv@W_mF)gmkl+LxsEoA9e{mAfT3G+3#(3kdL1TQ84IOi22&sz@~S+uwstO!Y|GXy`V-Xz zg5e{#q}IMYd$?2s2W0HX@No&Be)HmygTmz{i0(bHD@w!yBhy$xuP5x#CX~LD_CF@U zY0H+)JdZ2c{9`@6%8zwnCReuM?$gmo$_8qH&0e9XbeK_PHDs;&)i5ADeUU)-zQ=njDIm zR;F|I&#yx6ld?yU($h&%$Y!5GH!_wh^e~C9N&tu68>lKHa<0+(SDl!JN)ry1A}{klNetHxYW4z4h_D@;2Ot$3gB2cs3Yf4PSkmFTL0i&r?5LZ&YB<`nmR>jfR<%=L2F*qz-$WEKr&W_0(* zbK2L{sS_wRuTMUyoxq8yMEghk;mdyV+FeiwX_ih*@1HfJT#0O_g{L2%6&n9tg4^CA zLl(iU$N@8jx2-=D;cb`+Q}jg;I(gocaR5KnO%M9AXYaZ3B?@9~N`?XHq{e|o>t~QbH%=w!?t7BK%4sP*G?{3ni{f&1yAgGO&y7RLvf zn&lm6wTwC)4UoLJZyxK&9F>oI7I;Ve46wJLgs1EQ+x$QTp|}!)2{@YJEw5jvqCpQ_ zD-r@k_do9T^_z11(qjB#RIWr5b+Ds}`nZgA)^eG{^j0eOaRP_vF^pEUD1Nu>TZWuD z@FV0x{Q7lSSDe(%KX9$TvdLUUD9fqOZuRLe)Z1z!H_z66hE2CFb z@7lDh2rusK*x5x%)MdGzWAiXqsFm;)(}QAOTe*qlFAJ%~8ujU(&QUGi6B#l7jaeo| zp0!1oXka8@Hr+8UWumbSC**3|Yd=)*!yP+QHUzOgRQ4Ic5n1jbt3#G&X!!_Ns86gH zU)$eH(<@wJalG*YLbOdV#v|^*1SjsnD5+1!J=g|54^{U4?8xR%l}k|E1AQc$a_C+8 zK>UL_PW%J)*@=HpUiOy_z@hq5e`L`{2u4PD>_X}`TTouAsoyvnIf9+OU?Yv~335V|Ju zxYCHC46(U;hIE(X9!3nxKaiYa8N@DH6CZ?@S+yKRd$@vzoRHk?s81Qu`Q%#S=SOJ4 zhkv7Uf@4pRAnQ~UhE}(mclG|bgYrcg2GwOTEHk3SJ^1avtv)ipT$8E zbD>07Y6zHa_t-@4t_s(39t+A{JNT0~HsKw#4@U9Qt0L_LQFafJ=PShkLQog$rVL7- z8jl}yB@`r!jP#bjfSJ)>-r`5}a0D67Z`)L5bX2u9cUC{XTXg|5Xk!lX52L zR{KA|!;IYF@)n<~{Y^j(yx1me(Sc0Dg7eL&g!iT_(TDxSm+(eW2{FH@sNA7+Gi7%a zdB)BEBZ!avKm5&0D(&;q4r|C35z0)s3Jp=Wd=>u`Pi~cC$j=SSsLBoDzU_P9z3 zuA?1rsd1&1Y^#rpcRPQXLY`B+SOpaQlozM-(NPTjawTa?mku)^M!D0Pjx`V&)s<k{Pwk__@$Am}mu)86+xq3$kB1?iQvU$%D{fV|J%b6*_FpR<4mE zOBB^NqEGV4n#p!u9{(Zr2gl1cV0^R(j&ZsRwO8raj;96s=<2P+4X^o{a=h?QYbeks zwY^x4Uy5z`P!|(~S?(BNo?N;zVCI(yZ-0a^1sUpuDVikwR=nGh%>pwcdOtn#nw_0R z14)nu=E(ly_*ZzSNfhO!r$+Q5U@6w4VG0m`gG(D{4EIWB#yOo)-ps17N8R85!eJCo z?U)21tl2K%G#M*iBN%`?Ha3IVLy4>r$iBtQc z!}#JgG9JUbEz)?cx6Jk$WAGOu?o5Jrf6HCk$fUcp-qz8w1IQVtBj^p^bp{Gax&0d(TMoP2RG9Izwh?+w{yCHa__8~3c0 zQmz(HWZxmi?7Jl+8czH%=4|CR@^Yg$Hq8|~RuxZ7N9c$!Qnu4uJ&D|N13AM>yy63i zxLH)60+^PWO#?|ZU2@=N%()h{Fc!|ePYqy|F-KJX?JB_)h38PW)2m!;an5vp!4 zRM)j~W<=;6g4YblYcE&8Tk;z9UzD3)(>r|#b(jI=m{HBo^gk&8*>59ak})&r>XYd} zf7WDKE8`E(oF3*nvl_C9{nl!`Y_kGhEt5b9 z=iM?T)7<=(ZjO(vUPBe;`l_auyejinm#Qp>%G&>?`j^C4w^5H*FeOC@OFfa*jj{2r zWb4^dAS~-YvU;Pc&sd$TtQ+6#pC-qfT#u>6I3_=*8lriIzf}~?p)B4+Nmhg4t}IU$ zORcB0DtDSz zNPnI6v{WLT%RgCGNy`tXj{^v57Jo!GelIR*QNl-L+3a^UM%TS~3W*i*+!C=n4pi3t zMtWV=Y}`9rb^q^5uBn}Ll$aYcv6MP>w$YL-S!sx6C?A*#3F}MACk2vl(YG0KOVW^Xa zjmGf0Wce87!+J3_8*}7l&1tXtw+at%Cy6h|hR&i1i-o-kHOLVaU2WnQ=%%!1Ucubq z<^$TgSdAY^Numu*h8UKvG#{vwj!;zG+$0LuW5k(_Ns%{pra3k*UV%s7pXHik^Zl(O zm87?2B!&YAv@c>@5_)z39reT;#99jP;&|QfH0Fw5u0XuO4=}Jmi-co5NZ8p0_wpcT zNwpRKlRlNgpq|~li6AV`&xQl%{1}LbrCjT`gU>D@KlI=rey#1_sn2ei51A!n_RA!w z2vtkN^v8bB`7Rz$nPJ}_G|4zZB@6v&4Tq(llJ`8dSoC`J#^(yiyk&C*rZe20gvVvh zktCc9;z7vmkIxY_gT0o8T-w1R&Nj#An*Kbm=?0K)4M?{O>}^|CXCJ~E&N!lb~wA0a|7g#5_~@BA&tKi9Alp`h608%-o~fa+HGDBjKdYNM`!ui}Xl_zv+&hBO|HKHYeqp7ci1BjAV=+3C8$@DUs+AI58AV%D>1T zf52I4tH7AOUh`@lQjz(xj-nIotLc=6r|v?T8tsgW#K%MxGFJZIb(GDl{EB$Zb2{L>SbdS!(o$e1mI3LTgJHd8hs|^3VfNo4EQGLoxf5~ zn)!_;C9*8m$k>-$%&%PN!GoA;t{G7h>M-zaqATxcyC*^Ii$7f=ef1?OvSsT{tmY+9 z`6^MUT>hoQco96pflMF}zqdq&AVHU<1a*JrH3NCAo_v+1)l)z!TuWJ5^NbsShW}BI z`Jj`v&>e`^s^auxjlVT(v}C0(s)#e~gfi2tik|luWhhL(x-wE@vwq1|BjKS1!IWnZ zp}UB0$yK_tblnoE)e4d+RTcB5ZV|lZ$|W)yk^L&lWmRO<#Suk9iOaC;bJdbz9cg-= zVapx)1oO?y3WRvc0kAw?Q(#s+?ZqTosVtvLeb4{ep)w4M^vDKbSTMmE0E%TMW#Ap`|(tprd)?_4(2B0iXfx16FSAZ@!(N~Je88GSstTr?b6u2;1GQJ+zd^Nn0LUZ)#5)J)li zU%UZ<%H`tCLv{WG8W|H0{_z_EfCV>W1nXxlDIAI`1P=zhi9oix?V)r2_#@J*#BKC3 zKVUA@_)xgYU%A>#tWqx&xOJqnq&4|%%|0{Pf>A%A(r5m|Tp!tz!`*3ih@fPlHl#^6 zwRVgi6!r<@ygAQ^egr|oxBIxOGGTMCN;N-Q@^h;5#wNCS&B={e@h!04Q&vIgZu{m?O}L*F5bpAJU-6-C<78jn~YFcAC>u zq_Z_EOg=PG8t^h})c%?mOaPAHy4>F=rWNuRw|lbH0me!kJt2n@px*9ye#{j_ibfD?zDqv zfh@J}~E~vZ=U#8n5FMpT@=d{3T)Pm*d&H z9kO^8fRvFWWL>=Rr0A(yZbUVRahEH(i11X zm1l7;5*@~{zxRjNdCTLsjK}+5Mdde$VDP;El9W;s0E`|HuRf!gJ*u6gH0 zMh$WiLA)o8wm;y&De0DdvQXBf4{%sRalMaLvwfwci~Lv*5c#nh;It|p6i4cVGm)dZ z7X3aWkL`WcdCC79HN!^qNb2D3emw1Rx9^uf`;CpWnsy`{I!SP2#z+jcUsZC3q+PQ} zsh??-%AeQ!%0I3CfBS}T$j&(MY+`=CbDbyd_Ih&M{^|WRLxq0w;g)jfJxCeM3+?fa@7Q;#W`rfwYM79r1Ka)@>q$PKv0Nk~ti#x8zKvJ!DnA zp)NND`zf?hRC02&P7of_TQUGh0CH4{91Q7VA?L)G)9Y2lo1@)IzIg^07}>ZHM;a*Z z?4Xy5h9*Q_g_O>(4li=P50pKx@VPG!g3r}s0<*pe^I;l+<2K6_9WswO)dG=9oZ-14 zx8?+QxjDGS-|B72BP)nK)t~BJl5UkfudwC?&LL4bhXl%&S3lkUl0V*0ap~bV;nIz} zpjG10HGPI-0SEtH;q+=O57Mh?KjlGHHw3b$k+6G(`Mf;Y_jD=m5S{0Lse0{r$_F2a zAE)nIPG?4UIx}kT8VI)2K>qw|2eel!B%7SFSC0?N*h_xu~M-DLsEYsQEj`p+z&i3KBcbishF7G3?|k z5Y>yHJFLaKk{dmK$}0e`WWHuQ=f>*Akj}PoiQ&VArqQrjY%N}k@L|>=%GkRr(W<38 z;H*-wQp}xw3?ofjOxj*vgKU>Qq=u32Xi%vP|(ygcN%*337qhPhy6O zP!vhfa6DNTb{FFQ;q9aCUdS!d_$aY5=KPVHI0P_&x>8y8EFj1Jo~6+>R_Y(FhXmx(M`>6+MMTVPTZ5l(RM^9bx(UbvU{d6=QA3l zwpbtW9Vacng0<+tT^`d{fUh`a!B=Q5tD5!Uh`g#0D zFn0ykTH;C+)7fLD-31Nipmod%FBWC_o3`T#cWXDl>osS-(OT%m|04^yqAlj(q8(Mn zJDfS+dAZ8C4y%G&MsBP!Zd;ef&l-NN!~F7=HC4tG3`4G33-_?Y=yTCVf7$L(eYuHw z`sN+*Mi&M+jVY&Km^WuvHM#PL$G{050FaPd)#S<6DWcI#N_SFnb;=)gN**cQb&A{s zlBX9bc{(McQ}RjaB`MQFd_R=8eD!u6Zw0&^s@{IgTVLJ^)Y~}T3VG|R-tdTZVL#pq z)!P}o_2;dhdOM!CBYEqu-VWpKXx@%gZ{2u0I!~s2zsX|%HtMIMZrX$;@3LHT2XCEC z8}nQ(=9*cX8^QLbjlJ01crX?=x>^z=-6Xhnn9WVw`bM@D#4h|s9`nI#kUDnZUb7j@ zZrauz%qA`7=~T)4?EWHjQ2T6o<#h#WN!H%R!92MX$8n*b?X1D*-F)z;e4$j2h!_3w zPh2_RY(>_yc)VK3I}6mljGPW$Aothl8Y}H^G>3lS+<1G0r8gc+%M`m39k!NS zb4}B>UQJft$mT|LJ|fnD*ywM}4UD15>c!mjY^KM2h+VQbVwJ>3?~^gjIh9(>9S$|| zC(d`ZbkDM%q6zc~%RV$Br!$iBM7Mc=B}T1;u4aFXaWRUI$d+t(YzBZ?K5Z!^%%2$L zD(ysNeD~66@6X!S2&kZ)M;DlHkt1}hEnKZLUrir&SAc1BC649-Yh1?S{?;nw|i}|6V&C{52|nYm-hnhzslY< zW}kqRg9A503DE2SJHnsUjz&oS1uJ9FJJQU3 zYe&;&ma=QjzrC1$oH>38Gc@H9@q^Q9zsx*wKD-{&aQ-X+9BLZhf}b|(-?ZV%JIy!2 z{H6*2Yoh@0Bq{;RX>oV|3YMz2ktP@i> zEBp%f6m&<~Q|xC_Lg0rFtQ#8CeoIGiM#aoHW+m!K4?Moho}%D+DH&$W7kpZ&I{%8!f-d^YouqraW zkZo;w=!bGwD100KtmqW?!1f<-W31?|dd>77q~lbJzm=pacd#*4>}HB(w4Pia`@!Q< zrw2V$4{+uUddk?7aG*L)bfVz<7)!WoeOms*`B=QAtE=eOfpHhVnHx$QBQuMSGw$2L zCMGsgM2r~_*?3wxSCm!em_oC;DzZ7(h|2j=)Wbvb(aD|1i|FPqDCRG*gXOi#oVa*? zv7zL4pL>h~?%fhK^SHvfb7i4cUAK<;8Ha?44W5?Ve(aZ6wJ3ucg3c~PrM>o@U`}M? z>s7sBkCl!)OZo!V_E+MmFud0#eDYT7&tJ$a`Zl0_n(JtvzQq0qP~6~#*rCS@@jX~G?*%#da>7D?1v8u0Hc@_|>zpuR*+9kr!mF?7 ze|~cpDikfge`NW0Zt~*?h6uaJ&rI$caVCiSC4wcyd~d)h_cZSNfTBwdlbRD1je!@F zb*OnWQE_^?ys{;*b2EfZ>bRde0t0dXvmtr zq8Nz0P$YE^Z1xU(tHRX;<=&lVM4Cxc^EHcXAgM&a>f?#^o1bk&BP4mu@{$6(R){|I z0r`G01*|7gA`q>SZ+NL7R!W|p61y|G-qZ~9G3>|dTkWSjCE<{U&Cd75|I`8C5@{KP zQ%r#hzWK!nM>%s>cM+Zj0Zo4Uk85P z;yt_ZH2Wn54)`X8k2r@GmehVo4L;0c)(b=UsWL0x@W0?-LcV>x3%G-+zj=7oiSExM zZMnLQI%U~qcmHcr&N7iLSIGppM})9&k5jYDngeUf`cYkVy0_BlpRw?Q!VV&{DO6O% z$x)FJ%1`ILM(q)R)O@}AMBY5XTlgJiM57GUsw>|sSHe&~y)y$5ftN4zvyLXNHpJ0r zM^g!UraZ{H?`Z04L?t9_)vQhK&!I?ta!a6fD>1QS4HRZnl-`g!nlM~FLzfxI>H)m~LwnwJ9q%ge4C4rf) zDJj^;gx3C*@~lgY2|Z;if`@rUxpb@b+CTLoJOZqh_h(+jFCN29D@W8Zz|ak9xa+8* zRK|$8Ok^fOnhvqfSoDpw&Dhk41EwBt?stqg8Q<7?eJl=sRaskneJA;6f4oQgv%uLC z!=TWrpsdVgkSg$w-Z6QDw6p})5;QtLcvN30B`5u5I3C|!g~8LVGfSJrRt z;;yWpJyOQ2>XSwamMQe9y@b>*Xv6%0wf~gk@IMI-w$s`IZ>+9*k>7n_wf&X1vnWKq ziK0lvT6V5b@~lNn3(B}UE?*7~71Xjx?XSXrX^Ipq6ro=5P~y&UC!5qWz)ZSOQiRL4 zy*WMPi|jkxw9R*g-dw`Yoz?#H^!k$el%!AKspx}N4UG3dKS8{>SwkNcXOWS40&ljr zd}HAQjXZnG-nji|aCfa^#vj3}6@j%vZt%2(L!Tr7i4TiU9gKrbiE$f3FotsFk>;qu zqQzu&r%tVlpVYs#Mx93a_^|eO9rz|j{FJKfd<7;qxA|Xk>-7~a;S&lK|KV%eAC+-s zz@xi@$B%%(kx2;TI1osWSHq!Qlhv8P+BttGq4@pqIOUOl2_93=Q1JN8uzv*}9S?sC z9%r4pKRhm^s(%R{UC6u=rlZ|C)H;5lSgqyYrwbs?9L-fE8r;=Y5IzjGtOxiC{KM0) zfjfL;h4qBsVPu6;z9b7fIGX^DEx!`>yE~Jm=P9x)H}nI_S<25nw3EDMi{3Bn;~0Yj zU%_HNIUly9%1hDt^{Q!lGo!&e3VPOFpQ2aJd<0Jxq*oLkYA|bec6RU>@VSq|XIu6^ zr=28y1sAeI@8QQE=c4J^*Y@)&*ZU{v2ri zv`{BET|hInesWIPA775As(&3{l>I-5AQv#O2GNe`CyTX-xd%;Q3FT#-Nt+#!HgG3D zcsvnp#UuZAwqnSQu#}tEX&v&Fkp1)}p&neVq!?wSr{UFg_J9%zNNbc}Wa! zwy=7H?yX>x9&?>%NXyiDwT;1Fdg60Ll?}>#pQmNaby>>aoTqh87=}Uqc_PomcyuAz zHx@o3*DmaOkBDBI6I&-O|6qI>4%lUU0~jACH1i8Jk_iv6mv_{b=mFv*nYd_-`U;Zu z0Fy@@QDR7A6zx7&(nwdzzNmTGMO6=$$dDNBE!X)gMIYilUK#HOHA=h|Gs+fclq;tG zno&NO9;Ny3j#9LIzlGmw{eSO#UVZ-o=JO^J|CRale(!t&xBvEhdM17szTWeT1B@?0 z;`feE!VYT8RHO8`zT{dAg~E?zCd&tIR5ST^XvBXRUsL0&d|xfecczchD625@@j78X z>ovx5(Xcr`I5fOF*LbiQ-Y`-4P%fPJA&-_g;*ZU}Qpy9ja!mL)~@v@q=Ni0rc zubylNgp~OK;hq|QTV}s7lp496i)enXtW4nRMhXGBFkhk6aMIHITaOTG!%S9`BIVAbX)p-;JiBuXPUqIZvODd`@pI1 z=MO7SQvA@pXR^O-h1Rq2!yg`Gf7_Dy*8cW`AMC%sd8kT-JrX|fVEkbU_Oh#8m1*y8 zVI6uU9TDcnTxR{9IYryBulVup4cp3HLu8{dJb&6T9Dy?(HidoyjKq9Qcye{_MSLi7 zH*+$ww~4>OBzZpnH+ao!ARZ?HaoSKK89pNmiYjcW~?V(8CK{n^IDD9#%XH6OnQ zFUUrHWBdJ<^{fad^n3_@XN*DnADHx4;pB3IC!k%CVf7!Y6xRlqEzVp|!e4Fp5_t{G z)mnMEfgMQr_+yRwL4-KMR!W$%rY(7sT`l&_CnWhgshJ_#-`v(^gHiI@@5YB-_x?-x zFrh@@!`*|xhdJyO--!?F%o7s`@T`NWn9CAM%D`cZ5H7JuOh} zhB@mX)~2WkT=0APB?9fn;3dlQ-1|cG(O|NoN+^2Q01ySQPQ*JjClo8N+)L5ux|vgO z_u?(vJaZ6gWTc?YCBiBWtalBtRvs<(WIC3GEH}kCCHXk-K*CVnMaZBpO@dFj_E~qa z(Qs8l7Z!ERtnni;ejgr-a=kexBS^)PFxwhS0lP*Wo4g#Wb1JnY*5Qv+;}_wy&?6an z4~8X!?7^L5?YfZir|;l5;wHJhoRWChO_kX4{-utH*!B5+2tVf%?bk*mLg5hh*o`iM zJC~SEo3QU{bh*~b4Q4V&aLbat+)+lpo;mGkvn_qK8$6W2oX)jwFxy-$V{}k&({cMc z>r$n*n5)}2AH*NWm_MtNO>pRp;?#NM!_Tl-R5h6`lkJD7OP$;Gsb|`IN&LP7G?ISH z(#T?GQ>t2x!Ar$}&tQFX@$Lcu)yMI{sP6}KK9!>WfvaV8oJ+O(9AwmA;)-l;4DSwy zFe7yXBGhV?3P+QZ9{i+z5&BR9*9?yBfb&t!jiJoP30U%2r~D9f(NNKs4l9pUjq3TA zFM6uaLO=DM8kzW+S%1d7v{ zY~z37e3#;v4|smPJ$iug)sXnFjPLu;ugl;c{#VC$f9(Or_gfObcYOcSdFMlzi2uU) z6mO%hB-n`2EYg07jQX*8nYsU3Tr5i662VE%HN1 zi5C2K8MT6K;Sv4sIh-4c=nP&c(|dlRD9fX6QDjin7s}1baFs@etf?M#qk?_x-RJ0B zGtZDKLfr%L0wwP4o2rl0FaabxH!!;PUhi#qZ$o>o{4&xc->6I3XnN`Sou3yPJfHsG zO;dgc2DkE@ghA4uVd+Zy4p`>Yd0OVfA3yxN#wvOV;Ss0KQe)k$=dt(Vdu6OLE*Yya zM+}^0yyYsLmrf%hrV`098~2{an*;5+av7q>&V%I9V>jlAMMMTt*u8ky>)5%SG8_o| zqfJKi6R_J33G$m0cYScvE(esHz;?ao+x5<8#+*hzzO}Nn@q^Fa+mM8){k)XOs82?r z>XVqdb|0Ed)yFd)h|~2=Q}xk9sZh|?oWHoO7Zz_*Z z-(}TPNQGJ53Uh(q3+r0uSUK8wj>702#N@9^c!CEa8kGe zRqMe`UGlc0p0eG#l-9&Q5USLUlhE6siaF~37r&R>QLhPz^Z}3m#b$GO%XWQ5i$2%` z9ixhhLkValJhe`h-74L@{q!FNaBk`IeG}IDaz<6lF)7_YS2@D6@H!NTV7!V{^2tM zobHz4+Hx|k!XBq3j;-%|%y%mir@n6;p6vHy)E=lLNbBJDD-wk*f%s5k;rY<-NrmQ` zo^A6{@fVLloX|GAAg}}1w9i9D=vWLv)k+WEujulzGUQ0j0w~|HG*oU*Y_N*P|6QpSi4|Pe}^cF9WXQ;E(@na~V6ohpB zVh+h<$uc5OktCFhO4b_pKFXWQZ_G`oyxUi*d_uRx10-Cr*>%MBu=P?>`Uzb&zIT8t>2G+%+`H5O-{OUWy^l+d zMAPOC&?On*g4xcvjmQd;(gVb6mcHaS=02_RGC-iM2(vT52T8X>{3P%9mPiI(H6;Df z&kYq!+rE#%slqmX+#pI74IkXppuq(lZFtYuAawaheCtA&?Xx6zx>A`3RjJ$$+OjPq ztCCiQBqyu-3{sa-mAy^2x0HN2wf>cIo;EdtpB(Cs-;QW@lHy&=wLP1Z&WxBhcQl2H&j@w*gX zlf_`I*NF(tz1L4bhXO4$Q1~N!&SqJOAL{zmx`I$d-;wG|f=4CiL+$y&rc8E0s#5-l zMB+Eu-t@ZI6Cpy|D*V&tyx<3ve@CyR?__p%(NuWE5ARSomZKL@??tta0?980wI=d5 zb*^AkqjCT;OHgC(UHr;6FAGI6H^!VPBxNp?o{|xIQM%IFgpAGp8uXEOjsM@tmprbz z_26{XEm8Op)Gu+mWz5+}P13a&BM7h}J9tZVFS=QM>(Vg^FP-X`eLHV@{VH7MMRN#$ zBHfm{;1H}2Zn6Xst@nJE;B}Zy8&X6>Gvl9z>&=HOJ z-Y%%>mQ~QRNi4~*yk$eLz=ON5Uv@z4jq{ij?6L75gyea;3&9~S$4AlrBDtk;hkE^TSw?Gu&j_EC?C z>vkVmCOVGWoo6o!rn-XINh@mTvgx?JYg{eH$E-v}~@5 zZ0=hn2dyg=fP4kvk8^{$o*bXz%gU5jd;{MH0v++(*O|f440}Q_3G9IhlMRUIw8TP8 z(I6*v1e2v#vk?Jz4|!7$f4^Op#gD_*fLppta^43zJdFGr;F-OlH}T4tMk zGT~8!yux~trp@GvXrsLBS#2hl$BSbo_pF%78MC|T&)QT@^uLnfgg=pIIgh7s?F&*o zO1l$3{1s@1jTzvH`NTpi(@e5X`NIeF=5W~umP+4MJzx*WbT03pmEaLijstr#rpM<` zj6xu?Yj1TC!@K2fM5}_xTWB1!%FfqQ-ML%3qqZr!<0Fi&k4T4&M(q!&*RP%8sCV&e zpWzAIK7@CnR{&8eEE*g<9G?uYh!vLoF*^~{rB<6gPGzLk?N-dSPa~E+L;9-5Bk8x2 zuFP`NBJ&dWA(}>a?TvOOVzar-&6H6>tkU6=L;jz}yK@Qr_alin&Li@;=d25?kGv zD1M1))?CT&QCdIvi-%r4$-Cns{~B&$*fA$Fu@4h>rQGBi1!d2h$jB|%4Nxfj1{4UD z5;yrmsXRSfs=VgZLh((uF`K1->j1(97|{ZHPntV6wO?doUwZ(rNqGUMvT`_is|0w` z&}mLX%2!g^iqHe%=bx7K>S(24%7|1hZk^Skj7W{yg6%0o(qBs>3-1vf7JHsNYkvz6 z587*l*=e%|Js@iG75HrNHF7i*xAk+s6g*ubBtgL=Dti%fC2@(8OwJ$-!=^$Pny6ha zqN*a5g{S#}l5&>_WnfsxJcKJmjF$1)SD-*6pi+Pl#Y>TNoG7IoAk0Mp66YpUv0#uQ z01>j-7`yHLTEDp{|bch%Lo1jQEHBei!((rHKjrRYW` z#80_6vwc}R>x^aDv1!VoYeRgs9v($_RJy58@7iLVYN72#geJ+N%e3=E8B z=2-!v5Xcpr*;WTDp>u0cOjKQr~2|lnS)Hk`S}Z`_op`70_B4KNQq3DW$!<#0O(gy*y8q7JmD) z-3Kdw&L8%6a?`gFi$E!%>d0()AteuXe{0?OmxGiNmxlVjJ`*B|v(dZGvaeB9I`?5> znPGk`3{4HoL?qyZ@`XhAh`WcxZ@UW28WP!!FyI6ES~ zqOI1a+56y{l~7W{HzHwfUn8rkK zGl^2=i(G~}Rl+X_gDVPl5nL|W^yOCK>uf6X^q=uAA=rz_U%FB{^rB3eHIt(4NxA=| z@$$jGkPot-#>Yr*EY_?t`rM9JzcAHOuPgWqf8`{%Kki9Yw?M!?G94DFoiF0_CtZUf})%iXPzRUe^y%Gjod%JPzK1l z9EBy4KwtxVjX*%kM|S6g#=*)<7F6(a{W){y@u-G!Yo2uzQ0xN#(v_<37=_*Yi1s6!OguGI27 z?t98BR~hw#&vAFOWMj|1r5MK!7>iHHM}5uJwsU=C^UUKvW2YEi5Ubdzwz~EK>H6G5 zb`u({^0UO9gRo+D$L>CRBc8fZB#3;SD>^&qX9RDc3MwcRU5(dDAsOmx2nXr}XRBQK zVy>Fetu5Z(8!;JF)X)lY{fe!69rz%h!G|k;p(D0j#ux1SBqCj|x;qPbAwqbOQuQ`zFuFuR?wtAzq5!FLnA>{TMRJQB(FJ6$!?P^(kC)|gp6HPDE z_LUQ?Jv9or!5<-8g{&Vvyl-&S@E*Z4WE1S1Lck5-pSE5O*@Xh?&QG@Mxm?wFsYD^H zzm)z4mkP2jlJD<6)MZ0S(`%&$83>AgXAr5ZSzW!B$blb#W_d%lKWdF2jV z>RET9^H7nPf#;a8u%iLY@#fac!>oOX6flkvd3?OvVNb$M|qCropJcG$FHHAF|N2`90B!F?IqP#BY#& zA%kuD!99PZFpYxK<0OW=cSW0JWE*?UE!JXb~HtK|1(6}B0h|(f=8{X|4{2Bxz7%h zyCCCL(qQpS-(qV5-?>LnbZQPTQ_lD#o|a^=K7K{zEHHgfS_7pf(-$La@G8C*Sgq=7 z%>u5wGZCEo4DYcygU!x_hGZtpBwNrFZUqxMEX$`Ile zPZI70UCY=R z1KR{g381oxY~l7}^*N(*g-6a(Si*Q>M|by@UE5~dJCkw&9Ngv9aA9$rXXtUE4a86& z_Q*c#>F6F2+qMx!W;%WIyYQUt%U#lbO)dE9H9stmU)xv#=T^CF;N-;=54e^C zigH)0$F;&=IdQRaV8xj(Kvlw+2P#*HoAX3(|CgvXwLqz%E9$;d@IOvRD=991jaP|z z24F}8vpcPy`8esyZn#lKO^J&bS89EfzC%V)!#6(wYV*s@W$i}@J*F{%nKxFL9c&q z7f^=yO$@u$Zi9nUZUKKK2!|eF!&+II;?~Zn zovqW#6C;j1ozp?$?3Z&6|drVSzmC9ZEB`D}(b(1#ETVQJ~euyW3AF7*UW8f4$UfnzmJY;xVGP zOONpk<(#jLdVI>k0GX>JS`{|{ZrYkHBgo(+s`V{Zh@{_}}Cal9w)*!B~u)Z`~ z+MjXY$K3c`Z~6xQ(}>Pu$-!HJE2Zmfk2(^$VRkx#Q@HfDKjf?6kWq^wKf#*7-(z@y zE@`Z`e@_PBuQ!;CnX>N~#T9gueKom(iH#<`TBa=K%v>MFWsP48J4!%FyP3*l>wWKn zy@E61ji-h3&U*f~JaT}9CXut{jWQqc8OS5?!}f~5@@;j0vX4~f{zN#O*gl}w;%jsH zV5bGT_{(^yfWIP4o@+}Lk#7)AUchQX5H?y}rr^4rn~l+kDD|Ym&1}ajSA{tPG39cj z_IzE;Rbf_TT&8$>uJD<*M=sjyeP}mbS%5tH=0ZAv1pJ5 zb7OH7gj|Vb+Mfa1#=@H&8J&DqR~L`dUAiNJx)liOay&WRMd=}Vc@dG(;AtMhm|isY z3@%|bA1=f#hC(+4M`GKOSH-pEK1u53aB`fd*Tu(iZvmK)>(f8&wP8t?boC_>SlX*) zMv~xpg5hhypT|T6L5crIi|B7ax_#nf>tSJBQPF74+lKf)(d|#yXedI%8oWgI6lg}D zrEVDy;MKC&qo_Y6i#?Q=uCiEtk>NP?+fHwjvRGM=j8EM=$lRN`)NFTW4|L>^-V#n= zTquYj@>sf}CNm_hB?Xah$nKjO=w<;0pTP|C5-t`-YfuuOjA+csm5 zdX$?>l`!)Ro$3fPNmas330}~ZzjqvPDjVzp)}T8@PilFG`=@zERPN1%Ss3;UkeJQN zgOuV7o+~O}^CTwqZ}q*>U*;H>yuQY932&gg-*~2ZRHE>L#KqZth#18ebuz42ATEuS zJ_!y&*~=TsQ4wW%!m1IUhE_`PrwfPy@6x;WKyOY`XMnS4E6_Sxs22UW3xYQ~&pMVw ziZ^g!`g%PcN8zM;P{V;1tT^ai zV7xkzKwaGT%8L@4#M3(ZZt#K$Ba|u;iTml3=++R~pc&t# z*6O)xe2l5tbA9V+4?i}=bN#w&eGjfFT?50(E#2sAD2^J~>*8X&+_e#ln%t3z{9$-V zM=G{=^+XcGU$qlE*r9W`GZYrcF8c>dY-qTrp%&iXX#Q zEpE!jSS_plliPo5UppN*jILxZfw9AnMF)`i_ukkhg4C=yUsz zq$SV&&}Qv2O)2Wx7Y%0}WXd~m)0=c`tVAA(W5zyA@M|;$#OCL)Rw0lC<62=gEDn{Tz}*Wt*twvH(*H=6=wD~;I_r2v0T<=obbozq66KHy4uYAo#QF<-@j z2R<$LhVipSUVJ4sZSF44SzW7WhGm<|5d1K*8|RhVsNGyUYm@TQ__cOlxn8A3Htm~* zK8y6vyPl3jMNXFDLl0+Q(X$mwZ-kL)GjTKZcKa31ccF&D1Yfa2rVU3;2&}SRV!=n> zfxqz(NAE!)p=!#a6<`U=FZ1F&$qzDp)_|diS=aeEx+QuK-=c00MCMj*zMtM|?bi_t zs(oD)7(U4O(2Ejjdi$bSb=jgHr}qbKCkA8&_vL4jE9t`0h`tRBs?gs%uW1YRVXZC~ z9OvQ5&%v#ceKV&GH9zm--SQOkb0#k3;1aNP*!Yr@egSHaF?zjHsZr-mvr}P*U8KLO z#w!xH5bJNfLX2858#Y(T#c0!Rd~LcC`DGRAZ{owjM_Yao+ z`=I(fQ?L3D=<}Sv5fz@KK9B2y|66^Y|3!MWm^k$RHoeOE59l8rcJ;qUua>bK|Fims z$Itsu(5ppv{y##mp1t)u=+%n16}?(bX!-w->D6|LEc@TpKYVW7_tUGqw+>9Nc3>!Q zaC)`*jPImZ%P#*9(5uJZ$)Hykj{U!-R~gEO>C4~a&|JF#)jtcBdW4k6n$;yJuZ7Ns zan4J#yGc25>zESw$4*gidmmwb$?Yn@d=<_Mv+ArzZV)N@g#JsiR{e_GJ0cFR3*FRy zyYQuveb*YbA}5=*PgEB}CrdtEOnH-SP%dQ?BVM_MqZ!41)b3U1yU4z4jOgKV6j~xV zy5y~wys2s^6(sQAvvT&5coHh!V=4;IOaz3VhI+)6t87jUA6P$ob8lxu_6c$Xx(n5b zQG+PQNo;CC6^cQQx?iwlfGENgOa4Fq8iJwxdKK>U~+Ec?!`2CF9 zWt>Vrl&KHVeuW(38iVH|%{`h^ox8RpbajXOnA{MGE9jD;sqw(Hb!k0}gj{k$ziuO0i`23YFa}lfTu18Bi6@&#dr= zJ`<7tgLp8gbVX5sLAGKZ+6(EYdq465W&$a1$E__!B@=o7`JY*xK9oA@rn}ews z3C#Ghb3O(W(I%Q&P`YkxJeMFQ+{(Ccjf@(=u59jp5{31MaPS(9Do_4x{<2j8WAq9? zH*ATst7w_#N*e>nFsx4w1;fjx7SH@2qdv5l$uOcv(EkqKOSwi=_6q{K)$4}?ikeolu_ zP8>BxkK>^{esw{7)X@Sv0hj|n2QoLTxkey{oq6dx@dggK?}P3l&G}R^bKQ8~O_+>= zALHVMpK#ae40MId%25No;pmwkBQlh+vf{c&wz-fb3JRXAMqEoKMui7*Mh!xpTLD51 zT*q;^kF##&gY^iKJb}SaK4QbzDN8CPkL6A!CR%@GQ-j8R?+S%TOo`a6qU;Y!9(^Pa zB9Aua)JVx$yTkl3W>1l6*1`VXJB#(B;!Fk0X->@kYbdml9Mgiy(zCs~PLXI=Ux`Ud zLbS&HN-iofo5hK_@^YTrUg-(fT$dHR<8l@A#R=Obbb`91I95swpDI+0F&WF8+evVm zto{}EEn7Q_ZW(nrfmxFwp(V&Hz8i6ozH^HNRp!2CIBH-j$Z@&(gaE;z|HNyjeThpf zvRc9>zRNcZf{05@q{Tn+5{SPfBwhrMO1vg!qXZJ(=h*K*{BAPsO2}>e}$6s<0#XKU6vPDp>tj9hbCZ>$d_4Dp<8ovE{?yaWoPM;_)17*XllA;MRgX*8(*sd&i~9(vX8@hcGW{jg z<3AGnWkkQvqv}VEc`^SWYV2uFA1pQYqQ)UoBPLcO0#1#=9v;^k`9S9m!34g=T`HBj zb*00p)O{wE;&ApVU1@&I@2Aq<=Jax@^iVR4Pj>UmG0EZnTrw{iXOwofxC2t*rMkk4 ztIX+RsV~>4EztE9#QaxLUmtV&HBw(+>YI|R@5xksV|9IpwYYyOwcV;~yOHh4^j}SV z-Eb@oXU3olWB%#XS7c7VTk7L7H5?{)vdRlnRrb(T9*zjL#eE00D$PJuajcd<4E@qO zsk*ySd#$dze=JtV2WmgUY!IA~29Bfw(c?`vuw!%*2K7>E$+)9r%EP}Pi?lIM{_@X^ z3EiQMy8HP{Gd+x2xu9kQN5^9GNu!x#%m%p%lxB{l8QFA`&6ufXexjQ>PB0=Y%Tbz9 zcRf6s%0~dr#6;7ZX0UpFL^o3$i#3u)Gsl|^%XyM!PN11Ko|Da-kZLARH}eC*k#G}P zq?tAHmw#qVZhB}Y+{|B^>1oss(#@2_VjD=KnG;PF(p;K3iJTirm1gj%GGdWW11;D~ zVWav6=uQTG!eaj{ZCUb{e`f3>eyhv|kww!~FQaw^PXKN}EVe_QmfSVaZ1|EVY3dZ3 z+QoCSsqypDFNk5bYW&-Bi_pr3tz`d#qEwnZA=XroSU>!a~#yu5A{s-LPk&W z!DuE`2&I%NdQ*ka%5l(2KeTe?jP5d!&>bWh`;kXQ(8f|&$f6YPL*X=Glybptpz_R9 z!Kbd&aQuyeM&qycn2SpUiPT|2-)neX&F1(i?XM*FJCAFvbj7~Q*)R3`5S#td!3X(X zY`^8~xB7dYJ==MgbH}4xErD_c5(HhEV}k7gd@pTmkEYHW_=Iw_w67cx&mnseoIvtu zF32r}R=BfU2EdS1#IMEDH-yiQ8no;;2TY8BafYZ=dPKiC8D_bdhc;$#+E0>!kqSx*)EB+zS>MM}`Hb4url=FWlpSj-hBU%uhsyO_M!hduP zRXo&`x*@?(d#JJemcEx)a%=k)UR_YXQ%8qLbN@iu0?lFaAmcOUEaErCVZI{8%vQpX zqH57*RS$$;=d7Z%1W-LXnNF2g4ngn0Fc_E32)4T%q&|;oW+_?Zz`uix(*d7izw&@Nifd zv-ytehhN?>S=umd!@H(|4rYn|ojX>lF1%5LuiQm};D{{u5cJ_aLoXiT3YEtC@U{KD z^!Wmny4-QC-r;$a7vjfdTkgpUa3~z}-4dpM#zDq3>%nTN+p=x7}D4@Wf z#~d6r=7?o;VmxYMpD5GqBt911e-45TW|yPXkxQlZ&Z6H*l5V;^qVY|Av04UbtsMHK zV~nKEYw>PlDa3L+X=$;l<8ofrm4Pm=P^i`VD#$TSoS&#%)->v~MgCJKn)hPOE8>R| zMC#BwG|LVfQkWAODf<0PXzpNs3QNn@gg&Oz=(b`7bN279L|_6cR-n=(wzD;D)<-Tm z5>{}SM1KioS1)mb&`+jKj{SptW!q-{mZP}aSx@djSxl{`lXy_;X}0JU@FJ5^UBHAa zP!qyQtL*b>M`5`k3jm|uDEyhNO@kXY3f+;a zkSfS(7c$^((MnFzyi-+q*{*4vQk{x?el*=g-sA!ZA#f32*? z@zYVSmPmI-^nF@pS)lC8gDefV(-qZ;amS@$#nLlsUj~h2eGmaWGv>F3W3+*<{>lOg zSZE~15+GQMPs}{@aEv}<)rUz03csjWvizjj=yTa1hM=A`VP0r+^^QW z0Z@8ot=5dQ1aiK%_Fpow&J+kqivCcl7L`9#jh6-Db&Udi^Y99@L7vo_C3Qh6Ri2b- zqiWFFQli(lw5gOcoXmum3YZNlvxEzzMO{S?hDF`#!y$A}d5M9LgCy^q`7I=|k*6j{ zu$a$k?#(uPt*TP>RX3#i`X@5ekRE~4koxdA+3TGBPW$5OaGas}%;gh|`nOP38o(M> zE8;=uiNw}C^5vqJtDJBh_I+`5LX&M~IBb%_0JkZlg$P2Zs*q3SLIBXc_T$=>cMM)CYvKiRWqH&}i;qW^@wzASVUDlttzf?Qc>H|e6~MdO{JLy)O*eCO zz-)AC4_;?1$@7%G7FxKpn^e+WRg%kZ`wOc6xIgzrNi<(0rmCmxYvS}AkJM1~cpqwx zH0PGBr^59a74{1c*%!pNZhHSLRWS5k`$zBtzS@tl1KroncnoKX%L&ORs#tTFZMC9C zGlGB=3H2h{5rzV1lOPydZZ>A@f+Ft`h)m(Dr^9z@c2IPex^sFOF|;V_g_R@wJqso6 zk>hJa&SgA9kiBgsH>^8+;2MmYe?1k{Mbuk}k?*?T{pInoLm%|?C-T5cbuv9ftO@Jer&D+RN0Ty1rAXFFbT#u+<;Av%j9l&|B>r+3fWAXxJ?cM{`&fic7JB;BESQsTiCGDX71o}ulnX3}f(gU+JMcxNPb zDF8r!YnPy+eJfcNp0}dj{eM_H7x1X6Yw^z{0fIzNkbtRDP22PqDrykWM54~X49wJt z(n>0=qTGViR&A-yfDe$t$&eh61Kd_`>22+$tyOMoTUrtE1pzSu>jNKEd|ZoKMIg=Um_Wr;B_vib_oX0-q#5bV4`@MzwZ}9VhaNHL#$QQd>agGWDPyX@YKD; z8Xh}YSX!ip!&4_qJlq*$tl=|H9>dkFW^4EbCpU97Ct(ercXEQOOJ-TaFFSb_>A)^Y z*o#lT1Qg2rHaYjvxLwl-g$=){J>;0c@3KT;v!| zk0X+77fVi!?)ww{AB~0Yq)?(Tb2wXh4SlY=fp4B3!0+Bj0)!AB=SvbWd2fH5#W&+C zZpuFfPrN(L5{+SLuQOPf^j?Lqgali1pGQH_w=r1X#q;KQemuy>0#>!2;0BoHKbgio z{6EGpMMq|ZFi4^ zj}X@_bcWIavP}xlRA~*L%E3C`K&+c8o8T+gOV<9$ywxxobI*b? zFu4;hP0XEI&5;G2)^(?fUABzmNN0MZD8iOM%;?1hXnNzla%v&LcYUIOlj`*lO7&G& z?{n1*M|1H;(GawqoU$)_uok7mx!`j#gM!d8kuPk=P{1_JenFL*&jA*}{d1kr6y3FF8Z0NB~G9 z6(Fpekh8%lr$W7_9?^Y9W;%xcE5RWFZYW6%(y-e%f-!@I*U70zjz@Ap?{O!#z285j zr>cQ-|HY4BvcPJcm$Xw4)q+Zwu!(Sr`po!|oYn_RZ?C@8Kdp0AhgIww!Qc$NjdV3h zm{B>i&wU@O-xfKozj4~kmT+cbS1qsl4E{H4K}!9$8UmzlHrk^aE$m1!(HtIOHIKddKgba&;4^&50OrRMIIN)x@Y9@Cv2 zna+=`Oz4L*=(I6<9zNV(5odAR*J+l*QrJyT+vp`8be@SmmW z5y0b~3h3u`_3^GV=t@=N-l}joJ%Z=l#Tvt6l`W4lZ>Pq-nwtAQf$w6i{aWZVxjsvaSF)`jSpZpDQB@2tfZWx`k90Wl2DJmU%-97tDisj8fwb$B!8$%k|%|SpD zKT#wL%&)Xzb!-5dJrxbshAHA}AsiHeldntASl$SXtmPc(`&-dv9m}ss8I#V15PqEe zgq1QFnXT2OW_287`w`4@W^ex(a;hNd=2d`7BuIjsNjopM-Zs8kr5{eiFjtZ-P&_Da;E)k>21g5# z@Z@P#R;MT@Vt8B3-Bo};ZRuW`#0_;d%tCA|@sS8!@&?3aVkC9xRxAu!*Ch(ffp9r+ zTTrlOVOmzfLo_Q7kqW<#2e~^xCANdYZk!ME+h*^kP%bLmNVjkr$wCT7r*JjqO*GD$ zBCBbglzHONaoH6VeP~fIsA;-g!0fY zLG@MsQm7-~2y9Q?50Dik3!|ZmQ|sN$!E0O7wj$>#KZSvBfFV^#9TSc&+YhOO+3cf- z8-+>CM9dz3Ch7%k?5%r^((Sho8CI zrw|oqXry_c(wU**%#lSpQ#|iLM@(8p{K=|vaFE>zJ5dk$S1RtS8G!Tn9evLV9ow`( zJKOKRTB8Rtl?=?0^{I3Z$l%v@RV{Awy^(5epi+u1gw`LspJ$iIvqEA4V&wp53`goc zE^BZVvmxxh)hYg(u>74q%WrjlhX>%jx02t1{UP8-=j|T>KkByqO=6k7E&``3ur&xy zVFTsc<94?gTf7#9L48~fH3&)C$df5LG7gn;t{IaUON#j2bQG>9N;3JHs1s|frtvnX zrg7|ZY~YFTemw76_FF3)iiIEEIFFw^DJ~Z`*2fBUr^MLU3sdIBTAqwq(^2X_iQM1V zEv8yl>M3Uw7kbL+yhj=`GO&eTG^fjrigWFcxSxgwg9SJcB4KSO&gd4c=(l_l%`R>{ ziEtY=jd6m(*JMs7NjsekzdNk?T;8)o*d1+W8|A6eh%#ahEp>Urt4$Q{DzdXus)vu zi?u@F$p$(8$-cu^f%p(X$rYB4C0b@xr@!D_Ij&_vZRU0B?z5WawwD;eD5|d~FKsoQ!!3$mymIP5Eu6HT>Kq|lA>JVKwtjrH?J-4Y%3OQ3FaXV4VY9REf_?*wEOWLyt-8(_{*QEAms?!YXQl0O= zt_9T{Uf`@dvzY5!defgzIEQ6hZqNKJHaR&ivuA#6@|T-3yW!p=qp+gAy55H~`A;f1 z8}PhcLh(jM5vsG9>Tl1Gj^w|v3z#br(MyNQzy{!bR-taG2N5v2W8};HSzw5sZM?5?1x9HvzEW*^;bnLzlV!i{T`9OU zFt{TB&$>sFA)LRMma*cUbD-yQCpt@O;`ZwtEL-+n(VTKBAr5Fmn(Uq3ZWZo~R%g3x z#@2?nRlZ3?%0##arD6CPNm{Z}bOQ14>)C5h3fX5>`yrm433zj#U1&XmnvROvJEMM8 z%U=O&quKp6R!1{}JFX7LIRf;IVuYsEj}FtBkGXS*i`x##V9Ww=SH(Jh9{6 zAG2p8)5FL9DE1n*+xufMfU@5jeX`YYI~6!*RSR?z_Jo*yeoYjIWj^gzX~-fN-Tr7{ z=HaNY``zoOzTcl+@(8czLdxHk>7Y(V7iQeNz*y_&T;Z=6v;Q9LnqHNAc(=9T(P-CE zF?<@|sE>A?QyJ|#kMFsw<*Fi9IdvkUbt;^ADETbXFIqxKqR{RPnd*r$ICN*UYY3?X zC-!ai_w82jpcag1J>2Tp1z=l`usTHV6fd+@$66k@mfyzq7%jxZ(QGU8lmDT)t?+NV z%x$HAd$qZ(@^2-M0N)N`%vGT+yXzt1h4^6qu9gIvh4vv}%*5JzhthPEV#!~v3IEybYKb6a0L8?_I{?~Pw1ZvS<2te11V;rUU-D_p;_Md#_yN!l=;AXEUFiN z7OLp|EdPF^iy$)4I>1T!N2Gjje51Vc{t?u}v@_@7+{4{6;bvmJ&$1W-eXwM*%B)ko zS{jaqA7zzwgIj~Zt&e1X{ajS{S2i=a#kXT)pMV4ij(LYsNy+%lYFqS8`p9&LqGDGN zQVUxh5B~VF;$&BfITwTR@kfAVRW$sFN8GpmRn%R?(2Cr{I}L_{o8h3-m&dBah@1YUG0`v>J?)ubk;zY z+9`#)Cg!P9=f_~rGinOzJ&z%?*_V2zo)i`e>k$nWn6kbFU%VB1$2>yC%a(jcg)lzC z^~~NbOP?k0Ra1DA0&U-)WRZ(YdTeY@EKK0iy@k3kGvSSt5ey99*N5RntR!C~J;Z7! zD_R#IurshD?Q2TIRbq3Wa4LG^>v=6mVt($IAC^PCX0WyL`v4}Cot56fr*a09 z4e~Kr%JjV}zB1^9kJFMmJ^Fh*q=DOB~(G|H@t-{m;(&H<&<#rYTHaGq5 zU*-u^w@IsC<4v@X8pMLh+!3`Oj#ak9U#^W45n%c0@>QXotpxOH|B3q>KC|N;^4Vv3 z#cKTt5%uDQ(G{`q^Rbq9tj=LP#;#^%_WdE)$+I7C$-aMB%E_#8mULM+J(#RKwRH#x zxseyGhp}TPE6*6Z1yUESevY_7;E6;o{VBg3&8__B8F-Ay0}>1H^+| zn~k2|{0`|z7>1p3>Mf#t#pRr#8qU$AS%|&xH+S_W7l{sNL{Dni0-Ko4wI!Ev-ZtoTdyqO3; z=Pr3i%+jLSr6+}~jy76QVYDZQ2SX>2yse2jzZ8T^I3W(ORSh6+`YPuZK~RuUHp*(9 zy7;!3^BX}vaUYSnmp+7d#lvol==vjQN!!W%MCwd9cgb3?pVtG;nTg6KciE{b=vxyl zv|`fxMzZqE%JywY{E&&b7xT{0<4m?imx9$Pds5VyK2hc@L=TGNkoW^?g2p^B1#2A5 zc1Vvp$a1&0s=~^Q1GI*)VXM)Q_$ht@5q39 zr%z=5pqJ0MP0(U#TtYHL!xv5TE@DJ7a0LKS-zYCbuMaA<^0!bl4MzgG9aWq;kz2o52$)`kjH?;VeTqevfHPfVZCdcKwaG+Ptt@`wkwp{hct?J%pu z6FPAZ4fK0|;L^tv#9Ex)QNxeX68oySX;1fsilhE{CjkT>1WHz%W`E? z9BjJh?+%C4$y7l+9+(Y?)gD>P6X$%;A1^E(6ms(V0{KC{o)S@^gy#;C1*sL=w+JX> z_HQKo9G;Y2d5$&xeP;#oTIizkZKkbG+1z!Xk#^k2FETp{TppzD0cj{6ek&U8jkP== zjakcIM7f`I>KbGAe$E0l6*2pd10;57P#Mv!_PE#km3@n+&dpj^p>D{u!nh-2lYgVN z<<90+8=^jtGZpTEVnWoQmO?b6L$_ofkgl`Nn<<8^t<`Z77n5%mC|Y@u4>)?Aa2^mi zrtG|U(!2K(7e3|aH7FNQ$qum>VDOHCkE8G*#7!wMHZxZWjF;$t%uJVi--QMyKj&r4 z(J3^ef#8RCPS#1VIy-nPwBbOa@@7GlnEjH$Gl2xgcr1KGCWM6{m1mQgRWpC?uUTv{ zryv078#RAbcIkwW{YNV=`<{gHLId3@+Jq7}wxg@Ton_l(O~mZ&C6rnAK_782)_Z3Z z0zfe5;B48R6<3Jj2B!Axt*Wd_<0XRnb%*NlpgTmevSWqRjGYADL0TBKHdPVjf9Kw+ z5mlL2a|gl;t6OJt4g)oj1$@rR3xks?v}YAkAP>Q>bTV9r=A0#2s@6R<{5ax?%UTXx zc}dF57N{xH8n+)!*$)V)q9WJ4%go@DQTs6iH|P*mi%Fo{LXE_HYN~9@@|x-fVd%5y zC7_dXv zs!?TW7?s6sq<`*tpk$(;YrxFCd+`My^jGRiw$0zI^flHvp%vwa*AG%BX=sM1!CHy(!c|z(aA%TJ^Nqmo0B9!c}{KBINjP;Npfk1hYu7zF+b0-vw z4>EtX3$mmPWQ3;PNDF04Ytsb+f(OIyV=|CnRoO~#yjFIV0fyPRMKCQOQhniF2K8{N z&s`=cEn>_rA#k>?ZV)tXzXi7_UzvV@8GQrx8HJkq%7PFN`;XC<$E@YzW1+z+Cs2tk z3pJYiTi6|WzGi28B6<%+`@M&Si`V%@Vgiri+$=;_7#8O)8LLk+V)o5SGER*M-=fz_ zjw%hgvj605WpG+gVFv2hXT0hFZv?d}Wg(H@3vjVsrdN)CQjOP4`MU2HW*)Md-rid^ zp(^uQtmR>=^HSVAqGO-%=JK(uTd)~TuN58pT#P_g_H(w6EsyD*ud7UHgnO-5q!->x z+Pf^1Bi}nZjRb3DS;%^5(W$Vmmm#XQbKidHsG?bgwcO*b@a3?`*+fR&EUOt&<58Lq z4=>hL6h&bZ@0RL0=d6|&5ng1)#g+f-Aj$b3GY!1V+LBO&nO+)x|Ax! zY}5Ilriz{S$pOo`33j*(`CoSYlRBY?d~<_)=r<@Bg9j@7se-+>{aPol!1Z*tQQsIN%mnl%TJ;WxPU9VGRCy2`@0JcBuqtso3P69B2 z-uN9!dQfjx41E*W<$8t+q@c!4f^Gy5XHs#IS^Ey8#9Txu` zIj z6Vzbvbg00$0@ZTdfWFQ78}-VMM*p_Qt#D z0jLZb?&yl&>0bE{*-^BFM048^|6R12If&*Cd|-86BNQ^z= z`Vh{ZEG{z;IYU8)XP178?X*8V2+O2J<9K)oD21i0FR}x1OJ_YCSQtr#HTh(rldZjU0>i!sSlrsRT9O zLbVchXLEp#bxp|a|6tJroMN}B0VMGd+?!^?_Oz`JZ;4JmrzZ0=&aB=HK)1>W6x9mA zT?6=Z{KlW|oI2SIF9k7lWy}5ywawx z_M`VkZG3C&UFS!$sm4!NNr;Su&Db8ZR!B4#=!JX7FNC1aY$Q)*ta0>_(&_YZ$Y>h=DQ+?T{6883K1x}&1}vVY{1Dhw%dRImFof~}tEqmSg<^ic!#q=%K% zA*-?WeC)WQ$3xcrI3CCs-M1yA1d*$s0ojA|R3QIcDJG64g0i+lfc3^|_rfp0FY!e$ zFAd(w7`Ol2Y+7cFL+A?1{XOpQd3-)XfwKO~i`BgF#D)d_P3@MSaes-PS}HzEDjpcE zA8#}@m&^*UiHeHwASfw)EmbuJl+Ia1VQsBQv^>7}g6y@ULz(GVpNU1e^ETC<<5eg}eETU?n>(kTT^J{duJ(}qY^3`w)tN2- z8Bq%J?+vrO&;OYU^*by6kojM~CC2anz- zFR=wv_86Hy6(ZATQS{4TJ4bL47mSVW!*&ZFzhq&F>cL{+zefvomYW~Lo^gEU5m>cu zdcvtjloRbCPXdxC|BA39f9l8jDM~QBCp;C%{qf65&~j z^pPO5Wy4Q-;+3G*B1OH)2Q=pEO<=r5Zvt|R?LlO4DvFa-_)QOMB)^^F{w{Vgslo|! zE~^WfHO>lePB<6U(*0yu08*VjKzI`&;H59>iKm-$!1u zl{)T4>JdtA7Q_uTWV84XBKzMwlsjF2Fdr=8stHrX$O)2`o)Bd|cvLfiYxU{2eUsS~w;zf$lal_6G=z-f0;{8e#<)7pTCta&h%AD;&swp^`~D3zPi|Xt z8PCxnJqu+IylQoB){EWdf;>JO34%5CnNci2j3Y1Zj@pmJNK`_mn|SjV(uc*HzlkgS zTxr7EbWw$PCBjJB&%5hZtLQ18;1%Xc~_n=3{PjG6yp&H;4fyF+{>`I4TR7Tw&r6+&Dh$eW5sy z*#mD``6#z+IPRXLk%2vj^v{$Oz3v3iVwFG{0Hax*0A=Tdy*Zja@Yzf~dgqGlfgv2` z@f&*Bn;qb5tZ?=dlsMB`{tBX!SmDAIQZl;i)enJL`cVL!vGPyIE8JuXC!9cbmPGg^ zX6x9gdt;vtVHNQo3?~jBF($XY-&;t%evc&hGf0y}1{eObwP8s1K$EqyK#$S$^Oq^u zU5SzDhMk~Z-BEkDR$2LXfCTB%UiowOU=npX6(jV`zf0?;PSmd|9|Pq2k@tBhwXEnd z8xb({d;3{R=9Y_o4WOVdP|U;g4HCtw=iS?^A9jxxfpY#QQf*<{AQ1XII)bA%_=*Uj zg89qJI|y8LbTU-V%AMhhSqYmJ#Wqk9W>*NpA;2ubxqD>apsmKwAKKO(rmZU4>Z`!v z=Q|WEYw(+NxU|6(V;9b@q`^>MA!wlbV}p5|rWuSha03mL)qSVDD;Z3V&Ky#A*gFw` z3C(NJk{rP8J)3IiWo+y_P#E`@lX-339cvs13xXLE7xPbdQR96zs65VGgCLh}=4dC0 zIM70=*qM;}aQ$206<3@oP*5v3EB`sZ6DCqLLQM$2eLd!GT{w_bQE^tbo<@2v!SO7D z_7Lf{*)@$I(ru*L-2V5i{CG%?^m$AS2FQOogqPCbNZut@W0a(ojk7w2Q(5bh^w(fO zOr7a*f}2Jsf>}L}k77dl7+=u6WQoQ0STzB{IhT>pEx-pYBlpR>FEdR0G-Z=rx8u86<-F{ z0v#;B0X5M1cSg}VJKc_z$>5McW~o5t8ouPrCy@Ewrvx(lOFo%vJ^?aX^$Mz1$V}ro zNk5n}ARg!VG)BSUgXaif;!A`UbF42yW_sA0Bx5&I64r)wN=~6+A#pQAN~ef+`Y-yW zTRv?eD$Echf1-IEpcHgL*j}X+&^He% zwenTwB{p+PW(o^-LRyDfodp`yy*waCnr;pZJlr!Qrt{cv;Zr~mZG?Ok8J*4C6XWb z-@RKZGUxix@JHc&itdZv{*9>pkKp{IK?ZWY*b#m>h%jh;EW0I2P-uYAbw26$8nn(V z)kEzsYaAn_SKpKnUw>XD*#aDmq!~pNy>BOJ5#Wo)r0gB&>kUx7ClDD1=S8-muYE`e zzzsW5kjO^lJpn0J0_{CXIs8Klr=Lm*-IZo#MgZ^%!4}ZqD0aUE04JC_3D(c#k)ead zoiZEZ#o88j)^eJlOYVMoMA?**TPA}xOww=C=t3mqg8`1l<2e?)Dtz_9+D_U4)xh<7Ue>B^C zd}c72tk_FHIr3QmT%n-P!M)d(d4)O$PNf56@@#I$ro**jva2zW6CSzLv<7h%h(0lOh@h0I%lt`ED$= z*8)MoY>``!-_hD+<-aa_K;dj~t7aG$KHwsJ2k4alJ?NBs{m-nxSyq0cDa8P5hWSO9 zjAQlbv?|jXf4K>rs!ktSLPqpS=FLr@Pe_k?(fil}z=-q0-YIlMY2J^)GQKf1PtCao zXx>u6z#U=JOyPT#5rWKmKj2HX4%@_TC@2mFBWb3@_U{ESt2UPRpoT$dEuJ zw`ErLK-lWMoM(L-%sIr`aADYIRXf^w4(obhMercT18c)VXnJfCyllrr?!7N*hXI@UWzWR4MV(h_*yqTjQss|E63)^?c1%63PCNy z)Qj4O!CYnKACloS=2YR+Pw$uQY=J>SDp1kiM9iyS2V9R5qdR?c=4<>#FoA zP`NuIo&8X#&rh&3L=H@shGI<|wc-zXS75253kwn!ZGly>I$neS@kjqWmo##QGy-oB z3b4kVLL+@Y((|hL%aSrqMNu46aoD`5);$@;yx||LjvhV~&z$_lvaP}iHHFd>M5|Jp zaHi}hrY(N6Kj#(B+z`7dII09Ogt%znW8J!&U>rGtsgOh53m@Ql5+$>^-%e|T$*Nb8 z?lDy4OLDE{vX2*~x%179ahP~Rzt(^u2^%u3(Lw@!wYDL>5PBtIs6aM{h;K3Rxrlpr z@_JCMP&I;O-2?|ltVsLsD2=6fVdjW1hR|c5oxch*o5DoABX^2R5XB@|)Rv4#=I#F> z{ujr^jgvp<5BK29pKYxSWoDa+Kos~G`?UHu-78C2c3S54j!}Z~Z@Cjb4R-vD7lEAg zEw}cmkNUk8JmR|`AWWv+{S;)uPhS?1`qFhlU32`p_KY^d6%v{wRo7>taLs=A z+3TobmbA4BvrtiS_+s$u{`P*qw~-e~6ClL^wi~c}5*>wpsDHZpCLmzN3qbrvXQm1l zuku5U&L~x8>_SY?8yB%X`ndS2K=;RQw|nQ|valzh8eA);aCO|~_OqM+S|)%bT$Qt> zSMfC}xUa4OS0$Wvx*|-%^MF73d^ZJ8&+;dISfUWENZBt-Tm*58X?Z7|0v%E$ z@Qv}4di-8{E1FPu))z=SW^c#aBm>n&#FO6m8v21~bDjM3#Jd>*mXGOKe6vax&6%>Zv1Zca{q?eN zAn4NZ)Z}YEtmU$P0}QhAVju55wU`~UH!eC0qBzD^%dcdKOrPL~{`~{_GtmO=DzUr~ zlN;9344(}|&p*>i%dwl#~G_aS!)7)F+OQnzAKLk&U@;VT6oxrHL;x$t4zOn9^HtO6k4h7^w4BMC^K2z zk_ZlJ6NRY=)b=3zl-p{9icfA5%9z5JqYVz9w3HXux~s4=5mFh1tkd~*ej)HCKw5gV z$PaS4)!Z_HIeF}z4TyEVQqC{d`sHHf<>av^-pX2T@6DCY!5qp+Y~UXq0lkSqqFa z)vlO`f)6SCeWIm*2PbIFt}AJI6;4s7vx827Q2FsZW6EdjjSQ-V8R0H_?PtDjb$p7e z@QUXZfw#Ck$Xrd zRu43dZ?)eYy1|qrs(klXVuscP?e~T*q(%|lM*T>g_^4&CW=VCN4owH&C13CP#79CG z!?IFjE<3VDaCf={NA~A{+X6yoHOO+QaH^eiFBpK>dWD!8Ssei=vBF<5pXw2JMeX$p z)l%>Y*z6fq0PYZI^@e__y@kJVuAGrwDl1=-CkG8l@NEu;1LKZucZsKcAYm^cU`jA; z=gwj3E@*keTJZ6|A?5|Y!PVwi=xDEDJ%%B$n^{>eH{|nR)9fOYxCHeGZ zJ_RDeC;hJwDWAMs4*^GJ>HsK8=RdZy2nX*3UH&oRB225QwekxUegMv{(f7Cqy$bLjrF^z|AmId>=-4oL`v%WV; z?}ewo6di##31VTMLsero_Vb%$&B*(+lPNN`v=@RwM zV-TyPq~MK|3`tccKmrGP8j+VlJFh}ggJnQ<^8%D%k=}?gptx>hkz_x-sll)94}2g6 zWd;vz8~nKO+k9lckX0t_XZgY_@EE!kK)0wxTy9g!hwj3e0c6w1xu?AIkA;E_J`p!&j;6$=r$gu+-OQB;zhA~4y#HJBJMUMrgsEs+-UL}-*6f@0HXE0}o z3&+1;=08B;cmeGU@}T3QlRK1tENNqTU^Dv9X-4@95x_?$AG`Qh>~^Id#=w7*KPmX8 ziXrN2s5hf6$Kv^It-M-xuJR8C_#w)>3B+2Ilu@v=$bcA(m6vE5-U))q1H}jOwQ?AI zPwgh0r6#V(RysF-*=AvGhJ+WL>in>aD>=qVuyG-8nIkt<^T_=a5i>>Ng#pvaL7s== zew}cBs8cN;3ijhImh1Fc3WEfNYluSfgq$28x)gxfnQwh}(3Nk&Q}$jTq6K|C_Q0|& z(wt#`7*u`Flv!b7Bqcb2HYEyEzRqt%c%Hh(o++O)yZHQ7&Y*+4N3nfo&fY9v6aVPt zQ6Sz{Pn>B4&z&Ex<+;S!ik0uW87xZ5Pb@31%XVII+;T1*ronmlxYehBB!Sg0;ia@^;M<)ZUG}}g7py)6ZlZfH z#ZTgoV%d;xPRu=G^4V2O#vuQLYWv>uHQVhbYj_kECRz_{nAa~?KWOHGAOzmq5=xt> zFxW9?bUN5q3_o8Kec-hIyBPux=gfHtr%D~cILC32l>wn{y1%iJ*WvW1tqq;qq=_xN z2PG<}H^59FHi=a4jf@GWzbIWCo!885tBg$A8%7%axN4g zQe_o>!HsfiRS}uvs0~vvv+*j4Fd_k<;feeqE`WoNH;9?c8a}Z$;EYq4^pDr%1a@wC zZ`I&%`Z(}9h|41nGVe&JxDHB7XS}erAxdl`d7c>igjk3Ylt4RlCewkHU$pb?v|AwTw4x6r$;sxqW}Nt(W`I#ztN-fg&?Voo6-?y(6?VKqes_r`~Qs| zedp2tJ9<>ae?ozMw|@S<>2;x1nY6Qrj8>V;Q5QZSRR7dPnW$4xGKJly*i~yXA1fc> za#J(NB*K7W9ujEF`3Ol1FOn^{?B-|TJQeYBw_Wb8;bJEji`r16-YhX{`p!{!2#U@6 z)`y~_G>tBFlFltctc0uY_>G{fgTZQE_Y6W+$t%B&ML*%x)j#sfF91Pu0^L(g5R`kP z8O3B`-^-F7h~seceEZy{duwZ{%bwaGlrA*io_cbkFzEE75qk7;K9Rv($|{>mA&T`* zHLI<6>KM82ojOr|l6WWS8M|qGH%fY}HszSACl1!Oj)%@0`uc+GC#4;i$KFc;9g+_< zcAx)sfd7otY%~%_l66ddX8(La=x1qtN`Q^D5V}S=LuWr$P6_S&pk3-;Lr22iWK(}| zK7AGzNlchjzNd!DrSwqTyk!SJn@@@C<^Ie22m5`)Vf(>lud?9Jv}fN>FpM7qC96a1 z_X<}MtKe>vO9`9TTu*`!2n%sHDq@txkx-1vi~^B}IOaaS^&=P;2+B4&8(+Zr{}B7< z52StUp96`7W}Y|pm&-oNO54jN4se_EOM#B^bbZ{5fT9G26HNrSq?`!ohBsVkOY2TJR2#<%_;Zxn8=d0R5q3Ud{7;ID#&C7^vylDU= zkTVrhjR^u9Hdf0abrW9@KB}kcQ=z_{iZA0|*p%d<#z*lP1f+Aa(;x>le)P+?GgS;p zFrOi%Q-=&ko)`09P);UXhrW(V4k@e1AlyoTZapJ@Dmony;c1c_qxf)v=#O(A&4KgE*O*W}uZ&VObicK!IHPkVlA>hd ztPzZ!ak3;hSOV<+!U<7~)c3lrJo|(>FUqG=&h7rXv^uskBQpLX)2*!dKczI$uF;=B zY4m(5akHY%*;P?z+L$(MHR_kWTwQ^n6frvFgh=sF8|nJLM4j`h+R*vdE_+1^48@&p zChwi|#(iP(>JLQE z(F@tzKXJa-GJtZ}2rB%u`ED@#OUbMUdxlxvf_BF+;ml{cvG(&aon~tR2lCxZuTYqk z&ty9@p;O3oKKsiNA@>?$7?kzh@L2=%*;?LbozLlq&ZjZB_R$SY>$44=122O4HTr?# zJn8)68f@m5a{p{TMIqqhkD1R)O6L=LE>W-pi3DnwlsTr!p=@^2+8jTH83zu;fB*fJn0SA0DL5C zAo7!sIJo>JeGy7Mv*uqPkS2R4<88+IO*WQ2)RLS#nByAs`MjEF3votQe4mFU2RI3J z7qv%~p50Pt9*A}~L+T!=81_Z^w^LMIkAcq52+io;da1F6p2fu68=|IRYT0Ss*ub+Kkx}Pv74-?;J2zq^jG7jzT&=ev?yA7ylbee zWIfxjY?A1ZRN$_|%*Sl?>D6KWUSmE14qPf@h z`zI^=U3?Sd5S5(!4+(-V@$Qzdp`8J_k0j6Dmj5dX$>UGlC(a<+?J0 zzFgzihu&d_bgqqXqM1R)o%CtRmirrbQE=gCx!NwDEH`@K`x|%aoy7A==I(FYEwVK$ z|2lu&9YlB_5InLnq8nZs81;+94m?a4K4#GuQqJ9GV*}qi`7G%SF5lNY;WdzFtZy^~ zVXs(-436eH8duXOrj;G~!ow=C1m3}ZA^JDNXRL2Dgo1W{XWA*NLtc9C$ej6f>~5J7 zA(S0uU6QBX!^Lu{7vAIE@(3b-k~Py-2bB}prz{aI@l%n?%Q#iRe7|0Lq6rSl%X=B0 z|6YmQ=92f)S3|*0leSm27pg{?bngT}p1U*p)mS0jy`PY&bN6DE33e0~j`7{o>U|VZ z+>qWmE4ye(oFpIP&frFqw*6i^l z{P{xU)k*&hMaidJJ zXL-JpUu*eYayLK+{+(NQ%hx~XUxf?dZzTKauch7O+#b2?mIezGAL1vJ7~2D>?`Txu z7(%x2+Ng7XqoOL_vwx(JScr+bQ{+EF$cD%$?VRakcRGSA;dPTS>;>Pjt0~mT?nKQ` zu(fRW&&j^XaSm~1yAjtUUhIvyT8g9_ulk#%$WM#-SzNes%3Ln>IkhE(<0f6oeV-|= zUw}E`&?17lem^zzuAVFZxy( zI@_z@ks+$xO7Oi;w_fXoZb_KvV*kYe=6*v_6Q4+ba!P-SU@_%&t=5;6*MspMT2;nb zSS(4Wcy2(7@FPS@bMnA0^$10kYd+i^|9jb%vJX3*G==vgRXKkp}?nb>zwD(k7L55cUe6R=O;RX@S!nR$jzbQ=1CKBKHUdD{0o z=!5DPq`8@8?{!{Qihh;qML1{Ze?W)CA4lph`$kEMa9jiYL2%yqNMRW0b5Ixtj>dZO z49*+Y@~45RDt)qZ-~YpX#(#NO4g8ursf9j8?dSR zBVm%ctnCTij*CBWcPT%HD!|(X5j!!?+I;rJSc_+MJjgQ^?RbhUGP$))>Fvsbmf5&2H5#~inAm1r!7<*9Ky_rF`igRpA+; z(jQ2kE{d78rg4LpR`{Sj#wN0!q>X&wH?m(W*^b;XX{4gFRXWix%C?WVbl)fF>c_Y7 zBEI|U(pug@>ujcGF~L0C$$j~TDz64G^M8;?-2oSzYAlnB>e1m=rd9?i_#TI6Cj~-d zV*HaTxstKvpW=mhUW(l>xe*3U{UiPq;uMR$;ML#4hw|QRC{!h}-K(tl6Vag}!mu{f zW?O4P^=Gf1o;?`kYu#$a_RFk?`i9M4)pZyG5#3hizD@a>rbzPvQofzGxG9_&W`g_o z{Wo~kQ{mfF1qW`J$K>((1og-Xd!k5EjwaN2$jPpu>S)W5>xLl(JQiuT#A6_NQByRB z*o6b!;>HH36YwW&{#)(~un4*LacErx4r-Aq?=mG8S-uPD8X>!JZa-qrTAnipLIPyp zM*4K9u*grp3SFX~Rfv`w4#`i==Yo;S|E;0^@+uTro6TY{^p5fZD=lvVY?U^ti>JD@ ze6TLARdH;D?fe~>q1RUja-z|k*t|Cf#>csh=rTz0+;6;g5CfI3qRijojWAWlL_VbJ zCBWyu{YvDy+XSV-XYY7gDbe;aPr9CrzC1Y)$bppv2V~-e`n2}AMH2^PI|09(vDEy< zT~0HyPn}poMT+!6z%T1OT}B_|sbGJgXqAJzr0}e1OgKMS#mkgECPB6oOS7ir=P`%~ex2(?F zcuSDq-1`+)=lxvw#BYm^e=`4qy{jjFdzi?SJ@IuRNx6bkI5ynX1c`aZT}fCw(1<}< z9be@m2!Nk2hwy!sR(>+Ib6z4e5KO=x9L*l?+>`O5r^N_mmlwrmSC|5Q&jTC`r-&4+&AzZY8Gg`-uTS<)t)~BEY4}{U>-=Fte7{CXLOR_>2#a;m zuBk)m_|$58gk!LTR-eilF@8J0hat9^b_(*O+_dH}+1aj=dO-6)NFXV#3)dd>B~_C? zdTm6=Ub0Ry;=DJ@=zHFz_tak12(;%s1c}eK4hdb|#MBaJqmlW4yKpYY)Kp!CiDN8g z;p8s2I#y^GYjrNJ_Hs+s6A|zXV8s<)0_%9o6%xFa#b*+HPSAuQ>nsVP2$pz%QrczK zBl)+rJ9wmb9L5LajT!#}{xRF=o4^%MW!XI{Mu#=PYUZuDFiCCBh1K&VhTIBFI*@g3 z#<}g!7`m_EE3wuG-bu{cYx@pQ{U_AN-4wSogk8+41Axhh}%QI;Q|pd64jPA6xk! z2%>Pz3bjEEE~H(kX|5laoIhY!fnOk?f9*jZ^p<@K4^ucr=lY4*pXAfRc^|?OCkm-i z71Dnn{wMK<{nm%S_f0X;D74c#-Q_Mmh{8@x>w@?{otFY+FUKF^O*?JtX!CotnF{Zg zL>v*2#tn-k;~GKj4Yg!c^~BHWsBq>rJF`CbQMI)k50L)Cb^A1iJ^y9+U1DFm0J?;&G`pChw| zkGPRlW_8}m8!=u8@(_czw#qZSA&Nun!;UDY>E6m$RBAbTxw2cO3qnW>K8)`07ojV& z*F$aAN*HUBpe(Ke;h%RCFCAptpS@8II}k`ji@GW}{#<=#F*VUaazS*YB*DEa-;RV1WyA=(6%rBoOsvF-pI;5>xe2@;@)_`>&KTK|Kxb$ ztlSnYu8=#K&hamJwG7e>Uv@u<x>myVp#GpbDdNzjzNv*X=q7lWuz&(+p?HTFs;A?j&ZIkm|!}A>mB=S=q}w z{g(%Y;y9CTEPMIy=4D<`X5%0!Q5ZR{yDn6i750Y+$*Jg?y>9%IjB!v`{5I^*9>XP& znvM=?V)cjIl-88~EH8$ay_n!P@hf_+!NIAUR(goHkXWsIP|$+kqG{w?rjbXV@&_t1 zB6rWZ27fPy4XgtXxgSBw1i8KgGnivfm2tGJxqe)d|-C~I~L z<8+UB4jz!WG32zb*EP^qm{%2!we&6B)dnGPsD)7Jc%ZL=uSA)HDuvI$D_LV0qPY*C zM?}Pl6=#of79vqHX$EstotjJkovDeWeQYwbWWA1E?da1z>Geuktn)}OkNEOpu3fyDXiDBMJT^fc7LL3A(t39YCzPo zJT6<8LdQ$a8@Lk7hni5V@40~fLtm4*t+jFXh2X`jUBVbx%g;48hB=7PQ{EV|)xw*klV7LvJGjlhORf^RCF>A=LVniCx#ZP4 zAyiAYbATBQ8RhYIHu71#8c;oXnNH*V*wkM1qRi)5hqO9uV?Nm=7`Mft<6} zL6P3tn6>#@WjVl#wQYq9Ba9~_KrO@u&rlvP-reT35z4FIS|O2=QqH;f@^mZzn{-Yi zH5#c;eR&M~;i%@i!GZsVW|Fo5Y~4@WSDU&Y0@>qh-P|rA;%#fh1usV~5+~jrg}G=8_fC%AZxwp^ zp15o4wRZ{p9A(id$Bps^BI>^TCsE$`TLT7vZNw5tk)yE9Ucz?pQF!4ENmLE1WFi^$ zNKNa>K7frW=GYL;O8{hIaufW8-RzyuO=gaCxM8Ev2y6II*`Ff4uXV&F5U7M^( zYvmM(sYgZ%5g*JNK#B)}-)fdAqP0vH*|9bzorSg0o@wJi*mpSnPs4?A>YPO3su}Kg z2?&%Tc897}1fph1xlB~yZ|3c@H{Av;ZBO240~v-2G8ox?A>lcN$o<`pt( zmOr@$`bU17hdv4L_Cp-4%~MYS`>d`Lr4FH9!)02>=RShr-VNAe&K1?zO7ReE==rio zK2oL+<5kQ`*qQM?y&czP=B?X%lUK>y1F8+nEEPZ0`=`P~Z2<^v_5l;Sa{QB?Dx*!a zict(YVs*R?L|GoPA|#xD5f{B5>EI@fy}@78?!F})lCPvv`u&NN)eC7K_sT*&_dN?pUaccZ-bNG1il|kPO}CWt%?a{GCL0CE5Pu$k!%fPPP)Y2Lv5z{T!S5+kmyw z=UWu$XW&>pvS-(bPP8Ylo=~AvSorNMLCJyrFqylq8j|)8+NI64&y5K6-6(hulB$CG7t+YHZ+?KQ zyV9GK{hYx9PEWJh!)WFn2bj_f{8Bea3u0h#xRtzCU{KVlkSMCbPJ*poYk1*ggqWmz ztiduh{V=O>Z+a}}FOWSqne$itDfSzXUQtcQ(fpP{HyKM58*wluzg{8sH-d1IGnD_5 zI&v$P`%Tfk@j=y@SwJ&=K~lsg{(JFA_=Xh9CI~xa&zPY(Bv#30$ac>-*!sKOzuoYO zW64j1KzJQsDPK2GcjnfhUIa^9XV96DcQdcie~wDpGq=w0ICdatFtd6-*WNV#h`%oj z$xP3`t~b*oIsm_uZFX#HgC|z}0X+}o1tr2z@w& zGxu235R)&&2wo2HL~9p048B385lI+WFC7+%OuVB%oyu;0NbWOJMchQr6cFy>PT|gF zIbDl>A8A+SNU(@m*B9^&u|^)#<_t!6VC+HS&UM&)Ny<^O`A+x|`zIuA zA^5Q!S^{eeEZoIU3KKCYzo9Nfrcp`k%kjPnBk$CH-XvyyLgCfSF-(lv^geJ=^!mr8qM+teHxe7sr2C$j4;7ieb> zaymYS3&BjtG6M%UAE|X8_$xCmvBZTYe+F?Ck{T*{%16lZFIJni<$l^Q${Oyx{)0>7gXLCS}-SDhKoARv#xN`FAAPME=ZuZj;1Uh)FwoJDi_Q}Cmc z8!~SuoU3XPz9PdAajVp^JmFwCRA}3tD#Um8@08LafW~yFSr_RV%DHp@c(7lOXoMer&mXM>s{#%19`}V+MWMhB8OhHZBcR|m0>YytHgvK8FJgZaUVGS&nlX#~p z%~6|X@j{>x`@SJg`7R#Fh>q}`+ngaEfp|>gl3nJsMH746k%MK|*(+K(Ht0R>#gwAR zPE%y3JbGu4c*TjH=`vJzJP|)LcQpKvU`gM3!Tc8K+$ZZNQub91!g>vljNyMX{}c0* z)^{GVM#XnoH_OA2-1l(5lb5yNTWv7~@q_q7zHz%xA7!ZhBj4xNJF>VgO6cSNm3{)> zPhE$br8f6XBDi|uMo>y`{|O!Zf6-5TO{y=~PaNX9!g63kYTM<^-USNm3jbl@}Ax;J5u`61%NL(d$I{AI^$9Ic?2sY(j)62L1>DvZ@wrrW(Cy2reRWA!Wwt z6Eu`WtHzO~)_rsb0-2uJ=!CC#WxJWjzS9i%iEftNSVF{2~_yqg5{4_7`qH2~Gi>{srX?eIL+U3cW0cgA(U=DaxU9KwpXH1x!jQSd~x< z$`$eJe^DGiVcFvGT&6tUF13XEEIl8X4DUvPydQ8(Y>qTPCijaqC4*vm}jpNOR5jKOd+#+0Cj8MG@&;>-YrV{k(#Io;aqhzmtD>0i0is^Lk{vB zID;x~9_mBO`OF#it|N1GTGEC`p?pO6bCNWuVS() zyi2*pf4H=a&cAF<#rkN^Y}k)6IkboB7*<`*uR+Kaj<8I~Q*sI^-MVpU3sPSQ>_sgQ zxUcO7M$S~iu@eD=L=G}l$+>%diw&#uJzf{hDq4Bj=KNfMpgMLLyx?p!cfCI^*ULLO z(QKsO{i4^8Pyvgp#NDj*6P!R0>86tsgukPj3W(zHahr;jybzlTVwa?k)g&4$<~ROJ z!fje+Jr^jUcwSu8eHZI}!Z}U1#X9;VK3ndULyT}7QWeLfma*=kknYpG#SlKtr>v*xLzvf8XKsy9?vS zhd4JPO`iKG;!!Ko{7&YL$Z2USoH-`ag>lM5;l3B=ucB{eJ% zv&V1QNjJ&3skvGzF)7d7*SkcNp!vH_h$RNr(jSwBNv>QM zL7;$?REX|n514Bo?EWN(L&IvY1bI(!|CRGoRbyE{6x+Wk<%;}Qu+NWDbc>YnJKZ$? zu{wkrdY_Xz3>^}wfe6nx2{_9~p3j7jq|od4Z&$!=O!`s zKyJ$dKTI0K_J(TT%z91~G|kv}@;APoY}tlk37(SfwD-t3BVH!hi=r%7JoK*PKqT<+ z=|y_p$Ht=6;yj8CzytfApOBHD4Bgp7=WLeY^^YvbOM~$~=oyhG-grJ9`255tEt=ow z1sY}@nYF{B@p_Q`LLan#_d5kq1DCEVsb0Jy+!0%J{TJga_-ESOUzsm_k{XRz7`_IEMKJJ`ty_uvf~?5QI&ghRlH0d`d)2Tt@;DU%Zy5!S_}A{+yM zoKA9AlZNMUXFTe~9R$r3{~~d3Azt9{x3NkXzDo?nN#~#s$37wCFT&>G)?+7#WoQz>Zx7*0O_oda;(Ngs z*_=~___{V?KeE7eIp@5r!Juz5nQsxna-I9K+u#57uPGPxI+Mu>c$ip76c^$?NI*@a zoRDh~26R(Ihyuh&&dLozW*Tew1&wlgp4-IBd5uk6UK-)@vc?FPSI*!v-8h5GYlSE+ zZk)sASqr#KH7+1}!5H^wqWc7^`KMSBOYeIsG25NmzzS&cn~gO#J5#GaIZr~@-|C8m?Ix}V|CG(1U=rd+?e(1O#0Q2I6v;qjM$u| zSpUfTxCPqk$)%56?*yTu%p#I(L|^>I)+LK7WS{>Hl4_YkhOky*H&s# zKeF^GCeSj@Z4a)bJtCgfslYce7MsnT$cY*dG;h6E8jRTsMsp6Ri*;Q>rm!;Z?X$9) zbK4SS+m>0+&Xj69ek+6M5|0~+uiCzD(~qf+F|rEQaYZ15jq>Bpc~AN!Lr(v6Spw@; z(azq=P`oqw*2k|%^}b!y*mpw&1u%iPd1=tz5AxILl>(K@?XXRxl^Jj0Z z&fX6(lrpntbzI9!RJi+giGnBs#zdIEJEVU)6&Lu`TKOyJQ&9Dapz6~HswRCph|yY7 zb%R!Y$G%pXlm`cXl7SV{&Blzp?f8~QIm@*!AO`s|X@ zCkLgOAMbr`+;#VgF!{RXP=e)X@Gl!La-I;|e=)*Z6Xq{;LLW!|hB1ezJIOT~i4eYmjLsglY>{V4b zf5lqn9G2Mti`<;RcHni8J0VK6sm@_!ayuRSGZfHBJ8F__G7mTO9jog%*7A*UnPqz; zwG~)!Gi!XV`^@3&GuhK_PygBbS9yxYoAhwejY&E}&`)ghT{>Uuo`3??xw3{mXhn-( z4nqo;BGHXsl1@7_>VvVV(wFloJiVSzpS2$rC98?Jq8?)96*< zTsH9OM?ekq{o*O+7SuojJ?|`G9$eIklqyePYhDR*)v0#eQOEjFaD$QfazK1UccTKaHB6x zFOVJ6r%vCal>0O~S|LQ|vFjmy-X`?uvj{S#`+Qi`Sb=iy zmu+FKdo0>*2+LZh{Z{G_jw6pg{u9o>r&1Sq&^#bd6jNIGHoyNkPAKx3!MvePvx=V* z%zvCrO*q!~Ysxd(<~;j7%5x7w2v<(iCT>CrGAOtHCJR&O1?7Ah#mCAiN8U3~F5q|Z zrz%4(<#vDSmzy80oYg$`kKjPy9AoA;=}bfX+AK4m@`d*RhabBm3mm2YYv?cP05ywI zfC5eTY1FnrQGhADgOIK9JG@tgtbC13#zp)o(=VG~x?>JmGOAck%i^&Ap)A8yToY4a z*c2?r`ajS9-az!`)9Fk@=5XI$&RU+MSMzfk%X#{u?>Rrv*+(#R3?Hj=X}!ur5^SYo z=qsHBeKOxpI>(_H;HmiHSU@`|hv&U+6_Yyt#Kx^S+Trl8(% zKlnPvCPs#omF_VvA3v>*5Ths`m!jzBsHQl-dQKO4y6T7p+P}IQ#znR?$^Vmdeki;I z2HX?E!auQeJLQ4IKtzyP3-lH3UgMe3GG7{eeq`C_?;#W^{d|Fbj`-~F9%jfeF%S#; z&&tW5r&$LJ!{;IQmOhwo@bfd^r>@T+jPe;txHik8darc1GpYF9ajAH4#8d`ISD)lm13Jf2%`m;q@Fyq|Qip#1tN z{`+C_UKIU?zw*(woyt7%an$=a-MHN2*w=6L-lHT1fjBss+aYp$JGVj9?w2`)y1)O! z!TwbrKVQx$U7nmTvuBLUj3sWM92aZ+%|IW8*QuMH`f3vuG_JYAsGK#cM(_)w}DW46o;YD(@29Z`}B}R?poNC zBXv@}?vkBSmRI!GIrI9#Q^Yxn5zv4P}NS%QeKW&0)xG%UuC@1@} zM4aRv)^~vx6su;vFNstd5W{;JUGcPJ+++boq^T!#HRqUAupzYzw$=IA)=WRZ zwupb6(S2B`tI=s;CAx-DUwIaV3L{4|ct*LgCnvqH6cB8cKg`QzTR}LX)gb|cd;Ogx zYwyxQdLl(N>nl(;rvF71%)Za;>sK0@rgmDWI?gYa_vLAQ&jxlF1NJKAb|f;-CRc)g z4psXJ!O8M+N>)U%Zu(PVZ}NX=dlUGms`LLpfglmli9j$`)TmLxHB?X{s2MT|Gcdta z7E=_ZMv=O-s56Kn5IPyi^*WMPsdTZWRV!8dEnS3&EMYMLwFZ5r)RsQ)^-DfNMna%D1=K>Hn536P~@2Cs-`k61;yN?Bi_2{xr^xA zBC?z5^0`@)?`qAF*QetR^fC9{{nceNvGfktzU7;gP`&QK&=#rcUawihqg794zjrTU zz~&Fg#L+^Nn({e|N3w1Z|p!l8LDFk zCq)aD_*3+9?BL{RA6`s~%p-Tookm_IN$*Zk31(k_ zil9%vceQICSi8l!;xZr#W`HkoUfin4Z!b8L-x1-~H3rydo_&>EvwJ;EIv0=3U8Ubu*sI{^l#oPO2vG%gLl%Ia&_R`zojPXdO+dfUkO6b@RkB z&bt?wrfN!_;`|+d7PI&EgkTEGo#(mN)!?MepN)RN1;2M9fv$Ztz;}6i-qU)4ZyHd; ze$Fi43$q{`w9UDaP(>jbxbCAxi&EweK&G`ce~;mKU=dc`n${g%bcS!kM(bI@yy-X z#a_iDfKe#!SO4o}5`^04IdaKT3VLqkh~+%w-Ul`L82TC0qCJk}*%IxM1|)>q3lDqq z`EAg_NOGNZr|4Y0t;9Umqax>V9_gwCmrtMpmY<80b#XEmC+XrOF3NOKhL}Ty|1`Vm zO8s7GSKX!GyX>lZ{nq>mA-fdYYEBM({ONHj1vPFHtK>2rCgFMn5S2i zb9p6JK+uF*$4aHDE$}aRH?{uD{fhfkfS*ldpujE|YIrS#ya3mL+X|f>kD!09D)1lv z423anplKcEyek!W?B9pMa$K%>PV-4Fh?MTD>WxpuU+G}u$UjoBC^}oq3H@}NF?;t7 zB`JkYq*;S9OIniL=T5e}pXu=_ts|)6sUrT+b$9o)*tc}dCkw11HbRvJ2Qzw;|(cVJ=+J8v- zeU$>MMXHd%iXsD~KXW5BJpWzs;YuFi#p?wH8O{Ki%A{tPpc02<>_Dw-)JbwtL})bX!9Y|ki6uI0H$ zcaK!)*ywnMp+3^;kJP*|c>+(_#dpr*ydYZt-Lzq%IHZaf@yHu=T&%j}fL%2%mR51W zWZy>uk0VS4;ZuV?4F=i7euw}d~b;@5aY6VV65Hci_-jg*RDg>0W^^!&umnd$R9 zjHT<0qoliNm}ZJ$SIG=={)FsdWiYOE-GtWNXl^*o~jC*MaD($)ijUJl7{#G&~~mJvoJm z$T(4&$07idRXld394CDbV&&I-?7a3X>CPLO3zyBgJe|)Aq6D=i!p`MZ?Ze%-yg*uc zsxnduXcp2$$P0IweFPi(-V-GeOjK`XMcFkUf*_VAwM~GBuzX_oJGGEsM)oWZrT8x? zkH$=_hHO8ul<_s)$3>{2w}0dq{AYg52)f1~?eJU2zyfFTM}*0mWmhl5(hmD5@lW>W;|vTI_O8VXvGcDj`!*N4d=?`(pDeGxbN#lsLh;vWR(ckyT`GHn8*{8* z>sxs-?!1%~VaF9EH}En@jiw}iO>W5x37#;Da*HS@mGaMcfk#&hbOC2zbg45Qr+U1) zT7+`v@lu_2$8lGXrtz(G1A7Q8N%uOkJZ{PzaJxd1eyg2kC1vLZM85H8qMR48n9Fm!7*n_%&uff#ch_zeTw$KN>OZcb%tgyVb26?`2+@bwSvc!i{G zcitvUiQgobnqxNdW2)`-&VeqxIH!>2ir4rc=U42USC0|6lxY}w4m2d{?oh>ggE`3n zx?Y&mxA0@?=0@1lx3GZPLb3J6(>3x(6IBpymP}Ii?FUtF#m@Op82LrTDz}>2idAkk z*U)Kh+-hobs&VZn40D)r0#wrtHvhJjZ+O;lXw`kCK(+IWgQiXPN|ULHMH73sE-5vyIj=_=Qa@lVnaz{Ts18jNAyC_FMiy@i*yc6kbM=TC zLfXJ16WQ;NAZR1GY^5gIE25|6l+CDO?G~wAIK_L2khu5Tth34#RHKtQi{jxj_$qik z&0HMJLI;4b>`c#IqDO9@II%m=qW{dJA#hDm1Y>V!MzEUwm{Xd9W<|71{fG|?8EJe+ zJ^2d$SBG&>?lDNfXsKMXvAP*z_w4h5iNx?%e`2Jl%SHEY$q}W3BHATKMvy8Z1)^wb zizrZMIC{oFv)MSzWOH&0G@wgwbyT{j^?A2F6hb=9gBCfP*PC-S_3~&JDeCHtzg4 zlRxd!UdZ)x3&{uDO?|hr%X>4|CVEQ4gLeT9K;ae8I?upoR+a>;y0bt}2IFjpdr4lb zZ{2w@c*3_>^lV`H?0+0gjq*n}+T%Dps!KcV9QQf!Kt^AeGf1)` z4%RxCa10_g8kiXST;pd2zJ=Rpzwz_4U3*<+gD-5nkePaj$MAfOBOi?%t?mV^woDI^ z?}y6<*%JyFT6}wSm*0j(XR>Z(vO>IKwmwYHR+8Cr^MRALk{P@7EMNRV>Sop^Xx1(- z_r+x?C-PVJeGA_9W-rO?VeFkBd$!b?keAUJUqTK*_h+MFWi(!Vozqa)a!xFWUP&OZQhGc_j6Jo86<5a$0QV$HGfI)B#U z9H(#mksmTho`e0Sn07M6o z_o{)kKn1zfb*_Z%o}t)mCg4Tzyp-vNEvU7xdmJdCCgxOJ%s|juD;a|G=m%We z<{ATKy&*)D2%*R|u!p{;PYi}`Pxryu4f6KGSg14i7@i@cuaMPe?Uo$XuzJPP&F(@{ zRC@je3ONg@bqfmnMqhjxoioNs*4#!TW-#%ZttFBSgslhFFGMt^$Jezenv1y(+vbhy z3u~LgppwXBMvoR)#zK7SR^bhLiK*g8&uP%++8Z=ur7{(blz8?;VXGd|Y|egENXeeQ zAwBeq_IAkFB3+@w9dcQzu5hXyGNn9Zy9!`EDMhYziY{hI!gZr5KT{8HGat+@=W-5T zR3aX%szk2Sg9n_$-yf^;!6L3MQ}Mb|uBNE8oOVZ3y0Q|xt=_V}0}cu}U}kE?#Z=1T zz(^Mux*6=LxUeubU7HovzRcQUJo=`QH)L!v>LJ5|rGb>J)G`|D2C~& z+d+@BzeK#s+-E`af-sk*AFtF0Ua4U`b-wsv7j7b}|4PgImNHOlNrbZ9cW6g-Gw)n( zYeH`>64lVL=so{sSa~C;;u+^w@uM4Lpb)Rq>?L}Aw%8Q_X7$LvA;u{|^tflmzPlE! z#fr(|5+z~rHT?k2BVa$Nj)09yL0AFn6X%5^Xcr+o*E~V}U+Vm9pm|izjgie4DaWtg zIvWn-jRf@3a<3+y^7RPS)a2F#R8-?6zAuvf?C#8Gm0dmy>a$utS_XG84-%C5&488%4~CTH=B z!zcZQ=cuk%dE>tB`HsK2LADN%vkD65(rxzeDK{W*L#-;l%Tpd+&!cn%w0Sg504wOf zk4bLZ!4xtD9SaTYarrfRzgqhkiEEmMP$AxVVQYynpL47IxdNkvZF8%bq;5bmFC^2# zAJC^-MN4zrFjcJMSxyz_Qbo@9m`EAzyKm98%&Xn2<-6LM27~I1{+N%0ZsXQ#sp22$ zt&3klo9^+kAt{xq;X|`|M4&Ig`NU`biq8E1<2-a7#0__M8H5QwN9-QcZLhn|`FP=Z zolJLGcI#Uq1(f{mRVR86Rs_}tGhfzGX0Cpu<1;(mJ!z)fbT`R!`D@#2M=AYZw%5yT z4^cDa;PbCexWCX=mKuX zpbV_xTv#~d2G)?jd<@FKn!ET#8CX+K!9}hz zaG`!^$lx0yAnbO2EVpo>npxNk-fmQZta;iFzuPQDXcWSQ2esLZgX38RQug zT`k&X!DgKkIV1|5YEt*uQ91c-6#FLB4X&l_Or9d%$EzI6NJ>fviHm!7meS)wwgUCNzHIr91BVt`0n4nz-K)Meu& zTAp0%YtATbuU}SxtzU} zmcRRPTao>I$a+yB_j9$lBf1~avfh@VO4vS$fR$}VA8`lwFmNEq_+Bpk7~wB?8#!|x zK~mVk)kC-Xr6NKezhnOfS7Tcb0%?4=(ic~-N>q(KR|hHKUu*u#{FZ0`L*=cIL%Wk@g6=Q|cN_NeZnV^NW;7=m` zdD`}0YO>564Sk(;g!N69(-oaF?&4}?d*nsG$3b4i!jEB$tBo>wbzY@bR@bz%@0mhh z{Bf>3znk9An6+7x);Ldo3qleLw}!n=AKKO&LZ*3La6@y^s^5Cfzu=#0DzXHtBm*|| z$AujEG*#y1f|7wd7*Akts}y|07~k@MHT4Npp(_FywF(vHkwU_1ku={1g$rW&!bgPCXcUh&jSQ2D>#5dB-;1jkQef|8*`yYl5+onA2ucs zL}p{cG}4i7duvQv#uOsxnL?OMYJkQ7Bd|#8>aP$YbHiC2br`a;4$$eB} ziyAG}z@e@E3~#Y!u;>8?0EhizmKCzvM5tVN0sGdK#MAhP^s# zZ^fS(fLw+Lu;C!4c!k2aPUBdaxV_NoX^$zekHHUA@&XfQ+;b%(M7no+c3$i5Lzip; z5Zjz%Rk1w@XwM;uK60)BP?3LgbO5SO@V_+e^rscfhxDb8Oc^fAg5nC~$}; zhlB(wN__XqUNhuIh`f{R!U{G_XrySHbF?{dqe2*PL5&yxG1`lPL~pLOzlSj5L&cNa z;In%jyvkK)Ya6TkB1L;&%`CYiNXzq8X{ZD8NKD0t(T6z? zWp2rSsKoRI(mtl|?eVhWSOE*d{MRl|$_dAtpN{Hfl%NPR4lc`~185J6o(5zDDHHOIql^B(! z8wv|)xwGPLqUN5F>JcLl9!RHGYfp#!Cjv0qlB3W<==ma3a5JmymOF-Wl-VLz{^=&< zmP&0H16(1AxXUO>?AkW@usp9nub?0yuvI0T=~jM%#A#4W#@R?TutE2NULgl24B$;0 zDWITNgS)H%+{q_bx`6N)!#2^XQpG7A38e1L%I8eHS5TV5B`arJb*u9eV*4<4tr`(_ z$r_P5@0_&SJl|rbS}b$=#SHfY%u7Gi2l5UwAMAa~`+%=aBrqiN%q;dJlyLfObl;|( zVLf_HOr-N;$kXI5Rt@>crW^sT>@jQD48W)0+pM80$d%15Y{HJn?Iy+7@RzT3^Bsik zBZlrUN=CPSLRcR)qVHkRF$#eMRa|g1fBF_xY>B?h#JnGhkyjYeM)ATXqPt$kyuyeQ z@pAb6!(>rw=6Gtd_vwm>)<_S4|0^n4*60InQ8@=)$)}m3e?Lt{EAujO24izd@(_2^ z4i-9z;?HCK^P)=|=bVxk?aS>!ZaXdTvErS3qS`&qYX&pi20Wtma!(&bxO<%SJl8X9 zO=JZJnmku)aB8Sxtxg|4mHD4(yR#V|rt6PeBxi)LBb z%Io4)S7BP+rl|lPj{FW_Jfymje=Y6RjZgBsjDITxxn=tbdgMnu{W%ZtnM6C1ucy(y z;UWJdUI<}d^9GfPD*xF{>UB`xfnHuD=3>-nrxouWIdSb-qX^Lrdf#4a;OTg9mAB}h;|P>I(wsOt*WCVK!Z^*>q`*nQ&$4oP5AMfoaNWsW zfM?d9%MK+lyq$1Y*8s%Sykbat6@wYD&;Nco&06SXZZ#F$MooeRT zNlq8ogHO`H{+hFOKJoy!Sm$eIUQX0}GA|V$`|c6em1eKu1v3M7WHX3`6E|dE?3~EZ zya8!)bBbA4ZZ0$do4o;?ni;_GXYb4oV3(`Cbj4weWAoRIBRSD@*~QmseC5GU^cd&! z_YS7v(wMrX={2+C9-NeYDHCY)tHuy6i@%cC%;o5(7?wHW$kS-#FV5q?GGH(GfV=V* zvNFAn2Auf@Cd2Cyu2+4X!=e({7%gRE*Vw(y*yc4nkWvgc`dPvSq+T2ti(Aw`zn8gmp%$oxP`_wGXI@7dhDBYut z@Q7ui3>(qRipGeur6A!^R~FX0fdo z?h97Mi%WP-4K3Wwp64u)QWf(leHquP;=4`l|w8T)BhvRVgJ) zMZy)tD$mL%`Z+UW0gL9fBZ+g=i!bX$}nt{K}lKJh!_=crt(Mg_N zK;*p==b?+t%0tY$39?1+P|!LIiG;6d?H>LX0D{Der;g~_5dX}L4pv__2bwup~@F9(-73s_cgJ+rbxn#{4* zsFTLpfl~^{T7i>@1;4o{F!DUoR4|yVReZ!{(7dGRLlq%Bn3n#(!-NqC$k0A%h>lz+Xuj|^7X-a1 z&!^cJEmxgbF79Qhrp{G7P@N~6Ivc4vq0 z=`KK3oHy^N@%C8&(}&R|0MkzBeYamE>1av*K09B`?e`Jpwq)1;Ffg`#SIe$E4V4&3uWTQT71jweAbO`}1f}_XjH7_uu25 zek3?C0eZDan_eU=BV9K0sCHI3oAr&mV#$yp4&3r-HZ*M?QEwtiz`*iVi>#2a^I2+q z8>SS9ih=X-n=_z#1+k*oG0WlD2kVF+BuS&M$;92W>){e!Cyw?&)MshB=!(G->o=VX z`o$rsA-1dMs2))Vz2j9R>&*8xjiy?xJC$%DWqd4TS_2qtfgDfDN5zc?5IxY!yrR>S!_HTuIFu`B!${W%&`5z%*u&+Rzoi8FM2@S0 zH+)F?fpfFrS`6}hn_h()4)c!$uO|A?0f8jekZKfk-R`#r=8|v5Cjco7_ye6N3&S>NCNlNwK_+1-!fIQcf_MmU9yM z&-{sKe!zM^9XEC1c9z+1uWx1+WMgnQmAKZjC!268wXK4s=g$|pQQPW9R003GsR=Nu z(g@=xP%+(GAsU5V%f#oWn7pCOP^Y~?EFMXzET4f4WQ36zJ6B(jcF1x~95gRaQMQ{G zIUeMHP%36g68KlD27|cpvRH%Ze4cBMsl(6qGVw9i41sI4+T(>jlr1RE~_($ta{38=7#<%bg z^$*>Fg#~*}?6;xUSEi?jIL1sc}rZNbc|KQ=1<80_h8GG`{Ouyy5?A&Y!ljLr`H?)qT=Sbq@4*DZQq-)q$|H>0U zb)V`=_;)uk*~VLC`gzb9R%})U`6nJ*ZIL4cpXHD0^O4BAnw=(G!cfm4vUAUKU~>hm z+@#|r3UKxjDmVF0I?4A{z|SOVPk~DETud?=OafW>k#jLJT7G${tx(RLpu%jo5zYo| z1f-<=z#Xi6KCn*9n3H@DWth3~Y-$ZpvtCFxS;HcFHt&Mx2ZAm2ta?*NuPbtfe4RVRlZ1wxa+bPycjY$dJ9vkZ2(bHU6q+$bm#~=Fm3R`CG^;DAcCcsQ;*nl?d6FgUu=j%MF(>XQM|%dI@8(LbpM;!*}$e zDT8~Q37?qRH$BeJb&I%=|sN1h2Ny8@r5u0+2iy$R&(yMW%BDML)c6XqflZN z(y0NJ{AIuyfoD1M9w+Rux9_r3K6Yqk%HtwkIBJCVI8Jg@ly9q2c1>4r zU&fW9Hm zx#~B}Ax>E=0r5z00F!P&ZKe`w1Nn5Uzlryo<*A=y;AuPy4gX^jk9&9p?0*Yx90vPO z$vAhcWhFi5j@tv?zR9sg7tQE??}g(v0~?I;)B{R4o7-Q_u5YBSoYUi{+zFs>c$Iu+ zYfXs&ljixL_~JkE-jC%ye&kQ+W9#p+U6qAZ0Yfvo^pr=3K777QhYA5~1p%b-pSOE+ z?8Y&j$&p_GCEC-x2TF9+d7nq8n=?8QpmU|Bb1pv7+RWBNh2wBO`fe9UxW1?$dg(`-d5LXoGi33QE)E?TfylE~KLPZS6@FpRM-YsZPrCv_Vf=+ zmB`@)lr3t>V7@U@*8R?>v&_-Xd7I}Ni#N~4*!hC#O+wC~;{a-I}3p4ROW($ld*RZw>JU1_sQBtw+k$1^W^8UYthI zdT@j;t>;3CKu0MR)T;vF)AJ;?Alk}qr~Za7$O9ZD_w=Tc;K&D6BKl^vQW%+!sZO;r zm-D_GN&u`|JBu^$pv3Elg93zt4hI|1L=|Af9OyWOe>^NV-Dm$ z(B+&EQotHaP}GH%W!GKotPnA2nOe-Tx{gwkooW%pce(!DtIuG2i*jx;uYYVH(l%gV z0@f{bL6jJr1HyM8vlYr92xlmr`R@-ySl~6V=H90X< z_tzBU<&`3PoW*_E9$%_hJ~vj|N8=nduOXDU1svCT6#2Z!abnCl2^Ewy!*Mt1L+wECwfM0#m>m}p^BMB(T{6w;J&wD<-KsC#YGp5>DBMs zxgAI6%Vh5XzMv#=DL@~gimg#6Wc3hhrs@=wLJmiTB;6TMM&;3mvhxWgJ;QnQGmQ}h zFm=-=lS{nwU+MEI&0m-diUMyp^9Ei(2ASKZd#8@vtGYzyR}c}hXg+YX;#cxKcA&SfX)=Z_OyUw`2b&}a3fr^G!9<0; z*AWoEnD3e}89$$2wzzOeFkvE-xXC5M3C{%H90ckD2OJ!}IpCb;v%gec_xR4kC6b>v zm>TbWxetr9RvqX=Q5_H7S2`YaN&k5ygWV}ox>9@LB^(2#A-Az1vaCQ_>FBC)aqfXpj{`#H&Zp~^@m1w zSXoHakAm4|d)T8$dhZ3V-OF3&!Yi|JgfZR?Zun<`uwu|2RYJjK27AA!f=8zdax!ZG z#*zsOzI7w%snhU)o|tRSK#G`wS>|kZYP!EPLv@b|X9zDz>L9$kPX2F@G(cw9+Uo4N zR&Pud>xSpN+2Fjw8x~U2>lSx5E$2yW?O>iTS7zdUP4a*6x{~di)B0m|HJF&xlIgD3 zm0$3N2EWpk4bHVRn60AQ@UAx%W-7By0uwr+dYrMQ&aWF@QO@wr?lQc64Q6-(D{px3 zJPN2Ac? zWpy%~nN-o^u5V=tdpokRPj=x%4_leBMb?2L%MJ*?IqWyFs;{NjAJsLL-N=t>88 zrmMT1mr!*J!O-wIqQ2JAa~stHtgiMQ_|t~T@Kr06JbwHT4nQcomqMGv;5l6&WD(@T^p zZIRQxg=cN`3Mvw>Tj!=L#J+e>HnbPWSctY|1Q?KRw$K z=u_+))|81$^(|aRuXX1N0KV|rC3CJiw`pVF2|MZ(9l@#mbtvZBp-qM{l-nm`KeMWdvc76Rb^skFqmjvP8A+l z8$_Ha+JGX45BlZ%(GWYd@$)W4|yZgW?&<>E&&%nCQ2AqboEjll6GhcB~J>d>; zH6P|h4@X9Sf0<~g%z#0MGqj#8v7~$g?=klo(oQYsJ}!43tK+$k@3@~hJ~UtCjYb1- zKD`H{3dQn7@;TU?DlTREq>cpe=d{?DEX51FiGA58dQ=)S`I?>sCAIflAj60@x>l&- z9@+|9bBJ4YQyYBH7{rIO%Z(9KBSxh~$-9hb2TAe9u5~cDyGc^MTRy>_U9*kUWXd4s!XouJoo4#WS+idCj_zU>XrP- zfv)lhw>`UV8Vkrt%c;}%GUKF_kv3BR5m+=Y0FbE9fVTi))gaJdV9od*kx`RAy{C(ymk_G$b z(#&2pO|%2R_qaROSx8mxj*TB;7#W!NH9f-Z&^Dr~QJR>A+_}Cs8GmDMOJ|QRXZ2!g zVHHi?I*eNA6d1jy4vjo;35(XCFG zhMh_53Nr9!Fq!<8L-y6EGu`-#Oww-WkJyOwz&KNx2l+oV4~zlikr_-f$5JTM+aY32 zn62H;oqSj8;n-P&bmih#sXKIM@aw|ga2JZLDcdDl-WUHqx5A|lZbVoo{LK_5OV|cE zW!|Esa~B1Yn4P5e2bqYHsCF~s;X6=XGRod_`AVGU9Cn~LMai8WznDV{swvEt7=;^w z*F*Ob<|U6bEzuv!Ph&ReLf+HD?q*j?&X5Rx6B~vh+?5AM^KGYfYIM{w(kL3ays=T$jnKcuseOGxGBGrjnbe&pBxl zf_5b)*vE0K{R-}CROfPf=gPlKz$AN235oxtF_t{yeuk1xoLjMRR=vGS$D~vQJ@}Px zzc0RwGRP&J5`u7syo6i#@XW3%Q8gx*>27E21X`!`>p#H2rYDmCAw)rE)B@JkxZy(hZS zNB?D>x#xpKyj%VvXQ6D%!uPbZ+-rw?=ea}GV=v_;aNhNux|)25>NDq$rw&U-ynYz| z(lr4;2yYqW1CN#i@&yE-ejR{hVyx$angR49}43u&lj#g>Oi- z%{OH3wj432kzBHC5_mx*mdHSIeV%D2zKv@{n&oOB@w;WZv*Oy~cC4Anr6}M_l*PQgy_i=c?S4eNf+b#8>dQh6h$$aoRfKt^DOS&$;CV$uJ*Ljasfj zwt0p5L_waNP+77fRC)y(O;f!ibztGa^e%@~mnjD#JIz#DyEAoDW`6g@rOGIXuA-aH ziy$_@tMd<8_%*3P9&4O4BQN@}ec#`ytG(*_{P>Rf*vLJtI)}E!V$J+wS{pNpZ0#<= zrY3OsE0+=GV9S0X@|a3@RF=T1a~L)r(2rQuv6RiW7ppAK|4N}~(n!_>R~@lNHO9v# zxU@6qTU|678F{yf?`_;XFt52{m+(a!4Fk!@tO8i|Tne3-_uspJ~)q8(v%SXT!6J zp7^szPke*<*4;LG4^_n6)BTySG!^3m}*UM{C8|F4}5|h8vvZtYW=KN} z(+(d(U_+QX4x`>I00FFxwCd6YzUZRRWF5pzay`)8M$`4{il zK4yuwBzthD_+KuM@0Bx$?sL2`RwBEdznrEeO%4{=uyeFS3e}Y*!LLU{A*%ySG%hjd z66c#^0KG)yik=1^K~LYQ))iePG9#F{vLt_OBGB3c9pwsOmFf0GiQ@Yq^{SWYHwm?y zhF8$an>7bho=%fWlLPe<@G>x!Bla=M{^Z;0vsb$*k-SFZ&&*3TM@6mmggZ53yjL1O zu6y1qGaF~|%GHW4b>?BQnug3Cxm|;XcKq4iDUOE-Ba@j)x`gEYlolKtdckC&`?om_ zL^M>==>Km-gZ;E-G;E*3{*R0{*d#3hnl&gZ{rNxx&u}OEbeF{@tGIP~tdwiRDLGWg zI-Pr2T7o6)LXSL|Ly!2Gc2OkYr0zt?lP*#6QI-@z&H3MuBJVvTQsj3oDe__D_%taZ z9Gam;0$zzUEiy4|J+8UT**vUY zXp)~Rzlx|5rH~U{;#(~JO2}SQ<`O3vraHqQy9Xb8*AOVf#zLT+zDGP|llkN;#D}kG z7=_dL?LVVW#F`kqDNnH7POnqU;w3Lm~my(UGh2mJDSQGdC&iO zNueU=3{XLKJ|@W!-GuOiAl*fUe(TT#4hO(oh$Dxptyb>iL_Ci=rdtWo^#G8gpN_ab zqye#fd%4`fWk>vg_t0^Or;8lHl(moVQO0S3tnN75lxT+zu}$J`$bg}lVi*1Mlz|w} zzn6Lm%0tPC3QRDB=&7u`I%d|Ld;jG$4SFQ4FJ(O2 z)WLKd8^hT`>(693(E7r~(E6pW?_4d^{UoUSsZjUVLEYcH4Jv;ZRQ}$a`7i=urX+UJ zxpXxzQsM115%+GIaS`myk(gj6uFgCcEV$&mtJ%1V-UHy`JhFrAv2~LZtI68ikpuXU zWI@iC3l5S|?ydDlsOCg*4B$h>M^K63_i)KMbfnsfZ7yt83F+5_zobOdmdWXSwKKGB z-jzPm9?77@*f&%=nE{fUSQRbUtX^HAy-QnFMMiB@VJsq| zPj>#rqbE&`Z-l%WoinKq1|z+nycU0xeou>stHk1rp4NQ-bk2K%zo(Kq)SVNnyAc0b zd~dXmxuKGaa_3GP!R|HsJAz{(`=_?a=ra-Jr+2EZ+;43LlE;KAqTA+ump52YnHQzJ z;IsbO&#K9Db7oiY4zhSk^qS4zWcPYYF$<{j1yZ`P>cdZCECItNoXAKz*Lm~Q>nXQf zxu<;!v&Ut^qdu_b(FTfI}FmJ(^x{2I| zwR=FxY2Hi~KT$uB*fJe}TC-HPu>(DPiybbkj#Tk--a*275JcZz+~1E8f99M^zlQD$ zsJ|Co80=5v{p%0NkT7>zMHsnSBqWTJn(uOEAM zy?8`tBT~N3S2OT4DcrC}_0KH~Hl&}b?U8~}H%Ct=gAX091I?5;mmeptXiiDMZkXuY zzzt@-Y!bu}`1||UFkK+n;%^c!aeXmer}g7$-N~cbbjdWna7$~`G*L1KzKu*M_5m`! zF(9J)!LZ-hF}@zT4NHM=V)*Z;^f!74OfqrdhlC$hMtp=x0)$AFbJ{2vKYQ+o)&KYj zG*hD2DSzvS#ZWNOYc`+Jopt|aGWu{HAijoUIG}Z*=aXvz>M4jE>!;|@uX}=F;)nAy zfe}%#2djh9l6nY133M{+k;zC{?pt~JpxiwOda8K!uG8>E$W0-6D`3R3muHZRyFbGA z_X$UG$Rc0l+#=_rV+no^Wi%*%)&;?aUhBU>FfEd3#}4L4t^$wINv5S0A|38eM1Pxp zo#y8b%3dwvZ?7)Rr~lvZ$8Ih`uhqy)E(gJ4X?Q;bFPm1Ds}-_o4T4jd%-RX>#@c$g z4W#)CWvguaQk|wn=Ty^#8{d|Wokqu!c!Q)`oX0OT=F&y@pJ1t7>WriE);@($JBq#E z;u`KL5BP4c+qgcrI?G6=yuKw`n04&so0JjdPu6<3|0dU^)3A^jp z`vkY0i0nmYfebpI>2D4^aVCpuU6*0 z8jS7i862_`e`SqyX=nfR`H!%SL#9dQ)CeQa4K{3xcD6Sas~>2&T^r+L*n%*jew+q4 zOs;btn0+wy)OimP2jwW$mMDJHpCPnP;gX&{{BIWb+!1iqnkkhH5k4Vt(W1$S4A|RD z*VB}|oY~s&F`Hi%Ip61_dVi~~r?AJf1X1)XEr=T!TI5h=UgKKz@Z3o6_P8$2X^+39 z9w$RAwR1h_#v9*P;Ae2-oI&JsO%?Yu@ZoC~KZA%L3Tw__=fg)0Cd~!1v6TByf$Vs> zvbIJ2xj^eJF(s}xP zNiyaPwhhhDbOw)cs!pD4URN48d@M(UlbIjzJ9rMVxnRdH9I%!wNbExlY~W z3^X6r62Ni4+6R_WUc)++0ekka}gb-ihs@mnrJWbKiu$z@1oRvQYC;^ z^8&u{j`NTH2UE2TUyMx@e8D4WF>xrntE^O5cT4nyP7*ss$_Ay1Po)}6BS5f${LXOC zxm(D&F-$sa0-=Y?N{Hn?BEI#G9ZupAg222gdcNzi1(I;jTlHnIGo507u7t`aq>5LK zH|J=j^TseC^Q&BBG-?8K#0fmn07?CC%ofWaqqZF$kX-W-KvE3nS3gBgJq8&{E2P7! zqjH3X)wMH82d_1R@5+^w##iYKzZgwcO6D@VmTXM25#(H)SLnRj4>7%6Ga^)x$y4Et zMX`~&(+*Ya!rkdYVP0+rmg&pU_xc0}sSDvqYv=`0Q zqZS@r0UF9s|KL@|-w&ZAq2_1zp^l9K|r_IKe<-0Wt8N|&ngPX*M^ zJWu<2+=%sk3N+EfU-|&j2RqYVFOTY<=U=0z0Jk-v)WH3WZ?OxmWEbQ@d;Q*2>f2Yz z5v4NEp8K*>uiZ13uKY4AxbQXIBBZzRn`-Dr7dA?%2Q5bA90MCSP+_f=%)rLO+dSB) zp)<~BqzC|koJA!P2K~hu3@S>)V`jdfr=XyR?(H~r7P8EOOjBEBk&CTj@ z2E{_J<;pqcFwMKLFUgQ=9=>;;9_pSs;lz>0A%9+7@q4!Xx9mb@{C6*U!@jiBBR8Ed zi0{uK{ZMBA1ru|(`PcQOYtGQ&!lc#P2=`(4DxmjxwIro^b9%D?-Orb_&NTMH2sX)A z=Hz}RStpM#u6P7M^y45&=NCTh8yxeT`?)f?4lpeynyr}q3FRn*ptHxqmDUYTpD-O& z5|0?1g})77L7Wgi&XguL0NGGi)If`k$U*-yUlw__}lpB9z`;_CGzt z?2FzaM1b?@QQEpWE98qCKNdDaI(C;ix1Hn4bI!Rt#+!4_*Yu>JzQ2a1`s^>>n*A&Z zsE+^8fGVax>G^kOZ?alP{V|?%!F_TqPlRiNGK8*#xAQgqLGxnOReDc$L<+FP=Dnu> z-$%-EWw-O;FVVNGhwx0pKRZe$M@7!RD8T~e&w@ni)qWK73E@wh-H3fdjX$v75d3Ev zg5MDPkuiqQkIXc6bx@Z`j^wA{D34C=d2X6c=eTwrp+xdk-UhAWJ3u(euo-ft=V+7L zvZ2>cbz3~ikl&s6W$~S6Wdxfp88a2+IX^o`1U+q-qUwd)vw@~(XRF<-Xg586eShF% zk2d$|ZKe90v44WDH9-fRf3c5q&kK)VEHvU^Iawg&5!bDiSZr=*6WH-n=VyJH*QYyJ z8{&!o2S2{`^ey%Qd6qW&Vsj~J0Ue|3Q~^d!XCojq&tKZ*j~zNu(v?PE)rNR`q(5$j zTeywwIuzTI-)ycC3Y9p=&_{^`GLW1dzhmDFE&Ln&bv@R)c)$f2TKJgr4K2L%eX$=S z*NOM;7*nSo=iz1QCSh`CmpH9QXz$!-H1>(%XY3Zlo7$YK_|h4o79OJoi894s6#s#G z)13UDh9h7$b_C(eTRz;=4cxpt%~+<6lf{@SZhRxzBT-O9b2lyF0I zianApAFD2Z=b>zud(q`qJ?%{75RcN=Q=x`Wsq^1%oqNNHYd3BIxX1~U*Fp|E3K;V^zMNP#AlRy6m`Tk?bG9>R zZ4aKbAy~1&*Ys@x9E^3|C%&TEofPK#PcYO{e6;x`&W^(k5EXeqq^$AGmox6hZt(Lm zkr6$i^=s!D_^Efk3P0EWBD)x~RdWV@-hU?xKPT{|lf0oj{M%x*>-7rbn+hq3#aFtJo((sp{A^i7p;4gUth^b5Y&;FS$Kb7*G zF9;4>DaL<3NM15oO4N{C%pW1`!Ur@LBa_!~p98Od$k}3(3O#sDeuGMKKsH0)oDQ18V_&HD@B?C zyzY1I`*9Au_OzcC`dY_78CuU8&{65aYf9+rGxPkV_x!O`dPP2t?-%;A4f=ZPP;6^{ zv$-~a-PZ%`j{)pwGk}dPw-P8pZ;Ze8$WlR@Jy zeq5@$Gw|K#?JRs>%$LsLYM~2${2@)G;rl+?a0XJYD}Ho4i2r3`_;=pQ!rO=MP+{x! zIq;dqkGbWZpn*ge4Pvb zvDD$W&k8oYiGcP{-vP)B@Hu#;aa0Lv_lw3662WghAL-5Ys%o)XiIT#{jtCR+;5jJ%L&j4E+-3*t=j;Zwm^^vb@(oR7&zq_pdgs+h#%1zi1J)D+HX%yBj?~Kn=27eG^0YdHF?oAxfVLfRt zgreizZ*Wt!gVgx|mGyPCwNhlR9+InXHuYJb{kQcgKm_#mUb?9I24w5Ip-X*6_u;Lr zk?*)J>bWzqg>G^XHg9JNLKTs+X~=*SKCLd~8-HclG-P!Z2cxIckW@ErL%#TpLWf;t z7>15eT)+|qfSX~(#Zj8@5|6581#Amd?2jB79`fb5#HfqW6XDWpj${)D6}>(oJmKGY zD!UreaiCQF!nX*O0SDqmTh4Y_S`s@G1-40X`eYovsg@k}GlsT#jvaxry5zTXPNd}z zt_sQMZns?o)ovT_bWx#26l?9%8%cDj`Jj;+)zB0g3fQLi3Rz^mF*Id*X=s2{@yTxg zl2JY)ezNQl_NR)=rFk*d8de;zp`vZt#x4a-I$mg{=ONRCn)EIzxR{q2I(xD z1yu*q)en(tAtJ>p=)1ebO%-Zp<#u%n&U0q)wJ)}(jvS9F}m3|^V**po1cmJ%iM!_Hr4_-D5_Qh_4QmXb~3 zpIpTDhrFC4^I_T&iHGLSx9|dn^50VV*SS=FbgH38T!N0XshU{ZJ-y=*<*G~Ho27c` z?Hu}kd;C=$koTDb^6f*hXY-rQweW~XFq?6UbSxz9Q|C`SzU=YubUVL>oteQ$7o1`6 zQR^E9({?$(Hs7D6&vvFHNJ!K7V_(mnU-S6V38@90UulfDgK9kr@RcE^g~@863&t}h z#;g+WL`&;hCWXoCos*@R~dT8qt78f?h3{(0skKKHLYh+!VT|9yD!Sy zITs{@Tojaefk(+82z^&z5+1UPSkO?(`^Siq8Dio~hph{yTVu2y<{*0uuN6`yI$h*- zD6yPo=BD$n8UEz0zh=+hoBzRtjF^TjWUbJ@;Zk6D+L#7!Mm7!BjF_o%E}?YS7PPsZ z%Bk;oN_755xAC((lAkiP^nP-2B$m8>Gb!X5R$6xKZb36^=tX9Jw4eOe$B9`8%Kk#) zkS)%UYzC5rY>A^BX(wGN1wsuuY)YD?K#sm~3nrKn8#~MI5o}a%K|sgYq8BkXU*P@K z`QMNz@Ero+Vz5&D&*O=~P59>*dH1$1o@uW^XuS729; z7}P$lGTY-*qo5(2Qr<}wmr@0=xy7FQjuSWu!&h0B_~PJN#H74$yg=_G%biDYxf3Qr zCfFOP>*_O+Gk7w=pFFMI$SjRSd1nNqPV#R?$n-sJoEGOszC}!Xj1YM2vmSWh2_ME^ zU*880_0=b;rZu{R{&^fZCt}9an8Gw>r{cF??U(1`c4sj)U+u3?_NR)pyz&V3E&lrI zA=E_aKU3PA6j!;G{pmDF**=&7rfZ}%?z{>wrowMul{||2oLiZJ9D9cx3|xmHGIEoy zQtnm=?-LISF~v&6hwDUK#LSVRheYtpMCL0+g);W=OT^kkJ$+4Y@N|BdYs8Gd=9(*l z{;p728|BD5?Ug4Wp)&FW*(JRBx$3WOg>EP?1d5vt2WYKJFDf+@L`lKtetmp?C;6Q9 zy>s4`0BO%@Jv_iHUVExJIX9Piq&?lQ{417ZRYsm-;1#&=uMygCYQW&hJD8Og$d(mu z?e=9w&2@v44QB51oR_Yk{$suRl}pFlFX?ggFqu7^L8VB`}tOl zDQU!OJJENv2u}NQCXLha(z<|s%?Pfy_!AS$4qB5oM+*IkaM>ZNRR?J)>Lv zsmZf_tJ(tj4oB&{Hs>H|2A=vkLJe(bL3Z)nQB5rt`Yo~ChIZaB85nMO=S(qdv zp>PpNBYn(s9#Xvzc=dMvCOuy+?sO5Sux3!9)9kD3yAha*l==tu^YqyKQBZdzaKRJo z$2<_dI6Kjj2fQU>`WsyE{+m92&NhEHyx%vt!RhO_wsQ_uZ1dgoswV8a?em2jmJ)=$ zHJljrj5_FFuq$;U?<#I8BT$v_uEf9PW9b7b$gmXyp^HhE*Pxp2Dz5PlE&HRpvgSQ^%uehsh_U!`#xIqcTIT)AP z*dgup1@_01Y>!u{O<`Z~9w5;$JtJz2Z&kq<5Z2T2ebN5@*oTDJ+EZ9v@fTl0QFi2J zSG}C>S>=*<sxoE$?PqDObY0wNU&5a*U7>gPCZ zEOUPI51lwnmOW`1$JNhCX|&WYk5{r|eZ)x^Z!<(y0D3g}1L|pI3EC8C>=|DRYn<$0d98=dVCQJgwKsA$;sSKj>@rlWW_-DWRAw zq`NN9g&t0ej_P;RdNcSnba3oWjiOZ4B!jxebOeS{9+Fa9T}* zju2MB`qH;5I2qcc$l9{tt-LSu@;2-$I#ss6hqFC{DV!=wY8%=@zTcy0-Y^1i8xPvV zX0a$Xr#wG8fU{)Ubl9=h>@+^fc1Nm)pc+Dv{;XT^ zMSZ}%(PgSXQZTfw6I@kQNKUIDn~-MiF-GQ{KXsNIr>tF7<(*IG&@#dolN5+>TZ)cnXouZwx!#8Ed#>L!7BH=K|;t2o&odjX!$de^yo2iss04$4o> z+|(mO^S?n^j|6+mje&X%<&1>G$k8OkG3`c+$<>+lFHG}u>0g)sLR{mY$nMxCmfu)( zl;m!youD~MHak)+Ma&NK5(G~H>z5aeoKg_Ek#nmMo3?d~jxOIhGi+T0ULRZc)U_IK z^$XUNg66S@$L5a!Rwm`m58)U@tSobGqtDk@O!(BD?2B}kOPLoj^(7vwm7P!YD>GGz zDx0@z-+(|ii)z$F)(F|aDZ^=@opcwRy%U(^Umcf4 zPqz)qO!8e^f}XzE#v~i;G!E>mVMSyWog; z5(~}gnpk?$UU2w^&b}kB9_&jT$?`Le<)pC*+65b>y)=}d&QIvMASZLBU|`Y;o!~q>Q;%W=$+Q{nuSt(bptj)^?~cb_pQ zw;f#}$1k0ViGrF1Z|Tans%Sb&yz|r$wk$N%c?9v--lxh3xFwa$*L*T!I-wh1$Ka;5 z+B$c-g>`C%&WC{A;Ixc1Epn`+-PUGa3VY6NHL2R%`DN3zDzeLd=hjybiKC!K zGbP4xgW;wR%3ZEKhGTz=mA#P|i0L!%sBdI|>=-V=<7)(9&W~O|WpSl}GS*Qow7mwE zngqS*9ATy#MQPv+8XR%}GdyQ|KT*&0?msBv+*fS$t7d=0rqa(A6JZ#B0CEY;FE*== zG`79Aeu;_QypnajXf+oI*!3ONEv$ml1uab#e|&~vpC&U%->T{sqSp6_%yeVd*H9{C zI${^|CIpbC`%^rI zncJ0J34u9wd~;5Q(h#QU+TPi;SDgBydwXv0C(+({ZhJ2O7$AM9Lbg?6|K>x#4X0KR zEi+zg0ZHdR8ls`je%se1%T(t9Q^xEkOmlFS?6nt}-|AlgcJOaQk2Rde8C%5=B86v$ z`PBSMx!k&5=bBF73bSyERuAki z&KFbcr)M)|&U;hS5qRO2O^G0t#SUB-d5Y3STwf%2=g8ySm6$izMt#k z+tr^mYWHe>Io94k#>~&(I z>Zx$&CftkdvW>E0`H}HN&z=v0ccHUFX6SG*RUKy&XA$1q+XB9oK-$XCse$H8kMPG1 z96s-c_A!0(+Q$^;b9bb#X(>Y|UF!6Jb-AAO@x@PLkgV{dJ*BTWekOXQkoA&^AYa*H zq{;rL3Yl?^v;s;Kk(ng?1cpd~n9JTscam2lO|7cVm{Od*JG zuLW;_K%SB*k$-i8mN9YsRcH;>);7OEBc?@FN~A3%9&{T#C(~fLX)s{>har#qW?}o7 zzIoHF+xv}84CCCpeHx^%U+hQzC)2H~zp?J|#~yo(W3fJLT|L9MvaY9ZWo5yJw+l%S zoTxhh3HB<&Ie68!;D+~4hPGWKd4GFvD5q}~f*HmP0BlqHMt`%^7vH1aLMY*S#5nH2 zGnBsfgYZHg?v6!+Fv+Jj(Zx&i!-**c3}Lf7-1I=Y&zwQC9v?-$e~?%-ar|Sfg8yj+ zk@Xg0XL?$$hP-%*YB#xylCHM<{3KsDDAe6=&cShj-?Lr#UjRD8|8ngVZZ-U`>jY-p ztAJ}W+~n~bj%FW$6Bgu~agSx(>XGAi%XiZ=>WFin+BwQ=2OvI%nxXQ_(v1P;%eJuT zZ&bN8UO8ivZ|WBsJ$^ki%c2llv)2F`a~q(ky$qUIYqWB@?2kB@mb&q+rsvpA{daf2N4M==ILqGl_Q6p>qV8>OVT;?)mFIN#14ko*yEQm$KPpklt9@xB;K({9X7PBu_6Dn=~h)u(6??QvW4kZxT>BV=_8ZM!<$6XCB+gI+Ys!K$Th4Vci)F3FFyS~QusDi;c_5fl`ZHMK>nsz=^cRuCDYwZ+1K z#hqA|v${87QfGzB>Z&bD`I`e};s_l=1wkyCIssN}7EC_Qu=S88CgLOI$Rz&=5-Jig zlg%nd*nokr$%Hidzpar|7z8Q?ot_qXr3tZk5eByF1UKxW7F&It6+y2AY;sPcGh^iNZn07$AVGlQoT zeCxej{CXzuJ1wW+2$w(Vx*xuZj5xL@jsoB(8i2oa^3WZP*XMtRwrRR`x!`zP*q&dC z&;eM!ygq0z)+(So3|jZRCV(dIrFAJFeQA&8F%$g;v;BaYLU6BNgVY}73m2Sk6*wOT zG+$Iba(V$N&kQgh0+=V~!16pmc|4Fj9YC%Dj`ur>{hocYFFx9Z<9S#;Sbs8L+{XoD z^4ML4sksZlCcV2e@TNm4XF+ui7;+-?I?9{~{rE930&=={Bh?#J_Ft}BH!zfW(O0ps zyFShlYBd)Q?>#aDhYxTG9J;u(A8mI&@_)sLF2P#~UN)8~OgR2+fn0bpTUg^^jYFY|p1#mD;FD8qG7qSR~Zf&Wxf~AVoZsqqmTUUd4NrjoF{&TMQ>W5 zY8r$2`P9_|DcT(~kfMFTL#0-3q19P8{!d$cnARd#o0yg&Kjtp_2{mJyTbW;)?!fEa zIuM`Fk)*bJ&|nJ+@37zYR}S45Z>#hzY441=aKZCo)%Le|PC#?LNd8-Ux}|&d@a0sO zJcd7JziU4`t46b+<4J^?#%&iKk%6fyE`j9D>pj7V$9IseGcMx*9ja6?`Mn$L~xD#Yr{*IS9Qd_0xcbN;byv0Vk#iE9fm z@~s&`7I=;vUoTzjg5-^>YDNTx?Ba;Ds?a=F1)+RTZJq!>@WtWtrnFbV4^)XC_yT^Q zj!JRhvF7L=ZlIZa_UTXdiw+%r4a%yp^_hsU9r}YJN;G*D+LgL9$P9MYbZf#YdvBLnI&kf3&>~d=%By_`jP3NC2IvK~tp?YpkSF1&fvi)GXPB zS=}HN5UirMQM9dAs=I*Iz~b(bOo!F9N~L|Y($*@iT6tOp6oe#T5|Gk>RuJC+Uzjnz z04f9!^821UGn)4b8l>^Vh=!NjVMNj zHMZo-&Y_8KPX)44>YFNzBFCmfE*-GeBzlGFwu)x!?mST{RJS1y+G!|)7nuPM?#EX} zU^4DN7QJ9_Cv%E6K5zh567QGMV2c+%{&NHDPZj=lfj_o2;MB$9F6Z-*Q6)ff@UN<) zM`xAg(v!DO018^)?zY|{pSzN9)okm`O5tB=c?uj4739iHFttEfvZ*EvR=G|+Ou-@;_mg(qi5E^;AE`+j?3PcRjSC{ zGW7%Is0ttdjwNv(>RWg(^PHg#PQW=sc0!>feRp^hIQ9$_v)_FPBiCzGf)T zueIS3<5Lp$MONZQHlQNaA@7VXm^JH|W#y<;p@jR+9D;G>-2WrD?rwIbVcmQ&$W0?m zIpWcP4|}VjJIIeWbn%t&G$c}Ot%`moztP#TWIeOxbzgibF8+sU2vhsZt>D}35Ic}N~8Tk@=h!Mv~ z`H8t__+mGjy`Fhv0JIj$%<(h0YlH$aGyEOB8iJT|hiwr#dgeF9);U5EMk_|mZ;)U+ zm>GBUz+Ua?rp$!AWMh6{pB8El2DZl52XT~JCoqUGUa8HmW?Dsvsn^Xq(by}mI*Id< z9Pwhd=xP^nzK<|8Hg&o=hQnlUE{OfWk$aAik9)!lrOsE|G(1RjE&M8JO|iq@Tu?uu z$UH&YV4Ngbm@gu8mY4^oiMOApz8@(SC)bVmDmu|8WIv9hM4s&m_F`@NKN1n)?=f#( zdQP^1Iekruy26R#MvbMVMSV~CkXPP$$D$!A=Qc$E%JlYu8fab zr|o$(XKn2|*kk`Fk+!1KO3a<)bMkvIt|DS;>Cs?1F#`48u=T8DScq4ZCwSr09%v#r zU&I|O`<`@8&Z^~PgdTNSv)0WM^@#M5_1n>|Xsr>~ai>GV1Ueuelvw&~$>wbVKbArI`GSW}Z;=xLhxF2to2h zIxx-BpHWLKGAP zdm`jiU1<#=qEAL$?8Gh%80kx=Baa`iExTiK<%k&&-)v@)hiEOeO_d$@f6?n$uY4Cu z7M+17;!g2pMcnJTM8w_sj6072cv9wjU4Txnw&>;qFRR`d_X~>X^#L&x^+0O(`epq@ z8p_?DecW}TrzbeTB@NB?8tV94gZ0uh_TSU!uQT5Gk|Zwk%Ww*|RVzKl?W^cv(c%BU z=s{>9zEtp$ILM~{JRyqZci~bo<9d$Jxnv$W3Ppoef^lL73asYB>1R$reYM3Leli<> zrM;Rcq_G)^Xu5It#Hqu&v`vtQLa5M$A(cTTmnkZ-j_+`&L!AfdP^e;8vEzVY@(3N$ z_)!ni=mkXo$5qFA?t)`TWAxGNh=sY#TJ#$K_P?oqxft-CSmC z{~@*aoXN7j2<{=be@l+GrWPXN=dXs2h6){Z6C?au(Tn5z8#T{E4--t(VofSV|KA5{ zb{BZr)TOwE5pcd=Bzdtf{vP?giB{p5Yb`DI*x>#!!N%#0TMEK=@ z758=|;7~i{{pUY9UZkg!?X=uSD7_p$vy)+}cip-}70nhBl^Q@7>LC_De)VR{( z>My7)bHPjec+%py{}#u;5>c<^0G!~K6RX)n^cwr;0g{=8%A;lhehuSUCgfbV%modg z*gA#g5Ob&ka`D-Hz>?QrYbB?WKX9u6;BN>uLFs`Kf-fiJ3;+NA)zyJ}7Suwqy1pJuQ!yX`_IZ@JJI{Y!e4o9X5^8>t6pTKf<=f-) zUF2H~drCjVE3>MAjPl0Bf{WT{Tf1*5f1{Zf8Y%j`j3BB%0y(+{Ja(MKbwfh)4jsj+ zuGNWiQ%kCs6lCgUFiJ2K5L;d1nOv7ftxv|6fU3yv{K^1}17YrvMGlf_*E zkzKPdWFk3q5lOcA!Ck?3gKWh@#y;bPhbWD8t6=nb@m-<7{=1LkW{_UF*c>!tWrKw@BsT%uoGp)w`wY6S*m8L{)Hu zQ(o%FLi?5_M=J1f!FQhz{V2E3```qKMqv`D zRLf?}i5bI?1j3Ht5Zx@^I(#le{z}e}S9NBoq>hw*aNEKs5p0A=I{t*bA>}vals~Dv z{1m7BwkH_$nvV}EA9`Yxo|oc!=D3yp)jr<8#GT+ymW?0qJ&pX4kFHX!Tx*XK&awqo zH&jyXW2PiI z>kEywM)*-gkH9u9b0?E2Y`hpIa7Re6L7QEqHU8617>0Di}E%-04 zI4CDD?gs65jmgGdMtGHObdo3#hYghpo2-Y?n)oVw@iB@nxy%e5DC1&jq~^tFhSl@H zHa$}itj3kqc!lRIUg358)^mn!wQ-a*-1aX(Eb%91?GlFSWvToe4(}76aF9hRfUWd& ziEbPu4^c6tmR@QOCwigaWIfP1vq%pd)$S4A&tU{XxU=;x)JUmCy3wRpyoMEEOnvk` zzuweYIHtbfyinlAM`JgP3*4}J!rT**;Z^=^&E^1NB_iSI}A<6s1sKOhL+1c5Y#=|EIz~{jV&Fm=h*MOinOT4pQ2( z5z0R*T(9>dq+7dpH^YeKsIUAf^e4NpiHO^m_}zq!2|U0kvQj2f=AzVFqB8$_^-e4U zj*ApJ^M8u=-1Wv0y8|BTm6%8F{1%F%*~fD+L@tWWI~{)|TESR>rA>J(MT{BO8%HzO zDSxG)G1YNciWn27RvS}$IxJuNH=}SE(|nr3M9LF#ixp=65V@m#g}}un(3&t{xGO9N#1HYx6ql0TG8 zcd~XcZ*P8-S@s<%=lKmu-zfWcr)(oX#OSEv)9jIy?&klry#5U}biaDr0ifG&$pK*d zH>ub&q_}AVD`m*f*si`i6+CqNV*&iz4lcsRRP3NR{#gGGDMw&?3>k3)0NPf#tvKVKD> zMa3Jnr1f-Om?zQcOW>mQi}wyni0(r` z#~T8mM7fVhy;O}!-7QpSt5{D3m#{)`k$x9IVX13{2!L=M5C)p&Tqxpye%@HYMn3or z6}9=BGQs>n>)g`<|3n^=?kx|m^Y7!E4=XlcnVxQhHwmd+nu(p%huzPJ_S^5OXumYm zKYu(+h`+wK{e13x;neYZk$1@-0G)5k6*!-jtaYxy`2yEg0cGcXMOq&zJJ`4 zE3^5Wt=HxGdhhvT)=P5#2k-vZ)=IhG>fO(`o{;;$yZ6d1&srpp)_RX58@H8~N6WlN z)jaCqFBd`Ta+FSN50?m%ls~|f3CD<{B0Pjl9gFq2zM)La&kB2TwSRMU&HifttK@;o zoQfnu`tHn_u4;o}UU)Mt>6vJ6KUo%#BQL~}HGKomXu_xa*H;?{B&;&T4l}tfFB;gX zrP7dC#4Ntl9QX(FTHL-n8hGiBT@mvn{hWuTGHv|_kLvZKTIx~tnpJ0q^IEjmT57R+y+lj>UcDxow#j)d zIwmdkuzLNZmJ$U}vJ)f9AJpqx6I$w5>fKT;b-#Mo%SmJ!8g*+*OW~yfP|s+o-CQI) zd&hpt^Lj0HyZUAYY8~}WpV*Z=U!bLas-CaXQn#t+g|Uly-k_y^te(^5pQz_Wv2Q+K zk{={agt70GVt_X@2 zx$DGnT=Xk?U~PQ+F}kzoY0Xs4xS8d1#OCM451;)*%|7EH)f_vA`-D`KWB7$!xJTN- z)7gA1j%HLZx=+0up^7{#D%Gg*!UTQ**mzjTpL2ORt1D{!sgj#&lzoGUYaKoi-cfS8 zZ2yyM3$k7K3AvQ@j+kDtf`^r)_Y>R!I)V_sIJB13l6(o^)P^yuu?7I);31jb5XKJde>^nIJ z=Xu!#*mAgyy6Q+Pr*``Zc_4cWTe6ToFaEstgYryWO_OJ$Shkb$OkG9fS)n|;O`fSM zaoDw%?mFoC4>|Enn`9RoVp>nEu6Y*)V`()1rt6&z#`59i5*H0!Wcr^x3XV}Hc?3kO zK*n|g-VfJ@|7msM&4+&IC!Ek-3j2@$6OG|?{A4(-+fk!bwT3PbB>1XYLKpNw$y$XC z4(_wAsy=il^9F|NnCsEpo0nT_qSXI=#z3>>mEYiUr6n?Kn zGHOU3nyb})!T__L1=k48uv14N^mHSK04ysxA(R=Chl*@ODDae2sNJ)YA|h2yZ{UOm zrp1*dVZz~2cD8EEzH7u6>~AjDQsO$4JX)mHy#z^!QF$W|L~Y=2R);-rh5#!QM|*2^ zr!kjlu5t+ar<#KQ*8Oc4ckOWS%rKuDR1$p1xV0Xithw5J$#a>+ARF9T&pecSrkXG!>ge=9PlnaU>Hr+;5sp@P?wo6Klt5=lZaa5PuHf2wa*N{-<;i9wkW6;Zcmwezabx$309mF<}G~&6FdxHuzGQ*sc0M8DuUL z_M;1W`L|~-EKK#o>7}I&Iow4C!eXd*a)bU{wv^LNx6?@BbMP;BYLZljuW6}|X&`Y? z(es2OYH2?MO-jQ7zj^T_l&t3wIr0uQanVf9F2Wj`MS8qO9&$DlB zph%N8e*}H#D0p+*o7*BLini@5fEX>w_eznaN={ATQ7NY*?QhPD4Km{klDquR$&AF) z0$suK@g>Qf{t+9-_t>BZwri=I>FXNdNYjnlM}b$VPXM|HyhDM-7Kalx zUaa%Cah*KMoLCG%$)o+W`6uwCa(|0IwlZ_=XPY~WX^Y2X3eE{AU5|FpcW8ym2`MT> zJE7fsCigVL*5Fce(rdUxj282mmfFtL(v}4af-7Z?kvhj6aHv>@xjy_DTjAnJCNc=! z7b-I}eMUwonEoumzCP_y>zeP#0p98%)Gc4RLoF;Y3Ai9RI8d@MrLF^cG6HmDz9`f) zV?Wz$1^q92Q{kSAd8jvi+(#kBmG4;G0|LG9@382-YA=^jXFnY6bdo*#;HOm#Te#Bdd^|%k46|uHyb${fE z5bHfW(UK;Z6oPGsV72>d1;GpEsS*y+wke{myMY&yQ|!Dp?ZHOqZWBYUn;fUm=Jq=h z=&jv%4wAdJ;9vapuo(L~=l5^`;!0tJ1w(VNm;44*!VtdU4{ED}r`sLa1GLq7=B0Vs zvMXe-rmZ*D7qtt0!p}M$G4r%G&S`j%GTQPh{GtvgTLD54WftLj!(-<=xwmhXLFbt* z5=~}orwTMxBzXdzQzSVDtP4qM=@?gvEOTk{Im*Fe@X8%fpruddE>bhTSg(0GV$Q_< zVBu6MW;li41YUF4jINE}3`=r(s`az22R#nzu+wxSlqVlRa`L&B78|Ist)k7IBRErM zNzP>3t|V_HEg{{&S|w2~l!V7LK$>yvaniIp_sUR54O_iw3SmjgM@{v$kn7{DHllD`AOhDmi@77PpNC^}v3b#@uxy z%iGO9=9K@0g}nf)5T<{;njb42W;X3nMay+}B0wt&pMNQ+uur8)uN^SNKgqAU4W7@7 z#6^YA$ec>yy#_~7;_%x~3C_vrs}{;P)!*0mYIP(r>Us?`<=cDT+{TQtf5-RwbE-zF zRFIG+m&vLp5Bk5hCAq7Qat@mOs5&M1V!FFR3fp^So~`u06Hrn^xeKm>aD-*5Qm{&x z+l`Of(`i+A*1CTOn24e|fH9Sc{rn$jU}MYwKm*SJCkGCUj$|f{@MkWA9t!Y5*?@WQ z+$=v6h8Sp$m5RQ0pZy%DOCCk7x|9q1Fr#j43!c;4o+FU=>}Q%1K_!yYxyg^(e+JGh z3$m;Ez~iQ+97^%r-5xiMA>^+4t=zfH)^3nlp%`zlJ~#;H#JLo)u3*kM`Jslbw?F@! zp_YBIV=sz`yzQBcbes_rpqn*iG0A*HuZ7HAiZW%<{>q_=*ojElHTB^(TtP;&_}v0u zV;{B{C-&>ndfYa!nzVmzXn1S*Nhi~!L zKyxtgruIlv8H@c*jCMp$KCXFP+0b<}w5=03ma5?o2M%cWinK4X!>{x|~dws)%W;&kVw3QmFS zKFN_2HjWxi)yCWCvZVc>(Ih&hCA6uV@fG?aWqHaJBygH)(QCp_;-*{5G0xbn`Zwu@ z=A>d6SBO^rwt=Gg3mI)a#KcNp=KDB~zp33jg4T31s_g+hKwH~!vNNAEQ&lb(Ft6P! zigMkIHFuKnClG7ujP0`hJW_bi+{F$lZ0t5_pX6{cdoj~RJ(sZxjnZ$fy**OXB*+ES zgahiNt-xA>Ra&ypx9b&q^uRtPOzGO#W^?iqk~oZ|G)DdX`g0PLEdQkBft~v15BO}c zbU)&M726-KL$gU6$N)Dpz~c(-A_c3;N++WIJQ_#%+lsL1JfccpnD%kL5VP_2M^2)@}RXKE?D>jE0N{$C(+QDp%kQ)uMWw zJy_4oD&{Qh0_!@G5Iasf;%%Og^11B=jeqc+m&Er|ZP^&s_GS1hE+cqjnJ?U@?KuK1MS+MFb({GGu~NL2KFW= zRcs@Ubao1E0=Wg_vYorB0@kJpT(BnnQ0 zzy{NQp*5rV!1hFdR4&b)y#&bSj6#5LzLBG<9Q>I1E-J@6sC-{!glm+D?qKtYy)qK$ zgZj)pNqRLWoEYhQo>A=5^yZFx5O#c0=Z-w~-nJ|r?s}8CoxBS_F978sV}tcM+1g!9 zKd8o4>|L569@fr^C<+?UiwgePbtZRQqWkyYGsJdL@Tn~uj}f8QrDV~G)by{9`kOB9 z+9~CQg9?AqM~x}2Jylyhri>nQuWFTtcXz0J?Ox#|yg$QvudPP6P>I;pSlF}^v8%C2 zq_O83OrH|VmS*vz=V|MMMw^sJ`7idzHqKJ_#5hdBWbSJdS812tz=tjS1(%+3zeA3j ztlj`0Jo_gS=|md3@9R*f`qey`Q)Q#yoF_uW^uXbU*FBk?>q$b^Sy{!?K6pa~}TA#%bJh zH>o@yc5BFa4EQh^qD2iAZJ=J`)p_sFr4G&@69lH-;cwIKI9FQ(8_ioy8d{MjCfO?;8pij}E zd2YpWrnqVpLHT&6&7w~4rT8x+WH;^7&hi0G)B6QQ%|;u=qvb`(9dnzk{Gts-d(^Pe zax;Dfv2P0fK)>NKSg?~Mwmbe^zS+@ddPC8kWM{uQuPs3tJcpiBVM%#r>Svn|Ys;Gb z+aw>{ed1(TT~k{ctyvo}<80SPmjnZES8L;uoSUst8xO*P=Z4}7LluWfI(GrF)3pQP z1t&;%TEc3-5I)_Wttdkfg znK7Rl%}pN+@;7fjB>K3UHylJ-xRTZU=YwJM!x2R)w#C0q?!(^xS)^F#;mw5)iI}c? zhSpTFE?u6(rMvkt>+*_fb9$*MlQs1*z?ikqC_HdXEk2CaX&>UR_Fpguhu;8rSj}Vc zHRWcqn#RB8J2oWN|sNn*MDRCMc9d&)k}2_rG>ZI#SY!ExT$I$vo5|x|?2tP46BLEd}SjD~v~xa;0 zH;P`G-jUby-pRf#T3ht8ZOS{vrzM>y%X77{LssahVO!7Nud?Z`XjSnIw&WLJJ)#|H zL@~Ldb@piW6u#Q@4wcK(qP6w~JXG^9$3;5JODBoGS#tA)+0QR~j2wD_)>wc9g@ux) z=4%MVc<&XECtK12_TE44>jkmz$Xn|#IQ%o9rPwK);F|;}bK@?&hdKKNNvXYjrU+=Y z7H+s5YjS|0A6a-j`6iput%vQ5+)manTR5}q^|@z3BDtBD?!B? zrF+jm+GUT1;?6v990WvRD-Z9BL^%nOX&&oQY&pVpn z+gZ1Ao+u4|NRfzHP%Z;BUpEQgcE5#W zx{{Sc{UkU%kuvZ{*?6Fu*ljJU!u9`3XWr7>Qsbs@(-iFrumPP1-_TOa50<$x|vl{=w)azpaUSiUndeo@8TT_)z9Gp?6ro zd+GV($}r=wNvXV9&=!(iD{+0ZFY(7l5I%BYUVNAYn2GY8_wkaBF*)-Qd5v#|>VXM` z@qK1xiEBSjR)OlO(tb)W$oM-VwH)H(z`43qYBMHpvqol)!2Kmub22AjFtaf3w(xR# za*a^kDO#Oy-)_1S+7-If(jruK*ORwEW)CL}38jdP8!;D@%QVvse1VQT>0L=)l~PZl z#ths~bWoF@m@PG31^&D)66jEEJfnI`_6x%3CzX!~8$T`1jLAzj7X*#5B@+8L!aiG# zibtHW(K=bwJi@$B2vZ3fX0H!^4=<#nLg&8&oHf$(t^uFQW587>l|d!h(Uug)J?c`U zeIBhzlw?X*pn@)D=CEjB`8Habc`6reTxjzpvYwlEb@QfFm0YufL7EVQSfvwr<6_w~~}%9#=jQcfq;l=w9zRQRUsRctwDD2L>OJ<2PRpH2xh z^9qXF7RxFM4(@P16Rd&$sIgq(k0flsrshTWFrW4dXPE60=NkdS`9^_L!PA@-p@BrN zWGYquOo%tp%yM1S%1Hc2Kn2E9ZQ1*}@v3+PmRgBA>GjlN(u;G771&|}iSq&%9JB4X zA7F#Fe$#ZY>nu8ZiB5nC(GPb@ssJL&wbXK8p*CUq#;(Pv1{@7#bhBF^kSd()eHkYL6 zNZ&(&pqY6?epsM%Y^{0%~#_QcvdKU)*007 z62P#=YU5c&0+x_~_dNxK{Dp6Y6fV(LjW|!nIoy^jXPLdm{7%-Q_=Pfb#@4O@S8&hB z$mrP@IaR{uj_aWuNN?{?v^5HTS8RqrU3HTiO>|hC&s9a&3>}xd$JV zcvzp;DpV<+!75QgVP*aDfs_G-FFZC>bJU(-#M>f77YCgUgY|BYDYGK$Ngn14Yz{w#k zL(b?AA&5@g$TO3+7E1ES1Rua&8Vf~#tLcH#_&!L{)x(51!b?=?k(xcisYZ)Ha}A4n zm#q9#tru^jOLS*^q~-yq9ayupleyF%G@Pb&V_>_gFh^!M-8}BM4>3+?2Z^b`0Mptv z;Lkkh_?z`Z0s$iCz;emPI=h5Hs^ltwPy#v9|R^0lT#vpQ62G}2{U zLX_8$e|)GAM~QjaXmjESCf6{m>s6K36*XWyvrs-}`zn)e&!{7e=?#6f^dugdRb>D# zjKc+97T8g|XayRc+OlLeI6ga>3oho66RBf#;7C`8X~oxwNX&e8^!Xeqkj)27q`2rr zIg~)o2QsxBEQZ^htR*AOpXFpN*%Qo!Nn7&qH&8Ji*e_{I_L#k1`3-4Hen#4oIeEzz zCv6E?dO}BalOp| z*n#)=h0VKt{!o4O8dBMj133O;>%}r0GuWK331)&_WE80TBNzw=zKHh7$!e?bKcQdG|JY<_?Vx@4D@ ztjJ#ekgb{98MNl^^Zq% zSf7jf_9qK`SXnpoUd06nIv!nLZOZ1@^5N4aN-_yldIS@#Yi zP0B$M=w#ERczUC+>ZimB^z7$9kL{=5O_lN&>!cTi!m{=v=qrdbG~x&;anw04l>SKRBww`gw*|J_{ z)1+(Zugkhd+a#b9LymbJTHgt0&~o}5nZn=EHl?=2id0tY?KH(P7vwFI95#-nN=89) zPdEe@H7EQhna%O_+Ug90Eo{i4TL(AiHhH*7VISl$i`a2ycxf;&j`kXa+H80v+F)xx%X*sl(`Zt-1tm1b4Ovd@kKOq%l-W$qVVeIs8W0;JnEM6(pf){ zCa;kx>S=)N)9qi`(7c_GtW$qC=oF*-{VXq)~ud_j)OMlr`C8pFubHZBN$DYaOx%ho=jfdZI`ToC@ppyVSkkek}^~l$>Yo)2c zzJagBdp&bOi}M|CjAnq|-O1Z)`4~{23|D+eGES6A*HDPFh^c{dE1u-5$9O>0d}cu3 z?Jx}|c>YQGR1{SdL7IEfmJNY5AG@*xr^D|Z=_SZ`TTrByngBfLA~ zXO0`Fj^U^*km>L_^|LsxQqyt|>_BFv&4gsr?h*~@0c3~hdwEBtwro?nNlVL-q`En% zh@u~xmyM{;19=Z{J|+f3pvn&!w~fa4X{k}YKsOG_iG44K(+TrdHy)nBRgaXX_tPjn zSQ_ORknpJ6RHD-fBsx7paLc$ED{i3Wh;bcB>ZVLkMonyFSYcHvThyn0f-QZ78`Y=h zQm=I_i3DV^J01vyjy`U~z@HWcmOL#+V3gnzzMESF%!RJB4A*qFkZ#(F{+@b4S7UT+bIuVJPYt5p|Wv>MpM&{yowg7C*OE>i1SfVJEe`Z z2wEi7$H?s8hFmh0TZuY<2hP=+7V%4vD<>1)+^XEsc!KGTXFjuffvG-kO^d&bluOzL zMsNj$wCX~dS5zN9yIxHLF;pjMQT zjYN>F3$)L?lHOOe<11~xAT*N+6&^kiPw=uOY+h6RMNoSwL8>n;{YPq)yiwaF8vPSj zly&{1thbo0fG1G8K2JaSuJQnnB*o@{; zYJl)5Q@?PC=qlkyk}=}}JQPe7&FjSU29qC?)$k}jR^n7mr453DsPRs<@nOh(cD8~@ z4W4fJ&5Vq%WMdNH6&IxzcEehFhYa5`McKjnK3=M3EwzU-$F5wJ|H;Y)tnQf{_OtMH z(E}R$)E*@MJbRG#PvLEURWE!9SD6dCek^{_qQZQZSHXElm0VOL#||r@2qEvC@DHdlr{&{l*_kbZNM)jO__FHH6#C;VTkqj>pp;2M$Hb22 zbp@Mt6$gofWi^!46zy`}>}D%$lsrI6j9Fjr7~-u%Cm81&Et@|k-ehKJ$UMPlHue}z zkxa=0kxc&u=CDxU)mhseO0f5`0Lic;p)|OIt{Z)NjI*f!2BKKL_v?^}OPr2!5r*K- ze#H#boL?>@kMm58It^9NPYb6C8R7wVV?xDcuOqZaJgpNSZ8PBYdeTB)Booc} z%wd6}vtH-?EQr3VD{df|5bJ~eDG@T`^!-*0?~1|b=Cea-9ZosSPlWI=Qk|@a!4~a_ z-LBw`)-;m!VUj&dY3DF<5=n8hS6Y4uU0%gh%RpD&GG9x^8utQH=P)v1cKcyh6LQGSu>AweI12 z=e_B?cUGE^v%J~;Riz2gEPJ`9m$~pA!~Fd~i-HZwB6k6>O(e%|_!VEUpY<^DkB`9) zT>MeM!j zAa1of#y_(`jD_N*2ew^HAW^jFX9aHrgKo60`|}~ft%!VUk(K5?SyxmT-P_#CIT|XC zo3F*%Xq}HgEIqwl;p!7565@9nUSt(rafHqIC)O_wwCxCa=xrimVr&gBQ7vhBa%;um zMJN$VF;Op3)^Y0&@+I)NdWm{BT|2i)`^7&6jP!c`GI>(+u}>=SfB z)IxG5Ejs#tlayp&+hSB`M$g~t5*awwW0ybTwp9XiOugvbB4+I;eV3f z_(4H(7diJ!POhI6#7(>;zxy^H@mdaf(*uX%FF!x^Y@csTOK8~9v*m9WqjW-5X41Fw zjmd3pzGzvDJ5T=t1{%lsyW6@2)v=o`IwAOyZqy$T%~maj`3ru;ajLYynp`vC2o~Em zb$Ai$wUkS&kr7qp^3-8yQf`!6ZoZ;P=2z`f_q3D?{-E^j-#pS~i;>0QZ}Q%lyvRyT zfvzVn!jNFka9%p&M>`Ic-2crlWW2+RcmiPG`TL2E&zH5~aw=rZx~$44v+-uGg^_$k z*zk*^=9Po-er+`83`K~%SClV!$TCl>jem8FP<$#<C&Y>U+0q_>|@ zEJ76q^|Eka)==%c@^yEk!)L<8_ZSlj485?Gj0^nJTPus@x7GJ2 z{)#mc&m+=}qDfATfqwRnEhyGfR|zF~7B?>1=%+USCJ~Z7i`x*n@hons^MJzo1$*5d zoxAT$sRu9BoV{OmJ_XH@Mr|AEZ?QKag`p8fdty!*%o=mw5*DtIdHE3IwTkV=l)(g) zhM5)rekjJ`K8gm!N>zE@ye#TpyzueS!Bk?>zj z8KWsv)rH?~>;hvgnYl~DnSw!qy?6i3cx|=3mI*eh^#}rz1H4d*jKA|y{H3sA6TrT- z+V~u9znCR>iLnptoDT1Kl(7q=Y76I&>mT;-A$C7AOlU@dY1VG^pz9`^k_d=tCk1}U zs02)hVDwhsA84=##iUDx{;_KaJ`r!Oz?WA}*mOvK(gv$#jF9~8#W;VS=3zsxX=iF& z!T+049}WA+f+ z=pkQ_z;w0D85xSDFTyF-@EZPQP8osAb^hcwW7O^@ySN&UT;olDXRzY1kf^aXY`kHMGoqqX#WautXGY9r z4w=pu1apQ|OUSsgz!=Z?|CI3`>yT-0p~FCX?MxXPmLM4&5N8#(PRM~Sogc6!t`j;}umsIt3zY}j@BRhby46w* z!(hB7+WaA^m}=TB=Clz1UA6I9$mnq9!x5PaGAE3^V&eXkF%v$6s$|gUKEx|>Pk$=w zXASb^h~c7IO_c@z5*ko^-K-{c`)Zj3P=KJ*`pa4tX=a_hn?md_rP?WjB=%q;gFyzP z`YDXv7IW2uGImDoM*AW))XsXuV2K{0T;x0a>j=|T5S4I`SYAJIkg+N$-`Qj$S9Dgr zYPC=}2=D-?0D$f_13-=fh(}*yc-byQE4XV&AAi0}JDF(pup})LYLC zB;31-CFqXgWMlE@zBqAZ2K3o;qK_#{{P8_RlV;MWWinS)n@qj#}RBUEUG1cB+TRceY(H}Y9*OO-&}o$p9m!*A1RWL3vv zk3Ot^?;P&xSe;#uz1rhX$QO?#e>%h;Uu?Zf)KkZA1RuiBV)u#9nnS-{`PjMEygq0| zB*uT{+Z_MQ=uGZ7n%wP=^@Ve`7RV+C_^WU&5PTtX{Zo zHt;B9yf1)m{e=M9zWHMvKX={#DtP5gX@Q}5y7o#F$*lI^9U1SyPZx-T``7tneE>OG z(Co)lJun_f%@YR;9;C$@wZyFp8%@#7z!!xQ5w~9C#}}^HIX*M`bY!86b^q3A z05|meTO57!+A5WBlbW*91e&C$ZxhHO*;x4_zL?}0*&$aLdHLnyN?p9dUl8$J1OOob#b9KpWmWm)_@L07sV0dMe9eqgyD}uy-hj@HkVN{Qdf%8M-^^Uv0;(G znr#f=%u~5=BxXse!c99*wfUmeiFguox=Jcv)bDVXUq@-ZblIT=-z zy4uESsb5k>$hbpyJg7dl#{ceM*N>`hxOIF>5Q4$sQj)1}?iCmcNmkupaE6&#HGIc7+pYSPTdI)2ry z9|>3Nh}3)$L?l8wJtDA<&qU>r%DYBH2;Y@jUJSDLZRVXl(3RUj++aGy=CHE8;*zR# zfkQdjqp{an%lkM@~U`qzc|4JiB{59Q$H4bI~2O zoTjI?$>L2y>Q;O(B%b0@)T({iEU$pAFCDi37=t5W1NnH{*N30hGn{j&Qly=t)xQZE zP(r7Air!2DU*$wf&dY~oN3+rS2Dz#c3lY`@reT8y*L|zaEN`NZk zSd{FVMw%jF#G;x%oLxU92Jdeew3fu4bo7V{~nAf?6A8mdY1Pod@$#n!g(A5NR2~ArN7b6yngBi-_`?F#tvkkLGE zmm-BjiWE-bL2}noa+ibPI3elqK?m**#7+l3MHe}KvdT997MvzZ#4z#Cki&?1T@K2p zGHjU#1!5W>eF~l~e(CwHkC}}f-^EzA_8aT-7(qDKtoio*6l;tVd^bRyG z{hH7P^#uJdGfkY5u{RK8=+6%+&)zF{1hkZ#m&3#CC}^osJP8^{z*ES0TV?4| z>sm6yLA#3I)WYf`nTa@I;Dy{d4O&17# z6UO~Z<8rDRmv^$`a@ZS}FKE5zxO||V96K8JtxQW8qztB-r@8$A;x#g@ZC%aXN}1Qr zJRjR`Z&Qo1Lx0XRKc8)<{bwFGD3^4x{(w|CuB8087pYCDQ=WdPiX)kDo;^rao?s?n zvt|tH{>THbgbbT4xkugp%ixXl&~^j@k%6E0iHy6D^CjN6@1?ih{84IwkaNb~zqNbl zcPdKmC-@<%wR`GmsRJ~?IuTqgSOBD8@|~lQoy^3bxJgoNIAGo05Bi+d+ez~iuFSIm4$n(NRHkI}jVl#63k-6w#TvFM1`!TczloQf`vIozeE9+C>AF-Px!D#wM zpirqiui?UBMYju+hozi9@2E2e#4k--cDq0MKFsH6g3}_BFrIAvN-|x_GrzX%LbpuJ z?x=I+xKMz-fY>Kwiy5MG^Nu*x#)M5|o)yXjup!@-KzR3aFRAbZhrcl{w=-((!KU|M z&+xbRnO~pdis!ZVx}@!zc^0~$TpY(rc+fqu(!FVk_^cNM;lX)d$PfM=bS|2SFYWG+ zi`V*dc%zFYR54gQer8Qy z*4ycv2dbsFK~>5qZ1>H=4;(f!zdM0v5xFN)5^5%Q-ZoIB`^=sJj}hJ5^*=@2e3>cc zq*42&nr!WAF9p|)pNVk#XIl0qpi=2L^BZGgmpzX^9D1RpSJ040UrwTQrA`9r+Om^f zx)ObwOeU(`D6?r$lyX=}Kvcv2>*t=E@pbk7l+So0B^m69*IV7r-~mf0#-U zW)b9ZmvZ05td2(%+ah;xm)#G-;V!t+o2uH_!#1boh;3?x^^;pMZy?-5A1l1B*ZmpH zas0N3oo7XA{)Os!UF;-ZOSqMpR8XAUQFfp`c*cu7eu}v&kLvMOs=t-g_WVyjNkJh9 zJugE5jDL>+DRVtFMKG#zYs?@Ou+W~&RjVG~9-+S%?Mvyt^_ySj=*Clk|E+RErtc+Z<{~;)Le|(h4u|1sw{lbTm$Eq^m8{$2++gj~I z@3c|$BcLZ_93-?`HZkJQqY9)OE42q&tOupopA^4&p21_FE=Y}225@W0Z}ETsMGpTq z?<%$qY*$c`?3BWABR~)jwh>T#SQPK)aUn?>FjRJR3~<+reMpKN)-qO49_nI0m$@AV zc!fW4aE-Bf=1zykwDbVJ)Qx@J?a2m6n3%E2<6a+0t`OF9h_=;1TPM={nwhr;9bQ4~ z-q|x$Mvu`a2nl;cs-=aI3fT%iMCg!ph})oAfxKd|_ZSkykB2B6%H>_qI z>s**!Q)ldWxgsxHrcuGGfn#Z$cw|wGrSMvyE z>RY#-HE=vQ=ci1_5Wh~eTdaH} z=iZDii{sOdwwp#|u8d?X*=64#WuZ&mc#D+oAKj1p-Y~`+#GPR8pywWcm(QqW$=mVI zsp+@|ud2~yvCla9rqTXD(F{X#MQa%&K)^Sg8NKNqh(FzM8 z;9R|dm=}dGt?p$7c!GBjVL`&dYiNw%^&|>r@d~LH=tjW-IcE1lcu5~^{whAzwHMk$ z&Rc^V-hpSB#9uV@yq%SYPdc-}qk zK7k|P!eJ}4#nw?9=~8HCZfYV5Y1feCp%cwcwLa^p)Ivus3~Vi=MU$B zqLVvhfLaRXsJ;u9vfL*+S&q{qOrr>AwgOr9JRs zHSqilp3C_BQo5JviI>S6{taH9r0_9#F<$kW-{+!boI68jUSk(~@IZUd2~|7P2j!7; z*P#5k%q`y@EY#=X@-{{*OGlRqoRR}j;KaHO$&Ih6?1}Fen%#Q$TvE}L84gi@kcnM5 z*lweH&|A-T)q6|5p8y3=bezWx@cdQK7kFBvwXe-jH%7PTs z{IHc7=ZjKbaS(ewKsYh2$XAnu-KeHI?zcwPBVM5_Ny&F=ePT+(;m;BRI=Wqmp@w!l~E_r)iwh01j;GOry0lOn|3JTGza5?xz!<@o|+?7~qK%W6-9 z{ak^yrIZ}@%BG@^iZ$c8AejQL#!TX5E@KUZl%2c`qb3fmeJ`r5*(HkXNYlH$E*&+z zEdH`}&D%%8nabyZcRsIZW4tlEOwEb+sIEH=fr#bigY`@SQD&9!tI}U+DmL9pqSb;K z$91VeJkau9!M=AJgRJBw>(jTqhFnJ?v#Qi-ELO%k+7%n_)N@YMkq}2m%!Se-;?Ihg zvHclvd$lw0k{75*HuE_12NDh&pW>z!c!=AMH69EfuLcG=077>a;H*Eat2t>XM5om8 zfY~b~)ilPd-D)OttCTNJK7jdGU}2Pe8Pp>qDgwZ;9`(pmTQZe<$pqe~Rp;Y~e7w^E zLMhMrm;+C9fKZC`{!aC>&64VSmXN1vDfIGW)VcFI*-|X|BJ0*sK#>oTw68#f>o((9 zN7N(s=D+3Int1b>d(_X9co|QBWQ=9#^2diA=ib z-?QsF(bdT4L_phpu>5-RhiBSSIjNCf3JGSFGBvicV`RU7R3LjKm>g2>k1vvwo{K#w z>%Omu$eC|mc`fy*K-gX1nb#c>z7^abDi>chF)Z69>ca#DDe0ww7{No@LaOH?n7pNY z2$Hwx;BzY5|M(Z4KBc>by=xD5HK;E?2l>;32SVjysV9)}=Z+zJ)ik5IT_ZH_HP){$JFvOY0a797qJUM9rw?#^owx(q?RM0Ne%JU9>3MsxG5g{;?vrwt8E5jH;5D2 zINz;Jm(Vcn=~n%Wb|l|4Nb%_vc%MBe^bUNaD{mG{tZQqNI4o`y$?qY%-{D7p$oR8v6-&KAmRMfLcV^Re_Kg}=w1TX9Y7m=qMz`m1 zW@0Z&*JVs)FkOUfR)gsxWKxg8ypqw7CXaq!M)H~RP8Y3by0vI^pP_i@?)sH{E#)_< z@^x+o4fF%lQ|&R&-}4DK&S<2ZH_m9>#OJaxNzZZA8H3>r-J3RhMTf9~6foqpncjk! z!XRm>^<3ZwMA}(-((MbR)xAcCJ^tYhwo)317t9Z-wcDQE-IpKpk@RKXJ1j%DQl(mt zv+vX2msa@x3O{RQ^_Sm|l=lMHFfPRZM@yg0l~no9Kk&(^+~lkWQWEyh$R0aBUlSC2 z1p5k5WnoB-W(rG%*Iq>*MD)tik35~d8p!|7Q}{bB74dV#Qh&z>6rJuA4arn(wXWxp zJ5TM2fFOL!yRXXLyZ%A>5#tfXb~%YC2mXkuau<;^DdO0??IOPH?qAkYF5fSu6ZS5| ztgQ+=dL<;O&vIAzSStPfgRO+(jzDHV~W!NHL>|6J$BA*CPih3DZ_my_iO2Q|-0 z?lEc88AtOzfx>}T!E;rQ{;>K$efWKLJ9{MGpEo*n`{;AFr@bStYo0u{ z4qM=zgIB!u5z4XT(VrB8!ME#4kp1eAl+DV^jz8B5>y`IJrjD;r(i!8*cQP8{gy%Zn zktT@!LBx!fv+18yj*j*O$@9X-`qIMe9DIaUy*XHSw*$4*BkO9l@wloI40QM1(+hb5 zVYe%xvZ2u4v2c9R1D{{+-;-bcKI=)bO!Vxz{kK-^7JTtpZojjh8S{IT|1vxh@!nmZ z3y<4hMG9ZtU&g6Y+Wio;(yq+-p>lr?q~yTi&{1~WP81pwd>r%qi5}zmW%#!LFYo0* zqi*=K`f16;C(60vT;-f4`9^ADBZ*_cwRpKX?-f`ksUg0GYlcO-j)7+l=0SWmR4xhD zrmbygRYioecD%0k;pQN8&!yH4lh{ya!tcU~Tf^_ld!5~{uxB&bt_UwF%Zar>*$t9A zV0O=kFA`%ZY4_3fXt8SL(jlP}$o*}_Jv_`gJ)gcqOT0&`e&k79|_ z&ADGvy|0}pVG>{T*XmB0!(j!PRBR zqC#+p{4t9T{#JVCO7fGdympzpdk+p~V&w+~eaV*54nFc^cX2%N5ryO$HbYAbb$=5Y z=`uaAHNJD+PI@&L&Etw-Ygl@X#phk4u;T)6y^>cPuB1d5oWcwKNEjEm3L29!BzDF6 zwkG7({ZL`PFC9BZl{o`Yg)!kz*kfkG$MGN>ww@$KcaxH4*!qqs0w>8=BPiRW=Fo^a zzl`e9^*tt%Q8@pxHh###tp}6qW_Jy^a?$|Sx&tBY=^f-nnmB+E^=GJ&4DW8ykbfsC z>^Y|k)}rKclJtLOs5cwX#`pu$2yf@UFP&8V_K;wo4_Xxdp`mqAv!>8hV0|SKsXam( zfq;1>dx8gN3pfmKU0J!tHHp)s#n!>^R&&bX~y!W*?MKa;9S zL^W)^%wy9huAqQVj7L(YYBftu>L8RIH5w&6-G{ZoeQ&N%@7Kppjv8&l_B-|Z&?u_+ z{=HH2e&Luz7CDF4MUD1h`<-=0>T%1N$p=)Sk7E5R+JZ*d=REKe(OJF1zmHR{{6dha z!>CvQCN=~>vg^6nH&x2S_~*JYGHN7MuUZx4LN%)GCcdO?1z&ghsDXTVzjOhN37qoJ z#;&0F8RNpN_@9PFX3U#>24#s6C#Al3#{8gmZ<042MdVkNMa>zdqPKs0O&R672Hfzy z0R$3_M=LR>G-xz(7RjVw{`mg@VBR#oN7@IHtx=3rWe|c39a9t^!!*!K*`cL6)QrIIoL9cJ_ahOq(E8FFT=$si> znGSyY99CF|9&izrGuAR=6|>pZ3zZUSHts&z>ks-3S*^=RA`hQAKk9!UGnl#T4Qgz? zNB+t`-M<%u6`ZFv{!e?JtZNPb-)6^u@eP^Jqw=%gCSev<*N!!uV^=Jf>uno&(Eu*s z$GRs5t8R#zeS(tnGJa)x|Ll=S0kWA<%Zr4?4d0Vqf9G)0#N!T?Ja{A)ls+JNTv=Q{ z-k&`9dAuMwrqnNbHM35vounV@SgH6z$2T3kP$>4cv58n|`v(NpHt=c7SpN||aqz9y z20YEZtm_k{G1AV(`cn+TcEV~P)q2S$5}Ob)FBU7p1<{(FZW>xS&W&))mYI_Pp3#!& z{yt@uGVVC*@OROlVXK5AOq1Lumld~E`472lcG_C0j4j$H*2}j^(&>v;B1cSG9lv+y zxs!Kx<}BS6ECD6;py0^#XVZJSA^{m2cVVfvw*Bm2*O-=qGWyZfk#XvYobx-utjfKO z2mf38O7Ca}z3HfI(LeP-vVVl|%SSFfy7G5=z4%e*G$|9l!))->YmREC60q)b_~LrW zSDRB_p4wAk+it(i`xNJp?wrBX9%bc?Em={fQ~zRa{Pr^dCG#am|6-6C%@tB^M)$D- zXVXTKVYlT9EQ=(zHEsC0vm0K}oqp?rCW`UoYKwXFm@P@%&yS2eRz$8P7MoJ<2%|;@^EtN7JWJ!?QkzItSGw0B>VZ3(F@v%3mQXyIFDEGl?0aL0t zPO6Y(E-=SV%2>C+266=0h8%jIG?CP?sE`@t@Ymi=eu@|5yZ*w_zT`W2$bN{-z)t^R z>cuuL=K*mv&v^3p6D|HB8@9_wVCxQ@frjsbiqi-9!p0t$&b)m-UzzU;jvY9KNY4SC z@e_Sr!&{X5C6V2~WURnjS+zNrm98rmiX`Wj`eJ*6=D31C`+NnySV4;9t~?!#&(?82 zD`cH);I2&W`jX9$Dpz7~jB4Qxc8oqM`JrbLKc{~P<<4AoxcDfg?bb4lbOsVI9u(HD z0#f^9WO-1n5SfwUbK!WgsQXT>5*pq%yi@I8UL0RKd}64sE(z(+S~N!WNf6u z|AG1>g>!4A+pH6LD>feXJ2}(9PS9t@TjehxC{cj52AT}`RSFpi?u7^_l0A_{rH541 zG0onK_i`3L{|ZV%`{I!KxF91m>hTBo(K2cNVx=zk8*2TF)L_jmsq~gni4UG}>>MFP zSfS1Aqt@Ls5&8+Qn0>Bbs>jDNV?VH7XZtJLIf^-5bojS3QcU)aR<+(5d+CPTNqna* z>pLpha4m^p)^*(9J>L{PPj(r%@u?6ejvTI03-5=4V7_}D6~AD$j-I@_ke*t99g0N| z4`0#V6jKrpV-MloJWhgea>q`1T>o4iCzPX8-Ipn6bh)&qr9bBFmzdhI{7fVTN1r5% zcwv;B+{g@{9!pYMrVN1emH!c0vBB+0R-nF6F)lZcZPY}x6|wxI7&!sL$I z>jZC}u2cDyiNtYX7|lgKUpG95>lb?kPWaeuEf%*%_dJK3c_65l*C*6773vjZtP}2kH22*GRARA6G+@75hr{KJzsK2+O`N|G=f@4h_GFX8mbDriZ}m{vp0c{s=WTVlMo~*dIJK|*49{K8(OuXsEMFv$PCQX ziBc8iuTrVel-3P(22fdonStD1Mro`4(^f0pl(x3TS`{}4iwRN}#I;)MQY-hGR&Xhs zO5X49dG1Um0se2_x1UPp-utZQInQ~{InP<(NB<~JMerTdyFI-QBM8!7sILm^Ye|BB zs-NdqxHT>2SKMa^aiEZ!+ijLMqkE`OtctzS<>xf^|Br>h@+sU&r_cNnGYK&TJvmMG zo{c_rje@^_u#I0jI{w68i~W08pjGw!X++Qin zZ^A^Vq~NdkEz}UPs-BHGjUN8*jTv>X#hv{I+}SOw!A2dgeh7eJ$iVgg<)(a^O5uKd zKM!D{8w~GZbjs^R?aJ3SyKz#QwJxIqRE408>pJR>#CWPt!XR3E&u_UKS6rDU8+;P3 z8dkuM<8_A)qB59caI1y3gqPvIOC8=D@_HTIXG*G_9{jzucR7QQK z&%K4hhMZC6OWj#D^ZzA7j<|QzGD=#USlbIHM2XR{s5j2P;6fIn=X^s?@DO|jOZAq& zj5T9U!MDs(WhigP>||tW6W*rJ91`C5&%7kO>z_G3PhV3t+!Xk)oGyLc*x+;OX9-ch zIA@<&C3yMI+{D^;uw+{34>s9yAM#wFZUsvLlk=%Sw9IQmv>q2`^bFtf8==WdALTDO zY7CEg1j~!ug~r-_PK=xTv_Je?s7O0wI$)4b7QDq!PfrcTh-#Ce=1GX}eQzqeO=^f@ z`fO@;&hLMGBXlIj-m@r}! z^g`YIJUpYFg?G{MKF{ezi}_N(f}S(3$)KX8J9+vvr+2@4-L)_;|38GTG*5Rnp+E^F ztmow&(HQ|v=-1E!E-F!!r89ZDWW}TU0?&{-NtE<}Q#py198l+N{`@|s_c#pw!vV+A zKcP_N)71L8c_X@+Kc`RVUC+?5b@_S)ls7OiD1R~E^5pF<$eX_t?9I;?()Pjl+?dBl z34W;Qm8v6h9&xHojt-lK3}cInE8$wB-dyZ0^SOweg~Ge2#a-i;CrDa?CLeWF6GYcu zkJ~uuVW0H>akS!lOn#CWTV5k7?8cR7eV}OQim8SjHsOo7YWvLgSX-+4D?46{D2OJ5 zqKEqo>FF4+LW$0D^EURGCt_FtS1DMeJ$iRM8);oLK05Y3D=B=aR&n)q4dF^Obtu|W zfvlGAtZy5IZrPnt7FFDyNfmCq5LBq69!*%DHcKuiPB78BuOC<-f{HY=4jq#64B zeh+Zo6zO^1F=QaN)U*% zH!~b4gB`^ze!WfF-(E!we%+eK6H(e_cXF?NuEp;>{!TCj>cO|WExxfp;)Hs)WpGZe zbKvvcc3-`n%JeRy*Fkl@zwkVNOM2zmUF<8HlaF@iLe#cLwnt<&^$Eq3b+^1s)tQs| zv4J0s@$TSZ6A!aaFKlwWKh4#1&`BjWVTMtP0|VWj#v;;vod7=m9dqyxA?Dh#`EeA^ znh7MsqhtT_IyPCxHUXUoH%cGm{nAn5cp6uNx!|wR7~~C3V>6LAMy*`7kycKlmBRkh z@XYqBQQL+4SF7J32x;WJc+MmnCsnNFk#l#*8I6G0%b7PcQR%1X^uHF_9wYu}=1dw*HvPVqa%beCSK_W2&9Y?YcGO@HI(|&En3l8I>)c}z zPXVn`?!?u!!#L2tqf$A9){JDshjBNW5B@1HDf{^Sa-Px!N0p6^OmaF>t(n9U5_WYC zhK1suNn;Vi7)*4)Ya7M4*w}k)T&~<#>7E1-sQ9d2P)U0KOWoO{G}m+f{eotR3@`uO zHsfz@_IRQYD=*K9DG!7O4ktF#a$>#xBt&?KFRn$TxgsT;;cGFLn|u=g#JI(IiTD7y z*FcYCZp@IbG3L9%C~X89 z2^D8LtA~!_=89NcyZ59H=gU87hlg$w#CS7D*matKAXdReX-eB%;*-sq3Xk4qjnx6GhKa43UXvOPPM-^7eGn}N;l;rECw zo{0(1IhvQ8#7QctX2?8}^mvOuZ40gZftQq{t9LIjAOMXzi69mHS)4ickBDyHqf9>a z7W|~KznVEcOuIERQP|_h%MSQ^C$crCm{!@}C?h4uXzA7E+}WZJj|cyuaRYz3y)7lY ze()t~6ll!>q{K4xQ|9c2Ev~m_i|?kk|BDNBzhm~d$qk?rT)UpS)OQokw$U`~&xb@=zBTb;lQE$j< z____~VN|`3^1HWUh!*xOniQ0Zr|g3z?1_NK$TmnmNgX!)UlmGNDP=WVC-jSV_dNHG2uzTa_T{{kRy_aRz2vm9XV%Qw zkDOLuvJL(k`9nFxx2zHx__wD;&o8UY@4GzSfgg+C0BwzQ<-TI%D{Y7?C?D)GyP<{p z(%+MMLa;MMG_{0^ykRy};eN{cb|#zNEnHEtOfZf3lvVi4Nw^g!fFxHv)h3YOOCTl$ zAkxM&?&C4<&zYC$Aq1B9LoFSFrE(WzXh4oP*E35-Y`-4inHxjM9#1>R^08=k-;cV9@~Hcb zil}=%n?4_|vyL+0(&v-5I8o3e51%7w0gzG@6KxW>-vZ zrh1v)87_CdxLiov&6m<`eDwrA2)At5&v1%))rSrE8Fy=?BL*I5PwdqLIW&wa|0_Up zasOc@U-yRk;i5C!9wdowP;^^>JgE})J@r|Ofa3XhVZ@n8MAYfa?BCxZ_tA!B^%&7fY2B$Xr0PU74F z;=-~|HQ5=Zt`TWi-JZdglPzR+`MyHp9!woe)J$4nD{nFqML@@dh#mRhHAIan!lGb0 zyVI6qxDN?-mJ4%VUnP+H3#ky?PoX8FH&X%)n$hg3t;^Mx*@3}*T!=lyX%5RcZ2pzz zFg6oj`8tpw@MI9_p%cVsH>$X2R|yf-&==K^5x&Ca6ohL@)ZI;ot28GS`gBI0LKje| zSU+QYV`njgUKfM9MoD_7n6!{(e2fypOZIKv>7;B)1FYm#2Sq_@PUA!Awe z0mZv|)caQTEQ>W_@TV=#gVp8K_qg##8K)gu}gx)m^U*sXrB{|uh>e}8%^suYJ z4<5tpeu);zkK|paQg`;AkKxSCxfAggibzMsF0|*a+_Mbt@uQ;SHsSrqG66$3M&0l3 zgY}>V&hXQW1`L(L_1yNGW;raZ$c+J>ZNYNm>FEV^Xm1U6K_0a8dZ%b!zty}7^4Q+r zFTf(T=X=3k*T4sJlO5)eFK+K|#qwQ&IqXq6N*!7l4-2ahsP8IVzz%=UmFz>scPM;^ z?|u3kdA|3~?TY3$0#KF&Uo;0UD01SRh41t2_rvtPEc~9o=jqXe%Jr+ze(!Cx;9tVQ zxOV|z`b;jLxO>02eWEIk>LYeWcC?pN2~odCjqPiyoa_RAU}Q?jwA!S1H3}jkg>4z- zWVtIZQR#9@XN+FXup$ycTi@&#O1<%XhQ<3OldjS!5Q?-t5^S@3za&&At5{T>CZ{1k zblcv1-jI?&9`pED_KA{q&H!3kuwL`(StKPr&ZsW#gg1_0Sl>~*y4T1Lr!d6Az)b4L zP^>nCEFPEU7MFAmoy^xCaNIa z1n-kO&@*2Iw*CV0KWQ}4M7BcHVA8v>3Xy$2i&VwH`MC(I(T*A=iY9q71Q3t+8~P*Z zQNN^&_|iO2q;);lYZ>mR)rWzM@aJMah}FBdlZ3Y3VJ4%hQk8v6<8U6lZiKpPR(d)U zCwhCss8OjoCg&NIUpv=UPEonjjG0D@;t_#3;arx3BE#u+d8Lzm2VBVO0mfWzTR5H; zx~eroAn0TjR~9W@WWgIk9CQ_$sgqr-2k#Cu?L2hLF9ZUu+oK)P3Mcz9^@`L9Bln?B zNFAJ)N;ChYx!!sOt51k{SxdgMmVA9G&Qqe(Z3Xfrv!UBU^7Vl`zI<y;1|HZ^9Wz2CW%4$Yy#4J1k>t62!DbQ)Uvy1m_TGOx0g zIgBe=1lD3jKLbgf-)1HJJGT}v>ETo9FS5P8fBLhiO-DJI&oJ`{kzWXSQ~H_B#3gE7 zdzv`D6R$YOuE!-*mYUQ;KClj+IwU9Bun|u7e;JK;+X&W02D;6R1vJ~pat1#yjML2F zJ1`D;`TV$0J}1&BQw(MFSx5&akYmEd6xfQ^W2mI~0M<{^Dz===;i`lbzy4^f-c4Gu zfJnSO^o$Ao8yGPoB%{D!%fA4yuTIm4i@7JU(5QXyF0EuZ7%^|WtPEeS%2 z=T%}!uSyot*>$W3mt>50OM!lG{r4x`MqrB=PJ?_{rSpGArZNy-{f^DaCJ=3pz}ZCj zm;7kX%8e-@oVfTBJDwB25ss&-XgntdbhMB0nDDq6h9h0m2MlPC9gshb;Urqum$g2o zeqk_l-D1YqMOakTU>CEag?n4RZVo9@$_RA+W$VxsF+2BlgHz?S=ntkja?9v@1PLPn zixjKtaBflDm0-AL#`yE?{jY7$&6(zgo8~^qH+T6Y645a*f7QP}>Gn(!bOUu3Jh$wk zy&j+iH(-q0bADrICb!1|{qNB?kzuD+Lx1;qWt`E^;ND#tREy@xV!LZYHPKf8yk^en zqgV#wrJPZv>(bnbbqvZT|EghB!TEFx|K~h-&f%UJn8_`^g_EKCEP(O$TFUG)zAmPH z%6*oQK7~Rzz+d~TDFgwv*buCv^b)pgJ-h6Ow1Kp98-J2cbXzdWv=kLe;s11BVQ*~R zsZp5sTl`9{Mx}ZiVuohdkA2rJN^AC=eg%(G1)B1x>EXn4)q}}gd3M()-6jr6@B;Py zbrXy7smikBMQN>-HrZI|;S_vzUrqJ)3H>Wl^Stva+)X=P*1qC$uc`37Cg>?3Tyk@0)$T-S00!pZH!&nk&lG(iC4TpDEW#AJ4*zpFoqaPY7o zvrqcK$o38p{T)_Z34Jn0Gaku`N5>x$7Vy6oEF;_F$_({Ce2edRg=&~haKSLSU6&Wu zQ0qSj<;9H@_FeKmF0bx;raYm!_C8aJ4uYW@-3#`iVTdyXbz|?z=f9(zoHkSB*fYt&K$keWx88Y#9?Wa@VM0~?lHtZ#3E<~N#B z=zsmeLi1Ky)xIri=e&G7Z#<^kkX=vs( z`7GjpXYOrs~s4% zwy1Nz6Uo&VY%JjtblJHm+?Uu`q6nJS*UqxDWEu^y3o)I16N|VgcgV644F*0_M1S?& zycSCieAfw(A5deJsVz&&U>Y6-o-8TbyH*tR=`I$b#`@hDQC4oBa6FE{5&@FjYZ$KM zO+YGgc>U?Sy4^L#lk9XSGn}`&)5++5C!dxgGB!+9lv@ww;Fh?cR)+!lFK>@DUe3?p zY})O??|74eqj!t=NZ6$8@Aw<{PG&1CxPa_0(kG9LH*G`JMuwBTQarWCM;-Wa-2G-{ z!W&a${3kBD&`*|L3P#dr-EEz6sEN zJMV&=rJrW|n2$0=bsPWY|AMbx`4iV>2hJYQOi2nxOs@J^dM2rE#G5@ zAw?W8Zjh6a;@?>`3e*~RAn`K~;O{|Bwg$nJxNGKW;MRfWYM`w_7Xwl6c9U!-;yI1p znIs|`viAo5DgLN^H*il{Ed<4#Hq#gxwF+u$i~k7ZfJ)h6q6A9yFWJZ;L6oJK=j0JL zZ^{|-u=qT$oLpNgo!mx72+PtOajx2+f1WMgc+JjLYnz=*Hs&{=3cSjTbqs_&5?8G0 zEcxE2%yw{nxrrqFnh-P0vGXjy*>U99iMn>)!75%^{2F(#lPv*W_y7)yc?0A|w5CEZ zzmcn*AtBYtI}%LP5YaL}XqhT$ne)Uu%)5p{zX%#<(Tyh9civ9!^LDbuQ_N3IGXk_y z&QrahobN0dWCxwmTLwrTE8#(QEm&b9(?oW>=1q+Dn;3W61|v-Mrx2~P zM#~=}aF?2!)a^X5Q48ta?&*R_5&pUXQ>$N=$Lz%hvkSusuY)7r$uaK~(ch!k6wFvx zGI@yiOkD}$xGb2#WlUeJj(PLSb$5Ia-RbUF`i7npq;Sr0eT?BTRD7>%tMUuYIv&)A)Ad6_4G^Ws8^M|&o1o9T5vcOW|2#A* zkNg%i!K;$DI%B&0#VzegsAs%LqnDS{yxR@-+>7- zp@AN(0k_VrDj~y+H@B*FKq;-T;UeDg96JQb7huk(eFj?q#oitl*!;RT0GHxx`3q<| zf3J?-3Q{QLkkjV!tDqLTHM}Oz>xJg%qZ!YjxYt+(m%xqBnOM==ymR?!=O&faJ?-S? zp)G+J7Bd$;D?Vlq`O~5#P;<{?@8|QU9b!f`hKrD4Z{TBWSdT*iUNP2ifTQuMh;Y5) z9Usk2>=qCKg?08Zm|mt#=CMHp<0^J5RhK z{*VMdZN5J222M!-^3Wnc}ki zd6nOK!PgjD0e&!N5qHxn?JC>VQXpm<85}kOtZ2mId%h7GUK*qsvb)Q6FJeLWJ++@Z z#|(D4YMavc3N4qAqjI$Fq*sY>6;JM$w)_gpE{|Y*Q8-|1$H8GnDMY>v?JP!Z>#kg- zbIot2G8I<_4Y)L!{YBoUC>b}R?uE6%mFA_z$MAj3{VUeDd_JQ#s9{eQ;NdmaXmrAU zdhidX;b6M~b%@UhqC_rd5CnfD_my+YPxSkYW1=J5UEbt|R=DRJ6LAT301?Jqf=wPA zU>azl%@X|Z+?TmjHrz5jXkiUI_sg>duc<4QQ*f^(dkKuTco-#>scy71xJ{s_ss!IM z6Ey9w5^3-Y&7v6ZCu}qgY~*Tr7`TI8N^e^1d*CMwcI&uqnyDVR$RBjrL0^ zj7=#$vPg{vw_w(r384-i3TWD$YW3xB(CU3=OkB8aV91)VhF3h{KT)dhgo9LGAIJ)a zSMNIAO}(iAiecP9JuwXcs=(dnu|;DG-Y=dH>m4a=hu%fqhT7m#2_J^>Nex5rvAm5J zp5Ivgpv|nMtgxbvr>Msdo%B8Ovb~Q?xG&jUO^U#S*m22-M(^rL_*E`()3^7zh{V`+ zw45)NGmnza*b4n22n_$?(@dU#m3rY${&TZC_fg{pm;j-Yx%4vby3l8JoMP3sJN#>2 zlz#fk<#I6?f%+@b5rxb2(tnmf^AU~cqq+Zp4lQ~3P)hMR(uB@zL{Yq88Es&IfVOar%wDV=d)_|%97e@a?KR#Wn!Q-fLyv{i zCUh+297=soz0Q&eG#je1i9S!hv&SHy1#cj3RtnbU#_|L5A9{Vo2o-Qbxd~b1WVdN> zeOW51s z6fJ$I&f^dzu=h8XP`zyx#pJ+I?cW4V{Q7tMDv3MGgb)RP1?ih`1po3rT@=#XMQu-g zHGjWIe0Vzo_HNhHhR)~jM+CV|kNkIt)!NH>(BerFM|`5NpDfq_ErfLc8wQy=0x6~o z^ildA_>XS?zTc3e<@=(iQ8y5MGqYk8ui#o5e4Zj^e0h4&t#p|vD`M{Bk#l3p@YedT zg2~}foKD>Ilm6F8z$1T?^po0}yUWr;2p86~1f6DA8WW|Mv+C2l$>?8!poo^WI&9hi zf15YLLlD~4SsKFIy`~&1yv~S-KZ2n(#It((2YJIHoU+#<#4`BV>c%&H9M`g+IvMHP zwI;`EO`>gAm3AFv&)dAeT^QfRB%9EMn19N{`&$(z2m%Uw_kTbs@fv<6n z0PLEEKj#c7Tdf~rM)8ALkf^)IuU^h_ENzD0Ggr}{b}hE+YT=LVx{WRNsXT;?Mz%sK zp6@xCpMu2W?sYO3@;B+7yuG16aiPD!gHe?e`$#*ugHV2n&^qf~hT%0R!h+n(lQ4zb z*VjAQe^7-apa&_pW;H*~spJ=7`1pBY6+bVkuHt9YD1KgAJxX~E69j;-k9k*Amq!-- zvwQWP9m-;Wnx#86JdvAI9Zxj9lyK)%b3b!kh5xIs?&5GNj|_aA!X+gOO464pCYJ(Q z?AX2@lLgro_}{!+n>t!uwY^~g>gG<~wT%4}1uIGQ&Z;@1pD;E2$-mG>$GBTjl)USR zzFYLMw&&vrmIcRw;;>^Du143Ws8uhBPCWn*Wg_F`W=x8bPH(|Goa6J&O=dp+CNUim z8e3M&d<=olic3jvT7|P{DG&wpy86go!DnJ874jiL(9A-}i?JSq54#Gfzco8s+fn7z zQx)x$6jYTRC4b^i75|M|31Sd&7)Ts1=QH_c)zC2KuGHL|xMk9H-~2icDpW4x$79GM zF{gS|!i69P{qy@buPzGYwh5oZ8lLdbF{p9!{xb z>6`J~^#r3(?`*ng#ZL31b<589$X%st+zrHTb=Qn;|1kc$U>lqUEq--nEoC0684`o-t9-o&Nc;kzw%k?RAfHDhW~i~c{BhD#rm6w@nny?yat2Xl~Z^}9E55Ml6H zjyYplNl7CH%9cTC&o$e8jP+grdskn?&`{Rg#tPm2CVgqgUpSsNiziW?lPLL|5B++?* z{^0T;Mfq^kk#goXi~>*>*2dj)_^+Yf8GNB$k|wwTgRUhM>ugY@3Q+0aCVfVMev2Zl zgl(ew8MQR4TF&4zYD~?{UDPoN@9yD;ch2Dw<$lJ`xYz$581BkalFYU6NU33~pU}7- zJCLv4n>0A0?l6^etLqg5>oZ1lChe&=pnHknkN^ei`Abs`qZ-{Y)xs6Fb_3%+2c(Nu z6Wx6xSQKZQxL_#idCZQdYQ{~o2PH{9`{VcyxQ?h$bSFbdC*x=~@;3^9r=ZvW4_ITO z^AGak2)GfWhWzx?HEtB;eKY&V>RfCh~hsF!W&{+y!7da zyDKvCiFn-}GasaMlCPY#hFOscv3nBAP1YrShVV0&Ccx7cf84*7^jU9DRJc-&w_d4F zAU|~acjhIPk~}v{H<3A6Wp1yP;Ht2d|(Az>!RFQPwG&@zbd zy8o2m=N%ef8am!ky|U3g&KPQ$a~nEdqZn_kwKyOAfT<*M$?AF>9J`H(5^g-%P9<9B zfWc07h<<~rjWEEv`m}tG?)+u6;Ez3OS9dVFpf>^P#FNSmlc=H%zL?JpG?mdy#IzZT|~=7g`Iw&7AxvkM6}WTmL4L ztDFdOdG}zlvL?Ox6@BTN_Fq$dIs8+Lj+r%E;P~f_@B{cg@cBj}>?F9=2}33xt<;0b z+%YY@ZrxCtSo6>F_|in_Q)IJmiICKO%|FVcrEkPb|H5^3WX->hAf{&I*-xZBxaAdQ zn()rEdCQx|moxg6@IftxVQ-yNioxft?OZ3hWx#m^H-6mgDQwyagF;zoD-EzKdYg|} z`6VuU(bVw~uW=~pe`;8g^~5qpkR6)T!PI?zt>yr)=Q!D=8b{r0PU|iFAe6YqlxX@W zzWS*r?f>E<2@t=tTmjnrT1l-6`{}yh{}9B1&P+Bt!+L!eUH#40dd7*OwXZdGv${xxXb~K> zGTAhJkTWvY!hcH=xmY)UmxV-h;fHJ+PNz1&!O4M|ip;4k!poxl4U#09o=BEHD^$r3 zxv}5XBg}|nUV5mLkzaKJ64yjP+=l9+J7(Dq{_lokm-Jyj*rG=C`{xnY*mT*q2~Gb&beh zy2e%H^aX9&l#=lkF*U3E>BiEHVt&u5 z_iJw^=k+vuPDENaw6wl6--yW3HipH}>f6$*!vJF7)5mi^$BR{FcKRAzK<9DZh#5`ZS~SVz)-?Hq1Q^J0KKP8*v{Rxi&#a z)!Y~-;epK00#wa^FOXJ?$=)On5QR<)SIi($V|Ay6zm=*!Q!AG)td^h|oQ;*H*EB$gof+{8*~MADmH<$nrjp>?x} z*ILEZErcRH7wgbT32)XE@ip}c_q^J8)3XW0ERJup$O(7W6g(PJ<1?F6r_ucgj=!FZ zui&>R2#fYl?)*tiUw%kyreH?UIdKYIqV|3g;9jEIJyjLQCE2tqkvoqQ6$6Dm{>@Zj zNH6oM)|eu0^>4JV9@mJ?aC8h_X@HDA2&FO4x2`o&U<5x+Mnx0hg;HTY=TGTs7kvpM zN))`@$-<6aZ@Kq{zLdqCR{_6!GqN%4>GKGR!D~$9tlTkB*ciMp!&t4EO{#*6H0gg7 z$QS!H0=(&e*njLE3b37QEr)c-2OP|+giF*>IO)N>4*7uXxHCxJpn|P;oIlM-`?5-<)HJZDeOXhVt1@prvTzI^7 zHpgaz$vsK}z%_4iq-`Xhp?ohE&_vRkR70fVits$bpo#Nze2o{!O;(KWW)9YDJ66|S zO7b?r1qoWWmMiRI>R5*8zP!diqIBJ}A4lr`<`4u|z(23DAy;1Q9ez{PyW*yDW9uS5 z8hXYtWlnt)AR|9d_qDEH@qMLXlYRz$u<)~d(r|bb&?Zwz@iqt)?7_vC~- z5z+(;E}<&U(+E9*oimV-9=+xshx(BH1wTnFQ8E_pz1Ch<^GrO1}_WmfyQ1OZ28LPr76K zc=L?4cwT(*AMPVWj`}2*p{;c=+Gl_Pqqiq=XVpi#zb|$JqV|14bJmxn=7CTvAjguD z`B37&`?|VrY)|xa67E?Q4D2AnaRfF}5E~kPU>mjw=akk>ezeh>RZ;KU*}>kwmB6Cw zO6xN(I@xJpOQX9(1Yv@37ld(&?r^;CtHsF za`LcNH8#!FDMq~S37ldxImOyjHzZ1TAPLouZcn&ry;U`bAmbi=%ii4Q>#Sglj4U%AXaMzwzQW4T;Y7m3o|3UiK8%kV~S2@C-u;yp&UoW znec`uy{`cN?Gr|0DE?=@HG1l%hOJ7+cw<>{>9 z&2Ga`+);+-uIX;BTjQLGdvwEa)<3Rbv)?A+?S@G0#LD!)BikpAE=v)w++=V1-4}@? z)}H<&K$HM_yLn6z^1aZ0W7xi$>gl6YeKguW$XT;2To06jsj&$7_`!`qs>pF3h)L+p z6@sUc$1c+hDg6d2V^n$N)m<<0K9QTpz1-jZ@}oo{t$%HeWKplyfZ`Z_v+?33jk#HI zv{&o|bAEwJs`eDa=a$4!6LH7JJBAQL6Zvfjl~fBbMF%8u(dtPAW>1}?>$%a1y2oCo zh_Wp`wn1$!e3g;&u*p0ezN^P;?6Cd-Kg#B zqp9n+uP;vxQqH!+QSVNp7`o?FlhJ<2kM@6(-bAiUz=hXo(`XZ(;77vCYBWi%s~7%G zAL_DpP(Kl0QI|D?TJ(KW@-~@wCtP+#R=waz9lbumLxZzGg?>uD_KkDvsEE7shc%$qc;`5gm79bQTz zaBqH<|L6kJe6)P~@I4?9vTNtWD)k;b%s*zGqs@Hn_1-Q!2wVuA!Y;hwju@ahvi`r7Ws3yBvVNoaZ$=}mL3*ndx`|SK$ zcGZ~Xx=k|=#+9qRnWzRgod~Q@F&#vA_3(F&)JOPM)%kHX)ZFCIIGVX?yNp%C^U`mA^z0QQ$@Mn z^XH36kGIue_r32Cgb*Pw_&i)n{yS@95ze%0Fz!u07x*j@~HPUb`NlEO-~yaS?Msgtj>!8WgBne(>K=z?z9 z$rSv(_ipzhozsQy=wU-aXb6{wTHgB&__nsQre>#Fl^M81&g8)pg;W!(jMJgz({$(zz+VbjPw-oT>Yfc+gF46B@gQ# zPJdCbS!4KTer+Ti5Ce~d!?{~xWMDc>@UtUsqDCNe zrG|w(8KE9CrM}18P*J!E+n%tC<4qUytMWY@Z|e#p;;!l%|hdJ}9zM ztb}ohjMuGmZdqywG7VYX>UHdq_VkxNo8bUd&IrC(tVk;cH+=T+gZa~c9HS<9(s%`zR|*8@QVR* z&w7~iz*(g&yZ1QRt7z&GVMYtujO;X?aQPjQ8XfV@M@mi|kQh6^CUul}+VzCc66Lyx zGNdn}2PxiYt~s*cjqcSLCYyfaxmjfqS9;q`{xw6up(d3&zoMhO3=LfPJ6cv6w$XO+ zaO!U;v6UqkVlR`bu3;4LNRu=k{D+6vb)*i~Af6eAsgXKom$kk%q?sWep>Y5@!Ud%I zMfwe(vk`SS3GU8f-J*wn6Gd8#;QET9e2_HT*7%nwZU}zqY%;n&zyrp@#(h~QIFT^I zJb(p1^24mwhvG>pgPvnlbJ#|>zYl&-( z`F&7p{ixE;`Vm7YDVB82a10m58QGv-Ygo0aiZ5}e@x#d2Syj$05$dr5HJH?Vd+4zV z7lo_)3ck*T`5e4U%J?TWr{E1ki?@+{Ie{h5uTnnROz}^0gnIGHb2~MJnJzw>H3h#phO<52Pv^$K?oMle- z5Pm!Y1WU}Vjn-ciuYC$f!3I7VI(|Na>#Q0nyQ-3Pe|m#S&pd3U`s7Jm&dekEu}MFs zGIK_z#q1t-xjz)1+O8%TSrz;pnjw3HwUM@2!@-{5F+f86nj#EXz0)H3EXFF_E> z8q9+?={WEDlibPETcCEj?!_}gG!Bk4AI$AQ`&QJ;zBP30qY(bZ^hqI7^ImBtuKy|i z-1G4R)zyu=&VLreBfybt^8LF8X#c<0So-gHQ;U$hF*mm~K_tIhp5!61;8W|ybSDp9 z|GF(!jrA-~QMbE$SezFLcTJ<5KIZUJ$+I@&U^$PJ=@ZDL!Rnsag@-h@L!@~bbCA2E z^&O|aeQP-nqguB(&I99WBWpycf2W{ zZpRj=dszQ>BtzrHG1JO1Obx4mF7b*r;@>N22s+25r+?;GbckCG&myf<-5Yk?x<-&q$dL=q z992?JBdx29u#%b&!utb`qgrRov>Iu>va&SYh|W{oB_tgGgYHc-5gOfC_XjHk@x#go z(n0c|-Qz4&9*BIqWR&Jfe8peV$UsJk+{fr7!}zdhBt@5#(S`|b;2(7G24eou7x5{d zyg@JnV8(jR@;ABF0)oOuz3pE-vM}B3XQ?eilOI~Tv3fL(lL+eyc2mSS6}-it=_Cb< zcsKuzZ;_4(-!3I~*g=ubg)NMg|3eK|iI|Sw9BEzHrg!i;KU&NWQSx6H(~DaV#7}*)90}(1d|I>aO?_WZ{ff&ML$qKpm6?!eg;?Bj~4!X zxAez+*U#Y0;_uc*MGdbd>8bISE>sbVf0wBuuk1ok=CyjFR#2+Odba119{Oc$Zu2Zw z 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%0DLc1BSU~sIw`HhE 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�fRDyAw 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 qM9` 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

d(4PV7ME_lQ9*#&_kmY0`)nDn3ZWV@jS#Gm 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 H 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%0DbUhnOXF0^VuF1wN!C^){>U5Q(3bm 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�=OBvuMxxPvzt9Pd+gl^4=6kzZi~yu{&`qmptm3< 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 z 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

+** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *winMutexAlloc(int iType){ + sqlite3_mutex *p; + + switch( iType ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->id = iType; +#ifdef SQLITE_DEBUG +#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC + p->trace = 1; +#endif +#endif +#if SQLITE_OS_WINRT + InitializeCriticalSectionEx(&p->mutex, 0, 0); +#else + InitializeCriticalSection(&p->mutex); +#endif + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &winMutex_staticMutexes[iType-2]; +#ifdef SQLITE_DEBUG +#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC + InterlockedCompareExchange(&p->trace, 1, 0); +#endif +#endif + break; + } + } + assert( p==0 || p->id==iType ); + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void winMutexFree(sqlite3_mutex *p){ + assert( p ); + assert( p->nRef==0 && p->owner==0 ); + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ + DeleteCriticalSection(&p->mutex); + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; +#endif + } +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void winMutexEnter(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif +#ifdef SQLITE_DEBUG + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); +#else + assert( p ); +#endif + assert( winMutex_isInit==1 ); + EnterCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 || p->owner==0 ); + p->owner = tid; + p->nRef++; + if( p->trace ){ + OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", + tid, p->id, p, p->trace, p->nRef)); + } +#endif +} + +static int winMutexTry(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif + int rc = SQLITE_BUSY; + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); + /* + ** The sqlite3_mutex_try() routine is very rarely used, and when it + ** is used it is merely an optimization. So it is OK for it to always + ** fail. + ** + ** The TryEnterCriticalSection() interface is only available on WinNT. + ** And some windows compilers complain if you try to use it without + ** first doing some #defines that prevent SQLite from building on Win98. + ** For that reason, we will omit this optimization for now. See + ** ticket #2685. + */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 + assert( winMutex_isInit==1 ); + assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); + if( winMutex_isNt<0 ){ + winMutex_isNt = sqlite3_win32_is_nt(); + } + assert( winMutex_isNt==0 || winMutex_isNt==1 ); + if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ +#ifdef SQLITE_DEBUG + p->owner = tid; + p->nRef++; +#endif + rc = SQLITE_OK; + } +#else + UNUSED_PARAMETER(p); +#endif +#ifdef SQLITE_DEBUG + if( p->trace ){ + OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", + tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void winMutexLeave(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif + assert( p ); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 ); + assert( p->owner==tid ); + p->nRef--; + if( p->nRef==0 ) p->owner = 0; + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif + assert( winMutex_isInit==1 ); + LeaveCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ){ + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", + tid, p->id, p, p->trace, p->nRef)); + } +#endif +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + winMutexInit, + winMutexEnd, + winMutexAlloc, + winMutexFree, + winMutexEnter, + winMutexTry, + winMutexLeave, +#ifdef SQLITE_DEBUG + winMutexHeld, + winMutexNotheld +#else + 0, + 0 +#endif + }; + return &sMutex; +} + +#endif /* SQLITE_MUTEX_W32 */ + +/************** End of mutex_w32.c *******************************************/ +/************** Begin file malloc.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** Memory allocation functions used throughout sqlite. +*/ +/* #include "sqliteInt.h" */ +/* #include */ + +/* +** Attempt to release up to n bytes of non-essential memory currently +** held by SQLite. An example of non-essential memory is memory used to +** cache database pages that are not currently in use. +*/ +SQLITE_API int sqlite3_release_memory(int n){ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + return sqlite3PcacheReleaseMemory(n); +#else + /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine + ** is a no-op returning zero if SQLite is not compiled with + ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ + UNUSED_PARAMETER(n); + return 0; +#endif +} + +/* +** Default value of the hard heap limit. 0 means "no limit". +*/ +#ifndef SQLITE_MAX_MEMORY +# define SQLITE_MAX_MEMORY 0 +#endif + +/* +** State information local to the memory allocation subsystem. +*/ +static SQLITE_WSD struct Mem0Global { + sqlite3_mutex *mutex; /* Mutex to serialize access */ + sqlite3_int64 alarmThreshold; /* The soft heap limit */ + sqlite3_int64 hardLimit; /* The hard upper bound on memory */ + + /* + ** True if heap is nearly "full" where "full" is defined by the + ** sqlite3_soft_heap_limit() setting. + */ + int nearlyFull; +} mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 }; + +#define mem0 GLOBAL(struct Mem0Global, mem0) + +/* +** Return the memory allocator mutex. sqlite3_status() needs it. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ + return mem0.mutex; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. It used to set an alarm callback +** that was invoked when memory usage grew too large. Now it is a +** no-op. +*/ +SQLITE_API int sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + (void)xCallback; + (void)pArg; + (void)iThreshold; + return SQLITE_OK; +} +#endif + +/* +** Set the soft heap-size limit for the library. An argument of +** zero disables the limit. A negative argument is a no-op used to +** obtain the return value. +** +** The return value is the value of the heap limit just before this +** interface was called. +** +** If the hard heap limit is enabled, then the soft heap limit cannot +** be disabled nor raised above the hard heap limit. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; + sqlite3_int64 excess; + sqlite3_int64 nUsed; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.alarmThreshold; + if( n<0 ){ + sqlite3_mutex_leave(mem0.mutex); + return priorLimit; + } + if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){ + n = mem0.hardLimit; + } + mem0.alarmThreshold = n; + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed); + sqlite3_mutex_leave(mem0.mutex); + excess = sqlite3_memory_used() - n; + if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); + return priorLimit; +} +SQLITE_API void sqlite3_soft_heap_limit(int n){ + if( n<0 ) n = 0; + sqlite3_soft_heap_limit64(n); +} + +/* +** Set the hard heap-size limit for the library. An argument of zero +** disables the hard heap limit. A negative argument is a no-op used +** to obtain the return value without affecting the hard heap limit. +** +** The return value is the value of the hard heap limit just prior to +** calling this interface. +** +** Setting the hard heap limit will also activate the soft heap limit +** and constrain the soft heap limit to be no more than the hard heap +** limit. +*/ +SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.hardLimit; + if( n>=0 ){ + mem0.hardLimit = n; + if( n0 ); + + /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal + ** implementation of malloc_good_size(), which must be called in debug + ** mode and specifically when the DMD "Dark Matter Detector" is enabled + ** or else a crash results. Hence, do not attempt to optimize out the + ** following xRoundup() call. */ + nFull = sqlite3GlobalConfig.m.xRoundup(n); + + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); + if( mem0.alarmThreshold>0 ){ + sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.alarmThreshold - nFull ){ + AtomicStore(&mem0.nearlyFull, 1); + sqlite3MallocAlarm(nFull); + if( mem0.hardLimit ){ + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.hardLimit - nFull ){ + *pp = 0; + return; + } + } + }else{ + AtomicStore(&mem0.nearlyFull, 0); + } + } + p = sqlite3GlobalConfig.m.xMalloc(nFull); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( p==0 && mem0.alarmThreshold>0 ){ + sqlite3MallocAlarm(nFull); + p = sqlite3GlobalConfig.m.xMalloc(nFull); + } +#endif + if( p ){ + nFull = sqlite3MallocSize(p); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); + } + *pp = p; +} + +/* +** Maximum size of any single memory allocation. +** +** This is not a limit on the total amount of memory used. This is +** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). +** +** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 +** This provides a 256-byte safety margin for defense against 32-bit +** signed integer overflow bugs when computing memory allocation sizes. +** Paranoid applications might want to reduce the maximum allocation size +** further for an even larger safety margin. 0x3fffffff or 0x0fffffff +** or even smaller would be reasonable upper bounds on the size of a memory +** allocations for most applications. +*/ +#ifndef SQLITE_MAX_ALLOCATION_SIZE +# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 +#endif +#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 +# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 +#endif + +/* +** Allocate memory. This routine is like sqlite3_malloc() except that it +** assumes the memory subsystem has already been initialized. +*/ +SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ + void *p; + if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){ + p = 0; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + mallocWithAlarm((int)n, &p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3GlobalConfig.m.xMalloc((int)n); + } + assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */ + return p; +} + +/* +** This version of the memory allocation is for use by the application. +** First make sure the memory subsystem is initialized, then do the +** allocation. +*/ +SQLITE_API void *sqlite3_malloc(int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return n<=0 ? 0 : sqlite3Malloc(n); +} +SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Malloc(n); +} + +/* +** TRUE if p is a lookaside memory allocation from db +*/ +#ifndef SQLITE_OMIT_LOOKASIDE +static int isLookaside(sqlite3 *db, const void *p){ + return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pTrueEnd); +} +#else +#define isLookaside(A,B) 0 +#endif + +/* +** Return the size of a memory allocation previously obtained from +** sqlite3Malloc() or sqlite3_malloc(). +*/ +SQLITE_PRIVATE int sqlite3MallocSize(const void *p){ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return sqlite3GlobalConfig.m.xSize((void*)p); +} +static int lookasideMallocSize(sqlite3 *db, const void *p){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + return plookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL; +#else + return db->lookaside.szTrue; +#endif +} +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ + assert( p!=0 ); +#ifdef SQLITE_DEBUG + if( db==0 ){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + }else if( !isLookaside(db,p) ){ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + } +#endif + if( db ){ + if( ((uptr)p)<(uptr)(db->lookaside.pTrueEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + assert( sqlite3_mutex_held(db->mutex) ); + return LOOKASIDE_SMALL; + } +#endif + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + assert( sqlite3_mutex_held(db->mutex) ); + return db->lookaside.szTrue; + } + } + } + return sqlite3GlobalConfig.m.xSize((void*)p); +} +SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return p ? sqlite3GlobalConfig.m.xSize(p) : 0; +} + +/* +** Free memory previously obtained from sqlite3Malloc(). +*/ +SQLITE_API void sqlite3_free(void *p){ + if( p==0 ) return; /* IMP: R-49053-54554 */ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3GlobalConfig.m.xFree(p); + } +} + +/* +** Add the size of memory allocation "p" to the count in +** *db->pnBytesFreed. +*/ +static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ + *db->pnBytesFreed += sqlite3DbMallocSize(db,p); +} + +/* +** Free memory that might be associated with a particular database +** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op. +** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL. +*/ +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + assert( p!=0 ); + if( db ){ + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = pBuf; + return; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + return; + } + } + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } + } + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); +} +SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3 *db, void *p){ + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( p!=0 ); + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = pBuf; + return; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + return; + } + } + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); +} +SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p ) sqlite3DbFreeNN(db, p); +} + +/* +** Change the size of an existing memory allocation +*/ +SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ + int nOld, nNew, nDiff; + void *pNew; + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); + if( pOld==0 ){ + return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ + } + if( nBytes==0 ){ + sqlite3_free(pOld); /* IMP: R-26507-47431 */ + return 0; + } + if( nBytes>=0x7fffff00 ){ + /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ + return 0; + } + nOld = sqlite3MallocSize(pOld); + /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second + ** argument to xRealloc is always a value returned by a prior call to + ** xRoundup. */ + nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); + if( nOld==nNew ){ + pNew = pOld; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_int64 nUsed; + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); + nDiff = nNew - nOld; + if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >= + mem0.alarmThreshold-nDiff ){ + sqlite3MallocAlarm(nDiff); + if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ + sqlite3_mutex_leave(mem0.mutex); + return 0; + } + } + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( pNew==0 && mem0.alarmThreshold>0 ){ + sqlite3MallocAlarm((int)nBytes); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } +#endif + if( pNew ){ + nNew = sqlite3MallocSize(pNew); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); + } + sqlite3_mutex_leave(mem0.mutex); + }else{ + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */ + return pNew; +} + +/* +** The public interface to sqlite3Realloc. Make sure that the memory +** subsystem is initialized prior to invoking sqliteRealloc. +*/ +SQLITE_API void *sqlite3_realloc(void *pOld, int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + if( n<0 ) n = 0; /* IMP: R-26507-47431 */ + return sqlite3Realloc(pOld, n); +} +SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Realloc(pOld, n); +} + + +/* +** Allocate and zero memory. +*/ +SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){ + void *p = sqlite3Malloc(n); + if( p ){ + memset(p, 0, (size_t)n); + } + return p; +} + +/* +** Allocate and zero memory. If the allocation fails, make +** the mallocFailed flag in the connection pointer. +*/ +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ + void *p; + testcase( db==0 ); + p = sqlite3DbMallocRaw(db, n); + if( p ) memset(p, 0, (size_t)n); + return p; +} + + +/* Finish the work of sqlite3DbMallocRawNN for the unusual and +** slower case when the allocation cannot be fulfilled using lookaside. +*/ +static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ + void *p; + assert( db!=0 ); + p = sqlite3Malloc(n); + if( !p ) sqlite3OomFault(db); + sqlite3MemdebugSetType(p, + (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); + return p; +} + +/* +** Allocate memory, either lookaside (if possible) or heap. +** If the allocation fails, set the mallocFailed flag in +** the connection pointer. +** +** If db!=0 and db->mallocFailed is true (indicating a prior malloc +** failure on the same database connection) then always return 0. +** Hence for a particular database connection, once malloc starts +** failing, it fails consistently until mallocFailed is reset. +** This is an important assumption. There are many places in the +** code that do things like this: +** +** int *a = (int*)sqlite3DbMallocRaw(db, 100); +** int *b = (int*)sqlite3DbMallocRaw(db, 200); +** if( b ) a[10] = 9; +** +** In other words, if a subsequent malloc (ex: "b") worked, it is assumed +** that all prior mallocs (ex: "a") worked too. +** +** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is +** not a NULL pointer. +*/ +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ + void *p; + if( db ) return sqlite3DbMallocRawNN(db, n); + p = sqlite3Malloc(n); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + return p; +} +SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ +#ifndef SQLITE_OMIT_LOOKASIDE + LookasideSlot *pBuf; + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( db->pnBytesFreed==0 ); + if( n>db->lookaside.sz ){ + if( !db->lookaside.bDisable ){ + db->lookaside.anStat[1]++; + }else if( db->mallocFailed ){ + return 0; + } + return dbMallocRawFinish(db, n); + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( n<=LOOKASIDE_SMALL ){ + if( (pBuf = db->lookaside.pSmallFree)!=0 ){ + db->lookaside.pSmallFree = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else if( (pBuf = db->lookaside.pSmallInit)!=0 ){ + db->lookaside.pSmallInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + } + } +#endif + if( (pBuf = db->lookaside.pFree)!=0 ){ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else if( (pBuf = db->lookaside.pInit)!=0 ){ + db->lookaside.pInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else{ + db->lookaside.anStat[2]++; + } +#else + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( db->pnBytesFreed==0 ); + if( db->mallocFailed ){ + return 0; + } +#endif + return dbMallocRawFinish(db, n); +} + +/* Forward declaration */ +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); + +/* +** Resize the block of memory pointed to by p to n bytes. If the +** resize fails, set the mallocFailed flag in the connection object. +*/ +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ + assert( db!=0 ); + if( p==0 ) return sqlite3DbMallocRawNN(db, n); + assert( sqlite3_mutex_held(db->mutex) ); + if( ((uptr)p)<(uptr)db->lookaside.pEnd ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){ + if( n<=LOOKASIDE_SMALL ) return p; + }else +#endif + if( ((uptr)p)>=(uptr)db->lookaside.pStart ){ + if( n<=db->lookaside.szTrue ) return p; + } + } + return dbReallocFinish(db, p, n); +} +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ + void *pNew = 0; + assert( db!=0 ); + assert( p!=0 ); + if( db->mallocFailed==0 ){ + if( isLookaside(db, p) ){ + pNew = sqlite3DbMallocRawNN(db, n); + if( pNew ){ + memcpy(pNew, p, lookasideMallocSize(db, p)); + sqlite3DbFree(db, p); + } + }else{ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + pNew = sqlite3Realloc(p, n); + if( !pNew ){ + sqlite3OomFault(db); + } + sqlite3MemdebugSetType(pNew, + (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + } + } + return pNew; +} + +/* +** Attempt to reallocate p. If the reallocation fails, then free p +** and set the mallocFailed flag in the database connection. +*/ +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){ + void *pNew; + pNew = sqlite3DbRealloc(db, p, n); + if( !pNew ){ + sqlite3DbFree(db, p); + } + return pNew; +} + +/* +** Make a copy of a string in memory obtained from sqliteMalloc(). These +** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This +** is because when memory debugging is turned on, these two functions are +** called via macros that record the current file and line number in the +** ThreadData structure. +*/ +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){ + char *zNew; + size_t n; + if( z==0 ){ + return 0; + } + n = strlen(z) + 1; + zNew = sqlite3DbMallocRaw(db, n); + if( zNew ){ + memcpy(zNew, z, n); + } + return zNew; +} +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ + char *zNew; + assert( db!=0 ); + assert( z!=0 || n==0 ); + assert( (n&0x7fffffff)==n ); + zNew = z ? sqlite3DbMallocRawNN(db, n+1) : 0; + if( zNew ){ + memcpy(zNew, z, (size_t)n); + zNew[n] = 0; + } + return zNew; +} + +/* +** The text between zStart and zEnd represents a phrase within a larger +** SQL statement. Make a copy of this phrase in space obtained form +** sqlite3DbMalloc(). Omit leading and trailing whitespace. +*/ +SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + int n; +#ifdef SQLITE_DEBUG + /* Because of the way the parser works, the span is guaranteed to contain + ** at least one non-space character */ + for(n=0; sqlite3Isspace(zStart[n]); n++){ assert( &zStart[n]mallocFailed, and also +** temporarily disable the lookaside memory allocator and interrupt +** any running VDBEs. +** +** Always return a NULL pointer so that this routine can be invoked using +** +** return sqlite3OomFault(db); +** +** and thereby avoid unnecessary stack frame allocations for the overwhelmingly +** common case where no OOM occurs. +*/ +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3 *db){ + if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ + db->mallocFailed = 1; + if( db->nVdbeExec>0 ){ + AtomicStore(&db->u1.isInterrupted, 1); + } + DisableLookaside; + if( db->pParse ){ + Parse *pParse; + sqlite3ErrorMsg(db->pParse, "out of memory"); + db->pParse->rc = SQLITE_NOMEM_BKPT; + for(pParse=db->pParse->pOuterParse; pParse; pParse = pParse->pOuterParse){ + pParse->nErr++; + pParse->rc = SQLITE_NOMEM; + } + } + } + return 0; +} + +/* +** This routine reactivates the memory allocator and clears the +** db->mallocFailed flag as necessary. +** +** The memory allocator is not restarted if there are running +** VDBEs. +*/ +SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ + if( db->mallocFailed && db->nVdbeExec==0 ){ + db->mallocFailed = 0; + AtomicStore(&db->u1.isInterrupted, 0); + assert( db->lookaside.bDisable>0 ); + EnableLookaside; + } +} + +/* +** Take actions at the end of an API call to deal with error codes. +*/ +static SQLITE_NOINLINE int apiHandleError(sqlite3 *db, int rc){ + if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomClear(db); + sqlite3Error(db, SQLITE_NOMEM); + return SQLITE_NOMEM_BKPT; + } + return rc & db->errMask; +} + +/* +** This function must be called before exiting any API function (i.e. +** returning control to the user) that has called sqlite3_malloc or +** sqlite3_realloc. +** +** The returned value is normally a copy of the second argument to this +** function. However, if a malloc() failure has occurred since the previous +** invocation SQLITE_NOMEM is returned instead. +** +** If an OOM as occurred, then the connection error-code (the value +** returned by sqlite3_errcode()) is set to SQLITE_NOMEM. +*/ +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ + /* If the db handle must hold the connection handle mutex here. + ** Otherwise the read (and possible write) of db->mallocFailed + ** is unsafe, as is the call to sqlite3Error(). + */ + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + if( db->mallocFailed || rc ){ + return apiHandleError(db, rc); + } + return 0; +} + +/************** End of malloc.c **********************************************/ +/************** Begin file printf.c ******************************************/ +/* +** The "printf" code that follows dates from the 1980's. It is in +** the public domain. +** +************************************************************************** +** +** This file contains code for a set of "printf"-like routines. These +** routines format strings much like the printf() from the standard C +** library, though the implementation here has enhancements to support +** SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ +#define etRADIX 0 /* non-decimal integer types. %x %o */ +#define etFLOAT 1 /* Floating point. %f */ +#define etEXP 2 /* Exponentional notation. %e and %E */ +#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ +#define etSIZE 4 /* Return number of characters processed so far. %n */ +#define etSTRING 5 /* Strings. %s */ +#define etDYNSTRING 6 /* Dynamically allocated strings. %z */ +#define etPERCENT 7 /* Percent symbol. %% */ +#define etCHARX 8 /* Characters. %c */ +/* The rest are extensions, not normally found in printf() */ +#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */ +#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '', + NULL pointers replaced by SQL NULL. %Q */ +#define etTOKEN 11 /* a pointer to a Token structure */ +#define etSRCITEM 12 /* a pointer to a SrcItem */ +#define etPOINTER 13 /* The %p conversion */ +#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ +#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ +#define etDECIMAL 16 /* %d or %u, but not %x, %o */ + +#define etINVALID 17 /* Any unrecognized conversion type */ + + +/* +** An "etByte" is an 8-bit unsigned value. +*/ +typedef unsigned char etByte; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct et_info { /* Information about each format field */ + char fmttype; /* The format field code letter */ + etByte base; /* The base for radix conversion */ + etByte flags; /* One or more of FLAG_ constants below */ + etByte type; /* Conversion paradigm */ + etByte charset; /* Offset into aDigits[] of the digits string */ + etByte prefix; /* Offset into aPrefix[] of the prefix string */ +} et_info; + +/* +** Allowed values for et_info.flags +*/ +#define FLAG_SIGNED 1 /* True if the value to convert is signed */ +#define FLAG_STRING 4 /* Allow infinite precision */ + + +/* +** The following table is searched linearly, so it is good to put the +** most frequently used conversion types first. +*/ +static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; +static const char aPrefix[] = "-x0\000X0"; +static const et_info fmtinfo[] = { + { 'd', 10, 1, etDECIMAL, 0, 0 }, + { 's', 0, 4, etSTRING, 0, 0 }, + { 'g', 0, 1, etGENERIC, 30, 0 }, + { 'z', 0, 4, etDYNSTRING, 0, 0 }, + { 'q', 0, 4, etSQLESCAPE, 0, 0 }, + { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, + { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, + { 'c', 0, 0, etCHARX, 0, 0 }, + { 'o', 8, 0, etRADIX, 0, 2 }, + { 'u', 10, 0, etDECIMAL, 0, 0 }, + { 'x', 16, 0, etRADIX, 16, 1 }, + { 'X', 16, 0, etRADIX, 0, 4 }, +#ifndef SQLITE_OMIT_FLOATING_POINT + { 'f', 0, 1, etFLOAT, 0, 0 }, + { 'e', 0, 1, etEXP, 30, 0 }, + { 'E', 0, 1, etEXP, 14, 0 }, + { 'G', 0, 1, etGENERIC, 14, 0 }, +#endif + { 'i', 10, 1, etDECIMAL, 0, 0 }, + { 'n', 0, 0, etSIZE, 0, 0 }, + { '%', 0, 0, etPERCENT, 0, 0 }, + { 'p', 16, 0, etPOINTER, 0, 1 }, + + /* All the rest are undocumented and are for internal use only */ + { 'T', 0, 0, etTOKEN, 0, 0 }, + { 'S', 0, 0, etSRCITEM, 0, 0 }, + { 'r', 10, 1, etORDINAL, 0, 0 }, +}; + +/* Notes: +** +** %S Takes a pointer to SrcItem. Shows name or database.name +** %!S Like %S but prefer the zName over the zAlias +*/ + +/* +** Set the StrAccum object to an error mode. +*/ +SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum *p, u8 eError){ + assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); + p->accError = eError; + if( p->mxAlloc ) sqlite3_str_reset(p); + if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError); +} + +/* +** Extra argument values from a PrintfArguments object +*/ +static sqlite3_int64 getIntArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return sqlite3_value_int64(p->apArg[p->nUsed++]); +} +static double getDoubleArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0.0; + return sqlite3_value_double(p->apArg[p->nUsed++]); +} +static char *getTextArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); +} + +/* +** Allocate memory for a temporary buffer needed for printf rendering. +** +** If the requested size of the temp buffer is larger than the size +** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error. +** Do the size check before the memory allocation to prevent rogue +** SQL from requesting large allocations using the precision or width +** field of the printf() function. +*/ +static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ + char *z; + if( pAccum->accError ) return 0; + if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){ + sqlite3StrAccumSetError(pAccum, SQLITE_TOOBIG); + return 0; + } + z = sqlite3DbMallocRaw(pAccum->db, n); + if( z==0 ){ + sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); + } + return z; +} + +/* +** On machines with a small stack size, you can redefine the +** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. +*/ +#ifndef SQLITE_PRINT_BUF_SIZE +# define SQLITE_PRINT_BUF_SIZE 70 +#endif +#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ + +/* +** Hard limit on the precision of floating-point conversions. +*/ +#ifndef SQLITE_PRINTF_PRECISION_LIMIT +# define SQLITE_FP_PRECISION_LIMIT 100000000 +#endif + +/* +** Render a string given by "fmt" into the StrAccum object. +*/ +SQLITE_API void sqlite3_str_vappendf( + sqlite3_str *pAccum, /* Accumulate results here */ + const char *fmt, /* Format string */ + va_list ap /* arguments */ +){ + int c; /* Next character in the format string */ + char *bufpt; /* Pointer to the conversion buffer */ + int precision; /* Precision of the current field */ + int length; /* Length of the field */ + int idx; /* A general purpose loop counter */ + int width; /* Width of the current field */ + etByte flag_leftjustify; /* True if "-" flag is present */ + etByte flag_prefix; /* '+' or ' ' or 0 for prefix */ + etByte flag_alternateform; /* True if "#" flag is present */ + etByte flag_altform2; /* True if "!" flag is present */ + etByte flag_zeropad; /* True if field width constant starts with zero */ + etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */ + etByte done; /* Loop termination flag */ + etByte cThousand; /* Thousands separator for %d and %u */ + etByte xtype = etINVALID; /* Conversion paradigm */ + u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + sqlite_uint64 longvalue; /* Value for integer types */ + double realvalue; /* Value for real types */ + const et_info *infop; /* Pointer to the appropriate info structure */ + char *zOut; /* Rendering buffer */ + int nOut; /* Size of the rendering buffer */ + char *zExtra = 0; /* Malloced memory used by some conversion */ + int exp, e2; /* exponent of real numbers */ + etByte flag_dp; /* True if decimal point should be shown */ + etByte flag_rtz; /* True if trailing zeros should be removed */ + + PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ + char buf[etBUFSIZE]; /* Conversion buffer */ + + /* pAccum never starts out with an empty buffer that was obtained from + ** malloc(). This precondition is required by the mprintf("%z...") + ** optimization. */ + assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); + + bufpt = 0; + if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){ + pArgList = va_arg(ap, PrintfArguments*); + bArgList = 1; + }else{ + bArgList = 0; + } + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + bufpt = (char *)fmt; +#if HAVE_STRCHRNUL + fmt = strchrnul(fmt, '%'); +#else + do{ fmt++; }while( *fmt && *fmt != '%' ); +#endif + sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); + if( *fmt==0 ) break; + } + if( (c=(*++fmt))==0 ){ + sqlite3_str_append(pAccum, "%", 1); + break; + } + /* Find out what flags are present */ + flag_leftjustify = flag_prefix = cThousand = + flag_alternateform = flag_altform2 = flag_zeropad = 0; + done = 0; + width = 0; + flag_long = 0; + precision = -1; + do{ + switch( c ){ + case '-': flag_leftjustify = 1; break; + case '+': flag_prefix = '+'; break; + case ' ': flag_prefix = ' '; break; + case '#': flag_alternateform = 1; break; + case '!': flag_altform2 = 1; break; + case '0': flag_zeropad = 1; break; + case ',': cThousand = ','; break; + default: done = 1; break; + case 'l': { + flag_long = 1; + c = *++fmt; + if( c=='l' ){ + c = *++fmt; + flag_long = 2; + } + done = 1; + break; + } + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': { + unsigned wx = c - '0'; + while( (c = *++fmt)>='0' && c<='9' ){ + wx = wx*10 + c - '0'; + } + testcase( wx>0x7fffffff ); + width = wx & 0x7fffffff; +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( c!='.' && c!='l' ){ + done = 1; + }else{ + fmt--; + } + break; + } + case '*': { + if( bArgList ){ + width = (int)getIntArg(pArgList); + }else{ + width = va_arg(ap,int); + } + if( width<0 ){ + flag_leftjustify = 1; + width = width >= -2147483647 ? -width : 0; + } +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( (c = fmt[1])!='.' && c!='l' ){ + c = *++fmt; + done = 1; + } + break; + } + case '.': { + c = *++fmt; + if( c=='*' ){ + if( bArgList ){ + precision = (int)getIntArg(pArgList); + }else{ + precision = va_arg(ap,int); + } + if( precision<0 ){ + precision = precision >= -2147483647 ? -precision : -1; + } + c = *++fmt; + }else{ + unsigned px = 0; + while( c>='0' && c<='9' ){ + px = px*10 + c - '0'; + c = *++fmt; + } + testcase( px>0x7fffffff ); + precision = px & 0x7fffffff; + } +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ + precision = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( c=='l' ){ + --fmt; + }else{ + done = 1; + } + break; + } + } + }while( !done && (c=(*++fmt))!=0 ); + + /* Fetch the info entry for the field */ + infop = &fmtinfo[0]; + xtype = etINVALID; + for(idx=0; idxtype; + break; + } + } + + /* + ** At this point, variables are initialized as follows: + ** + ** flag_alternateform TRUE if a '#' is present. + ** flag_altform2 TRUE if a '!' is present. + ** flag_prefix '+' or ' ' or zero + ** flag_leftjustify TRUE if a '-' is present or if the + ** field width was negative. + ** flag_zeropad TRUE if the width began with 0. + ** flag_long 1 for "l", 2 for "ll" + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + assert( width>=0 ); + assert( precision>=(-1) ); + switch( xtype ){ + case etPOINTER: + flag_long = sizeof(char*)==sizeof(i64) ? 2 : + sizeof(char*)==sizeof(long int) ? 1 : 0; + /* no break */ deliberate_fall_through + case etORDINAL: + case etRADIX: + cThousand = 0; + /* no break */ deliberate_fall_through + case etDECIMAL: + if( infop->flags & FLAG_SIGNED ){ + i64 v; + if( bArgList ){ + v = getIntArg(pArgList); + }else if( flag_long ){ + if( flag_long==2 ){ + v = va_arg(ap,i64) ; + }else{ + v = va_arg(ap,long int); + } + }else{ + v = va_arg(ap,int); + } + if( v<0 ){ + testcase( v==SMALLEST_INT64 ); + testcase( v==(-1) ); + longvalue = ~v; + longvalue++; + prefix = '-'; + }else{ + longvalue = v; + prefix = flag_prefix; + } + }else{ + if( bArgList ){ + longvalue = (u64)getIntArg(pArgList); + }else if( flag_long ){ + if( flag_long==2 ){ + longvalue = va_arg(ap,u64); + }else{ + longvalue = va_arg(ap,unsigned long int); + } + }else{ + longvalue = va_arg(ap,unsigned int); + } + prefix = 0; + } + if( longvalue==0 ) flag_alternateform = 0; + if( flag_zeropad && precision=4 || (longvalue/10)%10==1 ){ + x = 0; + } + *(--bufpt) = zOrd[x*2+1]; + *(--bufpt) = zOrd[x*2]; + } + { + const char *cset = &aDigits[infop->charset]; + u8 base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (int)(&zOut[nOut-1]-bufpt); + while( precision>length ){ + *(--bufpt) = '0'; /* Zero pad */ + length++; + } + if( cThousand ){ + int nn = (length - 1)/3; /* Number of "," to insert */ + int ix = (length - 1)%3 + 1; + bufpt -= nn; + for(idx=0; nn>0; idx++){ + bufpt[idx] = bufpt[idx+nn]; + ix--; + if( ix==0 ){ + bufpt[++idx] = cThousand; + nn--; + ix = 3; + } + } + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + const char *pre; + char x; + pre = &aPrefix[infop->prefix]; + for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + length = (int)(&zOut[nOut-1]-bufpt); + break; + case etFLOAT: + case etEXP: + case etGENERIC: { + FpDecode s; + int iRound; + int j; + + if( bArgList ){ + realvalue = getDoubleArg(pArgList); + }else{ + realvalue = va_arg(ap,double); + } + if( precision<0 ) precision = 6; /* Set default precision */ +#ifdef SQLITE_FP_PRECISION_LIMIT + if( precision>SQLITE_FP_PRECISION_LIMIT ){ + precision = SQLITE_FP_PRECISION_LIMIT; + } +#endif + if( xtype==etFLOAT ){ + iRound = -precision; + }else if( xtype==etGENERIC ){ + if( precision==0 ) precision = 1; + iRound = precision; + }else{ + iRound = precision+1; + } + sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16); + if( s.isSpecial ){ + if( s.isSpecial==2 ){ + bufpt = flag_zeropad ? "null" : "NaN"; + length = sqlite3Strlen30(bufpt); + break; + }else if( flag_zeropad ){ + s.z[0] = '9'; + s.iDP = 1000; + s.n = 1; + }else{ + memcpy(buf, "-Inf", 5); + bufpt = buf; + if( s.sign=='-' ){ + /* no-op */ + }else if( flag_prefix ){ + buf[0] = flag_prefix; + }else{ + bufpt++; + } + length = sqlite3Strlen30(bufpt); + break; + } + } + if( s.sign=='-' ){ + prefix = '-'; + }else{ + prefix = flag_prefix; + } + + exp = s.iDP-1; + if( xtype==etGENERIC && precision>0 ) precision--; + + /* + ** If the field type is etGENERIC, then convert to either etEXP + ** or etFLOAT, as appropriate. + */ + if( xtype==etGENERIC ){ + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = etEXP; + }else{ + precision = precision - exp; + xtype = etFLOAT; + } + }else{ + flag_rtz = flag_altform2; + } + if( xtype==etEXP ){ + e2 = 0; + }else{ + e2 = s.iDP - 1; + } + bufpt = buf; + { + i64 szBufNeeded; /* Size of a temporary buffer needed */ + szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; + if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; + if( szBufNeeded > etBUFSIZE ){ + bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); + if( bufpt==0 ) return; + } + } + zOut = bufpt; + flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; + /* The sign in front of the number */ + if( prefix ){ + *(bufpt++) = prefix; + } + /* Digits prior to the decimal point */ + j = 0; + if( e2<0 ){ + *(bufpt++) = '0'; + }else{ + for(; e2>=0; e2--){ + *(bufpt++) = j1 ) *(bufpt++) = ','; + } + } + /* The decimal point */ + if( flag_dp ){ + *(bufpt++) = '.'; + } + /* "0" digits after the decimal point but before the first + ** significant digit of the number */ + for(e2++; e2<0 && precision>0; precision--, e2++){ + *(bufpt++) = '0'; + } + /* Significant digits after the decimal point */ + while( (precision--)>0 ){ + *(bufpt++) = jzOut ); + if( bufpt[-1]=='.' ){ + if( flag_altform2 ){ + *(bufpt++) = '0'; + }else{ + *(--bufpt) = 0; + } + } + } + /* Add the "eNNN" suffix */ + if( xtype==etEXP ){ + exp = s.iDP - 1; + *(bufpt++) = aDigits[infop->charset]; + if( exp<0 ){ + *(bufpt++) = '-'; exp = -exp; + }else{ + *(bufpt++) = '+'; + } + if( exp>=100 ){ + *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ + exp %= 100; + } + *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ + *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ + } + *bufpt = 0; + + /* The converted number is in buf[] and zero terminated. Output it. + ** Note that the number is in the usual order, not reversed as with + ** integer conversions. */ + length = (int)(bufpt-zOut); + bufpt = zOut; + + /* Special case: Add leading zeros if the flag_zeropad flag is + ** set and we are not left justified */ + if( flag_zeropad && !flag_leftjustify && length < width){ + int i; + int nPad = width - length; + for(i=width; i>=nPad; i--){ + bufpt[i] = bufpt[i-nPad]; + } + i = prefix!=0; + while( nPad-- ) bufpt[i++] = '0'; + length = width; + } + break; + } + case etSIZE: + if( !bArgList ){ + *(va_arg(ap,int*)) = pAccum->nChar; + } + length = width = 0; + break; + case etPERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case etCHARX: + if( bArgList ){ + bufpt = getTextArg(pArgList); + length = 1; + if( bufpt ){ + buf[0] = c = *(bufpt++); + if( (c&0xc0)==0xc0 ){ + while( length<4 && (bufpt[0]&0xc0)==0x80 ){ + buf[length++] = *(bufpt++); + } + } + }else{ + buf[0] = 0; + } + }else{ + unsigned int ch = va_arg(ap,unsigned int); + if( ch<0x00080 ){ + buf[0] = ch & 0xff; + length = 1; + }else if( ch<0x00800 ){ + buf[0] = 0xc0 + (u8)((ch>>6)&0x1f); + buf[1] = 0x80 + (u8)(ch & 0x3f); + length = 2; + }else if( ch<0x10000 ){ + buf[0] = 0xe0 + (u8)((ch>>12)&0x0f); + buf[1] = 0x80 + (u8)((ch>>6) & 0x3f); + buf[2] = 0x80 + (u8)(ch & 0x3f); + length = 3; + }else{ + buf[0] = 0xf0 + (u8)((ch>>18) & 0x07); + buf[1] = 0x80 + (u8)((ch>>12) & 0x3f); + buf[2] = 0x80 + (u8)((ch>>6) & 0x3f); + buf[3] = 0x80 + (u8)(ch & 0x3f); + length = 4; + } + } + if( precision>1 ){ + i64 nPrior = 1; + width -= precision-1; + if( width>1 && !flag_leftjustify ){ + sqlite3_str_appendchar(pAccum, width-1, ' '); + width = 0; + } + sqlite3_str_append(pAccum, buf, length); + precision--; + while( precision > 1 ){ + i64 nCopyBytes; + if( nPrior > precision-1 ) nPrior = precision - 1; + nCopyBytes = length*nPrior; + if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){ + sqlite3StrAccumEnlarge(pAccum, nCopyBytes); + } + if( pAccum->accError ) break; + sqlite3_str_append(pAccum, + &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); + precision -= nPrior; + nPrior *= 2; + } + } + bufpt = buf; + flag_altform2 = 1; + goto adjust_width_for_utf8; + case etSTRING: + case etDYNSTRING: + if( bArgList ){ + bufpt = getTextArg(pArgList); + xtype = etSTRING; + }else{ + bufpt = va_arg(ap,char*); + } + if( bufpt==0 ){ + bufpt = ""; + }else if( xtype==etDYNSTRING ){ + if( pAccum->nChar==0 + && pAccum->mxAlloc + && width==0 + && precision<0 + && pAccum->accError==0 + ){ + /* Special optimization for sqlite3_mprintf("%z..."): + ** Extend an existing memory allocation rather than creating + ** a new one. */ + assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); + pAccum->zText = bufpt; + pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt); + pAccum->nChar = 0x7fffffff & (int)strlen(bufpt); + pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED; + length = 0; + break; + } + zExtra = bufpt; + } + if( precision>=0 ){ + if( flag_altform2 ){ + /* Set length to the number of bytes needed in order to display + ** precision characters */ + unsigned char *z = (unsigned char*)bufpt; + while( precision-- > 0 && z[0] ){ + SQLITE_SKIP_UTF8(z); + } + length = (int)(z - (unsigned char*)bufpt); + }else{ + for(length=0; length0 ){ + /* Adjust width to account for extra bytes in UTF-8 characters */ + int ii = length - 1; + while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; + } + break; + case etSQLESCAPE: /* %q: Escape ' characters */ + case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ + case etSQLESCAPE3: { /* %w: Escape " characters */ + i64 i, j, k, n; + int needQuote, isnull; + char ch; + char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ + char *escarg; + + if( bArgList ){ + escarg = getTextArg(pArgList); + }else{ + escarg = va_arg(ap,char*); + } + isnull = escarg==0; + if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); + /* For %q, %Q, and %w, the precision is the number of bytes (or + ** characters if the ! flags is present) to use from the input. + ** Because of the extra quoting characters inserted, the number + ** of output characters may be larger than the precision. + */ + k = precision; + for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ + if( ch==q ) n++; + if( flag_altform2 && (ch&0xc0)==0xc0 ){ + while( (escarg[i+1]&0xc0)==0x80 ){ i++; } + } + } + needQuote = !isnull && xtype==etSQLESCAPE2; + n += i + 3; + if( n>etBUFSIZE ){ + bufpt = zExtra = printfTempBuf(pAccum, n); + if( bufpt==0 ) return; + }else{ + bufpt = buf; + } + j = 0; + if( needQuote ) bufpt[j++] = q; + k = i; + for(i=0; iprintfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; + if( flag_alternateform ){ + /* %#T means an Expr pointer that uses Expr.u.zToken */ + Expr *pExpr = va_arg(ap,Expr*); + if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){ + sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken); + sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr); + } + }else{ + /* %T means a Token pointer */ + Token *pToken = va_arg(ap, Token*); + assert( bArgList==0 ); + if( pToken && pToken->n ){ + sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + sqlite3RecordErrorByteOffset(pAccum->db, pToken->z); + } + } + length = width = 0; + break; + } + case etSRCITEM: { + SrcItem *pItem; + if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; + pItem = va_arg(ap, SrcItem*); + assert( bArgList==0 ); + if( pItem->zAlias && !flag_altform2 ){ + sqlite3_str_appendall(pAccum, pItem->zAlias); + }else if( pItem->zName ){ + if( pItem->zDatabase ){ + sqlite3_str_appendall(pAccum, pItem->zDatabase); + sqlite3_str_append(pAccum, ".", 1); + } + sqlite3_str_appendall(pAccum, pItem->zName); + }else if( pItem->zAlias ){ + sqlite3_str_appendall(pAccum, pItem->zAlias); + }else{ + Select *pSel = pItem->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_NestedFrom ){ + sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); + }else{ + sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); + } + } + length = width = 0; + break; + } + default: { + assert( xtype==etINVALID ); + return; + } + }/* End switch over the format type */ + /* + ** The text of the conversion is pointed to by "bufpt" and is + ** "length" characters long. The field width is "width". Do + ** the output. Both length and width are in bytes, not characters, + ** at this point. If the "!" flag was present on string conversions + ** indicating that width and precision should be expressed in characters, + ** then the values have been translated prior to reaching this point. + */ + width -= length; + if( width>0 ){ + if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + sqlite3_str_append(pAccum, bufpt, length); + if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + }else{ + sqlite3_str_append(pAccum, bufpt, length); + } + + if( zExtra ){ + sqlite3DbFree(pAccum->db, zExtra); + zExtra = 0; + } + }/* End for loop over the format string */ +} /* End of function */ + + +/* +** The z string points to the first character of a token that is +** associated with an error. If db does not already have an error +** byte offset recorded, try to compute the error byte offset for +** z and set the error byte offset in db. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){ + const Parse *pParse; + const char *zText; + const char *zEnd; + assert( z!=0 ); + if( NEVER(db==0) ) return; + if( db->errByteOffset!=(-2) ) return; + pParse = db->pParse; + if( NEVER(pParse==0) ) return; + zText =pParse->zTail; + if( NEVER(zText==0) ) return; + zEnd = &zText[strlen(zText)]; + if( SQLITE_WITHIN(z,zText,zEnd) ){ + db->errByteOffset = (int)(z-zText); + } +} + +/* +** If pExpr has a byte offset for the start of a token, record that as +** as the error offset. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ + while( pExpr + && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0) + ){ + pExpr = pExpr->pLeft; + } + if( pExpr==0 ) return; + db->errByteOffset = pExpr->w.iOfst; +} + +/* +** Enlarge the memory allocation on a StrAccum object so that it is +** able to accept at least N more bytes of text. +** +** Return the number of bytes of text that StrAccum is able to accept +** after the attempted enlargement. The value returned might be zero. +*/ +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){ + char *zNew; + assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ + if( p->accError ){ + testcase(p->accError==SQLITE_TOOBIG); + testcase(p->accError==SQLITE_NOMEM); + return 0; + } + if( p->mxAlloc==0 ){ + sqlite3StrAccumSetError(p, SQLITE_TOOBIG); + return p->nAlloc - p->nChar - 1; + }else{ + char *zOld = isMalloced(p) ? p->zText : 0; + i64 szNew = p->nChar + N + 1; + if( szNew+p->nChar<=p->mxAlloc ){ + /* Force exponential buffer size growth as long as it does not overflow, + ** to avoid having to call this routine too often */ + szNew += p->nChar; + } + if( szNew > p->mxAlloc ){ + sqlite3_str_reset(p); + sqlite3StrAccumSetError(p, SQLITE_TOOBIG); + return 0; + }else{ + p->nAlloc = (int)szNew; + } + if( p->db ){ + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); + }else{ + zNew = sqlite3Realloc(zOld, p->nAlloc); + } + if( zNew ){ + assert( p->zText!=0 || p->nChar==0 ); + if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); + p->zText = zNew; + p->nAlloc = sqlite3DbMallocSize(p->db, zNew); + p->printfFlags |= SQLITE_PRINTF_MALLOCED; + }else{ + sqlite3_str_reset(p); + sqlite3StrAccumSetError(p, SQLITE_NOMEM); + return 0; + } + } + assert( N>=0 && N<=0x7fffffff ); + return (int)N; +} + +/* +** Append N copies of character c to the given string buffer. +*/ +SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ + testcase( p->nChar + (i64)N > 0x7fffffff ); + if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ + return; + } + while( (N--)>0 ) p->zText[p->nChar++] = c; +} + +/* +** The StrAccum "p" is not large enough to accept N new bytes of z[]. +** So enlarge if first, then do the append. +** +** This is a helper routine to sqlite3_str_append() that does special-case +** work (enlarging the buffer) using tail recursion, so that the +** sqlite3_str_append() routine can use fast calling semantics. +*/ +static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ + N = sqlite3StrAccumEnlarge(p, N); + if( N>0 ){ + memcpy(&p->zText[p->nChar], z, N); + p->nChar += N; + } +} + +/* +** Append N bytes of text from z to the StrAccum object. Increase the +** size of the memory allocation for StrAccum if necessary. +*/ +SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){ + assert( z!=0 || N==0 ); + assert( p->zText!=0 || p->nChar==0 || p->accError ); + assert( N>=0 ); + assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 ); + if( p->nChar+N >= p->nAlloc ){ + enlargeAndAppend(p,z,N); + }else if( N ){ + assert( p->zText ); + p->nChar += N; + memcpy(&p->zText[p->nChar-N], z, N); + } +} + +/* +** Append the complete text of zero-terminated string z[] to the p string. +*/ +SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){ + sqlite3_str_append(p, z, sqlite3Strlen30(z)); +} + + +/* +** Finish off a string by making sure it is zero-terminated. +** Return a pointer to the resulting string. Return a NULL +** pointer if any kind of error was encountered. +*/ +static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ + char *zText; + assert( p->mxAlloc>0 && !isMalloced(p) ); + zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + if( zText ){ + memcpy(zText, p->zText, p->nChar+1); + p->printfFlags |= SQLITE_PRINTF_MALLOCED; + }else{ + sqlite3StrAccumSetError(p, SQLITE_NOMEM); + } + p->zText = zText; + return zText; +} +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ + if( p->zText ){ + p->zText[p->nChar] = 0; + if( p->mxAlloc>0 && !isMalloced(p) ){ + return strAccumFinishRealloc(p); + } + } + return p->zText; +} + +/* +** Use the content of the StrAccum passed as the second argument +** as the result of an SQL function. +*/ +SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context *pCtx, StrAccum *p){ + if( p->accError ){ + sqlite3_result_error_code(pCtx, p->accError); + sqlite3_str_reset(p); + }else if( isMalloced(p) ){ + sqlite3_result_text(pCtx, p->zText, p->nChar, SQLITE_DYNAMIC); + }else{ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + sqlite3_str_reset(p); + } +} + +/* +** This singleton is an sqlite3_str object that is returned if +** sqlite3_malloc() fails to provide space for a real one. This +** sqlite3_str object accepts no new text and always returns +** an SQLITE_NOMEM error. +*/ +static sqlite3_str sqlite3OomStr = { + 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 +}; + +/* Finalize a string created using sqlite3_str_new(). +*/ +SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){ + char *z; + if( p!=0 && p!=&sqlite3OomStr ){ + z = sqlite3StrAccumFinish(p); + sqlite3_free(p); + }else{ + z = 0; + } + return z; +} + +/* Return any error code associated with p */ +SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){ + return p ? p->accError : SQLITE_NOMEM; +} + +/* Return the current length of p in bytes */ +SQLITE_API int sqlite3_str_length(sqlite3_str *p){ + return p ? p->nChar : 0; +} + +/* Return the current value for p */ +SQLITE_API char *sqlite3_str_value(sqlite3_str *p){ + if( p==0 || p->nChar==0 ) return 0; + p->zText[p->nChar] = 0; + return p->zText; +} + +/* +** Reset an StrAccum string. Reclaim all malloced memory. +*/ +SQLITE_API void sqlite3_str_reset(StrAccum *p){ + if( isMalloced(p) ){ + sqlite3DbFree(p->db, p->zText); + p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; + } + p->nAlloc = 0; + p->nChar = 0; + p->zText = 0; +} + +/* +** Initialize a string accumulator. +** +** p: The accumulator to be initialized. +** db: Pointer to a database connection. May be NULL. Lookaside +** memory is used if not NULL. db->mallocFailed is set appropriately +** when not NULL. +** zBase: An initial buffer. May be NULL in which case the initial buffer +** is malloced. +** n: Size of zBase in bytes. If total space requirements never exceed +** n then no memory allocations ever occur. +** mx: Maximum number of bytes to accumulate. If mx==0 then no memory +** allocations will ever occur. +*/ +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ + p->zText = zBase; + p->db = db; + p->nAlloc = n; + p->mxAlloc = mx; + p->nChar = 0; + p->accError = 0; + p->printfFlags = 0; +} + +/* Allocate and initialize a new dynamic string object */ +SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){ + sqlite3_str *p = sqlite3_malloc64(sizeof(*p)); + if( p ){ + sqlite3StrAccumInit(p, 0, 0, 0, + db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); + }else{ + p = &sqlite3OomStr; + } + return p; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + assert( db!=0 ); + sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), + db->aLimit[SQLITE_LIMIT_LENGTH]); + acc.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + if( acc.accError==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } + return z; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc(). Omit the internal +** %-conversion extensions. +*/ +SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zFormat==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); + sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc()(). Omit the internal +** %-conversion extensions. +*/ +SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ + va_list ap; + char *z; +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + return z; +} + +/* +** sqlite3_snprintf() works like snprintf() except that it ignores the +** current locale settings. This is important for SQLite because we +** are not able to use a "," as the decimal point in place of "." as +** specified by some locales. +** +** Oops: The first two arguments of sqlite3_snprintf() are backwards +** from the snprintf() standard. Unfortunately, it is too late to change +** this without breaking compatibility, so we just have to live with the +** mistake. +** +** sqlite3_vsnprintf() is the varargs version. +*/ +SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ + StrAccum acc; + if( n<=0 ) return zBuf; +#ifdef SQLITE_ENABLE_API_ARMOR + if( zBuf==0 || zFormat==0 ) { + (void)SQLITE_MISUSE_BKPT; + if( zBuf ) zBuf[0] = 0; + return zBuf; + } +#endif + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); + sqlite3_str_vappendf(&acc, zFormat, ap); + zBuf[acc.nChar] = 0; + return zBuf; +} +SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ + StrAccum acc; + va_list ap; + if( n<=0 ) return zBuf; +#ifdef SQLITE_ENABLE_API_ARMOR + if( zBuf==0 || zFormat==0 ) { + (void)SQLITE_MISUSE_BKPT; + if( zBuf ) zBuf[0] = 0; + return zBuf; + } +#endif + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); + va_start(ap,zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + zBuf[acc.nChar] = 0; + return zBuf; +} + +/* +** This is the routine that actually formats the sqlite3_log() message. +** We house it in a separate routine from sqlite3_log() to avoid using +** stack space on small-stack systems when logging is disabled. +** +** sqlite3_log() must render into a static buffer. It cannot dynamically +** allocate memory because it might be called while the memory allocator +** mutex is held. +** +** sqlite3_str_vappendf() might ask for *temporary* memory allocations for +** certain format characters (%q) or for very large precisions or widths. +** Care must be taken that any sqlite3_log() calls that occur while the +** memory mutex is held do not use these mechanisms. +*/ +static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ + StrAccum acc; /* String accumulator */ + char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ + + sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); + sqlite3_str_vappendf(&acc, zFormat, ap); + sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, + sqlite3StrAccumFinish(&acc)); +} + +/* +** Format and write a message to the log if logging is enabled. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){ + va_list ap; /* Vararg list */ + if( sqlite3GlobalConfig.xLog ){ + va_start(ap, zFormat); + renderLogMsg(iErrCode, zFormat, ap); + va_end(ap); + } +} + +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) +/* +** A version of printf() that understands %lld. Used for debugging. +** The printf() built into some versions of windows does not understand %lld +** and segfaults if you give it a long long int. +*/ +SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ + va_list ap; + StrAccum acc; + char zBuf[SQLITE_PRINT_BUF_SIZE*10]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + va_start(ap,zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + sqlite3StrAccumFinish(&acc); +#ifdef SQLITE_OS_TRACE_PROC + { + extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf); + SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf)); + } +#else + fprintf(stdout,"%s", zBuf); + fflush(stdout); +#endif +} +#endif + + +/* +** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument +** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. +*/ +SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ + va_list ap; + va_start(ap,zFormat); + sqlite3_str_vappendf(p, zFormat, ap); + va_end(ap); +} + + +/***************************************************************************** +** Reference counted string/blob storage +*****************************************************************************/ + +/* +** Increase the reference count of the string by one. +** +** The input parameter is returned. +*/ +SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){ + RCStr *p = (RCStr*)z; + assert( p!=0 ); + p--; + p->nRCRef++; + return z; +} + +/* +** Decrease the reference count by one. Free the string when the +** reference count reaches zero. +*/ +SQLITE_PRIVATE void sqlite3RCStrUnref(void *z){ + RCStr *p = (RCStr*)z; + assert( p!=0 ); + p--; + assert( p->nRCRef>0 ); + if( p->nRCRef>=2 ){ + p->nRCRef--; + }else{ + sqlite3_free(p); + } +} + +/* +** Create a new string that is capable of holding N bytes of text, not counting +** the zero byte at the end. The string is uninitialized. +** +** The reference count is initially 1. Call sqlite3RCStrUnref() to free the +** newly allocated string. +** +** This routine returns 0 on an OOM. +*/ +SQLITE_PRIVATE char *sqlite3RCStrNew(u64 N){ + RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 ); + if( p==0 ) return 0; + p->nRCRef = 1; + return (char*)&p[1]; +} + +/* +** Change the size of the string so that it is able to hold N bytes. +** The string might be reallocated, so return the new allocation. +*/ +SQLITE_PRIVATE char *sqlite3RCStrResize(char *z, u64 N){ + RCStr *p = (RCStr*)z; + RCStr *pNew; + assert( p!=0 ); + p--; + assert( p->nRCRef==1 ); + pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1); + if( pNew==0 ){ + sqlite3_free(p); + return 0; + }else{ + return (char*)&pNew[1]; + } +} + +/************** End of printf.c **********************************************/ +/************** Begin file treeview.c ****************************************/ +/* +** 2015-06-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains C code to implement the TreeView debugging routines. +** These routines print a parse tree to standard output for debugging and +** analysis. +** +** The interfaces in this file is only available when compiling +** with SQLITE_DEBUG. +*/ +/* #include "sqliteInt.h" */ +#ifdef SQLITE_DEBUG + +/* +** Add a new subitem to the tree. The moreToFollow flag indicates that this +** is not the last item in the tree. +*/ +static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){ + TreeView *p = *pp; + if( p==0 ){ + *pp = p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return; + memset(p, 0, sizeof(*p)); + }else{ + p->iLevel++; + } + assert( moreToFollow==0 || moreToFollow==1 ); + if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow; +} + +/* +** Finished with one layer of the tree +*/ +static void sqlite3TreeViewPop(TreeView **pp){ + TreeView *p = *pp; + if( p==0 ) return; + p->iLevel--; + if( p->iLevel<0 ){ + sqlite3_free(p); + *pp = 0; + } +} + +/* +** Generate a single line of output for the tree, with a prefix that contains +** all the appropriate tree lines +*/ +SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ + va_list ap; + int i; + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + if( p ){ + for(i=0; iiLevel && i<(int)sizeof(p->bLine)-1; i++){ + sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); + } + sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); + } + if( zFormat!=0 ){ + va_start(ap, zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + assert( acc.nChar>0 || acc.accError ); + sqlite3_str_append(&acc, "\n", 1); + } + sqlite3StrAccumFinish(&acc); + fprintf(stdout,"%s", zBuf); + fflush(stdout); +} + +/* +** Shorthand for starting a new tree item that consists of a single label +*/ +static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ + sqlite3TreeViewPush(&p, moreFollows); + sqlite3TreeViewLine(p, "%s", zLabel); +} + +/* +** Show a list of Column objects in tree format. +*/ +SQLITE_PRIVATE void sqlite3TreeViewColumnList( + TreeView *pView, + const Column *aCol, + int nCol, + u8 moreToFollow +){ + int i; + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewLine(pView, "COLUMNS"); + for(i=0; inCte==0 ) return; + if( pWith->pOuter ){ + sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter); + }else{ + sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); + } + if( pWith->nCte>0 ){ + sqlite3TreeViewPush(&pView, moreToFollow); + for(i=0; inCte; i++){ + StrAccum x; + char zLine[1000]; + const struct Cte *pCte = &pWith->a[i]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3_str_appendf(&x, "%s", pCte->zName); + if( pCte->pCols && pCte->pCols->nExpr>0 ){ + char cSep = '('; + int j; + for(j=0; jpCols->nExpr; j++){ + sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName); + cSep = ','; + } + sqlite3_str_appendf(&x, ")"); + } + if( pCte->eM10d!=M10d_Any ){ + sqlite3_str_appendf(&x, " %sMATERIALIZED", + pCte->eM10d==M10d_No ? "NOT " : ""); + } + if( pCte->pUse ){ + sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, + pCte->pUse->nUse); + } + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inCte-1); + sqlite3TreeViewSelect(pView, pCte->pSelect, 0); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); + } +} + +/* +** Generate a human-readable description of a SrcList object. +*/ +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ + int i; + if( pSrc==0 ) return; + for(i=0; inSrc; i++){ + const SrcItem *pItem = &pSrc->a[i]; + StrAccum x; + int n = 0; + char zLine[1000]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + x.printfFlags |= SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); + if( pItem->pTab ){ + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", + pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); + } + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ + sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); + }else if( pItem->fg.jointype & JT_LEFT ){ + sqlite3_str_appendf(&x, " LEFT-JOIN"); + }else if( pItem->fg.jointype & JT_RIGHT ){ + sqlite3_str_appendf(&x, " RIGHT-JOIN"); + }else if( pItem->fg.jointype & JT_CROSS ){ + sqlite3_str_appendf(&x, " CROSS-JOIN"); + } + if( pItem->fg.jointype & JT_LTORJ ){ + sqlite3_str_appendf(&x, " LTORJ"); + } + if( pItem->fg.fromDDL ){ + sqlite3_str_appendf(&x, " DDL"); + } + if( pItem->fg.isCte ){ + sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + } + if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ + sqlite3_str_appendf(&x, " ON"); + } + if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); + if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); + if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); + if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); + if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); + if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); + + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inSrc-1); + n = 0; + if( pItem->pSelect ) n++; + if( pItem->fg.isTabFunc ) n++; + if( pItem->fg.isUsing ) n++; + if( pItem->fg.isUsing ){ + sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); + } + if( pItem->pSelect ){ + if( pItem->pTab ){ + Table *pTab = pItem->pTab; + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); + } + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); + } + if( pItem->fg.isTabFunc ){ + sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); + } + sqlite3TreeViewPop(&pView); + } +} + +/* +** Generate a human-readable description of a Select object. +*/ +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ + int n = 0; + int cnt = 0; + if( p==0 ){ + sqlite3TreeViewLine(pView, "nil-SELECT"); + return; + } + sqlite3TreeViewPush(&pView, moreToFollow); + if( p->pWith ){ + sqlite3TreeViewWith(pView, p->pWith, 1); + cnt = 1; + sqlite3TreeViewPush(&pView, 1); + } + do{ + if( p->selFlags & SF_WhereBegin ){ + sqlite3TreeViewLine(pView, "sqlite3WhereBegin()"); + }else{ + sqlite3TreeViewLine(pView, + "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", + ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), + ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), + p->selId, p, p->selFlags, + (int)p->nSelectRow + ); + } + if( cnt++ ) sqlite3TreeViewPop(&pView); + if( p->pPrior ){ + n = 1000; + }else{ + n = 0; + if( p->pSrc && p->pSrc->nSrc ) n++; + if( p->pWhere ) n++; + if( p->pGroupBy ) n++; + if( p->pHaving ) n++; + if( p->pOrderBy ) n++; + if( p->pLimit ) n++; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) n++; + if( p->pWinDefn ) n++; +#endif + } + if( p->pEList ){ + sqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set"); + } + n--; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + Window *pX; + sqlite3TreeViewPush(&pView, (n--)>0); + sqlite3TreeViewLine(pView, "window-functions"); + for(pX=p->pWin; pX; pX=pX->pNextWin){ + sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(&pView); + } +#endif + if( p->pSrc && p->pSrc->nSrc ){ + sqlite3TreeViewPush(&pView, (n--)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, p->pSrc); + sqlite3TreeViewPop(&pView); + } + if( p->pWhere ){ + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, p->pWhere, 0); + sqlite3TreeViewPop(&pView); + } + if( p->pGroupBy ){ + sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); + } + if( p->pHaving ){ + sqlite3TreeViewItem(pView, "HAVING", (n--)>0); + sqlite3TreeViewExpr(pView, p->pHaving, 0); + sqlite3TreeViewPop(&pView); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWinDefn ){ + Window *pX; + sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); + for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ + sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(&pView); + } +#endif + if( p->pOrderBy ){ + sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); + } + if( p->pLimit ){ + sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); + if( p->pLimit->pRight ){ + sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); + } + if( p->pPrior ){ + const char *zOp = "UNION"; + switch( p->op ){ + case TK_ALL: zOp = "UNION ALL"; break; + case TK_INTERSECT: zOp = "INTERSECT"; break; + case TK_EXCEPT: zOp = "EXCEPT"; break; + } + sqlite3TreeViewItem(pView, zOp, 1); + } + p = p->pPrior; + }while( p!=0 ); + sqlite3TreeViewPop(&pView); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a description of starting or stopping bounds +*/ +SQLITE_PRIVATE void sqlite3TreeViewBound( + TreeView *pView, /* View context */ + u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */ + Expr *pExpr, /* Value for PRECEDING or FOLLOWING */ + u8 moreToFollow /* True if more to follow */ +){ + switch( eBound ){ + case TK_UNBOUNDED: { + sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); + sqlite3TreeViewPop(&pView); + break; + } + case TK_CURRENT: { + sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); + sqlite3TreeViewPop(&pView); + break; + } + case TK_PRECEDING: { + sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(&pView); + break; + } + case TK_FOLLOWING: { + sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(&pView); + break; + } + } +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window object +*/ +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ + int nElement = 0; + if( pWin==0 ) return; + if( pWin->pFilter ){ + sqlite3TreeViewItem(pView, "FILTER", 1); + sqlite3TreeViewExpr(pView, pWin->pFilter, 0); + sqlite3TreeViewPop(&pView); + if( pWin->eFrmType==TK_FILTER ) return; + } + sqlite3TreeViewPush(&pView, more); + if( pWin->zName ){ + sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); + }else{ + sqlite3TreeViewLine(pView, "OVER (%p)", pWin); + } + if( pWin->zBase ) nElement++; + if( pWin->pOrderBy ) nElement++; + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ) nElement++; + if( pWin->eExclude ) nElement++; + if( pWin->zBase ){ + sqlite3TreeViewPush(&pView, (--nElement)>0); + sqlite3TreeViewLine(pView, "window: %s", pWin->zBase); + sqlite3TreeViewPop(&pView); + } + if( pWin->pPartition ){ + sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); + } + if( pWin->pOrderBy ){ + sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); + } + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ){ + char zBuf[30]; + const char *zFrmType = "ROWS"; + if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; + if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS"; + sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType, + pWin->bImplicitFrame ? " (implied)" : ""); + sqlite3TreeViewItem(pView, zBuf, (--nElement)>0); + sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); + sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); + sqlite3TreeViewPop(&pView); + } + if( pWin->eExclude ){ + char zBuf[30]; + const char *zExclude; + switch( pWin->eExclude ){ + case TK_NO: zExclude = "NO OTHERS"; break; + case TK_CURRENT: zExclude = "CURRENT ROW"; break; + case TK_GROUP: zExclude = "GROUP"; break; + case TK_TIES: zExclude = "TIES"; break; + default: + sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude); + zExclude = zBuf; + break; + } + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window Function object +*/ +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ + if( pWin==0 ) return; + sqlite3TreeViewPush(&pView, more); + sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", + pWin->pWFunc->zName, pWin->pWFunc->nArg); + sqlite3TreeViewWindow(pView, pWin, 0); + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** Generate a human-readable explanation of an expression tree. +*/ +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ + const char *zBinOp = 0; /* Binary operator */ + const char *zUniOp = 0; /* Unary operator */ + char zFlgs[200]; + sqlite3TreeViewPush(&pView, moreToFollow); + if( pExpr==0 ){ + sqlite3TreeViewLine(pView, "nil"); + sqlite3TreeViewPop(&pView); + return; + } + if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags || pExpr->pAggInfo ){ + StrAccum x; + sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); + sqlite3_str_appendf(&x, " fg.af=%x.%c", + pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); + if( ExprHasProperty(pExpr, EP_OuterON) ){ + sqlite3_str_appendf(&x, " outer.iJoin=%d", pExpr->w.iJoin); + } + if( ExprHasProperty(pExpr, EP_InnerON) ){ + sqlite3_str_appendf(&x, " inner.iJoin=%d", pExpr->w.iJoin); + } + if( ExprHasProperty(pExpr, EP_FromDDL) ){ + sqlite3_str_appendf(&x, " DDL"); + } + if( ExprHasVVAProperty(pExpr, EP_Immutable) ){ + sqlite3_str_appendf(&x, " IMMUTABLE"); + } + if( pExpr->pAggInfo!=0 ){ + sqlite3_str_appendf(&x, " agg-column[%d]", pExpr->iAgg); + } + sqlite3StrAccumFinish(&x); + }else{ + zFlgs[0] = 0; + } + switch( pExpr->op ){ + case TK_AGG_COLUMN: { + sqlite3TreeViewLine(pView, "AGG{%d:%d}%s", + pExpr->iTable, pExpr->iColumn, zFlgs); + break; + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + char zOp2[16]; + if( pExpr->op2 ){ + sqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2); + }else{ + zOp2[0] = 0; + } + sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", + pExpr->iColumn, zFlgs, zOp2); + }else{ + assert( ExprUseYTab(pExpr) ); + sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", + pExpr->iTable, pExpr->iColumn, + pExpr->y.pTab, zFlgs); + } + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } + break; + } + case TK_INTEGER: { + if( pExpr->flags & EP_IntValue ){ + sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue); + }else{ + sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken); + } + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); + break; + } + case TK_NULL: { + sqlite3TreeViewLine(pView,"NULL"); + break; + } + case TK_TRUEFALSE: { + sqlite3TreeViewLine(pView,"%s%s", + sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", + pExpr->u.zToken, pExpr->iColumn); + break; + } + case TK_REGISTER: { + sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); + break; + } + case TK_ID: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; + case TK_LE: zBinOp = "LE"; break; + case TK_GT: zBinOp = "GT"; break; + case TK_GE: zBinOp = "GE"; break; + case TK_NE: zBinOp = "NE"; break; + case TK_EQ: zBinOp = "EQ"; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "ISNOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "ADD"; break; + case TK_STAR: zBinOp = "MUL"; break; + case TK_MINUS: zBinOp = "SUB"; break; + case TK_REM: zBinOp = "REM"; break; + case TK_BITAND: zBinOp = "BITAND"; break; + case TK_BITOR: zBinOp = "BITOR"; break; + case TK_SLASH: zBinOp = "DIV"; break; + case TK_LSHIFT: zBinOp = "LSHIFT"; break; + case TK_RSHIFT: zBinOp = "RSHIFT"; break; + case TK_CONCAT: zBinOp = "CONCAT"; break; + case TK_DOT: zBinOp = "DOT"; break; + case TK_LIMIT: zBinOp = "LIMIT"; break; + + case TK_UMINUS: zUniOp = "UMINUS"; break; + case TK_UPLUS: zUniOp = "UPLUS"; break; + case TK_BITNOT: zUniOp = "BITNOT"; break; + case TK_NOT: zUniOp = "NOT"; break; + case TK_ISNULL: zUniOp = "ISNULL"; break; + case TK_NOTNULL: zUniOp = "NOTNULL"; break; + + case TK_TRUTH: { + int x; + const char *azOp[] = { + "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE" + }; + assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); + assert( pExpr->pRight ); + assert( sqlite3ExprSkipCollateAndLikely(pExpr->pRight)->op + == TK_TRUEFALSE ); + x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); + zUniOp = azOp[x]; + break; + } + + case TK_SPAN: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + + case TK_COLLATE: { + /* COLLATE operators without the EP_Collate flag are intended to + ** emulate collation associated with a table column. These show + ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE + ** operators that appear in the original SQL always have the + ** EP_Collate bit set and appear in treeview output as just "COLLATE" */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", + !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", + pExpr->u.zToken, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + + case TK_AGG_FUNCTION: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + Window *pWin; + if( ExprHasProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + pWin = 0; + }else{ + assert( ExprUseXList(pExpr) ); + pFarg = pExpr->x.pList; +#ifndef SQLITE_OMIT_WINDOWFUNC + pWin = IsWindowFunc(pExpr) ? pExpr->y.pWin : 0; +#else + pWin = 0; +#endif + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->op==TK_AGG_FUNCTION ){ + sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p", + pExpr->op2, pExpr->u.zToken, zFlgs, + pExpr->pAggInfo ? pExpr->pAggInfo->selId : 0, + pExpr->iAgg, pExpr->pAggInfo); + }else if( pExpr->op2!=0 ){ + const char *zOp2; + char zBuf[8]; + sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2); + zOp2 = zBuf; + if( pExpr->op2==NC_IsCheck ) zOp2 = "NC_IsCheck"; + if( pExpr->op2==NC_IdxExpr ) zOp2 = "NC_IdxExpr"; + if( pExpr->op2==NC_PartIdx ) zOp2 = "NC_PartIdx"; + if( pExpr->op2==NC_GenCol ) zOp2 = "NC_GenCol"; + sqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s", + pExpr->u.zToken, zFlgs, zOp2); + }else{ + sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); + } + if( pFarg ){ + sqlite3TreeViewExprList(pView, pFarg, pWin!=0 || pExpr->pLeft, 0); + if( pExpr->pLeft ){ + Expr *pOB = pExpr->pLeft; + assert( pOB->op==TK_ORDER ); + assert( ExprUseXList(pOB) ); + sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); + } + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + sqlite3TreeViewWindow(pView, pWin, 0); + } +#endif + break; + } + case TK_ORDER: { + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "ORDERBY"); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: { + assert( ExprUseXSelect(pExpr) ); + sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + break; + } + case TK_SELECT: { + assert( ExprUseXSelect(pExpr) ); + sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + break; + } + case TK_IN: { + sqlite3_str *pStr = sqlite3_str_new(0); + char *z; + sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags); + if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable); + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3_str_appendf(pStr, " subrtn(%d,%d)", + pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); + } + z = sqlite3_str_finish(pStr); + sqlite3TreeViewLine(pView, z); + sqlite3_free(z); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + if( ExprUseXSelect(pExpr) ){ + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + }else{ + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + } + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + const Expr *pX, *pY, *pZ; + pX = pExpr->pLeft; + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr==2 ); + pY = pExpr->x.pList->a[0].pExpr; + pZ = pExpr->x.pList->a[1].pExpr; + sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs); + sqlite3TreeViewExpr(pView, pX, 1); + sqlite3TreeViewExpr(pView, pY, 1); + sqlite3TreeViewExpr(pView, pZ, 0); + break; + } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + */ + sqlite3TreeViewLine(pView, "%s(%d)", + pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); + break; + } + case TK_CASE: { + sqlite3TreeViewLine(pView, "CASE"); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + assert( ExprUseXList(pExpr) ); + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + const char *zType = "unk"; + switch( pExpr->affExpr ){ + case OE_Rollback: zType = "rollback"; break; + case OE_Abort: zType = "abort"; break; + case OE_Fail: zType = "fail"; break; + case OE_Ignore: zType = "ignore"; break; + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + break; + } +#endif + case TK_MATCH: { + sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", + pExpr->iTable, pExpr->iColumn, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); + break; + } + case TK_VECTOR: { + char *z = sqlite3_mprintf("VECTOR%s",zFlgs); + assert( ExprUseXList(pExpr) ); + sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z); + sqlite3_free(z); + break; + } + case TK_SELECT_COLUMN: { + sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s", + pExpr->iColumn, pExpr->iTable-1, + pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : ""); + assert( ExprUseXSelect(pExpr->pLeft) ); + sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); + break; + } + case TK_IF_NULL_ROW: { + sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + case TK_ERROR: { + Expr tmp; + sqlite3TreeViewLine(pView, "ERROR"); + tmp = *pExpr; + tmp.op = pExpr->op2; + sqlite3TreeViewExpr(pView, &tmp, 0); + break; + } + case TK_ROW: { + if( pExpr->iColumn<=0 ){ + sqlite3TreeViewLine(pView, "First FROM table rowid"); + }else{ + sqlite3TreeViewLine(pView, "First FROM table column %d", + pExpr->iColumn-1); + } + break; + } + default: { + sqlite3TreeViewLine(pView, "op=%d", pExpr->op); + break; + } + } + if( zBinOp ){ + sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); + }else if( zUniOp ){ + sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } + sqlite3TreeViewPop(&pView); +} + + +/* +** Generate a human-readable explanation of an expression list. +*/ +SQLITE_PRIVATE void sqlite3TreeViewBareExprList( + TreeView *pView, + const ExprList *pList, + const char *zLabel +){ + if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; + if( pList==0 ){ + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); + }else{ + int i; + sqlite3TreeViewLine(pView, "%s", zLabel); + for(i=0; inExpr; i++){ + int j = pList->a[i].u.x.iOrderByCol; + char *zName = pList->a[i].zEName; + int moreToFollow = inExpr - 1; + if( j || zName ){ + sqlite3TreeViewPush(&pView, moreToFollow); + moreToFollow = 0; + sqlite3TreeViewLine(pView, 0); + if( zName ){ + switch( pList->a[i].fg.eEName ){ + default: + fprintf(stdout, "AS %s ", zName); + break; + case ENAME_TAB: + fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); + if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) "); + if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) "); + if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) "); + break; + case ENAME_SPAN: + fprintf(stdout, "SPAN(\"%s\") ", zName); + break; + } + } + if( j ){ + fprintf(stdout, "iOrderByCol=%d", j); + } + fprintf(stdout, "\n"); + fflush(stdout); + } + sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); + if( j || zName ){ + sqlite3TreeViewPop(&pView); + } + } + } +} +SQLITE_PRIVATE void sqlite3TreeViewExprList( + TreeView *pView, + const ExprList *pList, + u8 moreToFollow, + const char *zLabel +){ + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewBareExprList(pView, pList, zLabel); + sqlite3TreeViewPop(&pView); +} + +/* +** Generate a human-readable explanation of an id-list. +*/ +SQLITE_PRIVATE void sqlite3TreeViewBareIdList( + TreeView *pView, + const IdList *pList, + const char *zLabel +){ + if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; + if( pList==0 ){ + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); + }else{ + int i; + sqlite3TreeViewLine(pView, "%s", zLabel); + for(i=0; inId; i++){ + char *zName = pList->a[i].zName; + int moreToFollow = inId - 1; + if( zName==0 ) zName = "(null)"; + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewLine(pView, 0); + if( pList->eU4==EU4_NONE ){ + fprintf(stdout, "%s\n", zName); + }else if( pList->eU4==EU4_IDX ){ + fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx); + }else{ + assert( pList->eU4==EU4_EXPR ); + if( pList->a[i].u4.pExpr==0 ){ + fprintf(stdout, "%s (pExpr=NULL)\n", zName); + }else{ + fprintf(stdout, "%s\n", zName); + sqlite3TreeViewPush(&pView, inId-1); + sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0); + sqlite3TreeViewPop(&pView); + } + } + sqlite3TreeViewPop(&pView); + } + } +} +SQLITE_PRIVATE void sqlite3TreeViewIdList( + TreeView *pView, + const IdList *pList, + u8 moreToFollow, + const char *zLabel +){ + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewBareIdList(pView, pList, zLabel); + sqlite3TreeViewPop(&pView); +} + +/* +** Generate a human-readable explanation of a list of Upsert objects +*/ +SQLITE_PRIVATE void sqlite3TreeViewUpsert( + TreeView *pView, + const Upsert *pUpsert, + u8 moreToFollow +){ + if( pUpsert==0 ) return; + sqlite3TreeViewPush(&pView, moreToFollow); + while( pUpsert ){ + int n; + sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow); + sqlite3TreeViewLine(pView, "ON CONFLICT DO %s", + pUpsert->isDoUpdate ? "UPDATE" : "NOTHING"); + n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0); + sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET"); + sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET"); + if( pUpsert->pUpsertWhere ){ + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); + pUpsert = pUpsert->pNextUpsert; + } + sqlite3TreeViewPop(&pView); +} + +#if TREETRACE_ENABLED +/* +** Generate a human-readable diagram of the data structure that go +** into generating an DELETE statement. +*/ +SQLITE_PRIVATE void sqlite3TreeViewDelete( + const With *pWith, + const SrcList *pTabList, + const Expr *pWhere, + const ExprList *pOrderBy, + const Expr *pLimit, + const Trigger *pTrigger +){ + int n = 0; + TreeView *pView = 0; + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "DELETE"); + if( pWith ) n++; + if( pTabList ) n++; + if( pWhere ) n++; + if( pOrderBy ) n++; + if( pLimit ) n++; + if( pTrigger ) n++; + if( pWith ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(&pView); + } + if( pTabList ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(&pView); + } + if( pWhere ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "WHERE"); + sqlite3TreeViewExpr(pView, pWhere, 0); + sqlite3TreeViewPop(&pView); + } + if( pOrderBy ){ + sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); + } + if( pLimit ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "LIMIT"); + sqlite3TreeViewExpr(pView, pLimit, 0); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} +#endif /* TREETRACE_ENABLED */ + +#if TREETRACE_ENABLED +/* +** Generate a human-readable diagram of the data structure that go +** into generating an INSERT statement. +*/ +SQLITE_PRIVATE void sqlite3TreeViewInsert( + const With *pWith, + const SrcList *pTabList, + const IdList *pColumnList, + const Select *pSelect, + const ExprList *pExprList, + int onError, + const Upsert *pUpsert, + const Trigger *pTrigger +){ + TreeView *pView = 0; + int n = 0; + const char *zLabel = "INSERT"; + switch( onError ){ + case OE_Replace: zLabel = "REPLACE"; break; + case OE_Ignore: zLabel = "INSERT OR IGNORE"; break; + case OE_Rollback: zLabel = "INSERT OR ROLLBACK"; break; + case OE_Abort: zLabel = "INSERT OR ABORT"; break; + case OE_Fail: zLabel = "INSERT OR FAIL"; break; + } + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, zLabel); + if( pWith ) n++; + if( pTabList ) n++; + if( pColumnList ) n++; + if( pSelect ) n++; + if( pExprList ) n++; + if( pUpsert ) n++; + if( pTrigger ) n++; + if( pWith ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(&pView); + } + if( pTabList ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "INTO"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(&pView); + } + if( pColumnList ){ + sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS"); + } + if( pSelect ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "DATA-SOURCE"); + sqlite3TreeViewSelect(pView, pSelect, 0); + sqlite3TreeViewPop(&pView); + } + if( pExprList ){ + sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES"); + } + if( pUpsert ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "UPSERT"); + sqlite3TreeViewUpsert(pView, pUpsert, 0); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} +#endif /* TREETRACE_ENABLED */ + +#if TREETRACE_ENABLED +/* +** Generate a human-readable diagram of the data structure that go +** into generating an UPDATE statement. +*/ +SQLITE_PRIVATE void sqlite3TreeViewUpdate( + const With *pWith, + const SrcList *pTabList, + const ExprList *pChanges, + const Expr *pWhere, + int onError, + const ExprList *pOrderBy, + const Expr *pLimit, + const Upsert *pUpsert, + const Trigger *pTrigger +){ + int n = 0; + TreeView *pView = 0; + const char *zLabel = "UPDATE"; + switch( onError ){ + case OE_Replace: zLabel = "UPDATE OR REPLACE"; break; + case OE_Ignore: zLabel = "UPDATE OR IGNORE"; break; + case OE_Rollback: zLabel = "UPDATE OR ROLLBACK"; break; + case OE_Abort: zLabel = "UPDATE OR ABORT"; break; + case OE_Fail: zLabel = "UPDATE OR FAIL"; break; + } + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, zLabel); + if( pWith ) n++; + if( pTabList ) n++; + if( pChanges ) n++; + if( pWhere ) n++; + if( pOrderBy ) n++; + if( pLimit ) n++; + if( pUpsert ) n++; + if( pTrigger ) n++; + if( pWith ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(&pView); + } + if( pTabList ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(&pView); + } + if( pChanges ){ + sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET"); + } + if( pWhere ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "WHERE"); + sqlite3TreeViewExpr(pView, pWhere, 0); + sqlite3TreeViewPop(&pView); + } + if( pOrderBy ){ + sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); + } + if( pLimit ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "LIMIT"); + sqlite3TreeViewExpr(pView, pLimit, 0); + sqlite3TreeViewPop(&pView); + } + if( pUpsert ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "UPSERT"); + sqlite3TreeViewUpsert(pView, pUpsert, 0); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} +#endif /* TREETRACE_ENABLED */ + +#ifndef SQLITE_OMIT_TRIGGER +/* +** Show a human-readable graph of a TriggerStep +*/ +SQLITE_PRIVATE void sqlite3TreeViewTriggerStep( + TreeView *pView, + const TriggerStep *pStep, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pStep==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pStep->pNext!=0)); + do{ + if( cnt++ && pStep->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING"); + }while( showFullList && (pStep = pStep->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} + +/* +** Show a human-readable graph of a Trigger +*/ +SQLITE_PRIVATE void sqlite3TreeViewTrigger( + TreeView *pView, + const Trigger *pTrigger, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pTrigger==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pTrigger->pNext!=0)); + do{ + if( cnt++ && pTrigger->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName); + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1); + sqlite3TreeViewPop(&pView); + }while( showFullList && (pTrigger = pTrigger->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_TRIGGER */ + + +/* +** These simplified versions of the tree-view routines omit unnecessary +** parameters. These variants are intended to be used from a symbolic +** debugger, such as "gdb", during interactive debugging sessions. +** +** This routines are given external linkage so that they will always be +** accessible to the debugging, and to avoid warnings about unused +** functions. But these routines only exist in debugging builds, so they +** do not contaminate the interface. +*/ +SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} +SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); } +SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); } +SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,0); +} +SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,1); +} +SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); } +SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);} +#endif +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); } +#endif + +#endif /* SQLITE_DEBUG */ + +/************** End of treeview.c ********************************************/ +/************** Begin file random.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code to implement a pseudo-random number +** generator (PRNG) for SQLite. +** +** Random numbers are used by some of the database backends in order +** to generate random integer keys for tables or random filenames. +*/ +/* #include "sqliteInt.h" */ + + +/* All threads share a single random number generator. +** This structure is the current state of the generator. +*/ +static SQLITE_WSD struct sqlite3PrngType { + u32 s[16]; /* 64 bytes of chacha20 state */ + u8 out[64]; /* Output bytes */ + u8 n; /* Output bytes remaining */ +} sqlite3Prng; + + +/* The RFC-7539 ChaCha20 block function +*/ +#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define QR(a, b, c, d) ( \ + a += b, d ^= a, d = ROTL(d,16), \ + c += d, b ^= c, b = ROTL(b,12), \ + a += b, d ^= a, d = ROTL(d, 8), \ + c += d, b ^= c, b = ROTL(b, 7)) +static void chacha_block(u32 *out, const u32 *in){ + int i; + u32 x[16]; + memcpy(x, in, 64); + for(i=0; i<10; i++){ + QR(x[0], x[4], x[ 8], x[12]); + QR(x[1], x[5], x[ 9], x[13]); + QR(x[2], x[6], x[10], x[14]); + QR(x[3], x[7], x[11], x[15]); + QR(x[0], x[5], x[10], x[15]); + QR(x[1], x[6], x[11], x[12]); + QR(x[2], x[7], x[ 8], x[13]); + QR(x[3], x[4], x[ 9], x[14]); + } + for(i=0; i<16; i++) out[i] = x[i]+in[i]; +} + +/* +** Return N random bytes. +*/ +SQLITE_API void sqlite3_randomness(int N, void *pBuf){ + unsigned char *zBuf = pBuf; + + /* The "wsdPrng" macro will resolve to the pseudo-random number generator + ** state vector. If writable static data is unsupported on the target, + ** we have to locate the state vector at run-time. In the more common + ** case where writable static data is supported, wsdPrng can refer directly + ** to the "sqlite3Prng" state vector declared above. + */ +#ifdef SQLITE_OMIT_WSD + struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); +# define wsdPrng p[0] +#else +# define wsdPrng sqlite3Prng +#endif + +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif + +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return; +#endif + +#if SQLITE_THREADSAFE + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); +#endif + + sqlite3_mutex_enter(mutex); + if( N<=0 || pBuf==0 ){ + wsdPrng.s[0] = 0; + sqlite3_mutex_leave(mutex); + return; + } + + /* Initialize the state of the random number generator once, + ** the first time this routine is called. + */ + if( wsdPrng.s[0]==0 ){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); + static const u32 chacha20_init[] = { + 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + }; + memcpy(&wsdPrng.s[0], chacha20_init, 16); + if( NEVER(pVfs==0) ){ + memset(&wsdPrng.s[4], 0, 44); + }else{ + sqlite3OsRandomness(pVfs, 44, (char*)&wsdPrng.s[4]); + } + wsdPrng.s[15] = wsdPrng.s[12]; + wsdPrng.s[12] = 0; + wsdPrng.n = 0; + } + + assert( N>0 ); + while( 1 /* exit by break */ ){ + if( N<=wsdPrng.n ){ + memcpy(zBuf, &wsdPrng.out[wsdPrng.n-N], N); + wsdPrng.n -= N; + break; + } + if( wsdPrng.n>0 ){ + memcpy(zBuf, wsdPrng.out, wsdPrng.n); + N -= wsdPrng.n; + zBuf += wsdPrng.n; + } + wsdPrng.s[12]++; + chacha_block((u32*)wsdPrng.out, wsdPrng.s); + wsdPrng.n = 64; + } + sqlite3_mutex_leave(mutex); +} + +#ifndef SQLITE_UNTESTABLE +/* +** For testing purposes, we sometimes want to preserve the state of +** PRNG and restore the PRNG to its saved state at a later time, or +** to reset the PRNG to its initial state. These routines accomplish +** those tasks. +** +** The sqlite3_test_control() interface calls these routines to +** control the PRNG. +*/ +static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; +SQLITE_PRIVATE void sqlite3PrngSaveState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + sizeof(sqlite3Prng) + ); +} +SQLITE_PRIVATE void sqlite3PrngRestoreState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + sizeof(sqlite3Prng) + ); +} +#endif /* SQLITE_UNTESTABLE */ + +/************** End of random.c **********************************************/ +/************** Begin file threads.c *****************************************/ +/* +** 2012 July 21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file presents a simple cross-platform threading interface for +** use internally by SQLite. +** +** A "thread" can be created using sqlite3ThreadCreate(). This thread +** runs independently of its creator until it is joined using +** sqlite3ThreadJoin(), at which point it terminates. +** +** Threads do not have to be real. It could be that the work of the +** "thread" is done by the main thread at either the sqlite3ThreadCreate() +** or sqlite3ThreadJoin() call. This is, in fact, what happens in +** single threaded systems. Nothing in SQLite requires multiple threads. +** This interface exists so that applications that want to take advantage +** of multiple cores can do so, while also allowing applications to stay +** single-threaded if desired. +*/ +/* #include "sqliteInt.h" */ +#if SQLITE_OS_WIN +/* # include "os_win.h" */ +#endif + +#if SQLITE_MAX_WORKER_THREADS>0 + +/********************************* Unix Pthreads ****************************/ +#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 + +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ +/* #include */ + +/* A running thread */ +struct SQLiteThread { + pthread_t tid; /* Thread ID */ + int done; /* Set to true when thread finishes */ + void *pOut; /* Result returned by the thread */ + void *(*xTask)(void*); /* The thread routine */ + void *pIn; /* Argument to the thread */ +}; + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + int rc; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + /* This routine is never used in single-threaded mode */ + assert( sqlite3GlobalConfig.bCoreMutex!=0 ); + + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + memset(p, 0, sizeof(*p)); + p->xTask = xTask; + p->pIn = pIn; + /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a + ** function that returns SQLITE_ERROR when passed the argument 200, that + ** forces worker threads to run sequentially and deterministically + ** for testing purposes. */ + if( sqlite3FaultSim(200) ){ + rc = 1; + }else{ + rc = pthread_create(&p->tid, 0, xTask, pIn); + } + if( rc ){ + p->done = 1; + p->pOut = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + int rc; + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; + if( p->done ){ + *ppOut = p->pOut; + rc = SQLITE_OK; + }else{ + rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK; + } + sqlite3_free(p); + return rc; +} + +#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ +/******************************** End Unix Pthreads *************************/ + + +/********************************* Win32 Threads ****************************/ +#if SQLITE_OS_WIN_THREADS + +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ +#include + +/* A running thread */ +struct SQLiteThread { + void *tid; /* The thread handle */ + unsigned id; /* The thread identifier */ + void *(*xTask)(void*); /* The routine to run as a thread */ + void *pIn; /* Argument to xTask */ + void *pResult; /* Result of xTask */ +}; + +/* Thread procedure Win32 compatibility shim */ +static unsigned __stdcall sqlite3ThreadProc( + void *pArg /* IN: Pointer to the SQLiteThread structure */ +){ + SQLiteThread *p = (SQLiteThread *)pArg; + + assert( p!=0 ); +#if 0 + /* + ** This assert appears to trigger spuriously on certain + ** versions of Windows, possibly due to _beginthreadex() + ** and/or CreateThread() not fully setting their thread + ** ID parameter before starting the thread. + */ + assert( p->id==GetCurrentThreadId() ); +#endif + assert( p->xTask!=0 ); + p->pResult = p->xTask(p->pIn); + + _endthreadex(0); + return 0; /* NOT REACHED */ +} + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a + ** function that returns SQLITE_ERROR when passed the argument 200, that + ** forces worker threads to run sequentially and deterministically + ** (via the sqlite3FaultSim() term of the conditional) for testing + ** purposes. */ + if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){ + memset(p, 0, sizeof(*p)); + }else{ + p->xTask = xTask; + p->pIn = pIn; + p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); + if( p->tid==0 ){ + memset(p, 0, sizeof(*p)); + } + } + if( p->xTask==0 ){ + p->id = GetCurrentThreadId(); + p->pResult = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */ + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + DWORD rc; + BOOL bRc; + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; + if( p->xTask==0 ){ + /* assert( p->id==GetCurrentThreadId() ); */ + rc = WAIT_OBJECT_0; + assert( p->tid==0 ); + }else{ + assert( p->id!=0 && p->id!=GetCurrentThreadId() ); + rc = sqlite3Win32Wait((HANDLE)p->tid); + assert( rc!=WAIT_IO_COMPLETION ); + bRc = CloseHandle((HANDLE)p->tid); + assert( bRc ); + } + if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; + sqlite3_free(p); + return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; +} + +#endif /* SQLITE_OS_WIN_THREADS */ +/******************************** End Win32 Threads *************************/ + + +/********************************* Single-Threaded **************************/ +#ifndef SQLITE_THREADS_IMPLEMENTED +/* +** This implementation does not actually create a new thread. It does the +** work of the thread in the main thread, when either the thread is created +** or when it is joined +*/ + +/* A running thread */ +struct SQLiteThread { + void *(*xTask)(void*); /* The routine to run as a thread */ + void *pIn; /* Argument to xTask */ + void *pResult; /* Result of xTask */ +}; + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + if( (SQLITE_PTR_TO_INT(p)/17)&1 ){ + p->xTask = xTask; + p->pIn = pIn; + }else{ + p->xTask = 0; + p->pResult = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; + if( p->xTask ){ + *ppOut = p->xTask(p->pIn); + }else{ + *ppOut = p->pResult; + } + sqlite3_free(p); + +#if defined(SQLITE_TEST) + { + void *pTstAlloc = sqlite3Malloc(10); + if (!pTstAlloc) return SQLITE_NOMEM_BKPT; + sqlite3_free(pTstAlloc); + } +#endif + + return SQLITE_OK; +} + +#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */ +/****************************** End Single-Threaded *************************/ +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + +/************** End of threads.c *********************************************/ +/************** Begin file utf.c *********************************************/ +/* +** 2004 April 13 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used to translate between UTF-8, +** UTF-16, UTF-16BE, and UTF-16LE. +** +** Notes on UTF-8: +** +** Byte-0 Byte-1 Byte-2 Byte-3 Value +** 0xxxxxxx 00000000 00000000 0xxxxxxx +** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx +** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx +** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx +** +** +** Notes on UTF-16: (with wwww+1==uuuuu) +** +** Word-0 Word-1 Value +** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx +** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx +** +** +** BOM or Byte Order Mark: +** 0xff 0xfe little-endian utf-16 follows +** 0xfe 0xff big-endian utf-16 follows +** +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include "vdbeInt.h" */ + +#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0 +/* +** The following constant value is used by the SQLITE_BIGENDIAN and +** SQLITE_LITTLEENDIAN macros. +*/ +SQLITE_PRIVATE const int sqlite3one = 1; +#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */ + +/* +** This lookup table is used to help decode the first byte of +** a multi-byte UTF8 character. +*/ +static const unsigned char sqlite3Utf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + + +#define WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ +} + +#define WRITE_UTF16LE(zOut, c) { \ + if( c<=0xFFFF ){ \ + *zOut++ = (u8)(c&0x00FF); \ + *zOut++ = (u8)((c>>8)&0x00FF); \ + }else{ \ + *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ + *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ + *zOut++ = (u8)(c&0x00FF); \ + *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ + } \ +} + +#define WRITE_UTF16BE(zOut, c) { \ + if( c<=0xFFFF ){ \ + *zOut++ = (u8)((c>>8)&0x00FF); \ + *zOut++ = (u8)(c&0x00FF); \ + }else{ \ + *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ + *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ + *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ + *zOut++ = (u8)(c&0x00FF); \ + } \ +} + +/* +** Translate a single UTF-8 character. Return the unicode value. +** +** During translation, assume that the byte that zTerm points +** is a 0x00. +** +** Write a pointer to the next unread byte back into *pzNext. +** +** Notes On Invalid UTF-8: +** +** * This routine never allows a 7-bit character (0x00 through 0x7f) to +** be encoded as a multi-byte character. Any multi-byte character that +** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd. +** +** * This routine never allows a UTF16 surrogate value to be encoded. +** If a multi-byte character attempts to encode a value between +** 0xd800 and 0xe000 then it is rendered as 0xfffd. +** +** * Bytes in the range of 0x80 through 0xbf which occur as the first +** byte of a character are interpreted as single-byte characters +** and rendered as themselves even though they are technically +** invalid characters. +** +** * This routine accepts over-length UTF8 encodings +** for unicode values 0x80 and greater. It does not change over-length +** encodings to 0xfffd as some systems recommend. +*/ +#define READ_UTF8(zIn, zTerm, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = sqlite3Utf8Trans1[c-0xc0]; \ + while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + if( c<0x80 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ + } +SQLITE_PRIVATE u32 sqlite3Utf8Read( + const unsigned char **pz /* Pointer to string from which to read char */ +){ + unsigned int c; + + /* Same as READ_UTF8() above but without the zTerm parameter. + ** For this routine, we assume the UTF8 string is always zero-terminated. + */ + c = *((*pz)++); + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + while( (*(*pz) & 0xc0)==0x80 ){ + c = (c<<6) + (0x3f & *((*pz)++)); + } + if( c<0x80 + || (c&0xFFFFF800)==0xD800 + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } + } + return c; +} + +/* +** Read a single UTF8 character out of buffer z[], but reading no +** more than n characters from the buffer. z[] is not zero-terminated. +** +** Return the number of bytes used to construct the character. +** +** Invalid UTF8 might generate a strange result. No effort is made +** to detect invalid UTF8. +** +** At most 4 bytes will be read out of z[]. The return value will always +** be between 1 and 4. +*/ +SQLITE_PRIVATE int sqlite3Utf8ReadLimited( + const u8 *z, + int n, + u32 *piOut +){ + u32 c; + int i = 1; + assert( n>0 ); + c = z[0]; + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + if( n>4 ) n = 4; + while( idb==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->flags&MEM_Str ); + assert( pMem->enc!=desiredEnc ); + assert( pMem->enc!=0 ); + assert( pMem->n>=0 ); + +#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) + { + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "INPUT: %s\n", sqlite3StrAccumFinish(&acc)); + } +#endif + + /* If the translation is between UTF-16 little and big endian, then + ** all that is required is to swap the byte order. This case is handled + ** differently from the others. + */ + if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){ + u8 temp; + int rc; + rc = sqlite3VdbeMemMakeWriteable(pMem); + if( rc!=SQLITE_OK ){ + assert( rc==SQLITE_NOMEM ); + return SQLITE_NOMEM_BKPT; + } + zIn = (u8*)pMem->z; + zTerm = &zIn[pMem->n&~1]; + while( zInenc = desiredEnc; + goto translate_out; + } + + /* Set len to the maximum number of bytes required in the output buffer. */ + if( desiredEnc==SQLITE_UTF8 ){ + /* When converting from UTF-16, the maximum growth results from + ** translating a 2-byte character to a 4-byte UTF-8 character. + ** A single byte is required for the output string + ** nul-terminator. + */ + pMem->n &= ~1; + len = 2 * (sqlite3_int64)pMem->n + 1; + }else{ + /* When converting from UTF-8 to UTF-16 the maximum growth is caused + ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 + ** character. Two bytes are required in the output buffer for the + ** nul-terminator. + */ + len = 2 * (sqlite3_int64)pMem->n + 2; + } + + /* Set zIn to point at the start of the input buffer and zTerm to point 1 + ** byte past the end. + ** + ** Variable zOut is set to point at the output buffer, space obtained + ** from sqlite3_malloc(). + */ + zIn = (u8*)pMem->z; + zTerm = &zIn[pMem->n]; + zOut = sqlite3DbMallocRaw(pMem->db, len); + if( !zOut ){ + return SQLITE_NOMEM_BKPT; + } + z = zOut; + + if( pMem->enc==SQLITE_UTF8 ){ + if( desiredEnc==SQLITE_UTF16LE ){ + /* UTF-8 -> UTF-16 Little-endian */ + while( zIn UTF-16 Big-endian */ + while( zInn = (int)(z - zOut); + *z++ = 0; + }else{ + assert( desiredEnc==SQLITE_UTF8 ); + if( pMem->enc==SQLITE_UTF16LE ){ + /* UTF-16 Little-endian -> UTF-8 */ + while( zIn=0xd800 && c<0xe000 ){ +#ifdef SQLITE_REPLACE_INVALID_UTF + if( c>=0xdc00 || zIn>=zTerm ){ + c = 0xfffd; + }else{ + int c2 = *(zIn++); + c2 += (*(zIn++))<<8; + if( c2<0xdc00 || c2>=0xe000 ){ + zIn -= 2; + c = 0xfffd; + }else{ + c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000; + } + } +#else + if( zIn UTF-8 */ + while( zIn=0xd800 && c<0xe000 ){ +#ifdef SQLITE_REPLACE_INVALID_UTF + if( c>=0xdc00 || zIn>=zTerm ){ + c = 0xfffd; + }else{ + int c2 = (*(zIn++))<<8; + c2 += *(zIn++); + if( c2<0xdc00 || c2>=0xe000 ){ + zIn -= 2; + c = 0xfffd; + }else{ + c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000; + } + } +#else + if( zInn = (int)(z - zOut); + } + *z = 0; + assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); + + c = MEM_Str|MEM_Term|(pMem->flags&(MEM_AffMask|MEM_Subtype)); + sqlite3VdbeMemRelease(pMem); + pMem->flags = c; + pMem->enc = desiredEnc; + pMem->z = (char*)zOut; + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); + +translate_out: +#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) + { + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "OUTPUT: %s\n", sqlite3StrAccumFinish(&acc)); + } +#endif + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_UTF16 +/* +** This routine checks for a byte-order mark at the beginning of the +** UTF-16 string stored in *pMem. If one is present, it is removed and +** the encoding of the Mem adjusted. This routine does not do any +** byte-swapping, it just sets Mem.enc appropriately. +** +** The allocation (static, dynamic etc.) and encoding of the Mem may be +** changed by this function. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ + int rc = SQLITE_OK; + u8 bom = 0; + + assert( pMem->n>=0 ); + if( pMem->n>1 ){ + u8 b1 = *(u8 *)pMem->z; + u8 b2 = *(((u8 *)pMem->z) + 1); + if( b1==0xFE && b2==0xFF ){ + bom = SQLITE_UTF16BE; + } + if( b1==0xFF && b2==0xFE ){ + bom = SQLITE_UTF16LE; + } + } + + if( bom ){ + rc = sqlite3VdbeMemMakeWriteable(pMem); + if( rc==SQLITE_OK ){ + pMem->n -= 2; + memmove(pMem->z, &pMem->z[2], pMem->n); + pMem->z[pMem->n] = '\0'; + pMem->z[pMem->n+1] = '\0'; + pMem->flags |= MEM_Term; + pMem->enc = bom; + } + } + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, +** return the number of unicode characters in pZ up to (but not including) +** the first 0x00 byte. If nByte is not less than zero, return the +** number of unicode characters in the first nByte of pZ (or up to +** the first 0x00, whichever comes first). +*/ +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ + int r = 0; + const u8 *z = (const u8*)zIn; + const u8 *zTerm; + if( nByte>=0 ){ + zTerm = &z[nByte]; + }else{ + zTerm = (const u8*)(-1); + } + assert( z<=zTerm ); + while( *z!=0 && zmallocFailed ){ + sqlite3VdbeMemRelease(&m); + m.z = 0; + } + assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); + assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); + assert( m.z || db->mallocFailed ); + return m.z; +} + +/* +** zIn is a UTF-16 encoded unicode string at least nChar characters long. +** Return the number of bytes in the first nChar unicode characters +** in pZ. nChar must be non-negative. +*/ +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ + int c; + unsigned char const *z = zIn; + int n = 0; + + if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; + while( n=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2; + n++; + } + return (int)(z-(unsigned char const *)zIn) + - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE); +} + +#if defined(SQLITE_TEST) +/* +** This routine is called from the TCL test function "translate_selftest". +** It checks that the primitives for serializing and deserializing +** characters in each encoding are inverses of each other. +*/ +SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ + unsigned int i, t; + unsigned char zBuf[20]; + unsigned char *z; + int n; + unsigned int c; + + for(i=0; i<0x00110000; i++){ + z = zBuf; + WRITE_UTF8(z, i); + n = (int)(z-zBuf); + assert( n>0 && n<=4 ); + z[0] = 0; + z = zBuf; + c = sqlite3Utf8Read((const u8**)&z); + t = i; + if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; + if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; + assert( c==t ); + assert( (z-zBuf)==n ); + } +} +#endif /* SQLITE_TEST */ +#endif /* SQLITE_OMIT_UTF16 */ + +/************** End of utf.c *************************************************/ +/************** Begin file util.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Utility functions used throughout sqlite. +** +** This file contains functions for allocating memory, comparing +** strings, and stuff like that. +** +*/ +/* #include "sqliteInt.h" */ +/* #include */ +#ifndef SQLITE_OMIT_FLOATING_POINT +#include +#endif + +/* +** Calls to sqlite3FaultSim() are used to simulate a failure during testing, +** or to bypass normal error detection during testing in order to let +** execute proceed further downstream. +** +** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The +** sqlite3FaultSim() function only returns non-zero during testing. +** +** During testing, if the test harness has set a fault-sim callback using +** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then +** each call to sqlite3FaultSim() is relayed to that application-supplied +** callback and the integer return value form the application-supplied +** callback is returned by sqlite3FaultSim(). +** +** The integer argument to sqlite3FaultSim() is a code to identify which +** sqlite3FaultSim() instance is being invoked. Each call to sqlite3FaultSim() +** should have a unique code. To prevent legacy testing applications from +** breaking, the codes should not be changed or reused. +*/ +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ + int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; + return xCallback ? xCallback(iTest) : SQLITE_OK; +} +#endif + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is Not a Number (NaN). +** +** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. +** Otherwise, we have our own implementation that works on most systems. +*/ +SQLITE_PRIVATE int sqlite3IsNaN(double x){ + int rc; /* The value return */ +#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN + u64 y; + memcpy(&y,&x,sizeof(y)); + rc = IsNaN(y); +#else + rc = isnan(x); +#endif /* HAVE_ISNAN */ + testcase( rc ); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is NaN or +Inf or -Inf. +*/ +SQLITE_PRIVATE int sqlite3IsOverflow(double x){ + int rc; /* The value return */ + u64 y; + memcpy(&y,&x,sizeof(y)); + rc = IsOvfl(y); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +** +** The value returned will never be negative. Nor will it ever be greater +** than the actual length of the string. For very long strings (greater +** than 1GiB) the value returned might be less than the true string length. +*/ +SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ + if( z==0 ) return 0; + return 0x3fffffff & (int)strlen(z); +} + +/* +** Return the declared type of a column. Or return zDflt if the column +** has no declared type. +** +** The column type is an extra string stored after the zero-terminator on +** the column name if and only if the COLFLAG_HASTYPE flag is set. +*/ +SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){ + if( pCol->colFlags & COLFLAG_HASTYPE ){ + return pCol->zCnName + strlen(pCol->zCnName) + 1; + }else if( pCol->eCType ){ + assert( pCol->eCType<=SQLITE_N_STDTYPE ); + return (char*)sqlite3StdType[pCol->eCType-1]; + }else{ + return zDflt; + } +} + +/* +** Helper function for sqlite3Error() - called rarely. Broken out into +** a separate routine to avoid unnecessary register saves on entry to +** sqlite3Error(). +*/ +static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ + if( db->pErr ) sqlite3ValueSetNull(db->pErr); + sqlite3SystemError(db, err_code); +} + +/* +** Set the current error code to err_code and clear any prior error message. +** Also set iSysErrno (by calling sqlite3System) if the err_code indicates +** that would be appropriate. +*/ +SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ + assert( db!=0 ); + db->errCode = err_code; + if( err_code || db->pErr ){ + sqlite3ErrorFinish(db, err_code); + }else{ + db->errByteOffset = -1; + } +} + +/* +** The equivalent of sqlite3Error(db, SQLITE_OK). Clear the error state +** and error message. +*/ +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ + assert( db!=0 ); + db->errCode = SQLITE_OK; + db->errByteOffset = -1; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + +/* +** Load the sqlite3.iSysErrno field if that is an appropriate thing +** to do based on the SQLite error code in rc. +*/ +SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ + if( rc==SQLITE_IOERR_NOMEM ) return; +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) + if( rc==SQLITE_IOERR_IN_PAGE ){ + int ii; + int iErr; + sqlite3BtreeEnterAll(db); + for(ii=0; iinDb; ii++){ + if( db->aDb[ii].pBt ){ + iErr = sqlite3PagerWalSystemErrno(sqlite3BtreePager(db->aDb[ii].pBt)); + if( iErr ){ + db->iSysErrno = iErr; + } + } + } + sqlite3BtreeLeaveAll(db); + return; + } +#endif + rc &= 0xff; + if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ + db->iSysErrno = sqlite3OsGetLastError(db->pVfs); + } +} + +/* +** Set the most recent error code and error string for the sqlite +** handle "db". The error code is set to "err_code". +** +** If it is not NULL, string zFormat specifies the format of the +** error string. zFormat and any string tokens that follow it are +** assumed to be encoded in UTF-8. +** +** To clear the most recent error for sqlite handle "db", sqlite3Error +** should be called with err_code set to SQLITE_OK and zFormat set +** to NULL. +*/ +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ + assert( db!=0 ); + db->errCode = err_code; + sqlite3SystemError(db, err_code); + if( zFormat==0 ){ + sqlite3Error(db, err_code); + }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ + char *z; + va_list ap; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); + } +} + +/* +** Check for interrupts and invoke progress callback. +*/ +SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ + sqlite3 *db = p->db; + if( AtomicLoad(&db->u1.isInterrupted) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + if( p->rc==SQLITE_INTERRUPT ){ + p->nProgressSteps = 0; + }else if( (++p->nProgressSteps)>=db->nProgressOps ){ + if( db->xProgress(db->pProgressArg) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; + } + p->nProgressSteps = 0; + } + } +#endif +} + +/* +** Add an error message to pParse->zErrMsg and increment pParse->nErr. +** +** This function should be used to report any error that occurs while +** compiling an SQL statement (i.e. within sqlite3_prepare()). The +** last thing the sqlite3_prepare() function does is copy the error +** stored by this function into the database handle using sqlite3Error(). +** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used +** during statement execution (sqlite3_step() etc.). +*/ +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ + char *zMsg; + va_list ap; + sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse || db->pParse->pToplevel==pParse ); + db->errByteOffset = -2; + va_start(ap, zFormat); + zMsg = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + if( db->errByteOffset<-1 ) db->errByteOffset = -1; + if( db->suppressErr ){ + sqlite3DbFree(db, zMsg); + if( db->mallocFailed ){ + pParse->nErr++; + pParse->rc = SQLITE_NOMEM; + } + }else{ + pParse->nErr++; + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = zMsg; + pParse->rc = SQLITE_ERROR; + pParse->pWith = 0; + } +} + +/* +** If database connection db is currently parsing SQL, then transfer +** error code errCode to that parser if the parser has not already +** encountered some other kind of error. +*/ +SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3 *db, int errCode){ + Parse *pParse; + if( db==0 || (pParse = db->pParse)==0 ) return errCode; + pParse->rc = errCode; + pParse->nErr++; + return errCode; +} + +/* +** Convert an SQL-style quoted string into a normal string by removing +** the quote characters. The conversion is done in-place. If the +** input does not begin with a quote character, then this routine +** is a no-op. +** +** The input string must be zero-terminated. A new zero-terminator +** is added to the dequoted string. +** +** The return value is -1 if no dequoting occurs or the length of the +** dequoted string, exclusive of the zero terminator, if dequoting does +** occur. +** +** 2002-02-14: This routine is extended to remove MS-Access style +** brackets from around identifiers. For example: "[a-b-c]" becomes +** "a-b-c". +*/ +SQLITE_PRIVATE void sqlite3Dequote(char *z){ + char quote; + int i, j; + if( z==0 ) return; + quote = z[0]; + if( !sqlite3Isquote(quote) ) return; + if( quote=='[' ) quote = ']'; + for(i=1, j=0;; i++){ + assert( z[i] ); + if( z[i]==quote ){ + if( z[i+1]==quote ){ + z[j++] = quote; + i++; + }else{ + break; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; +} +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ + assert( !ExprHasProperty(p, EP_IntValue) ); + assert( sqlite3Isquote(p->u.zToken[0]) ); + p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted; + sqlite3Dequote(p->u.zToken); +} + +/* +** If the input token p is quoted, try to adjust the token to remove +** the quotes. This is not always possible: +** +** "abc" -> abc +** "ab""cd" -> (not possible because of the interior "") +** +** Remove the quotes if possible. This is a optimization. The overall +** system should still return the correct answer even if this routine +** is always a no-op. +*/ +SQLITE_PRIVATE void sqlite3DequoteToken(Token *p){ + unsigned int i; + if( p->n<2 ) return; + if( !sqlite3Isquote(p->z[0]) ) return; + for(i=1; in-1; i++){ + if( sqlite3Isquote(p->z[i]) ) return; + } + p->n -= 2; + p->z++; +} + +/* +** Generate a Token object from a string +*/ +SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){ + p->z = z; + p->n = sqlite3Strlen30(z); +} + +/* Convenient short-hand */ +#define UpperToLower sqlite3UpperToLower + +/* +** Some systems have stricmp(). Others have strcasecmp(). Because +** there is no consistency, we will define our own. +** +** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and +** sqlite3_strnicmp() APIs allow applications and extensions to compare +** the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ + if( zLeft==0 ){ + return zRight ? -1 : 0; + }else if( zRight==0 ){ + return 1; + } + return sqlite3StrICmp(zLeft, zRight); +} +SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ + unsigned char *a, *b; + int c, x; + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + for(;;){ + c = *a; + x = *b; + if( c==x ){ + if( c==0 ) break; + }else{ + c = (int)UpperToLower[c] - (int)UpperToLower[x]; + if( c ) break; + } + a++; + b++; + } + return c; +} +SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ + register unsigned char *a, *b; + if( zLeft==0 ){ + return zRight ? -1 : 0; + }else if( zRight==0 ){ + return 1; + } + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } + return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; +} + +/* +** Compute an 8-bit hash on a string that is insensitive to case differences +*/ +SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){ + u8 h = 0; + if( z==0 ) return 0; + while( z[0] ){ + h += UpperToLower[(unsigned char)z[0]]; + z++; + } + return h; +} + +/* Double-Double multiplication. (x[0],x[1]) *= (y,yy) +** +** Reference: +** T. J. Dekker, "A Floating-Point Technique for Extending the +** Available Precision". 1971-07-26. +*/ +static void dekkerMul2(volatile double *x, double y, double yy){ + /* + ** The "volatile" keywords on parameter x[] and on local variables + ** below are needed force intermediate results to be truncated to + ** binary64 rather than be carried around in an extended-precision + ** format. The truncation is necessary for the Dekker algorithm to + ** work. Intel x86 floating point might omit the truncation without + ** the use of volatile. + */ + volatile double tx, ty, p, q, c, cc; + double hx, hy; + u64 m; + memcpy(&m, (void*)&x[0], 8); + m &= 0xfffffffffc000000LL; + memcpy(&hx, &m, 8); + tx = x[0] - hx; + memcpy(&m, &y, 8); + m &= 0xfffffffffc000000LL; + memcpy(&hy, &m, 8); + ty = y - hy; + p = hx*hy; + q = hx*ty + tx*hy; + c = p+q; + cc = p - c + q + tx*ty; + cc = x[0]*yy + x[1]*y + cc; + x[0] = c + cc; + x[1] = c - x[0]; + x[1] += cc; +} + +/* +** The string z[] is an text representation of a real number. +** Convert this string to a double and write it into *pResult. +** +** The string z[] is length bytes in length (bytes, not characters) and +** uses the encoding enc. The string is not necessarily zero-terminated. +** +** Return TRUE if the result is a valid real number (or integer) and FALSE +** if the string is empty or contains extraneous text. More specifically +** return +** 1 => The input string is a pure integer +** 2 or more => The input has a decimal point or eNNN clause +** 0 or less => The input string is not a valid number +** -1 => Not a valid number, but has a valid prefix which +** includes a decimal point and/or an eNNN clause +** +** Valid numbers are in one of these formats: +** +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] +** +** Leading and trailing whitespace is ignored for the purpose of determining +** validity. +** +** If some prefix of the input string is a valid number, this routine +** returns FALSE but it still converts the prefix and writes the result +** into *pResult. +*/ +#if defined(_MSC_VER) +#pragma warning(disable : 4756) +#endif +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ +#ifndef SQLITE_OMIT_FLOATING_POINT + int incr; + const char *zEnd; + /* sign * significand * (10 ^ (esign * exponent)) */ + int sign = 1; /* sign of significand */ + u64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + int eValid = 1; /* True exponent is either not used or is well-formed */ + int nDigit = 0; /* Number of digits processed */ + int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + *pResult = 0.0; /* Default return value, in case of an error */ + if( length==0 ) return 0; + + if( enc==SQLITE_UTF8 ){ + incr = 1; + zEnd = z + length; + }else{ + int i; + incr = 2; + length &= ~1; + assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + testcase( enc==SQLITE_UTF16LE ); + testcase( enc==SQLITE_UTF16BE ); + for(i=3-enc; i=zEnd ) return 0; + + /* get sign of significand */ + if( *z=='-' ){ + sign = -1; + z+=incr; + }else if( *z=='+' ){ + z+=incr; + } + + /* copy max significant digits to significand */ + while( z=((LARGEST_UINT64-9)/10) ){ + /* skip non-significant significand digits + ** (increase exponent by d to shift decimal left) */ + while( z=zEnd ) goto do_atof_calc; + + /* if decimal point is present */ + if( *z=='.' ){ + z+=incr; + eType++; + /* copy digits from after decimal to significand + ** (decrease exponent by d to shift decimal right) */ + while( z=zEnd ) goto do_atof_calc; + + /* if exponent is present */ + if( *z=='e' || *z=='E' ){ + z+=incr; + eValid = 0; + eType++; + + /* This branch is needed to avoid a (harmless) buffer overread. The + ** special comment alerts the mutation tester that the correct answer + ** is obtained even if the branch is omitted */ + if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/ + + /* get sign of exponent */ + if( *z=='-' ){ + esign = -1; + z+=incr; + }else if( *z=='+' ){ + z+=incr; + } + /* copy digits to exponent */ + while( z0 && s<(LARGEST_UINT64/10) ){ + s *= 10; + e--; + } + while( e<0 && (s%10)==0 ){ + s /= 10; + e++; + } + + if( e==0 ){ + *pResult = s; + }else if( sqlite3Config.bUseLongDouble ){ + LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; + if( e>0 ){ + while( e>=100 ){ e-=100; r *= 1.0e+100L; } + while( e>=10 ){ e-=10; r *= 1.0e+10L; } + while( e>=1 ){ e-=1; r *= 1.0e+01L; } + }else{ + while( e<=-100 ){ e+=100; r *= 1.0e-100L; } + while( e<=-10 ){ e+=10; r *= 1.0e-10L; } + while( e<=-1 ){ e+=1; r *= 1.0e-01L; } + } + assert( r>=0.0 ); + if( r>+1.7976931348623157081452742373e+308L ){ +#ifdef INFINITY + *pResult = +INFINITY; +#else + *pResult = 1.0e308*10.0; +#endif + }else{ + *pResult = (double)r; + } + }else{ + double rr[2]; + u64 s2; + rr[0] = (double)s; + s2 = (u64)rr[0]; +#if defined(_MSC_VER) && _MSC_VER<1700 + if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } +#endif + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + if( e>0 ){ + while( e>=100 ){ + e -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( e>=10 ){ + e -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( e>=1 ){ + e -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); + } + }else{ + while( e<=-100 ){ + e += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( e<=-10 ){ + e += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( e<=-1 ){ + e += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); + } + } + *pResult = rr[0]+rr[1]; + if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; + } + if( sign<0 ) *pResult = -*pResult; + assert( !sqlite3IsNaN(*pResult) ); + +atof_return: + /* return true if number and no extra non-whitespace characters after */ + if( z==zEnd && nDigit>0 && eValid && eType>0 ){ + return eType; + }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){ + return -1; + }else{ + return 0; + } +#else + return !sqlite3Atoi64(z, pResult, length, enc); +#endif /* SQLITE_OMIT_FLOATING_POINT */ +} +#if defined(_MSC_VER) +#pragma warning(default : 4756) +#endif + +/* +** Render an signed 64-bit integer as text. Store the result in zOut[] and +** return the length of the string that was stored, in bytes. The value +** returned does not include the zero terminator at the end of the output +** string. +** +** The caller must ensure that zOut[] is at least 21 bytes in size. +*/ +SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ + int i; + u64 x; + char zTemp[22]; + if( v<0 ){ + x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; + }else{ + x = v; + } + i = sizeof(zTemp)-2; + zTemp[sizeof(zTemp)-1] = 0; + while( 1 /*exit-by-break*/ ){ + zTemp[i] = (x%10) + '0'; + x = x/10; + if( x==0 ) break; + i--; + }; + if( v<0 ) zTemp[--i] = '-'; + memcpy(zOut, &zTemp[i], sizeof(zTemp)-i); + return sizeof(zTemp)-1-i; +} + +/* +** Compare the 19-character string zNum against the text representation +** value 2^63: 9223372036854775808. Return negative, zero, or positive +** if zNum is less than, equal to, or greater than the string. +** Note that zNum must contain exactly 19 characters. +** +** Unlike memcmp() this routine is guaranteed to return the difference +** in the values of the last digit if the only difference is in the +** last digit. So, for example, +** +** compare2pow63("9223372036854775800", 1) +** +** will return -8. +*/ +static int compare2pow63(const char *zNum, int incr){ + int c = 0; + int i; + /* 012345678901234567 */ + const char *pow63 = "922337203685477580"; + for(i=0; c==0 && i<18; i++){ + c = (zNum[i*incr]-pow63[i])*10; + } + if( c==0 ){ + c = zNum[18*incr] - '8'; + testcase( c==(-1) ); + testcase( c==0 ); + testcase( c==(+1) ); + } + return c; +} + +/* +** Convert zNum to a 64-bit signed integer. zNum must be decimal. This +** routine does *not* accept hexadecimal notation. +** +** Returns: +** +** -1 Not even a prefix of the input text looks like an integer +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Excess non-space text after the integer value +** 2 Integer too large for a 64-bit signed integer or is malformed +** 3 Special case of 9223372036854775808 +** +** length is the number of bytes in the string (bytes, not characters). +** The string is not necessarily zero-terminated. The encoding is +** given by enc. +*/ +SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ + int incr; + u64 u = 0; + int neg = 0; /* assume positive */ + int i; + int c = 0; + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ + int rc; /* Baseline return code */ + const char *zStart; + const char *zEnd = zNum + length; + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + if( enc==SQLITE_UTF8 ){ + incr = 1; + }else{ + incr = 2; + length &= ~1; + assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + for(i=3-enc; i='0' && c<='9'; i+=incr){ + u = u*10 + c - '0'; + } + testcase( i==18*incr ); + testcase( i==19*incr ); + testcase( i==20*incr ); + if( u>LARGEST_INT64 ){ + /* This test and assignment is needed only to suppress UB warnings + ** from clang and -fsanitize=undefined. This test and assignment make + ** the code a little larger and slower, and no harm comes from omitting + ** them, but we must appease the undefined-behavior pharisees. */ + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; + }else if( neg ){ + *pNum = -(i64)u; + }else{ + *pNum = (i64)u; + } + rc = 0; + if( i==0 && zStart==zNum ){ /* No digits */ + rc = -1; + }else if( nonNum ){ /* UTF16 with high-order bytes non-zero */ + rc = 1; + }else if( &zNum[i]19*incr ? 1 : compare2pow63(zNum, incr); + if( c<0 ){ + /* zNum is less than 9223372036854775808 so it fits */ + assert( u<=LARGEST_INT64 ); + return rc; + }else{ + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; + if( c>0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 2; + }else{ + /* zNum is exactly 9223372036854775808. Fits if negative. The + ** special case 2 overflow if positive */ + assert( u-1==LARGEST_INT64 ); + return neg ? rc : 3; + } + } + } +} + +/* +** Transform a UTF-8 integer literal, in either decimal or hexadecimal, +** into a 64-bit signed integer. This routine accepts hexadecimal literals, +** whereas sqlite3Atoi64() does not. +** +** Returns: +** +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Excess text after the integer value +** 2 Integer too large for a 64-bit signed integer or is malformed +** 3 Special case of 9223372036854775808 +*/ +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + ){ + u64 u = 0; + int i, k; + for(i=2; z[i]=='0'; i++){} + for(k=i; sqlite3Isxdigit(z[k]); k++){ + u = u*16 + sqlite3HexToInt(z[k]); + } + memcpy(pOut, &u, 8); + if( k-i>16 ) return 2; + if( z[k]!=0 ) return 1; + return 0; + }else +#endif /* SQLITE_OMIT_HEX_INTEGER */ + { + int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789")); + if( z[n] ) n++; + return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8); + } +} + +/* +** If zNum represents an integer that will fit in 32-bits, then set +** *pValue to that integer and return true. Otherwise return false. +** +** This routine accepts both decimal and hexadecimal notation for integers. +** +** Any non-numeric characters that following zNum are ignored. +** This is different from sqlite3Atoi64() which requires the +** input number to be zero-terminated. +*/ +SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ + sqlite_int64 v = 0; + int i, c; + int neg = 0; + if( zNum[0]=='-' ){ + neg = 1; + zNum++; + }else if( zNum[0]=='+' ){ + zNum++; + } +#ifndef SQLITE_OMIT_HEX_INTEGER + else if( zNum[0]=='0' + && (zNum[1]=='x' || zNum[1]=='X') + && sqlite3Isxdigit(zNum[2]) + ){ + u32 u = 0; + zNum += 2; + while( zNum[0]=='0' ) zNum++; + for(i=0; i<8 && sqlite3Isxdigit(zNum[i]); i++){ + u = u*16 + sqlite3HexToInt(zNum[i]); + } + if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ + memcpy(pValue, &u, 4); + return 1; + }else{ + return 0; + } + } +#endif + if( !sqlite3Isdigit(zNum[0]) ) return 0; + while( zNum[0]=='0' ) zNum++; + for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ + v = v*10 + c; + } + + /* The longest decimal representation of a 32 bit integer is 10 digits: + ** + ** 1234567890 + ** 2^31 -> 2147483648 + */ + testcase( i==10 ); + if( i>10 ){ + return 0; + } + testcase( v-neg==2147483647 ); + if( v-neg>2147483647 ){ + return 0; + } + if( neg ){ + v = -v; + } + *pValue = (int)v; + return 1; +} + +/* +** Return a 32-bit integer value extracted from a string. If the +** string is not an integer, just return 0. +*/ +SQLITE_PRIVATE int sqlite3Atoi(const char *z){ + int x = 0; + sqlite3GetInt32(z, &x); + return x; +} + +/* +** Decode a floating-point value into an approximate decimal +** representation. +** +** Round the decimal representation to n significant digits if +** n is positive. Or round to -n signficant digits after the +** decimal point if n is negative. No rounding is performed if +** n is zero. +** +** The significant digits of the decimal representation are +** stored in p->z[] which is a often (but not always) a pointer +** into the middle of p->zBuf[]. There are p->n significant digits. +** The p->z[] array is *not* zero-terminated. +*/ +SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ + int i; + u64 v; + int e, exp = 0; + p->isSpecial = 0; + p->z = p->zBuf; + + /* Convert negative numbers to positive. Deal with Infinity, 0.0, and + ** NaN. */ + if( r<0.0 ){ + p->sign = '-'; + r = -r; + }else if( r==0.0 ){ + p->sign = '+'; + p->n = 1; + p->iDP = 1; + p->z = "0"; + return; + }else{ + p->sign = '+'; + } + memcpy(&v,&r,8); + e = v>>52; + if( (e&0x7ff)==0x7ff ){ + p->isSpecial = 1 + (v!=0x7ff0000000000000LL); + p->n = 0; + p->iDP = 0; + return; + } + + /* Multiply r by powers of ten until it lands somewhere in between + ** 1.0e+19 and 1.0e+17. + */ + if( sqlite3Config.bUseLongDouble ){ + LONGDOUBLE_TYPE rr = r; + if( rr>=1.0e+19 ){ + while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } + while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } + while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } + }else{ + while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } + while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } + while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } + } + v = (u64)rr; + }else{ + /* If high-precision floating point is not available using "long double", + ** then use Dekker-style double-double computation to increase the + ** precision. + ** + ** The error terms on constants like 1.0e+100 computed using the + ** decimal extension, for example as follows: + ** + ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); + */ + double rr[2]; + rr[0] = r; + rr[1] = 0.0; + if( rr[0]>9.223372036854774784e+18 ){ + while( rr[0]>9.223372036854774784e+118 ){ + exp += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( rr[0]>9.223372036854774784e+28 ){ + exp += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( rr[0]>9.223372036854774784e+18 ){ + exp += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); + } + }else{ + while( rr[0]<9.223372036854774784e-83 ){ + exp -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( rr[0]<9.223372036854774784e+07 ){ + exp -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( rr[0]<9.22337203685477478e+17 ){ + exp -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); + } + } + v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; + } + + + /* Extract significant digits. */ + i = sizeof(p->zBuf)-1; + assert( v>0 ); + while( v ){ p->zBuf[i--] = (v%10) + '0'; v /= 10; } + assert( i>=0 && izBuf)-1 ); + p->n = sizeof(p->zBuf) - 1 - i; + assert( p->n>0 ); + assert( p->nzBuf) ); + p->iDP = p->n + exp; + if( iRound<=0 ){ + iRound = p->iDP - iRound; + if( iRound==0 && p->zBuf[i+1]>='5' ){ + iRound = 1; + p->zBuf[i--] = '0'; + p->n++; + p->iDP++; + } + } + if( iRound>0 && (iRoundn || p->n>mxRound) ){ + char *z = &p->zBuf[i+1]; + if( iRound>mxRound ) iRound = mxRound; + p->n = iRound; + if( z[iRound]>='5' ){ + int j = iRound-1; + while( 1 /*exit-by-break*/ ){ + z[j]++; + if( z[j]<='9' ) break; + z[j] = '0'; + if( j==0 ){ + p->z[i--] = '1'; + p->n++; + p->iDP++; + break; + }else{ + j--; + } + } + } + } + p->z = &p->zBuf[i+1]; + assert( i+p->n < sizeof(p->zBuf) ); + while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; } +} + +/* +** Try to convert z into an unsigned 32-bit integer. Return true on +** success and false if there is an error. +** +** Only decimal notation is accepted. +*/ +SQLITE_PRIVATE int sqlite3GetUInt32(const char *z, u32 *pI){ + u64 v = 0; + int i; + for(i=0; sqlite3Isdigit(z[i]); i++){ + v = v*10 + z[i] - '0'; + if( v>4294967296LL ){ *pI = 0; return 0; } + } + if( i==0 || z[i]!=0 ){ *pI = 0; return 0; } + *pI = (u32)v; + return 1; +} + +/* +** The variable-length integer encoding is as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** C = xxxxxxxx 8 bits of data +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** 28 bits - BBBA +** 35 bits - BBBBA +** 42 bits - BBBBBA +** 49 bits - BBBBBBA +** 56 bits - BBBBBBBA +** 64 bits - BBBBBBBBC +*/ + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data write will be between 1 and 9 bytes. The number +** of bytes written is returned. +** +** A variable-length integer consists of the lower 7 bits of each byte +** for all bytes that have the 8th bit set and one byte with the 8th +** bit clear. Except, if we get to the 9th byte, it stores the full +** 8 bits and is the last byte. +*/ +static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){ + int i, j, n; + u8 buf[10]; + if( v & (((u64)0xff000000)<<32) ){ + p[8] = (u8)v; + v >>= 8; + for(i=7; i>=0; i--){ + p[i] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + } + return 9; + } + n = 0; + do{ + buf[n++] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + }while( v!=0 ); + buf[0] &= 0x7f; + assert( n<=9 ); + for(i=0, j=n-1; j>=0; j--, i++){ + p[i] = buf[j]; + } + return n; +} +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ + if( v<=0x7f ){ + p[0] = v&0x7f; + return 1; + } + if( v<=0x3fff ){ + p[0] = ((v>>7)&0x7f)|0x80; + p[1] = v&0x7f; + return 2; + } + return putVarint64(p,v); +} + +/* +** Bitmasks used by sqlite3GetVarint(). These precomputed constants +** are defined here rather than simply putting the constant expressions +** inline in order to work around bugs in the RVT compiler. +** +** SLOT_2_0 A mask for (0x7f<<14) | 0x7f +** +** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 +*/ +#define SLOT_2_0 0x001fc07f +#define SLOT_4_2_0 0xf01fc07f + + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +*/ +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ + u32 a,b,s; + + if( ((signed char*)p)[0]>=0 ){ + *v = *p; + return 1; + } + if( ((signed char*)p)[1]>=0 ){ + *v = ((u32)(p[0]&0x7f)<<7) | p[1]; + return 2; + } + + /* Verify that constants are precomputed correctly */ + assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); + assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); + + a = ((u32)p[0])<<14; + b = p[1]; + p += 2; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + a &= SLOT_2_0; + b &= 0x7f; + b = b<<7; + a |= b; + *v = a; + return 3; + } + + /* CSE1 from below */ + a &= SLOT_2_0; + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + b &= SLOT_2_0; + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + *v = a; + return 4; + } + + /* a: p0<<14 | p2 (masked) */ + /* b: p1<<14 | p3 (unmasked) */ + /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + b &= SLOT_2_0; + s = a; + /* s: p0<<14 | p2 (masked) */ + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* we can skip these cause they were (effectively) done above + ** while calculating s */ + /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + /* b &= (0x7f<<14)|(0x7f); */ + b = b<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 5; + } + + /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + s = s<<7; + s |= b; + /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + + p++; + b = b<<14; + b |= *p; + /* b: p1<<28 | p3<<14 | p5 (unmasked) */ + if (!(b&0x80)) + { + /* we can skip this cause it was (effectively) done above in calc'ing s */ + /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + a &= SLOT_2_0; + a = a<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 6; + } + + p++; + a = a<<14; + a |= *p; + /* a: p2<<28 | p4<<14 | p6 (unmasked) */ + if (!(a&0x80)) + { + a &= SLOT_4_2_0; + b &= SLOT_2_0; + b = b<<7; + a |= b; + s = s>>11; + *v = ((u64)s)<<32 | a; + return 7; + } + + /* CSE2 from below */ + a &= SLOT_2_0; + p++; + b = b<<14; + b |= *p; + /* b: p3<<28 | p5<<14 | p7 (unmasked) */ + if (!(b&0x80)) + { + b &= SLOT_4_2_0; + /* moved CSE2 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + s = s>>4; + *v = ((u64)s)<<32 | a; + return 8; + } + + p++; + a = a<<15; + a |= *p; + /* a: p4<<29 | p6<<15 | p8 (unmasked) */ + + /* moved CSE2 up */ + /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ + b &= SLOT_2_0; + b = b<<8; + a |= b; + + s = s<<4; + b = p[-4]; + b &= 0x7f; + b = b>>3; + s |= b; + + *v = ((u64)s)<<32 | a; + + return 9; +} + +/* +** Read a 32-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +** +** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned +** integer, then set *v to 0xffffffff. +** +** A MACRO version, getVarint32, is provided which inlines the +** single-byte case. All code should use the MACRO version as +** this function assumes the single-byte case has already been handled. +*/ +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ + u64 v64; + u8 n; + + /* Assume that the single-byte case has already been handled by + ** the getVarint32() macro */ + assert( (p[0] & 0x80)!=0 ); + + if( (p[1] & 0x80)==0 ){ + /* This is the two-byte case */ + *v = ((p[0]&0x7f)<<7) | p[1]; + return 2; + } + if( (p[2] & 0x80)==0 ){ + /* This is the three-byte case */ + *v = ((p[0]&0x7f)<<14) | ((p[1]&0x7f)<<7) | p[2]; + return 3; + } + /* four or more bytes */ + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ + *v = (u32)v64; + } + return n; +} + +/* +** Return the number of bytes that will be needed to store the given +** 64-bit integer. +*/ +SQLITE_PRIVATE int sqlite3VarintLen(u64 v){ + int i; + for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); } + return i; +} + + +/* +** Read or write a four-byte big-endian integer value. +*/ +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ +#if SQLITE_BYTEORDER==4321 + u32 x; + memcpy(&x,p,4); + return x; +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u32 x; + memcpy(&x,p,4); + return __builtin_bswap32(x); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u32 x; + memcpy(&x,p,4); + return _byteswap_ulong(x); +#else + testcase( p[0]&0x80 ); + return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; +#endif +} +SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ +#if SQLITE_BYTEORDER==4321 + memcpy(p,&v,4); +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u32 x = __builtin_bswap32(v); + memcpy(p,&x,4); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u32 x = _byteswap_ulong(v); + memcpy(p,&x,4); +#else + p[0] = (u8)(v>>24); + p[1] = (u8)(v>>16); + p[2] = (u8)(v>>8); + p[3] = (u8)v; +#endif +} + + + +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +SQLITE_PRIVATE u8 sqlite3HexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} + +#if !defined(SQLITE_OMIT_BLOB_LITERAL) +/* +** Convert a BLOB literal of the form "x'hhhhhh'" into its binary +** value. Return a pointer to its binary value. Space to hold the +** binary value has been obtained from malloc and must be freed by +** the calling routine. +*/ +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ + char *zBlob; + int i; + + zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1); + n--; + if( zBlob ){ + for(i=0; ieOpenState; + if( eOpenState!=SQLITE_STATE_OPEN ){ + if( sqlite3SafetyCheckSickOrOk(db) ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + logBadConnection("unopened"); + } + return 0; + }else{ + return 1; + } +} +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ + u8 eOpenState; + eOpenState = db->eOpenState; + if( eOpenState!=SQLITE_STATE_SICK && + eOpenState!=SQLITE_STATE_OPEN && + eOpenState!=SQLITE_STATE_BUSY ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + logBadConnection("invalid"); + return 0; + }else{ + return 1; + } +} + +/* +** Attempt to add, subtract, or multiply the 64-bit signed value iB against +** the other 64-bit signed integer at *pA and store the result in *pA. +** Return 0 on success. Or if the operation would have resulted in an +** overflow, leave *pA unchanged and return 1. +*/ +SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) + return __builtin_add_overflow(*pA, iB, pA); +#else + i64 iA = *pA; + testcase( iA==0 ); testcase( iA==1 ); + testcase( iB==-1 ); testcase( iB==0 ); + if( iB>=0 ){ + testcase( iA>0 && LARGEST_INT64 - iA == iB ); + testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); + if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; + }else{ + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); + if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; + } + *pA += iB; + return 0; +#endif +} +SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) + return __builtin_sub_overflow(*pA, iB, pA); +#else + testcase( iB==SMALLEST_INT64+1 ); + if( iB==SMALLEST_INT64 ){ + testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); + if( (*pA)>=0 ) return 1; + *pA -= iB; + return 0; + }else{ + return sqlite3AddInt64(pA, -iB); + } +#endif +} +SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) + return __builtin_mul_overflow(*pA, iB, pA); +#else + i64 iA = *pA; + if( iB>0 ){ + if( iA>LARGEST_INT64/iB ) return 1; + if( iA0 ){ + if( iBLARGEST_INT64/-iB ) return 1; + } + } + *pA = iA*iB; + return 0; +#endif +} + +/* +** Compute the absolute value of a 32-bit signed integer, of possible. Or +** if the integer has a value of -2147483648, return +2147483647 +*/ +SQLITE_PRIVATE int sqlite3AbsInt32(int x){ + if( x>=0 ) return x; + if( x==(int)0x80000000 ) return 0x7fffffff; + return -x; +} + +#ifdef SQLITE_ENABLE_8_3_NAMES +/* +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than +** three characters, then shorten the suffix on z[] to be the last three +** characters of the original suffix. +** +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always +** do the suffix shortening regardless of URI parameter. +** +** Examples: +** +** test.db-journal => test.nal +** test.db-wal => test.wal +** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa +*/ +SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ +#if SQLITE_ENABLE_8_3_NAMES<2 + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) +#endif + { + int i, sz; + sz = sqlite3Strlen30(z); + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); + } +} +#endif + +/* +** Find (an approximate) sum of two LogEst values. This computation is +** not a simple "+" operator because LogEst is stored as a logarithmic +** value. +** +*/ +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ + static const unsigned char x[] = { + 10, 10, /* 0,1 */ + 9, 9, /* 2,3 */ + 8, 8, /* 4,5 */ + 7, 7, 7, /* 6,7,8 */ + 6, 6, 6, /* 9,10,11 */ + 5, 5, 5, /* 12-14 */ + 4, 4, 4, 4, /* 15-18 */ + 3, 3, 3, 3, 3, 3, /* 19-24 */ + 2, 2, 2, 2, 2, 2, 2, /* 25-31 */ + }; + if( a>=b ){ + if( a>b+49 ) return a; + if( a>b+31 ) return a+1; + return a+x[a-b]; + }else{ + if( b>a+49 ) return b; + if( b>a+31 ) return b+1; + return b+x[b-a]; + } +} + +/* +** Convert an integer into a LogEst. In other words, compute an +** approximation for 10*log2(x). +*/ +SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ + static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; + LogEst y = 40; + if( x<8 ){ + if( x<2 ) return 0; + while( x<8 ){ y -= 10; x <<= 1; } + }else{ +#if GCC_VERSION>=5004000 + int i = 60 - __builtin_clzll(x); + y += i*10; + x >>= i; +#else + while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ + while( x>15 ){ y += 10; x >>= 1; } +#endif + } + return a[x&7] + y - 10; +} + +/* +** Convert a double into a LogEst +** In other words, compute an approximation for 10*log2(x). +*/ +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ + u64 a; + LogEst e; + assert( sizeof(x)==8 && sizeof(a)==8 ); + if( x<=1 ) return 0; + if( x<=2000000000 ) return sqlite3LogEst((u64)x); + memcpy(&a, &x, 8); + e = (a>>52) - 1022; + return e*10; +} + +/* +** Convert a LogEst into an integer. +*/ +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ + u64 n; + n = x%10; + x /= 10; + if( n>=5 ) n -= 2; + else if( n>=1 ) n -= 1; + if( x>60 ) return (u64)LARGEST_INT64; + return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); +} + +/* +** Add a new name/number pair to a VList. This might require that the +** VList object be reallocated, so return the new VList. If an OOM +** error occurs, the original VList returned and the +** db->mallocFailed flag is set. +** +** A VList is really just an array of integers. To destroy a VList, +** simply pass it to sqlite3DbFree(). +** +** The first integer is the number of integers allocated for the whole +** VList. The second integer is the number of integers actually used. +** Each name/number pair is encoded by subsequent groups of 3 or more +** integers. +** +** Each name/number pair starts with two integers which are the numeric +** value for the pair and the size of the name/number pair, respectively. +** The text name overlays one or more following integers. The text name +** is always zero-terminated. +** +** Conceptually: +** +** struct VList { +** int nAlloc; // Number of allocated slots +** int nUsed; // Number of used slots +** struct VListEntry { +** int iValue; // Value for this entry +** int nSlot; // Slots used by this entry +** // ... variable name goes here +** } a[0]; +** } +** +** During code generation, pointers to the variable names within the +** VList are taken. When that happens, nAlloc is set to zero as an +** indication that the VList may never again be enlarged, since the +** accompanying realloc() would invalidate the pointers. +*/ +SQLITE_PRIVATE VList *sqlite3VListAdd( + sqlite3 *db, /* The database connection used for malloc() */ + VList *pIn, /* The input VList. Might be NULL */ + const char *zName, /* Name of symbol to add */ + int nName, /* Bytes of text in zName */ + int iVal /* Value to associate with zName */ +){ + int nInt; /* number of sizeof(int) objects needed for zName */ + char *z; /* Pointer to where zName will be stored */ + int i; /* Index in pIn[] where zName is stored */ + + nInt = nName/4 + 3; + assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */ + if( pIn==0 || pIn[1]+nInt > pIn[0] ){ + /* Enlarge the allocation */ + sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt; + VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); + if( pOut==0 ) return pIn; + if( pIn==0 ) pOut[1] = 2; + pIn = pOut; + pIn[0] = nAlloc; + } + i = pIn[1]; + pIn[i] = iVal; + pIn[i+1] = nInt; + z = (char*)&pIn[i+2]; + pIn[1] = i+nInt; + assert( pIn[1]<=pIn[0] ); + memcpy(z, zName, nName); + z[nName] = 0; + return pIn; +} + +/* +** Return a pointer to the name of a variable in the given VList that +** has the value iVal. Or return a NULL if there is no such variable in +** the list +*/ +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){ + int i, mx; + if( pIn==0 ) return 0; + mx = pIn[1]; + i = 2; + do{ + if( pIn[i]==iVal ) return (char*)&pIn[i+2]; + i += pIn[i+1]; + }while( i */ + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +*/ +SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){ + assert( pNew!=0 ); + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ + HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + sqlite3_free(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + HashElem *next_elem = elem->next; + sqlite3_free(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** The hashing function. +*/ +static unsigned int strHash(const char *z){ + unsigned int h = 0; + unsigned char c; + while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). + ** 0x9e3779b1 is 2654435761 which is the closest prime number to + ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ + h += sqlite3UpperToLower[c]; + h *= 0x9e3779b1; + } + return h; +} + + +/* Link pNew element into the hash table pH. If pEntry!=0 then also +** insert pNew into the pEntry hash bucket. +*/ +static void insertElement( + Hash *pH, /* The complete hash table */ + struct _ht *pEntry, /* The entry into which pNew is inserted */ + HashElem *pNew /* The element to be inserted */ +){ + HashElem *pHead; /* First element already in pEntry */ + if( pEntry ){ + pHead = pEntry->count ? pEntry->chain : 0; + pEntry->count++; + pEntry->chain = pNew; + }else{ + pHead = 0; + } + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } +} + + +/* Resize the hash table so that it contains "new_size" buckets. +** +** The hash table might fail to resize if sqlite3_malloc() fails or +** if the new size is the same as the prior size. +** Return TRUE if the resize occurs and false if not. +*/ +static int rehash(Hash *pH, unsigned int new_size){ + struct _ht *new_ht; /* The new hash table */ + HashElem *elem, *next_elem; /* For looping over existing elements */ + +#if SQLITE_MALLOC_SOFT_LIMIT>0 + if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ + new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); + } + if( new_size==pH->htsize ) return 0; +#endif + + /* The inability to allocates space for a larger hash table is + ** a performance hit but it is not a fatal error. So mark the + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() + ** only zeroes the requested number of bytes whereas this module will + ** use the actual amount of space allocated for the hash table (which + ** may be larger than the requested amount). + */ + sqlite3BeginBenignMalloc(); + new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); + sqlite3EndBenignMalloc(); + + if( new_ht==0 ) return 0; + sqlite3_free(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); + memset(new_ht, 0, new_size*sizeof(struct _ht)); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + unsigned int h = strHash(elem->pKey) % new_size; + next_elem = elem->next; + insertElement(pH, &new_ht[h], elem); + } + return 1; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. If no element is found, +** a pointer to a static null element with HashElem.data==0 is returned. +** If pH is not NULL, then the hash for this key is written to *pH. +*/ +static HashElem *findElementWithHash( + const Hash *pH, /* The pH to be searched */ + const char *pKey, /* The key we are searching for */ + unsigned int *pHash /* Write the hash value here */ +){ + HashElem *elem; /* Used to loop thru the element list */ + unsigned int count; /* Number of elements left to test */ + unsigned int h; /* The computed hash */ + static HashElem nullElement = { 0, 0, 0, 0 }; + + if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ + struct _ht *pEntry; + h = strHash(pKey) % pH->htsize; + pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + }else{ + h = 0; + elem = pH->first; + count = pH->count; + } + if( pHash ) *pHash = h; + while( count ){ + assert( elem!=0 ); + if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ + return elem; + } + elem = elem->next; + count--; + } + return &nullElement; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void removeElementGivenHash( + Hash *pH, /* The pH containing "elem" */ + HashElem* elem, /* The element to be removed from the pH */ + unsigned int h /* Hash value for the element */ +){ + struct _ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + if( pH->ht ){ + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + assert( pEntry->count>0 ); + pEntry->count--; + } + sqlite3_free( elem ); + pH->count--; + if( pH->count==0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + sqlite3HashClear(pH); + } +} + +/* Attempt to locate an element of the hash table pH with a key +** that matches pKey. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ + assert( pH!=0 ); + assert( pKey!=0 ); + return findElementWithHash(pH, pKey, 0)->data; +} + +/* Insert an element into the hash table pH. The key is pKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created and NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ + unsigned int h; /* the hash of the key modulo hash table size */ + HashElem *elem; /* Used to loop thru the element list */ + HashElem *new_elem; /* New element added to the pH */ + + assert( pH!=0 ); + assert( pKey!=0 ); + elem = findElementWithHash(pH,pKey,&h); + if( elem->data ){ + void *old_data = elem->data; + if( data==0 ){ + removeElementGivenHash(pH,elem,h); + }else{ + elem->data = data; + elem->pKey = pKey; + } + return old_data; + } + if( data==0 ) return 0; + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); + if( new_elem==0 ) return data; + new_elem->pKey = pKey; + new_elem->data = data; + pH->count++; + if( pH->count>=10 && pH->count > 2*pH->htsize ){ + if( rehash(pH, pH->count*2) ){ + assert( pH->htsize>0 ); + h = strHash(pKey) % pH->htsize; + } + } + insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); + return 0; +} + +/************** End of hash.c ************************************************/ +/************** Begin file opcodes.c *****************************************/ +/* Automatically generated. Do not edit */ +/* See the tool/mkopcodec.tcl script for details. */ +#if !defined(SQLITE_OMIT_EXPLAIN) \ + || defined(VDBE_PROFILE) \ + || defined(SQLITE_DEBUG) +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG) +# define OpHelp(X) "\0" X +#else +# define OpHelp(X) +#endif +SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + static const char *const azName[] = { + /* 0 */ "Savepoint" OpHelp(""), + /* 1 */ "AutoCommit" OpHelp(""), + /* 2 */ "Transaction" OpHelp(""), + /* 3 */ "Checkpoint" OpHelp(""), + /* 4 */ "JournalMode" OpHelp(""), + /* 5 */ "Vacuum" OpHelp(""), + /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), + /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), + /* 8 */ "Init" OpHelp("Start at P2"), + /* 9 */ "Goto" OpHelp(""), + /* 10 */ "Gosub" OpHelp(""), + /* 11 */ "InitCoroutine" OpHelp(""), + /* 12 */ "Yield" OpHelp(""), + /* 13 */ "MustBeInt" OpHelp(""), + /* 14 */ "Jump" OpHelp(""), + /* 15 */ "Once" OpHelp(""), + /* 16 */ "If" OpHelp(""), + /* 17 */ "IfNot" OpHelp(""), + /* 18 */ "IsType" OpHelp("if typeof(P1.P3) in P5 goto P2"), + /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), + /* 20 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), + /* 21 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), + /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 29 */ "Found" OpHelp("key=r[P3@P4]"), + /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 32 */ "Last" OpHelp(""), + /* 33 */ "IfSmaller" OpHelp(""), + /* 34 */ "SorterSort" OpHelp(""), + /* 35 */ "Sort" OpHelp(""), + /* 36 */ "Rewind" OpHelp(""), + /* 37 */ "SorterNext" OpHelp(""), + /* 38 */ "Prev" OpHelp(""), + /* 39 */ "Next" OpHelp(""), + /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), + /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), + /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 48 */ "Program" OpHelp(""), + /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 58 */ "ElseEq" OpHelp(""), + /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 62 */ "IncrVacuum" OpHelp(""), + /* 63 */ "VNext" OpHelp(""), + /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), + /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), + /* 67 */ "Return" OpHelp(""), + /* 68 */ "EndCoroutine" OpHelp(""), + /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 70 */ "Halt" OpHelp(""), + /* 71 */ "Integer" OpHelp("r[P2]=P1"), + /* 72 */ "Int64" OpHelp("r[P2]=P4"), + /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 74 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), + /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 83 */ "FkCheck" OpHelp(""), + /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 85 */ "CollSeq" OpHelp(""), + /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 87 */ "RealAffinity" OpHelp(""), + /* 88 */ "Cast" OpHelp("affinity(r[P1])"), + /* 89 */ "Permutation" OpHelp(""), + /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), + /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 94 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), + /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), + /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 98 */ "Count" OpHelp("r[P2]=count()"), + /* 99 */ "ReadCookie" OpHelp(""), + /* 100 */ "SetCookie" OpHelp(""), + /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 115 */ "OpenDup" OpHelp(""), + /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 117 */ "String8" OpHelp("r[P2]='P4'"), + /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 119 */ "SorterOpen" OpHelp(""), + /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 122 */ "Close" OpHelp(""), + /* 123 */ "ColumnsUsed" OpHelp(""), + /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 129 */ "RowCell" OpHelp(""), + /* 130 */ "Delete" OpHelp(""), + /* 131 */ "ResetCount" OpHelp(""), + /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 133 */ "SorterData" OpHelp("r[P2]=data"), + /* 134 */ "RowData" OpHelp("r[P2]=data"), + /* 135 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), + /* 136 */ "NullRow" OpHelp(""), + /* 137 */ "SeekEnd" OpHelp(""), + /* 138 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 139 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 143 */ "FinishSeek" OpHelp(""), + /* 144 */ "Destroy" OpHelp(""), + /* 145 */ "Clear" OpHelp(""), + /* 146 */ "ResetSorter" OpHelp(""), + /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 148 */ "SqlExec" OpHelp(""), + /* 149 */ "ParseSchema" OpHelp(""), + /* 150 */ "LoadAnalysis" OpHelp(""), + /* 151 */ "DropTable" OpHelp(""), + /* 152 */ "DropIndex" OpHelp(""), + /* 153 */ "Real" OpHelp("r[P2]=P4"), + /* 154 */ "DropTrigger" OpHelp(""), + /* 155 */ "IntegrityCk" OpHelp(""), + /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 157 */ "Param" OpHelp(""), + /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 166 */ "Expire" OpHelp(""), + /* 167 */ "CursorLock" OpHelp(""), + /* 168 */ "CursorUnlock" OpHelp(""), + /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 170 */ "VBegin" OpHelp(""), + /* 171 */ "VCreate" OpHelp(""), + /* 172 */ "VDestroy" OpHelp(""), + /* 173 */ "VOpen" OpHelp(""), + /* 174 */ "VCheck" OpHelp(""), + /* 175 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 177 */ "VRename" OpHelp(""), + /* 178 */ "Pagecount" OpHelp(""), + /* 179 */ "MaxPgcnt" OpHelp(""), + /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), + /* 181 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), + /* 182 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), + /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 184 */ "Trace" OpHelp(""), + /* 185 */ "CursorHint" OpHelp(""), + /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 187 */ "Noop" OpHelp(""), + /* 188 */ "Explain" OpHelp(""), + /* 189 */ "Abortable" OpHelp(""), + }; + return azName[i]; +} +#endif + +/************** End of opcodes.c *********************************************/ +/************** Begin file os_kv.c *******************************************/ +/* +** 2022-09-06 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains an experimental VFS layer that operates on a +** Key/Value storage engine where both keys and values must be pure +** text. +*/ +/* #include */ +#if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) + +/***************************************************************************** +** Debugging logic +*/ + +/* SQLITE_KV_TRACE() is used for tracing calls to kvstorage routines. */ +#if 0 +#define SQLITE_KV_TRACE(X) printf X +#else +#define SQLITE_KV_TRACE(X) +#endif + +/* SQLITE_KV_LOG() is used for tracing calls to the VFS interface */ +#if 0 +#define SQLITE_KV_LOG(X) printf X +#else +#define SQLITE_KV_LOG(X) +#endif + + +/* +** Forward declaration of objects used by this VFS implementation +*/ +typedef struct KVVfsFile KVVfsFile; + +/* A single open file. There are only two files represented by this +** VFS - the database and the rollback journal. +*/ +struct KVVfsFile { + sqlite3_file base; /* IO methods */ + const char *zClass; /* Storage class */ + int isJournal; /* True if this is a journal file */ + unsigned int nJrnl; /* Space allocated for aJrnl[] */ + char *aJrnl; /* Journal content */ + int szPage; /* Last known page size */ + sqlite3_int64 szDb; /* Database file size. -1 means unknown */ + char *aData; /* Buffer to hold page data */ +}; +#define SQLITE_KVOS_SZ 133073 + +/* +** Methods for KVVfsFile +*/ +static int kvvfsClose(sqlite3_file*); +static int kvvfsReadDb(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int kvvfsReadJrnl(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int kvvfsWriteDb(sqlite3_file*,const void*,int iAmt, sqlite3_int64); +static int kvvfsWriteJrnl(sqlite3_file*,const void*,int iAmt, sqlite3_int64); +static int kvvfsTruncateDb(sqlite3_file*, sqlite3_int64 size); +static int kvvfsTruncateJrnl(sqlite3_file*, sqlite3_int64 size); +static int kvvfsSyncDb(sqlite3_file*, int flags); +static int kvvfsSyncJrnl(sqlite3_file*, int flags); +static int kvvfsFileSizeDb(sqlite3_file*, sqlite3_int64 *pSize); +static int kvvfsFileSizeJrnl(sqlite3_file*, sqlite3_int64 *pSize); +static int kvvfsLock(sqlite3_file*, int); +static int kvvfsUnlock(sqlite3_file*, int); +static int kvvfsCheckReservedLock(sqlite3_file*, int *pResOut); +static int kvvfsFileControlDb(sqlite3_file*, int op, void *pArg); +static int kvvfsFileControlJrnl(sqlite3_file*, int op, void *pArg); +static int kvvfsSectorSize(sqlite3_file*); +static int kvvfsDeviceCharacteristics(sqlite3_file*); + +/* +** Methods for sqlite3_vfs +*/ +static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int kvvfsAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int kvvfsFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *kvvfsDlOpen(sqlite3_vfs*, const char *zFilename); +static int kvvfsRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int kvvfsSleep(sqlite3_vfs*, int microseconds); +static int kvvfsCurrentTime(sqlite3_vfs*, double*); +static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs sqlite3OsKvvfsObject = { + 1, /* iVersion */ + sizeof(KVVfsFile), /* szOsFile */ + 1024, /* mxPathname */ + 0, /* pNext */ + "kvvfs", /* zName */ + 0, /* pAppData */ + kvvfsOpen, /* xOpen */ + kvvfsDelete, /* xDelete */ + kvvfsAccess, /* xAccess */ + kvvfsFullPathname, /* xFullPathname */ + kvvfsDlOpen, /* xDlOpen */ + 0, /* xDlError */ + 0, /* xDlSym */ + 0, /* xDlClose */ + kvvfsRandomness, /* xRandomness */ + kvvfsSleep, /* xSleep */ + kvvfsCurrentTime, /* xCurrentTime */ + 0, /* xGetLastError */ + kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */ +}; + +/* Methods for sqlite3_file objects referencing a database file +*/ +static sqlite3_io_methods kvvfs_db_io_methods = { + 1, /* iVersion */ + kvvfsClose, /* xClose */ + kvvfsReadDb, /* xRead */ + kvvfsWriteDb, /* xWrite */ + kvvfsTruncateDb, /* xTruncate */ + kvvfsSyncDb, /* xSync */ + kvvfsFileSizeDb, /* xFileSize */ + kvvfsLock, /* xLock */ + kvvfsUnlock, /* xUnlock */ + kvvfsCheckReservedLock, /* xCheckReservedLock */ + kvvfsFileControlDb, /* xFileControl */ + kvvfsSectorSize, /* xSectorSize */ + kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/* Methods for sqlite3_file objects referencing a rollback journal +*/ +static sqlite3_io_methods kvvfs_jrnl_io_methods = { + 1, /* iVersion */ + kvvfsClose, /* xClose */ + kvvfsReadJrnl, /* xRead */ + kvvfsWriteJrnl, /* xWrite */ + kvvfsTruncateJrnl, /* xTruncate */ + kvvfsSyncJrnl, /* xSync */ + kvvfsFileSizeJrnl, /* xFileSize */ + kvvfsLock, /* xLock */ + kvvfsUnlock, /* xUnlock */ + kvvfsCheckReservedLock, /* xCheckReservedLock */ + kvvfsFileControlJrnl, /* xFileControl */ + kvvfsSectorSize, /* xSectorSize */ + kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/****** Storage subsystem **************************************************/ +#include +#include +#include + +/* Forward declarations for the low-level storage engine +*/ +static int kvstorageWrite(const char*, const char *zKey, const char *zData); +static int kvstorageDelete(const char*, const char *zKey); +static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf); +#define KVSTORAGE_KEY_SZ 32 + +/* Expand the key name with an appropriate prefix and put the result +** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least +** KVSTORAGE_KEY_SZ bytes. +*/ +static void kvstorageMakeKey( + const char *zClass, + const char *zKeyIn, + char *zKeyOut +){ + sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); +} + +/* Write content into a key. zClass is the particular namespace of the +** underlying key/value store to use - either "local" or "session". +** +** Both zKey and zData are zero-terminated pure text strings. +** +** Return the number of errors. +*/ +static int kvstorageWrite( + const char *zClass, + const char *zKey, + const char *zData +){ + FILE *fd; + char zXKey[KVSTORAGE_KEY_SZ]; + kvstorageMakeKey(zClass, zKey, zXKey); + fd = fopen(zXKey, "wb"); + if( fd ){ + SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, + (int)strlen(zData), zData, + strlen(zData)>50 ? "..." : "")); + fputs(zData, fd); + fclose(fd); + return 0; + }else{ + return 1; + } +} + +/* Delete a key (with its corresponding data) from the key/value +** namespace given by zClass. If the key does not previously exist, +** this routine is a no-op. +*/ +static int kvstorageDelete(const char *zClass, const char *zKey){ + char zXKey[KVSTORAGE_KEY_SZ]; + kvstorageMakeKey(zClass, zKey, zXKey); + unlink(zXKey); + SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); + return 0; +} + +/* Read the value associated with a zKey from the key/value namespace given +** by zClass and put the text data associated with that key in the first +** nBuf bytes of zBuf[]. The value might be truncated if zBuf is not large +** enough to hold it all. The value put into zBuf must always be zero +** terminated, even if it gets truncated because nBuf is not large enough. +** +** Return the total number of bytes in the data, without truncation, and +** not counting the final zero terminator. Return -1 if the key does +** not exist. +** +** If nBuf<=0 then this routine simply returns the size of the data without +** actually reading it. +*/ +static int kvstorageRead( + const char *zClass, + const char *zKey, + char *zBuf, + int nBuf +){ + FILE *fd; + struct stat buf; + char zXKey[KVSTORAGE_KEY_SZ]; + kvstorageMakeKey(zClass, zKey, zXKey); + if( access(zXKey, R_OK)!=0 + || stat(zXKey, &buf)!=0 + || !S_ISREG(buf.st_mode) + ){ + SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); + return -1; + } + if( nBuf<=0 ){ + return (int)buf.st_size; + }else if( nBuf==1 ){ + zBuf[0] = 0; + SQLITE_KV_TRACE(("KVVFS-READ %-15s (%d)\n", zXKey, + (int)buf.st_size)); + return (int)buf.st_size; + } + if( nBuf > buf.st_size + 1 ){ + nBuf = buf.st_size + 1; + } + fd = fopen(zXKey, "rb"); + if( fd==0 ){ + SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); + return -1; + }else{ + sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd); + fclose(fd); + zBuf[n] = 0; + SQLITE_KV_TRACE(("KVVFS-READ %-15s (%lld) %.50s%s\n", zXKey, + n, zBuf, n>50 ? "..." : "")); + return (int)n; + } +} + +/* +** An internal level of indirection which enables us to replace the +** kvvfs i/o methods with JavaScript implementations in WASM builds. +** Maintenance reminder: if this struct changes in any way, the JSON +** rendering of its structure must be updated in +** sqlite3_wasm_enum_json(). There are no binary compatibility +** concerns, so it does not need an iVersion member. This file is +** necessarily always compiled together with sqlite3_wasm_enum_json(), +** and JS code dynamically creates the mapping of members based on +** that JSON description. +*/ +typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; +struct sqlite3_kvvfs_methods { + int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf); + int (*xWrite)(const char *zClass, const char *zKey, const char *zData); + int (*xDelete)(const char *zClass, const char *zKey); + const int nKeySize; +}; + +/* +** This object holds the kvvfs I/O methods which may be swapped out +** for JavaScript-side implementations in WASM builds. In such builds +** it cannot be const, but in native builds it should be so that +** the compiler can hopefully optimize this level of indirection out. +** That said, kvvfs is intended primarily for use in WASM builds. +** +** Note that this is not explicitly flagged as static because the +** amalgamation build will tag it with SQLITE_PRIVATE. +*/ +#ifndef SQLITE_WASM +const +#endif +SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { +kvstorageRead, +kvstorageWrite, +kvstorageDelete, +KVSTORAGE_KEY_SZ +}; + +/****** Utility subroutines ************************************************/ + +/* +** Encode binary into the text encoded used to persist on disk. +** The output text is stored in aOut[], which must be at least +** nData+1 bytes in length. +** +** Return the actual length of the encoded text, not counting the +** zero terminator at the end. +** +** Encoding format +** --------------- +** +** * Non-zero bytes are encoded as upper-case hexadecimal +** +** * A sequence of one or more zero-bytes that are not at the +** beginning of the buffer are encoded as a little-endian +** base-26 number using a..z. "a" means 0. "b" means 1, +** "z" means 25. "ab" means 26. "ac" means 52. And so forth. +** +** * Because there is no overlap between the encoding characters +** of hexadecimal and base-26 numbers, it is always clear where +** one stops and the next begins. +*/ +static int kvvfsEncode(const char *aData, int nData, char *aOut){ + int i, j; + const unsigned char *a = (const unsigned char*)aData; + for(i=j=0; i>4]; + aOut[j++] = "0123456789ABCDEF"[c&0xf]; + }else{ + /* A sequence of 1 or more zeros is stored as a little-endian + ** base-26 number using a..z as the digits. So one zero is "b". + ** Two zeros is "c". 25 zeros is "z", 26 zeros is "ab", 27 is "bb", + ** and so forth. + */ + int k; + for(k=1; i+k0 ){ + aOut[j++] = 'a'+(k%26); + k /= 26; + } + } + } + aOut[j] = 0; + return j; +} + +static const signed char kvvfsHexValue[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* +** Decode the text encoding back to binary. The binary content is +** written into pOut, which must be at least nOut bytes in length. +** +** The return value is the number of bytes actually written into aOut[]. +*/ +static int kvvfsDecode(const char *a, char *aOut, int nOut){ + int i, j; + int c; + const unsigned char *aIn = (const unsigned char*)a; + i = 0; + j = 0; + while( 1 ){ + c = kvvfsHexValue[aIn[i]]; + if( c<0 ){ + int n = 0; + int mult = 1; + c = aIn[i]; + if( c==0 ) break; + while( c>='a' && c<='z' ){ + n += (c - 'a')*mult; + mult *= 26; + c = aIn[++i]; + } + if( j+n>nOut ) return -1; + memset(&aOut[j], 0, n); + j += n; + if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ + }else{ + aOut[j] = c<<4; + c = kvvfsHexValue[aIn[++i]]; + if( c<0 ) break; + aOut[j++] += c; + i++; + } + } + return j; +} + +/* +** Decode a complete journal file. Allocate space in pFile->aJrnl +** and store the decoding there. Or leave pFile->aJrnl set to NULL +** if an error is encountered. +** +** The first few characters of the text encoding will be a little-endian +** base-26 number (digits a..z) that is the total number of bytes +** in the decoded journal file image. This base-26 number is followed +** by a single space, then the encoding of the journal. The space +** separator is required to act as a terminator for the base-26 number. +*/ +static void kvvfsDecodeJournal( + KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */ + const char *zTxt, /* Text encoding. Zero-terminated */ + int nTxt /* Bytes in zTxt, excluding zero terminator */ +){ + unsigned int n = 0; + int c, i, mult; + i = 0; + mult = 1; + while( (c = zTxt[i++])>='a' && c<='z' ){ + n += (zTxt[i] - 'a')*mult; + mult *= 26; + } + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = sqlite3_malloc64( n ); + if( pFile->aJrnl==0 ){ + pFile->nJrnl = 0; + return; + } + pFile->nJrnl = n; + n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl); + if( nnJrnl ){ + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = 0; + pFile->nJrnl = 0; + } +} + +/* +** Read or write the "sz" element, containing the database file size. +*/ +static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ + char zData[50]; + zData[0] = 0; + sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1); + return strtoll(zData, 0, 0); +} +static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){ + char zData[50]; + sqlite3_snprintf(sizeof(zData), zData, "%lld", sz); + return sqlite3KvvfsMethods.xWrite(pFile->zClass, "sz", zData); +} + +/****** sqlite3_io_methods methods ******************************************/ + +/* +** Close an kvvfs-file. +*/ +static int kvvfsClose(sqlite3_file *pProtoFile){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + + SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass, + pFile->isJournal ? "journal" : "db")); + sqlite3_free(pFile->aJrnl); + sqlite3_free(pFile->aData); + return SQLITE_OK; +} + +/* +** Read from the -journal file. +*/ +static int kvvfsReadJrnl( + sqlite3_file *pProtoFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + assert( pFile->isJournal ); + SQLITE_KV_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + if( pFile->aJrnl==0 ){ + int szTxt = kvstorageRead(pFile->zClass, "jrnl", 0, 0); + char *aTxt; + if( szTxt<=4 ){ + return SQLITE_IOERR; + } + aTxt = sqlite3_malloc64( szTxt+1 ); + if( aTxt==0 ) return SQLITE_NOMEM; + kvstorageRead(pFile->zClass, "jrnl", aTxt, szTxt+1); + kvvfsDecodeJournal(pFile, aTxt, szTxt); + sqlite3_free(aTxt); + if( pFile->aJrnl==0 ) return SQLITE_IOERR; + } + if( iOfst+iAmt>pFile->nJrnl ){ + return SQLITE_IOERR_SHORT_READ; + } + memcpy(zBuf, pFile->aJrnl+iOfst, iAmt); + return SQLITE_OK; +} + +/* +** Read from the database file. +*/ +static int kvvfsReadDb( + sqlite3_file *pProtoFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + unsigned int pgno; + int got, n; + char zKey[30]; + char *aData = pFile->aData; + assert( iOfst>=0 ); + assert( iAmt>=0 ); + SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + if( iOfst+iAmt>=512 ){ + if( (iOfst % iAmt)!=0 ){ + return SQLITE_IOERR_READ; + } + if( (iAmt & (iAmt-1))!=0 || iAmt<512 || iAmt>65536 ){ + return SQLITE_IOERR_READ; + } + pFile->szPage = iAmt; + pgno = 1 + iOfst/iAmt; + }else{ + pgno = 1; + } + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); + got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, + aData, SQLITE_KVOS_SZ-1); + if( got<0 ){ + n = 0; + }else{ + aData[got] = 0; + if( iOfst+iAmt<512 ){ + int k = iOfst+iAmt; + aData[k*2] = 0; + n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000); + if( n>=iOfst+iAmt ){ + memcpy(zBuf, &aData[2000+iOfst], iAmt); + n = iAmt; + }else{ + n = 0; + } + }else{ + n = kvvfsDecode(aData, zBuf, iAmt); + } + } + if( nzClass, iAmt, iOfst)); + if( iEnd>=0x10000000 ) return SQLITE_FULL; + if( pFile->aJrnl==0 || pFile->nJrnlaJrnl, iEnd); + if( aNew==0 ){ + return SQLITE_IOERR_NOMEM; + } + pFile->aJrnl = aNew; + if( pFile->nJrnlaJrnl+pFile->nJrnl, 0, iOfst-pFile->nJrnl); + } + pFile->nJrnl = iEnd; + } + memcpy(pFile->aJrnl+iOfst, zBuf, iAmt); + return SQLITE_OK; +} + +/* +** Write into the database file. +*/ +static int kvvfsWriteDb( + sqlite3_file *pProtoFile, + const void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + unsigned int pgno; + char zKey[30]; + char *aData = pFile->aData; + SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + assert( iAmt>=512 && iAmt<=65536 ); + assert( (iAmt & (iAmt-1))==0 ); + assert( pFile->szPage<0 || pFile->szPage==iAmt ); + pFile->szPage = iAmt; + pgno = 1 + iOfst/iAmt; + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); + kvvfsEncode(zBuf, iAmt, aData); + if( sqlite3KvvfsMethods.xWrite(pFile->zClass, zKey, aData) ){ + return SQLITE_IOERR; + } + if( iOfst+iAmt > pFile->szDb ){ + pFile->szDb = iOfst + iAmt; + } + return SQLITE_OK; +} + +/* +** Truncate an kvvfs-file. +*/ +static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + SQLITE_KV_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size)); + assert( size==0 ); + sqlite3KvvfsMethods.xDelete(pFile->zClass, "jrnl"); + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = 0; + pFile->nJrnl = 0; + return SQLITE_OK; +} +static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + if( pFile->szDb>size + && pFile->szPage>0 + && (size % pFile->szPage)==0 + ){ + char zKey[50]; + unsigned int pgno, pgnoMax; + SQLITE_KV_LOG(("xTruncate('%s-db',%lld)\n", pFile->zClass, size)); + pgno = 1 + size/pFile->szPage; + pgnoMax = 2 + pFile->szDb/pFile->szPage; + while( pgno<=pgnoMax ){ + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); + sqlite3KvvfsMethods.xDelete(pFile->zClass, zKey); + pgno++; + } + pFile->szDb = size; + return kvvfsWriteFileSize(pFile, size) ? SQLITE_IOERR : SQLITE_OK; + } + return SQLITE_IOERR; +} + +/* +** Sync an kvvfs-file. +*/ +static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ + int i, n; + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + char *zOut; + SQLITE_KV_LOG(("xSync('%s-journal')\n", pFile->zClass)); + if( pFile->nJrnl<=0 ){ + return kvvfsTruncateJrnl(pProtoFile, 0); + } + zOut = sqlite3_malloc64( pFile->nJrnl*2 + 50 ); + if( zOut==0 ){ + return SQLITE_IOERR_NOMEM; + } + n = pFile->nJrnl; + i = 0; + do{ + zOut[i++] = 'a' + (n%26); + n /= 26; + }while( n>0 ); + zOut[i++] = ' '; + kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); + i = sqlite3KvvfsMethods.xWrite(pFile->zClass, "jrnl", zOut); + sqlite3_free(zOut); + return i ? SQLITE_IOERR : SQLITE_OK; +} +static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){ + return SQLITE_OK; +} + +/* +** Return the current file-size of an kvvfs-file. +*/ +static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + SQLITE_KV_LOG(("xFileSize('%s-journal')\n", pFile->zClass)); + *pSize = pFile->nJrnl; + return SQLITE_OK; +} +static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + SQLITE_KV_LOG(("xFileSize('%s-db')\n", pFile->zClass)); + if( pFile->szDb>=0 ){ + *pSize = pFile->szDb; + }else{ + *pSize = kvvfsReadFileSize(pFile); + } + return SQLITE_OK; +} + +/* +** Lock an kvvfs-file. +*/ +static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + assert( !pFile->isJournal ); + SQLITE_KV_LOG(("xLock(%s,%d)\n", pFile->zClass, eLock)); + + if( eLock!=SQLITE_LOCK_NONE ){ + pFile->szDb = kvvfsReadFileSize(pFile); + } + return SQLITE_OK; +} + +/* +** Unlock an kvvfs-file. +*/ +static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + assert( !pFile->isJournal ); + SQLITE_KV_LOG(("xUnlock(%s,%d)\n", pFile->zClass, eLock)); + if( eLock==SQLITE_LOCK_NONE ){ + pFile->szDb = -1; + } + return SQLITE_OK; +} + +/* +** Check if another file-handle holds a RESERVED lock on an kvvfs-file. +*/ +static int kvvfsCheckReservedLock(sqlite3_file *pProtoFile, int *pResOut){ + SQLITE_KV_LOG(("xCheckReservedLock\n")); + *pResOut = 0; + return SQLITE_OK; +} + +/* +** File control method. For custom operations on an kvvfs-file. +*/ +static int kvvfsFileControlJrnl(sqlite3_file *pProtoFile, int op, void *pArg){ + SQLITE_KV_LOG(("xFileControl(%d) on journal\n", op)); + return SQLITE_NOTFOUND; +} +static int kvvfsFileControlDb(sqlite3_file *pProtoFile, int op, void *pArg){ + SQLITE_KV_LOG(("xFileControl(%d) on database\n", op)); + if( op==SQLITE_FCNTL_SYNC ){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + int rc = SQLITE_OK; + SQLITE_KV_LOG(("xSync('%s-db')\n", pFile->zClass)); + if( pFile->szDb>0 && 0!=kvvfsWriteFileSize(pFile, pFile->szDb) ){ + rc = SQLITE_IOERR; + } + return rc; + } + return SQLITE_NOTFOUND; +} + +/* +** Return the sector-size in bytes for an kvvfs-file. +*/ +static int kvvfsSectorSize(sqlite3_file *pFile){ + return 512; +} + +/* +** Return the device characteristic flags supported by an kvvfs-file. +*/ +static int kvvfsDeviceCharacteristics(sqlite3_file *pProtoFile){ + return 0; +} + +/****** sqlite3_vfs methods *************************************************/ + +/* +** Open an kvvfs file handle. +*/ +static int kvvfsOpen( + sqlite3_vfs *pProtoVfs, + const char *zName, + sqlite3_file *pProtoFile, + int flags, + int *pOutFlags +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + if( zName==0 ) zName = ""; + SQLITE_KV_LOG(("xOpen(\"%s\")\n", zName)); + if( strcmp(zName, "local")==0 + || strcmp(zName, "session")==0 + ){ + pFile->isJournal = 0; + pFile->base.pMethods = &kvvfs_db_io_methods; + }else + if( strcmp(zName, "local-journal")==0 + || strcmp(zName, "session-journal")==0 + ){ + pFile->isJournal = 1; + pFile->base.pMethods = &kvvfs_jrnl_io_methods; + }else{ + return SQLITE_CANTOPEN; + } + if( zName[0]=='s' ){ + pFile->zClass = "session"; + }else{ + pFile->zClass = "local"; + } + pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); + if( pFile->aData==0 ){ + return SQLITE_NOMEM; + } + pFile->aJrnl = 0; + pFile->nJrnl = 0; + pFile->szPage = -1; + pFile->szDb = -1; + return SQLITE_OK; +} + +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + if( strcmp(zPath, "local-journal")==0 ){ + sqlite3KvvfsMethods.xDelete("local", "jrnl"); + }else + if( strcmp(zPath, "session-journal")==0 ){ + sqlite3KvvfsMethods.xDelete("session", "jrnl"); + } + return SQLITE_OK; +} + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +*/ +static int kvvfsAccess( + sqlite3_vfs *pProtoVfs, + const char *zPath, + int flags, + int *pResOut +){ + SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); + if( strcmp(zPath, "local-journal")==0 ){ + *pResOut = sqlite3KvvfsMethods.xRead("local", "jrnl", 0, 0)>0; + }else + if( strcmp(zPath, "session-journal")==0 ){ + *pResOut = sqlite3KvvfsMethods.xRead("session", "jrnl", 0, 0)>0; + }else + if( strcmp(zPath, "local")==0 ){ + *pResOut = sqlite3KvvfsMethods.xRead("local", "sz", 0, 0)>0; + }else + if( strcmp(zPath, "session")==0 ){ + *pResOut = sqlite3KvvfsMethods.xRead("session", "sz", 0, 0)>0; + }else + { + *pResOut = 0; + } + SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); + return SQLITE_OK; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int kvvfsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + size_t nPath; +#ifdef SQLITE_OS_KV_ALWAYS_LOCAL + zPath = "local"; +#endif + nPath = strlen(zPath); + SQLITE_KV_LOG(("xFullPathname(\"%s\")\n", zPath)); + if( nOut +static int kvvfsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + struct timeval sNow; + (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ + *pTimeOut = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; + return SQLITE_OK; +} +#endif /* SQLITE_OS_KV || SQLITE_OS_UNIX */ + +#if SQLITE_OS_KV +/* +** This routine is called initialize the KV-vfs as the default VFS. +*/ +SQLITE_API int sqlite3_os_init(void){ + return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 1); +} +SQLITE_API int sqlite3_os_end(void){ + return SQLITE_OK; +} +#endif /* SQLITE_OS_KV */ + +#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) +SQLITE_PRIVATE int sqlite3KvvfsInit(void){ + return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 0); +} +#endif + +/************** End of os_kv.c ***********************************************/ +/************** Begin file os_unix.c *****************************************/ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains the VFS implementation for unix-like operating systems +** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others. +** +** There are actually several different VFS implementations in this file. +** The differences are in the way that file locking is done. The default +** implementation uses Posix Advisory Locks. Alternative implementations +** use flock(), dot-files, various proprietary locking schemas, or simply +** skip locking all together. +** +** This source file is organized into divisions where the logic for various +** subfunctions is contained within the appropriate division. PLEASE +** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed +** in the correct division and should be clearly labelled. +** +** The layout of divisions is as follows: +** +** * General-purpose declarations and utility functions. +** * Unique file ID logic used by VxWorks. +** * Various locking primitive implementations (all except proxy locking): +** + for Posix Advisory Locks +** + for no-op locks +** + for dot-file locks +** + for flock() locking +** + for named semaphore locks (VxWorks only) +** + for AFP filesystem locks (MacOSX only) +** * sqlite3_file methods not associated with locking. +** * Definitions of sqlite3_io_methods objects for all locking +** methods plus "finder" functions for each locking method. +** * sqlite3_vfs method implementations. +** * Locking primitives for the proxy uber-locking-method. (MacOSX only) +** * Definitions of sqlite3_vfs objects for all locking methods +** plus implementations of sqlite3_os_init() and sqlite3_os_end(). +*/ +/* #include "sqliteInt.h" */ +#if SQLITE_OS_UNIX /* This file is used on unix only */ + +/* +** There are various methods for file locking used for concurrency +** control: +** +** 1. POSIX locking (the default), +** 2. No locking, +** 3. Dot-file locking, +** 4. flock() locking, +** 5. AFP locking (OSX only), +** 6. Named POSIX semaphores (VXWorks only), +** 7. proxy locking. (OSX only) +** +** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE +** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic +** selection of the appropriate locking style based on the filesystem +** where the database is located. +*/ +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/* Use pread() and pwrite() if they are available */ +#if defined(__APPLE__) || defined(__linux__) +# define HAVE_PREAD 1 +# define HAVE_PWRITE 1 +#endif +#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64) +# undef USE_PREAD +# define USE_PREAD64 1 +#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE) +# undef USE_PREAD64 +# define USE_PREAD 1 +#endif + +/* +** standard include files. +*/ +#include /* amalgamator: keep */ +#include /* amalgamator: keep */ +#include +#include +#include /* amalgamator: keep */ +/* #include */ +#include /* amalgamator: keep */ +#include +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_WASI) +# include +#endif + +#if SQLITE_ENABLE_LOCKING_STYLE +/* # include */ +# include +# include +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + +/* +** Try to determine if gethostuuid() is available based on standard +** macros. This might sometimes compute the wrong value for some +** obscure platforms. For those cases, simply compile with one of +** the following: +** +** -DHAVE_GETHOSTUUID=0 +** -DHAVE_GETHOSTUUID=1 +** +** None if this matters except when building on Apple products with +** -DSQLITE_ENABLE_LOCKING_STYLE. +*/ +#ifndef HAVE_GETHOSTUUID +# define HAVE_GETHOSTUUID 0 +# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ + (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) +# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\ + && (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0)) +# undef HAVE_GETHOSTUUID +# define HAVE_GETHOSTUUID 1 +# else +# warning "gethostuuid() is disabled." +# endif +# endif +#endif + + +#if OS_VXWORKS +/* # include */ +# include +# include +#endif /* OS_VXWORKS */ + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE +# include +#endif + +#ifdef HAVE_UTIME +# include +#endif + +/* +** Allowed values of unixFile.fsFlags +*/ +#define SQLITE_FSFLAGS_IS_MSDOS 0x1 + +/* +** If we are to be thread-safe, include the pthreads header. +*/ +#if SQLITE_THREADSAFE +/* # include */ +#endif + +/* +** Default permissions when creating a new file +*/ +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 +#endif + +/* +** Default permissions when creating auto proxy dir +*/ +#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 +#endif + +/* +** Maximum supported path-length. +*/ +#define MAX_PATHNAME 512 + +/* +** Maximum supported symbolic links +*/ +#define SQLITE_MAX_SYMLINKS 100 + +/* +** Remove and stub certain info for WASI (WebAssembly System +** Interface) builds. +*/ +#ifdef SQLITE_WASI +# undef HAVE_FCHMOD +# undef HAVE_FCHOWN +# undef HAVE_MREMAP +# define HAVE_MREMAP 0 +# ifndef SQLITE_DEFAULT_UNIX_VFS +# define SQLITE_DEFAULT_UNIX_VFS "unix-dotfile" + /* ^^^ should SQLITE_DEFAULT_UNIX_VFS be "unix-none"? */ +# endif +# ifndef F_RDLCK +# define F_RDLCK 0 +# define F_WRLCK 1 +# define F_UNLCK 2 +# if __LONG_MAX == 0x7fffffffL +# define F_GETLK 12 +# define F_SETLK 13 +# define F_SETLKW 14 +# else +# define F_GETLK 5 +# define F_SETLK 6 +# define F_SETLKW 7 +# endif +# endif +#else /* !SQLITE_WASI */ +# ifndef HAVE_FCHMOD +# define HAVE_FCHMOD +# endif +#endif /* SQLITE_WASI */ + +#ifdef SQLITE_WASI +# define osGetpid(X) (pid_t)1 +#else +/* Always cast the getpid() return type for compatibility with +** kernel modules in VxWorks. */ +# define osGetpid(X) (pid_t)getpid() +#endif + +/* +** Only set the lastErrno if the error code is a real error and not +** a normal expected return code of SQLITE_BUSY or SQLITE_OK +*/ +#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) + +/* Forward references */ +typedef struct unixShm unixShm; /* Connection shared memory */ +typedef struct unixShmNode unixShmNode; /* Shared memory instance */ +typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ +typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */ + +/* +** Sometimes, after a file handle is closed by SQLite, the file descriptor +** cannot be closed immediately. In these cases, instances of the following +** structure are used to store the file descriptor while waiting for an +** opportunity to either close or reuse it. +*/ +struct UnixUnusedFd { + int fd; /* File descriptor to close */ + int flags; /* Flags this file descriptor was opened with */ + UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ +}; + +/* +** The unixFile structure is subclass of sqlite3_file specific to the unix +** VFS implementations. +*/ +typedef struct unixFile unixFile; +struct unixFile { + sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ + unixInodeInfo *pInode; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char eFileLock; /* The type of lock held on this fd */ + unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + int lastErrno; /* The unix errno from last I/O error */ + void *lockingContext; /* Locking style specific state */ + UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */ + const char *zPath; /* Name of the file */ + unixShm *pShm; /* Shared memory segment information */ + int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_MAX_MMAP_SIZE>0 + int nFetchOut; /* Number of outstanding xFetch refs */ + sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ + void *pMapRegion; /* Memory mapped region */ +#endif + int sectorSize; /* Device sector size */ + int deviceCharacteristics; /* Precomputed device characteristics */ +#if SQLITE_ENABLE_LOCKING_STYLE + int openFlags; /* The flags specified at open() */ +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) + unsigned fsFlags; /* cached details from statfs() */ +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + unsigned iBusyTimeout; /* Wait this many millisec on locks */ +#endif +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID */ +#endif +#ifdef SQLITE_DEBUG + /* The next group of variables are used to track whether or not the + ** transaction counter in bytes 24-27 of database files are updated + ** whenever any part of the database changes. An assertion fault will + ** occur if a file is updated without also updating the transaction + ** counter. This test is made to avoid new problems similar to the + ** one described by ticket #3584. + */ + unsigned char transCntrChng; /* True if the transaction counter changed */ + unsigned char dbUpdate; /* True if any part of database file changed */ + unsigned char inNormalWrite; /* True if in a normal write operation */ + +#endif + +#ifdef SQLITE_TEST + /* In test mode, increase the size of this structure a bit so that + ** it is larger than the struct CrashFile defined in test6.c. + */ + char aPadding[32]; +#endif +}; + +/* This variable holds the process id (pid) from when the xRandomness() +** method was called. If xOpen() is called from a different process id, +** indicating that a fork() has occurred, the PRNG will be reset. +*/ +static pid_t randomnessPid = 0; + +/* +** Allowed values for the unixFile.ctrlFlags bitmask: +*/ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#ifndef SQLITE_DISABLE_DIRSYNC +# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ +#else +# define UNIXFILE_DIRSYNC 0x00 +#endif +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +#define UNIXFILE_DELETE 0x20 /* Delete on close */ +#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ +#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ + +/* +** Include code that is common to all os_*.c files +*/ +/* #include "os_common.h" */ + +/* +** Define various macros that are missing from some systems. +*/ +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifdef SQLITE_DISABLE_LFS +# undef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +/* +** The threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. +*/ +#if SQLITE_THREADSAFE +#define threadid pthread_self() +#else +#define threadid 0 +#endif + +/* +** HAVE_MREMAP defaults to true on Linux and false everywhere else. +*/ +#if !defined(HAVE_MREMAP) +# if defined(__linux__) && defined(_GNU_SOURCE) +# define HAVE_MREMAP 1 +# else +# define HAVE_MREMAP 0 +# endif +#endif + +/* +** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek() +** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined. +*/ +#ifdef __ANDROID__ +# define lseek lseek64 +#endif + +#ifdef __linux__ +/* +** Linux-specific IOCTL magic numbers used for controlling F2FS +*/ +#define F2FS_IOCTL_MAGIC 0xf5 +#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) +#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) +#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) +#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) +#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32) +#define F2FS_FEATURE_ATOMIC_WRITE 0x0004 +#endif /* __linux__ */ + + +/* +** Different Unix systems declare open() in different ways. Same use +** open(const char*,int,mode_t). Others use open(const char*,int,...). +** The difference is important when using a pointer to the function. +** +** The safest way to deal with the problem is to always use this wrapper +** which always has the same well-defined interface. +*/ +static int posixOpen(const char *zFile, int flags, int mode){ + return open(zFile, flags, mode); +} + +/* Forward reference */ +static int openDirectory(const char*, int*); +static int unixGetpagesize(void); + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct unix_syscall { + const char *zName; /* Name of the system call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { + { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) + + { "close", (sqlite3_syscall_ptr)close, 0 }, +#define osClose ((int(*)(int))aSyscall[1].pCurrent) + + { "access", (sqlite3_syscall_ptr)access, 0 }, +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) + + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) + + { "stat", (sqlite3_syscall_ptr)stat, 0 }, +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) + +/* +** The DJGPP compiler environment looks mostly like Unix, but it +** lacks the fcntl() system call. So redefine fcntl() to be something +** that always succeeds. This means that locking does not occur under +** DJGPP. But it is DOS - what did you expect? +*/ +#ifdef __DJGPP__ + { "fstat", 0, 0 }, +#define osFstat(a,b,c) 0 +#else + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) +#endif + + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) + + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) + + { "read", (sqlite3_syscall_ptr)read, 0 }, +#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pread", (sqlite3_syscall_ptr)pread, 0 }, +#else + { "pread", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) + +#if defined(USE_PREAD64) + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, +#else + { "pread64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent) + + { "write", (sqlite3_syscall_ptr)write, 0 }, +#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, +#else + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[12].pCurrent) + +#if defined(USE_PREAD64) + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, +#else + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ + aSyscall[13].pCurrent) + +#if defined(HAVE_FCHMOD) + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, +#else + { "fchmod", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, +#else + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) + + { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, +#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) + + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, +#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) + + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, +#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + +#if defined(HAVE_FCHOWN) + { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, +#else + { "fchown", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) + +#if defined(HAVE_FCHOWN) + { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, +#else + { "geteuid", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) + +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_WASI) + { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, +#else + { "mmap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) + +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_WASI) + { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, +#else + { "munmap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent) + +#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, +#else + { "mremap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent) + +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, +#else + { "getpagesize", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent) + +#if defined(HAVE_READLINK) + { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, +#else + { "readlink", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) + +#if defined(HAVE_LSTAT) + { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, +#else + { "lstat", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) + +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +# ifdef __ANDROID__ + { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, +#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) +# else + { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, +#define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent) +# endif +#else + { "ioctl", (sqlite3_syscall_ptr)0, 0 }, +#endif + +}; /* End of the overrideable system calls */ + + +/* +** On some systems, calls to fchown() will trigger a message in a security +** log if they come from non-root processes. So avoid calling fchown() if +** we are not running as root. +*/ +static int robustFchown(int fd, uid_t uid, gid_t gid){ +#if defined(HAVE_FCHOWN) + return osGeteuid() ? 0 : osFchown(fd,uid,gid); +#else + return 0; +#endif +} + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "unix" VFSes. Return SQLITE_OK upon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int unixSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; + if( (f & (O_EXCL|O_CREAT))==(O_EXCL|O_CREAT) ){ + (void)osUnlink(z); + } + osClose(fd); + sqlite3_log(SQLITE_WARNING, + "attempt to open \"%s\" as file descriptor %d", z, fd); + fd = -1; + if( osOpen("/dev/null", O_RDONLY, m)<0 ) break; + } + if( fd>=0 ){ + if( m!=0 ){ + struct stat statbuf; + if( osFstat(fd, &statbuf)==0 + && statbuf.st_size==0 + && (statbuf.st_mode&0777)!=m + ){ + osFchmod(fd, m); + } + } +#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0) + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + } + return fd; +} + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the unixInodeInfo and +** vxworksFileId objects used by this file, all of which may be +** shared by multiple threads. +** +** Function unixMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** unixEnterMutex() +** assert( unixMutexHeld() ); +** unixEnterLeave() +** +** To prevent deadlock, the global unixBigLock must must be acquired +** before the unixInodeInfo.pLockMutex mutex, if both are held. It is +** OK to get the pLockMutex without holding unixBigLock first, but if +** that happens, the unixBigLock mutex must not be acquired until after +** pLockMutex is released. +** +** OK: enter(unixBigLock), enter(pLockInfo) +** OK: enter(unixBigLock) +** OK: enter(pLockInfo) +** ERROR: enter(pLockInfo), enter(unixBigLock) +*/ +static sqlite3_mutex *unixBigLock = 0; +static void unixEnterMutex(void){ + assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ + sqlite3_mutex_enter(unixBigLock); +} +static void unixLeaveMutex(void){ + assert( sqlite3_mutex_held(unixBigLock) ); + sqlite3_mutex_leave(unixBigLock); +} +#ifdef SQLITE_DEBUG +static int unixMutexHeld(void) { + return sqlite3_mutex_held(unixBigLock); +} +#endif + + +#ifdef SQLITE_HAVE_OS_TRACE +/* +** Helper function for printing out trace information from debugging +** binaries. This returns the string representation of the supplied +** integer lock-type. +*/ +static const char *azFileLock(int eFileLock){ + switch( eFileLock ){ + case NO_LOCK: return "NONE"; + case SHARED_LOCK: return "SHARED"; + case RESERVED_LOCK: return "RESERVED"; + case PENDING_LOCK: return "PENDING"; + case EXCLUSIVE_LOCK: return "EXCLUSIVE"; + } + return "ERROR"; +} +#endif + +#ifdef SQLITE_LOCK_TRACE +/* +** Print out information about all locking operations. +** +** This routine is used for troubleshooting locks on multithreaded +** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE +** command-line option on the compiler. This code is normally +** turned off. +*/ +static int lockTrace(int fd, int op, struct flock *p){ + char *zOpName, *zType; + int s; + int savedErrno; + if( op==F_GETLK ){ + zOpName = "GETLK"; + }else if( op==F_SETLK ){ + zOpName = "SETLK"; + }else{ + s = osFcntl(fd, op, p); + sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); + return s; + } + if( p->l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( p->l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( p->l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + assert( p->l_whence==SEEK_SET ); + s = osFcntl(fd, op, p); + savedErrno = errno; + sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", + threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, + (int)p->l_pid, s); + if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ + struct flock l2; + l2 = *p; + osFcntl(fd, F_GETLK, &l2); + if( l2.l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( l2.l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( l2.l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", + zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); + } + errno = savedErrno; + return s; +} +#undef osFcntl +#define osFcntl lockTrace +#endif /* SQLITE_LOCK_TRACE */ + +/* +** Retry ftruncate() calls that fail due to EINTR +** +** All calls to ftruncate() within this file should be made through +** this wrapper. On the Android platform, bypassing the logic below +** could lead to a corrupt database. +*/ +static int robust_ftruncate(int h, sqlite3_int64 sz){ + int rc; +#ifdef __ANDROID__ + /* On Android, ftruncate() always uses 32-bit offsets, even if + ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to + ** truncate a file to any size larger than 2GiB. Silently ignore any + ** such attempts. */ + if( sz>(sqlite3_int64)0x7FFFFFFF ){ + rc = SQLITE_OK; + }else +#endif + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); + return rc; +} + +/* +** This routine translates a standard POSIX errno code into something +** useful to the clients of the sqlite3 functions. Specifically, it is +** intended to translate a variety of "try again" errors into SQLITE_BUSY +** and a variety of "please close the file descriptor NOW" errors into +** SQLITE_IOERR +** +** Errors during initialization of locks, or file system support for locks, +** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. +*/ +static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { + assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + (sqliteIOErr == SQLITE_IOERR_RDLOCK) || + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ); + switch (posixError) { + case EACCES: + case EAGAIN: + case ETIMEDOUT: + case EBUSY: + case EINTR: + case ENOLCK: + /* random NFS retry error, unless during file system support + * introspection, in which it actually means what it says */ + return SQLITE_BUSY; + + case EPERM: + return SQLITE_PERM; + + default: + return sqliteIOErr; + } +} + + +/****************************************************************************** +****************** Begin Unique File ID Utility Used By VxWorks *************** +** +** On most versions of unix, we can get a unique ID for a file by concatenating +** the device number and the inode number. But this does not work on VxWorks. +** On VxWorks, a unique file id must be based on the canonical filename. +** +** A pointer to an instance of the following structure can be used as a +** unique file ID in VxWorks. Each instance of this structure contains +** a copy of the canonical filename. There is also a reference count. +** The structure is reclaimed when the number of pointers to it drops to +** zero. +** +** There are never very many files open at one time and lookups are not +** a performance-critical path, so it is sufficient to put these +** structures on a linked list. +*/ +struct vxworksFileId { + struct vxworksFileId *pNext; /* Next in a list of them all */ + int nRef; /* Number of references to this one */ + int nName; /* Length of the zCanonicalName[] string */ + char *zCanonicalName; /* Canonical filename */ +}; + +#if OS_VXWORKS +/* +** All unique filenames are held on a linked list headed by this +** variable: +*/ +static struct vxworksFileId *vxworksFileList = 0; + +/* +** Simplify a filename into its canonical form +** by making the following changes: +** +** * removing any trailing and duplicate / +** * convert /./ into just / +** * convert /A/../ where A is any simple name into just / +** +** Changes are made in-place. Return the new name length. +** +** The original filename is in z[0..n-1]. Return the number of +** characters in the simplified name. +*/ +static int vxworksSimplifyName(char *z, int n){ + int i, j; + while( n>1 && z[n-1]=='/' ){ n--; } + for(i=j=0; i0 && z[j-1]!='/' ){ j--; } + if( j>0 ){ j--; } + i += 2; + continue; + } + } + z[j++] = z[i]; + } + z[j] = 0; + return j; +} + +/* +** Find a unique file ID for the given absolute pathname. Return +** a pointer to the vxworksFileId object. This pointer is the unique +** file ID. +** +** The nRef field of the vxworksFileId object is incremented before +** the object is returned. A new vxworksFileId object is created +** and added to the global list if necessary. +** +** If a memory allocation error occurs, return NULL. +*/ +static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ + struct vxworksFileId *pNew; /* search key and new file ID */ + struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ + int n; /* Length of zAbsoluteName string */ + + assert( zAbsoluteName[0]=='/' ); + n = (int)strlen(zAbsoluteName); + pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); + if( pNew==0 ) return 0; + pNew->zCanonicalName = (char*)&pNew[1]; + memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); + n = vxworksSimplifyName(pNew->zCanonicalName, n); + + /* Search for an existing entry that matching the canonical name. + ** If found, increment the reference count and return a pointer to + ** the existing file ID. + */ + unixEnterMutex(); + for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ + if( pCandidate->nName==n + && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 + ){ + sqlite3_free(pNew); + pCandidate->nRef++; + unixLeaveMutex(); + return pCandidate; + } + } + + /* No match was found. We will make a new file ID */ + pNew->nRef = 1; + pNew->nName = n; + pNew->pNext = vxworksFileList; + vxworksFileList = pNew; + unixLeaveMutex(); + return pNew; +} + +/* +** Decrement the reference count on a vxworksFileId object. Free +** the object when the reference count reaches zero. +*/ +static void vxworksReleaseFileId(struct vxworksFileId *pId){ + unixEnterMutex(); + assert( pId->nRef>0 ); + pId->nRef--; + if( pId->nRef==0 ){ + struct vxworksFileId **pp; + for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} + assert( *pp==pId ); + *pp = pId->pNext; + sqlite3_free(pId); + } + unixLeaveMutex(); +} +#endif /* OS_VXWORKS */ +/*************** End of Unique File ID Utility Used By VxWorks **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Posix Advisory Locking **************************** +** +** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996) +** section 6.5.2.2 lines 483 through 490 specify that when a process +** sets or clears a lock, that operation overrides any prior locks set +** by the same process. It does not explicitly say so, but this implies +** that it overrides locks set by the same process using a different +** file descriptor. Consider this test case: +** +** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); +** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); +** +** Suppose ./file1 and ./file2 are really the same file (because +** one is a hard or symbolic link to the other) then if you set +** an exclusive lock on fd1, then try to get an exclusive lock +** on fd2, it works. I would have expected the second lock to +** fail since there was already a lock on the file due to fd1. +** But not so. Since both locks came from the same process, the +** second overrides the first, even though they were on different +** file descriptors opened on different file names. +** +** This means that we cannot use POSIX locks to synchronize file access +** among competing threads of the same process. POSIX locks will work fine +** to synchronize access for threads in separate processes, but not +** threads within the same process. +** +** To work around the problem, SQLite has to manage file locks internally +** on its own. Whenever a new database is opened, we have to find the +** specific inode of the database file (the inode is determined by the +** st_dev and st_ino fields of the stat structure that fstat() fills in) +** and check for locks already existing on that inode. When locks are +** created or removed, we have to look at our own internal record of the +** locks to see if another thread has previously set a lock on that same +** inode. +** +** (Aside: The use of inode numbers as unique IDs does not work on VxWorks. +** For VxWorks, we have to use the alternative unique ID system based on +** canonical filename and implemented in the previous division.) +** +** The sqlite3_file structure for POSIX is no longer just an integer file +** descriptor. It is now a structure that holds the integer file +** descriptor and a pointer to a structure that describes the internal +** locks on the corresponding inode. There is one locking structure +** per inode, so if the same inode is opened twice, both unixFile structures +** point to the same locking structure. The locking structure keeps +** a reference count (so we will know when to delete it) and a "cnt" +** field that tells us its internal lock status. cnt==0 means the +** file is unlocked. cnt==-1 means the file has an exclusive lock. +** cnt>0 means there are cnt shared locks on the file. +** +** Any attempt to lock or unlock a file first checks the locking +** structure. The fcntl() system call is only invoked to set a +** POSIX lock if the internal lock structure transitions between +** a locked and an unlocked state. +** +** But wait: there are yet more problems with POSIX advisory locks. +** +** If you close a file descriptor that points to a file that has locks, +** all locks on that file that are owned by the current process are +** released. To work around this problem, each unixInodeInfo object +** maintains a count of the number of pending locks on the inode. +** When an attempt is made to close an unixFile, if there are +** other unixFile open on the same inode that are holding locks, the call +** to close() the file descriptor is deferred until all of the locks clear. +** The unixInodeInfo structure keeps a list of file descriptors that need to +** be closed and that list is walked (and cleared) when the last lock +** clears. +** +** Yet another problem: LinuxThreads do not play well with posix locks. +** +** Many older versions of linux use the LinuxThreads library which is +** not posix compliant. Under LinuxThreads, a lock created by thread +** A cannot be modified or overridden by a different thread B. +** Only thread A can modify the lock. Locking behavior is correct +** if the application uses the newer Native Posix Thread Library (NPTL) +** on linux - with NPTL a lock created by thread A can override locks +** in thread B. But there is no way to know at compile-time which +** threading library is being used. So there is no way to know at +** compile-time whether or not thread A can override locks on thread B. +** One has to do a run-time check to discover the behavior of the +** current process. +** +** SQLite used to support LinuxThreads. But support for LinuxThreads +** was dropped beginning with version 3.7.0. SQLite will still work with +** LinuxThreads provided that (1) there is no more than one connection +** per database file in the same process and (2) database connections +** do not move across threads. +*/ + +/* +** An instance of the following structure serves as the key used +** to locate a particular unixInodeInfo object. +*/ +struct unixFileId { + dev_t dev; /* Device number */ +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID for vxworks. */ +#else + /* We are told that some versions of Android contain a bug that + ** sizes ino_t at only 32-bits instead of 64-bits. (See + ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c) + ** To work around this, always allocate 64-bits for the inode number. + ** On small machines that only have 32-bit inodes, this wastes 4 bytes, + ** but that should not be a big deal. */ + /* WAS: ino_t ino; */ + u64 ino; /* Inode number */ +#endif +}; + +/* +** An instance of the following structure is allocated for each open +** inode. +** +** A single inode can have multiple file descriptors, so each unixFile +** structure contains a pointer to an instance of this object and this +** object keeps a count of the number of unixFile pointing to it. +** +** Mutex rules: +** +** (1) Only the pLockMutex mutex must be held in order to read or write +** any of the locking fields: +** nShared, nLock, eFileLock, bProcessLock, pUnused +** +** (2) When nRef>0, then the following fields are unchanging and can +** be read (but not written) without holding any mutex: +** fileId, pLockMutex +** +** (3) With the exceptions above, all the fields may only be read +** or written while holding the global unixBigLock mutex. +** +** Deadlock prevention: The global unixBigLock mutex may not +** be acquired while holding the pLockMutex mutex. If both unixBigLock +** and pLockMutex are needed, then unixBigLock must be acquired first. +*/ +struct unixInodeInfo { + struct unixFileId fileId; /* The lookup key */ + sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ + int nShared; /* Number of SHARED locks held */ + int nLock; /* Number of outstanding file locks */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ + int nRef; /* Number of pointers to this structure */ + unixShmNode *pShmNode; /* Shared memory associated with this inode */ + unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ + unixInodeInfo *pPrev; /* .... doubly linked */ +#if SQLITE_ENABLE_LOCKING_STYLE + unsigned long long sharedByte; /* for AFP simulated shared lock */ +#endif +#if OS_VXWORKS + sem_t *pSem; /* Named POSIX semaphore */ + char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ +#endif +}; + +/* +** A lists of all unixInodeInfo objects. +** +** Must hold unixBigLock in order to read or write this variable. +*/ +static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ + +#ifdef SQLITE_DEBUG +/* +** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not. +** This routine is used only within assert() to help verify correct mutex +** usage. +*/ +int unixFileMutexHeld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_held(pFile->pInode->pLockMutex); +} +int unixFileMutexNotheld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_notheld(pFile->pInode->pLockMutex); +} +#endif + +/* +** +** This function - unixLogErrorAtLine(), is only ever called via the macro +** unixLogError(). +** +** It is invoked after an error occurs in an OS function and errno has been +** set. It logs a message using sqlite3_log() containing the current value of +** errno and, if possible, the human-readable equivalent from strerror() or +** strerror_r(). +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed (e.g. "unlink", "open") and the associated file-system path, +** if any. +*/ +#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) +static int unixLogErrorAtLine( + int errcode, /* SQLite error code */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char *zErr; /* Message from strerror() or equivalent */ + int iErrno = errno; /* Saved syscall error number */ + + /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use + ** the strerror() function to obtain the human-readable error message + ** equivalent to errno. Otherwise, use strerror_r(). + */ +#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) + char aErr[80]; + memset(aErr, 0, sizeof(aErr)); + zErr = aErr; + + /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, + ** assume that the system provides the GNU version of strerror_r() that + ** returns a pointer to a buffer containing the error message. That pointer + ** may point to aErr[], or it may point to some static storage somewhere. + ** Otherwise, assume that the system provides the POSIX version of + ** strerror_r(), which always writes an error message into aErr[]. + ** + ** If the code incorrectly assumes that it is the POSIX version that is + ** available, the error message will often be an empty string. Not a + ** huge problem. Incorrectly concluding that the GNU version is available + ** could lead to a segfault though. + */ +#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) + zErr = +# endif + strerror_r(iErrno, aErr, sizeof(aErr)-1); + +#elif SQLITE_THREADSAFE + /* This is a threadsafe build, but strerror_r() is not available. */ + zErr = ""; +#else + /* Non-threadsafe build, use strerror(). */ + zErr = strerror(iErrno); +#endif + + if( zPath==0 ) zPath = ""; + sqlite3_log(errcode, + "os_unix.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zErr + ); + + return errcode; +} + +/* +** Close a file descriptor. +** +** We assume that close() almost always works, since it is only in a +** very sick application or on a very sick platform that it might fail. +** If it does fail, simply leak the file descriptor, but do log the +** error. +** +** Note that it is not safe to retry close() after EINTR since the +** file descriptor might have already been reused by another thread. +** So we don't even try to recover from an EINTR. Just log the error +** and move on. +*/ +static void robust_close(unixFile *pFile, int h, int lineno){ + if( osClose(h) ){ + unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", + pFile ? pFile->zPath : 0, lineno); + } +} + +/* +** Set the pFile->lastErrno. Do this in a subroutine as that provides +** a convenient place to set a breakpoint. +*/ +static void storeLastErrno(unixFile *pFile, int error){ + pFile->lastErrno = error; +} + +/* +** Close all file descriptors accumulated in the unixInodeInfo->pUnused list. +*/ +static void closePendingFds(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p; + UnixUnusedFd *pNext; + assert( unixFileMutexHeld(pFile) ); + for(p=pInode->pUnused; p; p=pNext){ + pNext = p->pNext; + robust_close(pFile, p->fd, __LINE__); + sqlite3_free(p); + } + pInode->pUnused = 0; +} + +/* +** Release a unixInodeInfo structure previously allocated by findInodeInfo(). +** +** The global mutex must be held when this routine is called, but the mutex +** on the inode being deleted must NOT be held. +*/ +static void releaseInodeInfo(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + assert( unixFileMutexNotheld(pFile) ); + if( ALWAYS(pInode) ){ + pInode->nRef--; + if( pInode->nRef==0 ){ + assert( pInode->pShmNode==0 ); + sqlite3_mutex_enter(pInode->pLockMutex); + closePendingFds(pFile); + sqlite3_mutex_leave(pInode->pLockMutex); + if( pInode->pPrev ){ + assert( pInode->pPrev->pNext==pInode ); + pInode->pPrev->pNext = pInode->pNext; + }else{ + assert( inodeList==pInode ); + inodeList = pInode->pNext; + } + if( pInode->pNext ){ + assert( pInode->pNext->pPrev==pInode ); + pInode->pNext->pPrev = pInode->pPrev; + } + sqlite3_mutex_free(pInode->pLockMutex); + sqlite3_free(pInode); + } + } +} + +/* +** Given a file descriptor, locate the unixInodeInfo object that +** describes that file descriptor. Create a new one if necessary. The +** return value might be uninitialized if an error occurs. +** +** The global mutex must held when calling this routine. +** +** Return an appropriate error code. +*/ +static int findInodeInfo( + unixFile *pFile, /* Unix file with file desc used in the key */ + unixInodeInfo **ppInode /* Return the unixInodeInfo object here */ +){ + int rc; /* System call return code */ + int fd; /* The file descriptor for pFile */ + struct unixFileId fileId; /* Lookup key for the unixInodeInfo */ + struct stat statbuf; /* Low-level file information */ + unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ + + assert( unixMutexHeld() ); + + /* Get low-level information about the file that we can used to + ** create a unique name for the file. + */ + fd = pFile->h; + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + storeLastErrno(pFile, errno); +#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS) + if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; +#endif + return SQLITE_IOERR; + } + +#ifdef __APPLE__ + /* On OS X on an msdos filesystem, the inode number is reported + ** incorrectly for zero-size files. See ticket #3260. To work + ** around this problem (we consider it a bug in OS X, not SQLite) + ** we always increase the file size to 1 by writing a single byte + ** prior to accessing the inode number. The one byte written is + ** an ASCII 'S' character which also happens to be the first byte + ** in the header of every SQLite database. In this way, if there + ** is a race condition such that another thread has already populated + ** the first page of the database, no damage is done. + */ + if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ + do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); + if( rc!=1 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR; + } + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR; + } + } +#endif + + memset(&fileId, 0, sizeof(fileId)); + fileId.dev = statbuf.st_dev; +#if OS_VXWORKS + fileId.pId = pFile->pId; +#else + fileId.ino = (u64)statbuf.st_ino; +#endif + assert( unixMutexHeld() ); + pInode = inodeList; + while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ + pInode = pInode->pNext; + } + if( pInode==0 ){ + pInode = sqlite3_malloc64( sizeof(*pInode) ); + if( pInode==0 ){ + return SQLITE_NOMEM_BKPT; + } + memset(pInode, 0, sizeof(*pInode)); + memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + if( sqlite3GlobalConfig.bCoreMutex ){ + pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pInode->pLockMutex==0 ){ + sqlite3_free(pInode); + return SQLITE_NOMEM_BKPT; + } + } + pInode->nRef = 1; + assert( unixMutexHeld() ); + pInode->pNext = inodeList; + pInode->pPrev = 0; + if( inodeList ) inodeList->pPrev = pInode; + inodeList = pInode; + }else{ + pInode->nRef++; + } + *ppInode = pInode; + return SQLITE_OK; +} + +/* +** Return TRUE if pFile has been renamed or unlinked since it was first opened. +*/ +static int fileHasMoved(unixFile *pFile){ +#if OS_VXWORKS + return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId; +#else + struct stat buf; + return pFile->pInode!=0 && + (osStat(pFile->zPath, &buf)!=0 + || (u64)buf.st_ino!=pFile->pInode->fileId.ino); +#endif +} + + +/* +** Check a unixFile that is a database. Verify the following: +** +** (1) There is exactly one hard link on the file +** (2) The file is not a symbolic link +** (3) The file has not been renamed or unlinked +** +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. +*/ +static void verifyDbFile(unixFile *pFile){ + struct stat buf; + int rc; + + /* These verifications occurs for the main database only */ + if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return; + + rc = osFstat(pFile->h, &buf); + if( rc!=0 ){ + sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); + return; + } + if( buf.st_nlink==0 ){ + sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); + return; + } + if( buf.st_nlink>1 ){ + sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); + return; + } + if( fileHasMoved(pFile) ){ + sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); + return; + } +} + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); + sqlite3_mutex_enter(pFile->pInode->pLockMutex); + + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ +#ifndef __DJGPP__ + if( !reserved && !pFile->pInode->bProcessLock ){ + struct flock lock; + lock.l_whence = SEEK_SET; + lock.l_start = RESERVED_BYTE; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pFile->h, F_GETLK, &lock) ){ + rc = SQLITE_IOERR_CHECKRESERVEDLOCK; + storeLastErrno(pFile, errno); + } else if( lock.l_type!=F_UNLCK ){ + reserved = 1; + } + } +#endif + + sqlite3_mutex_leave(pFile->pInode->pLockMutex); + OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* Forward declaration*/ +static int unixSleep(sqlite3_vfs*,int); + +/* +** Set a posix-advisory-lock. +** +** There are two versions of this routine. If compiled with +** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter +** which is a pointer to a unixFile. If the unixFile->iBusyTimeout +** value is set, then it is the number of milliseconds to wait before +** failing the lock. The iBusyTimeout value is always reset back to +** zero on each call. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking +** attempt to set the lock. +*/ +#ifndef SQLITE_ENABLE_SETLK_TIMEOUT +# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x) +#else +static int osSetPosixAdvisoryLock( + int h, /* The file descriptor on which to take the lock */ + struct flock *pLock, /* The description of the lock */ + unixFile *pFile /* Structure holding timeout value */ +){ + int tm = pFile->iBusyTimeout; + int rc = osFcntl(h,F_SETLK,pLock); + while( rc<0 && tm>0 ){ + /* On systems that support some kind of blocking file lock with a timeout, + ** make appropriate changes here to invoke that blocking file lock. On + ** generic posix, however, there is no such API. So we simply try the + ** lock once every millisecond until either the timeout expires, or until + ** the lock is obtained. */ + unixSleep(0,1000); + rc = osFcntl(h,F_SETLK,pLock); + tm--; + } + return rc; +} +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ + + +/* +** Attempt to set a system-lock on the file pFile. The lock is +** described by pLock. +** +** If the pFile was opened read/write from unix-excl, then the only lock +** ever obtained is an exclusive lock, and it is obtained exactly once +** the first time any lock is attempted. All subsequent system locking +** operations become no-ops. Locking operations still happen internally, +** in order to coordinate access between separate database connections +** within this process, but all of that is handled in memory and the +** operating system does not participate. +** +** This function is a pass-through to fcntl(F_SETLK) if pFile is using +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" +** and is read-only. +** +** Zero is returned if the call completes successfully, or -1 if a call +** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). +*/ +static int unixFileLock(unixFile *pFile, struct flock *pLock){ + int rc; + unixInodeInfo *pInode = pFile->pInode; + assert( pInode!=0 ); + assert( sqlite3_mutex_held(pInode->pLockMutex) ); + if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ + if( pInode->bProcessLock==0 ){ + struct flock lock; + assert( pInode->nLock==0 ); + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + lock.l_type = F_WRLCK; + rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); + if( rc<0 ) return rc; + pInode->bProcessLock = 1; + pInode->nLock++; + }else{ + rc = 0; + } + }else{ + rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int unixLock(sqlite3_file *id, int eFileLock){ + /* The following describes the implementation of the various locks and + ** lock transitions in terms of the POSIX advisory shared and exclusive + ** lock primitives (called read-locks and write-locks below, to avoid + ** confusion with SQLite lock names). The algorithms are complicated + ** slightly in order to be compatible with Windows95 systems simultaneously + ** accessing the same database file, in case that is ever required. + ** + ** Symbols defined in os.h identify the 'pending byte' and the 'reserved + ** byte', each single bytes at well known offsets, and the 'shared byte + ** range', a range of 510 bytes at a well known offset. + ** + ** To obtain a SHARED lock, a read-lock is obtained on the 'pending + ** byte'. If this is successful, 'shared byte range' is read-locked + ** and the lock on the 'pending byte' released. (Legacy note: When + ** SQLite was first developed, Windows95 systems were still very common, + ** and Windows95 lacks a shared-lock capability. So on Windows95, a + ** single randomly selected by from the 'shared byte range' is locked. + ** Windows95 is now pretty much extinct, but this work-around for the + ** lack of shared-locks on Windows95 lives on, for backwards + ** compatibility.) + ** + ** A process may only obtain a RESERVED lock after it has a SHARED lock. + ** A RESERVED lock is implemented by grabbing a write-lock on the + ** 'reserved byte'. + ** + ** An EXCLUSIVE lock may only be requested after either a SHARED or + ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining + ** a write-lock on the entire 'shared byte range'. Since all other locks + ** require a read-lock on one of the bytes within this range, this ensures + ** that no other locks are held on the database. + ** + ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then + ** a PENDING lock is obtained first. A PENDING lock is implemented by + ** obtaining a write-lock on the 'pending byte'. This ensures that no new + ** SHARED locks can be obtained, but existing SHARED locks are allowed to + ** persist. If the call to this function fails to obtain the EXCLUSIVE + ** lock in this case, it holds the PENDING lock instead. The client may + ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED + ** locks have cleared. + */ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int tErrno = 0; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, + osGetpid(0))); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct. + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pending lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto end_lock; + } + + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + lock.l_len = 1L; + lock.l_whence = SEEK_SET; + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK) + ){ + lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); + lock.l_start = PENDING_BYTE; + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + goto end_lock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + } + + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + assert( rc==SQLITE_OK ); + + /* Now get the read-lock */ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + } + + /* Drop the temporary PENDING lock */ + lock.l_start = PENDING_BYTE; + lock.l_len = 1L; + lock.l_type = F_UNLCK; + if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ + /* This could happen with a network mount */ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + } + + if( rc ){ + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + goto end_lock; + }else{ + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + assert( 0!=pFile->eFileLock ); + lock.l_type = F_WRLCK; + + assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK ); + if( eFileLock==RESERVED_LOCK ){ + lock.l_start = RESERVED_BYTE; + lock.l_len = 1L; + }else{ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + } + + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + } + } + + +#ifdef SQLITE_DEBUG + /* Set up the transaction-counter change checking flags when + ** transitioning from a SHARED to a RESERVED lock. The change + ** from SHARED to RESERVED marks the beginning of a normal + ** write operation (not a hot journal rollback). + */ + if( rc==SQLITE_OK + && pFile->eFileLock<=SHARED_LOCK + && eFileLock==RESERVED_LOCK + ){ + pFile->transCntrChng = 0; + pFile->dbUpdate = 0; + pFile->inNormalWrite = 1; + } +#endif + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + } + +end_lock: + sqlite3_mutex_leave(pInode->pLockMutex); + OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Add the file descriptor used by file handle pFile to the corresponding +** pUnused list. +*/ +static void setPendingFd(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p = pFile->pPreallocatedUnused; + assert( unixFileMutexHeld(pFile) ); + p->pNext = pInode->pUnused; + pInode->pUnused = p; + pFile->h = -1; + pFile->pPreallocatedUnused = 0; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED +** the byte range is divided into 2 parts and the first part is unlocked then +** set to a read lock, then the other part is simply unlocked. This works +** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to +** remove the write lock on a region when a read lock is set. +*/ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int rc = SQLITE_OK; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + osGetpid(0))); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + +#ifdef SQLITE_DEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + pFile->inNormalWrite = 0; +#endif + + /* downgrading to a shared lock on NFS involves clearing the write lock + ** before establishing the readlock - to avoid a race condition we downgrade + ** the lock in 2 blocks, so that part of the range will be covered by a + ** write lock until the rest is covered by a read lock: + ** 1: [WWWWW] + ** 2: [....W] + ** 3: [RRRRW] + ** 4: [RRRR.] + */ + if( eFileLock==SHARED_LOCK ){ +#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE + (void)handleNFSUnlock; + assert( handleNFSUnlock==0 ); +#endif +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + if( handleNFSUnlock ){ + int tErrno; /* Error code from system call errors */ + off_t divSize = SHARED_SIZE - 1; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + goto end_unlock; + } + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + goto end_unlock; + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST+divSize; + lock.l_len = SHARED_SIZE-divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + goto end_unlock; + } + }else +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + { + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + /* In theory, the call to unixFileLock() cannot fail because another + ** process is holding an incompatible lock. If it does, this + ** indicates that the other process is not following the locking + ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ + rc = SQLITE_IOERR_RDLOCK; + storeLastErrno(pFile, errno); + goto end_unlock; + } + } + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = PENDING_BYTE; + lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = SHARED_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, errno); + goto end_unlock; + } + } + if( eFileLock==NO_LOCK ){ + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + pInode->nShared--; + if( pInode->nShared==0 ){ + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = lock.l_len = 0L; + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = NO_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, errno); + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + + /* Decrement the count of locks against this same file. When the + ** count reaches zero, close any other file descriptors whose close + ** was deferred because of outstanding locks. + */ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ) closePendingFds(pFile); + } + +end_unlock: + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int unixUnlock(sqlite3_file *id, int eFileLock){ +#if SQLITE_MAX_MMAP_SIZE>0 + assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); +#endif + return posixUnlock(id, eFileLock, 0); +} + +#if SQLITE_MAX_MMAP_SIZE>0 +static int unixMapfile(unixFile *pFd, i64 nByte); +static void unixUnmapfile(unixFile *pFd); +#endif + +/* +** This function performs the parts of the "close file" operation +** common to all locking schemes. It closes the directory and file +** handles, if they are valid, and sets all fields of the unixFile +** structure to 0. +** +** It is *not* necessary to hold the mutex when this routine is called, +** even on VxWorks. A mutex will be acquired on VxWorks by the +** vxworksReleaseFileId() routine. +*/ +static int closeUnixFile(sqlite3_file *id){ + unixFile *pFile = (unixFile*)id; +#if SQLITE_MAX_MMAP_SIZE>0 + unixUnmapfile(pFile); +#endif + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + pFile->h = -1; + } +#if OS_VXWORKS + if( pFile->pId ){ + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->pId->zCanonicalName); + } + vxworksReleaseFileId(pFile->pId); + pFile->pId = 0; + } +#endif +#ifdef SQLITE_UNLINK_AFTER_CLOSE + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->zPath); + sqlite3_free(*(char**)&pFile->zPath); + pFile->zPath = 0; + } +#endif + OSTRACE(("CLOSE %-3d\n", pFile->h)); + OpenCounter(-1); + sqlite3_free(pFile->pPreallocatedUnused); + memset(pFile, 0, sizeof(unixFile)); + return SQLITE_OK; +} + +/* +** Close a file. +*/ +static int unixClose(sqlite3_file *id){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile *)id; + unixInodeInfo *pInode = pFile->pInode; + + assert( pInode!=0 ); + verifyDbFile(pFile); + unixUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); + unixEnterMutex(); + + /* unixFile.pInode is always valid here. Otherwise, a different close + ** routine (e.g. nolockClose()) would be called instead. + */ + assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->pUnused list. It will be automatically closed + ** when the last lock is cleared. + */ + setPendingFd(pFile); + } + sqlite3_mutex_leave(pInode->pLockMutex); + releaseInodeInfo(pFile); + assert( pFile->pShm==0 ); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; +} + +/************** End of the posix advisory lock implementation ***************** +******************************************************************************/ + +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){ + UNUSED_PARAMETER(NotUsed); + *pResOut = 0; + return SQLITE_OK; +} +static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} +static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int nolockClose(sqlite3_file *id) { + return closeUnixFile(id); +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************* Begin dot-file Locking ****************************** +** +** The dotfile locking implementation uses the existence of separate lock +** files (really a directory) to control access to the database. This works +** on just about every filesystem imaginable. But there are serious downsides: +** +** (1) There is zero concurrency. A single reader blocks all other +** connections from reading or writing the database. +** +** (2) An application crash or power loss can leave stale lock files +** sitting around that need to be cleared manually. +** +** Nevertheless, a dotlock is an appropriate locking mode for use if no +** other locking strategy is available. +** +** Dotfile locking works by creating a subdirectory in the same directory as +** the database and with the same name but with a ".lock" extension added. +** The existence of a lock directory implies an EXCLUSIVE lock. All other +** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. +*/ + +/* +** The file suffix added to the data base filename in order to create the +** lock directory. +*/ +#define DOTLOCK_SUFFIX ".lock" + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +** +** In dotfile locking, either a lock exists or it does not. So in this +** variation of CheckReservedLock(), *pResOut is set to true if any lock +** is held on the file and false if the file is unlocked. +*/ +static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + reserved = osAccess((const char*)pFile->lockingContext, 0)==0; + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +** +** With dotfile locking, we really only support state (4): EXCLUSIVE. +** But we track the other locking levels internally. +*/ +static int dotlockLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc = SQLITE_OK; + + + /* If we have any lock, then the lock file already exists. All we have + ** to do is adjust our internal record of the lock level. + */ + if( pFile->eFileLock > NO_LOCK ){ + pFile->eFileLock = eFileLock; + /* Always update the timestamp on the old file */ +#ifdef HAVE_UTIME + utime(zLockFile, NULL); +#else + utimes(zLockFile, NULL); +#endif + return SQLITE_OK; + } + + /* grab an exclusive lock */ + rc = osMkdir(zLockFile, 0777); + if( rc<0 ){ + /* failed to open/create the lock directory */ + int tErrno = errno; + if( EEXIST == tErrno ){ + rc = SQLITE_BUSY; + } else { + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + } + return rc; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** When the locking level reaches NO_LOCK, delete the lock file. +*/ +static int dotlockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* To downgrade to shared, simply update our internal notion of the + ** lock state. No need to mess with the file on disk. + */ + if( eFileLock==SHARED_LOCK ){ + pFile->eFileLock = SHARED_LOCK; + return SQLITE_OK; + } + + /* To fully unlock the database, delete the lock file */ + assert( eFileLock==NO_LOCK ); + rc = osRmdir(zLockFile); + if( rc<0 ){ + int tErrno = errno; + if( tErrno==ENOENT ){ + rc = SQLITE_OK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* +** Close a file. Make sure the lock has been released before closing. +*/ +static int dotlockClose(sqlite3_file *id) { + unixFile *pFile = (unixFile*)id; + assert( id!=0 ); + dotlockUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); + return closeUnixFile(id); +} +/****************** End of the dot-file lock implementation ******************* +******************************************************************************/ + +/****************************************************************************** +************************** Begin flock Locking ******************************** +** +** Use the flock() system call to do file locking. +** +** flock() locking is like dot-file locking in that the various +** fine-grain locking levels supported by SQLite are collapsed into +** a single exclusive lock. In other words, SHARED, RESERVED, and +** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite +** still works when you do this, but concurrency is reduced since +** only a single process can be reading the database at a time. +** +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off +*/ +#if SQLITE_ENABLE_LOCKING_STYLE + +/* +** Retry flock() calls that fail with EINTR +*/ +#ifdef EINTR +static int robust_flock(int fd, int op){ + int rc; + do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_flock(a,b) flock(a,b) +#endif + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + /* attempt to get the lock */ + int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); + if( !lrc ){ + /* got the lock, unlock it */ + lrc = robust_flock(pFile->h, LOCK_UN); + if ( lrc ) { + int tErrno = errno; + /* unlock failed with an error */ + lrc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + rc = lrc; + } + } else { + int tErrno = errno; + reserved = 1; + /* someone else might have it reserved */ + lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(lrc) ){ + storeLastErrno(pFile, tErrno); + rc = lrc; + } + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); + +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & 0xff) == SQLITE_IOERR ){ + rc = SQLITE_OK; + reserved=1; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** flock() only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int flockLock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* grab an exclusive lock */ + + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { + int tErrno = errno; + /* didn't get, must be busy */ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + } else { + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + } + OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & 0xff) == SQLITE_IOERR ){ + rc = SQLITE_BUSY; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int flockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really, unlock. */ + if( robust_flock(pFile->h, LOCK_UN) ){ +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + return SQLITE_OK; +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return SQLITE_IOERR_UNLOCK; + }else{ + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; + } +} + +/* +** Close a file. +*/ +static int flockClose(sqlite3_file *id) { + assert( id!=0 ); + flockUnlock(id, NO_LOCK); + return closeUnixFile(id); +} + +#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ + +/******************* End of the flock lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************ Begin Named Semaphore Locking ************************ +** +** Named semaphore locking is only supported on VxWorks. +** +** Semaphore locking is like dot-lock and flock in that it really only +** supports EXCLUSIVE locking. Only a single process can read or write +** the database file at a time. This reduces potential concurrency, but +** makes the lock implementation much easier. +*/ +#if OS_VXWORKS + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + sem_t *pSem = pFile->pInode->pSem; + + if( sem_trywait(pSem)==-1 ){ + int tErrno = errno; + if( EAGAIN != tErrno ){ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); + storeLastErrno(pFile, tErrno); + } else { + /* someone else has the lock when we are in NO_LOCK */ + reserved = (pFile->eFileLock < SHARED_LOCK); + } + }else{ + /* we could have it if we want it */ + sem_post(pSem); + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** Semaphore locks only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int semXLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + int rc = SQLITE_OK; + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + rc = SQLITE_OK; + goto sem_end_lock; + } + + /* lock semaphore now but bail out when already locked. */ + if( sem_trywait(pSem)==-1 ){ + rc = SQLITE_BUSY; + goto sem_end_lock; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + + sem_end_lock: + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int semXUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + + assert( pFile ); + assert( pSem ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really unlock. */ + if ( sem_post(pSem)==-1 ) { + int rc, tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* + ** Close a file. + */ +static int semXClose(sqlite3_file *id) { + if( id ){ + unixFile *pFile = (unixFile*)id; + semXUnlock(id, NO_LOCK); + assert( pFile ); + assert( unixFileMutexNotheld(pFile) ); + unixEnterMutex(); + releaseInodeInfo(pFile); + unixLeaveMutex(); + closeUnixFile(id); + } + return SQLITE_OK; +} + +#endif /* OS_VXWORKS */ +/* +** Named semaphore locking is only available on VxWorks. +** +*************** End of the named semaphore lock implementation **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Begin AFP Locking ********************************* +** +** AFP is the Apple Filing Protocol. AFP is a network filesystem found +** on Apple Macintosh computers - both OS9 and OSX. +** +** Third-party implementations of AFP are available. But this code here +** only works on OSX. +*/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** The afpLockingContext structure contains all afp lock specific state +*/ +typedef struct afpLockingContext afpLockingContext; +struct afpLockingContext { + int reserved; + const char *dbPath; /* Name of the open file */ +}; + +struct ByteRangeLockPB2 +{ + unsigned long long offset; /* offset to first byte to lock */ + unsigned long long length; /* nbr of bytes to lock */ + unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ + unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ + unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ + int fd; /* file desc to assoc this lock with */ +}; + +#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) + +/* +** This is a utility for setting or clearing a bit-range lock on an +** AFP filesystem. +** +** Return SQLITE_OK on success, SQLITE_BUSY on failure. +*/ +static int afpSetLock( + const char *path, /* Name of the file to be locked or unlocked */ + unixFile *pFile, /* Open file descriptor on path */ + unsigned long long offset, /* First byte to be locked */ + unsigned long long length, /* Number of bytes to lock */ + int setLockFlag /* True to set lock. False to clear lock */ +){ + struct ByteRangeLockPB2 pb; + int err; + + pb.unLockFlag = setLockFlag ? 0 : 1; + pb.startEndFlag = 0; + pb.offset = offset; + pb.length = length; + pb.fd = pFile->h; + + OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", + (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), + offset, length)); + err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); + if ( err==-1 ) { + int rc; + int tErrno = errno; + OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", + path, tErrno, strerror(tErrno))); +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + rc = SQLITE_BUSY; +#else + rc = sqliteErrorFromPosixError(tErrno, + setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); +#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } else { + return SQLITE_OK; + } +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + afpLockingContext *context; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + context = (afpLockingContext *) pFile->lockingContext; + if( context->reserved ){ + *pResOut = 1; + return SQLITE_OK; + } + sqlite3_mutex_enter(pFile->pInode->pLockMutex); + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ + if( !reserved ){ + /* lock the RESERVED byte */ + int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( SQLITE_OK==lrc ){ + /* if we succeeded in taking the reserved lock, unlock it to restore + ** the original state */ + lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + } else { + /* if we failed to get the lock then someone else must have it */ + reserved = 1; + } + if( IS_LOCK_ERROR(lrc) ){ + rc=lrc; + } + } + + sqlite3_mutex_leave(pFile->pInode->pLockMutex); + OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int afpLock(sqlite3_file *id, int eFileLock){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode = pFile->pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0))); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pending lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto afp_end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto afp_end_lock; + } + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockdbPath, pFile, PENDING_BYTE, 1, 1); + if (failed) { + rc = failed; + goto afp_end_lock; + } + } + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + int lrc1, lrc2, lrc1Errno = 0; + long lk, mask; + + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + + mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; + /* Now get the read-lock SHARED_LOCK */ + /* note that the quality of the randomness doesn't matter that much */ + lk = random(); + pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); + lrc1 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST+pInode->sharedByte, 1, 1); + if( IS_LOCK_ERROR(lrc1) ){ + lrc1Errno = pFile->lastErrno; + } + /* Drop the temporary PENDING lock */ + lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + + if( IS_LOCK_ERROR(lrc1) ) { + storeLastErrno(pFile, lrc1Errno); + rc = lrc1; + goto afp_end_lock; + } else if( IS_LOCK_ERROR(lrc2) ){ + rc = lrc2; + goto afp_end_lock; + } else if( lrc1 != SQLITE_OK ) { + rc = lrc1; + } else { + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + int failed = 0; + assert( 0!=pFile->eFileLock ); + if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) { + /* Acquire a RESERVED lock */ + failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( !failed ){ + context->reserved = 1; + } + } + if (!failed && eFileLock == EXCLUSIVE_LOCK) { + /* Acquire an EXCLUSIVE lock */ + + /* Remove the shared lock before trying the range. we'll need to + ** reestablish the shared lock if we can't get the afpUnlock + */ + if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + + pInode->sharedByte, 1, 0)) ){ + int failed2 = SQLITE_OK; + /* now attempt to get the exclusive lock range */ + failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, + SHARED_SIZE, 1); + if( failed && (failed2 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ + /* Can't reestablish the shared lock. Sqlite can't deal, this is + ** a critical I/O error + */ + rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : + SQLITE_IOERR_LOCK; + goto afp_end_lock; + } + }else{ + rc = failed; + } + } + if( failed ){ + rc = failed; + } + } + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + +afp_end_lock: + sqlite3_mutex_leave(pInode->pLockMutex); + OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int afpUnlock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + int skipShared = 0; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + osGetpid(0))); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + +#ifdef SQLITE_DEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + assert( pFile->inNormalWrite==0 + || pFile->dbUpdate==0 + || pFile->transCntrChng==1 ); + pFile->inNormalWrite = 0; +#endif + + if( pFile->eFileLock==EXCLUSIVE_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ + /* only re-establish the shared lock if necessary */ + int sharedLockByte = SHARED_FIRST+pInode->sharedByte; + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); + } else { + skipShared = 1; + } + } + if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + } + if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ + rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + if( !rc ){ + context->reserved = 0; + } + } + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ + pInode->eFileLock = SHARED_LOCK; + } + } + if( rc==SQLITE_OK && eFileLock==NO_LOCK ){ + + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; + pInode->nShared--; + if( pInode->nShared==0 ){ + if( !skipShared ){ + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); + } + if( !rc ){ + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + if( rc==SQLITE_OK ){ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ) closePendingFds(pFile); + } + } + + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } + return rc; +} + +/* +** Close a file & cleanup AFP specific locking context +*/ +static int afpClose(sqlite3_file *id) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + assert( id!=0 ); + afpUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); + unixEnterMutex(); + if( pFile->pInode ){ + unixInodeInfo *pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); + } + sqlite3_mutex_leave(pInode->pLockMutex); + } + releaseInodeInfo(pFile); + sqlite3_free(pFile->lockingContext); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the AFP lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. If you don't compile for a mac, then the "unix-afp" +** VFS is not available. +** +********************* End of the AFP lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +*************************** Begin NFS Locking ********************************/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* + ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock + ** must be either NO_LOCK or SHARED_LOCK. + ** + ** If the locking level of the file descriptor is already at or below + ** the requested locking level, this routine is a no-op. + */ +static int nfsUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 1); +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the NFS lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. +** +********************* End of the NFS lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +**************** Non-locking sqlite3_file methods ***************************** +** +** The next division contains implementations for all methods of the +** sqlite3_file object other than the locking methods. The locking +** methods were defined in divisions above (one locking method per +** division). Those methods that are common to all locking modes +** are gather together into this division. +*/ + +/* +** Seek to the offset passed as the second argument, then read cnt +** bytes into pBuf. Return the number of bytes actually read. +** +** To avoid stomping the errno value on a failed read the lastErrno value +** is set before returning. +*/ +static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ + int got; + int prior = 0; +#if (!defined(USE_PREAD) && !defined(USE_PREAD64)) + i64 newOffset; +#endif + TIMER_START; + assert( cnt==(cnt&0x1ffff) ); + assert( id->h>2 ); + do{ +#if defined(USE_PREAD) + got = osPread(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#elif defined(USE_PREAD64) + got = osPread64(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#else + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset = -1 ); + if( newOffset<0 ){ + storeLastErrno((unixFile*)id, errno); + return -1; + } + got = osRead(id->h, pBuf, cnt); +#endif + if( got==cnt ) break; + if( got<0 ){ + if( errno==EINTR ){ got = 1; continue; } + prior = 0; + storeLastErrno((unixFile*)id, errno); + break; + }else if( got>0 ){ + cnt -= got; + offset += got; + prior += got; + pBuf = (void*)(got + (char*)pBuf); + } + }while( got>0 ); + TIMER_END; + OSTRACE(("READ %-3d %5d %7lld %llu\n", + id->h, got+prior, offset-prior, TIMER_ELAPSED)); + return got+prior; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int unixRead( + sqlite3_file *id, + void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile *)id; + int got; + assert( id ); + assert( offset>=0 ); + assert( amt>0 ); + + /* If this is a database file (not a journal, super-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pPreallocatedUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this read request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); + return SQLITE_OK; + }else{ + int nCopy = pFile->mmapSize - offset; + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + + got = seekAndRead(pFile, offset, pBuf, amt); + if( got==amt ){ + return SQLITE_OK; + }else if( got<0 ){ + /* pFile->lastErrno has been set by seekAndRead(). + ** Usually we return SQLITE_IOERR_READ here, though for some + ** kinds of errors we return SQLITE_IOERR_CORRUPTFS. The + ** SQLITE_IOERR_CORRUPTFS will be converted into SQLITE_CORRUPT + ** prior to returning to the application by the sqlite3ApiExit() + ** routine. + */ + switch( pFile->lastErrno ){ + case ERANGE: + case EIO: +#ifdef ENXIO + case ENXIO: +#endif +#ifdef EDEVERR + case EDEVERR: +#endif + return SQLITE_IOERR_CORRUPTFS; + } + return SQLITE_IOERR_READ; + }else{ + storeLastErrno(pFile, 0); /* not a system error */ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; + } +} + +/* +** Attempt to seek the file-descriptor passed as the first argument to +** absolute offset iOff, then attempt to write nBuf bytes of data from +** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, +** return the actual number of bytes written (which may be less than +** nBuf). +*/ +static int seekAndWriteFd( + int fd, /* File descriptor to write to */ + i64 iOff, /* File offset to begin writing at */ + const void *pBuf, /* Copy data from this buffer to the file */ + int nBuf, /* Size of buffer pBuf in bytes */ + int *piErrno /* OUT: Error number if error occurs */ +){ + int rc = 0; /* Value returned by system call */ + + assert( nBuf==(nBuf&0x1ffff) ); + assert( fd>2 ); + assert( piErrno!=0 ); + nBuf &= 0x1ffff; + TIMER_START; + +#if defined(USE_PREAD) + do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); +#elif defined(USE_PREAD64) + do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); +#else + do{ + i64 iSeek = lseek(fd, iOff, SEEK_SET); + SimulateIOError( iSeek = -1 ); + if( iSeek<0 ){ + rc = -1; + break; + } + rc = osWrite(fd, pBuf, nBuf); + }while( rc<0 && errno==EINTR ); +#endif + + TIMER_END; + OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); + + if( rc<0 ) *piErrno = errno; + return rc; +} + + +/* +** Seek to the offset in id->offset then read cnt bytes into pBuf. +** Return the number of bytes actually read. Update the offset. +** +** To avoid stomping the errno value on a failed write the lastErrno value +** is set before returning. +*/ +static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ + return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno); +} + + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int unixWrite( + sqlite3_file *id, + const void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile*)id; + int wrote = 0; + assert( id ); + assert( amt>0 ); + + /* If this is a database file (not a journal, super-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pPreallocatedUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#ifdef SQLITE_DEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) then record the fact that the database + ** has changed. If the transaction counter is modified, record that + ** fact too. + */ + if( pFile->inNormalWrite ){ + pFile->dbUpdate = 1; /* The database has been modified */ + if( offset<=24 && offset+amt>=27 ){ + int rc; + char oldCntr[4]; + SimulateIOErrorBenign(1); + rc = seekAndRead(pFile, 24, oldCntr, 4); + SimulateIOErrorBenign(0); + if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ + pFile->transCntrChng = 1; /* The transaction counter has changed */ + } + } + } +#endif + +#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this write request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); + return SQLITE_OK; + }else{ + int nCopy = pFile->mmapSize - offset; + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + + while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))0 ){ + amt -= wrote; + offset += wrote; + pBuf = &((char*)pBuf)[wrote]; + } + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); + + if( amt>wrote ){ + if( wrote<0 && pFile->lastErrno!=ENOSPC ){ + /* lastErrno set by seekAndWrite */ + return SQLITE_IOERR_WRITE; + }else{ + storeLastErrno(pFile, 0); /* not a system error */ + return SQLITE_FULL; + } + } + + return SQLITE_OK; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occurring at the right times. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif + +/* +** We do not trust systems to provide a working fdatasync(). Some do. +** Others do no. To be safe, we will stick with the (slightly slower) +** fsync(). If you know that your system does support fdatasync() correctly, +** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC +*/ +#if !defined(fdatasync) && !HAVE_FDATASYNC +# define fdatasync fsync +#endif + +/* +** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not +** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently +** only available on Mac OS X. But that could change. +*/ +#ifdef F_FULLFSYNC +# define HAVE_FULLFSYNC 1 +#else +# define HAVE_FULLFSYNC 0 +#endif + + +/* +** The fsync() system call does not work as advertised on many +** unix systems. The following procedure is an attempt to make +** it work better. +** +** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful +** for testing when we want to run through the test suite quickly. +** You are strongly advised *not* to deploy with SQLITE_NO_SYNC +** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash +** or power failure will likely corrupt the database file. +** +** SQLite sets the dataOnly flag if the size of the file is unchanged. +** The idea behind dataOnly is that it should only write the file content +** to disk, not the inode. We only set dataOnly if the file size is +** unchanged since the file size is part of the inode. However, +** Ted Ts'o tells us that fdatasync() will also write the inode if the +** file size has changed. The only real difference between fdatasync() +** and fsync(), Ted tells us, is that fdatasync() will not flush the +** inode if the mtime or owner or other inode attributes have changed. +** We only care about the file size, not the other file attributes, so +** as far as SQLite is concerned, an fdatasync() is always adequate. +** So, we always use fdatasync() if it is available, regardless of +** the value of the dataOnly flag. +*/ +static int full_fsync(int fd, int fullSync, int dataOnly){ + int rc; + + /* The following "ifdef/elif/else/" block has the same structure as + ** the one below. It is replicated here solely to avoid cluttering + ** up the real code with the UNUSED_PARAMETER() macros. + */ +#ifdef SQLITE_NO_SYNC + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#elif HAVE_FULLFSYNC + UNUSED_PARAMETER(dataOnly); +#else + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#endif + + /* Record the number of times that we do a normal fsync() and + ** FULLSYNC. This is used during testing to verify that this procedure + ** gets called with the correct arguments. + */ +#ifdef SQLITE_TEST + if( fullSync ) sqlite3_fullsync_count++; + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op. But go ahead and call fstat() to validate the file + ** descriptor as we need a method to provoke a failure during + ** coverage testing. + */ +#ifdef SQLITE_NO_SYNC + { + struct stat buf; + rc = osFstat(fd, &buf); + } +#elif HAVE_FULLFSYNC + if( fullSync ){ + rc = osFcntl(fd, F_FULLFSYNC, 0); + }else{ + rc = 1; + } + /* If the FULLFSYNC failed, fall back to attempting an fsync(). + ** It shouldn't be possible for fullfsync to fail on the local + ** file system (on OSX), so failure indicates that FULLFSYNC + ** isn't supported for this file system. So, attempt an fsync + ** and (for now) ignore the overhead of a superfluous fcntl call. + ** It'd be better to detect fullfsync support once and avoid + ** the fcntl call every time sync is called. + */ + if( rc ) rc = fsync(fd); + +#elif defined(__APPLE__) + /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly + ** so currently we default to the macro that redefines fdatasync to fsync + */ + rc = fsync(fd); +#else + rc = fdatasync(fd); +#if OS_VXWORKS + if( rc==-1 && errno==ENOTSUP ){ + rc = fsync(fd); + } +#endif /* OS_VXWORKS */ +#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */ + + if( OS_VXWORKS && rc!= -1 ){ + rc = 0; + } + return rc; +} + +/* +** Open a file descriptor to the directory containing file zFilename. +** If successful, *pFd is set to the opened file descriptor and +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined +** value. +** +** The directory file descriptor is used for only one thing - to +** fsync() a directory to make sure file creation and deletion events +** are flushed to disk. Such fsyncs are not needed on newer +** journaling filesystems, but are required on older filesystems. +** +** This routine can be overridden using the xSetSysCall interface. +** The ability to override this routine was added in support of the +** chromium sandbox. Opening a directory is a security risk (we are +** told) so making it overrideable allows the chromium sandbox to +** replace this routine with a harmless no-op. To make this routine +** a no-op, replace it with a stub that returns SQLITE_OK but leaves +** *pFd set to a negative number. +** +** If SQLITE_OK is returned, the caller is responsible for closing +** the file descriptor *pFd using close(). +*/ +static int openDirectory(const char *zFilename, int *pFd){ + int ii; + int fd = -1; + char zDirname[MAX_PATHNAME+1]; + + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); + for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--); + if( ii>0 ){ + zDirname[ii] = '\0'; + }else{ + if( zDirname[0]!='/' ) zDirname[0] = '.'; + zDirname[1] = 0; + } + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); + if( fd>=0 ){ + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); + } + *pFd = fd; + if( fd>=0 ) return SQLITE_OK; + return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname); +} + +/* +** Make sure all writes to a particular file are committed to disk. +** +** If dataOnly==0 then both the file itself and its metadata (file +** size, access time, etc) are synced. If dataOnly!=0 then only the +** file data is synced. +** +** Under Unix, also make sure that the directory entry for the file +** has been created by fsync-ing the directory that contains the file. +** If we do not do this and we encounter a power failure, the directory +** entry for the journal might not exist after we reboot. The next +** SQLite to access the file will not know that the journal exists (because +** the directory entry for the journal was never created) and the transaction +** will not roll back - possibly leading to database corruption. +*/ +static int unixSync(sqlite3_file *id, int flags){ + int rc; + unixFile *pFile = (unixFile*)id; + + int isDataOnly = (flags&SQLITE_SYNC_DATAONLY); + int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL; + + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + assert( pFile ); + OSTRACE(("SYNC %-3d\n", pFile->h)); + rc = full_fsync(pFile->h, isFullsync, isDataOnly); + SimulateIOError( rc=1 ); + if( rc ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); + } + + /* Also fsync the directory containing the file if the DIRSYNC flag + ** is set. This is a one-time occurrence. Many systems (examples: AIX) + ** are unable to fsync a directory, so ignore errors on the fsync. + */ + if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ + int dirfd; + OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, + HAVE_FULLFSYNC, isFullsync)); + rc = osOpenDirectory(pFile->zPath, &dirfd); + if( rc==SQLITE_OK ){ + full_fsync(dirfd, 0, 0); + robust_close(pFile, dirfd, __LINE__); + }else{ + assert( rc==SQLITE_CANTOPEN ); + rc = SQLITE_OK; + } + pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; + } + return rc; +} + +/* +** Truncate an open file to a specified size +*/ +static int unixTruncate(sqlite3_file *id, i64 nByte){ + unixFile *pFile = (unixFile *)id; + int rc; + assert( pFile ); + SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + rc = robust_ftruncate(pFile->h, nByte); + if( rc ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + }else{ +#ifdef SQLITE_DEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) and we truncate the file to zero length, + ** that effectively updates the change counter. This might happen + ** when restoring a database using the backup API from a zero-length + ** source. + */ + if( pFile->inNormalWrite && nByte==0 ){ + pFile->transCntrChng = 1; + } +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* If the file was just truncated to a size smaller than the currently + ** mapped region, reduce the effective mapping size as well. SQLite will + ** use read() and write() to access data beyond this point from now on. + */ + if( nBytemmapSize ){ + pFile->mmapSize = nByte; + } +#endif + + return SQLITE_OK; + } +} + +/* +** Determine the current size of a file in bytes +*/ +static int unixFileSize(sqlite3_file *id, i64 *pSize){ + int rc; + struct stat buf; + assert( id ); + rc = osFstat(((unixFile*)id)->h, &buf); + SimulateIOError( rc=1 ); + if( rc!=0 ){ + storeLastErrno((unixFile*)id, errno); + return SQLITE_IOERR_FSTAT; + } + *pSize = buf.st_size; + + /* When opening a zero-size database, the findInodeInfo() procedure + ** writes a single byte into that file in order to work around a bug + ** in the OS-X msdos filesystem. In order to avoid problems with upper + ** layers, we need to report this file size as zero even though it is + ** really 1. Ticket #3260. + */ + if( *pSize==1 ) *pSize = 0; + + + return SQLITE_OK; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Handler for proxy-locking file-control verbs. Defined below in the +** proxying locking division. +*/ +static int proxyFileControl(sqlite3_file*,int,void*); +#endif + +/* +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT +** file-control operation. Enlarge the database to nBytes in size +** (rounded up to the next chunk-size). If the database is already +** nBytes or larger, this routine is a no-op. +*/ +static int fcntlSizeHint(unixFile *pFile, i64 nByte){ + if( pFile->szChunk>0 ){ + i64 nSize; /* Required file size */ + struct stat buf; /* Used to hold return values of fstat() */ + + if( osFstat(pFile->h, &buf) ){ + return SQLITE_IOERR_FSTAT; + } + + nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; + if( nSize>(i64)buf.st_size ){ + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + /* The code below is handling the return value of osFallocate() + ** correctly. posix_fallocate() is defined to "returns zero on success, + ** or an error number on failure". See the manpage for details. */ + int err; + do{ + err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); + }while( err==EINTR ); + if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE; +#else + /* If the OS does not have posix_fallocate(), fake it. Write a + ** single byte to the last byte in each block that falls entirely + ** within the extended region. Then, if required, a single byte + ** at offset (nSize-1), to set the size of the file correctly. + ** This is a similar technique to that used by glibc on systems + ** that do not have a real fallocate() call. + */ + int nBlk = buf.st_blksize; /* File-system block size */ + int nWrite = 0; /* Number of bytes written by seekAndWrite */ + i64 iWrite; /* Next offset to write to */ + + iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1; + assert( iWrite>=buf.st_size ); + assert( ((iWrite+1)%nBlk)==0 ); + for(/*no-op*/; iWrite=nSize ) iWrite = nSize - 1; + nWrite = seekAndWrite(pFile, iWrite, "", 1); + if( nWrite!=1 ) return SQLITE_IOERR_WRITE; + } +#endif + } + } + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ + int rc; + if( pFile->szChunk<=0 ){ + if( robust_ftruncate(pFile->h, nByte) ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + } + } + + rc = unixMapfile(pFile, nByte); + return rc; + } +#endif + + return SQLITE_OK; +} + +/* +** If *pArg is initially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* Forward declaration */ +static int unixGetTempname(int nBuf, char *zBuf); +#ifndef SQLITE_OMIT_WAL + static int unixFcntlExternalReader(unixFile*, int*); +#endif + +/* +** Information and control of an open file handle. +*/ +static int unixFileControl(sqlite3_file *id, int op, void *pArg){ + unixFile *pFile = (unixFile*)id; + switch( op ){ +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: { + int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE); + return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK; + } + case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: { + int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE); + return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK; + } + case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { + int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE); + return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK; + } +#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->eFileLock; + return SQLITE_OK; + } + case SQLITE_FCNTL_LAST_ERRNO: { + *(int*)pArg = pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + int rc; + SimulateIOErrorBenign(1); + rc = fcntlSizeHint(pFile, *(i64 *)pArg); + SimulateIOErrorBenign(0); + return rc; + } + case SQLITE_FCNTL_PERSIST_WAL: { + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + return SQLITE_OK; + } + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); + if( zTFile ){ + unixGetTempname(pFile->pVfs->mxPathname, zTFile); + *(char**)pArg = zTFile; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_HAS_MOVED: { + *(int*)pArg = fileHasMoved(pFile); + return SQLITE_OK; + } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + case SQLITE_FCNTL_LOCK_TIMEOUT: { + int iOld = pFile->iBusyTimeout; +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 + pFile->iBusyTimeout = *(int*)pArg; +#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 + pFile->iBusyTimeout = !!(*(int*)pArg); +#else +# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" +#endif + *(int*)pArg = iOld; + return SQLITE_OK; + } +#endif +#if SQLITE_MAX_MMAP_SIZE>0 + case SQLITE_FCNTL_MMAP_SIZE: { + i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; + } + + /* The value of newLimit may be eventually cast to (size_t) and passed + ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a + ** 64-bit type. */ + if( newLimit>0 && sizeof(size_t)<8 ){ + newLimit = (newLimit & 0x7FFFFFFF); + } + + *(i64*)pArg = pFile->mmapSizeMax; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + unixUnmapfile(pFile); + rc = unixMapfile(pFile, -1); + } + } + return rc; + } +#endif +#ifdef SQLITE_DEBUG + /* The pager calls this method to signal that it has done + ** a rollback and that the database is therefore unchanged and + ** it hence it is OK for the transaction change counter to be + ** unchanged. + */ + case SQLITE_FCNTL_DB_UNCHANGED: { + ((unixFile*)id)->dbUpdate = 0; + return SQLITE_OK; + } +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + case SQLITE_FCNTL_SET_LOCKPROXYFILE: + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { + return proxyFileControl(id,op,pArg); + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ + + case SQLITE_FCNTL_EXTERNAL_READER: { +#ifndef SQLITE_OMIT_WAL + return unixFcntlExternalReader((unixFile*)id, (int*)pArg); +#else + *(int*)pArg = 0; + return SQLITE_OK; +#endif + } + } + return SQLITE_NOTFOUND; +} + +/* +** If pFd->sectorSize is non-zero when this function is called, it is a +** no-op. Otherwise, the values of pFd->sectorSize and +** pFd->deviceCharacteristics are set according to the file-system +** characteristics. +** +** There are two versions of this function. One for QNX and one for all +** other systems. +*/ +#ifndef __QNXNTO__ +static void setDeviceCharacteristics(unixFile *pFd){ + assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 ); + if( pFd->sectorSize==0 ){ +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + int res; + u32 f = 0; + + /* Check for support for F2FS atomic batch writes. */ + res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f); + if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){ + pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC; + } +#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + + /* Set the POWERSAFE_OVERWRITE flag if requested. */ + if( pFd->ctrlFlags & UNIXFILE_PSOW ){ + pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; + } + + pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + } +} +#else +#include +#include +static void setDeviceCharacteristics(unixFile *pFile){ + if( pFile->sectorSize == 0 ){ + struct statvfs fsInfo; + + /* Set defaults for non-supported filesystems */ + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + pFile->deviceCharacteristics = 0; + if( fstatvfs(pFile->h, &fsInfo) == -1 ) { + return; + } + + if( !strcmp(fsInfo.f_basetype, "tmp") ) { + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "etfs") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* etfs cluster size writes are atomic */ + (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "dos") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else{ + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + 0; + } + } + /* Last chance verification. If the sector size isn't a multiple of 512 + ** then it isn't valid.*/ + if( pFile->sectorSize % 512 != 0 ){ + pFile->deviceCharacteristics = 0; + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + } +} +#endif + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int unixSectorSize(sqlite3_file *id){ + unixFile *pFd = (unixFile*)id; + setDeviceCharacteristics(pFd); + return pFd->sectorSize; +} + +/* +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is controversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. +*/ +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *pFd = (unixFile*)id; + setDeviceCharacteristics(pFd); + return pFd->deviceCharacteristics; +} + +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + +/* +** Return the system page size. +** +** This function should not be called directly by other code in this file. +** Instead, it should be called via macro osGetpagesize(). +*/ +static int unixGetpagesize(void){ +#if OS_VXWORKS + return 1024; +#elif defined(_BSD_SOURCE) + return getpagesize(); +#else + return (int)sysconf(_SC_PAGESIZE); +#endif +} + +#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ + +#ifndef SQLITE_OMIT_WAL + +/* +** Object used to represent an shared memory buffer. +** +** When multiple threads all reference the same wal-index, each thread +** has its own unixShm object, but they all point to a single instance +** of this unixShmNode object. In other words, each wal-index is opened +** only once per process. +** +** Each unixShmNode object is connected to a single unixInodeInfo object. +** We could coalesce this object into unixInodeInfo, but that would mean +** every open file that does not use shared memory (in other words, most +** open files) would have to carry around this extra information. So +** the unixInodeInfo object contains a pointer to this unixShmNode object +** and the unixShmNode object is created only when needed. +** +** unixMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** +** The following fields are read-only after the object is created: +** +** hShm +** zFilename +** +** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and +** unixMutexHeld() is true when reading or writing any other field +** in this structure. +** +** aLock[SQLITE_SHM_NLOCK]: +** This array records the various locks held by clients on each of the +** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no +** locks are held by the process on this slot. If it is set to -1, then +** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[] +** value is set to a positive value, then it is the number of shared +** locks currently held on the slot. +** +** aMutex[SQLITE_SHM_NLOCK]: +** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex +** pShmMutex is used to protect the aLock[] array and the right to +** call fcntl() on unixShmNode.hShm to obtain or release locks. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array +** of mutexes - one for each locking slot. To read or write locking +** slot aLock[iSlot], the caller must hold the corresponding mutex +** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a +** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held. +*/ +struct unixShmNode { + unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ + sqlite3_mutex *pShmMutex; /* Mutex to access this object */ + char *zFilename; /* Name of the mmapped file */ + int hShm; /* Open file descriptor */ + int szRegion; /* Size of shared-memory regions */ + u16 nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + u8 isUnlocked; /* True if no DMS lock held */ + char **apRegion; /* Array of mapped shared-memory regions */ + int nRef; /* Number of unixShm objects pointing to this */ + unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK]; +#endif + int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ +#ifdef SQLITE_DEBUG + u8 nextShmId; /* Next available unixShm.id value */ +#endif +}; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** unixShm.pShmNode +** unixShm.id +** +** All other fields are read/write. The unixShm.pShmNode->pShmMutex must +** be held while accessing any read/write fields. +*/ +struct unixShm { + unixShmNode *pShmNode; /* The underlying unixShmNode object */ + unixShm *pNext; /* Next unixShm with the same unixShmNode */ + u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */ + u8 id; /* Id of this connection within its unixShmNode */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +}; + +/* +** Constants used for locking +*/ +#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Use F_GETLK to check whether or not there are any readers with open +** wal-mode transactions in other processes on database file pFile. If +** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are +** such transactions, or 0 otherwise. If an error occurs, return an +** SQLite error code. The final value of *piOut is undefined in this +** case. +*/ +static int unixFcntlExternalReader(unixFile *pFile, int *piOut){ + int rc = SQLITE_OK; + *piOut = 0; + if( pFile->pShm){ + unixShmNode *pShmNode = pFile->pShm->pShmNode; + struct flock f; + + memset(&f, 0, sizeof(f)); + f.l_type = F_WRLCK; + f.l_whence = SEEK_SET; + f.l_start = UNIX_SHM_BASE + 3; + f.l_len = SQLITE_SHM_NLOCK - 3; + + sqlite3_mutex_enter(pShmNode->pShmMutex); + if( osFcntl(pShmNode->hShm, F_GETLK, &f)<0 ){ + rc = SQLITE_IOERR_LOCK; + }else{ + *piOut = (f.l_type!=F_UNLCK); + } + sqlite3_mutex_leave(pShmNode->pShmMutex); + } + + return rc; +} + + +/* +** Apply posix advisory locks for all bytes from ofst through ofst+n-1. +** +** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking +** otherwise. +*/ +static int unixShmSystemLock( + unixFile *pFile, /* Open connection to the WAL file */ + int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ + int ofst, /* First byte of the locking range */ + int n /* Number of bytes to lock */ +){ + unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ + + pShmNode = pFile->pInode->pShmNode; + + /* Assert that the parameters are within expected range and that the + ** correct mutex or mutexes are held. */ + assert( pShmNode->nRef>=0 ); + assert( (ofst==UNIX_SHM_DMS && n==1) + || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK)) + ); + if( ofst==UNIX_SHM_DMS ){ + assert( pShmNode->nRef>0 || unixMutexHeld() ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int ii; + for(ii=ofst-UNIX_SHM_BASE; iiaMutex[ii]) ); + } +#else + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 ); +#endif + } + + /* Shared locks never span more than one byte */ + assert( n==1 || lockType!=F_RDLCK ); + + /* Locks are within range */ + assert( n>=1 && n<=SQLITE_SHM_NLOCK ); + assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) ); + + if( pShmNode->hShm>=0 ){ + int res; + /* Initialize the locking parameters */ + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; + res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); + if( res==-1 ){ +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1 + rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); +#else + rc = SQLITE_BUSY; +#endif + } + } + + /* Do debug tracing */ +#ifdef SQLITE_DEBUG + OSTRACE(("SHM-LOCK ")); + if( rc==SQLITE_OK ){ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1)); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1)); + } + }else{ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1)); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1)); + } + } +#endif + + return rc; +} + +/* +** Return the minimum number of 32KB shm regions that should be mapped at +** a time, assuming that each mapping must be an integer multiple of the +** current system page-size. +** +** Usually, this is 1. The exception seems to be systems that are configured +** to use 64KB pages - in this case each mapping must cover at least two +** shm regions. +*/ +static int unixShmRegionPerMap(void){ + int shmsz = 32*1024; /* SHM region size */ + int pgsz = osGetpagesize(); /* System page size */ + assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */ + if( pgszpInode->pShmNode; + assert( unixMutexHeld() ); + if( p && ALWAYS(p->nRef==0) ){ + int nShmPerMap = unixShmRegionPerMap(); + int i; + assert( p->pInode==pFd->pInode ); + sqlite3_mutex_free(p->pShmMutex); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + for(i=0; iaMutex[i]); + } +#endif + for(i=0; inRegion; i+=nShmPerMap){ + if( p->hShm>=0 ){ + osMunmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } + } + sqlite3_free(p->apRegion); + if( p->hShm>=0 ){ + robust_close(pFd, p->hShm, __LINE__); + p->hShm = -1; + } + p->pInode->pShmNode = 0; + sqlite3_free(p); + } +} + +/* +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to +** take it now. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If the DMS cannot be locked because this is a readonly_shm=1 +** connection and no other process already holds a lock, return +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. +*/ +static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ + struct flock lock; + int rc = SQLITE_OK; + + /* Use F_GETLK to determine the locks other processes are holding + ** on the DMS byte. If it indicates that another process is holding + ** a SHARED lock, then this process may also take a SHARED lock + ** and proceed with opening the *-shm file. + ** + ** Or, if no other process is holding any lock, then this process + ** is the first to open it. In this case take an EXCLUSIVE lock on the + ** DMS byte and truncate the *-shm file to zero bytes in size. Then + ** downgrade to a SHARED lock on the DMS byte. + ** + ** If another process is holding an EXCLUSIVE lock on the DMS byte, + ** return SQLITE_BUSY to the caller (it will try again). An earlier + ** version of this code attempted the SHARED lock at this point. But + ** this introduced a subtle race condition: if the process holding + ** EXCLUSIVE failed just before truncating the *-shm file, then this + ** process might open and use the *-shm file without truncating it. + ** And if the *-shm file has been corrupted by a power failure or + ** system crash, the database itself may also become corrupt. */ + lock.l_whence = SEEK_SET; + lock.l_start = UNIX_SHM_DMS; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) { + rc = SQLITE_IOERR_LOCK; + }else if( lock.l_type==F_UNLCK ){ + if( pShmNode->isReadonly ){ + pShmNode->isUnlocked = 1; + rc = SQLITE_READONLY_CANTINIT; + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* Do not use a blocking lock here. If the lock cannot be obtained + ** immediately, it means some other connection is truncating the + ** *-shm file. And after it has done so, it will not release its + ** lock, but only downgrade it to a shared lock. So no point in + ** blocking here. The call below to obtain the shared DMS lock may + ** use a blocking lock. */ + int iSaveTimeout = pDbFd->iBusyTimeout; + pDbFd->iBusyTimeout = 0; +#endif + rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + pDbFd->iBusyTimeout = iSaveTimeout; +#endif + /* The first connection to attach must truncate the -shm file. We + ** truncate to 3 bytes (an arbitrary small number, less than the + ** -shm header size) rather than 0 as a system debugging aid, to + ** help detect if a -shm file truncation is legitimate or is the work + ** or a rogue process. */ + if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename); + } + } + }else if( lock.l_type==F_WRLCK ){ + rc = SQLITE_BUSY; + } + + if( rc==SQLITE_OK ){ + assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK ); + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); + } + return rc; +} + +/* +** Open a shared-memory area associated with open database file pDbFd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". +** +** Another approach to is to use files in /dev/shm or /dev/tmp or an +** some other tmpfs mount. But if a file in a different directory +** from the database file is used, then differing access permissions +** or a chroot() might cause two different processes on the same +** database to end up using different files for shared memory - +** meaning that their memory would not really be shared - resulting +** in database corruption. Nevertheless, this tmpfs file usage +** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" +** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time +** option results in an incompatible build of SQLite; builds of SQLite +** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the +** same database file at the same time, database corruption will likely +** result. The SQLITE_SHM_DIRECTORY compile-time option is considered +** "unsupported" and may go away in a future SQLite release. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. +*/ +static int unixOpenSharedMemory(unixFile *pDbFd){ + struct unixShm *p = 0; /* The connection to be opened */ + struct unixShmNode *pShmNode; /* The underlying mmapped file */ + int rc = SQLITE_OK; /* Result code */ + unixInodeInfo *pInode; /* The inode of fd */ + char *zShm; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ + + /* Allocate space for the new unixShm object. */ + p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return SQLITE_NOMEM_BKPT; + memset(p, 0, sizeof(*p)); + assert( pDbFd->pShm==0 ); + + /* Check to see if a unixShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. + */ + assert( unixFileMutexNotheld(pDbFd) ); + unixEnterMutex(); + pInode = pDbFd->pInode; + pShmNode = pInode->pShmNode; + if( pShmNode==0 ){ + struct stat sStat; /* fstat() info for database file */ +#ifndef SQLITE_SHM_DIRECTORY + const char *zBasePath = pDbFd->zPath; +#endif + + /* Call fstat() to figure out the permissions on the database file. If + ** a new *-shm file is created, an attempt will be made to create it + ** with the same permissions. + */ + if( osFstat(pDbFd->h, &sStat) ){ + rc = SQLITE_IOERR_FSTAT; + goto shm_open_err; + } + +#ifdef SQLITE_SHM_DIRECTORY + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; +#else + nShmFilename = 6 + (int)strlen(zBasePath); +#endif + pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); + if( pShmNode==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); + zShm = pShmNode->zFilename = (char*)&pShmNode[1]; +#ifdef SQLITE_SHM_DIRECTORY + sqlite3_snprintf(nShmFilename, zShm, + SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", + (u32)sStat.st_ino, (u32)sStat.st_dev); +#else + sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); + sqlite3FileSuffix3(pDbFd->zPath, zShm); +#endif + pShmNode->hShm = -1; + pDbFd->pInode->pShmNode = pShmNode; + pShmNode->pInode = pDbFd->pInode; + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->pShmMutex==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { + int ii; + for(ii=0; iiaMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->aMutex[ii]==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + } + } +#endif + } + + if( pInode->bProcessLock==0 ){ + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW, + (sStat.st_mode&0777)); + } + if( pShmNode->hShm<0 ){ + pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW, + (sStat.st_mode&0777)); + if( pShmNode->hShm<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); + goto shm_open_err; + } + pShmNode->isReadonly = 1; + } + + /* If this process is running as root, make sure that the SHM file + ** is owned by the same user that owns the original database. Otherwise, + ** the original owner will not be able to connect. + */ + robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid); + + rc = unixLockSharedMemory(pDbFd, pShmNode); + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; + } + } + + /* Make the new connection a child of the unixShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + unixLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the unixEnterMutex() mutex and the pointer from the + ** new (struct unixShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the + ** pShmNode->pShmMutex. + */ + sqlite3_mutex_enter(pShmNode->pShmMutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->pShmMutex); + return rc; + + /* Jump here on any error */ +shm_open_err: + unixShmPurge(pDbFd); /* This call frees pShmNode if required */ + sqlite3_free(p); + unixLeaveMutex(); + return rc; +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int unixShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; + int nShmPerMap = unixShmRegionPerMap(); + int nReqRegion; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + } + + p = pDbFd->pShm; + pShmNode = p->pShmNode; + sqlite3_mutex_enter(pShmNode->pShmMutex); + if( pShmNode->isUnlocked ){ + rc = unixLockSharedMemory(pDbFd, pShmNode); + if( rc!=SQLITE_OK ) goto shmpage_out; + pShmNode->isUnlocked = 0; + } + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); + + /* Minimum number of regions required to be mapped. */ + nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; + + if( pShmNode->nRegionszRegion = szRegion; + + if( pShmNode->hShm>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + if( osFstat(pShmNode->hShm, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + + if( sStat.st_sizehShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){ + const char *zFile = pShmNode->zFilename; + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); + goto shmpage_out; + } + } + } + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc( + pShmNode->apRegion, nReqRegion*sizeof(char *) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shmpage_out; + } + pShmNode->apRegion = apNew; + while( pShmNode->nRegionhShm>=0 ){ + pMem = osMmap(0, nMap, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion + ); + if( pMem==MAP_FAILED ){ + rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc64(nMap); + if( pMem==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shmpage_out; + } + memset(pMem, 0, nMap); + } + + for(i=0; iapRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; + } + pShmNode->nRegion += nShmPerMap; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; + sqlite3_mutex_leave(pShmNode->pShmMutex); + return rc; +} + +/* +** Check that the pShmNode->aLock[] array comports with the locking bitmasks +** held by each client. Return true if it does, or false otherwise. This +** is to be used in an assert(). e.g. +** +** assert( assertLockingArrayOk(pShmNode) ); +*/ +#ifdef SQLITE_DEBUG +static int assertLockingArrayOk(unixShmNode *pShmNode){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + return 1; +#else + unixShm *pX; + int aLock[SQLITE_SHM_NLOCK]; + + memset(aLock, 0, sizeof(aLock)); + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + int i; + for(i=0; iexclMask & (1<sharedMask & (1<=0 ); + aLock[i]++; + } + } + } + + assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); + return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +#endif +} +#endif + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHARED and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int unixShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ + unixShm *p; /* The shared memory being locked */ + unixShmNode *pShmNode; /* The underlying file iNode */ + int rc = SQLITE_OK; /* Result code */ + u16 mask = (1<<(ofst+n)) - (1<pShm; + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + aLock = pShmNode->aLock; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); + + /* Check that, if this to be a blocking lock, no locks that occur later + ** in the following list than the lock being obtained are already held: + ** + ** 1. Checkpointer lock (ofst==1). + ** 2. Write lock (ofst==0). + ** 3. Read locks (ofst>=3 && ofstexclMask|p->sharedMask); + assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( + (ofst!=2) /* not RECOVER */ + && (ofst!=1 || lockMask==0 || lockMask==2) + && (ofst!=0 || lockMask<3) + && (ofst<3 || lockMask<(1<exclMask & mask) + ); + if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) + || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) + || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) + ){ + + /* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if + ** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any + ** other thread is holding this mutex, then it is either holding or about + ** to hold a lock exclusive to the one being requested, and we may + ** therefore return SQLITE_BUSY to the caller. + ** + ** Doing this prevents some deadlock scenarios. For example, thread 1 may + ** be a checkpointer blocked waiting on the WRITER lock. And thread 2 + ** may be a normal SQL client upgrading to a write transaction. In this + ** case thread 2 does a non-blocking request for the WRITER lock. But - + ** if it were to use sqlite3_mutex_enter() then it would effectively + ** become a (doomed) blocking request, as thread 2 would block until thread + ** 1 obtained WRITER and released the mutex. Since thread 2 already holds + ** a lock on a read-locking slot at this point, this breaks the + ** anti-deadlock rules (see above). */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int iMutex; + for(iMutex=ofst; iMutexaMutex[iMutex]); + if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes; + }else{ + sqlite3_mutex_enter(pShmNode->aMutex[iMutex]); + } + } +#else + sqlite3_mutex_enter(pShmNode->pShmMutex); +#endif + + if( ALWAYS(rc==SQLITE_OK) ){ + if( flags & SQLITE_SHM_UNLOCK ){ + /* Case (a) - unlock. */ + int bUnlock = 1; + assert( (p->exclMask & p->sharedMask)==0 ); + assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); + assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); + + /* If this is a SHARED lock being unlocked, it is possible that other + ** clients within this process are holding the same SHARED lock. In + ** this case, set bUnlock to 0 so that the posix lock is not removed + ** from the file-descriptor below. */ + if( flags & SQLITE_SHM_SHARED ){ + assert( n==1 ); + assert( aLock[ofst]>=1 ); + if( aLock[ofst]>1 ){ + bUnlock = 0; + aLock[ofst]--; + p->sharedMask &= ~mask; + } + } + + if( bUnlock ){ + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask &= ~mask; + p->exclMask &= ~mask; + } + } + }else if( flags & SQLITE_SHM_SHARED ){ + /* Case (b) - a shared lock. */ + + if( aLock[ofst]<0 ){ + /* An exclusive lock is held by some other connection. BUSY. */ + rc = SQLITE_BUSY; + }else if( aLock[ofst]==0 ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + aLock[ofst]++; + } + }else{ + /* Case (c) - an exclusive lock. */ + int ii; + + assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ); + assert( (p->sharedMask & mask)==0 ); + assert( (p->exclMask & mask)==0 ); + + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. */ + for(ii=ofst; iiexclMask |= mask; + for(ii=ofst; ii=ofst; iMutex--){ + sqlite3_mutex_leave(pShmNode->aMutex[iMutex]); + } +#else + sqlite3_mutex_leave(pShmNode->pShmMutex); +#endif + } + + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", + p->id, osGetpid(0), p->sharedMask, p->exclMask)); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void unixShmBarrier( + sqlite3_file *fd /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + assert( fd->pMethods->xLock==nolockLock + || unixFileMutexNotheld((unixFile*)fd) + ); + unixEnterMutex(); /* Also mutex, for redundancy */ + unixLeaveMutex(); +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int unixShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + unixShm *p; /* The connection to be closed */ + unixShmNode *pShmNode; /* The underlying shared-memory file */ + unixShm **pp; /* For looping over sibling connections */ + unixFile *pDbFd; /* The underlying database file */ + + pDbFd = (unixFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->pShmMutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->pShmMutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + assert( unixFileMutexNotheld(pDbFd) ); + unixEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + if( deleteFlag && pShmNode->hShm>=0 ){ + osUnlink(pShmNode->zFilename); + } + unixShmPurge(pDbFd); + } + unixLeaveMutex(); + + return SQLITE_OK; +} + + +#else +# define unixShmMap 0 +# define unixShmLock 0 +# define unixShmBarrier 0 +# define unixShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** If it is currently memory mapped, unmap file pFd. +*/ +static void unixUnmapfile(unixFile *pFd){ + assert( pFd->nFetchOut==0 ); + if( pFd->pMapRegion ){ + osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); + pFd->pMapRegion = 0; + pFd->mmapSize = 0; + pFd->mmapSizeActual = 0; + } +} + +/* +** Attempt to set the size of the memory mapping maintained by file +** descriptor pFd to nNew bytes. Any existing mapping is discarded. +** +** If successful, this function sets the following variables: +** +** unixFile.pMapRegion +** unixFile.mmapSize +** unixFile.mmapSizeActual +** +** If unsuccessful, an error message is logged via sqlite3_log() and +** the three variables above are zeroed. In this case SQLite should +** continue accessing the database using the xRead() and xWrite() +** methods. +*/ +static void unixRemapfile( + unixFile *pFd, /* File descriptor object */ + i64 nNew /* Required mapping size */ +){ + const char *zErr = "mmap"; + int h = pFd->h; /* File descriptor open on db file */ + u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */ + i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */ + u8 *pNew = 0; /* Location of new mapping */ + int flags = PROT_READ; /* Flags to pass to mmap() */ + + assert( pFd->nFetchOut==0 ); + assert( nNew>pFd->mmapSize ); + assert( nNew<=pFd->mmapSizeMax ); + assert( nNew>0 ); + assert( pFd->mmapSizeActual>=pFd->mmapSize ); + assert( MAP_FAILED!=0 ); + +#ifdef SQLITE_MMAP_READWRITE + if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; +#endif + + if( pOrig ){ +#if HAVE_MREMAP + i64 nReuse = pFd->mmapSize; +#else + const int szSyspage = osGetpagesize(); + i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); +#endif + u8 *pReq = &pOrig[nReuse]; + + /* Unmap any pages of the existing mapping that cannot be reused. */ + if( nReuse!=nOrig ){ + osMunmap(pReq, nOrig-nReuse); + } + +#if HAVE_MREMAP + pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); + zErr = "mremap"; +#else + pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse); + if( pNew!=MAP_FAILED ){ + if( pNew!=pReq ){ + osMunmap(pNew, nNew - nReuse); + pNew = 0; + }else{ + pNew = pOrig; + } + } +#endif + + /* The attempt to extend the existing mapping failed. Free it. */ + if( pNew==MAP_FAILED || pNew==0 ){ + osMunmap(pOrig, nReuse); + } + } + + /* If pNew is still NULL, try to create an entirely new mapping. */ + if( pNew==0 ){ + pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0); + } + + if( pNew==MAP_FAILED ){ + pNew = 0; + nNew = 0; + unixLogError(SQLITE_OK, zErr, pFd->zPath); + + /* If the mmap() above failed, assume that all subsequent mmap() calls + ** will probably fail too. Fall back to using xRead/xWrite exclusively + ** in this case. */ + pFd->mmapSizeMax = 0; + } + pFd->pMapRegion = (void *)pNew; + pFd->mmapSize = pFd->mmapSizeActual = nNew; +} + +/* +** Memory map or remap the file opened by file-descriptor pFd (if the file +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still +** outstanding xFetch() references to it, this function is a no-op. +** +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the +** requested size is the size of the file on disk. The actual size of the +** created mapping is either the requested size or the value configured +** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. +** +** SQLITE_OK is returned if no error occurs (even if the mapping is not +** recreated as a result of outstanding references) or an SQLite error +** code otherwise. +*/ +static int unixMapfile(unixFile *pFd, i64 nMap){ + assert( nMap>=0 || pFd->nFetchOut==0 ); + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); + if( pFd->nFetchOut>0 ) return SQLITE_OK; + + if( nMap<0 ){ + struct stat statbuf; /* Low-level file information */ + if( osFstat(pFd->h, &statbuf) ){ + return SQLITE_IOERR_FSTAT; + } + nMap = statbuf.st_size; + } + if( nMap>pFd->mmapSizeMax ){ + nMap = pFd->mmapSizeMax; + } + + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); + if( nMap!=pFd->mmapSize ){ + unixRemapfile(pFd, nMap); + } + + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** If possible, return a pointer to a mapping of file fd starting at offset +** iOff. The mapping must be valid for at least nAmt bytes. +** +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. +** Finally, if an error does occur, return an SQLite error code. The final +** value of *pp is undefined in this case. +** +** If this function does return a pointer, the caller must eventually +** release the reference by calling unixUnfetch(). +*/ +static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ +#endif + *pp = 0; + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; + if( pFd->pMapRegion==0 ){ + int rc = unixMapfile(pFd, -1); + if( rc!=SQLITE_OK ) return rc; + } + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ + *pp = &((u8 *)pFd->pMapRegion)[iOff]; + pFd->nFetchOut++; + } + } +#endif + return SQLITE_OK; +} + +/* +** If the third argument is non-NULL, then this function releases a +** reference obtained by an earlier call to unixFetch(). The second +** argument passed to this function must be the same as the corresponding +** argument that was passed to the unixFetch() invocation. +** +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping +** may now be invalid and should be unmapped. +*/ +static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ +#if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ + UNUSED_PARAMETER(iOff); + + /* If p==0 (unmap the entire file) then there must be no outstanding + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), + ** then there must be at least one outstanding. */ + assert( (p==0)==(pFd->nFetchOut==0) ); + + /* If p!=0, it must match the iOff value. */ + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); + + if( p ){ + pFd->nFetchOut--; + }else{ + unixUnmapfile(pFd); + } + + assert( pFd->nFetchOut>=0 ); +#else + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(p); + UNUSED_PARAMETER(iOff); +#endif + return SQLITE_OK; +} + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This division contains definitions of sqlite3_io_methods objects that +** implement various file locking strategies. It also contains definitions +** of "finder" functions. A finder-function is used to locate the appropriate +** sqlite3_io_methods object for a particular database file. The pAppData +** field of the sqlite3_vfs VFS objects are initialized to be pointers to +** the correct finder-function for that VFS. +** +** Most finder functions return a pointer to a fixed sqlite3_io_methods +** object. The only interesting finder-function is autolockIoFinder, which +** looks at the filesystem type and tries to guess the best locking +** strategy from that. +** +** For finder-function F, two objects are created: +** +** (1) The real finder-function named "FImpt()". +** +** (2) A constant pointer to this function named just "F". +** +** +** A pointer to the F pointer is used as the pAppData value for VFS +** objects. We have to do this instead of letting pAppData point +** directly at the finder-function since C90 rules prevent a void* +** from be cast into a function pointer. +** +** +** Each instance of this macro generates two objects: +** +** * A constant sqlite3_io_methods object call METHOD that has locking +** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. +** +** * An I/O method finder function called FINDER that returns a pointer +** to the METHOD object in the previous bullet. +*/ +#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ +static const sqlite3_io_methods METHOD = { \ + VERSION, /* iVersion */ \ + CLOSE, /* xClose */ \ + unixRead, /* xRead */ \ + unixWrite, /* xWrite */ \ + unixTruncate, /* xTruncate */ \ + unixSync, /* xSync */ \ + unixFileSize, /* xFileSize */ \ + LOCK, /* xLock */ \ + UNLOCK, /* xUnlock */ \ + CKLOCK, /* xCheckReservedLock */ \ + unixFileControl, /* xFileControl */ \ + unixSectorSize, /* xSectorSize */ \ + unixDeviceCharacteristics, /* xDeviceCapabilities */ \ + SHMMAP, /* xShmMap */ \ + unixShmLock, /* xShmLock */ \ + unixShmBarrier, /* xShmBarrier */ \ + unixShmUnmap, /* xShmUnmap */ \ + unixFetch, /* xFetch */ \ + unixUnfetch, /* xUnfetch */ \ +}; \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ + UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ + return &METHOD; \ +} \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ + = FINDER##Impl; + +/* +** Here are all of the sqlite3_io_methods objects for each of the +** locking strategies. Functions that return pointers to these methods +** are also created. +*/ +IOMETHODS( + posixIoFinder, /* Finder function name */ + posixIoMethods, /* sqlite3_io_methods object name */ + 3, /* shared memory and mmap are enabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + unixUnlock, /* xUnlock method */ + unixCheckReservedLock, /* xCheckReservedLock method */ + unixShmMap /* xShmMap method */ +) +IOMETHODS( + nolockIoFinder, /* Finder function name */ + nolockIoMethods, /* sqlite3_io_methods object name */ + 3, /* shared memory and mmap are enabled */ + nolockClose, /* xClose method */ + nolockLock, /* xLock method */ + nolockUnlock, /* xUnlock method */ + nolockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +IOMETHODS( + dotlockIoFinder, /* Finder function name */ + dotlockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + dotlockClose, /* xClose method */ + dotlockLock, /* xLock method */ + dotlockUnlock, /* xUnlock method */ + dotlockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) + +#if SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + flockIoFinder, /* Finder function name */ + flockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + flockClose, /* xClose method */ + flockLock, /* xLock method */ + flockUnlock, /* xUnlock method */ + flockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if OS_VXWORKS +IOMETHODS( + semIoFinder, /* Finder function name */ + semIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + semXClose, /* xClose method */ + semXLock, /* xLock method */ + semXUnlock, /* xUnlock method */ + semXCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + afpIoFinder, /* Finder function name */ + afpIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + afpClose, /* xClose method */ + afpLock, /* xLock method */ + afpUnlock, /* xUnlock method */ + afpCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +/* +** The proxy locking method is a "super-method" in the sense that it +** opens secondary file descriptors for the conch and lock files and +** it uses proxy, dot-file, AFP, and flock() locking methods on those +** secondary files. For this reason, the division that implements +** proxy locking is located much further down in the file. But we need +** to go ahead and define the sqlite3_io_methods and finder function +** for proxy locking here. So we forward declare the I/O methods. +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +static int proxyClose(sqlite3_file*); +static int proxyLock(sqlite3_file*, int); +static int proxyUnlock(sqlite3_file*, int); +static int proxyCheckReservedLock(sqlite3_file*, int*); +IOMETHODS( + proxyIoFinder, /* Finder function name */ + proxyIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + proxyClose, /* xClose method */ + proxyLock, /* xLock method */ + proxyUnlock, /* xUnlock method */ + proxyCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + nfsIoFinder, /* Finder function name */ + nfsIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + nfsUnlock, /* xUnlock method */ + unixCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** This "finder" function attempts to determine the best locking strategy +** for the database file "filePath". It then returns the sqlite3_io_methods +** object that implements that strategy. +** +** This is for MacOSX only. +*/ +static const sqlite3_io_methods *autolockIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* open file object for the database file */ +){ + static const struct Mapping { + const char *zFilesystem; /* Filesystem type name */ + const sqlite3_io_methods *pMethods; /* Appropriate locking method */ + } aMap[] = { + { "hfs", &posixIoMethods }, + { "ufs", &posixIoMethods }, + { "afpfs", &afpIoMethods }, + { "smbfs", &afpIoMethods }, + { "webdav", &nolockIoMethods }, + { 0, 0 } + }; + int i; + struct statfs fsInfo; + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + if( statfs(filePath, &fsInfo) != -1 ){ + if( fsInfo.f_flags & MNT_RDONLY ){ + return &nolockIoMethods; + } + for(i=0; aMap[i].zFilesystem; i++){ + if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){ + return aMap[i].pMethods; + } + } + } + + /* Default case. Handles, amongst others, "nfs". + ** Test byte-range lock using fcntl(). If the call succeeds, + ** assume that the file-system supports POSIX style locks. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ + return &nfsIoMethods; + } else { + return &posixIoMethods; + } + }else{ + return &dotlockIoMethods; + } +} +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + +#if OS_VXWORKS +/* +** This "finder" function for VxWorks checks to see if posix advisory +** locking works. If it does, then that is what is used. If it does not +** work, then fallback to named semaphore locking. +*/ +static const sqlite3_io_methods *vxworksIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* the open file object */ +){ + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + + /* Test if fcntl() is supported and use POSIX style locks. + ** Otherwise fall back to the named semaphore method. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + return &posixIoMethods; + }else{ + return &semIoMethods; + } +} +static const sqlite3_io_methods + *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; + +#endif /* OS_VXWORKS */ + +/* +** An abstract type for a pointer to an IO method finder function: +*/ +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); + + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +/* +** Initialize the contents of the unixFile structure pointed to by pId. +*/ +static int fillInUnixFile( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + int h, /* Open file descriptor of file being opened */ + sqlite3_file *pId, /* Write to the unixFile structure here */ + const char *zFilename, /* Name of the file being opened */ + int ctrlFlags /* Zero or more UNIXFILE_* values */ +){ + const sqlite3_io_methods *pLockingStyle; + unixFile *pNew = (unixFile *)pId; + int rc = SQLITE_OK; + + assert( pNew->pInode==NULL ); + + /* No locking occurs in temporary files */ + assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); + + OSTRACE(("OPEN %-3d %s\n", h, zFilename)); + pNew->h = h; + pNew->pVfs = pVfs; + pNew->zPath = zFilename; + pNew->ctrlFlags = (u8)ctrlFlags; +#if SQLITE_MAX_MMAP_SIZE>0 + pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; +#endif + if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), + "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; + } + if( strcmp(pVfs->zName,"unix-excl")==0 ){ + pNew->ctrlFlags |= UNIXFILE_EXCL; + } + +#if OS_VXWORKS + pNew->pId = vxworksFindFileId(zFilename); + if( pNew->pId==0 ){ + ctrlFlags |= UNIXFILE_NOLOCK; + rc = SQLITE_NOMEM_BKPT; + } +#endif + + if( ctrlFlags & UNIXFILE_NOLOCK ){ + pLockingStyle = &nolockIoMethods; + }else{ + pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); +#if SQLITE_ENABLE_LOCKING_STYLE + /* Cache zFilename in the locking context (AFP and dotlock override) for + ** proxyLock activation is possible (remote proxy is based on db name) + ** zFilename remains valid until file is closed, to support */ + pNew->lockingContext = (void*)zFilename; +#endif + } + + if( pLockingStyle == &posixIoMethods +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + || pLockingStyle == &nfsIoMethods +#endif + ){ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + /* If an error occurred in findInodeInfo(), close the file descriptor + ** immediately, before releasing the mutex. findInodeInfo() may fail + ** in two scenarios: + ** + ** (a) A call to fstat() failed. + ** (b) A malloc failed. + ** + ** Scenario (b) may only occur if the process is holding no other + ** file descriptors open on the same file. If there were other file + ** descriptors on this file, then no malloc would be required by + ** findInodeInfo(). If this is the case, it is quite safe to close + ** handle h - as it is guaranteed that no posix locks will be released + ** by doing so. + ** + ** If scenario (a) caused the error then things are not so safe. The + ** implicit assumption here is that if fstat() fails, things are in + ** such bad shape that dropping a lock or two doesn't matter much. + */ + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + else if( pLockingStyle == &afpIoMethods ){ + /* AFP locking uses the file path so it needs to be included in + ** the afpLockingContext. + */ + afpLockingContext *pCtx; + pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); + if( pCtx==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + /* NB: zFilename exists and remains valid until the file is closed + ** according to requirement F11141. So we do not need to make a + ** copy of the filename. */ + pCtx->dbPath = zFilename; + pCtx->reserved = 0; + srandomdev(); + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew->lockingContext); + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + } +#endif + + else if( pLockingStyle == &dotlockIoMethods ){ + /* Dotfile locking uses the file path so it needs to be included in + ** the dotlockLockingContext + */ + char *zLockFile; + int nFilename; + assert( zFilename!=0 ); + nFilename = (int)strlen(zFilename) + 6; + zLockFile = (char *)sqlite3_malloc64(nFilename); + if( zLockFile==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); + } + pNew->lockingContext = zLockFile; + } + +#if OS_VXWORKS + else if( pLockingStyle == &semIoMethods ){ + /* Named semaphore locking uses the file path so it needs to be + ** included in the semLockingContext + */ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ + char *zSemName = pNew->pInode->aSemName; + int n; + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", + pNew->pId->zCanonicalName); + for( n=1; zSemName[n]; n++ ) + if( zSemName[n]=='/' ) zSemName[n] = '_'; + pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); + if( pNew->pInode->pSem == SEM_FAILED ){ + rc = SQLITE_NOMEM_BKPT; + pNew->pInode->aSemName[0] = '\0'; + } + } + unixLeaveMutex(); + } +#endif + + storeLastErrno(pNew, 0); +#if OS_VXWORKS + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + h = -1; + osUnlink(zFilename); + pNew->ctrlFlags |= UNIXFILE_DELETE; + } +#endif + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + }else{ + pId->pMethods = pLockingStyle; + OpenCounter(+1); + verifyDbFile(pNew); + } + return rc; +} + +/* +** Directories to consider for temp files. +*/ +static const char *azTempDirs[] = { + 0, + 0, + "/var/tmp", + "/usr/tmp", + "/tmp", + "." +}; + +/* +** Initialize first two members of azTempDirs[] array. +*/ +static void unixTempFileInit(void){ + azTempDirs[0] = getenv("SQLITE_TMPDIR"); + azTempDirs[1] = getenv("TMPDIR"); +} + +/* +** Return the name of a directory in which to put temporary files. +** If no suitable temporary file directory can be found, return NULL. +*/ +static const char *unixTempFileDir(void){ + unsigned int i = 0; + struct stat buf; + const char *zDir = sqlite3_temp_directory; + + while(1){ + if( zDir!=0 + && osStat(zDir, &buf)==0 + && S_ISDIR(buf.st_mode) + && osAccess(zDir, 03)==0 + ){ + return zDir; + } + if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break; + zDir = azTempDirs[i++]; + } + return 0; +} + +/* +** Create a temporary file name in zBuf. zBuf must be allocated +** by the calling process and must be big enough to hold at least +** pVfs->mxPathname bytes. +*/ +static int unixGetTempname(int nBuf, char *zBuf){ + const char *zDir; + int iLimit = 0; + int rc = SQLITE_OK; + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. + */ + zBuf[0] = 0; + SimulateIOError( return SQLITE_IOERR ); + + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + zDir = unixTempFileDir(); + if( zDir==0 ){ + rc = SQLITE_IOERR_GETTEMPPATH; + }else{ + do{ + u64 r; + sqlite3_randomness(sizeof(r), &r); + assert( nBuf>2 ); + zBuf[nBuf-2] = 0; + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", + zDir, r, 0); + if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){ + rc = SQLITE_ERROR; + break; + } + }while( osAccess(zBuf,0)==0 ); + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + return rc; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Routine to transform a unixFile into a proxy-locking unixFile. +** Implementation in the proxy-lock division, but used by unixOpen() +** if SQLITE_PREFER_PROXY_LOCKING is defined. +*/ +static int proxyTransformUnixFile(unixFile*, const char*); +#endif + +/* +** Search for an unused file descriptor that was opened on the database +** file (not a journal or super-journal file) identified by pathname +** zPath with SQLITE_OPEN_XXX flags matching those passed as the second +** argument to this function. +** +** Such a file descriptor may exist if a database connection was closed +** but the associated file descriptor could not be closed because some +** other file descriptor open on the same file is holding a file-lock. +** Refer to comments in the unixClose() function and the lengthy comment +** describing "Posix Advisory Locking" at the start of this file for +** further details. Also, ticket #4018. +** +** If a suitable file descriptor is found, then it is returned. If no +** such file descriptor is located, -1 is returned. +*/ +static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ + UnixUnusedFd *pUnused = 0; + + /* Do not search for an unused file descriptor on vxworks. Not because + ** vxworks would not benefit from the change (it might, we're not sure), + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure + ** feature. */ +#if !OS_VXWORKS + struct stat sStat; /* Results of stat() call */ + + unixEnterMutex(); + + /* A stat() call may fail for various reasons. If this happens, it is + ** almost certain that an open() call on the same path will also fail. + ** For this reason, if an error occurs in the stat() call here, it is + ** ignored and -1 is returned. The caller will try to open a new file + ** descriptor on the same path, fail, and return an error to SQLite. + ** + ** Even if a subsequent open() call does succeed, the consequences of + ** not searching for a reusable file descriptor are not dire. */ + if( inodeList!=0 && 0==osStat(zPath, &sStat) ){ + unixInodeInfo *pInode; + + pInode = inodeList; + while( pInode && (pInode->fileId.dev!=sStat.st_dev + || pInode->fileId.ino!=(u64)sStat.st_ino) ){ + pInode = pInode->pNext; + } + if( pInode ){ + UnixUnusedFd **pp; + assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); + sqlite3_mutex_enter(pInode->pLockMutex); + flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); + for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); + pUnused = *pp; + if( pUnused ){ + *pp = pUnused->pNext; + } + sqlite3_mutex_leave(pInode->pLockMutex); + } + } + unixLeaveMutex(); +#endif /* if !OS_VXWORKS */ + return pUnused; +} + +/* +** Find the mode, uid and gid of file zFile. +*/ +static int getFileMode( + const char *zFile, /* File name */ + mode_t *pMode, /* OUT: Permissions of zFile */ + uid_t *pUid, /* OUT: uid of zFile. */ + gid_t *pGid /* OUT: gid of zFile. */ +){ + struct stat sStat; /* Output of stat() on database file */ + int rc = SQLITE_OK; + if( 0==osStat(zFile, &sStat) ){ + *pMode = sStat.st_mode & 0777; + *pUid = sStat.st_uid; + *pGid = sStat.st_gid; + }else{ + rc = SQLITE_IOERR_FSTAT; + } + return rc; +} + +/* +** This function is called by unixOpen() to determine the unix permissions +** to create new files with. If no error occurs, then SQLITE_OK is returned +** and a value suitable for passing as the third argument to open(2) is +** written to *pMode. If an IO error occurs, an SQLite error code is +** returned and the value of *pMode is not modified. +** +** In most cases, this routine sets *pMode to 0, which will become +** an indication to robust_open() to create the file using +** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. +** But if the file being opened is a WAL or regular journal file, then +** this function queries the file-system for the permissions on the +** corresponding database file and sets *pMode to this value. Whenever +** possible, WAL and journal files are created using the same permissions +** as the associated database file. +** +** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the +** original filename is unavailable. But 8_3_NAMES is only used for +** FAT filesystems and permissions do not matter there, so just use +** the default permissions. In 8_3_NAMES mode, leave *pMode set to zero. +*/ +static int findCreateFileMode( + const char *zPath, /* Path of file (possibly) being created */ + int flags, /* Flags passed as 4th argument to xOpen() */ + mode_t *pMode, /* OUT: Permissions to open file with */ + uid_t *pUid, /* OUT: uid to set on the file */ + gid_t *pGid /* OUT: gid to set on the file */ +){ + int rc = SQLITE_OK; /* Return Code */ + *pMode = 0; + *pUid = 0; + *pGid = 0; + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + char zDb[MAX_PATHNAME+1]; /* Database file path */ + int nDb; /* Number of valid bytes in zDb */ + + /* zPath is a path to a WAL or journal file. The following block derives + ** the path to the associated database file from zPath. This block handles + ** the following naming conventions: + ** + ** "-journal" + ** "-wal" + ** "-journalNN" + ** "-walNN" + ** + ** where NN is a decimal number. The NN naming schemes are + ** used by the test_multiplex.c module. + ** + ** In normal operation, the journal file name will always contain + ** a '-' character. However in 8+3 filename mode, or if a corrupt + ** rollback journal specifies a super-journal with a goofy name, then + ** the '-' might be missing or the '-' might be the first character in + ** the filename. In that case, just return SQLITE_OK with *pMode==0. + */ + nDb = sqlite3Strlen30(zPath) - 1; + while( nDb>0 && zPath[nDb]!='.' ){ + if( zPath[nDb]=='-' ){ + memcpy(zDb, zPath, nDb); + zDb[nDb] = '\0'; + rc = getFileMode(zDb, pMode, pUid, pGid); + break; + } + nDb--; + } + }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ + *pMode = 0600; + }else if( flags & SQLITE_OPEN_URI ){ + /* If this is a main database file and the file was opened using a URI + ** filename, check for the "modeof" parameter. If present, interpret + ** its value as a filename and try to copy the mode, uid and gid from + ** that file. */ + const char *z = sqlite3_uri_parameter(zPath, "modeof"); + if( z ){ + rc = getFileMode(z, pMode, pUid, pGid); + } + } + return rc; +} + +/* +** Open the file zPath. +** +** Previously, the SQLite OS layer used three functions in place of this +** one: +** +** sqlite3OsOpenReadWrite(); +** sqlite3OsOpenReadOnly(); +** sqlite3OsOpenExclusive(); +** +** These calls correspond to the following combinations of flags: +** +** ReadWrite() -> (READWRITE | CREATE) +** ReadOnly() -> (READONLY) +** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) +** +** The old OpenExclusive() accepted a boolean argument - "delFlag". If +** true, the file was configured to be automatically deleted when the +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for +** OpenExclusive(). +*/ +static int unixOpen( + sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ + const char *zPath, /* Pathname of file to be opened */ + sqlite3_file *pFile, /* The file descriptor to be filled in */ + int flags, /* Input flags to control the opening */ + int *pOutFlags /* Output flags returned to SQLite core */ +){ + unixFile *p = (unixFile *)pFile; + int fd = -1; /* File descriptor returned by open() */ + int openFlags = 0; /* Flags to pass to open() */ + int eType = flags&0x0FFF00; /* Type of file to open */ + int noLock; /* True to omit locking primitives */ + int rc = SQLITE_OK; /* Function Return Code */ + int ctrlFlags = 0; /* UNIXFILE_* flags */ + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#if SQLITE_ENABLE_LOCKING_STYLE + int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY); +#endif +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + struct statfs fsInfo; +#endif + + /* If creating a super- or main-file journal, this function will open + ** a file-descriptor on the directory too. The first time unixSync() + ** is called the directory file descriptor will be fsync()ed and close()d. + */ + int isNewJrnl = (isCreate && ( + eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char zTmpname[MAX_PATHNAME+2]; + const char *zName = zPath; + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and super-journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + /* Detect a pid change and reset the PRNG. There is a race condition + ** here such that two or more threads all trying to open databases at + ** the same instant might all reset the PRNG. But multiple resets + ** are harmless. + */ + if( randomnessPid!=osGetpid(0) ){ + randomnessPid = osGetpid(0); + sqlite3_randomness(0,0); + } + memset(p, 0, sizeof(unixFile)); + +#ifdef SQLITE_ASSERT_NO_FILES + /* Applications that never read or write a persistent disk files */ + assert( zName==0 ); +#endif + + if( eType==SQLITE_OPEN_MAIN_DB ){ + UnixUnusedFd *pUnused; + pUnused = findReusableFd(zName, flags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc64(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM_BKPT; + } + } + p->pPreallocatedUnused = pUnused; + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). */ + assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); + + }else if( !zName ){ + /* If zName is NULL, the upper layer is requesting a temp file. */ + assert(isDelete && !isNewJrnl); + rc = unixGetTempname(pVfs->mxPathname, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zName = zTmpname; + + /* Generated temporary filenames are always double-zero terminated + ** for use by sqlite3_uri_parameter(). */ + assert( zName[strlen(zName)+1]==0 ); + } + + /* Determine the value of the flags parameter passed to POSIX function + ** open(). These must be calculated even if open() is not called, as + ** they may be stored as part of the file handle and used by the + ** 'conch file' locking functions later on. */ + if( isReadonly ) openFlags |= O_RDONLY; + if( isReadWrite ) openFlags |= O_RDWR; + if( isCreate ) openFlags |= O_CREAT; + if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); + openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW); + + if( fd<0 ){ + mode_t openMode; /* Permissions to create file with */ + uid_t uid; /* Userid for the file */ + gid_t gid; /* Groupid for the file */ + rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); + if( rc!=SQLITE_OK ){ + assert( !p->pPreallocatedUnused ); + assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); + return rc; + } + fd = robust_open(zName, openFlags, openMode); + OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); + assert( !isExclusive || (openFlags & O_CREAT)!=0 ); + if( fd<0 ){ + if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){ + /* If unable to create a journal because the directory is not + ** writable, change the error code to indicate that. */ + rc = SQLITE_READONLY_DIRECTORY; + }else if( errno!=EISDIR && isReadWrite ){ + /* Failed to open the file for read/write access. Try read-only. */ + flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + openFlags &= ~(O_RDWR|O_CREAT); + flags |= SQLITE_OPEN_READONLY; + openFlags |= O_RDONLY; + isReadonly = 1; + fd = robust_open(zName, openFlags, openMode); + } + } + if( fd<0 ){ + int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); + if( rc==SQLITE_OK ) rc = rc2; + goto open_finished; + } + + /* The owner of the rollback journal or WAL file should always be the + ** same as the owner of the database file. Try to ensure that this is + ** the case. The chown() system call will be a no-op if the current + ** process lacks root privileges, be we should at least try. Without + ** this step, if a root process opens a database file, it can leave + ** behinds a journal/WAL that is owned by root and hence make the + ** database inaccessible to unprivileged processes. + ** + ** If openMode==0, then that means uid and gid are not set correctly + ** (probably because SQLite is configured to use 8+3 filename mode) and + ** in that case we do not want to attempt the chown(). + */ + if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){ + robustFchown(fd, uid, gid); + } + } + assert( fd>=0 ); + if( pOutFlags ){ + *pOutFlags = flags; + } + + if( p->pPreallocatedUnused ){ + p->pPreallocatedUnused->fd = fd; + p->pPreallocatedUnused->flags = + flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); + } + + if( isDelete ){ +#if OS_VXWORKS + zPath = zName; +#elif defined(SQLITE_UNLINK_AFTER_CLOSE) + zPath = sqlite3_mprintf("%s", zName); + if( zPath==0 ){ + robust_close(p, fd, __LINE__); + return SQLITE_NOMEM_BKPT; + } +#else + osUnlink(zName); +#endif + } +#if SQLITE_ENABLE_LOCKING_STYLE + else{ + p->openFlags = openFlags; + } +#endif + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + if( fstatfs(fd, &fsInfo) == -1 ){ + storeLastErrno(p, errno); + robust_close(p, fd, __LINE__); + return SQLITE_IOERR_ACCESS; + } + if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } + if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } +#endif + + /* Set up appropriate ctrlFlags */ + if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; + if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; + noLock = eType!=SQLITE_OPEN_MAIN_DB; + if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; + if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC; + if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; + +#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_PREFER_PROXY_LOCKING + isAutoProxy = 1; +#endif + if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ + char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); + int useProxy = 0; + + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + ** never use proxy, NULL means use proxy for non-local files only. */ + if( envforce!=NULL ){ + useProxy = atoi(envforce)>0; + }else{ + useProxy = !(fsInfo.f_flags&MNT_LOCAL); + } + if( useProxy ){ + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + if( rc==SQLITE_OK ){ + rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); + if( rc!=SQLITE_OK ){ + /* Use unixClose to clean up the resources added in fillInUnixFile + ** and clear all the structure's references. Specifically, + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op + */ + unixClose(pFile); + return rc; + } + } + goto open_finished; + } + } +#endif + + assert( zPath==0 || zPath[0]=='/' + || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL + ); + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + +open_finished: + if( rc!=SQLITE_OK ){ + sqlite3_free(p->pPreallocatedUnused); + } + return rc; +} + + +/* +** Delete the file at zPath. If the dirSync argument is true, fsync() +** the directory after deleting the file. +*/ +static int unixDelete( + sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ + const char *zPath, /* Name of file to be deleted */ + int dirSync /* If true, fsync() directory after deleting file */ +){ + int rc = SQLITE_OK; + UNUSED_PARAMETER(NotUsed); + SimulateIOError(return SQLITE_IOERR_DELETE); + if( osUnlink(zPath)==(-1) ){ + if( errno==ENOENT +#if OS_VXWORKS + || osAccess(zPath,0)!=0 +#endif + ){ + rc = SQLITE_IOERR_DELETE_NOENT; + }else{ + rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); + } + return rc; + } +#ifndef SQLITE_DISABLE_DIRSYNC + if( (dirSync & 1)!=0 ){ + int fd; + rc = osOpenDirectory(zPath, &fd); + if( rc==SQLITE_OK ){ + if( full_fsync(fd,0,0) ){ + rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); + } + robust_close(0, fd, __LINE__); + }else{ + assert( rc==SQLITE_CANTOPEN ); + rc = SQLITE_OK; + } + } +#endif + return rc; +} + +/* +** Test the existence of or access permissions of file zPath. The +** test performed depends on the value of flags: +** +** SQLITE_ACCESS_EXISTS: Return 1 if the file exists +** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. +** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. +** +** Otherwise return 0. +*/ +static int unixAccess( + sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ + const char *zPath, /* Path of the file to examine */ + int flags, /* What do we want to learn about the zPath file? */ + int *pResOut /* Write result boolean here */ +){ + UNUSED_PARAMETER(NotUsed); + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + assert( pResOut!=0 ); + + /* The spec says there are three possible values for flags. But only + ** two of them are actually used */ + assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); + + if( flags==SQLITE_ACCESS_EXISTS ){ + struct stat buf; + *pResOut = 0==osStat(zPath, &buf) && + (!S_ISREG(buf.st_mode) || buf.st_size>0); + }else{ + *pResOut = osAccess(zPath, W_OK|R_OK)==0; + } + return SQLITE_OK; +} + +/* +** A pathname under construction +*/ +typedef struct DbPath DbPath; +struct DbPath { + int rc; /* Non-zero following any error */ + int nSymlink; /* Number of symlinks resolved */ + char *zOut; /* Write the pathname here */ + int nOut; /* Bytes of space available to zOut[] */ + int nUsed; /* Bytes of zOut[] currently being used */ +}; + +/* Forward reference */ +static void appendAllPathElements(DbPath*,const char*); + +/* +** Append a single path element to the DbPath under construction +*/ +static void appendOnePathElement( + DbPath *pPath, /* Path under construction, to which to append zName */ + const char *zName, /* Name to append to pPath. Not zero-terminated */ + int nName /* Number of significant bytes in zName */ +){ + assert( nName>0 ); + assert( zName!=0 ); + if( zName[0]=='.' ){ + if( nName==1 ) return; + if( zName[1]=='.' && nName==2 ){ + if( pPath->nUsed>1 ){ + assert( pPath->zOut[0]=='/' ); + while( pPath->zOut[--pPath->nUsed]!='/' ){} + } + return; + } + } + if( pPath->nUsed + nName + 2 >= pPath->nOut ){ + pPath->rc = SQLITE_ERROR; + return; + } + pPath->zOut[pPath->nUsed++] = '/'; + memcpy(&pPath->zOut[pPath->nUsed], zName, nName); + pPath->nUsed += nName; +#if defined(HAVE_READLINK) && defined(HAVE_LSTAT) + if( pPath->rc==SQLITE_OK ){ + const char *zIn; + struct stat buf; + pPath->zOut[pPath->nUsed] = 0; + zIn = pPath->zOut; + if( osLstat(zIn, &buf)!=0 ){ + if( errno!=ENOENT ){ + pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); + } + }else if( S_ISLNK(buf.st_mode) ){ + ssize_t got; + char zLnk[SQLITE_MAX_PATHLEN+2]; + if( pPath->nSymlink++ > SQLITE_MAX_SYMLINK ){ + pPath->rc = SQLITE_CANTOPEN_BKPT; + return; + } + got = osReadlink(zIn, zLnk, sizeof(zLnk)-2); + if( got<=0 || got>=(ssize_t)sizeof(zLnk)-2 ){ + pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); + return; + } + zLnk[got] = 0; + if( zLnk[0]=='/' ){ + pPath->nUsed = 0; + }else{ + pPath->nUsed -= nName + 1; + } + appendAllPathElements(pPath, zLnk); + } + } +#endif +} + +/* +** Append all path elements in zPath to the DbPath under construction. +*/ +static void appendAllPathElements( + DbPath *pPath, /* Path under construction, to which to append zName */ + const char *zPath /* Path to append to pPath. Is zero-terminated */ +){ + int i = 0; + int j = 0; + do{ + while( zPath[i] && zPath[i]!='/' ){ i++; } + if( i>j ){ + appendOnePathElement(pPath, &zPath[j], i-j); + } + j = i+1; + }while( zPath[i++] ); +} + +/* +** Turn a relative pathname into a full pathname. The relative path +** is stored as a nul-terminated string in the buffer pointed to by +** zPath. +** +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** (in this case, MAX_PATHNAME bytes). The full-path is written to +** this buffer before returning. +*/ +static int unixFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ + DbPath path; + UNUSED_PARAMETER(pVfs); + path.rc = 0; + path.nUsed = 0; + path.nSymlink = 0; + path.nOut = nOut; + path.zOut = zOut; + if( zPath[0]!='/' ){ + char zPwd[SQLITE_MAX_PATHLEN+2]; + if( osGetcwd(zPwd, sizeof(zPwd)-2)==0 ){ + return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); + } + appendAllPathElements(&path, zPwd); + } + appendAllPathElements(&path, zPath); + zOut[path.nUsed] = 0; + if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT; + if( path.nSymlink ) return SQLITE_OK_SYMLINK; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +#include +static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ + UNUSED_PARAMETER(NotUsed); + return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); +} + +/* +** SQLite calls this function immediately after a call to unixDlSym() or +** unixDlOpen() fails (returns a null pointer). If a more detailed error +** message is available, it is written to zBufOut. If no error message +** is available, zBufOut is left unmodified and SQLite uses a default +** error message. +*/ +static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ + const char *zErr; + UNUSED_PARAMETER(NotUsed); + unixEnterMutex(); + zErr = dlerror(); + if( zErr ){ + sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); + } + unixLeaveMutex(); +} +static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ + /* + ** GCC with -pedantic-errors says that C90 does not allow a void* to be + ** cast into a pointer to a function. And yet the library dlsym() routine + ** returns a void* which is really a pointer to a function. So how do we + ** use dlsym() with -pedantic-errors? + ** + ** Variable x below is defined to be a pointer to a function taking + ** parameters void* and const char* and returning a pointer to a function. + ** We initialize x by assigning it a pointer to the dlsym() function. + ** (That assignment requires a cast.) Then we call the function that + ** x points to. + ** + ** This work-around is unlikely to work correctly on any system where + ** you really cannot cast a function pointer into void*. But then, on the + ** other hand, dlsym() will not work on such a system either, so we have + ** not really lost anything. + */ + void (*(*x)(void*,const char*))(void); + UNUSED_PARAMETER(NotUsed); + x = (void(*(*)(void*,const char*))(void))dlsym; + return (*x)(p, zSym); +} +static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){ + UNUSED_PARAMETER(NotUsed); + dlclose(pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define unixDlOpen 0 + #define unixDlError 0 + #define unixDlSym 0 + #define unixDlClose 0 +#endif + +/* +** Write nBuf bytes of random data to the supplied buffer zBuf. +*/ +static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ + UNUSED_PARAMETER(NotUsed); + assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int))); + + /* We have to initialize zBuf to prevent valgrind from reporting + ** errors. The reports issued by valgrind are incorrect - we would + ** prefer that the randomness be increased by making use of the + ** uninitialized space in zBuf - but valgrind errors tend to worry + ** some users. Rather than argue, it seems easier just to initialize + ** the whole array and silence valgrind, even if that means less randomness + ** in the random seed. + ** + ** When testing, initializing zBuf[] to zero is all we do. That means + ** that we always use the same random number sequence. This makes the + ** tests repeatable. + */ + memset(zBuf, 0, nBuf); + randomnessPid = osGetpid(0); +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) + { + int fd, got; + fd = robust_open("/dev/urandom", O_RDONLY, 0); + if( fd<0 ){ + time_t t; + time(&t); + memcpy(zBuf, &t, sizeof(t)); + memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); + assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); + nBuf = sizeof(t) + sizeof(randomnessPid); + }else{ + do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR ); + robust_close(0, fd, __LINE__); + } + } +#endif + return nBuf; +} + + +/* +** Sleep for a little while. Return the amount of time slept. +** The argument is the number of microseconds we want to sleep. +** The return value is the number of microseconds of sleep actually +** requested from the underlying operating system, a number which +** might be greater than or equal to the argument, but not less +** than the argument. +*/ +static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ +#if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 + struct timespec sp; + sp.tv_sec = microseconds / 1000000; + sp.tv_nsec = (microseconds % 1000000) * 1000; + + /* Almost all modern unix systems support nanosleep(). But if you are + ** compiling for one of the rare exceptions, you can use + ** -DHAVE_NANOSLEEP=0 (perhaps in conjuction with -DHAVE_USLEEP if + ** usleep() is available) in order to bypass the use of nanosleep() */ + nanosleep(&sp, NULL); + + UNUSED_PARAMETER(NotUsed); + return microseconds; +#elif defined(HAVE_USLEEP) && HAVE_USLEEP + if( microseconds>=1000000 ) sleep(microseconds/1000000); + if( microseconds%1000000 ) usleep(microseconds%1000000); + UNUSED_PARAMETER(NotUsed); + return microseconds; +#else + int seconds = (microseconds+999999)/1000000; + sleep(seconds); + UNUSED_PARAMETER(NotUsed); + return seconds*1000000; +#endif +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + int rc = SQLITE_OK; +#if defined(NO_GETTOD) + time_t t; + time(&t); + *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; +#elif OS_VXWORKS + struct timespec sNow; + clock_gettime(CLOCK_REALTIME, &sNow); + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; +#else + struct timeval sNow; + (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; +#endif + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(NotUsed); + return rc; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ + sqlite3_int64 i = 0; + int rc; + UNUSED_PARAMETER(NotUsed); + rc = unixCurrentTimeInt64(0, &i); + *prNow = i/86400000.0; + return rc; +} +#else +# define unixCurrentTime 0 +#endif + +/* +** The xGetLastError() method is designed to return a better +** low-level error message when operating-system problems come up +** during SQLite operation. Only the integer return code is currently +** used. +*/ +static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ + UNUSED_PARAMETER(NotUsed); + UNUSED_PARAMETER(NotUsed2); + UNUSED_PARAMETER(NotUsed3); + return errno; +} + + +/* +************************ End of sqlite3_vfs methods *************************** +******************************************************************************/ + +/****************************************************************************** +************************** Begin Proxy Locking ******************************** +** +** Proxy locking is a "uber-locking-method" in this sense: It uses the +** other locking methods on secondary lock files. Proxy locking is a +** meta-layer over top of the primitive locking implemented above. For +** this reason, the division that implements of proxy locking is deferred +** until late in the file (here) after all of the other I/O methods have +** been defined - so that the primitive locking methods are available +** as services to help with the implementation of proxy locking. +** +**** +** +** The default locking schemes in SQLite use byte-range locks on the +** database file to coordinate safe, concurrent access by multiple readers +** and writers [http://sqlite.org/lockingv3.html]. The five file locking +** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented +** as POSIX read & write locks over fixed set of locations (via fsctl), +** on AFP and SMB only exclusive byte-range locks are available via fsctl +** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states. +** To simulate a F_RDLCK on the shared range, on AFP a randomly selected +** address in the shared range is taken for a SHARED lock, the entire +** shared range is taken for an EXCLUSIVE lock): +** +** PENDING_BYTE 0x40000000 +** RESERVED_BYTE 0x40000001 +** SHARED_RANGE 0x40000002 -> 0x40000200 +** +** This works well on the local file system, but shows a nearly 100x +** slowdown in read performance on AFP because the AFP client disables +** the read cache when byte-range locks are present. Enabling the read +** cache exposes a cache coherency problem that is present on all OS X +** supported network file systems. NFS and AFP both observe the +** close-to-open semantics for ensuring cache coherency +** [http://nfs.sourceforge.net/#faq_a8], which does not effectively +** address the requirements for concurrent database access by multiple +** readers and writers +** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html]. +** +** To address the performance and cache coherency issues, proxy file locking +** changes the way database access is controlled by limiting access to a +** single host at a time and moving file locks off of the database file +** and onto a proxy file on the local file system. +** +** +** Using proxy locks +** ----------------- +** +** C APIs +** +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, +** | ":auto:"); +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, +** &); +** +** +** SQL pragmas +** +** PRAGMA [database.]lock_proxy_file= | :auto: +** PRAGMA [database.]lock_proxy_file +** +** Specifying ":auto:" means that if there is a conch file with a matching +** host ID in it, the proxy path in the conch file will be used, otherwise +** a proxy path based on the user's temp dir +** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the +** actual proxy file name is generated from the name and path of the +** database file. For example: +** +** For database path "/Users/me/foo.db" +** The lock path will be "/sqliteplocks/_Users_me_foo.db:auto:") +** +** Once a lock proxy is configured for a database connection, it can not +** be removed, however it may be switched to a different proxy path via +** the above APIs (assuming the conch file is not being held by another +** connection or process). +** +** +** How proxy locking works +** ----------------------- +** +** Proxy file locking relies primarily on two new supporting files: +** +** * conch file to limit access to the database file to a single host +** at a time +** +** * proxy file to act as a proxy for the advisory locks normally +** taken on the database +** +** The conch file - to use a proxy file, sqlite must first "hold the conch" +** by taking an sqlite-style shared lock on the conch file, reading the +** contents and comparing the host's unique host ID (see below) and lock +** proxy path against the values stored in the conch. The conch file is +** stored in the same directory as the database file and the file name +** is patterned after the database file name as ".-conch". +** If the conch file does not exist, or its contents do not match the +** host ID and/or proxy path, then the lock is escalated to an exclusive +** lock and the conch file contents is updated with the host ID and proxy +** path and the lock is downgraded to a shared lock again. If the conch +** is held by another process (with a shared lock), the exclusive lock +** will fail and SQLITE_BUSY is returned. +** +** The proxy file - a single-byte file used for all advisory file locks +** normally taken on the database file. This allows for safe sharing +** of the database file for multiple readers and writers on the same +** host (the conch ensures that they all use the same local lock file). +** +** Requesting the lock proxy does not immediately take the conch, it is +** only taken when the first request to lock database file is made. +** This matches the semantics of the traditional locking behavior, where +** opening a connection to a database file does not take a lock on it. +** The shared lock and an open file descriptor are maintained until +** the connection to the database is closed. +** +** The proxy file and the lock file are never deleted so they only need +** to be created the first time they are used. +** +** Configuration options +** --------------------- +** +** SQLITE_PREFER_PROXY_LOCKING +** +** Database files accessed on non-local file systems are +** automatically configured for proxy locking, lock files are +** named automatically using the same logic as +** PRAGMA lock_proxy_file=":auto:" +** +** SQLITE_PROXY_DEBUG +** +** Enables the logging of error messages during host id file +** retrieval and creation +** +** LOCKPROXYDIR +** +** Overrides the default directory used for lock proxy files that +** are named automatically via the ":auto:" setting +** +** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +** +** Permissions to use when creating a directory for storing the +** lock proxy files, only used when LOCKPROXYDIR is not set. +** +** +** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, +** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will +** force proxy locking to be used for every database file opened, and 0 +** will force automatic proxy locking to be disabled for all database +** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or +** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). +*/ + +/* +** Proxy locking is only available on MacOSX +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + +/* +** The proxyLockingContext has the path and file structures for the remote +** and local proxy files in it +*/ +typedef struct proxyLockingContext proxyLockingContext; +struct proxyLockingContext { + unixFile *conchFile; /* Open conch file */ + char *conchFilePath; /* Name of the conch file */ + unixFile *lockProxy; /* Open proxy lock file */ + char *lockProxyPath; /* Name of the proxy lock file */ + char *dbPath; /* Name of the open file */ + int conchHeld; /* 1 if the conch is held, -1 if lockless */ + int nFails; /* Number of conch taking failures */ + void *oldLockingContext; /* Original lockingcontext to restore on close */ + sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ +}; + +/* +** The proxy lock file path for the database at dbPath is written into lPath, +** which must point to valid, writable memory large enough for a maxLen length +** file path. +*/ +static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ + int len; + int dbLen; + int i; + +#ifdef LOCKPROXYDIR + len = strlcpy(lPath, LOCKPROXYDIR, maxLen); +#else +# ifdef _CS_DARWIN_USER_TEMP_DIR + { + if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ + OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", + lPath, errno, osGetpid(0))); + return SQLITE_IOERR_LOCK; + } + len = strlcat(lPath, "sqliteplocks", maxLen); + } +# else + len = strlcpy(lPath, "/tmp/", maxLen); +# endif +#endif + + if( lPath[len-1]!='/' ){ + len = strlcat(lPath, "/", maxLen); + } + + /* transform the db path to a unique cache name */ + dbLen = (int)strlen(dbPath); + for( i=0; i 0) ){ + /* only mkdir if leaf dir != "." or "/" or ".." */ + if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') + || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ + buf[i]='\0'; + if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ + int err=errno; + if( err!=EEXIST ) { + OSTRACE(("CREATELOCKPATH FAILED creating %s, " + "'%s' proxy lock path=%s pid=%d\n", + buf, strerror(err), lockPath, osGetpid(0))); + return err; + } + } + } + start=i+1; + } + buf[i] = lockPath[i]; + } + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0))); + return 0; +} + +/* +** Create a new VFS file descriptor (stored in memory obtained from +** sqlite3_malloc) and open the file named "path" in the file descriptor. +** +** The caller is responsible not only for closing the file descriptor +** but also for freeing the memory associated with the file descriptor. +*/ +static int proxyCreateUnixFile( + const char *path, /* path for the new unixFile */ + unixFile **ppFile, /* unixFile created and returned by ref */ + int islockfile /* if non zero missing dirs will be created */ +) { + int fd = -1; + unixFile *pNew; + int rc = SQLITE_OK; + int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW; + sqlite3_vfs dummyVfs; + int terrno = 0; + UnixUnusedFd *pUnused = NULL; + + /* 1. first try to open/create the file + ** 2. if that fails, and this is a lock file (not-conch), try creating + ** the parent directories and then try again. + ** 3. if that fails, try to open the file read-only + ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file + */ + pUnused = findReusableFd(path, openFlags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc64(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM_BKPT; + } + } + if( fd<0 ){ + fd = robust_open(path, openFlags, 0); + terrno = errno; + if( fd<0 && errno==ENOENT && islockfile ){ + if( proxyCreateLockPath(path) == SQLITE_OK ){ + fd = robust_open(path, openFlags, 0); + } + } + } + if( fd<0 ){ + openFlags = O_RDONLY | O_NOFOLLOW; + fd = robust_open(path, openFlags, 0); + terrno = errno; + } + if( fd<0 ){ + if( islockfile ){ + return SQLITE_BUSY; + } + switch (terrno) { + case EACCES: + return SQLITE_PERM; + case EIO: + return SQLITE_IOERR_LOCK; /* even though it is the conch */ + default: + return SQLITE_CANTOPEN_BKPT; + } + } + + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); + if( pNew==NULL ){ + rc = SQLITE_NOMEM_BKPT; + goto end_create_proxy; + } + memset(pNew, 0, sizeof(unixFile)); + pNew->openFlags = openFlags; + memset(&dummyVfs, 0, sizeof(dummyVfs)); + dummyVfs.pAppData = (void*)&autolockIoFinder; + dummyVfs.zName = "dummy"; + pUnused->fd = fd; + pUnused->flags = openFlags; + pNew->pPreallocatedUnused = pUnused; + + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); + if( rc==SQLITE_OK ){ + *ppFile = pNew; + return SQLITE_OK; + } +end_create_proxy: + robust_close(pNew, fd, __LINE__); + sqlite3_free(pNew); + sqlite3_free(pUnused); + return rc; +} + +#ifdef SQLITE_TEST +/* simulate multiple hosts by creating unique hostid file paths */ +SQLITE_API int sqlite3_hostid_num = 0; +#endif + +#define PROXY_HOSTIDLEN 16 /* conch file host id length */ + +#if HAVE_GETHOSTUUID +/* Not always defined in the headers as it ought to be */ +extern int gethostuuid(uuid_t id, const struct timespec *wait); +#endif + +/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN +** bytes of writable memory. +*/ +static int proxyGetHostID(unsigned char *pHostID, int *pError){ + assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); + memset(pHostID, 0, PROXY_HOSTIDLEN); +#if HAVE_GETHOSTUUID + { + struct timespec timeout = {1, 0}; /* 1 sec timeout */ + if( gethostuuid(pHostID, &timeout) ){ + int err = errno; + if( pError ){ + *pError = err; + } + return SQLITE_IOERR; + } + } +#else + UNUSED_PARAMETER(pError); +#endif +#ifdef SQLITE_TEST + /* simulate multiple hosts by creating unique hostid file paths */ + if( sqlite3_hostid_num != 0){ + pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); + } +#endif + + return SQLITE_OK; +} + +/* The conch file contains the header, host id and lock file path + */ +#define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */ +#define PROXY_HEADERLEN 1 /* conch file header length */ +#define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) +#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) + +/* +** Takes an open conch file, copies the contents to a new path and then moves +** it back. The newly created file's file descriptor is assigned to the +** conch file structure and finally the original conch file descriptor is +** closed. Returns zero if successful. +*/ +static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + char tPath[MAXPATHLEN]; + char buf[PROXY_MAXCONCHLEN]; + char *cPath = pCtx->conchFilePath; + size_t readLen = 0; + size_t pathLen = 0; + char errmsg[64] = ""; + int fd = -1; + int rc = -1; + UNUSED_PARAMETER(myHostID); + + /* create a new path by replace the trailing '-conch' with '-break' */ + pathLen = strlcpy(tPath, cPath, MAXPATHLEN); + if( pathLen>MAXPATHLEN || pathLen<6 || + (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ + sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); + goto end_breaklock; + } + /* read the conch content */ + readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); + if( readLenh, __LINE__); + conchFile->h = fd; + conchFile->openFlags = O_RDWR | O_CREAT; + +end_breaklock: + if( rc ){ + if( fd>=0 ){ + osUnlink(tPath); + robust_close(pFile, fd, __LINE__); + } + fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); + } + return rc; +} + +/* Take the requested lock on the conch file and break a stale lock if the +** host id matches. +*/ +static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + int nTries = 0; + struct timespec conchModTime; + + memset(&conchModTime, 0, sizeof(conchModTime)); + do { + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + nTries ++; + if( rc==SQLITE_BUSY ){ + /* If the lock failed (busy): + * 1st try: get the mod time of the conch, wait 0.5s and try again. + * 2nd try: fail if the mod time changed or host id is different, wait + * 10 sec and try again + * 3rd try: break the lock unless the mod time has changed. + */ + struct stat buf; + if( osFstat(conchFile->h, &buf) ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_LOCK; + } + + if( nTries==1 ){ + conchModTime = buf.st_mtimespec; + unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/ + continue; + } + + assert( nTries>1 ); + if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || + conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ + return SQLITE_BUSY; + } + + if( nTries==2 ){ + char tBuf[PROXY_MAXCONCHLEN]; + int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); + if( len<0 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_LOCK; + } + if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ + /* don't break the lock if the host id doesn't match */ + if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ + return SQLITE_BUSY; + } + }else{ + /* don't break the lock on short read or a version mismatch */ + return SQLITE_BUSY; + } + unixSleep(0,10000000); /* wait 10 sec and try the lock again */ + continue; + } + + assert( nTries==3 ); + if( 0==proxyBreakConchLock(pFile, myHostID) ){ + rc = SQLITE_OK; + if( lockType==EXCLUSIVE_LOCK ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); + } + if( !rc ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + } + } + } + } while( rc==SQLITE_BUSY && nTries<3 ); + + return rc; +} + +/* Takes the conch by taking a shared lock and read the contents conch, if +** lockPath is non-NULL, the host ID and lock file path must match. A NULL +** lockPath means that the lockPath in the conch file will be used if the +** host IDs match, or a new lock path will be generated automatically +** and written to the conch file. +*/ +static int proxyTakeConch(unixFile *pFile){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + + if( pCtx->conchHeld!=0 ){ + return SQLITE_OK; + }else{ + unixFile *conchFile = pCtx->conchFile; + uuid_t myHostID; + int pError = 0; + char readBuf[PROXY_MAXCONCHLEN]; + char lockPath[MAXPATHLEN]; + char *tempLockPath = NULL; + int rc = SQLITE_OK; + int createConch = 0; + int hostIdMatch = 0; + int readLen = 0; + int tryOldLockPath = 0; + int forceNewLockPath = 0; + + OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); + + rc = proxyGetHostID(myHostID, &pError); + if( (rc&0xff)==SQLITE_IOERR ){ + storeLastErrno(pFile, pError); + goto end_takeconch; + } + rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + goto end_takeconch; + } + /* read the existing conch file */ + readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); + if( readLen<0 ){ + /* I/O error: lastErrno set by seekAndRead */ + storeLastErrno(pFile, conchFile->lastErrno); + rc = SQLITE_IOERR_READ; + goto end_takeconch; + }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || + readBuf[0]!=(char)PROXY_CONCHVERSION ){ + /* a short read or version format mismatch means we need to create a new + ** conch file. + */ + createConch = 1; + } + /* if the host id matches and the lock path already exists in the conch + ** we'll try to use the path there, if we can't open that path, we'll + ** retry with a new auto-generated path + */ + do { /* in case we need to try again for an :auto: named lock file */ + + if( !createConch && !forceNewLockPath ){ + hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, + PROXY_HOSTIDLEN); + /* if the conch has data compare the contents */ + if( !pCtx->lockProxyPath ){ + /* for auto-named local lock file, just check the host ID and we'll + ** use the local lock file path that's already in there + */ + if( hostIdMatch ){ + size_t pathLen = (readLen - PROXY_PATHINDEX); + + if( pathLen>=MAXPATHLEN ){ + pathLen=MAXPATHLEN-1; + } + memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen); + lockPath[pathLen] = 0; + tempLockPath = lockPath; + tryOldLockPath = 1; + /* create a copy of the lock path if the conch is taken */ + goto end_takeconch; + } + }else if( hostIdMatch + && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX], + readLen-PROXY_PATHINDEX) + ){ + /* conch host and lock path match */ + goto end_takeconch; + } + } + + /* if the conch isn't writable and doesn't match, we can't take it */ + if( (conchFile->openFlags&O_RDWR) == 0 ){ + rc = SQLITE_BUSY; + goto end_takeconch; + } + + /* either the conch didn't match or we need to create a new one */ + if( !pCtx->lockProxyPath ){ + proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); + tempLockPath = lockPath; + /* create a copy of the lock path _only_ if the conch is taken */ + } + + /* update conch with host and path (this will fail if other process + ** has a shared lock already), if the host id matches, use the big + ** stick. + */ + futimes(conchFile->h, NULL); + if( hostIdMatch && !createConch ){ + if( conchFile->pInode && conchFile->pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + } else { + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + }else{ + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + if( rc==SQLITE_OK ){ + char writeBuffer[PROXY_MAXCONCHLEN]; + int writeSize = 0; + + writeBuffer[0] = (char)PROXY_CONCHVERSION; + memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); + if( pCtx->lockProxyPath!=NULL ){ + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, + MAXPATHLEN); + }else{ + strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); + } + writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); + robust_ftruncate(conchFile->h, writeSize); + rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); + full_fsync(conchFile->h,0,0); + /* If we created a new conch file (not just updated the contents of a + ** valid conch file), try to match the permissions of the database + */ + if( rc==SQLITE_OK && createConch ){ + struct stat buf; + int err = osFstat(pFile->h, &buf); + if( err==0 ){ + mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | + S_IROTH|S_IWOTH); + /* try to match the database file R/W permissions, ignore failure */ +#ifndef SQLITE_PROXY_DEBUG + osFchmod(conchFile->h, cmode); +#else + do{ + rc = osFchmod(conchFile->h, cmode); + }while( rc==(-1) && errno==EINTR ); + if( rc!=0 ){ + int code = errno; + fprintf(stderr, "fchmod %o FAILED with %d %s\n", + cmode, code, strerror(code)); + } else { + fprintf(stderr, "fchmod %o SUCCEDED\n",cmode); + } + }else{ + int code = errno; + fprintf(stderr, "STAT FAILED[%d] with %d %s\n", + err, code, strerror(code)); +#endif + } + } + } + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); + + end_takeconch: + OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); + if( rc==SQLITE_OK && pFile->openFlags ){ + int fd; + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + } + pFile->h = -1; + fd = robust_open(pCtx->dbPath, pFile->openFlags, 0); + OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); + if( fd>=0 ){ + pFile->h = fd; + }else{ + rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called + during locking */ + } + } + if( rc==SQLITE_OK && !pCtx->lockProxy ){ + char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath; + rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); + if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ + /* we couldn't create the proxy lock file with the old lock file path + ** so try again via auto-naming + */ + forceNewLockPath = 1; + tryOldLockPath = 0; + continue; /* go back to the do {} while start point, try again */ + } + } + if( rc==SQLITE_OK ){ + /* Need to make a copy of path if we extracted the value + ** from the conch file or the path was allocated on the stack + */ + if( tempLockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath); + if( !pCtx->lockProxyPath ){ + rc = SQLITE_NOMEM_BKPT; + } + } + } + if( rc==SQLITE_OK ){ + pCtx->conchHeld = 1; + + if( pCtx->lockProxy->pMethod == &afpIoMethods ){ + afpLockingContext *afpCtx; + afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; + afpCtx->dbPath = pCtx->lockProxyPath; + } + } else { + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + OSTRACE(("TAKECONCH %d %s\n", conchFile->h, + rc==SQLITE_OK?"ok":"failed")); + return rc; + } while (1); /* in case we need to retry the :auto: lock file - + ** we should never get here except via the 'continue' call. */ + } +} + +/* +** If pFile holds a lock on a conch file, then release that lock. +*/ +static int proxyReleaseConch(unixFile *pFile){ + int rc = SQLITE_OK; /* Subroutine return code */ + proxyLockingContext *pCtx; /* The locking context for the proxy lock */ + unixFile *conchFile; /* Name of the conch file */ + + pCtx = (proxyLockingContext *)pFile->lockingContext; + conchFile = pCtx->conchFile; + OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); + if( pCtx->conchHeld>0 ){ + rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + pCtx->conchHeld = 0; + OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + +/* +** Given the name of a database file, compute the name of its conch file. +** Store the conch filename in memory obtained from sqlite3_malloc64(). +** Make *pConchPath point to the new name. Return SQLITE_OK on success +** or SQLITE_NOMEM if unable to obtain memory. +** +** The caller is responsible for ensuring that the allocated memory +** space is eventually freed. +** +** *pConchPath is set to NULL if a memory allocation error occurs. +*/ +static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ + int i; /* Loop counter */ + int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ + char *conchPath; /* buffer in which to construct conch name */ + + /* Allocate space for the conch filename and initialize the name to + ** the name of the original database file. */ + *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); + if( conchPath==0 ){ + return SQLITE_NOMEM_BKPT; + } + memcpy(conchPath, dbPath, len+1); + + /* now insert a "." before the last / character */ + for( i=(len-1); i>=0; i-- ){ + if( conchPath[i]=='/' ){ + i++; + break; + } + } + conchPath[i]='.'; + while ( ilockingContext; + char *oldPath = pCtx->lockProxyPath; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + + /* nothing to do if the path is NULL, :auto: or matches the existing path */ + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || + (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){ + return SQLITE_OK; + }else{ + unixFile *lockProxy = pCtx->lockProxy; + pCtx->lockProxy=NULL; + pCtx->conchHeld = 0; + if( lockProxy!=NULL ){ + rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + } + sqlite3_free(oldPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, path); + } + + return rc; +} + +/* +** pFile is a file that has been opened by a prior xOpen call. dbPath +** is a string buffer at least MAXPATHLEN+1 characters in size. +** +** This routine find the filename associated with pFile and writes it +** int dbPath. +*/ +static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ +#if defined(__APPLE__) + if( pFile->pMethod == &afpIoMethods ){ + /* afp style keeps a reference to the db path in the filePath field + ** of the struct */ + assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, + MAXPATHLEN); + } else +#endif + if( pFile->pMethod == &dotlockIoMethods ){ + /* dot lock style uses the locking context to store the dot lock + ** file path */ + int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); + memcpy(dbPath, (char *)pFile->lockingContext, len + 1); + }else{ + /* all other styles use the locking context to store the db file path */ + assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN); + } + return SQLITE_OK; +} + +/* +** Takes an already filled in unix file and alters it so all file locking +** will be performed on the local proxy lock file. The following fields +** are preserved in the locking context so that they can be restored and +** the unix structure properly cleaned up at close time: +** ->lockingContext +** ->pMethod +*/ +static int proxyTransformUnixFile(unixFile *pFile, const char *path) { + proxyLockingContext *pCtx; + char dbPath[MAXPATHLEN+1]; /* Name of the database file */ + char *lockPath=NULL; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + proxyGetDbPathForUnixFile(pFile, dbPath); + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ + lockPath=NULL; + }else{ + lockPath=(char *)path; + } + + OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, + (lockPath ? lockPath : ":auto:"), osGetpid(0))); + + pCtx = sqlite3_malloc64( sizeof(*pCtx) ); + if( pCtx==0 ){ + return SQLITE_NOMEM_BKPT; + } + memset(pCtx, 0, sizeof(*pCtx)); + + rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); + if( rc==SQLITE_OK ){ + rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); + if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ + /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and + ** (c) the file system is read-only, then enable no-locking access. + ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts + ** that openFlags will have only one of O_RDONLY or O_RDWR. + */ + struct statfs fsInfo; + struct stat conchInfo; + int goLockless = 0; + + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { + int err = errno; + if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ + goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; + } + } + if( goLockless ){ + pCtx->conchHeld = -1; /* read only FS/ lockless */ + rc = SQLITE_OK; + } + } + } + if( rc==SQLITE_OK && lockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); + } + + if( rc==SQLITE_OK ){ + pCtx->dbPath = sqlite3DbStrDup(0, dbPath); + if( pCtx->dbPath==NULL ){ + rc = SQLITE_NOMEM_BKPT; + } + } + if( rc==SQLITE_OK ){ + /* all memory is allocated, proxys are created and assigned, + ** switch the locking context and pMethod then return. + */ + pCtx->oldLockingContext = pFile->lockingContext; + pFile->lockingContext = pCtx; + pCtx->pOldMethod = pFile->pMethod; + pFile->pMethod = &proxyIoMethods; + }else{ + if( pCtx->conchFile ){ + pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); + sqlite3_free(pCtx->conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3_free(pCtx); + } + OSTRACE(("TRANSPROXY %d %s\n", pFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + + +/* +** This routine handles sqlite3_file_control() calls that are specific +** to proxy locking. +*/ +static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ + switch( op ){ + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + if( pFile->pMethod == &proxyIoMethods ){ + proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; + proxyTakeConch(pFile); + if( pCtx->lockProxyPath ){ + *(const char **)pArg = pCtx->lockProxyPath; + }else{ + *(const char **)pArg = ":auto: (not held)"; + } + } else { + *(const char **)pArg = NULL; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_SET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + int rc = SQLITE_OK; + int isProxyStyle = (pFile->pMethod == &proxyIoMethods); + if( pArg==NULL || (const char *)pArg==0 ){ + if( isProxyStyle ){ + /* turn off proxy locking - not supported. If support is added for + ** switching proxy locking mode off then it will need to fail if + ** the journal mode is WAL mode. + */ + rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; + }else{ + /* turn off proxy locking - already off - NOOP */ + rc = SQLITE_OK; + } + }else{ + const char *proxyPath = (const char *)pArg; + if( isProxyStyle ){ + proxyLockingContext *pCtx = + (proxyLockingContext*)pFile->lockingContext; + if( !strcmp(pArg, ":auto:") + || (pCtx->lockProxyPath && + !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) + ){ + rc = SQLITE_OK; + }else{ + rc = switchLockProxyPath(pFile, proxyPath); + } + }else{ + /* turn on proxy file locking */ + rc = proxyTransformUnixFile(pFile, proxyPath); + } + } + return rc; + } + default: { + assert( 0 ); /* The call assures that only valid opcodes are sent */ + } + } + /*NOTREACHED*/ assert(0); + return SQLITE_ERROR; +} + +/* +** Within this division (the proxying locking implementation) the procedures +** above this point are all utilities. The lock-related methods of the +** proxy-locking sqlite3_io_method object follow. +*/ + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut); + }else{ /* conchHeld < 0 is lockless */ + pResOut=0; + } + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int proxyLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int proxyUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + +/* +** Close a file that uses proxy locks. +*/ +static int proxyClose(sqlite3_file *id) { + if( ALWAYS(id) ){ + unixFile *pFile = (unixFile*)id; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *lockProxy = pCtx->lockProxy; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + + if( lockProxy ){ + rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); + if( rc ) return rc; + rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + pCtx->lockProxy = 0; + } + if( conchFile ){ + if( pCtx->conchHeld ){ + rc = proxyReleaseConch(pFile); + if( rc ) return rc; + } + rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile); + if( rc ) return rc; + sqlite3_free(conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3DbFree(0, pCtx->dbPath); + /* restore the original locking context and pMethod then close it */ + pFile->lockingContext = pCtx->oldLockingContext; + pFile->pMethod = pCtx->pOldMethod; + sqlite3_free(pCtx); + return pFile->pMethod->xClose(id); + } + return SQLITE_OK; +} + + + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The proxy locking style is intended for use with AFP filesystems. +** And since AFP is only supported on MacOSX, the proxy locking is also +** restricted to MacOSX. +** +** +******************* End of the proxy lock implementation ********************** +******************************************************************************/ + +/* +** Initialize the operating system interface. +** +** This routine registers all VFS implementations for unix-like operating +** systems. This routine, and the sqlite3_os_end() routine that follows, +** should be the only routines in this file that are visible from other +** files. +** +** This routine is called once during SQLite initialization and by a +** single thread. The memory allocation and mutex subsystems have not +** necessarily been initialized when this routine is called, and so they +** should not be used. +*/ +SQLITE_API int sqlite3_os_init(void){ + /* + ** The following macro defines an initializer for an sqlite3_vfs object. + ** The name of the VFS is NAME. The pAppData is a pointer to a pointer + ** to the "finder" function. (pAppData is a pointer to a pointer because + ** silly C90 rules prohibit a void* from being cast to a function pointer + ** and so we have to go through the intermediate pointer to avoid problems + ** when compiling with -pedantic-errors on GCC.) + ** + ** The FINDER parameter to this macro is the name of the pointer to the + ** finder-function. The finder-function returns a pointer to the + ** sqlite_io_methods object that implements the desired locking + ** behaviors. See the division above that contains the IOMETHODS + ** macro for addition information on finder-functions. + ** + ** Most finders simply return a pointer to a fixed sqlite3_io_methods + ** object. But the "autolockIoFinder" available on MacOSX does a little + ** more than that; it looks at the filesystem type that hosts the + ** database file and tries to choose an locking method appropriate for + ** that filesystem time. + */ + #define UNIXVFS(VFSNAME, FINDER) { \ + 3, /* iVersion */ \ + sizeof(unixFile), /* szOsFile */ \ + MAX_PATHNAME, /* mxPathname */ \ + 0, /* pNext */ \ + VFSNAME, /* zName */ \ + (void*)&FINDER, /* pAppData */ \ + unixOpen, /* xOpen */ \ + unixDelete, /* xDelete */ \ + unixAccess, /* xAccess */ \ + unixFullPathname, /* xFullPathname */ \ + unixDlOpen, /* xDlOpen */ \ + unixDlError, /* xDlError */ \ + unixDlSym, /* xDlSym */ \ + unixDlClose, /* xDlClose */ \ + unixRandomness, /* xRandomness */ \ + unixSleep, /* xSleep */ \ + unixCurrentTime, /* xCurrentTime */ \ + unixGetLastError, /* xGetLastError */ \ + unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ + unixSetSystemCall, /* xSetSystemCall */ \ + unixGetSystemCall, /* xGetSystemCall */ \ + unixNextSystemCall, /* xNextSystemCall */ \ + } + + /* + ** All default VFSes for unix are contained in the following array. + ** + ** Note that the sqlite3_vfs.pNext field of the VFS object is modified + ** by the SQLite core when the VFS is registered. So the following + ** array cannot be const. + */ + static sqlite3_vfs aVfs[] = { +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix", autolockIoFinder ), +#elif OS_VXWORKS + UNIXVFS("unix", vxworksIoFinder ), +#else + UNIXVFS("unix", posixIoFinder ), +#endif + UNIXVFS("unix-none", nolockIoFinder ), + UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-excl", posixIoFinder ), +#if OS_VXWORKS + UNIXVFS("unix-namedsem", semIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS + UNIXVFS("unix-posix", posixIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + UNIXVFS("unix-flock", flockIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix-afp", afpIoFinder ), + UNIXVFS("unix-nfs", nfsIoFinder ), + UNIXVFS("unix-proxy", proxyIoFinder ), +#endif + }; + unsigned int i; /* Loop counter */ + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==29 ); + + /* Register all VFSes defined in the aVfs[] array */ + for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ +#ifdef SQLITE_DEFAULT_UNIX_VFS + sqlite3_vfs_register(&aVfs[i], + 0==strcmp(aVfs[i].zName,SQLITE_DEFAULT_UNIX_VFS)); +#else + sqlite3_vfs_register(&aVfs[i], i==0); +#endif + } +#ifdef SQLITE_OS_KV_OPTIONAL + sqlite3KvvfsInit(); +#endif + unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); + +#ifndef SQLITE_OMIT_WAL + /* Validate lock assumptions */ + assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */ + assert( UNIX_SHM_BASE==120 ); /* Start of locking area */ + /* Locks: + ** WRITE UNIX_SHM_BASE 120 + ** CKPT UNIX_SHM_BASE+1 121 + ** RECOVER UNIX_SHM_BASE+2 122 + ** READ-0 UNIX_SHM_BASE+3 123 + ** READ-1 UNIX_SHM_BASE+4 124 + ** READ-2 UNIX_SHM_BASE+5 125 + ** READ-3 UNIX_SHM_BASE+6 126 + ** READ-4 UNIX_SHM_BASE+7 127 + ** DMS UNIX_SHM_BASE+8 128 + */ + assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */ +#endif + + /* Initialize temp file dir array. */ + unixTempFileInit(); + + return SQLITE_OK; +} + +/* +** Shutdown the operating system interface. +** +** Some operating systems might need to do some cleanup in this routine, +** to release dynamically allocated objects. But not on unix. +** This routine is a no-op for unix. +*/ +SQLITE_API int sqlite3_os_end(void){ + unixBigLock = 0; + return SQLITE_OK; +} + +#endif /* SQLITE_OS_UNIX */ + +/************** End of os_unix.c *********************************************/ +/************** Begin file os_win.c ******************************************/ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Windows. +*/ +/* #include "sqliteInt.h" */ +#if SQLITE_OS_WIN /* This file is used for Windows only */ + +/* +** Include code that is common to all os_*.c files +*/ +/* #include "os_common.h" */ + +/* +** Include the header file for the Windows VFS. +*/ +/* #include "os_win.h" */ + +/* +** Compiling and using WAL mode requires several APIs that are only +** available in Windows platforms based on the NT kernel. +*/ +#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) +# error "WAL mode requires support from the Windows NT kernel, compile\ + with SQLITE_OMIT_WAL." +#endif + +#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0 +# error "Memory mapped files require support from the Windows NT kernel,\ + compile with SQLITE_MAX_MMAP_SIZE=0." +#endif + +/* +** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions +** based on the sub-platform)? +*/ +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) +# define SQLITE_WIN32_HAS_ANSI +#endif + +/* +** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions +** based on the sub-platform)? +*/ +#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ + !defined(SQLITE_WIN32_NO_WIDE) +# define SQLITE_WIN32_HAS_WIDE +#endif + +/* +** Make sure at least one set of Win32 APIs is available. +*/ +#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) +# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ + must be defined." +#endif + +/* +** Define the required Windows SDK version constants if they are not +** already available. +*/ +#ifndef NTDDI_WIN8 +# define NTDDI_WIN8 0x06020000 +#endif + +#ifndef NTDDI_WINBLUE +# define NTDDI_WINBLUE 0x06030000 +#endif + +#ifndef NTDDI_WINTHRESHOLD +# define NTDDI_WINTHRESHOLD 0x06040000 +#endif + +/* +** Check to see if the GetVersionEx[AW] functions are deprecated on the +** target system. GetVersionEx was first deprecated in Win8.1. +*/ +#ifndef SQLITE_WIN32_GETVERSIONEX +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE +# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ +# else +# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ +# endif +#endif + +/* +** Check to see if the CreateFileMappingA function is supported on the +** target system. It is unavailable when using "mincore.lib" on Win10. +** When compiling for Windows 10, always assume "mincore.lib" is in use. +*/ +#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD +# define SQLITE_WIN32_CREATEFILEMAPPINGA 0 +# else +# define SQLITE_WIN32_CREATEFILEMAPPINGA 1 +# endif +#endif + +/* +** This constant should already be defined (in the "WinDef.h" SDK file). +*/ +#ifndef MAX_PATH +# define MAX_PATH (260) +#endif + +/* +** Maximum pathname length (in chars) for Win32. This should normally be +** MAX_PATH. +*/ +#ifndef SQLITE_WIN32_MAX_PATH_CHARS +# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) +#endif + +/* +** This constant should already be defined (in the "WinNT.h" SDK file). +*/ +#ifndef UNICODE_STRING_MAX_CHARS +# define UNICODE_STRING_MAX_CHARS (32767) +#endif + +/* +** Maximum pathname length (in chars) for WinNT. This should normally be +** UNICODE_STRING_MAX_CHARS. +*/ +#ifndef SQLITE_WINNT_MAX_PATH_CHARS +# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS) +#endif + +/* +** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in +** characters, so we allocate 4 bytes per character assuming worst-case of +** 4-bytes-per-character for UTF8. +*/ +#ifndef SQLITE_WIN32_MAX_PATH_BYTES +# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) +#endif + +/* +** Maximum pathname length (in bytes) for WinNT. This should normally be +** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR). +*/ +#ifndef SQLITE_WINNT_MAX_PATH_BYTES +# define SQLITE_WINNT_MAX_PATH_BYTES \ + (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) +#endif + +/* +** Maximum error message length (in chars) for WinRT. +*/ +#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS +# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) +#endif + +/* +** Returns non-zero if the character should be treated as a directory +** separator. +*/ +#ifndef winIsDirSep +# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) +#endif + +/* +** This macro is used when a local variable is set to a value that is +** [sometimes] not used by the code (e.g. via conditional compilation). +*/ +#ifndef UNUSED_VARIABLE_VALUE +# define UNUSED_VARIABLE_VALUE(x) (void)(x) +#endif + +/* +** Returns the character that should be used as the directory separator. +*/ +#ifndef winGetDirSep +# define winGetDirSep() '\\' +#endif + +/* +** Do we need to manually define the Win32 file mapping APIs for use with WAL +** mode or memory mapped files (e.g. these APIs are available in the Windows +** CE SDK; however, they are not present in the header file)? +*/ +#if SQLITE_WIN32_FILEMAPPING_API && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) +/* +** Two of the file mapping APIs are different under WinRT. Figure out which +** set we need. +*/ +#if SQLITE_OS_WINRT +WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \ + LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR); + +WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T); +#else +#if defined(SQLITE_WIN32_HAS_ANSI) +WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \ + DWORD, DWORD, DWORD, LPCSTR); +#endif /* defined(SQLITE_WIN32_HAS_ANSI) */ + +#if defined(SQLITE_WIN32_HAS_WIDE) +WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ + DWORD, DWORD, DWORD, LPCWSTR); +#endif /* defined(SQLITE_WIN32_HAS_WIDE) */ + +WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); +#endif /* SQLITE_OS_WINRT */ + +/* +** These file mapping APIs are common to both Win32 and WinRT. +*/ + +WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T); +WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); +#endif /* SQLITE_WIN32_FILEMAPPING_API */ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + +#ifndef FILE_FLAG_MASK +# define FILE_FLAG_MASK (0xFF3C0000) +#endif + +#ifndef FILE_ATTRIBUTE_MASK +# define FILE_ATTRIBUTE_MASK (0x0003FFF7) +#endif + +#ifndef SQLITE_OMIT_WAL +/* Forward references to structures used for WAL */ +typedef struct winShm winShm; /* A connection to shared-memory */ +typedef struct winShmNode winShmNode; /* A region of shared-memory */ +#endif + +/* +** WinCE lacks native support for file locking so we have to fake it +** with some code of our own. +*/ +#if SQLITE_OS_WINCE +typedef struct winceLock { + int nReaders; /* Number of reader locks obtained */ + BOOL bPending; /* Indicates a pending lock has been obtained */ + BOOL bReserved; /* Indicates a reserved lock has been obtained */ + BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ +} winceLock; +#endif + +/* +** The winFile structure is a subclass of sqlite3_file* specific to the win32 +** portability layer. +*/ +typedef struct winFile winFile; +struct winFile { + const sqlite3_io_methods *pMethod; /*** Must be first ***/ + sqlite3_vfs *pVfs; /* The VFS used to open this file */ + HANDLE h; /* Handle for accessing the file */ + u8 locktype; /* Type of lock currently held on this file */ + short sharedLockByte; /* Randomly chosen byte used as a shared lock */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ + DWORD lastErrno; /* The Windows errno from the last I/O error */ +#ifndef SQLITE_OMIT_WAL + winShm *pShm; /* Instance of shared memory on this file */ +#endif + const char *zPath; /* Full pathname of this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_OS_WINCE + LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ + HANDLE hMutex; /* Mutex used to control access to shared lock */ + HANDLE hShared; /* Shared memory segment used for locking */ + winceLock local; /* Locks obtained by this instance of winFile */ + winceLock *shared; /* Global shared lock memory for the file */ +#endif +#if SQLITE_MAX_MMAP_SIZE>0 + int nFetchOut; /* Number of outstanding xFetch references */ + HANDLE hMap; /* Handle for accessing memory mapping */ + void *pMapRegion; /* Area memory mapped */ + sqlite3_int64 mmapSize; /* Size of mapped region */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ +#endif +}; + +/* +** The winVfsAppData structure is used for the pAppData member for all of the +** Win32 VFS variants. +*/ +typedef struct winVfsAppData winVfsAppData; +struct winVfsAppData { + const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */ + void *pAppData; /* The extra pAppData, if any. */ + BOOL bNoLock; /* Non-zero if locking is disabled. */ +}; + +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_RDONLY 0x02 /* Connection is read only */ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ + +/* + * The size of the buffer used by sqlite3_win32_write_debug(). + */ +#ifndef SQLITE_WIN32_DBG_BUF_SIZE +# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) +#endif + +/* + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the + * various Win32 API heap functions instead of our own. + */ +#ifdef SQLITE_WIN32_MALLOC + +/* + * If this is non-zero, an isolated heap will be created by the native Win32 + * allocator subsystem; otherwise, the default process heap will be used. This + * setting has no effect when compiling for WinRT. By default, this is enabled + * and an isolated heap will be created to store all allocated data. + * + ****************************************************************************** + * WARNING: It is important to note that when this setting is non-zero and the + * winMemShutdown function is called (e.g. by the sqlite3_shutdown + * function), all data that was allocated using the isolated heap will + * be freed immediately and any attempt to access any of that freed + * data will almost certainly result in an immediate access violation. + ****************************************************************************** + */ +#ifndef SQLITE_WIN32_HEAP_CREATE +# define SQLITE_WIN32_HEAP_CREATE (TRUE) +#endif + +/* + * This is the maximum possible initial size of the Win32-specific heap, in + * bytes. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE +# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U) +#endif + +/* + * This is the extra space for the initial size of the Win32-specific heap, + * in bytes. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA +# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304) +#endif + +/* + * Calculate the maximum legal cache size, in pages, based on the maximum + * possible initial heap size and the default page size, setting aside the + * needed extra space. + */ +#ifndef SQLITE_WIN32_MAX_CACHE_SIZE +# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \ + (SQLITE_DEFAULT_PAGE_SIZE)) +#endif + +/* + * This is cache size used in the calculation of the initial size of the + * Win32-specific heap. It cannot be negative. + */ +#ifndef SQLITE_WIN32_CACHE_SIZE +# if SQLITE_DEFAULT_CACHE_SIZE>=0 +# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) +# else +# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) +# endif +#endif + +/* + * Make sure that the calculated cache size, in pages, cannot cause the + * initial size of the Win32-specific heap to exceed the maximum amount + * of memory that can be specified in the call to HeapCreate. + */ +#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE +# undef SQLITE_WIN32_CACHE_SIZE +# define SQLITE_WIN32_CACHE_SIZE (2000) +#endif + +/* + * The initial size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) +#endif + +/* + * The maximum size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +#endif + +/* + * The extra flags to use in calls to the Win32 heap APIs. This value may be + * zero for the default behavior. + */ +#ifndef SQLITE_WIN32_HEAP_FLAGS +# define SQLITE_WIN32_HEAP_FLAGS (0) +#endif + + +/* +** The winMemData structure stores information required by the Win32-specific +** sqlite3_mem_methods implementation. +*/ +typedef struct winMemData winMemData; +struct winMemData { +#ifndef NDEBUG + u32 magic1; /* Magic number to detect structure corruption. */ +#endif + HANDLE hHeap; /* The handle to our heap. */ + BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ +#ifndef NDEBUG + u32 magic2; /* Magic number to detect structure corruption. */ +#endif +}; + +#ifndef NDEBUG +#define WINMEM_MAGIC1 0x42b2830b +#define WINMEM_MAGIC2 0xbd4d7cf4 +#endif + +static struct winMemData win_mem_data = { +#ifndef NDEBUG + WINMEM_MAGIC1, +#endif + NULL, FALSE +#ifndef NDEBUG + ,WINMEM_MAGIC2 +#endif +}; + +#ifndef NDEBUG +#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 ) +#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 ) +#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2(); +#else +#define winMemAssertMagic() +#endif + +#define winMemGetDataPtr() &win_mem_data +#define winMemGetHeap() win_mem_data.hHeap +#define winMemGetOwned() win_mem_data.bOwned + +static void *winMemMalloc(int nBytes); +static void winMemFree(void *pPrior); +static void *winMemRealloc(void *pPrior, int nBytes); +static int winMemSize(void *p); +static int winMemRoundup(int n); +static int winMemInit(void *pAppData); +static void winMemShutdown(void *pAppData); + +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** The following variable is (normally) set once and never changes +** thereafter. It records whether the operating system is Win9x +** or WinNT. +** +** 0: Operating system unknown. +** 1: Operating system is Win9x. +** 2: Operating system is WinNT. +** +** In order to facilitate testing on a WinNT system, the test fixture +** can manually set this value to 1 to emulate Win98 behavior. +*/ +#ifdef SQLITE_TEST +SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; +#else +static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; +#endif + +#ifndef SYSCALL +# define SYSCALL sqlite3_syscall_ptr +#endif + +/* +** This function is not available on Windows CE or WinRT. + */ + +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT +# define osAreFileApisANSI() 1 +#endif + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct win_syscall { + const char *zName; /* Name of the system call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, +#else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +#endif + +#ifndef osAreFileApisANSI +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) +#endif + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharLowerW", (SYSCALL)CharLowerW, 0 }, +#else + { "CharLowerW", (SYSCALL)0, 0 }, +#endif + +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharUpperW", (SYSCALL)CharUpperW, 0 }, +#else + { "CharUpperW", (SYSCALL)0, 0 }, +#endif + +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) + + { "CloseHandle", (SYSCALL)CloseHandle, 0 }, + +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "CreateFileA", (SYSCALL)CreateFileA, 0 }, +#else + { "CreateFileA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, +#else + { "CreateFileW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ + SQLITE_WIN32_CREATEFILEMAPPINGA + { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, +#else + { "CreateFileMappingA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) + +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, +#else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, +#else + { "CreateMutexW", (SYSCALL)0, 0 }, +#endif + +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ + LPCWSTR))aSyscall[8].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, +#else + { "DeleteFileA", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, +#else + { "DeleteFileW", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, +#else + { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPFILETIME))aSyscall[11].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, +#else + { "FileTimeToSystemTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPSYSTEMTIME))aSyscall[12].pCurrent) + + { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, + +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, +#else + { "FormatMessageA", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ + DWORD,va_list*))aSyscall[14].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, +#else + { "FormatMessageW", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ + DWORD,va_list*))aSyscall[15].pCurrent) + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, +#else + { "FreeLibrary", (SYSCALL)0, 0 }, +#endif + +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) + + { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, + +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, +#else + { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, +#else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[19].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, +#else + { "GetFileAttributesA", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, +#else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, +#else + { "GetFileAttributesExW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ + LPVOID))aSyscall[22].pCurrent) + +#if !SQLITE_OS_WINRT + { "GetFileSize", (SYSCALL)GetFileSize, 0 }, +#else + { "GetFileSize", (SYSCALL)0, 0 }, +#endif + +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, +#else + { "GetFullPathNameA", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, +#else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ + LPWSTR*))aSyscall[25].pCurrent) + + { "GetLastError", (SYSCALL)GetLastError, 0 }, + +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) +#if SQLITE_OS_WINCE + /* The GetProcAddressA() routine is only available on Windows CE. */ + { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, +#else + /* All other Windows platforms expect GetProcAddress() to take + ** an ANSI string regardless of the _UNICODE setting */ + { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, +#endif +#else + { "GetProcAddressA", (SYSCALL)0, 0 }, +#endif + +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ + LPCSTR))aSyscall[27].pCurrent) + +#if !SQLITE_OS_WINRT + { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, +#else + { "GetSystemInfo", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) + + { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, + +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) + +#if !SQLITE_OS_WINCE + { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, +#else + { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ + LPFILETIME))aSyscall[30].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, +#else + { "GetTempPathA", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, +#else + { "GetTempPathW", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) + +#if !SQLITE_OS_WINRT + { "GetTickCount", (SYSCALL)GetTickCount, 0 }, +#else + { "GetTickCount", (SYSCALL)0, 0 }, +#endif + +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX + { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, +#else + { "GetVersionExA", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + SQLITE_WIN32_GETVERSIONEX + { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, +#else + { "GetVersionExW", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExW ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOW))aSyscall[35].pCurrent) + + { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, + +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ + SIZE_T))aSyscall[36].pCurrent) + +#if !SQLITE_OS_WINRT + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, +#else + { "HeapCreate", (SYSCALL)0, 0 }, +#endif + +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ + SIZE_T))aSyscall[37].pCurrent) + +#if !SQLITE_OS_WINRT + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, +#else + { "HeapDestroy", (SYSCALL)0, 0 }, +#endif + +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent) + + { "HeapFree", (SYSCALL)HeapFree, 0 }, + +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent) + + { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, + +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ + SIZE_T))aSyscall[40].pCurrent) + + { "HeapSize", (SYSCALL)HeapSize, 0 }, + +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[41].pCurrent) + +#if !SQLITE_OS_WINRT + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, +#else + { "HeapValidate", (SYSCALL)0, 0 }, +#endif + +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[42].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "HeapCompact", (SYSCALL)HeapCompact, 0 }, +#else + { "HeapCompact", (SYSCALL)0, 0 }, +#endif + +#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, +#else + { "LoadLibraryA", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, +#else + { "LoadLibraryW", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent) + +#if !SQLITE_OS_WINRT + { "LocalFree", (SYSCALL)LocalFree, 0 }, +#else + { "LocalFree", (SYSCALL)0, 0 }, +#endif + +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "LockFile", (SYSCALL)LockFile, 0 }, +#else + { "LockFile", (SYSCALL)0, 0 }, +#endif + +#ifndef osLockFile +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[47].pCurrent) +#endif + +#if !SQLITE_OS_WINCE + { "LockFileEx", (SYSCALL)LockFileEx, 0 }, +#else + { "LockFileEx", (SYSCALL)0, 0 }, +#endif + +#ifndef osLockFileEx +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[48].pCurrent) +#endif + +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, +#else + { "MapViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + SIZE_T))aSyscall[49].pCurrent) + + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, + +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ + int))aSyscall[50].pCurrent) + + { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, + +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ + LARGE_INTEGER*))aSyscall[51].pCurrent) + + { "ReadFile", (SYSCALL)ReadFile, 0 }, + +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[52].pCurrent) + + { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, + +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent) + +#if !SQLITE_OS_WINRT + { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, +#else + { "SetFilePointer", (SYSCALL)0, 0 }, +#endif + +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ + DWORD))aSyscall[54].pCurrent) + +#if !SQLITE_OS_WINRT + { "Sleep", (SYSCALL)Sleep, 0 }, +#else + { "Sleep", (SYSCALL)0, 0 }, +#endif + +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) + + { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, + +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ + LPFILETIME))aSyscall[56].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, +#else + { "UnlockFile", (SYSCALL)0, 0 }, +#endif + +#ifndef osUnlockFile +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[57].pCurrent) +#endif + +#if !SQLITE_OS_WINCE + { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, +#else + { "UnlockFileEx", (SYSCALL)0, 0 }, +#endif + +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[58].pCurrent) + +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, +#else + { "UnmapViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent) + + { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, + +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ + LPCSTR,LPBOOL))aSyscall[60].pCurrent) + + { "WriteFile", (SYSCALL)WriteFile, 0 }, + +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[61].pCurrent) + +#if SQLITE_OS_WINRT + { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, +#else + { "CreateEventExW", (SYSCALL)0, 0 }, +#endif + +#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ + DWORD,DWORD))aSyscall[62].pCurrent) + +#if !SQLITE_OS_WINRT + { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, +#else + { "WaitForSingleObject", (SYSCALL)0, 0 }, +#endif + +#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ + DWORD))aSyscall[63].pCurrent) + +#if !SQLITE_OS_WINCE + { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, +#else + { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, +#endif + +#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ + BOOL))aSyscall[64].pCurrent) + +#if SQLITE_OS_WINRT + { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, +#else + { "SetFilePointerEx", (SYSCALL)0, 0 }, +#endif + +#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ + PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent) + +#if SQLITE_OS_WINRT + { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, +#else + { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, +#endif + +#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ + FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent) + +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, +#else + { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, +#endif + +#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ + SIZE_T))aSyscall[67].pCurrent) + +#if SQLITE_OS_WINRT + { "CreateFile2", (SYSCALL)CreateFile2, 0 }, +#else + { "CreateFile2", (SYSCALL)0, 0 }, +#endif + +#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ + LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent) + +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, +#else + { "LoadPackagedLibrary", (SYSCALL)0, 0 }, +#endif + +#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ + DWORD))aSyscall[69].pCurrent) + +#if SQLITE_OS_WINRT + { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, +#else + { "GetTickCount64", (SYSCALL)0, 0 }, +#endif + +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent) + +#if SQLITE_OS_WINRT + { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, +#else + { "GetNativeSystemInfo", (SYSCALL)0, 0 }, +#endif + +#define osGetNativeSystemInfo ((VOID(WINAPI*)( \ + LPSYSTEM_INFO))aSyscall[71].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, +#else + { "OutputDebugStringA", (SYSCALL)0, 0 }, +#endif + +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, +#else + { "OutputDebugStringW", (SYSCALL)0, 0 }, +#endif + +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent) + + { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, + +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent) + +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, +#else + { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ + LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) + +/* +** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" +** is really just a macro that uses a compiler intrinsic (e.g. x64). +** So do not try to make this is into a redefinable interface. +*/ +#if defined(InterlockedCompareExchange) + { "InterlockedCompareExchange", (SYSCALL)0, 0 }, + +#define osInterlockedCompareExchange InterlockedCompareExchange +#else + { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, + +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ + SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) +#endif /* defined(InterlockedCompareExchange) */ + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { "UuidCreate", (SYSCALL)UuidCreate, 0 }, +#else + { "UuidCreate", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, +#else + { "UuidCreateSequential", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreateSequential \ + ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent) + +#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 + { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, +#else + { "FlushViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osFlushViewOfFile \ + ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "win32" VFSes. Return SQLITE_OK upon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int winSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i0 ){ + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + memcpy(zDbgBuf, zBuf, nMin); + osOutputDebugStringA(zDbgBuf); + }else{ + osOutputDebugStringA(zBuf); + } +#elif defined(SQLITE_WIN32_HAS_WIDE) + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + if ( osMultiByteToWideChar( + osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf, + nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){ + return; + } + osOutputDebugStringW((LPCWSTR)zDbgBuf); +#else + if( nMin>0 ){ + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + memcpy(zDbgBuf, zBuf, nMin); + fprintf(stderr, "%s", zDbgBuf); + }else{ + fprintf(stderr, "%s", zBuf); + } +#endif +} + +/* +** The following routine suspends the current thread for at least ms +** milliseconds. This is equivalent to the Win32 Sleep() interface. +*/ +#if SQLITE_OS_WINRT +static HANDLE sleepObj = NULL; +#endif + +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ +#if SQLITE_OS_WINRT + if ( sleepObj==NULL ){ + sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, + SYNCHRONIZE); + } + assert( sleepObj!=NULL ); + osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); +#else + osSleep(milliseconds); +#endif +} + +#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ + SQLITE_THREADSAFE>0 +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ + DWORD rc; + while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, + TRUE))==WAIT_IO_COMPLETION ){} + return rc; +} +#endif + +/* +** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, +** or WinCE. Return false (zero) for Win95, Win98, or WinME. +** +** Here is an interesting observation: Win95, Win98, and WinME lack +** the LockFileEx() API. But we can still statically link against that +** API as long as we don't call it when running Win95/98/ME. A call to +** this routine is used to determine if the host is Win95/98/ME or +** WinNT/2K/XP so that we will know whether or not we can safely call +** the LockFileEx() API. +*/ + +#if !SQLITE_WIN32_GETVERSIONEX +# define osIsNT() (1) +#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) +# define osIsNT() (1) +#elif !defined(SQLITE_WIN32_HAS_WIDE) +# define osIsNT() (0) +#else +# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) +#endif + +/* +** This function determines if the machine is running a version of Windows +** based on the NT kernel. +*/ +SQLITE_API int sqlite3_win32_is_nt(void){ +#if SQLITE_OS_WINRT + /* + ** NOTE: The WinRT sub-platform is always assumed to be based on the NT + ** kernel. + */ + return 1; +#elif SQLITE_WIN32_GETVERSIONEX + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ +#if defined(SQLITE_WIN32_HAS_ANSI) + OSVERSIONINFOA sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + osGetVersionExA(&sInfo); + osInterlockedCompareExchange(&sqlite3_os_type, + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); +#elif defined(SQLITE_WIN32_HAS_WIDE) + OSVERSIONINFOW sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + osGetVersionExW(&sInfo); + osInterlockedCompareExchange(&sqlite3_os_type, + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); +#endif + } + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; +#elif SQLITE_TEST + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; +#else + /* + ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are + ** deprecated are always assumed to be based on the NT kernel. + */ + return 1; +#endif +} + +#ifdef SQLITE_WIN32_MALLOC +/* +** Allocate nBytes of memory. +*/ +static void *winMemMalloc(int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + assert( nBytes>=0 ); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", + nBytes, osGetLastError(), (void*)hHeap); + } + return p; +} + +/* +** Free memory. +*/ +static void winMemFree(void *pPrior){ + HANDLE hHeap; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ + if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", + pPrior, osGetLastError(), (void*)hHeap); + } +} + +/* +** Change the size of an existing memory allocation +*/ +static void *winMemRealloc(void *pPrior, int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + assert( nBytes>=0 ); + if( !pPrior ){ + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + }else{ + p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + } + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), + (void*)hHeap); + } + return p; +} + +/* +** Return the size of an outstanding allocation, in bytes. +*/ +static int winMemSize(void *p){ + HANDLE hHeap; + SIZE_T n; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) ); +#endif + if( !p ) return 0; + n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + if( n==(SIZE_T)-1 ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", + p, osGetLastError(), (void*)hHeap); + return 0; + } + return (int)n; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int winMemRoundup(int n){ + return n; +} + +/* +** Initialize this module. +*/ +static int winMemInit(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return SQLITE_ERROR; + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + +#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE + if( !pWinMemData->hHeap ){ + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; + if( dwMaximumSize==0 ){ + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; + }else if( dwInitialSize>dwMaximumSize ){ + dwInitialSize = dwMaximumSize; + } + pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, + dwInitialSize, dwMaximumSize); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, + dwMaximumSize); + return SQLITE_NOMEM_BKPT; + } + pWinMemData->bOwned = TRUE; + assert( pWinMemData->bOwned ); + } +#else + pWinMemData->hHeap = osGetProcessHeap(); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to GetProcessHeap (%lu)", osGetLastError()); + return SQLITE_NOMEM_BKPT; + } + pWinMemData->bOwned = FALSE; + assert( !pWinMemData->bOwned ); +#endif + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void winMemShutdown(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return; + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + + if( pWinMemData->hHeap ){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( pWinMemData->bOwned ){ + if( !osHeapDestroy(pWinMemData->hHeap) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", + osGetLastError(), (void*)pWinMemData->hHeap); + } + pWinMemData->bOwned = FALSE; + } + pWinMemData->hHeap = NULL; + } +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { + winMemMalloc, + winMemFree, + winMemRealloc, + winMemSize, + winMemRoundup, + winMemInit, + winMemShutdown, + &win_mem_data + }; + return &winMemMethods; +} + +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); +} +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** Convert a UTF-8 string to Microsoft Unicode. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static LPWSTR winUtf8ToUnicode(const char *zText){ + int nChar; + LPWSTR zWideText; + + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } + zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); + if( zWideText==0 ){ + return 0; + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, + nChar); + if( nChar==0 ){ + sqlite3_free(zWideText); + zWideText = 0; + } + return zWideText; +} + +/* +** Convert a Microsoft Unicode string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUnicodeToUtf8(LPCWSTR zWideText){ + int nByte; + char *zText; + + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, + 0, 0); + if( nByte == 0 ){ + sqlite3_free(zText); + zText = 0; + } + return zText; +} + +/* +** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM +** code page. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ + int nByte; + LPWSTR zMbcsText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; + + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, + 0)*sizeof(WCHAR); + if( nByte==0 ){ + return 0; + } + zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); + if( zMbcsText==0 ){ + return 0; + } + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, + nByte); + if( nByte==0 ){ + sqlite3_free(zMbcsText); + zMbcsText = 0; + } + return zMbcsText; +} + +/* +** Convert a Microsoft Unicode string to a multi-byte character string, +** using the ANSI or OEM code page. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ + int nByte; + char *zText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; + + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, + nByte, 0, 0); + if( nByte == 0 ){ + sqlite3_free(zText); + zText = 0; + } + return zText; +} + +/* +** Convert a multi-byte character string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winMbcsToUtf8(const char *zText, int useAnsi){ + char *zTextUtf8; + LPWSTR zTmpWide; + + zTmpWide = winMbcsToUnicode(zText, useAnsi); + if( zTmpWide==0 ){ + return 0; + } + zTextUtf8 = winUnicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zTextUtf8; +} + +/* +** Convert a UTF-8 string to a multi-byte character string. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUtf8ToMbcs(const char *zText, int useAnsi){ + char *zTextMbcs; + LPWSTR zTmpWide; + + zTmpWide = winUtf8ToUnicode(zText); + if( zTmpWide==0 ){ + return 0; + } + zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); + sqlite3_free(zTmpWide); + return zTextMbcs; +} + +/* +** This is a public wrapper for the winUtf8ToUnicode() function. +*/ +SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToUnicode(zText); +} + +/* +** This is a public wrapper for the winUnicodeToUtf8() function. +*/ +SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zWideText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUnicodeToUtf8(zWideText); +} + +/* +** This is a public wrapper for the winMbcsToUtf8() function. +*/ +SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, osAreFileApisANSI()); +} + +/* +** This is a public wrapper for the winMbcsToUtf8() function. +*/ +SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, useAnsi); +} + +/* +** This is a public wrapper for the winUtf8ToMbcs() function. +*/ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, osAreFileApisANSI()); +} + +/* +** This is a public wrapper for the winUtf8ToMbcs() function. +*/ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, useAnsi); +} + +/* +** This function is the same as sqlite3_win32_set_directory (below); however, +** it accepts a UTF-8 string. +*/ +SQLITE_API int sqlite3_win32_set_directory8( + unsigned long type, /* Identifier for directory being set or reset */ + const char *zValue /* New value for directory being set or reset */ +){ + char **ppDirectory = 0; + int rc; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_data_directory; + }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_temp_directory; + } + assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE + || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE + ); + assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); + if( ppDirectory ){ + char *zCopy = 0; + if( zValue && zValue[0] ){ + zCopy = sqlite3_mprintf("%s", zValue); + if ( zCopy==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto set_directory8_done; + } + } + sqlite3_free(*ppDirectory); + *ppDirectory = zCopy; + rc = SQLITE_OK; + }else{ + rc = SQLITE_ERROR; + } +set_directory8_done: + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + return rc; +} + +/* +** This function is the same as sqlite3_win32_set_directory (below); however, +** it accepts a UTF-16 string. +*/ +SQLITE_API int sqlite3_win32_set_directory16( + unsigned long type, /* Identifier for directory being set or reset */ + const void *zValue /* New value for directory being set or reset */ +){ + int rc; + char *zUtf8 = 0; + if( zValue ){ + zUtf8 = sqlite3_win32_unicode_to_utf8(zValue); + if( zUtf8==0 ) return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_win32_set_directory8(type, zUtf8); + if( zUtf8 ) sqlite3_free(zUtf8); + return rc; +} + +/* +** This function sets the data directory or the temporary directory based on +** the provided arguments. The type argument must be 1 in order to set the +** data directory or 2 in order to set the temporary directory. The zValue +** argument is the name of the directory to use. The return value will be +** SQLITE_OK if successful. +*/ +SQLITE_API int sqlite3_win32_set_directory( + unsigned long type, /* Identifier for directory being set or reset */ + void *zValue /* New value for directory being set or reset */ +){ + return sqlite3_win32_set_directory16(type, zValue); +} + +/* +** The return value of winGetLastErrorMsg +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). +*/ +static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ + /* FormatMessage returns 0 on failure. Otherwise it + ** returns the number of TCHARs written to the output + ** buffer, excluding the terminating null char. + */ + DWORD dwLen = 0; + char *zOut = 0; + + if( osIsNT() ){ +#if SQLITE_OS_WINRT + WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; + dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + zTempWide, + SQLITE_WIN32_MAX_ERRMSG_CHARS, + 0); +#else + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); +#endif + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = winUnicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); +#if !SQLITE_OS_WINRT + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTempWide); +#endif + } + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + char *zTemp = NULL; + dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPSTR) &zTemp, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTemp); + } + } +#endif + if( 0 == dwLen ){ + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); + }else{ + /* copy a maximum of nBuf chars to output buffer */ + sqlite3_snprintf(nBuf, zBuf, "%s", zOut); + /* free the UTF8 buffer */ + sqlite3_free(zOut); + } + return 0; +} + +/* +** +** This function - winLogErrorAtLine() - is only ever called via the macro +** winLogError(). +** +** This routine is invoked after an error occurs in an OS function. +** It logs a message using sqlite3_log() containing the current value of +** error code and, if possible, the human-readable equivalent from +** FormatMessage. +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed and the associated file-system path, if any. +*/ +#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) +static int winLogErrorAtLine( + int errcode, /* SQLite error code */ + DWORD lastErrno, /* Win32 last error */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char zMsg[500]; /* Human readable error text */ + int i; /* Loop counter */ + + zMsg[0] = 0; + winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} + zMsg[i] = 0; + sqlite3_log(errcode, + "os_win.c:%d: (%lu) %s(%s) - %s", + iLine, lastErrno, zFunc, zPath, zMsg + ); + + return errcode; +} + +/* +** The number of times that a ReadFile(), WriteFile(), and DeleteFile() +** will be retried following a locking error - probably caused by +** antivirus software. Also the initial delay before the first retry. +** The delay increases linearly with each retry. +*/ +#ifndef SQLITE_WIN32_IOERR_RETRY +# define SQLITE_WIN32_IOERR_RETRY 10 +#endif +#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY +# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 +#endif +static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; +static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; + +/* +** The "winIoerrCanRetry1" macro is used to determine if a particular I/O +** error code obtained via GetLastError() is eligible to be retried. It +** must accept the error code DWORD as its only argument and should return +** non-zero if the error code is transient in nature and the operation +** responsible for generating the original error might succeed upon being +** retried. The argument to this macro should be a variable. +** +** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it +** is defined, it will be consulted only when the macro "winIoerrCanRetry1" +** returns zero. The "winIoerrCanRetry2" macro is completely optional and +** may be used to include additional error codes in the set that should +** result in the failing I/O operation being retried by the caller. If +** defined, the "winIoerrCanRetry2" macro must exhibit external semantics +** identical to those of the "winIoerrCanRetry1" macro. +*/ +#if !defined(winIoerrCanRetry1) +#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ + ((a)==ERROR_SHARING_VIOLATION) || \ + ((a)==ERROR_LOCK_VIOLATION) || \ + ((a)==ERROR_DEV_NOT_EXIST) || \ + ((a)==ERROR_NETNAME_DELETED) || \ + ((a)==ERROR_SEM_TIMEOUT) || \ + ((a)==ERROR_NETWORK_UNREACHABLE)) +#endif + +/* +** If a ReadFile() or WriteFile() error occurs, invoke this routine +** to see if it should be retried. Return TRUE to retry. Return FALSE +** to give up with an error. +*/ +static int winRetryIoerr(int *pnRetry, DWORD *pError){ + DWORD e = osGetLastError(); + if( *pnRetry>=winIoerrRetry ){ + if( pError ){ + *pError = e; + } + return 0; + } + if( winIoerrCanRetry1(e) ){ + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } +#if defined(winIoerrCanRetry2) + else if( winIoerrCanRetry2(e) ){ + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } +#endif + if( pError ){ + *pError = e; + } + return 0; +} + +/* +** Log a I/O error retry episode. +*/ +static void winLogIoerr(int nRetry, int lineno){ + if( nRetry ){ + sqlite3_log(SQLITE_NOTICE, + "delayed %dms for lock/sharing conflict at line %d", + winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno + ); + } +} + +/* +** This #if does not rely on the SQLITE_OS_WINCE define because the +** corresponding section in "date.c" cannot use it. +*/ +#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +/* +** The MSVC CRT on Windows CE may not have a localtime() function. +** So define a substitute. +*/ +/* # include */ +struct tm *__cdecl localtime(const time_t *t) +{ + static struct tm y; + FILETIME uTm, lTm; + SYSTEMTIME pTm; + sqlite3_int64 t64; + t64 = *t; + t64 = (t64 + 11644473600)*10000000; + uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); + uTm.dwHighDateTime= (DWORD)(t64 >> 32); + osFileTimeToLocalFileTime(&uTm,&lTm); + osFileTimeToSystemTime(&lTm,&pTm); + y.tm_year = pTm.wYear - 1900; + y.tm_mon = pTm.wMonth - 1; + y.tm_wday = pTm.wDayOfWeek; + y.tm_mday = pTm.wDay; + y.tm_hour = pTm.wHour; + y.tm_min = pTm.wMinute; + y.tm_sec = pTm.wSecond; + return &y; +} +#endif + +#if SQLITE_OS_WINCE +/************************************************************************* +** This section contains code for WinCE only. +*/ +#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] + +/* +** Acquire a lock on the handle h +*/ +static void winceMutexAcquire(HANDLE h){ + DWORD dwErr; + do { + dwErr = osWaitForSingleObject(h, INFINITE); + } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); +} +/* +** Release a lock acquired by winceMutexAcquire() +*/ +#define winceMutexRelease(h) ReleaseMutex(h) + +/* +** Create the mutex and shared memory used for locking in the file +** descriptor pFile +*/ +static int winceCreateLock(const char *zFilename, winFile *pFile){ + LPWSTR zTok; + LPWSTR zName; + DWORD lastErrno; + BOOL bLogged = FALSE; + BOOL bInit = TRUE; + + zName = winUtf8ToUnicode(zFilename); + if( zName==0 ){ + /* out of memory */ + return SQLITE_IOERR_NOMEM_BKPT; + } + + /* Initialize the local lockdata */ + memset(&pFile->local, 0, sizeof(pFile->local)); + + /* Replace the backslashes from the filename and lowercase it + ** to derive a mutex name. */ + zTok = osCharLowerW(zName); + for (;*zTok;zTok++){ + if (*zTok == '\\') *zTok = '_'; + } + + /* Create/open the named mutex */ + pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); + if (!pFile->hMutex){ + pFile->lastErrno = osGetLastError(); + sqlite3_free(zName); + return winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock1", zFilename); + } + + /* Acquire the mutex before continuing */ + winceMutexAcquire(pFile->hMutex); + + /* Since the names of named mutexes, semaphores, file mappings etc are + ** case-sensitive, take advantage of that by uppercasing the mutex name + ** and using that as the shared filemapping name. + */ + osCharUpperW(zName); + pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, sizeof(winceLock), + zName); + + /* Set a flag that indicates we're the first to create the memory so it + ** must be zero-initialized */ + lastErrno = osGetLastError(); + if (lastErrno == ERROR_ALREADY_EXISTS){ + bInit = FALSE; + } + + sqlite3_free(zName); + + /* If we succeeded in making the shared memory handle, map it. */ + if( pFile->hShared ){ + pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, + FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); + /* If mapping failed, close the shared memory handle and erase it */ + if( !pFile->shared ){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock2", zFilename); + bLogged = TRUE; + osCloseHandle(pFile->hShared); + pFile->hShared = NULL; + } + } + + /* If shared memory could not be created, then close the mutex and fail */ + if( pFile->hShared==NULL ){ + if( !bLogged ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock3", zFilename); + bLogged = TRUE; + } + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + return SQLITE_IOERR; + } + + /* Initialize the shared memory if we're supposed to */ + if( bInit ){ + memset(pFile->shared, 0, sizeof(winceLock)); + } + + winceMutexRelease(pFile->hMutex); + return SQLITE_OK; +} + +/* +** Destroy the part of winFile that deals with wince locks +*/ +static void winceDestroyLock(winFile *pFile){ + if (pFile->hMutex){ + /* Acquire the mutex */ + winceMutexAcquire(pFile->hMutex); + + /* The following blocks should probably assert in debug mode, but they + are to cleanup in case any locks remained open */ + if (pFile->local.nReaders){ + pFile->shared->nReaders --; + } + if (pFile->local.bReserved){ + pFile->shared->bReserved = FALSE; + } + if (pFile->local.bPending){ + pFile->shared->bPending = FALSE; + } + if (pFile->local.bExclusive){ + pFile->shared->bExclusive = FALSE; + } + + /* De-reference and close our copy of the shared memory handle */ + osUnmapViewOfFile(pFile->shared); + osCloseHandle(pFile->hShared); + + /* Done with the mutex */ + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + } +} + +/* +** An implementation of the LockFile() API of Windows for CE +*/ +static BOOL winceLockFile( + LPHANDLE phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Wanting an exclusive lock? */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST + && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ + if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ + pFile->shared->bExclusive = TRUE; + pFile->local.bExclusive = TRUE; + bReturn = TRUE; + } + } + + /* Want a read-only lock? */ + else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && + nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bExclusive == 0){ + pFile->local.nReaders ++; + if (pFile->local.nReaders == 1){ + pFile->shared->nReaders ++; + } + bReturn = TRUE; + } + } + + /* Want a pending lock? */ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE + && nNumberOfBytesToLockLow == 1){ + /* If no pending lock has been acquired, then acquire it */ + if (pFile->shared->bPending == 0) { + pFile->shared->bPending = TRUE; + pFile->local.bPending = TRUE; + bReturn = TRUE; + } + } + + /* Want a reserved lock? */ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE + && nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bReserved == 0) { + pFile->shared->bReserved = TRUE; + pFile->local.bReserved = TRUE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} + +/* +** An implementation of the UnlockFile API of Windows for CE +*/ +static BOOL winceUnlockFile( + LPHANDLE phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToUnlockLow, + DWORD nNumberOfBytesToUnlockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Releasing a reader lock or an exclusive lock */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ + /* Did we have an exclusive lock? */ + if (pFile->local.bExclusive){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); + pFile->local.bExclusive = FALSE; + pFile->shared->bExclusive = FALSE; + bReturn = TRUE; + } + + /* Did we just have a reader lock? */ + else if (pFile->local.nReaders){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE + || nNumberOfBytesToUnlockLow == 1); + pFile->local.nReaders --; + if (pFile->local.nReaders == 0) + { + pFile->shared->nReaders --; + } + bReturn = TRUE; + } + } + + /* Releasing a pending lock */ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE + && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bPending){ + pFile->local.bPending = FALSE; + pFile->shared->bPending = FALSE; + bReturn = TRUE; + } + } + /* Releasing a reserved lock */ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE + && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bReserved) { + pFile->local.bReserved = FALSE; + pFile->shared->bReserved = FALSE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} +/* +** End of the special code for wince +*****************************************************************************/ +#endif /* SQLITE_OS_WINCE */ + +/* +** Lock a file region. +*/ +static BOOL winLockFile( + LPHANDLE phFile, + DWORD flags, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API LockFile. + */ + return winceLockFile(phFile, offsetLow, offsetHigh, + numBytesLow, numBytesHigh); +#else + if( osIsNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); + }else{ + return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, + numBytesHigh); + } +#endif +} + +/* +** Unlock a file region. + */ +static BOOL winUnlockFile( + LPHANDLE phFile, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API UnlockFile. + */ + return winceUnlockFile(phFile, offsetLow, offsetHigh, + numBytesLow, numBytesHigh); +#else + if( osIsNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); + }else{ + return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, + numBytesHigh); + } +#endif +} + +/***************************************************************************** +** The next group of routines implement the I/O methods specified +** by the sqlite3_io_methods object. +******************************************************************************/ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_SET_FILE_POINTER +# define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +/* +** Move the current position of the file handle passed as the first +** argument to offset iOffset within the file. If successful, return 0. +** Otherwise, set pFile->lastErrno and return non-zero. +*/ +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ +#if !SQLITE_OS_WINRT + LONG upperBits; /* Most sig. 32 bits of new offset */ + LONG lowerBits; /* Least sig. 32 bits of new offset */ + DWORD dwRet; /* Value returned by SetFilePointer() */ + DWORD lastErrno; /* Value returned by GetLastError() */ + + OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); + + upperBits = (LONG)((iOffset>>32) & 0x7fffffff); + lowerBits = (LONG)(iOffset & 0xffffffff); + + /* API oddity: If successful, SetFilePointer() returns a dword + ** containing the lower 32-bits of the new file-offset. Or, if it fails, + ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, + ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine + ** whether an error has actually occurred, it is also necessary to call + ** GetLastError(). + */ + dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + + if( (dwRet==INVALID_SET_FILE_POINTER + && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "winSeekFile", pFile->zPath); + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); + return 1; + } + + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); + return 0; +#else + /* + ** Same as above, except that this implementation works for WinRT. + */ + + LARGE_INTEGER x; /* The new offset */ + BOOL bRet; /* Value returned by SetFilePointerEx() */ + + x.QuadPart = iOffset; + bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); + + if(!bRet){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "winSeekFile", pFile->zPath); + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); + return 1; + } + + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); + return 0; +#endif +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* Forward references to VFS helper methods used for memory mapped files */ +static int winMapfile(winFile*, sqlite3_int64); +static int winUnmapfile(winFile*); +#endif + +/* +** Close a file. +** +** It is reported that an attempt to close a handle might sometimes +** fail. This is a very unreasonable result, but Windows is notorious +** for being unreasonable so I do not doubt that it might happen. If +** the close fails, we pause for 100 milliseconds and try again. As +** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before +** giving up and returning an error. +*/ +#define MX_CLOSE_ATTEMPT 3 +static int winClose(sqlite3_file *id){ + int rc, cnt = 0; + winFile *pFile = (winFile*)id; + + assert( id!=0 ); +#ifndef SQLITE_OMIT_WAL + assert( pFile->pShm==0 ); +#endif + assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n", + osGetCurrentProcessId(), pFile, pFile->h)); + +#if SQLITE_MAX_MMAP_SIZE>0 + winUnmapfile(pFile); +#endif + + do{ + rc = osCloseHandle(pFile->h); + /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); +#if SQLITE_OS_WINCE +#define WINCE_DELETION_ATTEMPTS 3 + { + winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; + if( pAppData==NULL || !pAppData->bNoLock ){ + winceDestroyLock(pFile); + } + } + if( pFile->zDeleteOnClose ){ + int cnt = 0; + while( + osDeleteFileW(pFile->zDeleteOnClose)==0 + && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + && cnt++ < WINCE_DELETION_ATTEMPTS + ){ + sqlite3_win32_sleep(100); /* Wait a little before trying again */ + } + sqlite3_free(pFile->zDeleteOnClose); + } +#endif + if( rc ){ + pFile->h = NULL; + } + OpenCounter(-1); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed")); + return rc ? SQLITE_OK + : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), + "winClose", pFile->zPath); +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int winRead( + sqlite3_file *id, /* File to read from */ + void *pBuf, /* Write content into this buffer */ + int amt, /* Number of bytes to read */ + sqlite3_int64 offset /* Begin reading at this offset */ +){ +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + OVERLAPPED overlapped; /* The offset for ReadFile. */ +#endif + winFile *pFile = (winFile*)id; /* file handle */ + DWORD nRead; /* Number of bytes actually read from file */ + int nRetry = 0; /* Number of retrys */ + + assert( id!=0 ); + assert( amt>0 ); + assert( offset>=0 ); + SimulateIOError(return SQLITE_IOERR_READ); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, + pFile->h, pBuf, amt, offset, pFile->locktype)); + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this read request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); + OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + int nCopy = (int)(pFile->mmapSize - offset); + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + if( winSeekFile(pFile, offset) ){ + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_FULL; + } + while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ +#else + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); + while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && + osGetLastError()!=ERROR_HANDLE_EOF ){ +#endif + DWORD lastErrno; + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; + pFile->lastErrno = lastErrno; + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, + "winRead", pFile->zPath); + } + winLogIoerr(nRetry, __LINE__); + if( nRead<(DWORD)amt ){ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[nRead], 0, amt-nRead); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_IOERR_SHORT_READ; + } + + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int winWrite( + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + int rc = 0; /* True if error has occurred, else false */ + winFile *pFile = (winFile*)id; /* File handle */ + int nRetry = 0; /* Number of retries */ + + assert( amt>0 ); + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_WRITE); + SimulateDiskfullError(return SQLITE_FULL); + + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, + pFile->h, pBuf, amt, offset, pFile->locktype)); + +#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this write request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); + OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + int nCopy = (int)(pFile->mmapSize - offset); + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + rc = winSeekFile(pFile, offset); + if( rc==0 ){ +#else + { +#endif +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + OVERLAPPED overlapped; /* The offset for WriteFile. */ +#endif + u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ + int nRem = amt; /* Number of bytes yet to be written */ + DWORD nWrite; /* Bytes written by each WriteFile() call */ + DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ + +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); +#endif + + while( nRem>0 ){ +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ +#else + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ +#endif + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; + break; + } + assert( nWrite==0 || nWrite<=(DWORD)nRem ); + if( nWrite==0 || nWrite>(DWORD)nRem ){ + lastErrno = osGetLastError(); + break; + } +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + offset += nWrite; + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); +#endif + aRem += nWrite; + nRem -= nWrite; + } + if( nRem>0 ){ + pFile->lastErrno = lastErrno; + rc = 1; + } + } + + if( rc ){ + if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) + || ( pFile->lastErrno==ERROR_DISK_FULL )){ + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_FULL, pFile->lastErrno, + "winWrite1", pFile->zPath); + } + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, + "winWrite2", pFile->zPath); + }else{ + winLogIoerr(nRetry, __LINE__); + } + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +} + +/* +** Truncate an open file to a specified size +*/ +static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ + winFile *pFile = (winFile*)id; /* File handle object */ + int rc = SQLITE_OK; /* Return code for this function */ + DWORD lastErrno; +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_int64 oldMmapSize; + if( pFile->nFetchOut>0 ){ + /* File truncation is a no-op if there are outstanding memory mapped + ** pages. This is because truncating the file means temporarily unmapping + ** the file, and that might delete memory out from under existing cursors. + ** + ** This can result in incremental vacuum not truncating the file, + ** if there is an active read cursor when the incremental vacuum occurs. + ** No real harm comes of this - the database file is not corrupted, + ** though some folks might complain that the file is bigger than it + ** needs to be. + ** + ** The only feasible work-around is to defer the truncation until after + ** all references to memory-mapped content are closed. That is doable, + ** but involves adding a few branches in the common write code path which + ** could slow down normal operations slightly. Hence, we have decided for + ** now to simply make transactions a no-op if there are pending reads. We + ** can maybe revisit this decision in the future. + */ + return SQLITE_OK; + } +#endif + + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_TRUNCATE); + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + oldMmapSize = pFile->mmapSize; + }else{ + oldMmapSize = 0; + } + winUnmapfile(pFile); +#endif + + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ + if( winSeekFile(pFile, nByte) ){ + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate1", pFile->zPath); + }else if( 0==osSetEndOfFile(pFile->h) && + ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ + pFile->lastErrno = lastErrno; + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate2", pFile->zPath); + } + +#if SQLITE_MAX_MMAP_SIZE>0 + if( rc==SQLITE_OK && oldMmapSize>0 ){ + if( oldMmapSize>nByte ){ + winMapfile(pFile, -1); + }else{ + winMapfile(pFile, oldMmapSize); + } + } +#endif + + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); + return rc; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occurring at the right times. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +static int winSync(sqlite3_file *id, int flags){ +#ifndef SQLITE_NO_SYNC + /* + ** Used only when SQLITE_NO_SYNC is not defined. + */ + BOOL rc; +#endif +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ + defined(SQLITE_HAVE_OS_TRACE) + /* + ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or + ** OSTRACE() macros. + */ + winFile *pFile = (winFile*)id; +#else + UNUSED_PARAMETER(id); +#endif + + assert( pFile ); + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, flags, + pFile->locktype)); + +#ifndef SQLITE_TEST + UNUSED_PARAMETER(flags); +#else + if( (flags&0x0F)==SQLITE_SYNC_FULL ){ + sqlite3_fullsync_count++; + } + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +#else +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_OK\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winSync1", pFile->zPath); + } + } +#endif + rc = osFlushFileBuffers(pFile->h); + SimulateIOError( rc=FALSE ); + if( rc ){ + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, + "winSync2", pFile->zPath); + } +#endif +} + +/* +** Determine the current size of a file in bytes +*/ +static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + + assert( id!=0 ); + assert( pSize!=0 ); + SimulateIOError(return SQLITE_IOERR_FSTAT); + OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); + +#if SQLITE_OS_WINRT + { + FILE_STANDARD_INFO info; + if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, + &info, sizeof(info)) ){ + *pSize = info.EndOfFile.QuadPart; + }else{ + pFile->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); + } + } +#else + { + DWORD upperBits; + DWORD lowerBits; + DWORD lastErrno; + + lowerBits = osGetFileSize(pFile->h, &upperBits); + *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; + if( (lowerBits == INVALID_FILE_SIZE) + && ((lastErrno = osGetLastError())!=NO_ERROR) ){ + pFile->lastErrno = lastErrno; + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); + } + } +#endif + OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", + pFile->h, pSize, *pSize, sqlite3ErrName(rc))); + return rc; +} + +/* +** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. +*/ +#ifndef LOCKFILE_FAIL_IMMEDIATELY +# define LOCKFILE_FAIL_IMMEDIATELY 1 +#endif + +#ifndef LOCKFILE_EXCLUSIVE_LOCK +# define LOCKFILE_EXCLUSIVE_LOCK 2 +#endif + +/* +** Historically, SQLite has used both the LockFile and LockFileEx functions. +** When the LockFile function was used, it was always expected to fail +** immediately if the lock could not be obtained. Also, it always expected to +** obtain an exclusive lock. These flags are used with the LockFileEx function +** and reflect those expectations; therefore, they should not be changed. +*/ +#ifndef SQLITE_LOCKFILE_FLAGS +# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ + LOCKFILE_EXCLUSIVE_LOCK) +#endif + +/* +** Currently, SQLite never calls the LockFileEx function without wanting the +** call to fail immediately if the lock cannot be obtained. +*/ +#ifndef SQLITE_LOCKFILEEX_FLAGS +# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) +#endif + +/* +** Acquire a reader lock. +** Different API routines are called depending on whether or not this +** is Win9x or WinNT. +*/ +static int winGetReadLock(winFile *pFile){ + int res; + OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); + if( osIsNT() ){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API LockFileEx. + */ + res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); +#else + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + int lk; + sqlite3_randomness(sizeof(lk), &lk); + pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, + SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + } +#endif + if( res == 0 ){ + pFile->lastErrno = osGetLastError(); + /* No need to log a failure to lock */ + } + OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); + return res; +} + +/* +** Undo a readlock +*/ +static int winUnlockReadLock(winFile *pFile){ + int res; + DWORD lastErrno; + OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); + if( osIsNT() ){ + res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + } +#endif + if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, + "winUnlockReadLock", pFile->zPath); + } + OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); + return res; +} + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. The winUnlock() routine +** erases all locks at once and returns us immediately to locking level 0. +** It is not possible to lower the locking level one step at a time. You +** must go straight to locking level 0. +*/ +static int winLock(sqlite3_file *id, int locktype){ + int rc = SQLITE_OK; /* Return code from subroutines */ + int res = 1; /* Result of a Windows lock call */ + int newLocktype; /* Set pFile->locktype to this value before exiting */ + int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ + winFile *pFile = (winFile*)id; + DWORD lastErrno = NO_ERROR; + + assert( id!=0 ); + OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); + + /* If there is already a lock of this type or more restrictive on the + ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** sqlite3OsEnterMutex() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + + /* Do not allow any kind of write-lock on a read-only database + */ + if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){ + return SQLITE_IOERR_LOCK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or + ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of + ** the PENDING_LOCK byte is temporary. + */ + newLocktype = pFile->locktype; + if( pFile->locktype==NO_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) + ){ + int cnt = 3; + while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, + PENDING_BYTE, 0, 1, 0))==0 ){ + /* Try 3 times to get the pending lock. This is needed to work + ** around problems caused by indexing and/or anti-virus software on + ** Windows systems. + ** If you are using this code as a model for alternative VFSes, do not + ** copy this retry logic. It is a hack intended for Windows only. + */ + lastErrno = osGetLastError(); + OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", + pFile->h, cnt, res)); + if( lastErrno==ERROR_INVALID_HANDLE ){ + pFile->lastErrno = lastErrno; + rc = SQLITE_IOERR_LOCK; + OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", + pFile->h, cnt, sqlite3ErrName(rc))); + return rc; + } + if( cnt ) sqlite3_win32_sleep(1); + } + gotPendingLock = res; + if( !res ){ + lastErrno = osGetLastError(); + } + } + + /* Acquire a shared lock + */ + if( locktype==SHARED_LOCK && res ){ + assert( pFile->locktype==NO_LOCK ); + res = winGetReadLock(pFile); + if( res ){ + newLocktype = SHARED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a RESERVED lock + */ + if( locktype==RESERVED_LOCK && res ){ + assert( pFile->locktype==SHARED_LOCK ); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); + if( res ){ + newLocktype = RESERVED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a PENDING lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + newLocktype = PENDING_LOCK; + gotPendingLock = 0; + } + + /* Acquire an EXCLUSIVE lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + assert( pFile->locktype>=SHARED_LOCK ); + (void)winUnlockReadLock(pFile); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); + if( res ){ + newLocktype = EXCLUSIVE_LOCK; + }else{ + lastErrno = osGetLastError(); + winGetReadLock(pFile); + } + } + + /* If we are holding a PENDING lock that ought to be released, then + ** release it now. + */ + if( gotPendingLock && locktype==SHARED_LOCK ){ + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); + } + + /* Update the state of the lock has held in the file descriptor then + ** return the appropriate result code. + */ + if( res ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = lastErrno; + rc = SQLITE_BUSY; + OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", + pFile->h, locktype, newLocktype)); + } + pFile->locktype = (u8)newLocktype; + OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", + pFile->h, pFile->locktype, sqlite3ErrName(rc))); + return rc; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero, otherwise zero. +*/ +static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ + int res; + winFile *pFile = (winFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); + + assert( id!=0 ); + if( pFile->locktype>=RESERVED_LOCK ){ + res = 1; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); + }else{ + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0); + if( res ){ + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); + } + res = !res; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); + } + *pResOut = res; + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + pFile->h, pResOut, *pResOut)); + return SQLITE_OK; +} + +/* +** Lower the locking level on file descriptor id to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** It is not possible for this routine to fail if the second argument +** is NO_LOCK. If the second argument is SHARED_LOCK then this routine +** might return SQLITE_IOERR; +*/ +static int winUnlock(sqlite3_file *id, int locktype){ + int type; + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + assert( pFile!=0 ); + assert( locktype<=SHARED_LOCK ); + OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); + type = pFile->locktype; + if( type>=EXCLUSIVE_LOCK ){ + winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ + /* This should never happen. We should always be able to + ** reacquire the read lock */ + rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), + "winUnlock", pFile->zPath); + } + } + if( type>=RESERVED_LOCK ){ + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); + } + if( locktype==NO_LOCK && type>=SHARED_LOCK ){ + winUnlockReadLock(pFile); + } + if( type>=PENDING_LOCK ){ + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); + } + pFile->locktype = (u8)locktype; + OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", + pFile->h, pFile->locktype, sqlite3ErrName(rc))); + return rc; +} + +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int winNolockLock(sqlite3_file *id, int locktype){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(locktype); + return SQLITE_OK; +} + +static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(pResOut); + return SQLITE_OK; +} + +static int winNolockUnlock(sqlite3_file *id, int locktype){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(locktype); + return SQLITE_OK; +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + +/* +** If *pArg is initially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* Forward references to VFS helper methods used for temporary files */ +static int winGetTempname(sqlite3_vfs *, char **); +static int winIsDir(const void *); +static BOOL winIsLongPathPrefix(const char *); +static BOOL winIsDriveLetterAndColon(const char *); + +/* +** Control and query of the open file handle. +*/ +static int winFileControl(sqlite3_file *id, int op, void *pArg){ + winFile *pFile = (winFile*)id; + OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->locktype; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_LAST_ERRNO: { + *(int*)pArg = (int)pFile->lastErrno; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + if( pFile->szChunk>0 ){ + sqlite3_int64 oldSz; + int rc = winFileSize(id, &oldSz); + if( rc==SQLITE_OK ){ + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; + if( newSz>oldSz ){ + SimulateIOErrorBenign(1); + rc = winTruncate(id, newSz); + SimulateIOErrorBenign(0); + } + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_PERSIST_WAL: { + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_AV_RETRY: { + int *a = (int*)pArg; + if( a[0]>0 ){ + winIoerrRetry = a[0]; + }else{ + a[0] = winIoerrRetry; + } + if( a[1]>0 ){ + winIoerrRetryDelay = a[1]; + }else{ + a[1] = winIoerrRetryDelay; + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_GET_HANDLE: { + LPHANDLE phFile = (LPHANDLE)pArg; + *phFile = pFile->h; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } +#ifdef SQLITE_TEST + case SQLITE_FCNTL_WIN32_SET_HANDLE: { + LPHANDLE phFile = (LPHANDLE)pArg; + HANDLE hOldFile = pFile->h; + pFile->h = *phFile; + *phFile = hOldFile; + OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n", + hOldFile, pFile->h)); + return SQLITE_OK; + } +#endif + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = 0; + int rc = winGetTempname(pFile->pVfs, &zTFile); + if( rc==SQLITE_OK ){ + *(char**)pArg = zTFile; + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } +#if SQLITE_MAX_MMAP_SIZE>0 + case SQLITE_FCNTL_MMAP_SIZE: { + i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; + } + + /* The value of newLimit may be eventually cast to (SIZE_T) and passed + ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at + ** least a 64-bit type. */ + if( newLimit>0 && sizeof(SIZE_T)<8 ){ + newLimit = (newLimit & 0x7FFFFFFF); + } + + *(i64*)pArg = pFile->mmapSizeMax; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + winUnmapfile(pFile); + rc = winMapfile(pFile, -1); + } + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } +#endif + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int winSectorSize(sqlite3_file *id){ + (void)id; + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return a vector of device characteristics. +*/ +static int winDeviceCharacteristics(sqlite3_file *id){ + winFile *p = (winFile*)id; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); +} + +/* +** Windows will only let you create file view mappings +** on allocation size granularity boundaries. +** During sqlite3_os_init() we do a GetSystemInfo() +** to get the granularity size. +*/ +static SYSTEM_INFO winSysInfo; + +#ifndef SQLITE_OMIT_WAL + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the winLockInfo objects used by +** this file, all of which may be shared by multiple threads. +** +** Function winShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** winShmEnterMutex() +** assert( winShmMutexHeld() ); +** winShmLeaveMutex() +*/ +static sqlite3_mutex *winBigLock = 0; +static void winShmEnterMutex(void){ + sqlite3_mutex_enter(winBigLock); +} +static void winShmLeaveMutex(void){ + sqlite3_mutex_leave(winBigLock); +} +#ifndef NDEBUG +static int winShmMutexHeld(void) { + return sqlite3_mutex_held(winBigLock); +} +#endif + +/* +** Object used to represent a single file opened and mmapped to provide +** shared memory. When multiple threads all reference the same +** log-summary, each thread has its own winFile object, but they all +** point to a single instance of this object. In other words, each +** log-summary is opened only once per process. +** +** winShmMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** pNext +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either winShmNode.mutex must be held or winShmNode.nRef==0 and +** winShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +*/ +struct winShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the file */ + winFile hFile; /* File handle from winOpen */ + + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + u8 isUnlocked; /* True if no DMS lock held */ + + struct ShmRegion { + HANDLE hMap; /* File handle from CreateFileMapping */ + void *pMap; + } *aRegion; + DWORD lastErrno; /* The Windows errno from the last I/O error */ + + int nRef; /* Number of winShm objects pointing to this */ + winShm *pFirst; /* All winShm objects pointing to this */ + winShmNode *pNext; /* Next in list of all winShmNode objects */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + u8 nextShmId; /* Next available winShm.id value */ +#endif +}; + +/* +** A global array of all winShmNode objects. +** +** The winShmMutexHeld() must be true while reading or writing this list. +*/ +static winShmNode *winShmNodeList = 0; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** winShm.pShmNode +** winShm.id +** +** All other fields are read/write. The winShm.pShmNode->mutex must be held +** while accessing any read/write fields. +*/ +struct winShm { + winShmNode *pShmNode; /* The underlying winShmNode object */ + winShm *pNext; /* Next winShm with the same winShmNode */ + u8 hasMutex; /* True if holding the winShmNode mutex */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + u8 id; /* Id of this connection with its winShmNode */ +#endif +}; + +/* +** Constants used for locking +*/ +#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define WINSHM_UNLCK 1 +#define WINSHM_RDLCK 2 +#define WINSHM_WRLCK 3 +static int winShmSystemLock( + winShmNode *pFile, /* Apply locks to this open shared-memory segment */ + int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + int rc = 0; /* Result code form Lock/UnlockFileEx() */ + + /* Access to the winShmNode object is serialized by the caller */ + assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); + + OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", + pFile->hFile.h, lockType, ofst, nByte)); + + /* Release/Acquire the system-level lock */ + if( lockType==WINSHM_UNLCK ){ + rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); + }else{ + /* Initialize the locking parameters */ + DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; + if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); + } + + if( rc!= 0 ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + rc = SQLITE_BUSY; + } + + OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", + pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : + "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); + + return rc; +} + +/* Forward references to VFS methods */ +static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); +static int winDelete(sqlite3_vfs *,const char*,int); + +/* +** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ + winShmNode **pp; + winShmNode *p; + assert( winShmMutexHeld() ); + OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", + osGetCurrentProcessId(), deleteFlag)); + pp = &winShmNodeList; + while( (p = *pp)!=0 ){ + if( p->nRef==0 ){ + int i; + if( p->mutex ){ sqlite3_mutex_free(p->mutex); } + for(i=0; inRegion; i++){ + BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); + OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); + UNUSED_VARIABLE_VALUE(bRc); + bRc = osCloseHandle(p->aRegion[i].hMap); + OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); + UNUSED_VARIABLE_VALUE(bRc); + } + if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ + SimulateIOErrorBenign(1); + winClose((sqlite3_file *)&p->hFile); + SimulateIOErrorBenign(0); + } + if( deleteFlag ){ + SimulateIOErrorBenign(1); + sqlite3BeginBenignMalloc(); + winDelete(pVfs, p->zFilename, 0); + sqlite3EndBenignMalloc(); + SimulateIOErrorBenign(0); + } + *pp = p->pNext; + sqlite3_free(p->aRegion); + sqlite3_free(p); + }else{ + pp = &p->pNext; + } + } +} + +/* +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to +** take it now. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If the DMS cannot be locked because this is a readonly_shm=1 +** connection and no other process already holds a lock, return +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. +*/ +static int winLockSharedMemory(winShmNode *pShmNode){ + int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); + + if( rc==SQLITE_OK ){ + if( pShmNode->isReadonly ){ + pShmNode->isUnlocked = 1; + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + return SQLITE_READONLY_CANTINIT; + }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), + "winLockSharedMemory", pShmNode->zFilename); + } + } + + if( rc==SQLITE_OK ){ + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + } + + return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); +} + +/* +** Open the shared-memory area associated with database file pDbFd. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +*/ +static int winOpenSharedMemory(winFile *pDbFd){ + struct winShm *p; /* The connection to be opened */ + winShmNode *pShmNode = 0; /* The underlying mmapped file */ + int rc = SQLITE_OK; /* Result code */ + winShmNode *pNew; /* Newly allocated winShmNode */ + int nName; /* Size of zName in bytes */ + + assert( pDbFd->pShm==0 ); /* Not previously opened */ + + /* Allocate space for the new sqlite3_shm object. Also speculatively + ** allocate space for a new winShmNode and filename. + */ + p = sqlite3MallocZero( sizeof(*p) ); + if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; + nName = sqlite3Strlen30(pDbFd->zPath); + pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); + if( pNew==0 ){ + sqlite3_free(p); + return SQLITE_IOERR_NOMEM_BKPT; + } + pNew->zFilename = (char*)&pNew[1]; + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); + + /* Look to see if there is an existing winShmNode that can be used. + ** If no matching winShmNode currently exists, create a new one. + */ + winShmEnterMutex(); + for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ + /* TBD need to come up with better match here. Perhaps + ** use FILE_ID_BOTH_DIR_INFO Structure. + */ + if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; + } + if( pShmNode ){ + sqlite3_free(pNew); + }else{ + int inFlags = SQLITE_OPEN_WAL; + int outFlags = 0; + + pShmNode = pNew; + pNew = 0; + ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; + pShmNode->pNext = winShmNodeList; + winShmNodeList = pShmNode; + + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shm_open_err; + } + } + + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + }else{ + inFlags |= SQLITE_OPEN_READONLY; + } + rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, + (sqlite3_file*)&pShmNode->hFile, + inFlags, &outFlags); + if( rc!=SQLITE_OK ){ + rc = winLogError(rc, osGetLastError(), "winOpenShm", + pShmNode->zFilename); + goto shm_open_err; + } + if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; + + rc = winLockSharedMemory(pShmNode); + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; + } + + /* Make the new connection a child of the winShmNode */ + p->pShmNode = pShmNode; +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + winShmLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the winShmEnterMutex() mutex and the pointer from the + ** new (struct winShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; + + /* Jump here on any error */ +shm_open_err: + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ + sqlite3_free(p); + sqlite3_free(pNew); + winShmLeaveMutex(); + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +*/ +static int winShmUnmap( + sqlite3_file *fd, /* Database holding shared memory */ + int deleteFlag /* Delete after closing if true */ +){ + winFile *pDbFd; /* Database holding shared-memory */ + winShm *p; /* The connection to be closed */ + winShmNode *pShmNode; /* The underlying shared-memory file */ + winShm **pp; /* For looping over sibling connections */ + + pDbFd = (winFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + winShmEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + winShmPurge(pDbFd->pVfs, deleteFlag); + } + winShmLeaveMutex(); + + return SQLITE_OK; +} + +/* +** Change the lock state for a shared-memory segment. +*/ +static int winShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ + winShm *p = pDbFd->pShm; /* The shared memory being locked */ + winShm *pX; /* For looping over all siblings */ + winShmNode *pShmNode; + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = (u16)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", + osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, + sqlite3ErrName(rc))); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void winShmBarrier( + sqlite3_file *fd /* Database holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + winShmEnterMutex(); /* Also mutex, for redundancy */ + winShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int winShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int isWrite, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + winFile *pDbFd = (winFile*)fd; + winShm *pShm = pDbFd->pShm; + winShmNode *pShmNode; + DWORD protect = PAGE_READWRITE; + DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; + int rc = SQLITE_OK; + + if( !pShm ){ + rc = winOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + pShm = pDbFd->pShm; + assert( pShm!=0 ); + } + pShmNode = pShm->pShmNode; + + sqlite3_mutex_enter(pShmNode->mutex); + if( pShmNode->isUnlocked ){ + rc = winLockSharedMemory(pShmNode); + if( rc!=SQLITE_OK ) goto shmpage_out; + pShmNode->isUnlocked = 0; + } + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + + if( pShmNode->nRegion<=iRegion ){ + struct ShmRegion *apNew; /* New aRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; + + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap1", pDbFd->zPath); + goto shmpage_out; + } + + if( szhFile, nByte); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap2", pDbFd->zPath); + goto shmpage_out; + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (struct ShmRegion *)sqlite3_realloc64( + pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shmpage_out; + } + pShmNode->aRegion = apNew; + + if( pShmNode->isReadonly ){ + protect = PAGE_READONLY; + flags = FILE_MAP_READ; + } + + while( pShmNode->nRegion<=iRegion ){ + HANDLE hMap = NULL; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + +#if SQLITE_OS_WINRT + hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, + NULL, protect, nByte, NULL + ); +#elif defined(SQLITE_WIN32_HAS_WIDE) + hMap = osCreateFileMappingW(pShmNode->hFile.h, + NULL, protect, 0, nByte, NULL + ); +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA + hMap = osCreateFileMappingA(pShmNode->hFile.h, + NULL, protect, 0, nByte, NULL + ); +#endif + OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, nByte, + hMap ? "ok" : "failed")); + if( hMap ){ + int iOffset = pShmNode->nRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; +#if SQLITE_OS_WINRT + pMap = osMapViewOfFileFromApp(hMap, flags, + iOffset - iOffsetShift, szRegion + iOffsetShift + ); +#else + pMap = osMapViewOfFile(hMap, flags, + 0, iOffset - iOffsetShift, szRegion + iOffsetShift + ); +#endif + OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, iOffset, + szRegion, pMap ? "ok" : "failed")); + } + if( !pMap ){ + pShmNode->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, + "winShmMap3", pDbFd->zPath); + if( hMap ) osCloseHandle(hMap); + goto shmpage_out; + } + + pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; + pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + int iOffset = iRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iOffsetShift]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +#else +# define winShmMap 0 +# define winShmLock 0 +# define winShmBarrier 0 +# define winShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Cleans up the mapped region of the specified file, if any. +*/ +#if SQLITE_MAX_MMAP_SIZE>0 +static int winUnmapfile(winFile *pFile){ + assert( pFile!=0 ); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " + "mmapSize=%lld, mmapSizeMax=%lld\n", + osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, + pFile->mmapSize, pFile->mmapSizeMax)); + if( pFile->pMapRegion ){ + if( !osUnmapViewOfFile(pFile->pMapRegion) ){ + pFile->lastErrno = osGetLastError(); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, + pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winUnmapfile1", pFile->zPath); + } + pFile->pMapRegion = 0; + pFile->mmapSize = 0; + } + if( pFile->hMap!=NULL ){ + if( !osCloseHandle(pFile->hMap) ){ + pFile->lastErrno = osGetLastError(); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", + osGetCurrentProcessId(), pFile, pFile->hMap)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winUnmapfile2", pFile->zPath); + } + pFile->hMap = NULL; + } + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile)); + return SQLITE_OK; +} + +/* +** Memory map or remap the file opened by file-descriptor pFd (if the file +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still +** outstanding xFetch() references to it, this function is a no-op. +** +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the +** requested size is the size of the file on disk. The actual size of the +** created mapping is either the requested size or the value configured +** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. +** +** SQLITE_OK is returned if no error occurs (even if the mapping is not +** recreated as a result of outstanding references) or an SQLite error +** code otherwise. +*/ +static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ + sqlite3_int64 nMap = nByte; + int rc; + + assert( nMap>=0 || pFd->nFetchOut==0 ); + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", + osGetCurrentProcessId(), pFd, nByte)); + + if( pFd->nFetchOut>0 ) return SQLITE_OK; + + if( nMap<0 ){ + rc = winFileSize((sqlite3_file*)pFd, &nMap); + if( rc ){ + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", + osGetCurrentProcessId(), pFd)); + return SQLITE_IOERR_FSTAT; + } + } + if( nMap>pFd->mmapSizeMax ){ + nMap = pFd->mmapSizeMax; + } + nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); + + if( nMap==0 && pFd->mmapSize>0 ){ + winUnmapfile(pFd); + } + if( nMap!=pFd->mmapSize ){ + void *pNew = 0; + DWORD protect = PAGE_READONLY; + DWORD flags = FILE_MAP_READ; + + winUnmapfile(pFd); +#ifdef SQLITE_MMAP_READWRITE + if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ + protect = PAGE_READWRITE; + flags |= FILE_MAP_WRITE; + } +#endif +#if SQLITE_OS_WINRT + pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); +#elif defined(SQLITE_WIN32_HAS_WIDE) + pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA + pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +#endif + if( pFd->hMap==NULL ){ + pFd->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, + "winMapfile1", pFd->zPath); + /* Log the error, but continue normal operation using xRead/xWrite */ + OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return SQLITE_OK; + } + assert( (nMap % winSysInfo.dwPageSize)==0 ); + assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); +#if SQLITE_OS_WINRT + pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); +#else + pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); +#endif + if( pNew==NULL ){ + osCloseHandle(pFd->hMap); + pFd->hMap = NULL; + pFd->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, + "winMapfile2", pFd->zPath); + /* Log the error, but continue normal operation using xRead/xWrite */ + OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return SQLITE_OK; + } + pFd->pMapRegion = pNew; + pFd->mmapSize = nMap; + } + + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFd)); + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** If possible, return a pointer to a mapping of file fd starting at offset +** iOff. The mapping must be valid for at least nAmt bytes. +** +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. +** Finally, if an error does occur, return an SQLite error code. The final +** value of *pp is undefined in this case. +** +** If this function does return a pointer, the caller must eventually +** release the reference by calling winUnfetch(). +*/ +static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#if SQLITE_MAX_MMAP_SIZE>0 + winFile *pFd = (winFile*)fd; /* The underlying database file */ +#endif + *pp = 0; + + OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", + osGetCurrentProcessId(), fd, iOff, nAmt, pp)); + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; + if( pFd->pMapRegion==0 ){ + int rc = winMapfile(pFd, -1); + if( rc!=SQLITE_OK ){ + OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return rc; + } + } + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ + assert( pFd->pMapRegion!=0 ); + *pp = &((u8 *)pFd->pMapRegion)[iOff]; + pFd->nFetchOut++; + } + } +#endif + + OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), fd, pp, *pp)); + return SQLITE_OK; +} + +/* +** If the third argument is non-NULL, then this function releases a +** reference obtained by an earlier call to winFetch(). The second +** argument passed to this function must be the same as the corresponding +** argument that was passed to the winFetch() invocation. +** +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping +** may now be invalid and should be unmapped. +*/ +static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ +#if SQLITE_MAX_MMAP_SIZE>0 + winFile *pFd = (winFile*)fd; /* The underlying database file */ + + /* If p==0 (unmap the entire file) then there must be no outstanding + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), + ** then there must be at least one outstanding. */ + assert( (p==0)==(pFd->nFetchOut==0) ); + + /* If p!=0, it must match the iOff value. */ + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); + + OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", + osGetCurrentProcessId(), pFd, iOff, p)); + + if( p ){ + pFd->nFetchOut--; + }else{ + /* FIXME: If Windows truly always prevents truncating or deleting a + ** file while a mapping is held, then the following winUnmapfile() call + ** is unnecessary can be omitted - potentially improving + ** performance. */ + winUnmapfile(pFd); + } + + assert( pFd->nFetchOut>=0 ); +#endif + + OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), fd)); + return SQLITE_OK; +} + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32. +*/ +static const sqlite3_io_methods winIoMethod = { + 3, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winLock, /* xLock */ + winUnlock, /* xUnlock */ + winCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap, /* xShmUnmap */ + winFetch, /* xFetch */ + winUnfetch /* xUnfetch */ +}; + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32 without performing any locking. +*/ +static const sqlite3_io_methods winIoNolockMethod = { + 3, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winNolockLock, /* xLock */ + winNolockUnlock, /* xUnlock */ + winNolockCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap, /* xShmUnmap */ + winFetch, /* xFetch */ + winUnfetch /* xUnfetch */ +}; + +static winVfsAppData winAppData = { + &winIoMethod, /* pMethod */ + 0, /* pAppData */ + 0 /* bNoLock */ +}; + +static winVfsAppData winNolockAppData = { + &winIoNolockMethod, /* pMethod */ + 0, /* pAppData */ + 1 /* bNoLock */ +}; + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +#if defined(__CYGWIN__) +/* +** Convert a filename from whatever the underlying operating system +** supports for filenames into UTF-8. Space to hold the result is +** obtained from malloc and must be freed by the calling function. +*/ +static char *winConvertToUtf8Filename(const void *zFilename){ + char *zConverted = 0; + if( osIsNT() ){ + zConverted = winUnicodeToUtf8(zFilename); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} +#endif + +/* +** Convert a UTF-8 filename into whatever form the underlying +** operating system wants filenames in. Space to hold the result +** is obtained from malloc and must be freed by the calling +** function. +*/ +static void *winConvertFromUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( osIsNT() ){ + zConverted = winUtf8ToUnicode(zFilename); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} + +/* +** This function returns non-zero if the specified UTF-8 string buffer +** ends with a directory separator character or one was successfully +** added to it. +*/ +static int winMakeEndInDirSep(int nBuf, char *zBuf){ + if( zBuf ){ + int nLen = sqlite3Strlen30(zBuf); + if( nLen>0 ){ + if( winIsDirSep(zBuf[nLen-1]) ){ + return 1; + }else if( nLen+1mxPathname; nBuf = nMax + 2; + zBuf = sqlite3MallocZero( nBuf ); + if( !zBuf ){ + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); + return SQLITE_IOERR_NOMEM_BKPT; + } + + /* Figure out the effective temporary directory. First, check if one + ** has been explicitly set by the application; otherwise, use the one + ** configured by the operating system. + */ + nDir = nMax - (nPre + 15); + assert( nDir>0 ); + if( winTempDirDefined() ){ + int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); + if( nDirLen>0 ){ + if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ + nDirLen++; + } + if( nDirLen>nDir ){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); + return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); + } + sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + } + +#if defined(__CYGWIN__) + else{ + static const char *azDirs[] = { + 0, /* getenv("SQLITE_TMPDIR") */ + 0, /* getenv("TMPDIR") */ + 0, /* getenv("TMP") */ + 0, /* getenv("TEMP") */ + 0, /* getenv("USERPROFILE") */ + "/var/tmp", + "/usr/tmp", + "/tmp", + ".", + 0 /* List terminator */ + }; + unsigned int i; + const char *zDir = 0; + + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); + if( !azDirs[2] ) azDirs[2] = getenv("TMP"); + if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); + if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); + for(i=0; i/etilqs_XXXXXXXXXXXXXXX\0\0" + ** + ** If not, return SQLITE_ERROR. The number 17 is used here in order to + ** account for the space used by the 15 character random suffix and the + ** two trailing NUL characters. The final directory separator character + ** has already added if it was not already present. + */ + nLen = sqlite3Strlen30(zBuf); + if( (nLen + nPre + 17) > nBuf ){ + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); + return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); + } + + sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); + + j = sqlite3Strlen30(zBuf); + sqlite3_randomness(15, &zBuf[j]); + pid = osGetCurrentProcessId(); + for(i=0; i<15; i++, j++){ + zBuf[j] += pid & 0xff; + pid >>= 8; + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + zBuf[j+1] = 0; + *pzBuf = zBuf; + + OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); + return SQLITE_OK; +} + +/* +** Return TRUE if the named file is really a directory. Return false if +** it is something other than a directory, or if there is any kind of memory +** allocation failure. +*/ +static int winIsDir(const void *zConverted){ + DWORD attr; + int rc = 0; + DWORD lastErrno; + + if( osIsNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} + if( !rc ){ + return 0; /* Invalid name? */ + } + attr = sAttrData.dwFileAttributes; +#if SQLITE_OS_WINCE==0 + }else{ + attr = osGetFileAttributesA((char*)zConverted); +#endif + } + return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); +} + +/* forward reference */ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +); + +/* +** Open a file. +*/ +static int winOpen( + sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ + const char *zName, /* Name of the file (UTF-8) */ + sqlite3_file *id, /* Write the SQLite file handle here */ + int flags, /* Open mode flags */ + int *pOutFlags /* Status return flags */ +){ + HANDLE h; + DWORD lastErrno = 0; + DWORD dwDesiredAccess; + DWORD dwShareMode; + DWORD dwCreationDisposition; + DWORD dwFlagsAndAttributes = 0; +#if SQLITE_OS_WINCE + int isTemp = 0; +#endif + winVfsAppData *pAppData; + winFile *pFile = (winFile*)id; + void *zConverted; /* Filename in OS encoding */ + const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ + int cnt = 0; + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char *zTmpname = 0; /* For temporary filename, if necessary. */ + + int rc = SQLITE_OK; /* Function Return Code */ +#if !defined(NDEBUG) || SQLITE_OS_WINCE + int eType = flags&0xFFFFFF00; /* Type of file to open */ +#endif + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); + +#ifndef NDEBUG + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", + zUtf8Name, id, flags, pOutFlags)); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and super-journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + assert( pFile!=0 ); + memset(pFile, 0, sizeof(winFile)); + pFile->h = INVALID_HANDLE_VALUE; + +#if SQLITE_OS_WINRT + if( !zUtf8Name && !sqlite3_temp_directory ){ + sqlite3_log(SQLITE_ERROR, + "sqlite3_temp_directory variable should be set for WinRT"); + } +#endif + + /* If the second argument to this function is NULL, generate a + ** temporary file name to use + */ + if( !zUtf8Name ){ + assert( isDelete && !isOpenJournal ); + rc = winGetTempname(pVfs, &zTmpname); + if( rc!=SQLITE_OK ){ + OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); + return rc; + } + zUtf8Name = zTmpname; + } + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). + */ + assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); + + /* Convert the filename to the system encoding. */ + zConverted = winConvertFromUtf8Filename(zUtf8Name); + if( zConverted==0 ){ + sqlite3_free(zTmpname); + OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); + return SQLITE_IOERR_NOMEM_BKPT; + } + + if( winIsDir(zConverted) ){ + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); + return SQLITE_CANTOPEN_ISDIR; + } + + if( isReadWrite ){ + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + }else{ + dwDesiredAccess = GENERIC_READ; + } + + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + dwCreationDisposition = CREATE_NEW; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + dwCreationDisposition = OPEN_ALWAYS; + }else{ + /* Opens a file, only if it exists. */ + dwCreationDisposition = OPEN_EXISTING; + } + + if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){ + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + }else{ + dwShareMode = 0; + } + + if( isDelete ){ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; + isTemp = 1; +#else + dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY + | FILE_ATTRIBUTE_HIDDEN + | FILE_FLAG_DELETE_ON_CLOSE; +#endif + }else{ + dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + } + /* Reports from the internet are that performance is always + ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; +#endif + + if( osIsNT() ){ +#if SQLITE_OS_WINRT + CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; + extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); + extendedParameters.dwFileAttributes = + dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; + extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; + extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; + extendedParameters.lpSecurityAttributes = NULL; + extendedParameters.hTemplateFile = NULL; + do{ + h = osCreateFile2((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + &extendedParameters); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2, isRO = 0; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); +#else + do{ + h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2, isRO = 0; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + do{ + h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2, isRO = 0; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); + } +#endif + winLogIoerr(cnt, __LINE__); + + OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, + dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + + if( h==INVALID_HANDLE_VALUE ){ + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + if( isReadWrite && !isExclusive ){ + return winOpen(pVfs, zName, id, + ((flags|SQLITE_OPEN_READONLY) & + ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), + pOutFlags); + }else{ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); + return SQLITE_CANTOPEN_BKPT; + } + } + + if( pOutFlags ){ + if( isReadWrite ){ + *pOutFlags = SQLITE_OPEN_READWRITE; + }else{ + *pOutFlags = SQLITE_OPEN_READONLY; + } + } + + OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " + "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? + *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + + pAppData = (winVfsAppData*)pVfs->pAppData; + +#if SQLITE_OS_WINCE + { + if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB + && ((pAppData==NULL) || !pAppData->bNoLock) + && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK + ){ + osCloseHandle(h); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); + return rc; + } + } + if( isTemp ){ + pFile->zDeleteOnClose = zConverted; + }else +#endif + { + sqlite3_free(zConverted); + } + + sqlite3_free(zTmpname); + id->pMethods = pAppData ? pAppData->pMethod : &winIoMethod; + pFile->pVfs = pVfs; + pFile->h = h; + if( isReadonly ){ + pFile->ctrlFlags |= WINFILE_RDONLY; + } + if( (flags & SQLITE_OPEN_MAIN_DB) + && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) + ){ + pFile->ctrlFlags |= WINFILE_PSOW; + } + pFile->lastErrno = NO_ERROR; + pFile->zPath = zName; +#if SQLITE_MAX_MMAP_SIZE>0 + pFile->hMap = NULL; + pFile->pMapRegion = 0; + pFile->mmapSize = 0; + pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; +#endif + + OpenCounter(+1); + return rc; +} + +/* +** Delete the named file. +** +** Note that Windows does not allow a file to be deleted if some other +** process has it open. Sometimes a virus scanner or indexing program +** will open a journal file shortly after it is created in order to do +** whatever it does. While this other process is holding the +** file open, we will be unable to delete it. To work around this +** problem, we delay 100 milliseconds and try to delete again. Up +** to MX_DELETION_ATTEMPTs deletion attempts are run before giving +** up and returning an error. +*/ +static int winDelete( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to delete */ + int syncDir /* Not used on win32 */ +){ + int cnt = 0; + int rc; + DWORD attr; + DWORD lastErrno = 0; + void *zConverted; + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(syncDir); + + SimulateIOError(return SQLITE_IOERR_DELETE); + OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); + + zConverted = winConvertFromUtf8Filename(zFilename); + if( zConverted==0 ){ + OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); + return SQLITE_IOERR_NOMEM_BKPT; + } + if( osIsNT() ){ + do { +#if SQLITE_OS_WINRT + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, + &sAttrData) ){ + attr = sAttrData.dwFileAttributes; + }else{ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } +#else + attr = osGetFileAttributesW(zConverted); +#endif + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileW(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + do { + attr = osGetFileAttributesA(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileA(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); + } +#endif + if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); + }else{ + winLogIoerr(cnt, __LINE__); + } + sqlite3_free(zConverted); + OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); + return rc; +} + +/* +** Check the existence and status of a file. +*/ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +){ + DWORD attr; + int rc = 0; + DWORD lastErrno = 0; + void *zConverted; + UNUSED_PARAMETER(pVfs); + + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", + zFilename, flags, pResOut)); + + if( zFilename==0 ){ + *pResOut = 0; + OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + zFilename, pResOut, *pResOut)); + return SQLITE_OK; + } + + zConverted = winConvertFromUtf8Filename(zFilename); + if( zConverted==0 ){ + OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); + return SQLITE_IOERR_NOMEM_BKPT; + } + if( osIsNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} + if( rc ){ + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( flags==SQLITE_ACCESS_EXISTS + && sAttrData.nFileSizeHigh==0 + && sAttrData.nFileSizeLow==0 ){ + attr = INVALID_FILE_ATTRIBUTES; + }else{ + attr = sAttrData.dwFileAttributes; + } + }else{ + winLogIoerr(cnt, __LINE__); + if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", + zFilename); + }else{ + attr = INVALID_FILE_ATTRIBUTES; + } + } + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + attr = osGetFileAttributesA((char*)zConverted); + } +#endif + sqlite3_free(zConverted); + switch( flags ){ + case SQLITE_ACCESS_READ: + case SQLITE_ACCESS_EXISTS: + rc = attr!=INVALID_FILE_ATTRIBUTES; + break; + case SQLITE_ACCESS_READWRITE: + rc = attr!=INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)==0; + break; + default: + assert(!"Invalid flags argument"); + } + *pResOut = rc; + OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + zFilename, pResOut, *pResOut)); + return SQLITE_OK; +} + +/* +** Returns non-zero if the specified path name starts with the "long path" +** prefix. +*/ +static BOOL winIsLongPathPrefix( + const char *zPathname +){ + return ( zPathname[0]=='\\' && zPathname[1]=='\\' + && zPathname[2]=='?' && zPathname[3]=='\\' ); +} + +/* +** Returns non-zero if the specified path name starts with a drive letter +** followed by a colon character. +*/ +static BOOL winIsDriveLetterAndColon( + const char *zPathname +){ + return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); +} + +/* +** Returns non-zero if the specified path name should be used verbatim. If +** non-zero is returned from this function, the calling function must simply +** use the provided path name verbatim -OR- resolve it into a full path name +** using the GetFullPathName Win32 API function (if available). +*/ +static BOOL winIsVerbatimPathname( + const char *zPathname +){ + /* + ** If the path name starts with a forward slash or a backslash, it is either + ** a legal UNC name, a volume relative path, or an absolute path name in the + ** "Unix" format on Windows. There is no easy way to differentiate between + ** the final two cases; therefore, we return the safer return value of TRUE + ** so that callers of this function will simply use it verbatim. + */ + if ( winIsDirSep(zPathname[0]) ){ + return TRUE; + } + + /* + ** If the path name starts with a letter and a colon it is either a volume + ** relative path or an absolute path. Callers of this function must not + ** attempt to treat it as a relative path name (i.e. they should simply use + ** it verbatim). + */ + if ( winIsDriveLetterAndColon(zPathname) ){ + return TRUE; + } + + /* + ** If we get to this point, the path name should almost certainly be a purely + ** relative one (i.e. not a UNC name, not absolute, and not volume relative). + */ + return FALSE; +} + +/* +** Turn a relative pathname into a full pathname. Write the full +** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname +** bytes in size. +*/ +static int winFullPathnameNoMutex( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) + DWORD nByte; + void *zConverted; + char *zOut; +#endif + + /* If this path name begins with "/X:" or "\\?\", where "X" is any + ** alphabetic character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1) + || winIsLongPathPrefix(zRelative+1)) ){ + zRelative++; + } + +#if defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(nFull); + assert( nFull>=pVfs->mxPathname ); + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a slash. + */ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | + CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, + "winFullPathname1", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM_BKPT; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); + } + }else{ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), + zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, + "winFullPathname2", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM_BKPT; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); + } + } + return SQLITE_OK; +#endif + +#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); + /* WinCE has no concept of a relative pathname, or so I am told. */ + /* WinRT has no way to convert a relative path to an absolute one. */ + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a backslash. + */ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); + }else{ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); + } + return SQLITE_OK; +#endif + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a backslash. + */ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); + return SQLITE_OK; + } + zConverted = winConvertFromUtf8Filename(zRelative); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + if( osIsNT() ){ + LPWSTR zTemp; + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname1", zRelative); + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM_BKPT; + } + nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname2", zRelative); + } + sqlite3_free(zConverted); + zOut = winUnicodeToUtf8(zTemp); + sqlite3_free(zTemp); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + char *zTemp; + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname3", zRelative); + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM_BKPT; + } + nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname4", zRelative); + } + sqlite3_free(zConverted); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); + sqlite3_free(zTemp); + } +#endif + if( zOut ){ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); + sqlite3_free(zOut); + return SQLITE_OK; + }else{ + return SQLITE_IOERR_NOMEM_BKPT; + } +#endif +} +static int winFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ + int rc; + MUTEX_LOGIC( sqlite3_mutex *pMutex; ) + MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); ) + sqlite3_mutex_enter(pMutex); + rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); + sqlite3_mutex_leave(pMutex); + return rc; +} + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ + HANDLE h; +#if defined(__CYGWIN__) + int nFull = pVfs->mxPathname+1; + char *zFull = sqlite3MallocZero( nFull ); + void *zConverted = 0; + if( zFull==0 ){ + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ + sqlite3_free(zFull); + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + zConverted = winConvertFromUtf8Filename(zFull); + sqlite3_free(zFull); +#else + void *zConverted = winConvertFromUtf8Filename(zFilename); + UNUSED_PARAMETER(pVfs); +#endif + if( zConverted==0 ){ + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + if( osIsNT() ){ +#if SQLITE_OS_WINRT + h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); +#else + h = osLoadLibraryW((LPCWSTR)zConverted); +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + h = osLoadLibraryA((char*)zConverted); + } +#endif + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); + sqlite3_free(zConverted); + return (void*)h; +} +static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ + UNUSED_PARAMETER(pVfs); + winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); +} +static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ + FARPROC proc; + UNUSED_PARAMETER(pVfs); + proc = osGetProcAddressA((HANDLE)pH, zSym); + OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", + (void*)pH, zSym, (void*)proc)); + return (void(*)(void))proc; +} +static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ + UNUSED_PARAMETER(pVfs); + osFreeLibrary((HANDLE)pHandle); + OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define winDlOpen 0 + #define winDlError 0 + #define winDlSym 0 + #define winDlClose 0 +#endif + +/* State information for the randomness gatherer. */ +typedef struct EntropyGatherer EntropyGatherer; +struct EntropyGatherer { + unsigned char *a; /* Gather entropy into this buffer */ + int na; /* Size of a[] in bytes */ + int i; /* XOR next input into a[i] */ + int nXor; /* Number of XOR operations done */ +}; + +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) +/* Mix sz bytes of entropy into p. */ +static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ + int j, k; + for(j=0, k=p->i; ja[k++] ^= x[j]; + if( k>=p->na ) k = 0; + } + p->i = k; + p->nXor += sz; +} +#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ + +/* +** Write up to nBuf bytes of randomness into zBuf. +*/ +static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) + UNUSED_PARAMETER(pVfs); + memset(zBuf, 0, nBuf); + return nBuf; +#else + EntropyGatherer e; + UNUSED_PARAMETER(pVfs); + memset(zBuf, 0, nBuf); + e.a = (unsigned char*)zBuf; + e.na = nBuf; + e.nXor = 0; + e.i = 0; + { + SYSTEMTIME x; + osGetSystemTime(&x); + xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); + } + { + DWORD pid = osGetCurrentProcessId(); + xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); + } +#if SQLITE_OS_WINRT + { + ULONGLONG cnt = osGetTickCount64(); + xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); + } +#else + { + DWORD cnt = osGetTickCount(); + xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); + } +#endif /* SQLITE_OS_WINRT */ + { + LARGE_INTEGER i; + osQueryPerformanceCounter(&i); + xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); + } +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { + UUID id; + memset(&id, 0, sizeof(UUID)); + osUuidCreate(&id); + xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + memset(&id, 0, sizeof(UUID)); + osUuidCreateSequential(&id); + xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + } +#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ + return e.nXor>nBuf ? nBuf : e.nXor; +#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ +} + + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +static int winSleep(sqlite3_vfs *pVfs, int microsec){ + sqlite3_win32_sleep((microsec+999)/1000); + UNUSED_PARAMETER(pVfs); + return ((microsec+999)/1000)*1000; +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ + /* FILETIME structure is a 64-bit value representing the number of + 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). + */ + FILETIME ft; + static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif + /* 2^32 - to avoid use of LL and warnings in gcc */ + static const sqlite3_int64 max32BitValue = + (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + + (sqlite3_int64)294967296; + +#if SQLITE_OS_WINCE + SYSTEMTIME time; + osGetSystemTime(&time); + /* if SystemTimeToFileTime() fails, it returns zero. */ + if (!osSystemTimeToFileTime(&time,&ft)){ + return SQLITE_ERROR; + } +#else + osGetSystemTimeAsFileTime( &ft ); +#endif + + *piNow = winFiletimeEpoch + + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(pVfs); + return SQLITE_OK; +} + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ + int rc; + sqlite3_int64 i; + rc = winCurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* +** The idea is that this function works like a combination of +** GetLastError() and FormatMessage() on Windows (or errno and +** strerror_r() on Unix). After an error is returned by an OS +** function, SQLite calls this function with zBuf pointing to +** a buffer of nBuf bytes. The OS layer should populate the +** buffer with a nul-terminated UTF-8 encoded error message +** describing the last IO error to have occurred within the calling +** thread. +** +** If the error message is too large for the supplied buffer, +** it should be truncated. The return value of xGetLastError +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). If non-zero is returned, +** then it is not necessary to include the nul-terminator character +** in the output buffer. +** +** Not supplying an error message will have no adverse effect +** on SQLite. It is fine to have an implementation that never +** returns an error message: +** +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** assert(zBuf[0]=='\0'); +** return 0; +** } +** +** However if an error message is supplied, it will be incorporated +** by sqlite into the error message available to the user using +** sqlite3_errmsg(), possibly making IO errors easier to debug. +*/ +static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + DWORD e = osGetLastError(); + UNUSED_PARAMETER(pVfs); + if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); + return e; +} + +/* +** Initialize and deinitialize the operating system interface. +*/ +SQLITE_API int sqlite3_os_init(void){ + static sqlite3_vfs winVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32", /* zName */ + &winAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#if defined(SQLITE_WIN32_HAS_WIDE) + static sqlite3_vfs winLongPathVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-longpath", /* zName */ + &winAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#endif + static sqlite3_vfs winNolockVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-none", /* zName */ + &winNolockAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#if defined(SQLITE_WIN32_HAS_WIDE) + static sqlite3_vfs winLongPathNolockVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-longpath-none", /* zName */ + &winNolockAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#endif + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==80 ); + + /* get memory map allocation granularity */ + memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); +#if SQLITE_OS_WINRT + osGetNativeSystemInfo(&winSysInfo); +#else + osGetSystemInfo(&winSysInfo); +#endif + assert( winSysInfo.dwAllocationGranularity>0 ); + assert( winSysInfo.dwPageSize>0 ); + + sqlite3_vfs_register(&winVfs, 1); + +#if defined(SQLITE_WIN32_HAS_WIDE) + sqlite3_vfs_register(&winLongPathVfs, 0); +#endif + + sqlite3_vfs_register(&winNolockVfs, 0); + +#if defined(SQLITE_WIN32_HAS_WIDE) + sqlite3_vfs_register(&winLongPathNolockVfs, 0); +#endif + +#ifndef SQLITE_OMIT_WAL + winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + + return SQLITE_OK; +} + +SQLITE_API int sqlite3_os_end(void){ +#if SQLITE_OS_WINRT + if( sleepObj!=NULL ){ + osCloseHandle(sleepObj); + sleepObj = NULL; + } +#endif + +#ifndef SQLITE_OMIT_WAL + winBigLock = 0; +#endif + + return SQLITE_OK; +} + +#endif /* SQLITE_OS_WIN */ + +/************** End of os_win.c **********************************************/ +/************** Begin file memdb.c *******************************************/ +/* +** 2016-09-07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements an in-memory VFS. A database is held as a contiguous +** block of memory. +** +** This file also implements interface sqlite3_serialize() and +** sqlite3_deserialize(). +*/ +/* #include "sqliteInt.h" */ +#ifndef SQLITE_OMIT_DESERIALIZE + +/* +** Forward declaration of objects used by this utility +*/ +typedef struct sqlite3_vfs MemVfs; +typedef struct MemFile MemFile; +typedef struct MemStore MemStore; + +/* Access to a lower-level VFS that (might) implement dynamic loading, +** access to randomness, etc. +*/ +#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) + +/* Storage for a memdb file. +** +** An memdb object can be shared or separate. Shared memdb objects can be +** used by more than one database connection. Mutexes are used by shared +** memdb objects to coordinate access. Separate memdb objects are only +** connected to a single database connection and do not require additional +** mutexes. +** +** Shared memdb objects have .zFName!=0 and .pMutex!=0. They are created +** using "file:/name?vfs=memdb". The first character of the name must be +** "/" or else the object will be a separate memdb object. All shared +** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order. +** +** Separate memdb objects are created using a name that does not begin +** with "/" or using sqlite3_deserialize(). +** +** Access rules for shared MemStore objects: +** +** * .zFName is initialized when the object is created and afterwards +** is unchanged until the object is destroyed. So it can be accessed +** at any time as long as we know the object is not being destroyed, +** which means while either the SQLITE_MUTEX_STATIC_VFS1 or +** .pMutex is held or the object is not part of memdb_g.apMemStore[]. +** +** * Can .pMutex can only be changed while holding the +** SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part +** of memdb_g.apMemStore[]. +** +** * Other fields can only be changed while holding the .pMutex mutex +** or when the .nRef is less than zero and the object is not part of +** memdb_g.apMemStore[]. +** +** * The .aData pointer has the added requirement that it can can only +** be changed (for resizing) when nMmap is zero. +** +*/ +struct MemStore { + sqlite3_int64 sz; /* Size of the file */ + sqlite3_int64 szAlloc; /* Space allocated to aData */ + sqlite3_int64 szMax; /* Maximum allowed size of the file */ + unsigned char *aData; /* content of the file */ + sqlite3_mutex *pMutex; /* Used by shared stores only */ + int nMmap; /* Number of memory mapped pages */ + unsigned mFlags; /* Flags */ + int nRdLock; /* Number of readers */ + int nWrLock; /* Number of writers. (Always 0 or 1) */ + int nRef; /* Number of users of this MemStore */ + char *zFName; /* The filename for shared stores */ +}; + +/* An open file */ +struct MemFile { + sqlite3_file base; /* IO methods */ + MemStore *pStore; /* The storage */ + int eLock; /* Most recent lock against this file */ +}; + +/* +** File-scope variables for holding the memdb files that are accessible +** to multiple database connections in separate threads. +** +** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object. +*/ +static struct MemFS { + int nMemStore; /* Number of shared MemStore objects */ + MemStore **apMemStore; /* Array of all shared MemStore objects */ +} memdb_g; + +/* +** Methods for MemFile +*/ +static int memdbClose(sqlite3_file*); +static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); +static int memdbSync(sqlite3_file*, int flags); +static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int memdbLock(sqlite3_file*, int); +static int memdbUnlock(sqlite3_file*, int); +/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ +static int memdbFileControl(sqlite3_file*, int op, void *pArg); +/* static int memdbSectorSize(sqlite3_file*); // not used */ +static int memdbDeviceCharacteristics(sqlite3_file*); +static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); + +/* +** Methods for MemVfs +*/ +static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */ +static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename); +static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void memdbDlClose(sqlite3_vfs*, void*); +static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int memdbSleep(sqlite3_vfs*, int microseconds); +/* static int memdbCurrentTime(sqlite3_vfs*, double*); */ +static int memdbGetLastError(sqlite3_vfs*, int, char *); +static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs memdb_vfs = { + 2, /* iVersion */ + 0, /* szOsFile (set when registered) */ + 1024, /* mxPathname */ + 0, /* pNext */ + "memdb", /* zName */ + 0, /* pAppData (set when registered) */ + memdbOpen, /* xOpen */ + 0, /* memdbDelete, */ /* xDelete */ + memdbAccess, /* xAccess */ + memdbFullPathname, /* xFullPathname */ + memdbDlOpen, /* xDlOpen */ + memdbDlError, /* xDlError */ + memdbDlSym, /* xDlSym */ + memdbDlClose, /* xDlClose */ + memdbRandomness, /* xRandomness */ + memdbSleep, /* xSleep */ + 0, /* memdbCurrentTime, */ /* xCurrentTime */ + memdbGetLastError, /* xGetLastError */ + memdbCurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0, /* xNextSystemCall */ +}; + +static const sqlite3_io_methods memdb_io_methods = { + 3, /* iVersion */ + memdbClose, /* xClose */ + memdbRead, /* xRead */ + memdbWrite, /* xWrite */ + memdbTruncate, /* xTruncate */ + memdbSync, /* xSync */ + memdbFileSize, /* xFileSize */ + memdbLock, /* xLock */ + memdbUnlock, /* xUnlock */ + 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ + memdbFileControl, /* xFileControl */ + 0, /* memdbSectorSize,*/ /* xSectorSize */ + memdbDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + memdbFetch, /* xFetch */ + memdbUnfetch /* xUnfetch */ +}; + +/* +** Enter/leave the mutex on a MemStore +*/ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0 +static void memdbEnter(MemStore *p){ + UNUSED_PARAMETER(p); +} +static void memdbLeave(MemStore *p){ + UNUSED_PARAMETER(p); +} +#else +static void memdbEnter(MemStore *p){ + sqlite3_mutex_enter(p->pMutex); +} +static void memdbLeave(MemStore *p){ + sqlite3_mutex_leave(p->pMutex); +} +#endif + + + +/* +** Close an memdb-file. +** Free the underlying MemStore object when its refcount drops to zero +** or less. +*/ +static int memdbClose(sqlite3_file *pFile){ + MemStore *p = ((MemFile*)pFile)->pStore; + if( p->zFName ){ + int i; +#ifndef SQLITE_MUTEX_OMIT + sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + sqlite3_mutex_enter(pVfsMutex); + for(i=0; ALWAYS(inRef==1 ){ + memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore]; + if( memdb_g.nMemStore==0 ){ + sqlite3_free(memdb_g.apMemStore); + memdb_g.apMemStore = 0; + } + } + break; + } + } + sqlite3_mutex_leave(pVfsMutex); + }else{ + memdbEnter(p); + } + p->nRef--; + if( p->nRef<=0 ){ + if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){ + sqlite3_free(p->aData); + } + memdbLeave(p); + sqlite3_mutex_free(p->pMutex); + sqlite3_free(p); + }else{ + memdbLeave(p); + } + return SQLITE_OK; +} + +/* +** Read data from an memdb-file. +*/ +static int memdbRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( iOfst+iAmt>p->sz ){ + memset(zBuf, 0, iAmt); + if( iOfstsz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst); + memdbLeave(p); + return SQLITE_IOERR_SHORT_READ; + } + memcpy(zBuf, p->aData+iOfst, iAmt); + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Try to enlarge the memory allocation to hold at least sz bytes +*/ +static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){ + unsigned char *pNew; + if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){ + return SQLITE_FULL; + } + if( newSz>p->szMax ){ + return SQLITE_FULL; + } + newSz *= 2; + if( newSz>p->szMax ) newSz = p->szMax; + pNew = sqlite3Realloc(p->aData, newSz); + if( pNew==0 ) return SQLITE_IOERR_NOMEM; + p->aData = pNew; + p->szAlloc = newSz; + return SQLITE_OK; +} + +/* +** Write data to an memdb-file. +*/ +static int memdbWrite( + sqlite3_file *pFile, + const void *z, + int iAmt, + sqlite_int64 iOfst +){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ + /* Can't happen: memdbLock() will return SQLITE_READONLY before + ** reaching this point */ + memdbLeave(p); + return SQLITE_IOERR_WRITE; + } + if( iOfst+iAmt>p->sz ){ + int rc; + if( iOfst+iAmt>p->szAlloc + && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK + ){ + memdbLeave(p); + return rc; + } + if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); + p->sz = iOfst+iAmt; + } + memcpy(p->aData+iOfst, z, iAmt); + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Truncate an memdb-file. +** +** In rollback mode (which is always the case for memdb, as it does not +** support WAL mode) the truncate() method is only used to reduce +** the size of a file, never to increase the size. +*/ +static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ + MemStore *p = ((MemFile*)pFile)->pStore; + int rc = SQLITE_OK; + memdbEnter(p); + if( size>p->sz ){ + /* This can only happen with a corrupt wal mode db */ + rc = SQLITE_CORRUPT; + }else{ + p->sz = size; + } + memdbLeave(p); + return rc; +} + +/* +** Sync an memdb-file. +*/ +static int memdbSync(sqlite3_file *pFile, int flags){ + UNUSED_PARAMETER(pFile); + UNUSED_PARAMETER(flags); + return SQLITE_OK; +} + +/* +** Return the current file-size of an memdb-file. +*/ +static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + *pSize = p->sz; + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Lock an memdb-file. +*/ +static int memdbLock(sqlite3_file *pFile, int eLock){ + MemFile *pThis = (MemFile*)pFile; + MemStore *p = pThis->pStore; + int rc = SQLITE_OK; + if( eLock<=pThis->eLock ) return SQLITE_OK; + memdbEnter(p); + + assert( p->nWrLock==0 || p->nWrLock==1 ); + assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 ); + assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 ); + + if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ + rc = SQLITE_READONLY; + }else{ + switch( eLock ){ + case SQLITE_LOCK_SHARED: { + assert( pThis->eLock==SQLITE_LOCK_NONE ); + if( p->nWrLock>0 ){ + rc = SQLITE_BUSY; + }else{ + p->nRdLock++; + } + break; + }; + + case SQLITE_LOCK_RESERVED: + case SQLITE_LOCK_PENDING: { + assert( pThis->eLock>=SQLITE_LOCK_SHARED ); + if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){ + if( p->nWrLock>0 ){ + rc = SQLITE_BUSY; + }else{ + p->nWrLock = 1; + } + } + break; + } + + default: { + assert( eLock==SQLITE_LOCK_EXCLUSIVE ); + assert( pThis->eLock>=SQLITE_LOCK_SHARED ); + if( p->nRdLock>1 ){ + rc = SQLITE_BUSY; + }else if( pThis->eLock==SQLITE_LOCK_SHARED ){ + p->nWrLock = 1; + } + break; + } + } + } + if( rc==SQLITE_OK ) pThis->eLock = eLock; + memdbLeave(p); + return rc; +} + +/* +** Unlock an memdb-file. +*/ +static int memdbUnlock(sqlite3_file *pFile, int eLock){ + MemFile *pThis = (MemFile*)pFile; + MemStore *p = pThis->pStore; + if( eLock>=pThis->eLock ) return SQLITE_OK; + memdbEnter(p); + + assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE ); + if( eLock==SQLITE_LOCK_SHARED ){ + if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){ + p->nWrLock--; + } + }else{ + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + p->nWrLock--; + } + p->nRdLock--; + } + + pThis->eLock = eLock; + memdbLeave(p); + return SQLITE_OK; +} + +#if 0 +/* +** This interface is only used for crash recovery, which does not +** occur on an in-memory database. +*/ +static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + *pResOut = 0; + return SQLITE_OK; +} +#endif + + +/* +** File control method. For custom operations on an memdb-file. +*/ +static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ + MemStore *p = ((MemFile*)pFile)->pStore; + int rc = SQLITE_NOTFOUND; + memdbEnter(p); + if( op==SQLITE_FCNTL_VFSNAME ){ + *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); + rc = SQLITE_OK; + } + if( op==SQLITE_FCNTL_SIZE_LIMIT ){ + sqlite3_int64 iLimit = *(sqlite3_int64*)pArg; + if( iLimitsz ){ + if( iLimit<0 ){ + iLimit = p->szMax; + }else{ + iLimit = p->sz; + } + } + p->szMax = iLimit; + *(sqlite3_int64*)pArg = iLimit; + rc = SQLITE_OK; + } + memdbLeave(p); + return rc; +} + +#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +/* +** Return the sector-size in bytes for an memdb-file. +*/ +static int memdbSectorSize(sqlite3_file *pFile){ + return 1024; +} +#endif + +/* +** Return the device characteristic flags supported by an memdb-file. +*/ +static int memdbDeviceCharacteristics(sqlite3_file *pFile){ + UNUSED_PARAMETER(pFile); + return SQLITE_IOCAP_ATOMIC | + SQLITE_IOCAP_POWERSAFE_OVERWRITE | + SQLITE_IOCAP_SAFE_APPEND | + SQLITE_IOCAP_SEQUENTIAL; +} + +/* Fetch a page of a memory-mapped file */ +static int memdbFetch( + sqlite3_file *pFile, + sqlite3_int64 iOfst, + int iAmt, + void **pp +){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){ + *pp = 0; + }else{ + p->nMmap++; + *pp = (void*)(p->aData + iOfst); + } + memdbLeave(p); + return SQLITE_OK; +} + +/* Release a memory-mapped page */ +static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ + MemStore *p = ((MemFile*)pFile)->pStore; + UNUSED_PARAMETER(iOfst); + UNUSED_PARAMETER(pPage); + memdbEnter(p); + p->nMmap--; + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Open an mem file handle. +*/ +static int memdbOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFd, + int flags, + int *pOutFlags +){ + MemFile *pFile = (MemFile*)pFd; + MemStore *p = 0; + int szName; + UNUSED_PARAMETER(pVfs); + + memset(pFile, 0, sizeof(*pFile)); + szName = sqlite3Strlen30(zName); + if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){ + int i; +#ifndef SQLITE_MUTEX_OMIT + sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + sqlite3_mutex_enter(pVfsMutex); + for(i=0; izFName,zName)==0 ){ + p = memdb_g.apMemStore[i]; + break; + } + } + if( p==0 ){ + MemStore **apNew; + p = sqlite3Malloc( sizeof(*p) + szName + 3 ); + if( p==0 ){ + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + apNew = sqlite3Realloc(memdb_g.apMemStore, + sizeof(apNew[0])*(memdb_g.nMemStore+1) ); + if( apNew==0 ){ + sqlite3_free(p); + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + apNew[memdb_g.nMemStore++] = p; + memdb_g.apMemStore = apNew; + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; + p->zFName = (char*)&p[1]; + memcpy(p->zFName, zName, szName+1); + p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( p->pMutex==0 ){ + memdb_g.nMemStore--; + sqlite3_free(p); + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + p->nRef = 1; + memdbEnter(p); + }else{ + memdbEnter(p); + p->nRef++; + } + sqlite3_mutex_leave(pVfsMutex); + }else{ + p = sqlite3Malloc( sizeof(*p) ); + if( p==0 ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; + } + pFile->pStore = p; + if( pOutFlags!=0 ){ + *pOutFlags = flags | SQLITE_OPEN_MEMORY; + } + pFd->pMethods = &memdb_io_methods; + memdbLeave(p); + return SQLITE_OK; +} + +#if 0 /* Only used to delete rollback journals, super-journals, and WAL + ** files, none of which exist in memdb. So this routine is never used */ +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + return SQLITE_IOERR_DELETE; +} +#endif + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +** +** With memdb, no files ever exist on disk. So always return false. +*/ +static int memdbAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(zPath); + UNUSED_PARAMETER(flags); + *pResOut = 0; + return SQLITE_OK; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int memdbFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + UNUSED_PARAMETER(pVfs); + sqlite3_snprintf(nOut, zOut, "%s", zPath); + return SQLITE_OK; +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ + return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){ + ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){ + return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); +} + +#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */ +/* +** Return the current time as a Julian Day number in *pTimeOut. +*/ +static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); +} +#endif + +static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); +} +static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ + return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); +} + +/* +** Translate a database connection pointer and schema name into a +** MemFile pointer. +*/ +static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ + MemFile *p = 0; + MemStore *pStore; + int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); + if( rc ) return 0; + if( p->base.pMethods!=&memdb_io_methods ) return 0; + pStore = p->pStore; + memdbEnter(pStore); + if( pStore->zFName!=0 ) p = 0; + memdbLeave(pStore); + return p; +} + +/* +** Return the serialization of a database +*/ +SQLITE_API unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which database within the connection */ + sqlite3_int64 *piSize, /* Write size here, if not NULL */ + unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */ +){ + MemFile *p; + int iDb; + Btree *pBt; + sqlite3_int64 sz; + int szPage = 0; + sqlite3_stmt *pStmt = 0; + unsigned char *pOut; + char *zSql; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; + p = memdbFromDbSchema(db, zSchema); + iDb = sqlite3FindDbName(db, zSchema); + if( piSize ) *piSize = -1; + if( iDb<0 ) return 0; + if( p ){ + MemStore *pStore = p->pStore; + assert( pStore->pMutex==0 ); + if( piSize ) *piSize = pStore->sz; + if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ + pOut = pStore->aData; + }else{ + pOut = sqlite3_malloc64( pStore->sz ); + if( pOut ) memcpy(pOut, pStore->aData, pStore->sz); + } + return pOut; + } + pBt = db->aDb[iDb].pBt; + if( pBt==0 ) return 0; + szPage = sqlite3BtreeGetPageSize(pBt); + zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); + rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; + sqlite3_free(zSql); + if( rc ) return 0; + rc = sqlite3_step(pStmt); + if( rc!=SQLITE_ROW ){ + pOut = 0; + }else{ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + if( sz==0 ){ + sqlite3_reset(pStmt); + sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + } + } + if( piSize ) *piSize = sz; + if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ + pOut = 0; + }else{ + pOut = sqlite3_malloc64( sz ); + if( pOut ){ + int nPage = sqlite3_column_int(pStmt, 0); + Pager *pPager = sqlite3BtreePager(pBt); + int pgno; + for(pgno=1; pgno<=nPage; pgno++){ + DbPage *pPage = 0; + unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1); + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); + if( rc==SQLITE_OK ){ + memcpy(pTo, sqlite3PagerGetData(pPage), szPage); + }else{ + memset(pTo, 0, szPage); + } + sqlite3PagerUnref(pPage); + } + } + } + } + sqlite3_finalize(pStmt); + return pOut; +} + +/* Convert zSchema to a MemDB and initialize its content. +*/ +SQLITE_API int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to reopen with the deserialization */ + unsigned char *pData, /* The serialized database content */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ + unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ +){ + MemFile *p; + char *zSql; + sqlite3_stmt *pStmt = 0; + int rc; + int iDb; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( szDb<0 ) return SQLITE_MISUSE_BKPT; + if( szBuf<0 ) return SQLITE_MISUSE_BKPT; +#endif + + sqlite3_mutex_enter(db->mutex); + if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; + iDb = sqlite3FindDbName(db, zSchema); + testcase( iDb==1 ); + if( iDb<2 && iDb!=0 ){ + rc = SQLITE_ERROR; + goto end_deserialize; + } + zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + if( rc ) goto end_deserialize; + db->init.iDb = (u8)iDb; + db->init.reopenMemdb = 1; + rc = sqlite3_step(pStmt); + db->init.reopenMemdb = 0; + if( rc!=SQLITE_DONE ){ + rc = SQLITE_ERROR; + goto end_deserialize; + } + p = memdbFromDbSchema(db, zSchema); + if( p==0 ){ + rc = SQLITE_ERROR; + }else{ + MemStore *pStore = p->pStore; + pStore->aData = pData; + pData = 0; + pStore->sz = szDb; + pStore->szAlloc = szBuf; + pStore->szMax = szBuf; + if( pStore->szMaxszMax = sqlite3GlobalConfig.mxMemdbSize; + } + pStore->mFlags = mFlags; + rc = SQLITE_OK; + } + +end_deserialize: + sqlite3_finalize(pStmt); + if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ + sqlite3_free(pData); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Return true if the VFS is the memvfs. +*/ +SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs *pVfs){ + return pVfs==&memdb_vfs; +} + +/* +** This routine is called when the extension is loaded. +** Register the new VFS. +*/ +SQLITE_PRIVATE int sqlite3MemdbInit(void){ + sqlite3_vfs *pLower = sqlite3_vfs_find(0); + unsigned int sz; + if( NEVER(pLower==0) ) return SQLITE_ERROR; + sz = pLower->szOsFile; + memdb_vfs.pAppData = pLower; + /* The following conditional can only be true when compiled for + ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave + ** it in, to be safe, but it is marked as NO_TEST since there + ** is no way to reach it under most builds. */ + if( szBITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is +** a hash table that will hold up to BITVEC_MXHASH distinct values. +** +** Otherwise, the value i is redirected into one of BITVEC_NPTR +** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap +** handles up to iDivisor separate values of i. apSub[0] holds +** values between 1 and iDivisor. apSub[1] holds values between +** iDivisor+1 and 2*iDivisor. apSub[N] holds values between +** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized +** to hold deal with values between 1 and iDivisor. +*/ +struct Bitvec { + u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ + u32 nSet; /* Number of bits that are set - only valid for aHash + ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512, + ** this would be 125. */ + u32 iDivisor; /* Number of bits handled by each apSub[] entry. */ + /* Should >=0 for apSub element. */ + /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */ + /* For a BITVEC_SZ of 512, this would be 34,359,739. */ + union { + BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ + u32 aHash[BITVEC_NINT]; /* Hash table representation */ + Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ + } u; +}; + +/* +** Create a new bitmap object able to handle bits between 0 and iSize, +** inclusive. Return a pointer to the new object. Return NULL if +** malloc fails. +*/ +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){ + Bitvec *p; + assert( sizeof(*p)==BITVEC_SZ ); + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->iSize = iSize; + } + return p; +} + +/* +** Check to see if the i-th bit is set. Return true or false. +** If p is NULL (if the bitmap has not been created) or if +** i is out of range, then return false. +*/ +SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){ + assert( p!=0 ); + i--; + if( i>=p->iSize ) return 0; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return 0; + } + } + if( p->iSize<=BITVEC_NBIT ){ + return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0; + } else{ + u32 h = BITVEC_HASH(i++); + while( p->u.aHash[h] ){ + if( p->u.aHash[h]==i ) return 1; + h = (h+1) % BITVEC_NINT; + } + return 0; + } +} +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ + return p!=0 && sqlite3BitvecTestNotNull(p,i); +} + +/* +** Set the i-th bit. Return 0 on success and an error code if +** anything goes wrong. +** +** This routine might cause sub-bitmaps to be allocated. Failing +** to get the memory needed to hold the sub-bitmap is the only +** that can go wrong with an insert, assuming p and i are valid. +** +** The calling function must ensure that p is a valid Bitvec object +** and that the value for "i" is within range of the Bitvec object. +** Otherwise the behavior is undefined. +*/ +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ + u32 h; + if( p==0 ) return SQLITE_OK; + assert( i>0 ); + assert( i<=p->iSize ); + i--; + while((p->iSize > BITVEC_NBIT) && p->iDivisor) { + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + if( p->u.apSub[bin]==0 ){ + p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); + if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT; + } + p = p->u.apSub[bin]; + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); + return SQLITE_OK; + } + h = BITVEC_HASH(i++); + /* if there wasn't a hash collision, and this doesn't */ + /* completely fill the hash, then just add it without */ + /* worrying about sub-dividing and re-hashing. */ + if( !p->u.aHash[h] ){ + if (p->nSet<(BITVEC_NINT-1)) { + goto bitvec_set_end; + } else { + goto bitvec_set_rehash; + } + } + /* there was a collision, check to see if it's already */ + /* in hash, if not, try to find a spot for it */ + do { + if( p->u.aHash[h]==i ) return SQLITE_OK; + h++; + if( h>=BITVEC_NINT ) h = 0; + } while( p->u.aHash[h] ); + /* we didn't find it in the hash. h points to the first */ + /* available free spot. check to see if this is going to */ + /* make our hash too "full". */ +bitvec_set_rehash: + if( p->nSet>=BITVEC_MXHASH ){ + unsigned int j; + int rc; + u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); + if( aiValues==0 ){ + return SQLITE_NOMEM_BKPT; + }else{ + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.apSub, 0, sizeof(p->u.apSub)); + p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; + rc = sqlite3BitvecSet(p, i); + for(j=0; jnSet++; + p->u.aHash[h] = i; + return SQLITE_OK; +} + +/* +** Clear the i-th bit. +** +** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage +** that BitvecClear can use to rebuilt its hash table. +*/ +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ + if( p==0 ) return; + assert( i>0 ); + i--; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return; + } + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); + }else{ + unsigned int j; + u32 *aiValues = pBuf; + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.aHash, 0, sizeof(p->u.aHash)); + p->nSet = 0; + for(j=0; jnSet++; + while( p->u.aHash[h] ){ + h++; + if( h>=BITVEC_NINT ) h = 0; + } + p->u.aHash[h] = aiValues[j]; + } + } + } +} + +/* +** Destroy a bitmap object. Reclaim all memory used. +*/ +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){ + if( p==0 ) return; + if( p->iDivisor ){ + unsigned int i; + for(i=0; iu.apSub[i]); + } + } + sqlite3_free(p); +} + +/* +** Return the value of the iSize parameter specified when Bitvec *p +** was created. +*/ +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ + return p->iSize; +} + +#ifndef SQLITE_UNTESTABLE +/* +** Let V[] be an array of unsigned characters sufficient to hold +** up to N bits. Let I be an integer between 0 and N. 0<=I>3] |= (1<<(I&7)) +#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) +#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 + +/* +** This routine runs an extensive test of the Bitvec code. +** +** The input is an array of integers that acts as a program +** to test the Bitvec. The integers are opcodes followed +** by 0, 1, or 3 operands, depending on the opcode. Another +** opcode follows immediately after the last operand. +** +** There are 6 opcodes numbered from 0 through 5. 0 is the +** "halt" opcode and causes the test to end. +** +** 0 Halt and return the number of errors +** 1 N S X Set N bits beginning with S and incrementing by X +** 2 N S X Clear N bits beginning with S and incrementing by X +** 3 N Set N randomly chosen bits +** 4 N Clear N randomly chosen bits +** 5 N S X Set N bits from S increment X in array only, not in bitvec +** +** The opcodes 1 through 4 perform set and clear operations are performed +** on both a Bitvec object and on a linear array of bits obtained from malloc. +** Opcode 5 works on the linear array only, not on the Bitvec. +** Opcode 5 is used to deliberately induce a fault in order to +** confirm that error detection works. +** +** At the conclusion of the test the linear array is compared +** against the Bitvec object. If there are any differences, +** an error is returned. If they are the same, zero is returned. +** +** If a memory allocation error occurs, return -1. +*/ +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ + Bitvec *pBitvec = 0; + unsigned char *pV = 0; + int rc = -1; + int i, nx, pc, op; + void *pTmpSpace; + + /* Allocate the Bitvec to be tested and a linear array of + ** bits to act as the reference */ + pBitvec = sqlite3BitvecCreate( sz ); + pV = sqlite3MallocZero( (sz+7)/8 + 1 ); + pTmpSpace = sqlite3_malloc64(BITVEC_SZ); + if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; + + /* NULL pBitvec tests */ + sqlite3BitvecSet(0, 1); + sqlite3BitvecClear(0, 1, pTmpSpace); + + /* Run the program */ + pc = i = 0; + while( (op = aOp[pc])!=0 ){ + switch( op ){ + case 1: + case 2: + case 5: { + nx = 4; + i = aOp[pc+2] - 1; + aOp[pc+2] += aOp[pc+3]; + break; + } + case 3: + case 4: + default: { + nx = 2; + sqlite3_randomness(sizeof(i), &i); + break; + } + } + if( (--aOp[pc+1]) > 0 ) nx = 0; + pc += nx; + i = (i & 0x7fffffff)%sz; + if( (op & 1)!=0 ){ + SETBIT(pV, (i+1)); + if( op!=5 ){ + if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; + } + }else{ + CLEARBIT(pV, (i+1)); + sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); + } + } + + /* Test to make sure the linear array exactly matches the + ** Bitvec object. Start with the assumption that they do + ** match (rc==0). Change rc to non-zero if a discrepancy + ** is found. + */ + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + + sqlite3BitvecTest(pBitvec, 0) + + (sqlite3BitvecSize(pBitvec) - sz); + for(i=1; i<=sz; i++){ + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ + rc = i; + break; + } + } + + /* Free allocated structure */ +bitvec_end: + sqlite3_free(pTmpSpace); + sqlite3_free(pV); + sqlite3BitvecDestroy(pBitvec); + return rc; +} +#endif /* SQLITE_UNTESTABLE */ + +/************** End of bitvec.c **********************************************/ +/************** Begin file pcache.c ******************************************/ +/* +** 2008 August 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements that page cache. +*/ +/* #include "sqliteInt.h" */ + +/* +** A complete page cache is an instance of this structure. Every +** entry in the cache holds a single page of the database file. The +** btree layer only operates on the cached copy of the database pages. +** +** A page cache entry is "clean" if it exactly matches what is currently +** on disk. A page is "dirty" if it has been modified and needs to be +** persisted to disk. +** +** pDirty, pDirtyTail, pSynced: +** All dirty pages are linked into the doubly linked list using +** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order +** such that p was added to the list more recently than p->pDirtyNext. +** PCache.pDirty points to the first (newest) element in the list and +** pDirtyTail to the last (oldest). +** +** The PCache.pSynced variable is used to optimize searching for a dirty +** page to eject from the cache mid-transaction. It is better to eject +** a page that does not require a journal sync than one that does. +** Therefore, pSynced is maintained so that it *almost* always points +** to either the oldest page in the pDirty/pDirtyTail list that has a +** clear PGHDR_NEED_SYNC flag or to a page that is older than this one +** (so that the right page to eject can be found by following pDirtyPrev +** pointers). +*/ +struct PCache { + PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ + PgHdr *pSynced; /* Last synced page in dirty page list */ + i64 nRefSum; /* Sum of ref counts over all pages */ + int szCache; /* Configured cache size */ + int szSpill; /* Size before spilling occurs */ + int szPage; /* Size of every page in this cache */ + int szExtra; /* Size of extra space for each page */ + u8 bPurgeable; /* True if pages are on backing store */ + u8 eCreate; /* eCreate value for for xFetch() */ + int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ + void *pStress; /* Argument to xStress */ + sqlite3_pcache *pCache; /* Pluggable cache module */ +}; + +/********************************** Test and Debug Logic **********************/ +/* +** Debug tracing macros. Enable by by changing the "0" to "1" and +** recompiling. +** +** When sqlite3PcacheTrace is 1, single line trace messages are issued. +** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries +** is displayed for many operations, resulting in a lot of output. +*/ +#if defined(SQLITE_DEBUG) && 0 + int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ + int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ +# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} + static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){ + PgHdr *pPg; + unsigned char *a; + int j; + if( pLower==0 ){ + printf("%3d: NULL\n", i); + }else{ + pPg = (PgHdr*)pLower->pExtra; + printf("%3d: nRef %2lld flgs %02x data ", i, pPg->nRef, pPg->flags); + a = (unsigned char *)pLower->pBuf; + for(j=0; j<12; j++) printf("%02x", a[j]); + printf(" ptr %p\n", pPg); + } + } + static void pcacheDump(PCache *pCache){ + int N; + int i; + sqlite3_pcache_page *pLower; + + if( sqlite3PcacheTrace<2 ) return; + if( pCache->pCache==0 ) return; + N = sqlite3PcachePagecount(pCache); + if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; + for(i=1; i<=N; i++){ + pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); + pcachePageTrace(i, pLower); + if( pLower && ((PgHdr*)pLower)->pPage==0 ){ + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); + } + } + } +#else +# define pcacheTrace(X) +# define pcachePageTrace(PGNO, X) +# define pcacheDump(X) +#endif + +/* +** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. +** This routine runs inside of assert() statements only. +*/ +#if defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) +static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + if( p==pPg ) return 1; + } + return 0; +} +static int pageNotOnDirtyList(PCache *pCache, PgHdr *pPg){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + if( p==pPg ) return 0; + } + return 1; +} +#else +# define pageOnDirtyList(A,B) 1 +# define pageNotOnDirtyList(A,B) 1 +#endif + +/* +** Check invariants on a PgHdr entry. Return true if everything is OK. +** Return false if any invariant is violated. +** +** This routine is for use inside of assert() statements only. For +** example: +** +** assert( sqlite3PcachePageSanity(pPg) ); +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ + PCache *pCache; + assert( pPg!=0 ); + assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ + pCache = pPg->pCache; + assert( pCache!=0 ); /* Every page has an associated PCache */ + if( pPg->flags & PGHDR_CLEAN ){ + assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ + assert( pageNotOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirtylist */ + }else{ + assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ + assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); + assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg ); + assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg ); + assert( pageOnDirtyList(pCache, pPg) ); + } + /* WRITEABLE pages must also be DIRTY */ + if( pPg->flags & PGHDR_WRITEABLE ){ + assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ + } + /* NEED_SYNC can be set independently of WRITEABLE. This can happen, + ** for example, when using the sqlite3PagerDontWrite() optimization: + ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. + ** (2) Page X moved to freelist, WRITEABLE is cleared + ** (3) Page X reused, WRITEABLE is set again + ** If NEED_SYNC had been cleared in step 2, then it would not be reset + ** in step 3, and page might be written into the database without first + ** syncing the rollback journal, which might cause corruption on a power + ** loss. + ** + ** Another example is when the database page size is smaller than the + ** disk sector size. When any page of a sector is journalled, all pages + ** in that sector are marked NEED_SYNC even if they are still CLEAN, just + ** in case they are later modified, since all pages in the same sector + ** must be journalled and synced before any of those pages can be safely + ** written. + */ + return 1; +} +#endif /* SQLITE_DEBUG */ + + +/********************************** Linked List Management ********************/ + +/* Allowed values for second argument to pcacheManageDirtyList() */ +#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ +#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ +#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ + +/* +** Manage pPage's participation on the dirty list. Bits of the addRemove +** argument determines what operation to do. The 0x01 bit means first +** remove pPage from the dirty list. The 0x02 means add pPage back to +** the dirty list. Doing both moves pPage to the front of the dirty list. +*/ +static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ + PCache *p = pPage->pCache; + + pcacheTrace(("%p.DIRTYLIST.%s %d\n", p, + addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT", + pPage->pgno)); + if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ + assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); + assert( pPage->pDirtyPrev || pPage==p->pDirty ); + + /* Update the PCache1.pSynced variable if necessary. */ + if( p->pSynced==pPage ){ + p->pSynced = pPage->pDirtyPrev; + } + + if( pPage->pDirtyNext ){ + pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; + }else{ + assert( pPage==p->pDirtyTail ); + p->pDirtyTail = pPage->pDirtyPrev; + } + if( pPage->pDirtyPrev ){ + pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; + }else{ + /* If there are now no dirty pages in the cache, set eCreate to 2. + ** This is an optimization that allows sqlite3PcacheFetch() to skip + ** searching for a dirty page to eject from the cache when it might + ** otherwise have to. */ + assert( pPage==p->pDirty ); + p->pDirty = pPage->pDirtyNext; + assert( p->bPurgeable || p->eCreate==2 ); + if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/ + assert( p->bPurgeable==0 || p->eCreate==1 ); + p->eCreate = 2; + } + } + } + if( addRemove & PCACHE_DIRTYLIST_ADD ){ + pPage->pDirtyPrev = 0; + pPage->pDirtyNext = p->pDirty; + if( pPage->pDirtyNext ){ + assert( pPage->pDirtyNext->pDirtyPrev==0 ); + pPage->pDirtyNext->pDirtyPrev = pPage; + }else{ + p->pDirtyTail = pPage; + if( p->bPurgeable ){ + assert( p->eCreate==2 ); + p->eCreate = 1; + } + } + p->pDirty = pPage; + + /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set + ** pSynced to point to it. Checking the NEED_SYNC flag is an + ** optimization, as if pSynced points to a page with the NEED_SYNC + ** flag set sqlite3PcacheFetchStress() searches through all newer + ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */ + if( !p->pSynced + && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/ + ){ + p->pSynced = pPage; + } + } + pcacheDump(p); +} + +/* +** Wrapper around the pluggable caches xUnpin method. If the cache is +** being used for an in-memory database, this function is a no-op. +*/ +static void pcacheUnpin(PgHdr *p){ + if( p->pCache->bPurgeable ){ + pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno)); + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); + pcacheDump(p->pCache); + } +} + +/* +** Compute the number of pages of cache requested. p->szCache is the +** cache size requested by the "PRAGMA cache_size" statement. +*/ +static int numberOfCachePages(PCache *p){ + if( p->szCache>=0 ){ + /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the + ** suggested cache size is set to N. */ + return p->szCache; + }else{ + i64 n; + /* IMPLEMENTATION-OF: R-59858-46238 If the argument N is negative, then the + ** number of cache pages is adjusted to be a number of pages that would + ** use approximately abs(N*1024) bytes of memory based on the current + ** page size. */ + n = ((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + if( n>1000000000 ) n = 1000000000; + return (int)n; + } +} + +/*************************************************** General Interfaces ****** +** +** Initialize and shutdown the page cache subsystem. Neither of these +** functions are threadsafe. +*/ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the + ** built-in default page cache is used instead of the application defined + ** page cache. */ + sqlite3PCacheSetDefault(); + assert( sqlite3GlobalConfig.pcache2.xInit!=0 ); + } + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); +} +SQLITE_PRIVATE void sqlite3PcacheShutdown(void){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ + /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); + } +} + +/* +** Return the size in bytes of a PCache object. +*/ +SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); } + +/* +** Create a new PCache object. Storage space to hold the object +** has already been allocated and is passed in as the p pointer. +** The caller discovers how much space needs to be allocated by +** calling sqlite3PcacheSize(). +** +** szExtra is some extra space allocated for each page. The first +** 8 bytes of the extra space will be zeroed as the page is allocated, +** but remaining content will be uninitialized. Though it is opaque +** to this module, the extra space really ends up being the MemPage +** structure in the pager. +*/ +SQLITE_PRIVATE int sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *p /* Preallocated space for the PCache */ +){ + memset(p, 0, sizeof(PCache)); + p->szPage = 1; + p->szExtra = szExtra; + assert( szExtra>=8 ); /* First 8 bytes will be zeroed */ + p->bPurgeable = bPurgeable; + p->eCreate = 2; + p->xStress = xStress; + p->pStress = pStress; + p->szCache = 100; + p->szSpill = 1; + pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable)); + return sqlite3PcacheSetPageSize(p, szPage); +} + +/* +** Change the page size for PCache object. The caller must ensure that there +** are no outstanding page references when this function is called. +*/ +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ + assert( pCache->nRefSum==0 && pCache->pDirty==0 ); + if( pCache->szPage ){ + sqlite3_pcache *pNew; + pNew = sqlite3GlobalConfig.pcache2.xCreate( + szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)), + pCache->bPurgeable + ); + if( pNew==0 ) return SQLITE_NOMEM_BKPT; + sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + } + pCache->pCache = pNew; + pCache->szPage = szPage; + pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage)); + } + return SQLITE_OK; +} + +/* +** Try to obtain a page from the cache. +** +** This routine returns a pointer to an sqlite3_pcache_page object if +** such an object is already in cache, or if a new one is created. +** This routine returns a NULL pointer if the object was not in cache +** and could not be created. +** +** The createFlags should be 0 to check for existing pages and should +** be 3 (not 1, but 3) to try to create a new page. +** +** If the createFlag is 0, then NULL is always returned if the page +** is not already in the cache. If createFlag is 1, then a new page +** is created only if that can be done without spilling dirty pages +** and without exceeding the cache size limit. +** +** The caller needs to invoke sqlite3PcacheFetchFinish() to properly +** initialize the sqlite3_pcache_page object and convert it into a +** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() +** routines are split this way for performance reasons. When separated +** they can both (usually) operate without having to push values to +** the stack on entry and pop them back off on exit, which saves a +** lot of pushing and popping. +*/ +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + int createFlag /* If true, create page if it does not exist already */ +){ + int eCreate; + sqlite3_pcache_page *pRes; + + assert( pCache!=0 ); + assert( pCache->pCache!=0 ); + assert( createFlag==3 || createFlag==0 ); + assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); + + /* eCreate defines what to do if the page does not exist. + ** 0 Do not allocate a new page. (createFlag==0) + ** 1 Allocate a new page if doing so is inexpensive. + ** (createFlag==1 AND bPurgeable AND pDirty) + ** 2 Allocate a new page even it doing so is difficult. + ** (createFlag==1 AND !(bPurgeable AND pDirty) + */ + eCreate = createFlag & pCache->eCreate; + assert( eCreate==0 || eCreate==1 || eCreate==2 ); + assert( createFlag==0 || pCache->eCreate==eCreate ); + assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); + pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); + pcacheTrace(("%p.FETCH %d%s (result: %p) ",pCache,pgno, + createFlag?" create":"",pRes)); + pcachePageTrace(pgno, pRes); + return pRes; +} + +/* +** If the sqlite3PcacheFetch() routine is unable to allocate a new +** page because no clean pages are available for reuse and the cache +** size limit has been reached, then this routine can be invoked to +** try harder to allocate a page. This routine might invoke the stress +** callback to spill dirty pages to the journal. It will then try to +** allocate the new page and will only fail to allocate a new page on +** an OOM error. +** +** This routine should be invoked only after sqlite3PcacheFetch() fails. +*/ +SQLITE_PRIVATE int sqlite3PcacheFetchStress( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + sqlite3_pcache_page **ppPage /* Write result here */ +){ + PgHdr *pPg; + if( pCache->eCreate==2 ) return 0; + + if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){ + /* Find a dirty page to write-out and recycle. First try to find a + ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC + ** cleared), but if that is not possible settle for any other + ** unreferenced dirty page. + ** + ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC + ** flag is currently referenced, then the following may leave pSynced + ** set incorrectly (pointing to other than the LRU page with NEED_SYNC + ** cleared). This is Ok, as pSynced is just an optimization. */ + for(pPg=pCache->pSynced; + pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); + pPg=pPg->pDirtyPrev + ); + pCache->pSynced = pPg; + if( !pPg ){ + for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); + } + if( pPg ){ + int rc; +#ifdef SQLITE_LOG_CACHE_SPILL + sqlite3_log(SQLITE_FULL, + "spill page %d making room for %d - cache used: %d/%d", + pPg->pgno, pgno, + sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), + numberOfCachePages(pCache)); +#endif + pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); + rc = pCache->xStress(pCache->pStress, pPg); + pcacheDump(pCache); + if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ + return rc; + } + } + } + *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); + return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; +} + +/* +** This is a helper routine for sqlite3PcacheFetchFinish() +** +** In the uncommon case where the page being fetched has not been +** initialized, this routine is invoked to do the initialization. +** This routine is broken out into a separate function since it +** requires extra stack manipulation that can be avoided in the common +** case. +*/ +static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number obtained */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ +){ + PgHdr *pPgHdr; + assert( pPage!=0 ); + pPgHdr = (PgHdr*)pPage->pExtra; + assert( pPgHdr->pPage==0 ); + memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, 8); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; + pPgHdr->flags = PGHDR_CLEAN; + return sqlite3PcacheFetchFinish(pCache,pgno,pPage); +} + +/* +** This routine converts the sqlite3_pcache_page object returned by +** sqlite3PcacheFetch() into an initialized PgHdr object. This routine +** must be called after sqlite3PcacheFetch() in order to get a usable +** result. +*/ +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number obtained */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ +){ + PgHdr *pPgHdr; + + assert( pPage!=0 ); + pPgHdr = (PgHdr *)pPage->pExtra; + + if( !pPgHdr->pPage ){ + return pcacheFetchFinishWithInit(pCache, pgno, pPage); + } + pCache->nRefSum++; + pPgHdr->nRef++; + assert( sqlite3PcachePageSanity(pPgHdr) ); + return pPgHdr; +} + +/* +** Decrement the reference count on a page. If the page is clean and the +** reference count drops to 0, then it is made eligible for recycling. +*/ +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ + assert( p->nRef>0 ); + p->pCache->nRefSum--; + if( (--p->nRef)==0 ){ + if( p->flags&PGHDR_CLEAN ){ + pcacheUnpin(p); + }else{ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); + assert( sqlite3PcachePageSanity(p) ); + } + } +} + +/* +** Increase the reference count of a supplied page by 1. +*/ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){ + assert(p->nRef>0); + assert( sqlite3PcachePageSanity(p) ); + p->nRef++; + p->pCache->nRefSum++; +} + +/* +** Drop a page from the cache. There must be exactly one reference to the +** page. This function deletes that reference, so after it returns the +** page pointed to by p is invalid. +*/ +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ + assert( p->nRef==1 ); + assert( sqlite3PcachePageSanity(p) ); + if( p->flags&PGHDR_DIRTY ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + } + p->pCache->nRefSum--; + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); +} + +/* +** Make sure the page is marked as dirty. If it isn't dirty already, +** make it so. +*/ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ + assert( p->nRef>0 ); + assert( sqlite3PcachePageSanity(p) ); + if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ + p->flags &= ~PGHDR_DONT_WRITE; + if( p->flags & PGHDR_CLEAN ){ + p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); + pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); + assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); + assert( sqlite3PcachePageSanity(p) ); + } + assert( sqlite3PcachePageSanity(p) ); + } +} + +/* +** Make sure the page is marked as clean. If it isn't clean already, +** make it so. +*/ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ + assert( sqlite3PcachePageSanity(p) ); + assert( (p->flags & PGHDR_DIRTY)!=0 ); + assert( (p->flags & PGHDR_CLEAN)==0 ); + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); + p->flags |= PGHDR_CLEAN; + pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); + assert( sqlite3PcachePageSanity(p) ); + if( p->nRef==0 ){ + pcacheUnpin(p); + } +} + +/* +** Make every page in the cache clean. +*/ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){ + PgHdr *p; + pcacheTrace(("%p.CLEAN-ALL\n",pCache)); + while( (p = pCache->pDirty)!=0 ){ + sqlite3PcacheMakeClean(p); + } +} + +/* +** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages. +*/ +SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){ + PgHdr *p; + pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache)); + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE); + } + pCache->pSynced = pCache->pDirtyTail; +} + +/* +** Clear the PGHDR_NEED_SYNC flag from all dirty pages. +*/ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~PGHDR_NEED_SYNC; + } + pCache->pSynced = pCache->pDirtyTail; +} + +/* +** Change the page number of page p to newPgno. +*/ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ + PCache *pCache = p->pCache; + sqlite3_pcache_page *pOther; + assert( p->nRef>0 ); + assert( newPgno>0 ); + assert( sqlite3PcachePageSanity(p) ); + pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); + pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0); + if( pOther ){ + PgHdr *pXPage = (PgHdr*)pOther->pExtra; + assert( pXPage->nRef==0 ); + pXPage->nRef++; + pCache->nRefSum++; + sqlite3PcacheDrop(pXPage); + } + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); + p->pgno = newPgno; + if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); + assert( sqlite3PcachePageSanity(p) ); + } +} + +/* +** Drop every cache entry whose page number is greater than "pgno". The +** caller must ensure that there are no outstanding references to any pages +** other than page 1 with a page number greater than pgno. +** +** If there is a reference to page 1 and the pgno parameter passed to this +** function is 0, then the data area associated with page 1 is zeroed, but +** the page object is not dropped. +*/ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ + if( pCache->pCache ){ + PgHdr *p; + PgHdr *pNext; + pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno)); + for(p=pCache->pDirty; p; p=pNext){ + pNext = p->pDirtyNext; + /* This routine never gets call with a positive pgno except right + ** after sqlite3PcacheCleanAll(). So if there are dirty pages, + ** it must be that pgno==0. + */ + assert( p->pgno>0 ); + if( p->pgno>pgno ){ + assert( p->flags&PGHDR_DIRTY ); + sqlite3PcacheMakeClean(p); + } + } + if( pgno==0 && pCache->nRefSum ){ + sqlite3_pcache_page *pPage1; + pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0); + if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because + ** pCache->nRefSum>0 */ + memset(pPage1->pBuf, 0, pCache->szPage); + pgno = 1; + } + } + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); + } +} + +/* +** Close a cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ + assert( pCache->pCache!=0 ); + pcacheTrace(("%p.CLOSE\n",pCache)); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); +} + +/* +** Discard the contents of the cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){ + sqlite3PcacheTruncate(pCache, 0); +} + +/* +** Merge two lists of pages connected by pDirty and in pgno order. +** Do not bother fixing the pDirtyPrev pointers. +*/ +static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ + PgHdr result, *pTail; + pTail = &result; + assert( pA!=0 && pB!=0 ); + for(;;){ + if( pA->pgnopgno ){ + pTail->pDirty = pA; + pTail = pA; + pA = pA->pDirty; + if( pA==0 ){ + pTail->pDirty = pB; + break; + } + }else{ + pTail->pDirty = pB; + pTail = pB; + pB = pB->pDirty; + if( pB==0 ){ + pTail->pDirty = pA; + break; + } + } + } + return result.pDirty; +} + +/* +** Sort the list of pages in ascending order by pgno. Pages are +** connected by pDirty pointers. The pDirtyPrev pointers are +** corrupted by this sort. +** +** Since there cannot be more than 2^31 distinct pages in a database, +** there cannot be more than 31 buckets required by the merge sorter. +** One extra bucket is added to catch overflow in case something +** ever changes to make the previous sentence incorrect. +*/ +#define N_SORT_BUCKET 32 +static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ + PgHdr *a[N_SORT_BUCKET], *p; + int i; + memset(a, 0, sizeof(a)); + while( pIn ){ + p = pIn; + pIn = p->pDirty; + p->pDirty = 0; + for(i=0; ALWAYS(ipDirty; p; p=p->pDirtyNext){ + p->pDirty = p->pDirtyNext; + } + return pcacheSortDirtyList(pCache->pDirty); +} + +/* +** Return the total number of references to all pages held by the cache. +** +** This is not the total number of pages referenced, but the sum of the +** reference count for all pages. +*/ +SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache *pCache){ + return pCache->nRefSum; +} + +/* +** Return the number of references to the page supplied as an argument. +*/ +SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr *p){ + return p->nRef; +} + +/* +** Return the total number of pages in the cache. +*/ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ + assert( pCache->pCache!=0 ); + return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); +} + +#ifdef SQLITE_TEST +/* +** Get the suggested cache-size value. +*/ +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){ + return numberOfCachePages(pCache); +} +#endif + +/* +** Set the suggested cache-size value. +*/ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ + assert( pCache->pCache!=0 ); + pCache->szCache = mxPage; + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); +} + +/* +** Set the suggested cache-spill value. Make no changes if if the +** argument is zero. Return the effective cache-spill size, which will +** be the larger of the szSpill and szCache. +*/ +SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){ + int res; + assert( p->pCache!=0 ); + if( mxPage ){ + if( mxPage<0 ){ + mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra)); + } + p->szSpill = mxPage; + } + res = numberOfCachePages(p); + if( resszSpill ) res = p->szSpill; + return res; +} + +/* +** Free up as much memory as possible from the page cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){ + assert( pCache->pCache!=0 ); + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); +} + +/* +** Return the size of the header added by this middleware layer +** in the page-cache hierarchy. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } + +/* +** Return the number of dirty pages currently in the cache, as a percentage +** of the configured cache size. +*/ +SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){ + PgHdr *pDirty; + int nDirty = 0; + int nCache = numberOfCachePages(pCache); + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++; + return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; +} + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +/* +** Return true if there are one or more dirty pages in the cache. Else false. +*/ +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){ + return (pCache->pDirty!=0); +} +#endif + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* +** For all dirty pages currently in the cache, invoke the specified +** callback. This is only used if the SQLITE_CHECK_PAGES macro is +** defined. +*/ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ + PgHdr *pDirty; + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ + xIter(pDirty); + } +} +#endif + +/************** End of pcache.c **********************************************/ +/************** Begin file pcache1.c *****************************************/ +/* +** 2008 November 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements the default page cache implementation (the +** sqlite3_pcache interface). It also contains part of the implementation +** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. +** If the default page cache implementation is overridden, then neither of +** these two features are available. +** +** A Page cache line looks like this: +** +** ------------------------------------------------------------- +** | database page content | PgHdr1 | MemPage | PgHdr | +** ------------------------------------------------------------- +** +** The database page content is up front (so that buffer overreads tend to +** flow harmlessly into the PgHdr1, MemPage, and PgHdr extensions). MemPage +** is the extension added by the btree.c module containing information such +** as the database page number and how that database page is used. PgHdr +** is added by the pcache.c layer and contains information used to keep track +** of which pages are "dirty". PgHdr1 is an extension added by this +** module (pcache1.c). The PgHdr1 header is a subclass of sqlite3_pcache_page. +** PgHdr1 contains information needed to look up a page by its page number. +** The superclass sqlite3_pcache_page.pBuf points to the start of the +** database page content and sqlite3_pcache_page.pExtra points to PgHdr. +** +** The size of the extension (MemPage+PgHdr+PgHdr1) can be determined at +** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The +** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this +** size can vary according to architecture, compile-time options, and +** SQLite library version number. +** +** Historical note: It used to be that if the SQLITE_PCACHE_SEPARATE_HEADER +** was defined, then the page content would be held in a separate memory +** allocation from the PgHdr1. This was intended to avoid clownshoe memory +** allocations. However, the btree layer needs a small (16-byte) overrun +** area after the page content buffer. The header serves as that overrun +** area. Therefore SQLITE_PCACHE_SEPARATE_HEADER was discontinued to avoid +** any possibility of a memory error. +** +** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates +** with this module. Information is passed back and forth as PgHdr1 pointers. +** +** The pcache.c and pager.c modules deal pointers to PgHdr objects. +** The btree.c module deals with pointers to MemPage objects. +** +** SOURCE OF PAGE CACHE MEMORY: +** +** Memory for a page might come from any of three sources: +** +** (1) The general-purpose memory allocator - sqlite3Malloc() +** (2) Global page-cache memory provided using sqlite3_config() with +** SQLITE_CONFIG_PAGECACHE. +** (3) PCache-local bulk allocation. +** +** The third case is a chunk of heap memory (defaulting to 100 pages worth) +** that is allocated when the page cache is created. The size of the local +** bulk allocation can be adjusted using +** +** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). +** +** If N is positive, then N pages worth of memory are allocated using a single +** sqlite3Malloc() call and that memory is used for the first N pages allocated. +** Or if N is negative, then -1024*N bytes of memory are allocated and used +** for as many pages as can be accommodated. +** +** Only one of (2) or (3) can be used. Once the memory available to (2) or +** (3) is exhausted, subsequent allocations fail over to the general-purpose +** memory allocator (1). +** +** Earlier versions of SQLite used only methods (1) and (2). But experiments +** show that method (3) with N==100 provides about a 5% performance boost for +** common workloads. +*/ +/* #include "sqliteInt.h" */ + +typedef struct PCache1 PCache1; +typedef struct PgHdr1 PgHdr1; +typedef struct PgFreeslot PgFreeslot; +typedef struct PGroup PGroup; + +/* +** Each cache entry is represented by an instance of the following +** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated +** directly before this structure and is used to cache the page content. +** +** When reading a corrupt database file, it is possible that SQLite might +** read a few bytes (no more than 16 bytes) past the end of the page buffer. +** It will only read past the end of the page buffer, never write. This +** object is positioned immediately after the page buffer to serve as an +** overrun area, so that overreads are harmless. +** +** Variables isBulkLocal and isAnchor were once type "u8". That works, +** but causes a 2-byte gap in the structure for most architectures (since +** pointers must be either 4 or 8-byte aligned). As this structure is located +** in memory directly after the associated page data, if the database is +** corrupt, code at the b-tree layer may overread the page buffer and +** read part of this structure before the corruption is detected. This +** can cause a valgrind error if the uninitialized gap is accessed. Using u16 +** ensures there is no such gap, and therefore no bytes of uninitialized +** memory in the structure. +** +** The pLruNext and pLruPrev pointers form a double-linked circular list +** of all pages that are unpinned. The PGroup.lru element (which should be +** the only element on the list with PgHdr1.isAnchor set to 1) forms the +** beginning and the end of the list. +*/ +struct PgHdr1 { + sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ + unsigned int iKey; /* Key value (page number) */ + u16 isBulkLocal; /* This page from bulk local storage */ + u16 isAnchor; /* This is the PGroup.lru element */ + PgHdr1 *pNext; /* Next in hash table chain */ + PCache1 *pCache; /* Cache that currently owns this page */ + PgHdr1 *pLruNext; /* Next in circular LRU list of unpinned pages */ + PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ + /* NB: pLruPrev is only valid if pLruNext!=0 */ +}; + +/* +** A page is pinned if it is not on the LRU list. To be "pinned" means +** that the page is in active use and must not be deallocated. +*/ +#define PAGE_IS_PINNED(p) ((p)->pLruNext==0) +#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0) + +/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set +** of one or more PCaches that are able to recycle each other's unpinned +** pages when they are under memory pressure. A PGroup is an instance of +** the following object. +** +** This page cache implementation works in one of two modes: +** +** (1) Every PCache is the sole member of its own PGroup. There is +** one PGroup per PCache. +** +** (2) There is a single global PGroup that all PCaches are a member +** of. +** +** Mode 1 uses more memory (since PCache instances are not able to rob +** unused pages from other PCaches) but it also operates without a mutex, +** and is therefore often faster. Mode 2 requires a mutex in order to be +** threadsafe, but recycles pages more efficiently. +** +** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single +** PGroup which is the pcache1.grp global variable and its mutex is +** SQLITE_MUTEX_STATIC_LRU. +*/ +struct PGroup { + sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ + unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ + unsigned int nMinPage; /* Sum of nMin for purgeable caches */ + unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ + unsigned int nPurgeable; /* Number of purgeable pages allocated */ + PgHdr1 lru; /* The beginning and end of the LRU list */ +}; + +/* Each page cache is an instance of the following object. Every +** open database file (including each in-memory database and each +** temporary or transient database) has a single page cache which +** is an instance of this object. +** +** Pointers to structures of this type are cast and returned as +** opaque sqlite3_pcache* handles. +*/ +struct PCache1 { + /* Cache configuration parameters. Page size (szPage) and the purgeable + ** flag (bPurgeable) and the pnPurgeable pointer are all set when the + ** cache is created and are never changed thereafter. nMax may be + ** modified at any time by a call to the pcache1Cachesize() method. + ** The PGroup mutex must be held when accessing nMax. + */ + PGroup *pGroup; /* PGroup this cache belongs to */ + unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */ + int szPage; /* Size of database content section */ + int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */ + int szAlloc; /* Total size of one pcache line */ + int bPurgeable; /* True if cache is purgeable */ + unsigned int nMin; /* Minimum number of pages reserved */ + unsigned int nMax; /* Configured "cache_size" value */ + unsigned int n90pct; /* nMax*9/10 */ + unsigned int iMaxKey; /* Largest key seen since xTruncate() */ + unsigned int nPurgeableDummy; /* pnPurgeable points here when not used*/ + + /* Hash table of all pages. The following variables may only be accessed + ** when the accessor is holding the PGroup mutex. + */ + unsigned int nRecyclable; /* Number of pages in the LRU list */ + unsigned int nPage; /* Total number of pages in apHash */ + unsigned int nHash; /* Number of slots in apHash[] */ + PgHdr1 **apHash; /* Hash table for fast lookup by key */ + PgHdr1 *pFree; /* List of unused pcache-local pages */ + void *pBulk; /* Bulk memory used by pcache-local */ +}; + +/* +** Free slots in the allocator used to divide up the global page cache +** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism. +*/ +struct PgFreeslot { + PgFreeslot *pNext; /* Next free slot */ +}; + +/* +** Global data used by this cache. +*/ +static SQLITE_WSD struct PCacheGlobal { + PGroup grp; /* The global PGroup for mode (2) */ + + /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The + ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all + ** fixed at sqlite3_initialize() time and do not require mutex protection. + ** The nFreeSlot and pFree values do require mutex protection. + */ + int isInit; /* True if initialized */ + int separateCache; /* Use a new PGroup for each PCache */ + int nInitPage; /* Initial bulk allocation size */ + int szSlot; /* Size of each free slot */ + int nSlot; /* The number of pcache slots */ + int nReserve; /* Try to keep nFreeSlot above this */ + void *pStart, *pEnd; /* Bounds of global page cache memory */ + /* Above requires no mutex. Use mutex below for variable that follow. */ + sqlite3_mutex *mutex; /* Mutex for accessing the following: */ + PgFreeslot *pFree; /* Free page blocks */ + int nFreeSlot; /* Number of unused pcache slots */ + /* The following value requires a mutex to change. We skip the mutex on + ** reading because (1) most platforms read a 32-bit integer atomically and + ** (2) even if an incorrect value is read, no great harm is done since this + ** is really just an optimization. */ + int bUnderPressure; /* True if low on PAGECACHE memory */ +} pcache1_g; + +/* +** All code in this file should access the global structure above via the +** alias "pcache1". This ensures that the WSD emulation is used when +** compiling for systems that do not support real WSD. +*/ +#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) + +/* +** Macros to enter and leave the PCache LRU mutex. +*/ +#if !defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 +# define pcache1EnterMutex(X) assert((X)->mutex==0) +# define pcache1LeaveMutex(X) assert((X)->mutex==0) +# define PCACHE1_MIGHT_USE_GROUP_MUTEX 0 +#else +# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) +# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) +# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1 +#endif + +/******************************************************************************/ +/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ + + +/* +** This function is called during initialization if a static buffer is +** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE +** verb to sqlite3_config(). Parameter pBuf points to an allocation large +** enough to contain 'n' buffers of 'sz' bytes each. +** +** This routine is called from sqlite3_initialize() and so it is guaranteed +** to be serialized already. There is no need for further mutexing. +*/ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ + if( pcache1.isInit ){ + PgFreeslot *p; + if( pBuf==0 ) sz = n = 0; + if( n==0 ) sz = 0; + sz = ROUNDDOWN8(sz); + pcache1.szSlot = sz; + pcache1.nSlot = pcache1.nFreeSlot = n; + pcache1.nReserve = n>90 ? 10 : (n/10 + 1); + pcache1.pStart = pBuf; + pcache1.pFree = 0; + pcache1.bUnderPressure = 0; + while( n-- ){ + p = (PgFreeslot*)pBuf; + p->pNext = pcache1.pFree; + pcache1.pFree = p; + pBuf = (void*)&((char*)pBuf)[sz]; + } + pcache1.pEnd = pBuf; + } +} + +/* +** Try to initialize the pCache->pFree and pCache->pBulk fields. Return +** true if pCache->pFree ends up containing one or more free pages. +*/ +static int pcache1InitBulk(PCache1 *pCache){ + i64 szBulk; + char *zBulk; + if( pcache1.nInitPage==0 ) return 0; + /* Do not bother with a bulk allocation if the cache size very small */ + if( pCache->nMax<3 ) return 0; + sqlite3BeginBenignMalloc(); + if( pcache1.nInitPage>0 ){ + szBulk = pCache->szAlloc * (i64)pcache1.nInitPage; + }else{ + szBulk = -1024 * (i64)pcache1.nInitPage; + } + if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ + szBulk = pCache->szAlloc*(i64)pCache->nMax; + } + zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); + sqlite3EndBenignMalloc(); + if( zBulk ){ + int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; + do{ + PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; + pX->page.pBuf = zBulk; + pX->page.pExtra = &pX[1]; + pX->isBulkLocal = 1; + pX->isAnchor = 0; + pX->pNext = pCache->pFree; + pX->pLruPrev = 0; /* Initializing this saves a valgrind error */ + pCache->pFree = pX; + zBulk += pCache->szAlloc; + }while( --nBulk ); + } + return pCache->pFree!=0; +} + +/* +** Malloc function used within this file to allocate space from the buffer +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** such buffer exists or there is no space left in it, this function falls +** back to sqlite3Malloc(). +** +** Multiple threads can run this routine at the same time. Global variables +** in pcache1 need to be protected via mutex. +*/ +static void *pcache1Alloc(int nByte){ + void *p = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + if( nByte<=pcache1.szSlot ){ + sqlite3_mutex_enter(pcache1.mutex); + p = (PgHdr1 *)pcache1.pFree; + if( p ){ + pcache1.pFree = pcache1.pFree->pNext; + pcache1.nFreeSlot--; + pcache1.bUnderPressure = pcache1.nFreeSlot=0 ); + sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); + } + sqlite3_mutex_leave(pcache1.mutex); + } + if( p==0 ){ + /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get + ** it from sqlite3Malloc instead. + */ + p = sqlite3Malloc(nByte); +#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + if( p ){ + int sz = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); + } +#endif + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); + } + return p; +} + +/* +** Free an allocated buffer obtained from pcache1Alloc(). +*/ +static void pcache1Free(void *p){ + if( p==0 ) return; + if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){ + PgFreeslot *pSlot; + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); + pSlot = (PgFreeslot*)p; + pSlot->pNext = pcache1.pFree; + pcache1.pFree = pSlot; + pcache1.nFreeSlot++; + pcache1.bUnderPressure = pcache1.nFreeSlot=pcache1.pStart && ppGroup->mutex) ); + if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ + assert( pCache->pFree!=0 ); + p = pCache->pFree; + pCache->pFree = p->pNext; + p->pNext = 0; + }else{ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + /* The group mutex must be released before pcache1Alloc() is called. This + ** is because it might call sqlite3_release_memory(), which assumes that + ** this mutex is not held. */ + assert( pcache1.separateCache==0 ); + assert( pCache->pGroup==&pcache1.grp ); + pcache1LeaveMutex(pCache->pGroup); +#endif + if( benignMalloc ){ sqlite3BeginBenignMalloc(); } + pPg = pcache1Alloc(pCache->szAlloc); + if( benignMalloc ){ sqlite3EndBenignMalloc(); } +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + pcache1EnterMutex(pCache->pGroup); +#endif + if( pPg==0 ) return 0; + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; + p->page.pBuf = pPg; + p->page.pExtra = &p[1]; + p->isBulkLocal = 0; + p->isAnchor = 0; + p->pLruPrev = 0; /* Initializing this saves a valgrind error */ + } + (*pCache->pnPurgeable)++; + return p; +} + +/* +** Free a page object allocated by pcache1AllocPage(). +*/ +static void pcache1FreePage(PgHdr1 *p){ + PCache1 *pCache; + assert( p!=0 ); + pCache = p->pCache; + assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); + if( p->isBulkLocal ){ + p->pNext = pCache->pFree; + pCache->pFree = p; + }else{ + pcache1Free(p->page.pBuf); + } + (*pCache->pnPurgeable)--; +} + +/* +** Malloc function used by SQLite to obtain space from the buffer configured +** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer +** exists, this function falls back to sqlite3Malloc(). +*/ +SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ + assert( sz<=65536+8 ); /* These allocations are never very large */ + return pcache1Alloc(sz); +} + +/* +** Free an allocated buffer obtained from sqlite3PageMalloc(). +*/ +SQLITE_PRIVATE void sqlite3PageFree(void *p){ + pcache1Free(p); +} + + +/* +** Return true if it desirable to avoid allocating a new page cache +** entry. +** +** If memory was allocated specifically to the page cache using +** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then +** it is desirable to avoid allocating a new page cache entry because +** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient +** for all page cache needs and we should not need to spill the +** allocation onto the heap. +** +** Or, the heap is used for all page cache memory but the heap is +** under memory pressure, then again it is desirable to avoid +** allocating a new page cache entry in order to avoid stressing +** the heap even further. +*/ +static int pcache1UnderMemoryPressure(PCache1 *pCache){ + if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ + return pcache1.bUnderPressure; + }else{ + return sqlite3HeapNearlyFull(); + } +} + +/******************************************************************************/ +/******** General Implementation Functions ************************************/ + +/* +** This function is used to resize the hash table used by the cache passed +** as the first argument. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1ResizeHash(PCache1 *p){ + PgHdr1 **apNew; + unsigned int nNew; + unsigned int i; + + assert( sqlite3_mutex_held(p->pGroup->mutex) ); + + nNew = p->nHash*2; + if( nNew<256 ){ + nNew = 256; + } + + pcache1LeaveMutex(p->pGroup); + if( p->nHash ){ sqlite3BeginBenignMalloc(); } + apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); + if( p->nHash ){ sqlite3EndBenignMalloc(); } + pcache1EnterMutex(p->pGroup); + if( apNew ){ + for(i=0; inHash; i++){ + PgHdr1 *pPage; + PgHdr1 *pNext = p->apHash[i]; + while( (pPage = pNext)!=0 ){ + unsigned int h = pPage->iKey % nNew; + pNext = pPage->pNext; + pPage->pNext = apNew[h]; + apNew[h] = pPage; + } + } + sqlite3_free(p->apHash); + p->apHash = apNew; + p->nHash = nNew; + } +} + +/* +** This function is used internally to remove the page pPage from the +** PGroup LRU list, if is part of it. If pPage is not part of the PGroup +** LRU list, then this function is a no-op. +** +** The PGroup mutex must be held when this function is called. +*/ +static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ + assert( pPage!=0 ); + assert( PAGE_IS_UNPINNED(pPage) ); + assert( pPage->pLruNext ); + assert( pPage->pLruPrev ); + assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) ); + pPage->pLruPrev->pLruNext = pPage->pLruNext; + pPage->pLruNext->pLruPrev = pPage->pLruPrev; + pPage->pLruNext = 0; + /* pPage->pLruPrev = 0; + ** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */ + assert( pPage->isAnchor==0 ); + assert( pPage->pCache->pGroup->lru.isAnchor==1 ); + pPage->pCache->nRecyclable--; + return pPage; +} + + +/* +** Remove the page supplied as an argument from the hash table +** (PCache1.apHash structure) that it is currently stored in. +** Also free the page if freePage is true. +** +** The PGroup mutex must be held when this function is called. +*/ +static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){ + unsigned int h; + PCache1 *pCache = pPage->pCache; + PgHdr1 **pp; + + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + h = pPage->iKey % pCache->nHash; + for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); + *pp = (*pp)->pNext; + + pCache->nPage--; + if( freeFlag ) pcache1FreePage(pPage); +} + +/* +** If there are currently more than nMaxPage pages allocated, try +** to recycle pages to reduce the number allocated to nMaxPage. +*/ +static void pcache1EnforceMaxPage(PCache1 *pCache){ + PGroup *pGroup = pCache->pGroup; + PgHdr1 *p; + assert( sqlite3_mutex_held(pGroup->mutex) ); + while( pGroup->nPurgeable>pGroup->nMaxPage + && (p=pGroup->lru.pLruPrev)->isAnchor==0 + ){ + assert( p->pCache->pGroup==pGroup ); + assert( PAGE_IS_UNPINNED(p) ); + pcache1PinPage(p); + pcache1RemoveFromHash(p, 1); + } + if( pCache->nPage==0 && pCache->pBulk ){ + sqlite3_free(pCache->pBulk); + pCache->pBulk = pCache->pFree = 0; + } +} + +/* +** Discard all pages from cache pCache with a page number (key value) +** greater than or equal to iLimit. Any pinned pages that meet this +** criteria are unpinned before they are discarded. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1TruncateUnsafe( + PCache1 *pCache, /* The cache to truncate */ + unsigned int iLimit /* Drop pages with this pgno or larger */ +){ + TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */ + unsigned int h, iStop; + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + assert( pCache->iMaxKey >= iLimit ); + assert( pCache->nHash > 0 ); + if( pCache->iMaxKey - iLimit < pCache->nHash ){ + /* If we are just shaving the last few pages off the end of the + ** cache, then there is no point in scanning the entire hash table. + ** Only scan those hash slots that might contain pages that need to + ** be removed. */ + h = iLimit % pCache->nHash; + iStop = pCache->iMaxKey % pCache->nHash; + TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ + }else{ + /* This is the general case where many pages are being removed. + ** It is necessary to scan the entire hash table */ + h = pCache->nHash/2; + iStop = h - 1; + } + for(;;){ + PgHdr1 **pp; + PgHdr1 *pPage; + assert( hnHash ); + pp = &pCache->apHash[h]; + while( (pPage = *pp)!=0 ){ + if( pPage->iKey>=iLimit ){ + pCache->nPage--; + *pp = pPage->pNext; + if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage); + pcache1FreePage(pPage); + }else{ + pp = &pPage->pNext; + TESTONLY( if( nPage>=0 ) nPage++; ) + } + } + if( h==iStop ) break; + h = (h+1) % pCache->nHash; + } + assert( nPage<0 || pCache->nPage==(unsigned)nPage ); +} + +/******************************************************************************/ +/******** sqlite3_pcache Methods **********************************************/ + +/* +** Implementation of the sqlite3_pcache.xInit method. +*/ +static int pcache1Init(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit==0 ); + memset(&pcache1, 0, sizeof(pcache1)); + + + /* + ** The pcache1.separateCache variable is true if each PCache has its own + ** private PGroup (mode-1). pcache1.separateCache is false if the single + ** PGroup in pcache1.grp is used for all page caches (mode-2). + ** + ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT + ** + ** * Use a unified cache in single-threaded applications that have + ** configured a start-time buffer for use as page-cache memory using + ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL + ** pBuf argument. + ** + ** * Otherwise use separate caches (mode-1) + */ +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) + pcache1.separateCache = 0; +#elif SQLITE_THREADSAFE + pcache1.separateCache = sqlite3GlobalConfig.pPage==0 + || sqlite3GlobalConfig.bCoreMutex>0; +#else + pcache1.separateCache = sqlite3GlobalConfig.pPage==0; +#endif + +#if SQLITE_THREADSAFE + if( sqlite3GlobalConfig.bCoreMutex ){ + pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); + } +#endif + if( pcache1.separateCache + && sqlite3GlobalConfig.nPage!=0 + && sqlite3GlobalConfig.pPage==0 + ){ + pcache1.nInitPage = sqlite3GlobalConfig.nPage; + }else{ + pcache1.nInitPage = 0; + } + pcache1.grp.mxPinned = 10; + pcache1.isInit = 1; + return SQLITE_OK; +} + +/* +** Implementation of the sqlite3_pcache.xShutdown method. +** Note that the static mutex allocated in xInit does +** not need to be freed. +*/ +static void pcache1Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit!=0 ); + memset(&pcache1, 0, sizeof(pcache1)); +} + +/* forward declaration */ +static void pcache1Destroy(sqlite3_pcache *p); + +/* +** Implementation of the sqlite3_pcache.xCreate method. +** +** Allocate a new cache. +*/ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ + PCache1 *pCache; /* The newly created page cache */ + PGroup *pGroup; /* The group the new page cache will belong to */ + int sz; /* Bytes of memory required to allocate the new cache */ + + assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); + assert( szExtra < 300 ); + + sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache; + pCache = (PCache1 *)sqlite3MallocZero(sz); + if( pCache ){ + if( pcache1.separateCache ){ + pGroup = (PGroup*)&pCache[1]; + pGroup->mxPinned = 10; + }else{ + pGroup = &pcache1.grp; + } + pcache1EnterMutex(pGroup); + if( pGroup->lru.isAnchor==0 ){ + pGroup->lru.isAnchor = 1; + pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru; + } + pCache->pGroup = pGroup; + pCache->szPage = szPage; + pCache->szExtra = szExtra; + pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1)); + pCache->bPurgeable = (bPurgeable ? 1 : 0); + pcache1ResizeHash(pCache); + if( bPurgeable ){ + pCache->nMin = 10; + pGroup->nMinPage += pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->pnPurgeable = &pGroup->nPurgeable; + }else{ + pCache->pnPurgeable = &pCache->nPurgeableDummy; + } + pcache1LeaveMutex(pGroup); + if( pCache->nHash==0 ){ + pcache1Destroy((sqlite3_pcache*)pCache); + pCache = 0; + } + } + return (sqlite3_pcache *)pCache; +} + +/* +** Implementation of the sqlite3_pcache.xCachesize method. +** +** Configure the cache_size limit for a cache. +*/ +static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ + PCache1 *pCache = (PCache1 *)p; + u32 n; + assert( nMax>=0 ); + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + pcache1EnterMutex(pGroup); + n = (u32)nMax; + if( n > 0x7fff0000 - pGroup->nMaxPage + pCache->nMax ){ + n = 0x7fff0000 - pGroup->nMaxPage + pCache->nMax; + } + pGroup->nMaxPage += (n - pCache->nMax); + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->nMax = n; + pCache->n90pct = pCache->nMax*9/10; + pcache1EnforceMaxPage(pCache); + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xShrink method. +** +** Free up as much memory as possible. +*/ +static void pcache1Shrink(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1*)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + unsigned int savedMaxPage; + pcache1EnterMutex(pGroup); + savedMaxPage = pGroup->nMaxPage; + pGroup->nMaxPage = 0; + pcache1EnforceMaxPage(pCache); + pGroup->nMaxPage = savedMaxPage; + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xPagecount method. +*/ +static int pcache1Pagecount(sqlite3_pcache *p){ + int n; + PCache1 *pCache = (PCache1*)p; + pcache1EnterMutex(pCache->pGroup); + n = pCache->nPage; + pcache1LeaveMutex(pCache->pGroup); + return n; +} + + +/* +** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described +** in the header of the pcache1Fetch() procedure. +** +** This steps are broken out into a separate procedure because they are +** usually not needed, and by avoiding the stack initialization required +** for these steps, the main pcache1Fetch() procedure can run faster. +*/ +static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( + PCache1 *pCache, + unsigned int iKey, + int createFlag +){ + unsigned int nPinned; + PGroup *pGroup = pCache->pGroup; + PgHdr1 *pPage = 0; + + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ + assert( pCache->nPage >= pCache->nRecyclable ); + nPinned = pCache->nPage - pCache->nRecyclable; + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); + assert( pCache->n90pct == pCache->nMax*9/10 ); + if( createFlag==1 && ( + nPinned>=pGroup->mxPinned + || nPinned>=pCache->n90pct + || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclablenPage>=pCache->nHash ) pcache1ResizeHash(pCache); + assert( pCache->nHash>0 && pCache->apHash ); + + /* Step 4. Try to recycle a page. */ + if( pCache->bPurgeable + && !pGroup->lru.pLruPrev->isAnchor + && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache)) + ){ + PCache1 *pOther; + pPage = pGroup->lru.pLruPrev; + assert( PAGE_IS_UNPINNED(pPage) ); + pcache1RemoveFromHash(pPage, 0); + pcache1PinPage(pPage); + pOther = pPage->pCache; + if( pOther->szAlloc != pCache->szAlloc ){ + pcache1FreePage(pPage); + pPage = 0; + }else{ + pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable); + } + } + + /* Step 5. If a usable page buffer has still not been found, + ** attempt to allocate a new one. + */ + if( !pPage ){ + pPage = pcache1AllocPage(pCache, createFlag==1); + } + + if( pPage ){ + unsigned int h = iKey % pCache->nHash; + pCache->nPage++; + pPage->iKey = iKey; + pPage->pNext = pCache->apHash[h]; + pPage->pCache = pCache; + pPage->pLruNext = 0; + /* pPage->pLruPrev = 0; + ** No need to clear pLruPrev since it is not accessed when pLruNext==0 */ + *(void **)pPage->page.pExtra = 0; + pCache->apHash[h] = pPage; + if( iKey>pCache->iMaxKey ){ + pCache->iMaxKey = iKey; + } + } + return pPage; +} + +/* +** Implementation of the sqlite3_pcache.xFetch method. +** +** Fetch a page by key value. +** +** Whether or not a new page may be allocated by this function depends on +** the value of the createFlag argument. 0 means do not allocate a new +** page. 1 means allocate a new page if space is easily available. 2 +** means to try really hard to allocate a new page. +** +** For a non-purgeable cache (a cache used as the storage for an in-memory +** database) there is really no difference between createFlag 1 and 2. So +** the calling function (pcache.c) will never have a createFlag of 1 on +** a non-purgeable cache. +** +** There are three different approaches to obtaining space for a page, +** depending on the value of parameter createFlag (which may be 0, 1 or 2). +** +** 1. Regardless of the value of createFlag, the cache is searched for a +** copy of the requested page. If one is found, it is returned. +** +** 2. If createFlag==0 and the page is not already in the cache, NULL is +** returned. +** +** 3. If createFlag is 1, and the page is not already in the cache, then +** return NULL (do not allocate a new page) if any of the following +** conditions are true: +** +** (a) the number of pages pinned by the cache is greater than +** PCache1.nMax, or +** +** (b) the number of pages pinned by the cache is greater than +** the sum of nMax for all purgeable caches, less the sum of +** nMin for all other purgeable caches, or +** +** 4. If none of the first three conditions apply and the cache is marked +** as purgeable, and if one of the following is true: +** +** (a) The number of pages allocated for the cache is already +** PCache1.nMax, or +** +** (b) The number of pages allocated for all purgeable caches is +** already equal to or greater than the sum of nMax for all +** purgeable caches, +** +** (c) The system is under memory pressure and wants to avoid +** unnecessary pages cache entry allocations +** +** then attempt to recycle a page from the LRU list. If it is the right +** size, return the recycled buffer. Otherwise, free the buffer and +** proceed to step 5. +** +** 5. Otherwise, allocate and return a new page buffer. +** +** There are two versions of this routine. pcache1FetchWithMutex() is +** the general case. pcache1FetchNoMutex() is a faster implementation for +** the common case where pGroup->mutex is NULL. The pcache1Fetch() wrapper +** invokes the appropriate routine. +*/ +static PgHdr1 *pcache1FetchNoMutex( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = 0; + + /* Step 1: Search the hash table for an existing entry. */ + pPage = pCache->apHash[iKey % pCache->nHash]; + while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } + + /* Step 2: If the page was found in the hash table, then return it. + ** If the page was not in the hash table and createFlag is 0, abort. + ** Otherwise (page not in hash and createFlag!=0) continue with + ** subsequent steps to try to create the page. */ + if( pPage ){ + if( PAGE_IS_UNPINNED(pPage) ){ + return pcache1PinPage(pPage); + }else{ + return pPage; + } + }else if( createFlag ){ + /* Steps 3, 4, and 5 implemented by this subroutine */ + return pcache1FetchStage2(pCache, iKey, createFlag); + }else{ + return 0; + } +} +#if PCACHE1_MIGHT_USE_GROUP_MUTEX +static PgHdr1 *pcache1FetchWithMutex( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage; + + pcache1EnterMutex(pCache->pGroup); + pPage = pcache1FetchNoMutex(p, iKey, createFlag); + assert( pPage==0 || pCache->iMaxKey>=iKey ); + pcache1LeaveMutex(pCache->pGroup); + return pPage; +} +#endif +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ +#if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG) + PCache1 *pCache = (PCache1 *)p; +#endif + + assert( offsetof(PgHdr1,page)==0 ); + assert( pCache->bPurgeable || createFlag!=1 ); + assert( pCache->bPurgeable || pCache->nMin==0 ); + assert( pCache->bPurgeable==0 || pCache->nMin==10 ); + assert( pCache->nMin==0 || pCache->bPurgeable ); + assert( pCache->nHash>0 ); +#if PCACHE1_MIGHT_USE_GROUP_MUTEX + if( pCache->pGroup->mutex ){ + return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag); + }else +#endif + { + return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag); + } +} + + +/* +** Implementation of the sqlite3_pcache.xUnpin method. +** +** Mark a page as unpinned (eligible for asynchronous recycling). +*/ +static void pcache1Unpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int reuseUnlikely +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PGroup *pGroup = pCache->pGroup; + + assert( pPage->pCache==pCache ); + pcache1EnterMutex(pGroup); + + /* It is an error to call this function if the page is already + ** part of the PGroup LRU list. + */ + assert( pPage->pLruNext==0 ); + assert( PAGE_IS_PINNED(pPage) ); + + if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ + pcache1RemoveFromHash(pPage, 1); + }else{ + /* Add the page to the PGroup LRU list. */ + PgHdr1 **ppFirst = &pGroup->lru.pLruNext; + pPage->pLruPrev = &pGroup->lru; + (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; + *ppFirst = pPage; + pCache->nRecyclable++; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xRekey method. +*/ +static void pcache1Rekey( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + unsigned int iOld, + unsigned int iNew +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PgHdr1 **pp; + unsigned int hOld, hNew; + assert( pPage->iKey==iOld ); + assert( pPage->pCache==pCache ); + assert( iOld!=iNew ); /* The page number really is changing */ + + pcache1EnterMutex(pCache->pGroup); + + assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ + hOld = iOld%pCache->nHash; + pp = &pCache->apHash[hOld]; + while( (*pp)!=pPage ){ + pp = &(*pp)->pNext; + } + *pp = pPage->pNext; + + assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ + hNew = iNew%pCache->nHash; + pPage->iKey = iNew; + pPage->pNext = pCache->apHash[hNew]; + pCache->apHash[hNew] = pPage; + if( iNew>pCache->iMaxKey ){ + pCache->iMaxKey = iNew; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xTruncate method. +** +** Discard all unpinned pages in the cache with a page number equal to +** or greater than parameter iLimit. Any pinned pages with a page number +** equal to or greater than iLimit are implicitly unpinned. +*/ +static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ + PCache1 *pCache = (PCache1 *)p; + pcache1EnterMutex(pCache->pGroup); + if( iLimit<=pCache->iMaxKey ){ + pcache1TruncateUnsafe(pCache, iLimit); + pCache->iMaxKey = iLimit-1; + } + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xDestroy method. +** +** Destroy a cache allocated using pcache1Create(). +*/ +static void pcache1Destroy(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1 *)p; + PGroup *pGroup = pCache->pGroup; + assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); + pcache1EnterMutex(pGroup); + if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0); + assert( pGroup->nMaxPage >= pCache->nMax ); + pGroup->nMaxPage -= pCache->nMax; + assert( pGroup->nMinPage >= pCache->nMin ); + pGroup->nMinPage -= pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1EnforceMaxPage(pCache); + pcache1LeaveMutex(pGroup); + sqlite3_free(pCache->pBulk); + sqlite3_free(pCache->apHash); + sqlite3_free(pCache); +} + +/* +** This function is called during initialization (sqlite3_initialize()) to +** install the default pluggable cache module, assuming the user has not +** already provided an alternative. +*/ +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ + static const sqlite3_pcache_methods2 defaultMethods = { + 1, /* iVersion */ + 0, /* pArg */ + pcache1Init, /* xInit */ + pcache1Shutdown, /* xShutdown */ + pcache1Create, /* xCreate */ + pcache1Cachesize, /* xCachesize */ + pcache1Pagecount, /* xPagecount */ + pcache1Fetch, /* xFetch */ + pcache1Unpin, /* xUnpin */ + pcache1Rekey, /* xRekey */ + pcache1Truncate, /* xTruncate */ + pcache1Destroy, /* xDestroy */ + pcache1Shrink /* xShrink */ + }; + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); +} + +/* +** Return the size of the header on each page of this PCACHE implementation. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } + +/* +** Return the global mutex used by this PCACHE implementation. The +** sqlite3_status() routine needs access to this mutex. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){ + return pcache1.mutex; +} + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* +** This function is called to free superfluous dynamically allocated memory +** held by the pager system. Memory in use by any SQLite pager allocated +** by the current thread may be sqlite3_free()ed. +** +** nReq is the number of bytes of memory required. Once this much has +** been released, the function returns. The return value is the total number +** of bytes of memory released. +*/ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ + int nFree = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.mutex) ); + if( sqlite3GlobalConfig.pPage==0 ){ + PgHdr1 *p; + pcache1EnterMutex(&pcache1.grp); + while( (nReq<0 || nFreeisAnchor==0 + ){ + nFree += pcache1MemSize(p->page.pBuf); + assert( PAGE_IS_UNPINNED(p) ); + pcache1PinPage(p); + pcache1RemoveFromHash(p, 1); + } + pcache1LeaveMutex(&pcache1.grp); + } + return nFree; +} +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ + +#ifdef SQLITE_TEST +/* +** This function is used by test procedures to inspect the internal state +** of the global cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheStats( + int *pnCurrent, /* OUT: Total number of pages cached */ + int *pnMax, /* OUT: Global maximum cache size */ + int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ + int *pnRecyclable /* OUT: Total number of pages available for recycling */ +){ + PgHdr1 *p; + int nRecyclable = 0; + for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){ + assert( PAGE_IS_UNPINNED(p) ); + nRecyclable++; + } + *pnCurrent = pcache1.grp.nPurgeable; + *pnMax = (int)pcache1.grp.nMaxPage; + *pnMin = (int)pcache1.grp.nMinPage; + *pnRecyclable = nRecyclable; +} +#endif + +/************** End of pcache1.c *********************************************/ +/************** Begin file rowset.c ******************************************/ +/* +** 2008 December 3 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This module implements an object we call a "RowSet". +** +** The RowSet object is a collection of rowids. Rowids +** are inserted into the RowSet in an arbitrary order. Inserts +** can be intermixed with tests to see if a given rowid has been +** previously inserted into the RowSet. +** +** After all inserts are finished, it is possible to extract the +** elements of the RowSet in sorted order. Once this extraction +** process has started, no new elements may be inserted. +** +** Hence, the primitive operations for a RowSet are: +** +** CREATE +** INSERT +** TEST +** SMALLEST +** DESTROY +** +** The CREATE and DESTROY primitives are the constructor and destructor, +** obviously. The INSERT primitive adds a new element to the RowSet. +** TEST checks to see if an element is already in the RowSet. SMALLEST +** extracts the least value from the RowSet. +** +** The INSERT primitive might allocate additional memory. Memory is +** allocated in chunks so most INSERTs do no allocation. There is an +** upper bound on the size of allocated memory. No memory is freed +** until DESTROY. +** +** The TEST primitive includes a "batch" number. The TEST primitive +** will only see elements that were inserted before the last change +** in the batch number. In other words, if an INSERT occurs between +** two TESTs where the TESTs have the same batch number, then the +** value added by the INSERT will not be visible to the second TEST. +** The initial batch number is zero, so if the very first TEST contains +** a non-zero batch number, it will see all prior INSERTs. +** +** No INSERTs may occurs after a SMALLEST. An assertion will fail if +** that is attempted. +** +** The cost of an INSERT is roughly constant. (Sometimes new memory +** has to be allocated on an INSERT.) The cost of a TEST with a new +** batch number is O(NlogN) where N is the number of elements in the RowSet. +** The cost of a TEST using the same batch number is O(logN). The cost +** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST +** primitives are constant time. The cost of DESTROY is O(N). +** +** TEST and SMALLEST may not be used by the same RowSet. This used to +** be possible, but the feature was not used, so it was removed in order +** to simplify the code. +*/ +/* #include "sqliteInt.h" */ + + +/* +** Target size for allocation chunks. +*/ +#define ROWSET_ALLOCATION_SIZE 1024 + +/* +** The number of rowset entries per allocation chunk. +*/ +#define ROWSET_ENTRY_PER_CHUNK \ + ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) + +/* +** Each entry in a RowSet is an instance of the following object. +** +** This same object is reused to store a linked list of trees of RowSetEntry +** objects. In that alternative use, pRight points to the next entry +** in the list, pLeft points to the tree, and v is unused. The +** RowSet.pForest value points to the head of this forest list. +*/ +struct RowSetEntry { + i64 v; /* ROWID value for this entry */ + struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ + struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ +}; + +/* +** RowSetEntry objects are allocated in large chunks (instances of the +** following structure) to reduce memory allocation overhead. The +** chunks are kept on a linked list so that they can be deallocated +** when the RowSet is destroyed. +*/ +struct RowSetChunk { + struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */ + struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */ +}; + +/* +** A RowSet in an instance of the following structure. +** +** A typedef of this structure if found in sqliteInt.h. +*/ +struct RowSet { + struct RowSetChunk *pChunk; /* List of all chunk allocations */ + sqlite3 *db; /* The database connection */ + struct RowSetEntry *pEntry; /* List of entries using pRight */ + struct RowSetEntry *pLast; /* Last entry on the pEntry list */ + struct RowSetEntry *pFresh; /* Source of new entry objects */ + struct RowSetEntry *pForest; /* List of binary trees of entries */ + u16 nFresh; /* Number of objects on pFresh */ + u16 rsFlags; /* Various flags */ + int iBatch; /* Current insert batch */ +}; + +/* +** Allowed values for RowSet.rsFlags +*/ +#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ +#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ + +/* +** Allocate a RowSet object. Return NULL if a memory allocation +** error occurs. +*/ +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){ + RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); + if( p ){ + int N = sqlite3DbMallocSize(db, p); + p->pChunk = 0; + p->db = db; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); + p->rsFlags = ROWSET_SORTED; + p->iBatch = 0; + } + return p; +} + +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){ + RowSet *p = (RowSet*)pArg; + struct RowSetChunk *pChunk, *pNextChunk; + for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ + pNextChunk = pChunk->pNextChunk; + sqlite3DbFree(p->db, pChunk); + } + p->pChunk = 0; + p->nFresh = 0; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->rsFlags = ROWSET_SORTED; +} + +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){ + sqlite3RowSetClear(pArg); + sqlite3DbFree(((RowSet*)pArg)->db, pArg); +} + +/* +** Allocate a new RowSetEntry object that is associated with the +** given RowSet. Return a pointer to the new and completely uninitialized +** object. +** +** In an OOM situation, the RowSet.db->mallocFailed flag is set and this +** routine returns NULL. +*/ +static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ + assert( p!=0 ); + if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* We could allocate a fresh RowSetEntry each time one is needed, but it + ** is more efficient to pull a preallocated entry from the pool */ + struct RowSetChunk *pNew; + pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); + if( pNew==0 ){ + return 0; + } + pNew->pNextChunk = p->pChunk; + p->pChunk = pNew; + p->pFresh = pNew->aEntry; + p->nFresh = ROWSET_ENTRY_PER_CHUNK; + } + p->nFresh--; + return p->pFresh++; +} + +/* +** Insert a new value into a RowSet. +** +** The mallocFailed flag of the database connection is set if a +** memory allocation fails. +*/ +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ + struct RowSetEntry *pEntry; /* The new entry */ + struct RowSetEntry *pLast; /* The last prior entry */ + + /* This routine is never called after sqlite3RowSetNext() */ + assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); + + pEntry = rowSetEntryAlloc(p); + if( pEntry==0 ) return; + pEntry->v = rowid; + pEntry->pRight = 0; + pLast = p->pLast; + if( pLast ){ + if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/ + /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags + ** where possible */ + p->rsFlags &= ~ROWSET_SORTED; + } + pLast->pRight = pEntry; + }else{ + p->pEntry = pEntry; + } + p->pLast = pEntry; +} + +/* +** Merge two lists of RowSetEntry objects. Remove duplicates. +** +** The input lists are connected via pRight pointers and are +** assumed to each already be in sorted order. +*/ +static struct RowSetEntry *rowSetEntryMerge( + struct RowSetEntry *pA, /* First sorted list to be merged */ + struct RowSetEntry *pB /* Second sorted list to be merged */ +){ + struct RowSetEntry head; + struct RowSetEntry *pTail; + + pTail = &head; + assert( pA!=0 && pB!=0 ); + for(;;){ + assert( pA->pRight==0 || pA->v<=pA->pRight->v ); + assert( pB->pRight==0 || pB->v<=pB->pRight->v ); + if( pA->v<=pB->v ){ + if( pA->vv ) pTail = pTail->pRight = pA; + pA = pA->pRight; + if( pA==0 ){ + pTail->pRight = pB; + break; + } + }else{ + pTail = pTail->pRight = pB; + pB = pB->pRight; + if( pB==0 ){ + pTail->pRight = pA; + break; + } + } + } + return head.pRight; +} + +/* +** Sort all elements on the list of RowSetEntry objects into order of +** increasing v. +*/ +static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ + unsigned int i; + struct RowSetEntry *pNext, *aBucket[40]; + + memset(aBucket, 0, sizeof(aBucket)); + while( pIn ){ + pNext = pIn->pRight; + pIn->pRight = 0; + for(i=0; aBucket[i]; i++){ + pIn = rowSetEntryMerge(aBucket[i], pIn); + aBucket[i] = 0; + } + aBucket[i] = pIn; + pIn = pNext; + } + pIn = aBucket[0]; + for(i=1; ipLeft ){ + struct RowSetEntry *p; + rowSetTreeToList(pIn->pLeft, ppFirst, &p); + p->pRight = pIn; + }else{ + *ppFirst = pIn; + } + if( pIn->pRight ){ + rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast); + }else{ + *ppLast = pIn; + } + assert( (*ppLast)->pRight==0 ); +} + + +/* +** Convert a sorted list of elements (connected by pRight) into a binary +** tree with depth of iDepth. A depth of 1 means the tree contains a single +** node taken from the head of *ppList. A depth of 2 means a tree with +** three nodes. And so forth. +** +** Use as many entries from the input list as required and update the +** *ppList to point to the unused elements of the list. If the input +** list contains too few elements, then construct an incomplete tree +** and leave *ppList set to NULL. +** +** Return a pointer to the root of the constructed binary tree. +*/ +static struct RowSetEntry *rowSetNDeepTree( + struct RowSetEntry **ppList, + int iDepth +){ + struct RowSetEntry *p; /* Root of the new tree */ + struct RowSetEntry *pLeft; /* Left subtree */ + if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Prevent unnecessary deep recursion when we run out of entries */ + return 0; + } + if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ + /* This branch causes a *balanced* tree to be generated. A valid tree + ** is still generated without this branch, but the tree is wildly + ** unbalanced and inefficient. */ + pLeft = rowSetNDeepTree(ppList, iDepth-1); + p = *ppList; + if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* It is safe to always return here, but the resulting tree + ** would be unbalanced */ + return pLeft; + } + p->pLeft = pLeft; + *ppList = p->pRight; + p->pRight = rowSetNDeepTree(ppList, iDepth-1); + }else{ + p = *ppList; + *ppList = p->pRight; + p->pLeft = p->pRight = 0; + } + return p; +} + +/* +** Convert a sorted list of elements into a binary tree. Make the tree +** as deep as it needs to be in order to contain the entire list. +*/ +static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ + int iDepth; /* Depth of the tree so far */ + struct RowSetEntry *p; /* Current tree root */ + struct RowSetEntry *pLeft; /* Left subtree */ + + assert( pList!=0 ); + p = pList; + pList = p->pRight; + p->pLeft = p->pRight = 0; + for(iDepth=1; pList; iDepth++){ + pLeft = p; + p = pList; + pList = p->pRight; + p->pLeft = pLeft; + p->pRight = rowSetNDeepTree(&pList, iDepth); + } + return p; +} + +/* +** Extract the smallest element from the RowSet. +** Write the element into *pRowid. Return 1 on success. Return +** 0 if the RowSet is already empty. +** +** After this routine has been called, the sqlite3RowSetInsert() +** routine may not be called again. +** +** This routine may not be called after sqlite3RowSetTest() has +** been used. Older versions of RowSet allowed that, but as the +** capability was not used by the code generator, it was removed +** for code economy. +*/ +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ + assert( p!=0 ); + assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */ + + /* Merge the forest into a single sorted list on first call */ + if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + p->pEntry = rowSetEntrySort(p->pEntry); + } + p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT; + } + + /* Return the next entry on the list */ + if( p->pEntry ){ + *pRowid = p->pEntry->v; + p->pEntry = p->pEntry->pRight; + if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Free memory immediately, rather than waiting on sqlite3_finalize() */ + sqlite3RowSetClear(p); + } + return 1; + }else{ + return 0; + } +} + +/* +** Check to see if element iRowid was inserted into the rowset as +** part of any insert batch prior to iBatch. Return 1 or 0. +** +** If this is the first test of a new batch and if there exist entries +** on pRowSet->pEntry, then sort those entries into the forest at +** pRowSet->pForest so that they can be tested. +*/ +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ + struct RowSetEntry *p, *pTree; + + /* This routine is never called after sqlite3RowSetNext() */ + assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); + + /* Sort entries into the forest on the first test of a new batch. + ** To save unnecessary work, only do this when the batch number changes. + */ + if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/ + p = pRowSet->pEntry; + if( p ){ + struct RowSetEntry **ppPrevTree = &pRowSet->pForest; + if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* Only sort the current set of entries if they need it */ + p = rowSetEntrySort(p); + } + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ + ppPrevTree = &pTree->pRight; + if( pTree->pLeft==0 ){ + pTree->pLeft = rowSetListToTree(p); + break; + }else{ + struct RowSetEntry *pAux, *pTail; + rowSetTreeToList(pTree->pLeft, &pAux, &pTail); + pTree->pLeft = 0; + p = rowSetEntryMerge(pAux, p); + } + } + if( pTree==0 ){ + *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet); + if( pTree ){ + pTree->v = 0; + pTree->pRight = 0; + pTree->pLeft = rowSetListToTree(p); + } + } + pRowSet->pEntry = 0; + pRowSet->pLast = 0; + pRowSet->rsFlags |= ROWSET_SORTED; + } + pRowSet->iBatch = iBatch; + } + + /* Test to see if the iRowid value appears anywhere in the forest. + ** Return 1 if it does and 0 if not. + */ + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ + p = pTree->pLeft; + while( p ){ + if( p->vpRight; + }else if( p->v>iRowid ){ + p = p->pLeft; + }else{ + return 1; + } + } + } + return 0; +} + +/************** End of rowset.c **********************************************/ +/************** Begin file pager.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the implementation of the page cache subsystem or "pager". +** +** The pager is used to access a database disk file. It implements +** atomic commit and rollback through the use of a journal file that +** is separate from the database file. The pager also implements file +** locking to prevent two processes from writing the same database +** file simultaneously, or one process from reading the database while +** another is writing. +*/ +#ifndef SQLITE_OMIT_DISKIO +/* #include "sqliteInt.h" */ +/************** Include wal.h in the middle of pager.c ***********************/ +/************** Begin file wal.h *********************************************/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef SQLITE_WAL_H +#define SQLITE_WAL_H + +/* #include "sqliteInt.h" */ + +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): +*/ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) + +#ifdef SQLITE_OMIT_WAL +# define sqlite3WalOpen(x,y,z) 0 +# define sqlite3WalLimit(x,y) +# define sqlite3WalClose(v,w,x,y,z) 0 +# define sqlite3WalBeginReadTransaction(y,z) 0 +# define sqlite3WalEndReadTransaction(z) +# define sqlite3WalDbsize(y) 0 +# define sqlite3WalBeginWriteTransaction(y) 0 +# define sqlite3WalEndWriteTransaction(x) 0 +# define sqlite3WalUndo(x,y,z) 0 +# define sqlite3WalSavepoint(y,z) +# define sqlite3WalSavepointUndo(y,z) 0 +# define sqlite3WalFrames(u,v,w,x,y,z) 0 +# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 +# define sqlite3WalCallback(z) 0 +# define sqlite3WalExclusiveMode(y,z) 0 +# define sqlite3WalHeapMemory(z) 0 +# define sqlite3WalFramesize(z) 0 +# define sqlite3WalFindFrame(x,y,z) 0 +# define sqlite3WalFile(x) 0 +# undef SQLITE_USE_SEH +#else + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct Wal Wal; + +/* Open and close a connection to a write-ahead log. */ +SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); +SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *); + +/* Set the limiting size of a WAL file. */ +SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); + +/* Used by readers to open (lock) and close (unlock) a snapshot. A +** snapshot is like a read-transaction. It is the state of the database +** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and +** preserves the current state even if the other threads or processes +** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the +** transaction and releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); + +/* Read a page from the write-ahead log, if it is present. */ +SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); +SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); + +/* If the WAL is not empty, return the size of the database. */ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); + +/* Obtain or release the WRITER lock. */ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); + +/* Undo any frames written (but not committed) to the log */ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); + +/* Return an integer that records the current (uncommitted) write +** position in the WAL */ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); + +/* Move the write position of the WAL back to iFrame. Called in +** response to a ROLLBACK TO command. */ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); + +/* Write a frame or frames to the log. */ +SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); + +/* Copy pages from the log to the database file */ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +); + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); + +/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) +** by the pager layer on the database file. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); + +/* Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); + +#ifdef SQLITE_ENABLE_SNAPSHOT +SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); +#endif + +#ifdef SQLITE_ENABLE_ZIPVFS +/* If the WAL file is not empty, return the number of bytes of content +** stored in each frame (i.e. the db page-size when the WAL was created). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); +#endif + +/* Return the sqlite3_file object for the WAL file */ +SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock); +SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); +#endif + +#ifdef SQLITE_USE_SEH +SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal*); +#endif + +#endif /* ifndef SQLITE_OMIT_WAL */ +#endif /* SQLITE_WAL_H */ + +/************** End of wal.h *************************************************/ +/************** Continuing where we left off in pager.c **********************/ + + +/******************* NOTES ON THE DESIGN OF THE PAGER ************************ +** +** This comment block describes invariants that hold when using a rollback +** journal. These invariants do not apply for journal_mode=WAL, +** journal_mode=MEMORY, or journal_mode=OFF. +** +** Within this comment block, a page is deemed to have been synced +** automatically as soon as it is written when PRAGMA synchronous=OFF. +** Otherwise, the page is not synced until the xSync method of the VFS +** is called successfully on the file containing the page. +** +** Definition: A page of the database file is said to be "overwriteable" if +** one or more of the following are true about the page: +** +** (a) The original content of the page as it was at the beginning of +** the transaction has been written into the rollback journal and +** synced. +** +** (b) The page was a freelist leaf page at the start of the transaction. +** +** (c) The page number is greater than the largest page that existed in +** the database file at the start of the transaction. +** +** (1) A page of the database file is never overwritten unless one of the +** following are true: +** +** (a) The page and all other pages on the same sector are overwriteable. +** +** (b) The atomic page write optimization is enabled, and the entire +** transaction other than the update of the transaction sequence +** number consists of a single page change. +** +** (2) The content of a page written into the rollback journal exactly matches +** both the content in the database when the rollback journal was written +** and the content in the database at the beginning of the current +** transaction. +** +** (3) Writes to the database file are an integer multiple of the page size +** in length and are aligned on a page boundary. +** +** (4) Reads from the database file are either aligned on a page boundary and +** an integer multiple of the page size in length or are taken from the +** first 100 bytes of the database file. +** +** (5) All writes to the database file are synced prior to the rollback journal +** being deleted, truncated, or zeroed. +** +** (6) If a super-journal file is used, then all writes to the database file +** are synced prior to the super-journal being deleted. +** +** Definition: Two databases (or the same database at two points it time) +** are said to be "logically equivalent" if they give the same answer to +** all queries. Note in particular the content of freelist leaf +** pages can be changed arbitrarily without affecting the logical equivalence +** of the database. +** +** (7) At any time, if any subset, including the empty set and the total set, +** of the unsynced changes to a rollback journal are removed and the +** journal is rolled back, the resulting database file will be logically +** equivalent to the database file at the beginning of the transaction. +** +** (8) When a transaction is rolled back, the xTruncate method of the VFS +** is called to restore the database file to the same size it was at +** the beginning of the transaction. (In some VFSes, the xTruncate +** method is a no-op, but that does not change the fact the SQLite will +** invoke it.) +** +** (9) Whenever the database file is modified, at least one bit in the range +** of bytes from 24 through 39 inclusive will be changed prior to releasing +** the EXCLUSIVE lock, thus signaling other connections on the same +** database to flush their caches. +** +** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less +** than one billion transactions. +** +** (11) A database file is well-formed at the beginning and at the conclusion +** of every transaction. +** +** (12) An EXCLUSIVE lock is held on the database file when writing to +** the database file. +** +** (13) A SHARED lock is held on the database file while reading any +** content out of the database file. +** +******************************************************************************/ + +/* +** Macros for troubleshooting. Normally turned off +*/ +#if 0 +int sqlite3PagerTrace=1; /* True to enable tracing */ +#define sqlite3DebugPrintf printf +#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; } +#else +#define PAGERTRACE(X) +#endif + +/* +** The following two macros are used within the PAGERTRACE() macros above +** to print out file-descriptors. +** +** PAGERID() takes a pointer to a Pager struct as its argument. The +** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file +** struct as its argument. +*/ +#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd)) +#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd)) + +/* +** The Pager.eState variable stores the current 'state' of a pager. A +** pager may be in any one of the seven states shown in the following +** state diagram. +** +** OPEN <------+------+ +** | | | +** V | | +** +---------> READER-------+ | +** | | | +** | V | +** |<-------WRITER_LOCKED------> ERROR +** | | ^ +** | V | +** |<------WRITER_CACHEMOD-------->| +** | | | +** | V | +** |<-------WRITER_DBMOD---------->| +** | | | +** | V | +** +<------WRITER_FINISHED-------->+ +** +** +** List of state transitions and the C [function] that performs each: +** +** OPEN -> READER [sqlite3PagerSharedLock] +** READER -> OPEN [pager_unlock] +** +** READER -> WRITER_LOCKED [sqlite3PagerBegin] +** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] +** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] +** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] +** WRITER_*** -> READER [pager_end_transaction] +** +** WRITER_*** -> ERROR [pager_error] +** ERROR -> OPEN [pager_unlock] +** +** +** OPEN: +** +** The pager starts up in this state. Nothing is guaranteed in this +** state - the file may or may not be locked and the database size is +** unknown. The database may not be read or written. +** +** * No read or write transaction is active. +** * Any lock, or no lock at all, may be held on the database file. +** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. +** +** READER: +** +** In this state all the requirements for reading the database in +** rollback (non-WAL) mode are met. Unless the pager is (or recently +** was) in exclusive-locking mode, a user-level read transaction is +** open. The database size is known in this state. +** +** A connection running with locking_mode=normal enters this state when +** it opens a read-transaction on the database and returns to state +** OPEN after the read-transaction is completed. However a connection +** running in locking_mode=exclusive (including temp databases) remains in +** this state even after the read-transaction is closed. The only way +** a locking_mode=exclusive connection can transition from READER to OPEN +** is via the ERROR state (see below). +** +** * A read transaction may be active (but a write-transaction cannot). +** * A SHARED or greater lock is held on the database file. +** * The dbSize variable may be trusted (even if a user-level read +** transaction is not active). The dbOrigSize and dbFileSize variables +** may not be trusted at this point. +** * If the database is a WAL database, then the WAL connection is open. +** * Even if a read-transaction is not open, it is guaranteed that +** there is no hot-journal in the file-system. +** +** WRITER_LOCKED: +** +** The pager moves to this state from READER when a write-transaction +** is first opened on the database. In WRITER_LOCKED state, all locks +** required to start a write-transaction are held, but no actual +** modifications to the cache or database have taken place. +** +** In rollback mode, a RESERVED or (if the transaction was opened with +** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when +** moving to this state, but the journal file is not written to or opened +** to in this state. If the transaction is committed or rolled back while +** in WRITER_LOCKED state, all that is required is to unlock the database +** file. +** +** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. +** If the connection is running with locking_mode=exclusive, an attempt +** is made to obtain an EXCLUSIVE lock on the database file. +** +** * A write transaction is active. +** * If the connection is open in rollback-mode, a RESERVED or greater +** lock is held on the database file. +** * If the connection is open in WAL-mode, a WAL write transaction +** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully +** called). +** * The dbSize, dbOrigSize and dbFileSize variables are all valid. +** * The contents of the pager cache have not been modified. +** * The journal file may or may not be open. +** * Nothing (not even the first header) has been written to the journal. +** +** WRITER_CACHEMOD: +** +** A pager moves from WRITER_LOCKED state to this state when a page is +** first modified by the upper layer. In rollback mode the journal file +** is opened (if it is not already open) and a header written to the +** start of it. The database file on disk has not been modified. +** +** * A write transaction is active. +** * A RESERVED or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** to it, but the header has not been synced to disk. +** * The contents of the page cache have been modified. +** +** WRITER_DBMOD: +** +** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state +** when it modifies the contents of the database file. WAL connections +** never enter this state (since they do not modify the database file, +** just the log file). +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** and synced to disk. +** * The contents of the page cache have been modified (and possibly +** written to disk). +** +** WRITER_FINISHED: +** +** It is not possible for a WAL connection to enter this state. +** +** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD +** state after the entire transaction has been successfully written into the +** database file. In this state the transaction may be committed simply +** by finalizing the journal file. Once in WRITER_FINISHED state, it is +** not possible to modify the database further. At this point, the upper +** layer must either commit or rollback the transaction. +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * All writing and syncing of journal and database data has finished. +** If no error occurred, all that remains is to finalize the journal to +** commit the transaction. If an error did occur, the caller will need +** to rollback the transaction. +** +** ERROR: +** +** The ERROR state is entered when an IO or disk-full error (including +** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +** difficult to be sure that the in-memory pager state (cache contents, +** db size etc.) are consistent with the contents of the file-system. +** +** Temporary pager files may enter the ERROR state, but in-memory pagers +** cannot. +** +** For example, if an IO error occurs while performing a rollback, +** the contents of the page-cache may be left in an inconsistent state. +** At this point it would be dangerous to change back to READER state +** (as usually happens after a rollback). Any subsequent readers might +** report database corruption (due to the inconsistent cache), and if +** they upgrade to writers, they may inadvertently corrupt the database +** file. To avoid this hazard, the pager switches into the ERROR state +** instead of READER following such an error. +** +** Once it has entered the ERROR state, any attempt to use the pager +** to read or write data returns an error. Eventually, once all +** outstanding transactions have been abandoned, the pager is able to +** transition back to OPEN state, discarding the contents of the +** page-cache and any other in-memory state at the same time. Everything +** is reloaded from disk (and, if necessary, hot-journal rollback performed) +** when a read-transaction is next opened on the pager (transitioning +** the pager into READER state). At that point the system has recovered +** from the error. +** +** Specifically, the pager jumps into the ERROR state if: +** +** 1. An error occurs while attempting a rollback. This happens in +** function sqlite3PagerRollback(). +** +** 2. An error occurs while attempting to finalize a journal file +** following a commit in function sqlite3PagerCommitPhaseTwo(). +** +** 3. An error occurs while attempting to write to the journal or +** database file in function pagerStress() in order to free up +** memory. +** +** In other cases, the error is returned to the b-tree layer. The b-tree +** layer then attempts a rollback operation. If the error condition +** persists, the pager enters the ERROR state via condition (1) above. +** +** Condition (3) is necessary because it can be triggered by a read-only +** statement executed within a transaction. In this case, if the error +** code were simply returned to the user, the b-tree layer would not +** automatically attempt a rollback, as it assumes that an error in a +** read-only statement cannot leave the pager in an internally inconsistent +** state. +** +** * The Pager.errCode variable is set to something other than SQLITE_OK. +** * There are one or more outstanding references to pages (after the +** last reference is dropped the pager should move back to OPEN state). +** * The pager is not an in-memory pager. +** +** +** Notes: +** +** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the +** connection is open in WAL mode. A WAL connection is always in one +** of the first four states. +** +** * Normally, a connection open in exclusive mode is never in PAGER_OPEN +** state. There are two exceptions: immediately after exclusive-mode has +** been turned on (and before any read or write transactions are +** executed), and when the pager is leaving the "error state". +** +** * See also: assert_pager_state(). +*/ +#define PAGER_OPEN 0 +#define PAGER_READER 1 +#define PAGER_WRITER_LOCKED 2 +#define PAGER_WRITER_CACHEMOD 3 +#define PAGER_WRITER_DBMOD 4 +#define PAGER_WRITER_FINISHED 5 +#define PAGER_ERROR 6 + +/* +** The Pager.eLock variable is almost always set to one of the +** following locking-states, according to the lock currently held on +** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** This variable is kept up to date as locks are taken and released by +** the pagerLockDb() and pagerUnlockDb() wrappers. +** +** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY +** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not +** the operation was successful. In these circumstances pagerLockDb() and +** pagerUnlockDb() take a conservative approach - eLock is always updated +** when unlocking the file, and only updated when locking the file if the +** VFS call is successful. This way, the Pager.eLock variable may be set +** to a less exclusive (lower) value than the lock that is actually held +** at the system level, but it is never set to a more exclusive value. +** +** This is usually safe. If an xUnlock fails or appears to fail, there may +** be a few redundant xLock() calls or a lock may be held for longer than +** required, but nothing really goes wrong. +** +** The exception is when the database file is unlocked as the pager moves +** from ERROR to OPEN state. At this point there may be a hot-journal file +** in the file-system that needs to be rolled back (as part of an OPEN->SHARED +** transition, by the same pager or any other). If the call to xUnlock() +** fails at this point and the pager is left holding an EXCLUSIVE lock, this +** can confuse the call to xCheckReservedLock() call made later as part +** of hot-journal detection. +** +** xCheckReservedLock() is defined as returning true "if there is a RESERVED +** lock held by this process or any others". So xCheckReservedLock may +** return true because the caller itself is holding an EXCLUSIVE lock (but +** doesn't know it because of a previous error in xUnlock). If this happens +** a hot-journal may be mistaken for a journal being created by an active +** transaction in another process, causing SQLite to read from the database +** without rolling it back. +** +** To work around this, if a call to xUnlock() fails when unlocking the +** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It +** is only changed back to a real locking state after a successful call +** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE +** lock on the database file before attempting to roll it back. See function +** PagerSharedLock() for more detail. +** +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +** PAGER_OPEN state. +*/ +#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) + +/* +** The maximum allowed sector size. 64KiB. If the xSectorsize() method +** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. +** This could conceivably cause corruption following a power failure on +** such a system. This is currently an undocumented limit. +*/ +#define MAX_SECTOR_SIZE 0x10000 + + +/* +** An instance of the following structure is allocated for each active +** savepoint and statement transaction in the system. All such structures +** are stored in the Pager.aSavepoint[] array, which is allocated and +** resized using sqlite3Realloc(). +** +** When a savepoint is created, the PagerSavepoint.iHdrOffset field is +** set to 0. If a journal-header is written into the main journal while +** the savepoint is active, then iHdrOffset is set to the byte offset +** immediately following the last journal record written into the main +** journal before the journal-header. This is required during savepoint +** rollback (see pagerPlaybackSavepoint()). +*/ +typedef struct PagerSavepoint PagerSavepoint; +struct PagerSavepoint { + i64 iOffset; /* Starting offset in main journal */ + i64 iHdrOffset; /* See above */ + Bitvec *pInSavepoint; /* Set of pages in this savepoint */ + Pgno nOrig; /* Original number of pages in file */ + Pgno iSubRec; /* Index of first record in sub-journal */ + int bTruncateOnRelease; /* If stmt journal may be truncated on RELEASE */ +#ifndef SQLITE_OMIT_WAL + u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ +#endif +}; + +/* +** Bits of the Pager.doNotSpill flag. See further description below. +*/ +#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ +#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ +#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ + +/* +** An open page cache is an instance of struct Pager. A description of +** some of the more important member variables follows: +** +** eState +** +** The current 'state' of the pager object. See the comment and state +** diagram above for a description of the pager state. +** +** eLock +** +** For a real on-disk database, the current lock held on the database file - +** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** +** For a temporary or in-memory database (neither of which require any +** locks), this variable is always set to EXCLUSIVE_LOCK. Since such +** databases always have Pager.exclusiveMode==1, this tricks the pager +** logic into thinking that it already has all the locks it will ever +** need (and no reason to release them). +** +** In some (obscure) circumstances, this variable may also be set to +** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for +** details. +** +** changeCountDone +** +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. +** +** It is set to true when the change-counter field is updated, which +** can only happen if an exclusive lock is held on the database file. +** It is cleared (set to false) whenever an exclusive lock is +** relinquished on the database file. Each time a transaction is committed, +** The changeCountDone flag is inspected. If it is true, the work of +** updating the change-counter is omitted for the current transaction. +** +** This mechanism means that when running in exclusive mode, a connection +** need only update the change-counter once, for the first transaction +** committed. +** +** setSuper +** +** When PagerCommitPhaseOne() is called to commit a transaction, it may +** (or may not) specify a super-journal name to be written into the +** journal file before it is synced to disk. +** +** Whether or not a journal file contains a super-journal pointer affects +** the way in which the journal file is finalized after the transaction is +** committed or rolled back when running in "journal_mode=PERSIST" mode. +** If a journal file does not contain a super-journal pointer, it is +** finalized by overwriting the first journal header with zeroes. If +** it does contain a super-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were +** running in "journal_mode=truncate" mode. +** +** Journal files that contain super-journal pointers cannot be finalized +** simply by overwriting the first journal-header with zeroes, as the +** super-journal pointer could interfere with hot-journal rollback of any +** subsequently interrupted transaction that reuses the journal file. +** +** The flag is cleared as soon as the journal file is finalized (either +** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the +** journal file from being successfully finalized, the setSuper flag +** is cleared anyway (and the pager will move to ERROR state). +** +** doNotSpill +** +** This variables control the behavior of cache-spills (calls made by +** the pcache module to the pagerStress() routine to write cached data +** to the file-system in order to free up memory). +** +** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, +** writing to the database from pagerStress() is disabled altogether. +** The SPILLFLAG_ROLLBACK case is done in a very obscure case that +** comes up during savepoint rollback that requires the pcache module +** to allocate a new page to prevent the journal file from being written +** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF +** case is a user preference. +** +** If the SPILLFLAG_NOSYNC bit is set, writing to the database from +** pagerStress() is permitted, but syncing the journal file is not. +** This flag is set by sqlite3PagerWrite() when the file-system sector-size +** is larger than the database page-size in order to prevent a journal sync +** from happening in between the journalling of two pages on the same sector. +** +** subjInMemory +** +** This is a boolean variable. If true, then any required sub-journal +** is opened as an in-memory journal file. If false, then in-memory +** sub-journals are only used for in-memory pager files. +** +** This variable is updated by the upper layer each time a new +** write-transaction is opened. +** +** dbSize, dbOrigSize, dbFileSize +** +** Variable dbSize is set to the number of pages in the database file. +** It is valid in PAGER_READER and higher states (all states except for +** OPEN and ERROR). +** +** dbSize is set based on the size of the database file, which may be +** larger than the size of the database (the value stored at offset +** 28 of the database header by the btree). If the size of the file +** is not an integer multiple of the page-size, the value stored in +** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). +** Except, any file that is greater than 0 bytes in size is considered +** to have at least one page. (i.e. a 1KB file with 2K page-size leads +** to dbSize==1). +** +** During a write-transaction, if pages with page-numbers greater than +** dbSize are modified in the cache, dbSize is updated accordingly. +** Similarly, if the database is truncated using PagerTruncateImage(), +** dbSize is updated. +** +** Variables dbOrigSize and dbFileSize are valid in states +** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize +** variable at the start of the transaction. It is used during rollback, +** and to determine whether or not pages need to be journalled before +** being modified. +** +** Throughout a write-transaction, dbFileSize contains the size of +** the file on disk in pages. It is set to a copy of dbSize when the +** write-transaction is first opened, and updated when VFS calls are made +** to write or truncate the database file on disk. +** +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), +** pager_truncate() is called. The pager_truncate() call uses xFilesize() +** to measure the database file on disk, and then truncates it if required. +** dbFileSize is not used when rolling back a transaction. In this case +** pager_truncate() is called unconditionally (which means there may be +** a call to xFilesize() that is not strictly required). In either case, +** pager_truncate() may cause the file to become smaller or larger. +** +** dbHintSize +** +** The dbHintSize variable is used to limit the number of calls made to +** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** +** dbHintSize is set to a copy of the dbSize variable when a +** write-transaction is opened (at the same time as dbFileSize and +** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, +** dbHintSize is increased to the number of pages that correspond to the +** size-hint passed to the method call. See pager_write_pagelist() for +** details. +** +** errCode +** +** The Pager.errCode variable is only ever used in PAGER_ERROR state. It +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** sub-codes. +** +** syncFlags, walSyncFlags +** +** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). +** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode +** and contains the flags used to sync the checkpoint operations in the +** lower two bits, and sync flags used for transaction commits in the WAL +** file in bits 0x04 and 0x08. In other words, to get the correct sync flags +** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct +** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note +** that with synchronous=NORMAL in WAL mode, transaction commit is not synced +** meaning that the 0x04 and 0x08 bits are both zero. +*/ +struct Pager { + sqlite3_vfs *pVfs; /* OS functions to use for IO */ + u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ + u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ + u8 useJournal; /* Use a rollback journal on this file */ + u8 noSync; /* Do not sync the journal if true */ + u8 fullSync; /* Do extra syncs of the journal for robustness */ + u8 extraSync; /* sync directory after journal delete */ + u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + u8 walSyncFlags; /* See description above */ + u8 tempFile; /* zFilename is a temporary or immutable file */ + u8 noLock; /* Do not lock (except in WAL mode) */ + u8 readOnly; /* True for a read-only database */ + u8 memDb; /* True to inhibit all file I/O */ + u8 memVfs; /* VFS-implemented memory database */ + + /************************************************************************** + ** The following block contains those class members that change during + ** routine operation. Class members not in this block are either fixed + ** when the pager is first created or else only change when there is a + ** significant mode change (such as changing the page_size, locking_mode, + ** or the journal_mode). From another view, these class members describe + ** the "state" of the pager, while other class members describe the + ** "configuration" of the pager. + */ + u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ + u8 eLock; /* Current lock held on database file */ + u8 changeCountDone; /* Set after incrementing the change-counter */ + u8 setSuper; /* Super-jrnl name is written into jrnl */ + u8 doNotSpill; /* Do not spill the cache when non-zero */ + u8 subjInMemory; /* True to use in-memory sub-journals */ + u8 bUseFetch; /* True to use xFetch() */ + u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ + Pgno dbSize; /* Number of pages in the database */ + Pgno dbOrigSize; /* dbSize before the current transaction */ + Pgno dbFileSize; /* Number of pages in the database file */ + Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ + int errCode; /* One of several kinds of errors */ + int nRec; /* Pages journalled since last j-header written */ + u32 cksumInit; /* Quasi-random value added to every checksum */ + u32 nSubRec; /* Number of records written to sub-journal */ + Bitvec *pInJournal; /* One bit for each page in the database file */ + sqlite3_file *fd; /* File descriptor for database */ + sqlite3_file *jfd; /* File descriptor for main journal */ + sqlite3_file *sjfd; /* File descriptor for sub-journal */ + i64 journalOff; /* Current write offset in the journal file */ + i64 journalHdr; /* Byte offset to previous journal header */ + sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ + PagerSavepoint *aSavepoint; /* Array of active savepoints */ + int nSavepoint; /* Number of elements in aSavepoint[] */ + u32 iDataVersion; /* Changes whenever database content changes */ + char dbFileVers[16]; /* Changes whenever database file changes */ + + int nMmapOut; /* Number of mmap pages currently outstanding */ + sqlite3_int64 szMmap; /* Desired maximum mmap size */ + PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ + /* + ** End of the routinely-changing class members + ***************************************************************************/ + + u16 nExtra; /* Add this many bytes to each in-memory page */ + i16 nReserve; /* Number of unused bytes at end of each page */ + u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ + u32 sectorSize; /* Assumed sector size during rollback */ + Pgno mxPgno; /* Maximum allowed size of the database */ + Pgno lckPgno; /* Page number for the locking page */ + i64 pageSize; /* Number of bytes in a page */ + i64 journalSizeLimit; /* Size limit for persistent journal files */ + char *zFilename; /* Name of the database file */ + char *zJournal; /* Name of the journal file */ + int (*xBusyHandler)(void*); /* Function to call when busy */ + void *pBusyHandlerArg; /* Context argument for xBusyHandler */ + u32 aStat[4]; /* Total cache hits, misses, writes, spills */ +#ifdef SQLITE_TEST + int nRead; /* Database pages read */ +#endif + void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ + int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ + char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ + PCache *pPCache; /* Pointer to page cache object */ +#ifndef SQLITE_OMIT_WAL + Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + char *zWal; /* File name for write-ahead log */ +#endif +}; + +/* +** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains +** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS +** or CACHE_WRITE to sqlite3_db_status(). +*/ +#define PAGER_STAT_HIT 0 +#define PAGER_STAT_MISS 1 +#define PAGER_STAT_WRITE 2 +#define PAGER_STAT_SPILL 3 + +/* +** The following global variables hold counters used for +** testing purposes only. These variables do not exist in +** a non-testing build. These variables are not thread-safe. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ +SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ +SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ +# define PAGER_INCR(v) v++ +#else +# define PAGER_INCR(v) +#endif + + + +/* +** Journal files begin with the following magic string. The data +** was obtained from /dev/random. It is used only as a sanity check. +** +** Since version 2.8.0, the journal format contains additional sanity +** checking information. If the power fails while the journal is being +** written, semi-random garbage data might appear in the journal +** file after power is restored. If an attempt is then made +** to roll the journal back, the database could be corrupted. The additional +** sanity checking data is an attempt to discover the garbage in the +** journal and ignore it. +** +** The sanity checking information for the new journal format consists +** of a 32-bit checksum on each page of data. The checksum covers both +** the page number and the pPager->pageSize bytes of data for the page. +** This cksum is initialized to a 32-bit random value that appears in the +** journal file right after the header. The random initializer is important, +** because garbage data that appears at the end of a journal is likely +** data that was once in other files that have now been deleted. If the +** garbage data came from an obsolete journal file, the checksums might +** be correct. But by initializing the checksum to random value which +** is different for every journal, we minimize that risk. +*/ +static const unsigned char aJournalMagic[] = { + 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7, +}; + +/* +** The size of the of each page record in the journal is given by +** the following macro. +*/ +#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) + +/* +** The journal header size for this pager. This is usually the same +** size as a single disk sector. See also setSectorSize(). +*/ +#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) + +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch +** interfaces to access the database using memory-mapped I/O. +*/ +#if SQLITE_MAX_MMAP_SIZE>0 +# define USEFETCH(x) ((x)->bUseFetch) +#else +# define USEFETCH(x) 0 +#endif + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods!=0) + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +/* +** Return true if page pgno can be read directly from the database file +** by the b-tree layer. This is the case if: +** +** * the database file is open, +** * there are no dirty pages in the cache, and +** * the desired page is not currently in the wal file. +*/ +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ + if( pPager->fd->pMethods==0 ) return 0; + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; +#ifndef SQLITE_OMIT_WAL + if( pPager->pWal ){ + u32 iRead = 0; + (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + return iRead==0; + } +#endif + return 1; +} +#endif + +#ifndef SQLITE_OMIT_WAL +# define pagerUseWal(x) ((x)->pWal!=0) +#else +# define pagerUseWal(x) 0 +# define pagerRollbackWal(x) 0 +# define pagerWalFrames(v,w,x,y) 0 +# define pagerOpenWalIfPresent(z) SQLITE_OK +# define pagerBeginReadTransaction(z) SQLITE_OK +#endif + +#ifndef NDEBUG +/* +** Usage: +** +** assert( assert_pager_state(pPager) ); +** +** This function runs many asserts to try to find inconsistencies in +** the internal state of the Pager object. +*/ +static int assert_pager_state(Pager *p){ + Pager *pPager = p; + + /* State must be valid. */ + assert( p->eState==PAGER_OPEN + || p->eState==PAGER_READER + || p->eState==PAGER_WRITER_LOCKED + || p->eState==PAGER_WRITER_CACHEMOD + || p->eState==PAGER_WRITER_DBMOD + || p->eState==PAGER_WRITER_FINISHED + || p->eState==PAGER_ERROR + ); + + /* Regardless of the current state, a temp-file connection always behaves + ** as if it has an exclusive lock on the database file. It never updates + ** the change-counter field, so the changeCountDone flag is always set. + */ + assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); + assert( p->tempFile==0 || pPager->changeCountDone ); + + /* If the useJournal flag is clear, the journal-mode must be "OFF". + ** And if the journal-mode is "OFF", the journal file must not be open. + */ + assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); + assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); + + /* Check that MEMDB implies noSync. And an in-memory journal. Since + ** this means an in-memory pager performs no IO at all, it cannot encounter + ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing + ** a journal file. (although the in-memory journal implementation may + ** return SQLITE_IOERR_NOMEM while the journal file is being written). It + ** is therefore not possible for an in-memory pager to enter the ERROR + ** state. + */ + if( MEMDB ){ + assert( !isOpen(p->fd) ); + assert( p->noSync ); + assert( p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_MEMORY + ); + assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); + assert( pagerUseWal(p)==0 ); + } + + /* If changeCountDone is set, a RESERVED lock or greater must be held + ** on the file. + */ + assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); + assert( p->eLock!=PENDING_LOCK ); + + switch( p->eState ){ + case PAGER_OPEN: + assert( !MEMDB ); + assert( pPager->errCode==SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); + break; + + case PAGER_READER: + assert( pPager->errCode==SQLITE_OK ); + assert( p->eLock!=UNKNOWN_LOCK ); + assert( p->eLock>=SHARED_LOCK ); + break; + + case PAGER_WRITER_LOCKED: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + assert( p->eLock>=RESERVED_LOCK ); + } + assert( pPager->dbSize==pPager->dbOrigSize ); + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + assert( pPager->setSuper==0 ); + break; + + case PAGER_WRITER_CACHEMOD: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + /* It is possible that if journal_mode=wal here that neither the + ** journal file nor the WAL file are open. This happens during + ** a rollback transaction that switches from journal_mode=off + ** to journal_mode=wal. + */ + assert( p->eLock>=RESERVED_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + } + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + break; + + case PAGER_WRITER_DBMOD: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( p->eLock>=EXCLUSIVE_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + ); + assert( pPager->dbOrigSize<=pPager->dbHintSize ); + break; + + case PAGER_WRITER_FINISHED: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + ); + break; + + case PAGER_ERROR: + /* There must be at least one outstanding reference to the pager if + ** in ERROR state. Otherwise the pager should have already dropped + ** back to OPEN state. + */ + assert( pPager->errCode!=SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile ); + break; + } + + return 1; +} +#endif /* ifndef NDEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Return a pointer to a human readable string in a static buffer +** containing the state of the Pager object passed as an argument. This +** is intended to be used within debuggers. For example, as an alternative +** to "print *pPager" in gdb: +** +** (gdb) printf "%s", print_pager_state(pPager) +** +** This routine has external linkage in order to suppress compiler warnings +** about an unused function. It is enclosed within SQLITE_DEBUG and so does +** not appear in normal builds. +*/ +char *print_pager_state(Pager *p){ + static char zRet[1024]; + + sqlite3_snprintf(1024, zRet, + "Filename: %s\n" + "State: %s errCode=%d\n" + "Lock: %s\n" + "Locking mode: locking_mode=%s\n" + "Journal mode: journal_mode=%s\n" + "Backing store: tempFile=%d memDb=%d useJournal=%d\n" + "Journal: journalOff=%lld journalHdr=%lld\n" + "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n" + , p->zFilename + , p->eState==PAGER_OPEN ? "OPEN" : + p->eState==PAGER_READER ? "READER" : + p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" : + p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : + p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : + p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : + p->eState==PAGER_ERROR ? "ERROR" : "?error?" + , (int)p->errCode + , p->eLock==NO_LOCK ? "NO_LOCK" : + p->eLock==RESERVED_LOCK ? "RESERVED" : + p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : + p->eLock==SHARED_LOCK ? "SHARED" : + p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?" + , p->exclusiveMode ? "exclusive" : "normal" + , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" : + p->journalMode==PAGER_JOURNALMODE_OFF ? "off" : + p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" : + p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" : + p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" : + p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?" + , (int)p->tempFile, (int)p->memDb, (int)p->useJournal + , p->journalOff, p->journalHdr + , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize + ); + + return zRet; +} +#endif + +/* Forward references to the various page getters */ +static int getPageNormal(Pager*,Pgno,DbPage**,int); +static int getPageError(Pager*,Pgno,DbPage**,int); +#if SQLITE_MAX_MMAP_SIZE>0 +static int getPageMMap(Pager*,Pgno,DbPage**,int); +#endif + +/* +** Set the Pager.xGet method for the appropriate routine used to fetch +** content from the pager. +*/ +static void setGetterMethod(Pager *pPager){ + if( pPager->errCode ){ + pPager->xGet = getPageError; +#if SQLITE_MAX_MMAP_SIZE>0 + }else if( USEFETCH(pPager) ){ + pPager->xGet = getPageMMap; +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + }else{ + pPager->xGet = getPageNormal; + } +} + +/* +** Return true if it is necessary to write page *pPg into the sub-journal. +** A page needs to be written into the sub-journal if there exists one +** or more open savepoints for which: +** +** * The page-number is less than or equal to PagerSavepoint.nOrig, and +** * The bit corresponding to the page-number is not set in +** PagerSavepoint.pInSavepoint. +*/ +static int subjRequiresPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + PagerSavepoint *p; + Pgno pgno = pPg->pgno; + int i; + for(i=0; inSavepoint; i++){ + p = &pPager->aSavepoint[i]; + if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; inSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } + return 1; + } + } + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** Return true if the page is already in the journal file. +*/ +static int pageInJournal(Pager *pPager, PgHdr *pPg){ + return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); +} +#endif + +/* +** Read a 32-bit integer from the given file descriptor. Store the integer +** that is read in *pRes. Return SQLITE_OK if everything worked, or an +** error code is something goes wrong. +** +** All values are stored on disk as big-endian. +*/ +static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ + unsigned char ac[4]; + int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); + if( rc==SQLITE_OK ){ + *pRes = sqlite3Get4byte(ac); + } + return rc; +} + +/* +** Write a 32-bit integer into a string buffer in big-endian byte order. +*/ +#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) + + +/* +** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK +** on success or an error code is something goes wrong. +*/ +static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ + char ac[4]; + put32bits(ac, val); + return sqlite3OsWrite(fd, ac, 4, offset); +} + +/* +** Unlock the database file to level eLock, which must be either NO_LOCK +** or SHARED_LOCK. Regardless of whether or not the call to xUnlock() +** succeeds, set the Pager.eLock variable to match the (attempted) new lock. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it. See the comment above the #define of +** UNKNOWN_LOCK for an explanation of this. +*/ +static int pagerUnlockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( !pPager->exclusiveMode || pPager->eLock==eLock ); + assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); + assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); + if( isOpen(pPager->fd) ){ + assert( pPager->eLock>=eLock ); + rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); + if( pPager->eLock!=UNKNOWN_LOCK ){ + pPager->eLock = (u8)eLock; + } + IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) + } + pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */ + return rc; +} + +/* +** Lock the database file to level eLock, which must be either SHARED_LOCK, +** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the +** Pager.eLock variable to the new locking state. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +** See the comment above the #define of UNKNOWN_LOCK for an explanation +** of this. +*/ +static int pagerLockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); + if( pPager->eLockeLock==UNKNOWN_LOCK ){ + rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); + if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ + pPager->eLock = (u8)eLock; + IOTRACE(("LOCK %p %d\n", pPager, eLock)) + } + } + return rc; +} + +/* +** This function determines whether or not the atomic-write or +** atomic-batch-write optimizations can be used with this pager. The +** atomic-write optimization can be used if: +** +** (a) the value returned by OsDeviceCharacteristics() indicates that +** a database page may be written atomically, and +** (b) the value returned by OsSectorSize() is less than or equal +** to the page size. +** +** If it can be used, then the value returned is the size of the journal +** file when it contains rollback data for exactly one page. +** +** The atomic-batch-write optimization can be used if OsDeviceCharacteristics() +** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is +** returned in this case. +** +** If neither optimization can be used, 0 is returned. +*/ +static int jrnlBufferSize(Pager *pPager){ + assert( !MEMDB ); + +#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ + || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + int dc; /* Device characteristics */ + + assert( isOpen(pPager->fd) ); + dc = sqlite3OsDeviceCharacteristics(pPager->fd); +#else + UNUSED_PARAMETER(pPager); +#endif + +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){ + return -1; + } +#endif + +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + { + int nSector = pPager->sectorSize; + int szPage = pPager->pageSize; + + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ + return 0; + } + } + + return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); +#endif + + return 0; +} + +/* +** If SQLITE_CHECK_PAGES is defined then we do some sanity checking +** on the cache using a hash function. This is used for testing +** and debugging only. +*/ +#ifdef SQLITE_CHECK_PAGES +/* +** Return a 32-bit hash of the page data for pPage. +*/ +static u32 pager_datahash(int nByte, unsigned char *pData){ + u32 hash = 0; + int i; + for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); +} +static void pager_set_pagehash(PgHdr *pPage){ + pPage->pageHash = pager_pagehash(pPage); +} + +/* +** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES +** is defined, and NDEBUG is not defined, an assert() statement checks +** that the page is either dirty or still matches the calculated page-hash. +*/ +#define CHECK_PAGE(x) checkPage(x) +static void checkPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( pPager->eState!=PAGER_ERROR ); + assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); +} + +#else +#define pager_datahash(X,Y) 0 +#define pager_pagehash(X) 0 +#define pager_set_pagehash(X) +#define CHECK_PAGE(x) +#endif /* SQLITE_CHECK_PAGES */ + +/* +** When this is called the journal file for pager pPager must be open. +** This function attempts to read a super-journal file name from the +** end of the file and, if successful, copies it into memory supplied +** by the caller. See comments above writeSuperJournal() for the format +** used to store a super-journal file name at the end of a journal file. +** +** zSuper must point to a buffer of at least nSuper bytes allocated by +** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is +** enough space to write the super-journal name). If the super-journal +** name in the journal is longer than nSuper bytes (including a +** nul-terminator), then this is handled as if no super-journal name +** were present in the journal. +** +** If a super-journal file name is present at the end of the journal +** file, then it is copied into the buffer pointed to by zSuper. A +** nul-terminator byte is appended to the buffer following the +** super-journal file name. +** +** If it is determined that no super-journal file name is present +** zSuper[0] is set to 0 and SQLITE_OK returned. +** +** If an error occurs while reading from the journal file, an SQLite +** error code is returned. +*/ +static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u32 nSuper){ + int rc; /* Return code */ + u32 len; /* Length in bytes of super-journal name */ + i64 szJ; /* Total size in bytes of journal file pJrnl */ + u32 cksum; /* MJ checksum value read from journal */ + u32 u; /* Unsigned loop counter */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + zSuper[0] = '\0'; + + if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) + || szJ<16 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) + || len>=nSuper + || len>szJ-16 + || len==0 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) + || memcmp(aMagic, aJournalMagic, 8) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zSuper, len, szJ-16-len)) + ){ + return rc; + } + + /* See if the checksum matches the super-journal name */ + for(u=0; ujournalOff, assuming a sector +** size of pPager->sectorSize bytes. +** +** i.e for a sector size of 512: +** +** Pager.journalOff Return value +** --------------------------------------- +** 0 0 +** 512 512 +** 100 512 +** 2000 2048 +** +*/ +static i64 journalHdrOffset(Pager *pPager){ + i64 offset = 0; + i64 c = pPager->journalOff; + if( c ){ + offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); + } + assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); + assert( offset>=c ); + assert( (offset-c)jfd) ); + assert( !sqlite3JournalIsInMemory(pPager->jfd) ); + if( pPager->journalOff ){ + const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */ + + IOTRACE(("JZEROHDR %p\n", pPager)) + if( doTruncate || iLimit==0 ){ + rc = sqlite3OsTruncate(pPager->jfd, 0); + }else{ + static const char zeroHdr[28] = {0}; + rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); + } + if( rc==SQLITE_OK && !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); + } + + /* At this point the transaction is committed but the write lock + ** is still held on the file. If there is a size limit configured for + ** the persistent journal and the journal file currently consumes more + ** space than that limit allows for, truncate it now. There is no need + ** to sync the file following this operation. + */ + if( rc==SQLITE_OK && iLimit>0 ){ + i64 sz; + rc = sqlite3OsFileSize(pPager->jfd, &sz); + if( rc==SQLITE_OK && sz>iLimit ){ + rc = sqlite3OsTruncate(pPager->jfd, iLimit); + } + } + } + return rc; +} + +/* +** The journal file must be open when this routine is called. A journal +** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the +** current location. +** +** The format for the journal header is as follows: +** - 8 bytes: Magic identifying journal format. +** - 4 bytes: Number of records in journal, or -1 no-sync mode is on. +** - 4 bytes: Random number used for page hash. +** - 4 bytes: Initial database page count. +** - 4 bytes: Sector size used by the process that wrote this journal. +** - 4 bytes: Database page size. +** +** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. +*/ +static int writeJournalHdr(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */ + u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */ + u32 nWrite; /* Bytes of header sector written */ + int ii; /* Loop counter */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + if( nHeader>JOURNAL_HDR_SZ(pPager) ){ + nHeader = JOURNAL_HDR_SZ(pPager); + } + + /* If there are active savepoints and any of them were created + ** since the most recent journal header was written, update the + ** PagerSavepoint.iHdrOffset fields now. + */ + for(ii=0; iinSavepoint; ii++){ + if( pPager->aSavepoint[ii].iHdrOffset==0 ){ + pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff; + } + } + + pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); + + /* + ** Write the nRec Field - the number of page records that follow this + ** journal header. Normally, zero is written to this value at this time. + ** After the records are added to the journal (and the journal synced, + ** if in full-sync mode), the zero is overwritten with the true number + ** of records (see syncJournal()). + ** + ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When + ** reading the journal this value tells SQLite to assume that the + ** rest of the journal file contains valid page records. This assumption + ** is dangerous, as if a failure occurred whilst writing to the journal + ** file it may contain some garbage data. There are two scenarios + ** where this risk can be ignored: + ** + ** * When the pager is in no-sync mode. Corruption can follow a + ** power failure in this case anyway. + ** + ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees + ** that garbage data is never appended to the journal file. + */ + assert( isOpen(pPager->fd) || pPager->noSync ); + if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + ){ + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); + }else{ + memset(zHeader, 0, sizeof(aJournalMagic)+4); + } + + + + /* The random check-hash initializer */ + if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + } +#ifdef SQLITE_DEBUG + else{ + /* The Pager.cksumInit variable is usually randomized above to protect + ** against there being existing records in the journal file. This is + ** dangerous, as following a crash they may be mistaken for records + ** written by the current transaction and rolled back into the database + ** file, causing corruption. The following assert statements verify + ** that this is not required in "journal_mode=memory" mode, as in that + ** case the journal file is always 0 bytes in size at this point. + ** It is advantageous to avoid the sqlite3_randomness() call if possible + ** as it takes the global PRNG mutex. */ + i64 sz = 0; + sqlite3OsFileSize(pPager->jfd, &sz); + assert( sz==0 ); + assert( pPager->journalOff==journalHdrOffset(pPager) ); + assert( sqlite3JournalIsInMemory(pPager->jfd) ); + } +#endif + put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + + /* The initial database size */ + put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); + /* The assumed sector size for this process */ + put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); + + /* The page size */ + put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize); + + /* Initializing the tail of the buffer is not necessary. Everything + ** works find if the following memset() is omitted. But initializing + ** the memory prevents valgrind from complaining, so we are willing to + ** take the performance hit. + */ + memset(&zHeader[sizeof(aJournalMagic)+20], 0, + nHeader-(sizeof(aJournalMagic)+20)); + + /* In theory, it is only necessary to write the 28 bytes that the + ** journal header consumes to the journal file here. Then increment the + ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next + ** record is written to the following sector (leaving a gap in the file + ** that will be implicitly filled in by the OS). + ** + ** However it has been discovered that on some systems this pattern can + ** be significantly slower than contiguously writing data to the file, + ** even if that means explicitly writing data to the block of + ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what + ** is done. + ** + ** The loop is required here in case the sector-size is larger than the + ** database page size. Since the zHeader buffer is only Pager.pageSize + ** bytes in size, more than one call to sqlite3OsWrite() may be required + ** to populate the entire journal header sector. + */ + for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) + rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); + assert( pPager->journalHdr <= pPager->journalOff ); + pPager->journalOff += nHeader; + } + + return rc; +} + +/* +** The journal file must be open when this is called. A journal header file +** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal +** file. The current location in the journal file is given by +** pPager->journalOff. See comments above function writeJournalHdr() for +** a description of the journal header format. +** +** If the header is read successfully, *pNRec is set to the number of +** page records following this header and *pDbSize is set to the size of the +** database before the transaction began, in pages. Also, pPager->cksumInit +** is set to the value read from the journal header. SQLITE_OK is returned +** in this case. +** +** If the journal header file appears to be corrupted, SQLITE_DONE is +** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes +** cannot be read from the journal file an error code is returned. +*/ +static int readJournalHdr( + Pager *pPager, /* Pager object */ + int isHot, + i64 journalSize, /* Size of the open journal file in bytes */ + u32 *pNRec, /* OUT: Value read from the nRec field */ + u32 *pDbSize /* OUT: Value of original database size field */ +){ + int rc; /* Return code */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + i64 iHdrOff; /* Offset of journal header being read */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + /* Advance Pager.journalOff to the start of the next sector. If the + ** journal file is too small for there to be a header stored at this + ** point, return SQLITE_DONE. + */ + pPager->journalOff = journalHdrOffset(pPager); + if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ + return SQLITE_DONE; + } + iHdrOff = pPager->journalOff; + + /* Read in the first 8 bytes of the journal header. If they do not match + ** the magic string found at the start of each journal header, return + ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, + ** proceed. + */ + if( isHot || iHdrOff!=pPager->journalHdr ){ + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + if( rc ){ + return rc; + } + if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ + return SQLITE_DONE; + } + } + + /* Read the first three 32-bit fields of the journal header: The nRec + ** field, the checksum-initializer and the database size at the start + ** of the transaction. Return an error code if anything goes wrong. + */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize)) + ){ + return rc; + } + + if( pPager->journalOff==0 ){ + u32 iPageSize; /* Page-size field of journal header */ + u32 iSectorSize; /* Sector-size field of journal header */ + + /* Read the page-size and sector-size journal header fields. */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize)) + ){ + return rc; + } + + /* Versions of SQLite prior to 3.5.8 set the page-size field of the + ** journal header to zero. In this case, assume that the Pager.pageSize + ** variable is already set to the correct page size. + */ + if( iPageSize==0 ){ + iPageSize = pPager->pageSize; + } + + /* Check that the values read from the page-size and sector-size fields + ** are within range. To be 'in range', both values need to be a power + ** of two greater than or equal to 512 or 32, and not greater than their + ** respective compile time maximum limits. + */ + if( iPageSize<512 || iSectorSize<32 + || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE + || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 + ){ + /* If the either the page-size or sector-size in the journal-header is + ** invalid, then the process that wrote the journal-header must have + ** crashed before the header was synced. In this case stop reading + ** the journal file here. + */ + return SQLITE_DONE; + } + + /* Update the page-size to match the value read from the journal. + ** Use a testcase() macro to make sure that malloc failure within + ** PagerSetPagesize() is tested. + */ + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); + testcase( rc!=SQLITE_OK ); + + /* Update the assumed sector-size to match the value used by + ** the process that created this journal. If this journal was + ** created by a process other than this one, then this routine + ** is being called from within pager_playback(). The local value + ** of Pager.sectorSize is restored at the end of that routine. + */ + pPager->sectorSize = iSectorSize; + } + + pPager->journalOff += JOURNAL_HDR_SZ(pPager); + return rc; +} + + +/* +** Write the supplied super-journal name into the journal file for pager +** pPager at the current location. The super-journal name must be the last +** thing written to a journal file. If the pager is in full-sync mode, the +** journal file descriptor is advanced to the next sector boundary before +** anything is written. The format is: +** +** + 4 bytes: PAGER_SJ_PGNO. +** + N bytes: super-journal filename in utf-8. +** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator). +** + 4 bytes: super-journal name checksum. +** + 8 bytes: aJournalMagic[]. +** +** The super-journal page checksum is the sum of the bytes in the super-journal +** name, where each byte is interpreted as a signed 8-bit integer. +** +** If zSuper is a NULL pointer (occurs for a single database transaction), +** this call is a no-op. +*/ +static int writeSuperJournal(Pager *pPager, const char *zSuper){ + int rc; /* Return code */ + int nSuper; /* Length of string zSuper */ + i64 iHdrOff; /* Offset of header in journal file */ + i64 jrnlSize; /* Size of journal file on disk */ + u32 cksum = 0; /* Checksum of string zSuper */ + + assert( pPager->setSuper==0 ); + assert( !pagerUseWal(pPager) ); + + if( !zSuper + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || !isOpen(pPager->jfd) + ){ + return SQLITE_OK; + } + pPager->setSuper = 1; + assert( pPager->journalHdr <= pPager->journalOff ); + + /* Calculate the length in bytes and the checksum of zSuper */ + for(nSuper=0; zSuper[nSuper]; nSuper++){ + cksum += zSuper[nSuper]; + } + + /* If in full-sync mode, advance to the next disk sector before writing + ** the super-journal name. This is in case the previous page written to + ** the journal has already been synced. + */ + if( pPager->fullSync ){ + pPager->journalOff = journalHdrOffset(pPager); + } + iHdrOff = pPager->journalOff; + + /* Write the super-journal data to the end of the journal file. If + ** an error occurs, return the error code to the caller. + */ + if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager)))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, + iHdrOff+4+nSuper+8))) + ){ + return rc; + } + pPager->journalOff += (nSuper+20); + + /* If the pager is in persistent-journal mode, then the physical + ** journal-file may extend past the end of the super-journal name + ** and 8 bytes of magic data just written to the file. This is + ** dangerous because the code to rollback a hot-journal file + ** will not be able to find the super-journal name to determine + ** whether or not the journal is hot. + ** + ** Easiest thing to do in this scenario is to truncate the journal + ** file to the required size. + */ + if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) + && jrnlSize>pPager->journalOff + ){ + rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); + } + return rc; +} + +/* +** Discard the entire contents of the in-memory page-cache. +*/ +static void pager_reset(Pager *pPager){ + pPager->iDataVersion++; + sqlite3BackupRestart(pPager->pBackup); + sqlite3PcacheClear(pPager->pPCache); +} + +/* +** Return the pPager->iDataVersion value +*/ +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ + return pPager->iDataVersion; +} + +/* +** Free all structures in the Pager.aSavepoint[] array and set both +** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal +** if it is open and the pager is not in exclusive mode. +*/ +static void releaseAllSavepoints(Pager *pPager){ + int ii; /* Iterator for looping through Pager.aSavepoint */ + for(ii=0; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){ + sqlite3OsClose(pPager->sjfd); + } + sqlite3_free(pPager->aSavepoint); + pPager->aSavepoint = 0; + pPager->nSavepoint = 0; + pPager->nSubRec = 0; +} + +/* +** Set the bit number pgno in the PagerSavepoint.pInSavepoint +** bitvecs of all open savepoints. Return SQLITE_OK if successful +** or SQLITE_NOMEM if a malloc failure occurs. +*/ +static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ + int ii; /* Loop counter */ + int rc = SQLITE_OK; /* Result code */ + + for(ii=0; iinSavepoint; ii++){ + PagerSavepoint *p = &pPager->aSavepoint[ii]; + if( pgno<=p->nOrig ){ + rc |= sqlite3BitvecSet(p->pInSavepoint, pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + } + } + return rc; +} + +/* +** This function is a no-op if the pager is in exclusive mode and not +** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN +** state. +** +** If the pager is not in exclusive-access mode, the database file is +** completely unlocked. If the file is unlocked and the file-system does +** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is +** closed (if it is open). +** +** If the pager is in ERROR state when this function is called, the +** contents of the pager cache are discarded before switching back to +** the OPEN state. Regardless of whether the pager is in exclusive-mode +** or not, any journal file left in the file-system will be treated +** as a hot-journal and rolled back the next time a read-transaction +** is opened (by this or by any other connection). +*/ +static void pager_unlock(Pager *pPager){ + + assert( pPager->eState==PAGER_READER + || pPager->eState==PAGER_OPEN + || pPager->eState==PAGER_ERROR + ); + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + releaseAllSavepoints(pPager); + + if( pagerUseWal(pPager) ){ + assert( !isOpen(pPager->jfd) ); + sqlite3WalEndReadTransaction(pPager->pWal); + pPager->eState = PAGER_OPEN; + }else if( !pPager->exclusiveMode ){ + int rc; /* Error code returned by pagerUnlockDb() */ + int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; + + /* If the operating system support deletion of open files, then + ** close the journal file when dropping the database lock. Otherwise + ** another connection with journal_mode=delete might delete the file + ** out from under us. + */ + assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 ); + assert( (PAGER_JOURNALMODE_OFF & 5)!=1 ); + assert( (PAGER_JOURNALMODE_WAL & 5)!=1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) + || 1!=(pPager->journalMode & 5) + ){ + sqlite3OsClose(pPager->jfd); + } + + /* If the pager is in the ERROR state and the call to unlock the database + ** file fails, set the current lock to UNKNOWN_LOCK. See the comment + ** above the #define for UNKNOWN_LOCK for an explanation of why this + ** is necessary. + */ + rc = pagerUnlockDb(pPager, NO_LOCK); + if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){ + pPager->eLock = UNKNOWN_LOCK; + } + + /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here + ** without clearing the error code. This is intentional - the error + ** code is cleared and the cache reset in the block below. + */ + assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); + pPager->eState = PAGER_OPEN; + } + + /* If Pager.errCode is set, the contents of the pager cache cannot be + ** trusted. Now that there are no outstanding references to the pager, + ** it can safely move back to PAGER_OPEN state. This happens in both + ** normal and exclusive-locking mode. + */ + assert( pPager->errCode==SQLITE_OK || !MEMDB ); + if( pPager->errCode ){ + if( pPager->tempFile==0 ){ + pager_reset(pPager); + pPager->changeCountDone = 0; + pPager->eState = PAGER_OPEN; + }else{ + pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER); + } + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + pPager->errCode = SQLITE_OK; + setGetterMethod(pPager); + } + + pPager->journalOff = 0; + pPager->journalHdr = 0; + pPager->setSuper = 0; +} + +/* +** This function is called whenever an IOERR or FULL error that requires +** the pager to transition into the ERROR state may have occurred. +** The first argument is a pointer to the pager structure, the second +** the error-code about to be returned by a pager API function. The +** value returned is a copy of the second argument to this function. +** +** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the +** IOERR sub-codes, the pager enters the ERROR state and the error code +** is stored in Pager.errCode. While the pager remains in the ERROR state, +** all major API calls on the Pager will immediately return Pager.errCode. +** +** The ERROR state indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding +** the contents of the pager-cache. If a transaction was active when +** the persistent error occurred, then the rollback journal may need +** to be replayed to restore the contents of the database file (as if +** it were a hot-journal). +*/ +static int pager_error(Pager *pPager, int rc){ + int rc2 = rc & 0xff; + assert( rc==SQLITE_OK || !MEMDB ); + assert( + pPager->errCode==SQLITE_FULL || + pPager->errCode==SQLITE_OK || + (pPager->errCode & 0xff)==SQLITE_IOERR + ); + if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ + pPager->errCode = rc; + pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); + } + return rc; +} + +static int pager_truncate(Pager *pPager, Pgno nPage); + +/* +** The write transaction open on pPager is being committed (bCommit==1) +** or rolled back (bCommit==0). +** +** Return TRUE if and only if all dirty pages should be flushed to disk. +** +** Rules: +** +** * For non-TEMP databases, always sync to disk. This is necessary +** for transactions to be durable. +** +** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing +** file has been created already (via a spill on pagerStress()) and +** when the number of dirty pages in memory exceeds 25% of the total +** cache size. +*/ +static int pagerFlushOnCommit(Pager *pPager, int bCommit){ + if( pPager->tempFile==0 ) return 1; + if( !bCommit ) return 0; + if( !isOpen(pPager->fd) ) return 0; + return (sqlite3PCachePercentDirty(pPager->pPCache)>=25); +} + +/* +** This routine ends a transaction. A transaction is usually ended by +** either a COMMIT or a ROLLBACK operation. This routine may be called +** after rollback of a hot-journal, or if an error occurs while opening +** the journal file or writing the very first journal-header of a +** database transaction. +** +** This routine is never called in PAGER_ERROR state. If it is called +** in PAGER_NONE or PAGER_SHARED state and the lock held is less +** exclusive than a RESERVED lock, it is a no-op. +** +** Otherwise, any active savepoints are released. +** +** If the journal file is open, then it is "finalized". Once a journal +** file has been finalized it is not possible to use it to roll back a +** transaction. Nor will it be considered to be a hot-journal by this +** or any other database connection. Exactly how a journal is finalized +** depends on whether or not the pager is running in exclusive mode and +** the current journal-mode (Pager.journalMode value), as follows: +** +** journalMode==MEMORY +** Journal file descriptor is simply closed. This destroys an +** in-memory journal. +** +** journalMode==TRUNCATE +** Journal file is truncated to zero bytes in size. +** +** journalMode==PERSIST +** The first 28 bytes of the journal file are zeroed. This invalidates +** the first journal header in the file, and hence the entire journal +** file. An invalid journal file cannot be rolled back. +** +** journalMode==DELETE +** The journal file is closed and deleted using sqlite3OsDelete(). +** +** If the pager is running in exclusive mode, this method of finalizing +** the journal file is never used. Instead, if the journalMode is +** DELETE and the pager is in exclusive mode, the method described under +** journalMode==PERSIST is used instead. +** +** After the journal is finalized, the pager moves to PAGER_READER state. +** If running in non-exclusive rollback mode, the lock on the file is +** downgraded to a SHARED_LOCK. +** +** SQLITE_OK is returned if no error occurs. If an error occurs during +** any of the IO operations to finalize the journal file or unlock the +** database then the IO error code is returned to the user. If the +** operation to finalize the journal file fails, then the code still +** tries to unlock the database file if not in exclusive mode. If the +** unlock operation fails as well, then the first error code related +** to the first error encountered (the journal finalization one) is +** returned. +*/ +static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ + int rc = SQLITE_OK; /* Error code from journal finalization operation */ + int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ + + /* Do nothing if the pager does not have an open write transaction + ** or at least a RESERVED lock. This function may be called when there + ** is no write-transaction active but a RESERVED or greater lock is + ** held under two circumstances: + ** + ** 1. After a successful hot-journal rollback, it is called with + ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. + ** + ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE + ** lock switches back to locking_mode=normal and then executes a + ** read-transaction, this function is called with eState==PAGER_READER + ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. + */ + assert( assert_pager_state(pPager) ); + assert( pPager->eState!=PAGER_ERROR ); + if( pPager->eStateeLockjfd) || pPager->pInJournal==0 + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + ); + if( isOpen(pPager->jfd) ){ + assert( !pagerUseWal(pPager) ); + + /* Finalize the journal file. */ + if( sqlite3JournalIsInMemory(pPager->jfd) ){ + /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */ + sqlite3OsClose(pPager->jfd); + }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ + if( pPager->journalOff==0 ){ + rc = SQLITE_OK; + }else{ + rc = sqlite3OsTruncate(pPager->jfd, 0); + if( rc==SQLITE_OK && pPager->fullSync ){ + /* Make sure the new file size is written into the inode right away. + ** Otherwise the journal might resurrect following a power loss and + ** cause the last transaction to roll back. See + ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 + */ + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + } + } + pPager->journalOff = 0; + }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST + || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + ){ + rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile); + pPager->journalOff = 0; + }else{ + /* This branch may be executed with Pager.journalMode==MEMORY if + ** a hot-journal was just rolled back. In this case the journal + ** file should be closed and deleted. If this connection writes to + ** the database file, it will do so using an in-memory journal. + */ + int bDelete = !pPager->tempFile; + assert( sqlite3JournalIsInMemory(pPager->jfd)==0 ); + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + sqlite3OsClose(pPager->jfd); + if( bDelete ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); + } + } + } + +#ifdef SQLITE_CHECK_PAGES + sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ + PgHdr *p = sqlite3PagerLookup(pPager, 1); + if( p ){ + p->pageHash = 0; + sqlite3PagerUnrefNotNull(p); + } + } +#endif + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->nRec = 0; + if( rc==SQLITE_OK ){ + if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){ + sqlite3PcacheCleanAll(pPager->pPCache); + }else{ + sqlite3PcacheClearWritable(pPager->pPCache); + } + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); + } + + if( pagerUseWal(pPager) ){ + /* Drop the WAL write-lock, if any. Also, if the connection was in + ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE + ** lock held on the database file. + */ + rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); + assert( rc2==SQLITE_OK ); + }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ + /* This branch is taken when committing a transaction in rollback-journal + ** mode if the database file on disk is larger than the database image. + ** At this point the journal has been finalized and the transaction + ** successfully committed, but the EXCLUSIVE lock is still held on the + ** file. So it is safe to truncate the database file to its minimum + ** required size. */ + assert( pPager->eLock==EXCLUSIVE_LOCK ); + rc = pager_truncate(pPager, pPager->dbSize); + } + + if( rc==SQLITE_OK && bCommit ){ + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } + + if( !pPager->exclusiveMode + && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) + ){ + rc2 = pagerUnlockDb(pPager, SHARED_LOCK); + } + pPager->eState = PAGER_READER; + pPager->setSuper = 0; + + return (rc==SQLITE_OK?rc2:rc); +} + +/* Forward reference */ +static int pager_playback(Pager *pPager, int isHot); + +/* +** Execute a rollback if a transaction is active and unlock the +** database file. +** +** If the pager has already entered the ERROR state, do not attempt +** the rollback at this time. Instead, pager_unlock() is called. The +** call to pager_unlock() will discard all in-memory pages, unlock +** the database file and move the pager back to OPEN state. If this +** means that there is a hot-journal left in the file-system, the next +** connection to obtain a shared lock on the pager (which may be this one) +** will roll it back. +** +** If the pager has not already entered the ERROR state, but an IO or +** malloc error occurs during a rollback, then this will itself cause +** the pager to enter the ERROR state. Which will be cleared by the +** call to pager_unlock(), as described above. +*/ +static void pagerUnlockAndRollback(Pager *pPager){ + if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_LOCKED ){ + sqlite3BeginBenignMalloc(); + sqlite3PagerRollback(pPager); + sqlite3EndBenignMalloc(); + }else if( !pPager->exclusiveMode ){ + assert( pPager->eState==PAGER_READER ); + pager_end_transaction(pPager, 0, 0); + } + }else if( pPager->eState==PAGER_ERROR + && pPager->journalMode==PAGER_JOURNALMODE_MEMORY + && isOpen(pPager->jfd) + ){ + /* Special case for a ROLLBACK due to I/O error with an in-memory + ** journal: We have to rollback immediately, before the journal is + ** closed, because once it is closed, all content is forgotten. */ + int errCode = pPager->errCode; + u8 eLock = pPager->eLock; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + pPager->eLock = EXCLUSIVE_LOCK; + pager_playback(pPager, 1); + pPager->errCode = errCode; + pPager->eLock = eLock; + } + pager_unlock(pPager); +} + +/* +** Parameter aData must point to a buffer of pPager->pageSize bytes +** of data. Compute and return a checksum based on the contents of the +** page of data and the current value of pPager->cksumInit. +** +** This is not a real checksum. It is really just the sum of the +** random initial value (pPager->cksumInit) and every 200th byte +** of the page data, starting with byte offset (pPager->pageSize%200). +** Each byte is interpreted as an 8-bit unsigned integer. +** +** Changing the formula used to compute this checksum results in an +** incompatible journal file format. +** +** If journal corruption occurs due to a power failure, the most likely +** scenario is that one end or the other of the record will be changed. +** It is much less likely that the two ends of the journal record will be +** correct and the middle be corrupt. Thus, this "checksum" scheme, +** though fast and simple, catches the mostly likely kind of corruption. +*/ +static u32 pager_cksum(Pager *pPager, const u8 *aData){ + u32 cksum = pPager->cksumInit; /* Checksum value to return */ + int i = pPager->pageSize-200; /* Loop counter */ + while( i>0 ){ + cksum += aData[i]; + i -= 200; + } + return cksum; +} + +/* +** Read a single page from either the journal file (if isMainJrnl==1) or +** from the sub-journal (if isMainJrnl==0) and playback that page. +** The page begins at offset *pOffset into the file. The *pOffset +** value is increased to the start of the next page in the journal. +** +** The main rollback journal uses checksums - the statement journal does +** not. +** +** If the page number of the page record read from the (sub-)journal file +** is greater than the current value of Pager.dbSize, then playback is +** skipped and SQLITE_OK is returned. +** +** If pDone is not NULL, then it is a record of pages that have already +** been played back. If the page at *pOffset has already been played back +** (if the corresponding pDone bit is set) then skip the playback. +** Make sure the pDone bit corresponding to the *pOffset page is set +** prior to returning. +** +** If the page record is successfully read from the (sub-)journal file +** and played back, then SQLITE_OK is returned. If an IO error occurs +** while reading the record from the (sub-)journal file or while writing +** to the database file, then the IO error code is returned. If data +** is successfully read from the (sub-)journal file but appears to be +** corrupted, SQLITE_DONE is returned. Data is considered corrupted in +** two circumstances: +** +** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or +** * If the record is being rolled back from the main journal file +** and the checksum field does not match the record content. +** +** Neither of these two scenarios are possible during a savepoint rollback. +** +** If this is a savepoint rollback, then memory may have to be dynamically +** allocated by this function. If this is the case and an allocation fails, +** SQLITE_NOMEM is returned. +*/ +static int pager_playback_one_page( + Pager *pPager, /* The pager being played back */ + i64 *pOffset, /* Offset of record to playback */ + Bitvec *pDone, /* Bitvec of pages already played back */ + int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ + int isSavepnt /* True for a savepoint rollback */ +){ + int rc; + PgHdr *pPg; /* An existing page in the cache */ + Pgno pgno; /* The page number of a page in journal */ + u32 cksum; /* Checksum used for sanity checking */ + char *aData; /* Temporary storage for the page */ + sqlite3_file *jfd; /* The file descriptor for the journal file */ + int isSynced; /* True if journal page is synced */ + + assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ + assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ + assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ + assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ + + aData = pPager->pTmpSpace; + assert( aData ); /* Temp storage must have already been allocated */ + assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); + + /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction + ** or savepoint rollback done at the request of the caller) or this is + ** a hot-journal rollback. If it is a hot-journal rollback, the pager + ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback + ** only reads from the main journal, not the sub-journal. + */ + assert( pPager->eState>=PAGER_WRITER_CACHEMOD + || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK) + ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl ); + + /* Read the page number and page data from the journal or sub-journal + ** file. Return an error code to the caller if an IO error occurs. + */ + jfd = isMainJrnl ? pPager->jfd : pPager->sjfd; + rc = read32bits(jfd, *pOffset, &pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); + if( rc!=SQLITE_OK ) return rc; + *pOffset += pPager->pageSize + 4 + isMainJrnl*4; + + /* Sanity checking on the page. This is more important that I originally + ** thought. If a power failure occurs while the journal is being written, + ** it could cause invalid data to be written into the journal. We need to + ** detect this invalid data (with high probability) and ignore it. + */ + if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){ + assert( !isSavepnt ); + return SQLITE_DONE; + } + if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ + return SQLITE_OK; + } + if( isMainJrnl ){ + rc = read32bits(jfd, (*pOffset)-4, &cksum); + if( rc ) return rc; + if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ + return SQLITE_DONE; + } + } + + /* If this page has already been played back before during the current + ** rollback, then don't bother to play it back again. + */ + if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ + return rc; + } + + /* When playing back page 1, restore the nReserve setting + */ + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ + pPager->nReserve = ((u8*)aData)[20]; + } + + /* If the pager is in CACHEMOD state, then there must be a copy of this + ** page in the pager cache. In this case just update the pager cache, + ** not the database file. The page is left marked dirty in this case. + ** + ** An exception to the above rule: If the database is in no-sync mode + ** and a page is moved during an incremental vacuum then the page may + ** not be in the pager cache. Later: if a malloc() or IO error occurs + ** during a Movepage() call, then the page may not be in the cache + ** either. So the condition described in the above paragraph is not + ** assert()able. + ** + ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the + ** pager cache if it exists and the main file. The page is then marked + ** not dirty. Since this code is only executed in PAGER_OPEN state for + ** a hot-journal rollback, it is guaranteed that the page-cache is empty + ** if the pager is in OPEN state. + ** + ** Ticket #1171: The statement journal might contain page content that is + ** different from the page content at the start of the transaction. + ** This occurs when a page is changed prior to the start of a statement + ** then changed again within the statement. When rolling back such a + ** statement we must not write to the original database unless we know + ** for certain that original page contents are synced into the main rollback + ** journal. Otherwise, a power loss might leave modified data in the + ** database file without an entry in the rollback journal that can + ** restore the database to its original form. Two conditions must be + ** met before writing to the database files. (1) the database must be + ** locked. (2) we know that the original page content is fully synced + ** in the main journal either because the page is not in cache or else + ** the page is marked as needSync==0. + ** + ** 2008-04-14: When attempting to vacuum a corrupt database file, it + ** is possible to fail a statement on a database that does not yet exist. + ** Do not attempt to write if database file has never been opened. + */ + if( pagerUseWal(pPager) ){ + pPg = 0; + }else{ + pPg = sqlite3PagerLookup(pPager, pgno); + } + assert( pPg || !MEMDB ); + assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile ); + PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", + PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), + (isMainJrnl?"main-journal":"sub-journal") + )); + if( isMainJrnl ){ + isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr); + }else{ + isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC)); + } + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + && isSynced + ){ + i64 ofst = (pgno-1)*(i64)pPager->pageSize; + testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); + assert( !pagerUseWal(pPager) ); + + /* Write the data read from the journal back into the database file. + ** This is usually safe even for an encrypted database - as the data + ** was encrypted before it was written to the journal file. The exception + ** is if the data was just read from an in-memory sub-journal. In that + ** case it must be encrypted here before it is copied into the database + ** file. */ + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + if( pPager->pBackup ){ + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + } + }else if( !isMainJrnl && pPg==0 ){ + /* If this is a rollback of a savepoint and data was not written to + ** the database and the page is not in-memory, there is a potential + ** problem. When the page is next fetched by the b-tree layer, it + ** will be read from the database file, which may or may not be + ** current. + ** + ** There are a couple of different ways this can happen. All are quite + ** obscure. When running in synchronous mode, this can only happen + ** if the page is on the free-list at the start of the transaction, then + ** populated, then moved using sqlite3PagerMovepage(). + ** + ** The solution is to add an in-memory page to the cache containing + ** the data just read from the sub-journal. Mark the page as dirty + ** and if the pager requires a journal-sync, then mark the page as + ** requiring a journal-sync before it is written. + */ + assert( isSavepnt ); + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); + pPager->doNotSpill |= SPILLFLAG_ROLLBACK; + rc = sqlite3PagerGet(pPager, pgno, &pPg, 1); + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); + pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; + if( rc!=SQLITE_OK ) return rc; + sqlite3PcacheMakeDirty(pPg); + } + if( pPg ){ + /* No page should ever be explicitly rolled back that is in use, except + ** for page 1 which is held in use in order to keep the lock on the + ** database active. However such a page may be rolled back as a result + ** of an internal error resulting in an automatic call to + ** sqlite3PagerRollback(). + */ + void *pData; + pData = pPg->pData; + memcpy(pData, (u8*)aData, pPager->pageSize); + pPager->xReiniter(pPg); + /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But + ** that call was dangerous and had no detectable benefit since the cache + ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so + ** has been removed. */ + pager_set_pagehash(pPg); + + /* If this was page 1, then restore the value of Pager.dbFileVers. + ** Do this before any decoding. */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); + } + sqlite3PcacheRelease(pPg); + } + return rc; +} + +/* +** Parameter zSuper is the name of a super-journal file. A single journal +** file that referred to the super-journal file has just been rolled back. +** This routine checks if it is possible to delete the super-journal file, +** and does so if it is. +** +** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not +** available for use within this function. +** +** When a super-journal file is created, it is populated with the names +** of all of its child journals, one after another, formatted as utf-8 +** encoded text. The end of each child journal file is marked with a +** nul-terminator byte (0x00). i.e. the entire contents of a super-journal +** file for a transaction involving two databases might be: +** +** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" +** +** A super-journal file may only be deleted once all of its child +** journals have been rolled back. +** +** This function reads the contents of the super-journal file into +** memory and loops through each of the child journal names. For +** each child journal, it checks if: +** +** * if the child journal exists, and if so +** * if the child journal contains a reference to super-journal +** file zSuper +** +** If a child journal can be found that matches both of the criteria +** above, this function returns without doing anything. Otherwise, if +** no such child journal can be found, file zSuper is deleted from +** the file-system using sqlite3OsDelete(). +** +** If an IO error within this function, an error code is returned. This +** function allocates memory by calling sqlite3Malloc(). If an allocation +** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors +** occur, SQLITE_OK is returned. +** +** TODO: This function allocates a single block of memory to load +** the entire contents of the super-journal file. This could be +** a couple of kilobytes or so - potentially larger than the page +** size. +*/ +static int pager_delsuper(Pager *pPager, const char *zSuper){ + sqlite3_vfs *pVfs = pPager->pVfs; + int rc; /* Return code */ + sqlite3_file *pSuper; /* Malloc'd super-journal file descriptor */ + sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ + char *zSuperJournal = 0; /* Contents of super-journal file */ + i64 nSuperJournal; /* Size of super-journal file */ + char *zJournal; /* Pointer to one journal within MJ file */ + char *zSuperPtr; /* Space to hold super-journal filename */ + char *zFree = 0; /* Free this buffer */ + int nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ + + /* Allocate space for both the pJournal and pSuper file descriptors. + ** If successful, open the super-journal file for reading. + */ + pSuper = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); + if( !pSuper ){ + rc = SQLITE_NOMEM_BKPT; + pJournal = 0; + }else{ + const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zSuper, pSuper, flags, 0); + pJournal = (sqlite3_file *)(((u8 *)pSuper) + pVfs->szOsFile); + } + if( rc!=SQLITE_OK ) goto delsuper_out; + + /* Load the entire super-journal file into space obtained from + ** sqlite3_malloc() and pointed to by zSuperJournal. Also obtain + ** sufficient space (in zSuperPtr) to hold the names of super-journal + ** files extracted from regular rollback-journals. + */ + rc = sqlite3OsFileSize(pSuper, &nSuperJournal); + if( rc!=SQLITE_OK ) goto delsuper_out; + nSuperPtr = pVfs->mxPathname+1; + zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); + if( !zFree ){ + rc = SQLITE_NOMEM_BKPT; + goto delsuper_out; + } + zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; + zSuperJournal = &zFree[4]; + zSuperPtr = &zSuperJournal[nSuperJournal+2]; + rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); + if( rc!=SQLITE_OK ) goto delsuper_out; + zSuperJournal[nSuperJournal] = 0; + zSuperJournal[nSuperJournal+1] = 0; + + zJournal = zSuperJournal; + while( (zJournal-zSuperJournal)pageSize bytes). +** If the file on disk is currently larger than nPage pages, then use the VFS +** xTruncate() method to truncate it. +** +** Or, it might be the case that the file on disk is smaller than +** nPage pages. Some operating system implementations can get confused if +** you try to truncate a file to some size that is larger than it +** currently is, so detect this case and write a single zero byte to +** the end of the new file instead. +** +** If successful, return SQLITE_OK. If an IO error occurs while modifying +** the database file, return the error code to the caller. +*/ +static int pager_truncate(Pager *pPager, Pgno nPage){ + int rc = SQLITE_OK; + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState!=PAGER_READER ); + PAGERTRACE(("Truncate %d npage %u\n", PAGERID(pPager), nPage)); + + + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + i64 currentSize, newSize; + int szPage = pPager->pageSize; + assert( pPager->eLock==EXCLUSIVE_LOCK ); + /* TODO: Is it safe to use Pager.dbFileSize here? */ + rc = sqlite3OsFileSize(pPager->fd, ¤tSize); + newSize = szPage*(i64)nPage; + if( rc==SQLITE_OK && currentSize!=newSize ){ + if( currentSize>newSize ){ + rc = sqlite3OsTruncate(pPager->fd, newSize); + }else if( (currentSize+szPage)<=newSize ){ + char *pTmp = pPager->pTmpSpace; + memset(pTmp, 0, szPage); + testcase( (newSize-szPage) == currentSize ); + testcase( (newSize-szPage) > currentSize ); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &newSize); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); + } + if( rc==SQLITE_OK ){ + pPager->dbFileSize = nPage; + } + } + } + return rc; +} + +/* +** Return a sanitized version of the sector-size of OS file pFile. The +** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE. +*/ +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){ + int iRet = sqlite3OsSectorSize(pFile); + if( iRet<32 ){ + iRet = 512; + }else if( iRet>MAX_SECTOR_SIZE ){ + assert( MAX_SECTOR_SIZE>=512 ); + iRet = MAX_SECTOR_SIZE; + } + return iRet; +} + +/* +** Set the value of the Pager.sectorSize variable for the given +** pager based on the value returned by the xSectorSize method +** of the open database file. The sector size will be used +** to determine the size and alignment of journal header and +** super-journal pointers within created journal files. +** +** For temporary files the effective sector size is always 512 bytes. +** +** Otherwise, for non-temporary files, the effective sector size is +** the value returned by the xSectorSize() method rounded up to 32 if +** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it +** is greater than MAX_SECTOR_SIZE. +** +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set +** the effective sector size to its minimum value (512). The purpose of +** pPager->sectorSize is to define the "blast radius" of bytes that +** might change if a crash occurs while writing to a single byte in +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector +** size. For backwards compatibility of the rollback journal file format, +** we cannot reduce the effective sector size below 512. +*/ +static void setSectorSize(Pager *pPager){ + assert( isOpen(pPager->fd) || pPager->tempFile ); + + if( pPager->tempFile + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 + ){ + /* Sector size doesn't matter for temporary files. Also, the file + ** may not have been opened yet, in which case the OsSectorSize() + ** call will segfault. */ + pPager->sectorSize = 512; + }else{ + pPager->sectorSize = sqlite3SectorSize(pPager->fd); + } +} + +/* +** Playback the journal and thus restore the database file to +** the state it was in before we started making changes. +** +** The journal file format is as follows: +** +** (1) 8 byte prefix. A copy of aJournalMagic[]. +** (2) 4 byte big-endian integer which is the number of valid page records +** in the journal. If this value is 0xffffffff, then compute the +** number of page records from the journal size. +** (3) 4 byte big-endian integer which is the initial value for the +** sanity checksum. +** (4) 4 byte integer which is the number of pages to truncate the +** database to during a rollback. +** (5) 4 byte big-endian integer which is the sector size. The header +** is this many bytes in size. +** (6) 4 byte big-endian integer which is the page size. +** (7) zero padding out to the next sector size. +** (8) Zero or more pages instances, each as follows: +** + 4 byte page number. +** + pPager->pageSize bytes of data. +** + 4 byte checksum +** +** When we speak of the journal header, we mean the first 7 items above. +** Each entry in the journal is an instance of the 8th item. +** +** Call the value from the second bullet "nRec". nRec is the number of +** valid page entries in the journal. In most cases, you can compute the +** value of nRec from the size of the journal file. But if a power +** failure occurred while the journal was being written, it could be the +** case that the size of the journal file had already been increased but +** the extra entries had not yet made it safely to disk. In such a case, +** the value of nRec computed from the file size would be too large. For +** that reason, we always use the nRec value in the header. +** +** If the nRec value is 0xffffffff it means that nRec should be computed +** from the file size. This value is used when the user selects the +** no-sync option for the journal. A power failure could lead to corruption +** in this case. But for things like temporary table (which will be +** deleted when the power is restored) we don't care. +** +** If the file opened as the journal file is not a well-formed +** journal file then all pages up to the first corrupted page are rolled +** back (or no pages if the journal header is corrupted). The journal file +** is then deleted and SQLITE_OK returned, just as if no corruption had +** been encountered. +** +** If an I/O or malloc() error occurs, the journal-file is not deleted +** and an error code is returned. +** +** The isHot parameter indicates that we are trying to rollback a journal +** that might be a hot journal. Or, it could be that the journal is +** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. +** If the journal really is hot, reset the pager cache prior rolling +** back any content. If the journal is merely persistent, no reset is +** needed. +*/ +static int pager_playback(Pager *pPager, int isHot){ + sqlite3_vfs *pVfs = pPager->pVfs; + i64 szJ; /* Size of the journal file in bytes */ + u32 nRec; /* Number of Records in the journal */ + u32 u; /* Unsigned loop counter */ + Pgno mxPg = 0; /* Size of the original file in pages */ + int rc; /* Result code of a subroutine */ + int res = 1; /* Value returned by sqlite3OsAccess() */ + char *zSuper = 0; /* Name of super-journal file if any */ + int needPagerReset; /* True to reset page prior to first page rollback */ + int nPlayback = 0; /* Total number of pages restored from journal */ + u32 savedPageSize = pPager->pageSize; + + /* Figure out how many records are in the journal. Abort early if + ** the journal is empty. + */ + assert( isOpen(pPager->jfd) ); + rc = sqlite3OsFileSize(pPager->jfd, &szJ); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + + /* Read the super-journal name from the journal, if it is present. + ** If a super-journal file name is specified, but the file is not + ** present on disk, then the journal is not hot and does not need to be + ** played back. + ** + ** TODO: Technically the following is an error because it assumes that + ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that + ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c, + ** mxPathname is 512, which is the same as the minimum allowable value + ** for pageSize. + */ + zSuper = pPager->pTmpSpace; + rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); + if( rc==SQLITE_OK && zSuper[0] ){ + rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); + } + zSuper = 0; + if( rc!=SQLITE_OK || !res ){ + goto end_playback; + } + pPager->journalOff = 0; + needPagerReset = isHot; + + /* This loop terminates either when a readJournalHdr() or + ** pager_playback_one_page() call returns SQLITE_DONE or an IO error + ** occurs. + */ + while( 1 ){ + /* Read the next journal header from the journal file. If there are + ** not enough bytes left in the journal file for a complete header, or + ** it is corrupted, then a process must have failed while writing it. + ** This indicates nothing more needs to be rolled back. + */ + rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + goto end_playback; + } + + /* If nRec is 0xffffffff, then this journal was created by a process + ** working in no-sync mode. This means that the rest of the journal + ** file consists of pages, there are no more journal headers. Compute + ** the value of nRec based on this assumption. + */ + if( nRec==0xffffffff ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); + nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager)); + } + + /* If nRec is 0 and this rollback is of a transaction created by this + ** process and if this is the final header in the journal, then it means + ** that this part of the journal was being filled but has not yet been + ** synced to disk. Compute the number of pages based on the remaining + ** size of the file. + ** + ** The third term of the test was added to fix ticket #2565. + ** When rolling back a hot journal, nRec==0 always means that the next + ** chunk of the journal contains zero pages to be rolled back. But + ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in + ** the journal, it means that the journal might contain additional + ** pages that need to be rolled back and that the number of pages + ** should be computed based on the journal file size. + */ + if( nRec==0 && !isHot && + pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ + nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); + } + + /* If this is the first header read from the journal, truncate the + ** database file back to its original size. + */ + if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ + rc = pager_truncate(pPager, mxPg); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + pPager->dbSize = mxPg; + if( pPager->mxPgnomxPgno = mxPg; + } + } + + /* Copy original pages out of the journal and back into the + ** database file and/or page cache. + */ + for(u=0; ujournalOff,0,1,0); + if( rc==SQLITE_OK ){ + nPlayback++; + }else{ + if( rc==SQLITE_DONE ){ + pPager->journalOff = szJ; + break; + }else if( rc==SQLITE_IOERR_SHORT_READ ){ + /* If the journal has been truncated, simply stop reading and + ** processing the journal. This might happen if the journal was + ** not completely written and synced prior to a crash. In that + ** case, the database should have never been written in the + ** first place so it is OK to simply abandon the rollback. */ + rc = SQLITE_OK; + goto end_playback; + }else{ + /* If we are unable to rollback, quit and return the error + ** code. This will cause the pager to enter the error state + ** so that no further harm will be done. Perhaps the next + ** process to come along will be able to rollback the database. + */ + goto end_playback; + } + } + } + } + /*NOTREACHED*/ + assert( 0 ); + +end_playback: + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1); + } + /* Following a rollback, the database file should be back in its original + ** state prior to the start of the transaction, so invoke the + ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the + ** assertion that the transaction counter was modified. + */ +#ifdef SQLITE_DEBUG + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); +#endif + + /* If this playback is happening automatically as a result of an IO or + ** malloc error that occurred after the change-counter was updated but + ** before the transaction was committed, then the change-counter + ** modification may just have been reverted. If this happens in exclusive + ** mode, then subsequent transactions performed by the connection will not + ** update the change-counter at all. This may lead to cache inconsistency + ** problems for other processes at some point in the future. So, just + ** in case this has happened, clear the changeCountDone flag now. + */ + pPager->changeCountDone = pPager->tempFile; + + if( rc==SQLITE_OK ){ + /* Leave 4 bytes of space before the super-journal filename in memory. + ** This is because it may end up being passed to sqlite3OsOpen(), in + ** which case it requires 4 0x00 bytes in memory immediately before + ** the filename. */ + zSuper = &pPager->pTmpSpace[4]; + rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + rc = sqlite3PagerSync(pPager, 0); + } + if( rc==SQLITE_OK ){ + rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK && zSuper[0] && res ){ + /* If there was a super-journal and this routine will return success, + ** see if it is possible to delete the super-journal. + */ + assert( zSuper==&pPager->pTmpSpace[4] ); + memset(pPager->pTmpSpace, 0, 4); + rc = pager_delsuper(pPager, zSuper); + testcase( rc!=SQLITE_OK ); + } + if( isHot && nPlayback ){ + sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", + nPlayback, pPager->zJournal); + } + + /* The Pager.sectorSize variable may have been updated while rolling + ** back a journal created by a process with a different sector size + ** value. Reset it to the correct value for this process. + */ + setSectorSize(pPager); + return rc; +} + + +/* +** Read the content for page pPg out of the database file (or out of +** the WAL if that is where the most recent copy if found) into +** pPg->pData. A shared lock or greater must be held on the database +** file before this function is called. +** +** If page 1 is read, then the value of Pager.dbFileVers[] is set to +** the value read from the database file. +** +** If an IO error occurs, then the IO error is returned to the caller. +** Otherwise, SQLITE_OK is returned. +*/ +static int readDbPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ + int rc = SQLITE_OK; /* Return code */ + +#ifndef SQLITE_OMIT_WAL + u32 iFrame = 0; /* Frame of WAL containing pgno */ + + assert( pPager->eState>=PAGER_READER && !MEMDB ); + assert( isOpen(pPager->fd) ); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); + if( rc ) return rc; + } + if( iFrame ){ + rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); + }else +#endif + { + i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + + if( pPg->pgno==1 ){ + if( rc ){ + /* If the read is unsuccessful, set the dbFileVers[] to something + ** that will never be a valid file version. dbFileVers[] is a copy + ** of bytes 24..39 of the database. Bytes 28..31 should always be + ** zero or the size of the database in page. Bytes 32..35 and 35..39 + ** should be page numbers which are never 0xffffffff. So filling + ** pPager->dbFileVers[] with all 0xff bytes should suffice. + ** + ** For an encrypted database, the situation is more complex: bytes + ** 24..39 of the database are white noise. But the probability of + ** white noise equaling 16 bytes of 0xff is vanishingly small so + ** we should still be ok. + */ + memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); + }else{ + u8 *dbFileVers = &((u8*)pPg->pData)[24]; + memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); + } + } + PAGER_INCR(sqlite3_pager_readdb_count); + PAGER_INCR(pPager->nRead); + IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); + PAGERTRACE(("FETCH %d page %d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, pager_pagehash(pPg))); + + return rc; +} + +/* +** Update the value of the change-counter at offsets 24 and 92 in +** the header and the sqlite version number at offset 96. +** +** This is an unconditional update. See also the pager_incr_changecounter() +** routine which only updates the change-counter if the update is actually +** needed, as determined by the pPager->changeCountDone state variable. +*/ +static void pager_write_changecounter(PgHdr *pPg){ + u32 change_counter; + if( NEVER(pPg==0) ) return; + + /* Increment the value just read and write it back to byte 24. */ + change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; + put32bits(((char*)pPg->pData)+24, change_counter); + + /* Also store the SQLite version number in bytes 96..99 and in + ** bytes 92..95 store the change counter for which the version number + ** is valid. */ + put32bits(((char*)pPg->pData)+92, change_counter); + put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER); +} + +#ifndef SQLITE_OMIT_WAL +/* +** This function is invoked once for each page that has already been +** written into the log file when a WAL transaction is rolled back. +** Parameter iPg is the page number of said page. The pCtx argument +** is actually a pointer to the Pager structure. +** +** If page iPg is present in the cache, and has no outstanding references, +** it is discarded. Otherwise, if there are one or more outstanding +** references, the page content is reloaded from the database. If the +** attempt to reload content from the database is required and fails, +** return an SQLite error code. Otherwise, SQLITE_OK. +*/ +static int pagerUndoCallback(void *pCtx, Pgno iPg){ + int rc = SQLITE_OK; + Pager *pPager = (Pager *)pCtx; + PgHdr *pPg; + + assert( pagerUseWal(pPager) ); + pPg = sqlite3PagerLookup(pPager, iPg); + if( pPg ){ + if( sqlite3PcachePageRefcount(pPg)==1 ){ + sqlite3PcacheDrop(pPg); + }else{ + rc = readDbPage(pPg); + if( rc==SQLITE_OK ){ + pPager->xReiniter(pPg); + } + sqlite3PagerUnrefNotNull(pPg); + } + } + + /* Normally, if a transaction is rolled back, any backup processes are + ** updated as data is copied out of the rollback journal and into the + ** database. This is not generally possible with a WAL database, as + ** rollback involves simply truncating the log file. Therefore, if one + ** or more frames have already been written to the log (and therefore + ** also copied into the backup databases) as part of this transaction, + ** the backups must be restarted. + */ + sqlite3BackupRestart(pPager->pBackup); + + return rc; +} + +/* +** This function is called to rollback a transaction on a WAL database. +*/ +static int pagerRollbackWal(Pager *pPager){ + int rc; /* Return Code */ + PgHdr *pList; /* List of dirty pages to revert */ + + /* For all pages in the cache that are currently dirty or have already + ** been written (but not committed) to the log file, do one of the + ** following: + ** + ** + Discard the cached page (if refcount==0), or + ** + Reload page content from the database (if refcount>0). + */ + pPager->dbSize = pPager->dbOrigSize; + rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + pList = sqlite3PcacheDirtyList(pPager->pPCache); + while( pList && rc==SQLITE_OK ){ + PgHdr *pNext = pList->pDirty; + rc = pagerUndoCallback((void *)pPager, pList->pgno); + pList = pNext; + } + + return rc; +} + +/* +** This function is a wrapper around sqlite3WalFrames(). As well as logging +** the contents of the list of pages headed by pList (connected by pDirty), +** this function notifies any active backup processes that the pages have +** changed. +** +** The list of pages passed into this routine is always sorted by page number. +** Hence, if page 1 appears anywhere on the list, it will be the first page. +*/ +static int pagerWalFrames( + Pager *pPager, /* Pager object */ + PgHdr *pList, /* List of frames to log */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit /* True if this is a commit */ +){ + int rc; /* Return code */ + int nList; /* Number of pages in pList */ + PgHdr *p; /* For looping over pages */ + + assert( pPager->pWal ); + assert( pList ); +#ifdef SQLITE_DEBUG + /* Verify that the page list is in ascending order */ + for(p=pList; p && p->pDirty; p=p->pDirty){ + assert( p->pgno < p->pDirty->pgno ); + } +#endif + + assert( pList->pDirty==0 || isCommit ); + if( isCommit ){ + /* If a WAL transaction is being committed, there is no point in writing + ** any pages with page numbers greater than nTruncate into the WAL file. + ** They will never be read by any client. So remove them from the pDirty + ** list here. */ + PgHdr **ppNext = &pList; + nList = 0; + for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ + if( p->pgno<=nTruncate ){ + ppNext = &p->pDirty; + nList++; + } + } + assert( pList ); + }else{ + nList = 1; + } + pPager->aStat[PAGER_STAT_WRITE] += nList; + + if( pList->pgno==1 ) pager_write_changecounter(pList); + rc = sqlite3WalFrames(pPager->pWal, + pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags + ); + if( rc==SQLITE_OK && pPager->pBackup ){ + for(p=pList; p; p=p->pDirty){ + sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); + } + } + +#ifdef SQLITE_CHECK_PAGES + pList = sqlite3PcacheDirtyList(pPager->pPCache); + for(p=pList; p; p=p->pDirty){ + pager_set_pagehash(p); + } +#endif + + return rc; +} + +/* +** Begin a read transaction on the WAL. +** +** This routine used to be called "pagerOpenSnapshot()" because it essentially +** makes a snapshot of the database at the current point in time and preserves +** that snapshot for use by the reader in spite of concurrently changes by +** other writers or checkpointers. +*/ +static int pagerBeginReadTransaction(Pager *pPager){ + int rc; /* Return code */ + int changed = 0; /* True if cache must be reset */ + + assert( pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + + /* sqlite3WalEndReadTransaction() was not called for the previous + ** transaction in locking_mode=EXCLUSIVE. So call it now. If we + ** are in locking_mode=NORMAL and EndRead() was previously called, + ** the duplicate call is harmless. + */ + sqlite3WalEndReadTransaction(pPager->pWal); + + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + if( rc!=SQLITE_OK || changed ){ + pager_reset(pPager); + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + } + + return rc; +} +#endif + +/* +** This function is called as part of the transition from PAGER_OPEN +** to PAGER_READER state to determine the size of the database file +** in pages (assuming the page size currently stored in Pager.pageSize). +** +** If no error occurs, SQLITE_OK is returned and the size of the database +** in pages is stored in *pnPage. Otherwise, an error code (perhaps +** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified. +*/ +static int pagerPagecount(Pager *pPager, Pgno *pnPage){ + Pgno nPage; /* Value to return via *pnPage */ + + /* Query the WAL sub-system for the database size. The WalDbsize() + ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or + ** if the database size is not available. The database size is not + ** available from the WAL sub-system if the log file is empty or + ** contains no valid committed transactions. + */ + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK ); + assert( isOpen(pPager->fd) ); + assert( pPager->tempFile==0 ); + nPage = sqlite3WalDbsize(pPager->pWal); + + /* If the number of pages in the database is not available from the + ** WAL sub-system, determine the page count based on the size of + ** the database file. If the size of the database file is not an + ** integer multiple of the page-size, round up the result. + */ + if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){ + i64 n = 0; /* Size of db file in bytes */ + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; + } + nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); + } + + /* If the current number of pages in the file is greater than the + ** configured maximum pager number, increase the allowed limit so + ** that the file can be read. + */ + if( nPage>pPager->mxPgno ){ + pPager->mxPgno = (Pgno)nPage; + } + + *pnPage = nPage; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Check if the *-wal file that corresponds to the database opened by pPager +** exists if the database is not empty, or verify that the *-wal file does +** not exist (by deleting it) if the database file is empty. +** +** If the database is not empty and the *-wal file exists, open the pager +** in WAL mode. If the database is empty or if no *-wal file exists and +** if no error occurs, make sure Pager.journalMode is not set to +** PAGER_JOURNALMODE_WAL. +** +** Return SQLITE_OK or an error code. +** +** The caller must hold a SHARED lock on the database file to call this +** function. Because an EXCLUSIVE lock on the db file is required to delete +** a WAL on a none-empty database, this ensures there is no race condition +** between the xAccess() below and an xDelete() being executed by some +** other connection. +*/ +static int pagerOpenWalIfPresent(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK ); + + if( !pPager->tempFile ){ + int isWal; /* True if WAL file exists */ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal + ); + if( rc==SQLITE_OK ){ + if( isWal ){ + Pgno nPage; /* Size of the database file */ + + rc = pagerPagecount(pPager, &nPage); + if( rc ) return rc; + if( nPage==0 ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); + }else{ + testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); + rc = sqlite3PagerOpenWal(pPager, 0); + } + }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + pPager->journalMode = PAGER_JOURNALMODE_DELETE; + } + } + } + return rc; +} +#endif + +/* +** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback +** the entire super-journal file. The case pSavepoint==NULL occurs when +** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +** savepoint. +** +** When pSavepoint is not NULL (meaning a non-transaction savepoint is +** being rolled back), then the rollback consists of up to three stages, +** performed in the order specified: +** +** * Pages are played back from the main journal starting at byte +** offset PagerSavepoint.iOffset and continuing to +** PagerSavepoint.iHdrOffset, or to the end of the main journal +** file if PagerSavepoint.iHdrOffset is zero. +** +** * If PagerSavepoint.iHdrOffset is not zero, then pages are played +** back starting from the journal header immediately following +** PagerSavepoint.iHdrOffset to the end of the main journal file. +** +** * Pages are then played back from the sub-journal file, starting +** with the PagerSavepoint.iSubRec and continuing to the end of +** the journal file. +** +** Throughout the rollback process, each time a page is rolled back, the +** corresponding bit is set in a bitvec structure (variable pDone in the +** implementation below). This is used to ensure that a page is only +** rolled back the first time it is encountered in either journal. +** +** If pSavepoint is NULL, then pages are only played back from the main +** journal file. There is no need for a bitvec in this case. +** +** In either case, before playback commences the Pager.dbSize variable +** is reset to the value that it held at the start of the savepoint +** (or transaction). No page with a page-number greater than this value +** is played back. If one is encountered it is simply skipped. +*/ +static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ + i64 szJ; /* Effective size of the main journal */ + i64 iHdrOff; /* End of first segment of main-journal records */ + int rc = SQLITE_OK; /* Return code */ + Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ + + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + + /* Allocate a bitvec to use to store the set of pages rolled back */ + if( pSavepoint ){ + pDone = sqlite3BitvecCreate(pSavepoint->nOrig); + if( !pDone ){ + return SQLITE_NOMEM_BKPT; + } + } + + /* Set the database size back to the value it was before the savepoint + ** being reverted was opened. + */ + pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; + pPager->changeCountDone = pPager->tempFile; + + if( !pSavepoint && pagerUseWal(pPager) ){ + return pagerRollbackWal(pPager); + } + + /* Use pPager->journalOff as the effective size of the main rollback + ** journal. The actual file might be larger than this in + ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything + ** past pPager->journalOff is off-limits to us. + */ + szJ = pPager->journalOff; + assert( pagerUseWal(pPager)==0 || szJ==0 ); + + /* Begin by rolling back records from the main journal starting at + ** PagerSavepoint.iOffset and continuing to the next journal header. + ** There might be records in the main journal that have a page number + ** greater than the current database size (pPager->dbSize) but those + ** will be skipped automatically. Pages are added to pDone as they + ** are played back. + */ + if( pSavepoint && !pagerUseWal(pPager) ){ + iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ; + pPager->journalOff = pSavepoint->iOffset; + while( rc==SQLITE_OK && pPager->journalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + }else{ + pPager->journalOff = 0; + } + + /* Continue rolling back records out of the main journal starting at + ** the first journal header seen and continuing until the effective end + ** of the main journal file. Continue to skip out-of-range pages and + ** continue adding pages rolled back to pDone. + */ + while( rc==SQLITE_OK && pPager->journalOffjournalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff" + ** test is related to ticket #2565. See the discussion in the + ** pager_playback() function for additional information. + */ + if( nJRec==0 + && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff + ){ + nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); + } + for(ii=0; rc==SQLITE_OK && iijournalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + } + assert( rc!=SQLITE_OK || pPager->journalOff>=szJ ); + + /* Finally, rollback pages from the sub-journal. Page that were + ** previously rolled back out of the main journal (and are hence in pDone) + ** will be skipped. Out-of-range pages are also skipped. + */ + if( pSavepoint ){ + u32 ii; /* Loop counter */ + i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + } + for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ + assert( offset==(i64)ii*(4+pPager->pageSize) ); + rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); + } + assert( rc!=SQLITE_DONE ); + } + + sqlite3BitvecDestroy(pDone); + if( rc==SQLITE_OK ){ + pPager->journalOff = szJ; + } + + return rc; +} + +/* +** Change the maximum number of in-memory pages that are allowed +** before attempting to recycle clean and unused pages. +*/ +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ + sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); +} + +/* +** Change the maximum number of in-memory pages that are allowed +** before attempting to spill pages to journal. +*/ +SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ + return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage); +} + +/* +** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. +*/ +static void pagerFixMaplimit(Pager *pPager){ +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_file *fd = pPager->fd; + if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ + sqlite3_int64 sz; + sz = pPager->szMmap; + pPager->bUseFetch = (sz>0); + setGetterMethod(pPager); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); + } +#endif +} + +/* +** Change the maximum size of any memory mapping made of the database file. +*/ +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){ + pPager->szMmap = szMmap; + pagerFixMaplimit(pPager); +} + +/* +** Free as much memory as possible from the pager. +*/ +SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); +} + +/* +** Adjust settings of the pager to those specified in the pgFlags parameter. +** +** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness +** of the database to damage due to OS crashes or power failures by +** changing the number of syncs()s when writing the journals. +** There are four levels: +** +** OFF sqlite3OsSync() is never called. This is the default +** for temporary and transient files. +** +** NORMAL The journal is synced once before writes begin on the +** database. This is normally adequate protection, but +** it is theoretically possible, though very unlikely, +** that an inopertune power failure could leave the journal +** in a state which would cause damage to the database +** when it is rolled back. +** +** FULL The journal is synced twice before writes begin on the +** database (with some additional information - the nRec field +** of the journal header - being written in between the two +** syncs). If we assume that writing a +** single disk sector is atomic, then this mode provides +** assurance that the journal will not be corrupted to the +** point of causing damage to the database during rollback. +** +** EXTRA This is like FULL except that is also syncs the directory +** that contains the rollback journal after the rollback +** journal is unlinked. +** +** The above is for a rollback-journal mode. For WAL mode, OFF continues +** to mean that no syncs ever occur. NORMAL means that the WAL is synced +** prior to the start of checkpoint and that the database file is synced +** at the conclusion of the checkpoint if the entire content of the WAL +** was written back into the database. But no sync operations occur for +** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL +** file is synced following each commit operation, in addition to the +** syncs associated with NORMAL. There is no difference between FULL +** and EXTRA for WAL mode. +** +** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The +** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync +** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an +** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL +** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the +** synchronous=FULL versus synchronous=NORMAL setting determines when +** the xSync primitive is called and is relevant to all platforms. +** +** Numeric values associated with these states are OFF==1, NORMAL=2, +** and FULL=3. +*/ +SQLITE_PRIVATE void sqlite3PagerSetFlags( + Pager *pPager, /* The pager to set safety level for */ + unsigned pgFlags /* Various flags */ +){ + unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; + if( pPager->tempFile ){ + pPager->noSync = 1; + pPager->fullSync = 0; + pPager->extraSync = 0; + }else{ + pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0; + pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0; + pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0; + } + if( pPager->noSync ){ + pPager->syncFlags = 0; + }else if( pgFlags & PAGER_FULLFSYNC ){ + pPager->syncFlags = SQLITE_SYNC_FULL; + }else{ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + } + pPager->walSyncFlags = (pPager->syncFlags<<2); + if( pPager->fullSync ){ + pPager->walSyncFlags |= pPager->syncFlags; + } + if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){ + pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2); + } + if( pgFlags & PAGER_CACHESPILL ){ + pPager->doNotSpill &= ~SPILLFLAG_OFF; + }else{ + pPager->doNotSpill |= SPILLFLAG_OFF; + } +} + +/* +** The following global variable is incremented whenever the library +** attempts to open a temporary file. This information is used for +** testing and analysis only. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_opentemp_count = 0; +#endif + +/* +** Open a temporary file. +** +** Write the file descriptor into *pFile. Return SQLITE_OK on success +** or some other error code if we fail. The OS will automatically +** delete the temporary file when it is closed. +** +** The flags passed to the VFS layer xOpen() call are those specified +** by parameter vfsFlags ORed with the following: +** +** SQLITE_OPEN_READWRITE +** SQLITE_OPEN_CREATE +** SQLITE_OPEN_EXCLUSIVE +** SQLITE_OPEN_DELETEONCLOSE +*/ +static int pagerOpentemp( + Pager *pPager, /* The pager object */ + sqlite3_file *pFile, /* Write the file descriptor here */ + int vfsFlags /* Flags passed through to the VFS */ +){ + int rc; /* Return code */ + +#ifdef SQLITE_TEST + sqlite3_opentemp_count++; /* Used for testing and analysis only */ +#endif + + vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; + rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); + assert( rc!=SQLITE_OK || isOpen(pFile) ); + return rc; +} + +/* +** Set the busy handler function. +** +** The pager invokes the busy-handler if sqlite3OsLock() returns +** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, +** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +** lock. It does *not* invoke the busy handler when upgrading from +** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE +** (which occurs during hot-journal rollback). Summary: +** +** Transition | Invokes xBusyHandler +** -------------------------------------------------------- +** NO_LOCK -> SHARED_LOCK | Yes +** SHARED_LOCK -> RESERVED_LOCK | No +** SHARED_LOCK -> EXCLUSIVE_LOCK | No +** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes +** +** If the busy-handler callback returns non-zero, the lock is +** retried. If it returns zero, then the SQLITE_BUSY error is +** returned to the caller of the pager API function. +*/ +SQLITE_PRIVATE void sqlite3PagerSetBusyHandler( + Pager *pPager, /* Pager object */ + int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ + void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ +){ + void **ap; + pPager->xBusyHandler = xBusyHandler; + pPager->pBusyHandlerArg = pBusyHandlerArg; + ap = (void **)&pPager->xBusyHandler; + assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); + assert( ap[1]==pBusyHandlerArg ); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); +} + +/* +** Change the page size used by the Pager object. The new page size +** is passed in *pPageSize. +** +** If the pager is in the error state when this function is called, it +** is a no-op. The value returned is the error state error code (i.e. +** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). +** +** Otherwise, if all of the following are true: +** +** * the new page size (value of *pPageSize) is valid (a power +** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and +** +** * there are no outstanding page references, and +** +** * the database is either not an in-memory database or it is +** an in-memory database that currently consists of zero pages. +** +** then the pager object page size is set to *pPageSize. +** +** If the page size is changed, then this function uses sqlite3PagerMalloc() +** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +** In all other cases, SQLITE_OK is returned. +** +** If the page size is not changed, either because one of the enumerated +** conditions above is not true, the pager was in error state when this +** function was called, or because the memory allocation attempt failed, +** then *pPageSize is set to the old, retained page size before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ + int rc = SQLITE_OK; + + /* It is not possible to do a full assert_pager_state() here, as this + ** function may be called from within PagerOpen(), before the state + ** of the Pager object is internally consistent. + ** + ** At one point this function returned an error if the pager was in + ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that + ** there is at least one outstanding page reference, this function + ** is a no-op for that case anyhow. + */ + + u32 pageSize = *pPageSize; + assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); + if( (pPager->memDb==0 || pPager->dbSize==0) + && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=(u32)pPager->pageSize + ){ + char *pNew = NULL; /* New temp space */ + i64 nByte = 0; + + if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ + rc = sqlite3OsFileSize(pPager->fd, &nByte); + } + if( rc==SQLITE_OK ){ + /* 8 bytes of zeroed overrun space is sufficient so that the b-tree + * cell header parser will never run off the end of the allocation */ + pNew = (char *)sqlite3PageMalloc(pageSize+8); + if( !pNew ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + memset(pNew+pageSize, 0, 8); + } + } + + if( rc==SQLITE_OK ){ + pager_reset(pPager); + rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); + } + if( rc==SQLITE_OK ){ + sqlite3PageFree(pPager->pTmpSpace); + pPager->pTmpSpace = pNew; + pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); + pPager->pageSize = pageSize; + pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1; + }else{ + sqlite3PageFree(pNew); + } + } + + *pPageSize = pPager->pageSize; + if( rc==SQLITE_OK ){ + if( nReserve<0 ) nReserve = pPager->nReserve; + assert( nReserve>=0 && nReserve<1000 ); + pPager->nReserve = (i16)nReserve; + pagerFixMaplimit(pPager); + } + return rc; +} + +/* +** Return a pointer to the "temporary page" buffer held internally +** by the pager. This is a buffer that is big enough to hold the +** entire content of a database page. This buffer is used internally +** during rollback and will be overwritten whenever a rollback +** occurs. But other modules are free to use it too, as long as +** no rollbacks are happening. +*/ +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){ + return pPager->pTmpSpace; +} + +/* +** Attempt to set the maximum database page count if mxPage is positive. +** Make no changes if mxPage is zero or negative. And never reduce the +** maximum page count below the current size of the database. +** +** Regardless of mxPage, return the current maximum page count. +*/ +SQLITE_PRIVATE Pgno sqlite3PagerMaxPageCount(Pager *pPager, Pgno mxPage){ + if( mxPage>0 ){ + pPager->mxPgno = mxPage; + } + assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ + /* assert( pPager->mxPgno>=pPager->dbSize ); */ + /* OP_MaxPgcnt ensures that the parameter passed to this function is not + ** less than the total number of valid pages in the database. But this + ** may be less than Pager.dbSize, and so the assert() above is not valid */ + return pPager->mxPgno; +} + +/* +** The following set of routines are used to disable the simulated +** I/O error mechanism. These routines are used to avoid simulated +** errors in places where we do not care about errors. +** +** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops +** and generate no code. +*/ +#ifdef SQLITE_TEST +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_hit; +static int saved_cnt; +void disable_simulated_io_errors(void){ + saved_cnt = sqlite3_io_error_pending; + sqlite3_io_error_pending = -1; +} +void enable_simulated_io_errors(void){ + sqlite3_io_error_pending = saved_cnt; +} +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +/* +** Read the first N bytes from the beginning of the file into memory +** that pDest points to. +** +** If the pager was opened on a transient file (zFilename==""), or +** opened on a file less than N bytes in size, the output buffer is +** zeroed and SQLITE_OK returned. The rationale for this is that this +** function is used to read database headers, and a new transient or +** zero sized database has a header than consists entirely of zeroes. +** +** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered, +** the error code is returned to the caller and the contents of the +** output buffer undefined. +*/ +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ + int rc = SQLITE_OK; + memset(pDest, 0, N); + assert( isOpen(pPager->fd) || pPager->tempFile ); + + /* This routine is only called by btree immediately after creating + ** the Pager object. There has not been an opportunity to transition + ** to WAL mode yet. + */ + assert( !pagerUseWal(pPager) ); + + if( isOpen(pPager->fd) ){ + IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) + rc = sqlite3OsRead(pPager->fd, pDest, N, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + return rc; +} + +/* +** This function may only be called when a read-transaction is open on +** the pager. It returns the total number of pages in the database. +** +** However, if the file is between 1 and bytes in size, then +** this is considered a 1 page file. +*/ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ + assert( pPager->eState>=PAGER_READER ); + assert( pPager->eState!=PAGER_WRITER_FINISHED ); + *pnPage = (int)pPager->dbSize; +} + + +/* +** Try to obtain a lock of type locktype on the database file. If +** a similar or greater lock is already held, this function is a no-op +** (returning SQLITE_OK immediately). +** +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +** the busy callback if the lock is currently not available. Repeat +** until the busy callback returns false or until the attempt to +** obtain the lock succeeds. +** +** Return SQLITE_OK on success and an error code if we cannot obtain +** the lock. If the lock is obtained successfully, set the Pager.state +** variable to locktype before returning. +*/ +static int pager_wait_on_lock(Pager *pPager, int locktype){ + int rc; /* Return code */ + + /* Check that this is either a no-op (because the requested lock is + ** already held), or one of the transitions that the busy-handler + ** may be invoked during, according to the comment above + ** sqlite3PagerSetBusyhandler(). + */ + assert( (pPager->eLock>=locktype) + || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) + || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK) + ); + + do { + rc = pagerLockDb(pPager, locktype); + }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); + return rc; +} + +/* +** Function assertTruncateConstraint(pPager) checks that one of the +** following is true for all dirty pages currently in the page-cache: +** +** a) The page number is less than or equal to the size of the +** current database image, in pages, OR +** +** b) if the page content were written at this time, it would not +** be necessary to write the current content out to the sub-journal. +** +** If the condition asserted by this function were not true, and the +** dirty page were to be discarded from the cache via the pagerStress() +** routine, pagerStress() would not write the current page content to +** the database file. If a savepoint transaction were rolled back after +** this happened, the correct behavior would be to restore the current +** content of the page. However, since this content is not present in either +** the database file or the portion of the rollback journal and +** sub-journal rolled back the content could not be restored and the +** database image would become corrupt. It is therefore fortunate that +** this circumstance cannot arise. +*/ +#if defined(SQLITE_DEBUG) +static void assertTruncateConstraintCb(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( pPg->flags&PGHDR_DIRTY ); + if( pPg->pgno>pPager->dbSize ){ /* if (a) is false */ + Pgno pgno = pPg->pgno; + int i; + for(i=0; ipPager->nSavepoint; i++){ + PagerSavepoint *p = &pPager->aSavepoint[i]; + assert( p->nOrigpInSavepoint,pgno) ); + } + } +} +static void assertTruncateConstraint(Pager *pPager){ + sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); +} +#else +# define assertTruncateConstraint(pPager) +#endif + +/* +** Truncate the in-memory database file image to nPage pages. This +** function does not actually modify the database file on disk. It +** just sets the internal state of the pager object so that the +** truncation will be done when the current transaction is committed. +** +** This function is only called right before committing a transaction. +** Once this function has been called, the transaction must either be +** rolled back or committed. It is not safe to call this function and +** then continue writing to the database. +*/ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ + assert( pPager->dbSize>=nPage || CORRUPT_DB ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + pPager->dbSize = nPage; + + /* At one point the code here called assertTruncateConstraint() to + ** ensure that all pages being truncated away by this operation are, + ** if one or more savepoints are open, present in the savepoint + ** journal so that they can be restored if the savepoint is rolled + ** back. This is no longer necessary as this function is now only + ** called right before committing a transaction. So although the + ** Pager object may still have open savepoints (Pager.nSavepoint!=0), + ** they cannot be rolled back. So the assertTruncateConstraint() call + ** is no longer correct. */ +} + + +/* +** This function is called before attempting a hot-journal rollback. It +** syncs the journal file to disk, then sets pPager->journalHdr to the +** size of the journal file so that the pager_playback() routine knows +** that the entire journal file has been synced. +** +** Syncing a hot-journal to disk before attempting to roll it back ensures +** that if a power-failure occurs during the rollback, the process that +** attempts rollback following system recovery sees the same journal +** content as this process. +** +** If everything goes as planned, SQLITE_OK is returned. Otherwise, +** an SQLite error code. +*/ +static int pagerSyncHotJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); + } + return rc; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** Obtain a reference to a memory mapped page object for page number pgno. +** The new object will use the pointer pData, obtained from xFetch(). +** If successful, set *ppPage to point to the new page reference +** and return SQLITE_OK. Otherwise, return an SQLite error code and set +** *ppPage to zero. +** +** Page references obtained by calling this function should be released +** by calling pagerReleaseMapPage(). +*/ +static int pagerAcquireMapPage( + Pager *pPager, /* Pager object */ + Pgno pgno, /* Page number */ + void *pData, /* xFetch()'d data for this page */ + PgHdr **ppPage /* OUT: Acquired page object */ +){ + PgHdr *p; /* Memory mapped page to return */ + + if( pPager->pMmapFreelist ){ + *ppPage = p = pPager->pMmapFreelist; + pPager->pMmapFreelist = p->pDirty; + p->pDirty = 0; + assert( pPager->nExtra>=8 ); + memset(p->pExtra, 0, 8); + }else{ + *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); + if( p==0 ){ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); + return SQLITE_NOMEM_BKPT; + } + p->pExtra = (void *)&p[1]; + p->flags = PGHDR_MMAP; + p->nRef = 1; + p->pPager = pPager; + } + + assert( p->pExtra==(void *)&p[1] ); + assert( p->pPage==0 ); + assert( p->flags==PGHDR_MMAP ); + assert( p->pPager==pPager ); + assert( p->nRef==1 ); + + p->pgno = pgno; + p->pData = pData; + pPager->nMmapOut++; + + return SQLITE_OK; +} +#endif + +/* +** Release a reference to page pPg. pPg must have been returned by an +** earlier call to pagerAcquireMapPage(). +*/ +static void pagerReleaseMapPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + pPager->nMmapOut--; + pPg->pDirty = pPager->pMmapFreelist; + pPager->pMmapFreelist = pPg; + + assert( pPager->fd->pMethods->iVersion>=3 ); + sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); +} + +/* +** Free all PgHdr objects stored in the Pager.pMmapFreelist list. +*/ +static void pagerFreeMapHdrs(Pager *pPager){ + PgHdr *p; + PgHdr *pNext; + for(p=pPager->pMmapFreelist; p; p=pNext){ + pNext = p->pDirty; + sqlite3_free(p); + } +} + +/* Verify that the database file has not be deleted or renamed out from +** under the pager. Return SQLITE_OK if the database is still where it ought +** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error +** code from sqlite3OsAccess()) if the database has gone missing. +*/ +static int databaseIsUnmoved(Pager *pPager){ + int bHasMoved = 0; + int rc; + + if( pPager->tempFile ) return SQLITE_OK; + if( pPager->dbSize==0 ) return SQLITE_OK; + assert( pPager->zFilename && pPager->zFilename[0] ); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); + if( rc==SQLITE_NOTFOUND ){ + /* If the HAS_MOVED file-control is unimplemented, assume that the file + ** has not been moved. That is the historical behavior of SQLite: prior to + ** version 3.8.3, it never checked */ + rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bHasMoved ){ + rc = SQLITE_READONLY_DBMOVED; + } + return rc; +} + + +/* +** Shutdown the page cache. Free all memory and close all files. +** +** If a transaction was in progress when this routine is called, that +** transaction is rolled back. All outstanding pages are invalidated +** and their memory is freed. Any attempt to use a page associated +** with this page cache after this function returns will likely +** result in a coredump. +** +** This function always succeeds. If a transaction is active an attempt +** is made to roll it back. If an error occurs during the rollback +** a hot journal may be left in the filesystem but no error is returned +** to the caller. +*/ +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ + u8 *pTmp = (u8*)pPager->pTmpSpace; + assert( db || pagerUseWal(pPager)==0 ); + assert( assert_pager_state(pPager) ); + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + pagerFreeMapHdrs(pPager); + /* pPager->errCode = 0; */ + pPager->exclusiveMode = 0; +#ifndef SQLITE_OMIT_WAL + { + u8 *a = 0; + assert( db || pPager->pWal==0 ); + if( db && 0==(db->flags & SQLITE_NoCkptOnClose) + && SQLITE_OK==databaseIsUnmoved(pPager) + ){ + a = pTmp; + } + sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + pPager->pWal = 0; + } +#endif + pager_reset(pPager); + if( MEMDB ){ + pager_unlock(pPager); + }else{ + /* If it is open, sync the journal file before calling UnlockAndRollback. + ** If this is not done, then an unsynced portion of the open journal + ** file may be played back into the database. If a power failure occurs + ** while this is happening, the database could become corrupt. + ** + ** If an error occurs while trying to sync the journal, shift the pager + ** into the ERROR state. This causes UnlockAndRollback to unlock the + ** database and close the journal file without attempting to roll it + ** back or finalize it. The next database user will have to do hot-journal + ** rollback before accessing the database file. + */ + if( isOpen(pPager->jfd) ){ + pager_error(pPager, pagerSyncHotJournal(pPager)); + } + pagerUnlockAndRollback(pPager); + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); + IOTRACE(("CLOSE %p\n", pPager)) + sqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pTmp); + sqlite3PcacheClose(pPager->pPCache); + assert( !pPager->aSavepoint && !pPager->pInJournal ); + assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); + + sqlite3_free(pPager); + return SQLITE_OK; +} + +#if !defined(NDEBUG) || defined(SQLITE_TEST) +/* +** Return the page number for page pPg. +*/ +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){ + return pPg->pgno; +} +#endif + +/* +** Increment the reference count for page pPg. +*/ +SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ + sqlite3PcacheRef(pPg); +} + +/* +** Sync the journal. In other words, make sure all the pages that have +** been written to the journal have actually reached the surface of the +** disk and can be restored in the event of a hot-journal rollback. +** +** If the Pager.noSync flag is set, then this function is a no-op. +** Otherwise, the actions required depend on the journal-mode and the +** device characteristics of the file-system, as follows: +** +** * If the journal file is an in-memory journal file, no action need +** be taken. +** +** * Otherwise, if the device does not support the SAFE_APPEND property, +** then the nRec field of the most recently written journal header +** is updated to contain the number of journal records that have +** been written following it. If the pager is operating in full-sync +** mode, then the journal file is synced before this field is updated. +** +** * If the device does not support the SEQUENTIAL property, then +** journal file is synced. +** +** Or, in pseudo-code: +** +** if( NOT ){ +** if( NOT SAFE_APPEND ){ +** if( ) xSync(); +** +** } +** if( NOT SEQUENTIAL ) xSync(); +** } +** +** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +** page currently held in memory before returning SQLITE_OK. If an IO +** error is encountered, then the IO error code is returned to the caller. +*/ +static int syncJournal(Pager *pPager, int newHdr){ + int rc; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( !pagerUseWal(pPager) ); + + rc = sqlite3PagerExclusiveLock(pPager); + if( rc!=SQLITE_OK ) return rc; + + if( !pPager->noSync ){ + assert( !pPager->tempFile ); + if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + assert( isOpen(pPager->jfd) ); + + if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + /* This block deals with an obscure problem. If the last connection + ** that wrote to this database was operating in persistent-journal + ** mode, then the journal file may at this point actually be larger + ** than Pager.journalOff bytes. If the next thing in the journal + ** file happens to be a journal-header (written as part of the + ** previous connection's transaction), and a crash or power-failure + ** occurs after nRec is updated but before this connection writes + ** anything else to the journal file (or commits/rolls back its + ** transaction), then SQLite may become confused when doing the + ** hot-journal rollback following recovery. It may roll back all + ** of this connections data, then proceed to rolling back the old, + ** out-of-date data that follows it. Database corruption. + ** + ** To work around this, if the journal file does appear to contain + ** a valid header following Pager.journalOff, then write a 0x00 + ** byte to the start of it to prevent it from being recognized. + ** + ** Variable iNextHdrOffset is set to the offset at which this + ** problematic header will occur, if it exists. aMagic is used + ** as a temporary buffer to inspect the first couple of bytes of + ** the potential journal header. + */ + i64 iNextHdrOffset; + u8 aMagic[8]; + u8 zHeader[sizeof(aJournalMagic)+4]; + + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + + iNextHdrOffset = journalHdrOffset(pPager); + rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); + if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ + static const u8 zerobyte = 0; + rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); + } + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ + return rc; + } + + /* Write the nRec value into the journal file header. If in + ** full-synchronous mode, sync the journal first. This ensures that + ** all data has really hit the disk before nRec is updated to mark + ** it as a candidate for rollback. + ** + ** This is not required if the persistent media supports the + ** SAFE_APPEND property. Because in this case it is not possible + ** for garbage data to be appended to the file, the nRec field + ** is populated with 0xFFFFFFFF when the journal header is written + ** and never needs to be updated. + */ + if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + if( rc!=SQLITE_OK ) return rc; + } + IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); + rc = sqlite3OsWrite( + pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr + ); + if( rc!=SQLITE_OK ) return rc; + } + if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| + (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) + ); + if( rc!=SQLITE_OK ) return rc; + } + + pPager->journalHdr = pPager->journalOff; + if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + pPager->nRec = 0; + rc = writeJournalHdr(pPager); + if( rc!=SQLITE_OK ) return rc; + } + }else{ + pPager->journalHdr = pPager->journalOff; + } + } + + /* Unless the pager is in noSync mode, the journal file was just + ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on + ** all pages. + */ + sqlite3PcacheClearSyncFlags(pPager->pPCache); + pPager->eState = PAGER_WRITER_DBMOD; + assert( assert_pager_state(pPager) ); + return SQLITE_OK; +} + +/* +** The argument is the first in a linked list of dirty pages connected +** by the PgHdr.pDirty pointer. This function writes each one of the +** in-memory pages in the list to the database file. The argument may +** be NULL, representing an empty list. In this case this function is +** a no-op. +** +** The pager must hold at least a RESERVED lock when this function +** is called. Before writing anything to the database file, this lock +** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, +** SQLITE_BUSY is returned and no data is written to the database file. +** +** If the pager is a temp-file pager and the actual file-system file +** is not yet open, it is created and opened before any data is +** written out. +** +** Once the lock has been upgraded and, if necessary, the file opened, +** the pages are written out to the database file in list order. Writing +** a page is skipped if it meets either of the following criteria: +** +** * The page number is greater than Pager.dbSize, or +** * The PGHDR_DONT_WRITE flag is set on the page. +** +** If writing out a page causes the database file to grow, Pager.dbFileSize +** is updated accordingly. If page 1 is written out, then the value cached +** in Pager.dbFileVers[] is updated to match the new value stored in +** the database file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot +** be obtained, SQLITE_BUSY is returned. +*/ +static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ + int rc = SQLITE_OK; /* Return code */ + + /* This function is only called for rollback pagers in WRITER_DBMOD state. */ + assert( !pagerUseWal(pPager) ); + assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD ); + assert( pPager->eLock==EXCLUSIVE_LOCK ); + assert( isOpen(pPager->fd) || pList->pDirty==0 ); + + /* If the file is a temp-file has not yet been opened, open it now. It + ** is not possible for rc to be other than SQLITE_OK if this branch + ** is taken, as pager_wait_on_lock() is a no-op for temp-files. + */ + if( !isOpen(pPager->fd) ){ + assert( pPager->tempFile && rc==SQLITE_OK ); + rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); + } + + /* Before the first write, give the VFS a hint of what the final + ** file size will be. + */ + assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); + if( rc==SQLITE_OK + && pPager->dbHintSizedbSize + && (pList->pDirty || pList->pgno>pPager->dbHintSize) + ){ + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + pPager->dbHintSize = pPager->dbSize; + } + + while( rc==SQLITE_OK && pList ){ + Pgno pgno = pList->pgno; + + /* If there are dirty pages in the page cache with page numbers greater + ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to + ** make the file smaller (presumably by auto-vacuum code). Do not write + ** any such pages to the file. + ** + ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag + ** set (set by sqlite3PagerDontWrite()). + */ + if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ + i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ + char *pData; /* Data to write */ + + assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); + if( pList->pgno==1 ) pager_write_changecounter(pList); + + pData = pList->pData; + + /* Write out the page data. */ + rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); + + /* If page 1 was just written, update Pager.dbFileVers to match + ** the value now stored in the database file. If writing this + ** page caused the database file to grow, update dbFileSize. + */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); + } + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + pPager->aStat[PAGER_STAT_WRITE]++; + + /* Update any backup objects copying the contents of this pager. */ + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); + + PAGERTRACE(("STORE %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pList))); + IOTRACE(("PGOUT %p %d\n", pPager, pgno)); + PAGER_INCR(sqlite3_pager_writedb_count); + }else{ + PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); + } + pager_set_pagehash(pList); + pList = pList->pDirty; + } + + return rc; +} + +/* +** Ensure that the sub-journal file is open. If it is already open, this +** function is a no-op. +** +** SQLITE_OK is returned if everything goes according to plan. An +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +** fails. +*/ +static int openSubJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !isOpen(pPager->sjfd) ){ + const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE + | SQLITE_OPEN_DELETEONCLOSE; + int nStmtSpill = sqlite3Config.nStmtSpill; + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ + nStmtSpill = -1; + } + rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill); + } + return rc; +} + +/* +** Append a record of the current state of page pPg to the sub-journal. +** +** If successful, set the bit corresponding to pPg->pgno in the bitvecs +** for all open savepoints before returning. +** +** This function returns SQLITE_OK if everything is successful, an IO +** error code if the attempt to write to the sub-journal fails, or +** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint +** bitvec. +*/ +static int subjournalPage(PgHdr *pPg){ + int rc = SQLITE_OK; + Pager *pPager = pPg->pPager; + if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + + /* Open the sub-journal, if it has not already been opened */ + assert( pPager->useJournal ); + assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); + assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); + assert( pagerUseWal(pPager) + || pageInJournal(pPager, pPg) + || pPg->pgno>pPager->dbOrigSize + ); + rc = openSubJournal(pPager); + + /* If the sub-journal was opened successfully (or was already open), + ** write the journal record into the file. */ + if( rc==SQLITE_OK ){ + void *pData = pPg->pData; + i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); + char *pData2; + pData2 = pData; + PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); + rc = write32bits(pPager->sjfd, offset, pPg->pgno); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + } + } + } + if( rc==SQLITE_OK ){ + pPager->nSubRec++; + assert( pPager->nSavepoint>0 ); + rc = addToSavepointBitvecs(pPager, pPg->pgno); + } + return rc; +} +static int subjournalPageIfRequired(PgHdr *pPg){ + if( subjRequiresPage(pPg) ){ + return subjournalPage(pPg); + }else{ + return SQLITE_OK; + } +} + +/* +** This function is called by the pcache layer when it has reached some +** soft memory limit. The first argument is a pointer to a Pager object +** (cast as a void*). The pager is always 'purgeable' (not an in-memory +** database). The second argument is a reference to a page that is +** currently dirty but has no outstanding references. The page +** is always associated with the Pager object passed as the first +** argument. +** +** The job of this function is to make pPg clean by writing its contents +** out to the database file, if possible. This may involve syncing the +** journal file. +** +** If successful, sqlite3PcacheMakeClean() is called on the page and +** SQLITE_OK returned. If an IO error occurs while trying to make the +** page clean, the IO error code is returned. If the page cannot be +** made clean for some other reason, but no error occurs, then SQLITE_OK +** is returned by sqlite3PcacheMakeClean() is not called. +*/ +static int pagerStress(void *p, PgHdr *pPg){ + Pager *pPager = (Pager *)p; + int rc = SQLITE_OK; + + assert( pPg->pPager==pPager ); + assert( pPg->flags&PGHDR_DIRTY ); + + /* The doNotSpill NOSYNC bit is set during times when doing a sync of + ** journal (and adding a new header) is not allowed. This occurs + ** during calls to sqlite3PagerWrite() while trying to journal multiple + ** pages belonging to the same sector. + ** + ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling + ** regardless of whether or not a sync is required. This is set during + ** a rollback or by user request, respectively. + ** + ** Spilling is also prohibited when in an error state since that could + ** lead to database corruption. In the current implementation it + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 + ** while in the error state, hence it is impossible for this routine to + ** be called in the error state. Nevertheless, we include a NEVER() + ** test for the error state as a safeguard against future changes. + */ + if( NEVER(pPager->errCode) ) return SQLITE_OK; + testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); + testcase( pPager->doNotSpill & SPILLFLAG_OFF ); + testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC ); + if( pPager->doNotSpill + && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 + || (pPg->flags & PGHDR_NEED_SYNC)!=0) + ){ + return SQLITE_OK; + } + + pPager->aStat[PAGER_STAT_SPILL]++; + pPg->pDirty = 0; + if( pagerUseWal(pPager) ){ + /* Write a single frame for this page to the log. */ + rc = subjournalPageIfRequired(pPg); + if( rc==SQLITE_OK ){ + rc = pagerWalFrames(pPager, pPg, 0, 0); + } + }else{ + +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( pPager->tempFile==0 ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ) return pager_error(pPager, rc); + } +#endif + + /* Sync the journal file if required. */ + if( pPg->flags&PGHDR_NEED_SYNC + || pPager->eState==PAGER_WRITER_CACHEMOD + ){ + rc = syncJournal(pPager, 1); + } + + /* Write the contents of the page out to the database file. */ + if( rc==SQLITE_OK ){ + assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); + rc = pager_write_pagelist(pPager, pPg); + } + } + + /* Mark the page as clean. */ + if( rc==SQLITE_OK ){ + PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); + sqlite3PcacheMakeClean(pPg); + } + + return pager_error(pPager, rc); +} + +/* +** Flush all unreferenced dirty pages to disk. +*/ +SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){ + int rc = pPager->errCode; + if( !MEMDB ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + assert( assert_pager_state(pPager) ); + while( rc==SQLITE_OK && pList ){ + PgHdr *pNext = pList->pDirty; + if( pList->nRef==0 ){ + rc = pagerStress((void*)pPager, pList); + } + pList = pNext; + } + } + + return rc; +} + +/* +** Allocate and initialize a new Pager object and put a pointer to it +** in *ppPager. The pager should eventually be freed by passing it +** to sqlite3PagerClose(). +** +** The zFilename argument is the path to the database file to open. +** If zFilename is NULL then a randomly-named temporary file is created +** and used as the file to be cached. Temporary files are be deleted +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. +** This can be used to implement an in-memory database. +** +** The nExtra parameter specifies the number of bytes of space allocated +** along with each page reference. This space is available to the user +** via the sqlite3PagerGetExtra() API. When a new page is allocated, the +** first 8 bytes of this space are zeroed but the remainder is uninitialized. +** (The extra space is used by btree as the MemPage object.) +** +** The flags argument is used to specify properties that affect the +** operation of the pager. It should be passed some bitwise combination +** of the PAGER_* flags. +** +** The vfsFlags parameter is a bitmask to pass to the flags parameter +** of the xOpen() method of the supplied VFS when opening files. +** +** If the pager object is allocated and the specified file opened +** successfully, SQLITE_OK is returned and *ppPager set to point to +** the new pager object. If an error occurs, *ppPager is set to NULL +** and error code returned. This function may return SQLITE_NOMEM +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** various SQLITE_IO_XXX errors. +*/ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs *pVfs, /* The virtual file system to use */ + Pager **ppPager, /* OUT: Return the Pager structure here */ + const char *zFilename, /* Name of the database file to open */ + int nExtra, /* Extra bytes append to each in-memory page */ + int flags, /* flags controlling this file */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ + void (*xReinit)(DbPage*) /* Function to reinitialize pages */ +){ + u8 *pPtr; + Pager *pPager = 0; /* Pager object to allocate and return */ + int rc = SQLITE_OK; /* Return code */ + int tempFile = 0; /* True for temp files (incl. in-memory files) */ + int memDb = 0; /* True if this is an in-memory file */ + int memJM = 0; /* Memory journal mode */ + int readOnly = 0; /* True if this is a read-only file */ + int journalFileSize; /* Bytes to allocate for each journal fd */ + char *zPathname = 0; /* Full path to database file */ + int nPathname = 0; /* Number of bytes in zPathname */ + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ + int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ + u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + const char *zUri = 0; /* URI args to copy */ + int nUriByte = 1; /* Number of bytes of URI args at *zUri */ + + /* Figure out how much space is required for each journal file-handle + ** (there are two of them, the main journal and the sub-journal). */ + journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); + + /* Set the output variable to NULL in case an error occurs. */ + *ppPager = 0; + +#ifndef SQLITE_OMIT_MEMORYDB + if( flags & PAGER_MEMORY ){ + memDb = 1; + if( zFilename && zFilename[0] ){ + zPathname = sqlite3DbStrDup(0, zFilename); + if( zPathname==0 ) return SQLITE_NOMEM_BKPT; + nPathname = sqlite3Strlen30(zPathname); + zFilename = 0; + } + } +#endif + + /* Compute and store the full pathname in an allocated buffer pointed + ** to by zPathname, length nPathname. Or, if this is a temporary file, + ** leave both nPathname and zPathname set to 0. + */ + if( zFilename && zFilename[0] ){ + const char *z; + nPathname = pVfs->mxPathname+1; + zPathname = sqlite3DbMallocRaw(0, nPathname*2); + if( zPathname==0 ){ + return SQLITE_NOMEM_BKPT; + } + zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_OK_SYMLINK ){ + if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){ + rc = SQLITE_CANTOPEN_SYMLINK; + }else{ + rc = SQLITE_OK; + } + } + } + nPathname = sqlite3Strlen30(zPathname); + z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; + while( *z ){ + z += strlen(z)+1; + z += strlen(z)+1; + } + nUriByte = (int)(&z[1] - zUri); + assert( nUriByte>=1 ); + if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ + /* This branch is taken when the journal path required by + ** the database being opened will be more than pVfs->mxPathname + ** bytes in length. This means the database cannot be opened, + ** as it will not be possible to open the journal file or even + ** check for a hot-journal before reading. + */ + rc = SQLITE_CANTOPEN_BKPT; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(0, zPathname); + return rc; + } + } + + /* Allocate memory for the Pager structure, PCache object, the + ** three file descriptors, the database file name and the journal + ** file name. The layout in memory is as follows: + ** + ** Pager object (sizeof(Pager) bytes) + ** PCache object (sqlite3PcacheSize() bytes) + ** Database file handle (pVfs->szOsFile bytes) + ** Sub-journal file handle (journalFileSize bytes) + ** Main journal file handle (journalFileSize bytes) + ** Ptr back to the Pager (sizeof(Pager*) bytes) + ** \0\0\0\0 database prefix (4 bytes) + ** Database file name (nPathname+1 bytes) + ** URI query parameters (nUriByte bytes) + ** Journal filename (nPathname+8+1 bytes) + ** WAL filename (nPathname+4+1 bytes) + ** \0\0\0 terminator (3 bytes) + ** + ** Some 3rd-party software, over which we have no control, depends on + ** the specific order of the filenames and the \0 separators between them + ** so that it can (for example) find the database filename given the WAL + ** filename without using the sqlite3_filename_database() API. This is a + ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party + ** software is in widespread use, so we try to avoid changing the filename + ** order and formatting if possible. In particular, the details of the + ** filename format expected by 3rd-party software should be as follows: + ** + ** - Main Database Path + ** - \0 + ** - Multiple URI components consisting of: + ** - Key + ** - \0 + ** - Value + ** - \0 + ** - \0 + ** - Journal Path + ** - \0 + ** - WAL Path (zWALName) + ** - \0 + ** + ** The sqlite3_create_filename() interface and the databaseFilename() utility + ** that is used by sqlite3_filename_database() and kin also depend on the + ** specific formatting and order of the various filenames, so if the format + ** changes here, be sure to change it there as well. + */ + assert( SQLITE_PTRSIZE==sizeof(Pager*) ); + pPtr = (u8 *)sqlite3MallocZero( + ROUND8(sizeof(*pPager)) + /* Pager structure */ + ROUND8(pcacheSize) + /* PCache object */ + ROUND8(pVfs->szOsFile) + /* The main db file */ + journalFileSize * 2 + /* The two journal files */ + SQLITE_PTRSIZE + /* Space to hold a pointer */ + 4 + /* Database prefix */ + nPathname + 1 + /* database filename */ + nUriByte + /* query parameters */ + nPathname + 8 + 1 + /* Journal filename */ +#ifndef SQLITE_OMIT_WAL + nPathname + 4 + 1 + /* WAL filename */ +#endif + 3 /* Terminator */ + ); + assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); + if( !pPtr ){ + sqlite3DbFree(0, zPathname); + return SQLITE_NOMEM_BKPT; + } + pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); + pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); + pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); + pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); + memcpy(pPtr, &pPager, SQLITE_PTRSIZE); pPtr += SQLITE_PTRSIZE; + + /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ + pPtr += 4; /* Skip zero prefix */ + pPager->zFilename = (char*)pPtr; + if( nPathname>0 ){ + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1; + if( zUri ){ + memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte; + }else{ + pPtr++; + } + } + + + /* Fill in Pager.zJournal */ + if( nPathname>0 ){ + pPager->zJournal = (char*)pPtr; + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + memcpy(pPtr, "-journal",8); pPtr += 8 + 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + sqlite3FileSuffix3(zFilename,pPager->zJournal); + pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); +#endif + }else{ + pPager->zJournal = 0; + } + +#ifndef SQLITE_OMIT_WAL + /* Fill in Pager.zWal */ + if( nPathname>0 ){ + pPager->zWal = (char*)pPtr; + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + sqlite3FileSuffix3(zFilename, pPager->zWal); + pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); +#endif + }else{ + pPager->zWal = 0; + } +#endif + (void)pPtr; /* Suppress warning about unused pPtr value */ + + if( nPathname ) sqlite3DbFree(0, zPathname); + pPager->pVfs = pVfs; + pPager->vfsFlags = vfsFlags; + + /* Open the pager file. + */ + if( zFilename && zFilename[0] ){ + int fout = 0; /* VFS flags returned by xOpen() */ + rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + assert( !memDb ); + pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; + readOnly = (fout&SQLITE_OPEN_READONLY)!=0; + + /* If the file was successfully opened for read/write access, + ** choose a default page size in case we have to create the + ** database file. The default page size is the maximum of: + ** + ** + SQLITE_DEFAULT_PAGE_SIZE, + ** + The value returned by sqlite3OsSectorSize() + ** + The largest page size that can be written atomically. + */ + if( rc==SQLITE_OK ){ + int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + if( !readOnly ){ + setSectorSize(pPager); + assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); + if( szPageDfltsectorSize ){ + if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ + szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; + }else{ + szPageDflt = (u32)pPager->sectorSize; + } + } +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + { + int ii; + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); + for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ + if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ + szPageDflt = ii; + } + } + } +#endif + } + pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); + if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 + || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ + vfsFlags |= SQLITE_OPEN_READONLY; + goto act_like_temp_file; + } + } + }else{ + /* If a temporary file is requested, it is not opened immediately. + ** In this case we accept the default page size and delay actually + ** opening the file until the first call to OsWrite(). + ** + ** This branch is also run for an in-memory database. An in-memory + ** database is the same as a temp-file that is never written out to + ** disk and uses an in-memory rollback journal. + ** + ** This branch also runs for files marked as immutable. + */ +act_like_temp_file: + tempFile = 1; + pPager->eState = PAGER_READER; /* Pretend we already have a lock */ + pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ + pPager->noLock = 1; /* Do no locking */ + readOnly = (vfsFlags&SQLITE_OPEN_READONLY); + } + + /* The following call to PagerSetPagesize() serves to set the value of + ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. + */ + if( rc==SQLITE_OK ){ + assert( pPager->memDb==0 ); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); + testcase( rc!=SQLITE_OK ); + } + + /* Initialize the PCache object. */ + if( rc==SQLITE_OK ){ + nExtra = ROUND8(nExtra); + assert( nExtra>=8 && nExtra<1000 ); + rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, + !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); + } + + /* If an error occurred above, free the Pager structure and close the file. + */ + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pPager->pTmpSpace); + sqlite3_free(pPager); + return rc; + } + + PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); + IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) + + pPager->useJournal = (u8)useJournal; + /* pPager->stmtOpen = 0; */ + /* pPager->stmtInUse = 0; */ + /* pPager->nRef = 0; */ + /* pPager->stmtSize = 0; */ + /* pPager->stmtJSize = 0; */ + /* pPager->nPage = 0; */ + pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; + /* pPager->state = PAGER_UNLOCK; */ + /* pPager->errMask = 0; */ + pPager->tempFile = (u8)tempFile; + assert( tempFile==PAGER_LOCKINGMODE_NORMAL + || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); + pPager->exclusiveMode = (u8)tempFile; + pPager->changeCountDone = pPager->tempFile; + pPager->memDb = (u8)memDb; + pPager->readOnly = (u8)readOnly; + assert( useJournal || pPager->tempFile ); + sqlite3PagerSetFlags(pPager, (SQLITE_DEFAULT_SYNCHRONOUS+1)|PAGER_CACHESPILL); + /* pPager->pFirst = 0; */ + /* pPager->pFirstSynced = 0; */ + /* pPager->pLast = 0; */ + pPager->nExtra = (u16)nExtra; + pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; + assert( isOpen(pPager->fd) || tempFile ); + setSectorSize(pPager); + if( !useJournal ){ + pPager->journalMode = PAGER_JOURNALMODE_OFF; + }else if( memDb || memJM ){ + pPager->journalMode = PAGER_JOURNALMODE_MEMORY; + } + /* pPager->xBusyHandler = 0; */ + /* pPager->pBusyHandlerArg = 0; */ + pPager->xReiniter = xReinit; + setGetterMethod(pPager); + /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ + /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ + + *ppPager = pPager; + return SQLITE_OK; +} + +/* +** Return the sqlite3_file for the main database given the name +** of the corresponding WAL or Journal name as passed into +** xOpen. +*/ +SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ + Pager *pPager; + const char *p; + while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ + zName--; + } + p = zName - 4 - sizeof(Pager*); + assert( EIGHT_BYTE_ALIGNMENT(p) ); + pPager = *(Pager**)p; + return pPager->fd; +} + + +/* +** This function is called after transitioning from PAGER_UNLOCK to +** PAGER_SHARED state. It tests if there is a hot journal present in +** the file-system for the given pager. A hot journal is one that +** needs to be played back. According to this function, a hot-journal +** file exists if the following criteria are met: +** +** * The journal file exists in the file system, and +** * No process holds a RESERVED or greater lock on the database file, and +** * The database file itself is greater than 0 bytes in size, and +** * The first byte of the journal file exists and is not 0x00. +** +** If the current size of the database file is 0 but a journal file +** exists, that is probably an old journal left over from a prior +** database with the same name. In this case the journal file is +** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK +** is returned. +** +** This routine does not check if there is a super-journal filename +** at the end of the file. If there is, and that super-journal file +** does not exist, then the journal file is not really hot. In this +** case this routine will return a false-positive. The pager_playback() +** routine will discover that the journal file is not really hot and +** will not roll it back. +** +** If a hot-journal file is found to exist, *pExists is set to 1 and +** SQLITE_OK returned. If no hot-journal file is present, *pExists is +** set to 0 and SQLITE_OK returned. If an IO error occurs while trying +** to determine whether or not a hot-journal file exists, the IO error +** code is returned and the value of *pExists is undefined. +*/ +static int hasHotJournal(Pager *pPager, int *pExists){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int rc = SQLITE_OK; /* Return code */ + int exists = 1; /* True if a journal file is present */ + int jrnlOpen = !!isOpen(pPager->jfd); + + assert( pPager->useJournal ); + assert( isOpen(pPager->fd) ); + assert( pPager->eState==PAGER_OPEN ); + + assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & + SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN + )); + + *pExists = 0; + if( !jrnlOpen ){ + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + } + if( rc==SQLITE_OK && exists ){ + int locked = 0; /* True if some process holds a RESERVED lock */ + + /* Race condition here: Another process might have been holding the + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() + ** call above, but then delete the journal and drop the lock before + ** we get to the following sqlite3OsCheckReservedLock() call. If that + ** is the case, this routine might think there is a hot journal when + ** in fact there is none. This results in a false-positive which will + ** be dealt with by the playback routine. Ticket #3883. + */ + rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); + if( rc==SQLITE_OK && !locked ){ + Pgno nPage; /* Number of pages in database file */ + + assert( pPager->tempFile==0 ); + rc = pagerPagecount(pPager, &nPage); + if( rc==SQLITE_OK ){ + /* If the database is zero pages in size, that means that either (1) the + ** journal is a remnant from a prior database with the same name where + ** the database file but not the journal was deleted, or (2) the initial + ** transaction that populates a new database is being rolled back. + ** In either case, the journal file can be deleted. However, take care + ** not to delete the journal file if it is already open due to + ** journal_mode=PERSIST. + */ + if( nPage==0 && !jrnlOpen ){ + sqlite3BeginBenignMalloc(); + if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ + sqlite3OsDelete(pVfs, pPager->zJournal, 0); + if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); + } + sqlite3EndBenignMalloc(); + }else{ + /* The journal file exists and no other connection has a reserved + ** or greater lock on the database file. Now check that there is + ** at least one non-zero bytes at the start of the journal file. + ** If there is, then we consider this journal to be hot. If not, + ** it can be ignored. + */ + if( !jrnlOpen ){ + int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + } + if( rc==SQLITE_OK ){ + u8 first = 0; + rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + if( !jrnlOpen ){ + sqlite3OsClose(pPager->jfd); + } + *pExists = (first!=0); + }else if( rc==SQLITE_CANTOPEN ){ + /* If we cannot open the rollback journal file in order to see if + ** it has a zero header, that might be due to an I/O error, or + ** it might be due to the race condition described above and in + ** ticket #3883. Either way, assume that the journal is hot. + ** This might be a false positive. But if it is, then the + ** automatic journal playback and recovery mechanism will deal + ** with it under an EXCLUSIVE lock where we do not need to + ** worry so much with race conditions. + */ + *pExists = 1; + rc = SQLITE_OK; + } + } + } + } + } + + return rc; +} + +/* +** This function is called to obtain a shared lock on the database file. +** It is illegal to call sqlite3PagerGet() until after this function +** has been successfully called. If a shared-lock is already held when +** this function is called, it is a no-op. +** +** The following operations are also performed by this function. +** +** 1) If the pager is currently in PAGER_OPEN state (no lock held +** on the database file), then an attempt is made to obtain a +** SHARED lock on the database file. Immediately after obtaining +** the SHARED lock, the file-system is checked for a hot-journal, +** which is played back if present. Following any hot-journal +** rollback, the contents of the cache are validated by checking +** the 'change-counter' field of the database file header and +** discarded if they are found to be invalid. +** +** 2) If the pager is running in exclusive-mode, and there are currently +** no outstanding references to any pages, and is in the error state, +** then an attempt is made to clear the error state by discarding +** the contents of the page cache and rolling back any open journal +** file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs while locking the database, checking for a hot-journal file or +** rolling back a journal file, the IO error code is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine is only called from b-tree and only when there are no + ** outstanding pages. This implies that the pager state should either + ** be OPEN or READER. READER is only possible if the pager is or was in + ** exclusive access mode. */ + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + assert( pPager->errCode==SQLITE_OK ); + + if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ + int bHotJournal = 1; /* True if there exists a hot journal-file */ + + assert( !MEMDB ); + assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK ); + + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); + goto failed; + } + + /* If a journal file exists, and there is no RESERVED lock on the + ** database file, then it either needs to be played back or deleted. + */ + if( pPager->eLock<=SHARED_LOCK ){ + rc = hasHotJournal(pPager, &bHotJournal); + } + if( rc!=SQLITE_OK ){ + goto failed; + } + if( bHotJournal ){ + if( pPager->readOnly ){ + rc = SQLITE_READONLY_ROLLBACK; + goto failed; + } + + /* Get an EXCLUSIVE lock on the database file. At this point it is + ** important that a RESERVED lock is not obtained on the way to the + ** EXCLUSIVE lock. If it were, another process might open the + ** database file, detect the RESERVED lock, and conclude that the + ** database is safe to read while this process is still rolling the + ** hot-journal back. + ** + ** Because the intermediate RESERVED lock is not requested, any + ** other process attempting to access the database file will get to + ** this point in the code and fail to obtain its own EXCLUSIVE lock + ** on the database file. + ** + ** Unless the pager is in locking_mode=exclusive mode, the lock is + ** downgraded to SHARED_LOCK before this function returns. + */ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + goto failed; + } + + /* If it is not already open and the file exists on disk, open the + ** journal for read/write access. Write access is required because + ** in exclusive-access mode the file descriptor will be kept open + ** and possibly used for a transaction later on. Also, write-access + ** is usually required to finalize the journal in journal_mode=persist + ** mode (and also for journal_mode=truncate on some systems). + ** + ** If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. + */ + if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int bExists; /* True if journal file exists */ + rc = sqlite3OsAccess( + pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); + if( rc==SQLITE_OK && bExists ){ + int fout = 0; + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; + assert( !pPager->tempFile ); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ + rc = SQLITE_CANTOPEN_BKPT; + sqlite3OsClose(pPager->jfd); + } + } + } + + /* Playback and delete the journal. Drop the database write + ** lock and reacquire the read lock. Purge the cache before + ** playing back the hot-journal so that we don't end up with + ** an inconsistent cache. Sync the hot journal before playing + ** it back since the process that crashed and left the hot journal + ** probably did not sync it and we are required to always sync + ** the journal before playing it back. + */ + if( isOpen(pPager->jfd) ){ + assert( rc==SQLITE_OK ); + rc = pagerSyncHotJournal(pPager); + if( rc==SQLITE_OK ){ + rc = pager_playback(pPager, !pPager->tempFile); + pPager->eState = PAGER_OPEN; + } + }else if( !pPager->exclusiveMode ){ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + if( rc!=SQLITE_OK ){ + /* This branch is taken if an error occurs while trying to open + ** or roll back a hot-journal while holding an EXCLUSIVE lock. The + ** pager_unlock() routine will be called before returning to unlock + ** the file. If the unlock attempt fails, then Pager.eLock must be + ** set to UNKNOWN_LOCK (see the comment above the #define for + ** UNKNOWN_LOCK above for an explanation). + ** + ** In order to get pager_unlock() to do this, set Pager.eState to + ** PAGER_ERROR now. This is not actually counted as a transition + ** to ERROR state in the state diagram at the top of this file, + ** since we know that the same call to pager_unlock() will very + ** shortly transition the pager object to the OPEN state. Calling + ** assert_pager_state() would fail now, as it should not be possible + ** to be in ERROR state when there are zero outstanding page + ** references. + */ + pager_error(pPager, rc); + goto failed; + } + + assert( pPager->eState==PAGER_OPEN ); + assert( (pPager->eLock==SHARED_LOCK) + || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) + ); + } + + if( !pPager->tempFile && pPager->hasHeldSharedLock ){ + /* The shared-lock has just been acquired then check to + ** see if the database has been modified. If the database has changed, + ** flush the cache. The hasHeldSharedLock flag prevents this from + ** occurring on the very first access to a file, in order to save a + ** single unnecessary sqlite3OsRead() call at the start-up. + ** + ** Database changes are detected by looking at 15 bytes beginning + ** at offset 24 into the file. The first 4 of these 16 bytes are + ** a 32-bit counter that is incremented with each change. The + ** other bytes change randomly with each file change when + ** a codec is in use. + ** + ** There is a vanishingly small chance that a change will not be + ** detected. The chance of an undetected change is so small that + ** it can be neglected. + */ + char dbFileVers[sizeof(pPager->dbFileVers)]; + + IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); + rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); + if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_IOERR_SHORT_READ ){ + goto failed; + } + memset(dbFileVers, 0, sizeof(dbFileVers)); + } + + if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ + pager_reset(pPager); + + /* Unmap the database file. It is possible that external processes + ** may have truncated the database file and then extended it back + ** to its original size while this process was not holding a lock. + ** In this case there may exist a Pager.pMap mapping that appears + ** to be the right size but is not actually valid. Avoid this + ** possibility by unmapping the db here. */ + if( USEFETCH(pPager) ){ + sqlite3OsUnfetch(pPager->fd, 0, 0); + } + } + } + + /* If there is a WAL file in the file-system, open this database in WAL + ** mode. Otherwise, the following function call is a no-op. + */ + rc = pagerOpenWalIfPresent(pPager); +#ifndef SQLITE_OMIT_WAL + assert( pPager->pWal==0 || rc==SQLITE_OK ); +#endif + } + + if( pagerUseWal(pPager) ){ + assert( rc==SQLITE_OK ); + rc = pagerBeginReadTransaction(pPager); + } + + if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ + rc = pagerPagecount(pPager, &pPager->dbSize); + } + + failed: + if( rc!=SQLITE_OK ){ + assert( !MEMDB ); + pager_unlock(pPager); + assert( pPager->eState==PAGER_OPEN ); + }else{ + pPager->eState = PAGER_READER; + pPager->hasHeldSharedLock = 1; + } + return rc; +} + +/* +** If the reference count has reached zero, rollback any active +** transaction and unlock the pager. +** +** Except, in locking_mode=EXCLUSIVE when there is nothing to in +** the rollback journal, the unlock is not performed and there is +** nothing to rollback, so this routine is a no-op. +*/ +static void pagerUnlockIfUnused(Pager *pPager){ + if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ + assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ + pagerUnlockAndRollback(pPager); + } +} + +/* +** The page getter methods each try to acquire a reference to a +** page with page number pgno. If the requested reference is +** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. +** +** There are different implementations of the getter method depending +** on the current state of the pager. +** +** getPageNormal() -- The normal getter +** getPageError() -- Used if the pager is in an error state +** getPageMmap() -- Used if memory-mapped I/O is enabled +** +** If the requested page is already in the cache, it is returned. +** Otherwise, a new page object is allocated and populated with data +** read from the database file. In some cases, the pcache module may +** choose not to allocate a new page object and may reuse an existing +** object with no outstanding references. +** +** The extra data appended to a page is always initialized to zeros the +** first time a page is loaded into memory. If the page requested is +** already in the cache when this function is called, then the extra +** data is left as it was when the page object was last used. +** +** If the database image is smaller than the requested page or if +** the flags parameter contains the PAGER_GET_NOCONTENT bit and the +** requested page is not already stored in the cache, then no +** actual disk read occurs. In this case the memory image of the +** page is initialized to all zeros. +** +** If PAGER_GET_NOCONTENT is true, it means that we do not care about +** the contents of the page. This occurs in two scenarios: +** +** a) When reading a free-list leaf page from the database, and +** +** b) When a savepoint is being rolled back and we need to load +** a new page into the cache to be filled with the data read +** from the savepoint journal. +** +** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead +** of being read from the database. Additionally, the bits corresponding +** to pgno in Pager.pInJournal (bitvec of pages already written to the +** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open +** savepoints are set. This means if the page is made writable at any +** point in the future, using a call to sqlite3PagerWrite(), its contents +** will not be journaled. This saves IO. +** +** The acquisition might fail for several reasons. In all cases, +** an appropriate error code is returned and *ppPage is set to NULL. +** +** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt +** to find a page in the in-memory cache first. If the page is not already +** in memory, this routine goes to disk to read it in whereas Lookup() +** just returns 0. This routine acquires a read-lock the first time it +** has to go to disk, and could also playback an old journal if necessary. +** Since Lookup() never goes to disk, it never has to deal with locks +** or journal files. +*/ +static int getPageNormal( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + int rc = SQLITE_OK; + PgHdr *pPg; + u8 noContent; /* True if PAGER_GET_NOCONTENT is set */ + sqlite3_pcache_page *pBase; + + assert( pPager->errCode==SQLITE_OK ); + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + assert( pPager->hasHeldSharedLock==1 ); + + if( pgno==0 ) return SQLITE_CORRUPT_BKPT; + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); + if( pBase==0 ){ + pPg = 0; + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); + if( rc!=SQLITE_OK ) goto pager_acquire_err; + if( pBase==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto pager_acquire_err; + } + } + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); + assert( pPg==(*ppPage) ); + assert( pPg->pgno==pgno ); + assert( pPg->pPager==pPager || pPg->pPager==0 ); + + noContent = (flags & PAGER_GET_NOCONTENT)!=0; + if( pPg->pPager && !noContent ){ + /* In this case the pcache already contains an initialized copy of + ** the page. Return without further ado. */ + assert( pgno!=PAGER_SJ_PGNO(pPager) ); + pPager->aStat[PAGER_STAT_HIT]++; + return SQLITE_OK; + + }else{ + /* The pager cache has created a new page. Its content needs to + ** be initialized. But first some error checks: + ** + ** (*) obsolete. Was: maximum page number is 2^31 + ** (2) Never try to fetch the locking page + */ + if( pgno==PAGER_SJ_PGNO(pPager) ){ + rc = SQLITE_CORRUPT_BKPT; + goto pager_acquire_err; + } + + pPg->pPager = pPager; + + assert( !isOpen(pPager->fd) || !MEMDB ); + if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ + rc = SQLITE_FULL; + if( pgno<=pPager->dbSize ){ + sqlite3PcacheRelease(pPg); + pPg = 0; + } + goto pager_acquire_err; + } + if( noContent ){ + /* Failure to set the bits in the InJournal bit-vectors is benign. + ** It merely means that we might do some extra work to journal a + ** page that does not need to be journaled. Nevertheless, be sure + ** to test the case where a malloc error occurs while trying to set + ** a bit in a bit vector. + */ + sqlite3BeginBenignMalloc(); + if( pgno<=pPager->dbOrigSize ){ + TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno); + testcase( rc==SQLITE_NOMEM ); + } + TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); + testcase( rc==SQLITE_NOMEM ); + sqlite3EndBenignMalloc(); + } + memset(pPg->pData, 0, pPager->pageSize); + IOTRACE(("ZERO %p %d\n", pPager, pgno)); + }else{ + assert( pPg->pPager==pPager ); + pPager->aStat[PAGER_STAT_MISS]++; + rc = readDbPage(pPg); + if( rc!=SQLITE_OK ){ + goto pager_acquire_err; + } + } + pager_set_pagehash(pPg); + } + return SQLITE_OK; + +pager_acquire_err: + assert( rc!=SQLITE_OK ); + if( pPg ){ + sqlite3PcacheDrop(pPg); + } + pagerUnlockIfUnused(pPager); + *ppPage = 0; + return rc; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* The page getter for when memory-mapped I/O is enabled */ +static int getPageMMap( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + int rc = SQLITE_OK; + PgHdr *pPg = 0; + u32 iFrame = 0; /* Frame to read from WAL file */ + + /* It is acceptable to use a read-only (mmap) page for any page except + ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY + ** flag was specified by the caller. And so long as the db is not a + ** temporary or in-memory database. */ + const int bMmapOk = (pgno>1 + && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) + ); + + assert( USEFETCH(pPager) ); + + /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here + ** allows the compiler optimizer to reuse the results of the "pgno>1" + ** test in the previous statement, and avoid testing pgno==0 in the + ** common case where pgno is large. */ + if( pgno<=1 && pgno==0 ){ + return SQLITE_CORRUPT_BKPT; + } + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + assert( pPager->hasHeldSharedLock==1 ); + assert( pPager->errCode==SQLITE_OK ); + + if( bMmapOk && pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + if( rc!=SQLITE_OK ){ + *ppPage = 0; + return rc; + } + } + if( bMmapOk && iFrame==0 ){ + void *pData = 0; + rc = sqlite3OsFetch(pPager->fd, + (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData + ); + if( rc==SQLITE_OK && pData ){ + if( pPager->eState>PAGER_READER || pPager->tempFile ){ + pPg = sqlite3PagerLookup(pPager, pgno); + } + if( pPg==0 ){ + rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); + }else{ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); + } + if( pPg ){ + assert( rc==SQLITE_OK ); + *ppPage = pPg; + return SQLITE_OK; + } + } + if( rc!=SQLITE_OK ){ + *ppPage = 0; + return rc; + } + } + return getPageNormal(pPager, pgno, ppPage, flags); +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* The page getter method for when the pager is an error state */ +static int getPageError( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + UNUSED_PARAMETER(pgno); + UNUSED_PARAMETER(flags); + assert( pPager->errCode!=SQLITE_OK ); + *ppPage = 0; + return pPager->errCode; +} + + +/* Dispatch all page fetch requests to the appropriate getter method. +*/ +SQLITE_PRIVATE int sqlite3PagerGet( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ +#if 0 /* Trace page fetch by setting to 1 */ + int rc; + printf("PAGE %u\n", pgno); + fflush(stdout); + rc = pPager->xGet(pPager, pgno, ppPage, flags); + if( rc ){ + printf("PAGE %u failed with 0x%02x\n", pgno, rc); + fflush(stdout); + } + return rc; +#else + /* Normal, high-speed version of sqlite3PagerGet() */ + return pPager->xGet(pPager, pgno, ppPage, flags); +#endif +} + +/* +** Acquire a page if it is already in the in-memory cache. Do +** not read the page from disk. Return a pointer to the page, +** or 0 if the page is not in cache. +** +** See also sqlite3PagerGet(). The difference between this routine +** and sqlite3PagerGet() is that _get() will go to the disk and read +** in the page if the page is not already in cache. This routine +** returns NULL if the page is not in cache or if a disk I/O error +** has ever happened. +*/ +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ + sqlite3_pcache_page *pPage; + assert( pPager!=0 ); + assert( pgno!=0 ); + assert( pPager->pPCache!=0 ); + pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); + assert( pPage==0 || pPager->hasHeldSharedLock ); + if( pPage==0 ) return 0; + return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); +} + +/* +** Release a page reference. +** +** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be used +** if we know that the page being released is not the last reference to page1. +** The btree layer always holds page1 open until the end, so these first +** two routines can be used to release any page other than BtShared.pPage1. +** The assert() at tag-20230419-2 proves that this constraint is always +** honored. +** +** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine +** checks the total number of outstanding pages and if the number of +** pages reaches zero it drops the database lock. +*/ +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ + TESTONLY( Pager *pPager = pPg->pPager; ) + assert( pPg!=0 ); + if( pPg->flags & PGHDR_MMAP ){ + assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */ + pagerReleaseMapPage(pPg); + }else{ + sqlite3PcacheRelease(pPg); + } + /* Do not use this routine to release the last reference to page1 */ + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); /* tag-20230419-2 */ +} +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ + if( pPg ) sqlite3PagerUnrefNotNull(pPg); +} +SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){ + Pager *pPager; + assert( pPg!=0 ); + assert( pPg->pgno==1 ); + assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ + pPager = pPg->pPager; + sqlite3PcacheRelease(pPg); + pagerUnlockIfUnused(pPager); +} + +/* +** This function is called at the start of every write transaction. +** There must already be a RESERVED or EXCLUSIVE lock on the database +** file when this routine is called. +** +** Open the journal file for pager pPager and write a journal header +** to the start of it. If there are active savepoints, open the sub-journal +** as well. This function is only used when the journal file is being +** opened to write a rollback log for a transaction. It is not used +** when opening a hot journal file to roll it back. +** +** If the journal file is already open (as it may be in exclusive mode), +** then this function just writes a journal header to the start of the +** already open file. +** +** Whether or not the journal file is opened by this function, the +** Pager.pInJournal bitvec structure is allocated. +** +** Return SQLITE_OK if everything is successful. Otherwise, return +** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +** an IO error code if opening or writing the journal file fails. +*/ +static int pager_open_journal(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ + + assert( pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + assert( pPager->pInJournal==0 ); + + /* If already in the error state, this function is a no-op. But on + ** the other hand, this routine is never called if we are already in + ** an error state. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); + if( pPager->pInJournal==0 ){ + return SQLITE_NOMEM_BKPT; + } + + /* Open the journal file if it is not already open. */ + if( !isOpen(pPager->jfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3MemJournalOpen(pPager->jfd); + }else{ + int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + int nSpill; + + if( pPager->tempFile ){ + flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); + flags |= SQLITE_OPEN_EXCLUSIVE; + nSpill = sqlite3Config.nStmtSpill; + }else{ + flags |= SQLITE_OPEN_MAIN_JOURNAL; + nSpill = jrnlBufferSize(pPager); + } + + /* Verify that the database still has the same name as it did when + ** it was originally opened. */ + rc = databaseIsUnmoved(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3JournalOpen ( + pVfs, pPager->zJournal, pPager->jfd, flags, nSpill + ); + } + } + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + } + + + /* Write the first journal header to the journal file and open + ** the sub-journal if necessary. + */ + if( rc==SQLITE_OK ){ + /* TODO: Check if all of these are really required. */ + pPager->nRec = 0; + pPager->journalOff = 0; + pPager->setSuper = 0; + pPager->journalHdr = 0; + rc = writeJournalHdr(pPager); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->journalOff = 0; + }else{ + assert( pPager->eState==PAGER_WRITER_LOCKED ); + pPager->eState = PAGER_WRITER_CACHEMOD; + } + + return rc; +} + +/* +** Begin a write-transaction on the specified pager object. If a +** write-transaction has already been opened, this function is a no-op. +** +** If the exFlag argument is false, then acquire at least a RESERVED +** lock on the database file. If exFlag is true, then acquire at least +** an EXCLUSIVE lock. If such a lock is already held, no locking +** functions need be called. +** +** If the subjInMemory argument is non-zero, then any sub-journal opened +** within this transaction will be opened as an in-memory file. This +** has no effect if the sub-journal is already opened (as it may be when +** running in exclusive mode) or if the transaction does not require a +** sub-journal. If the subjInMemory argument is zero, then any required +** sub-journal is implemented in-memory if pPager is an in-memory database, +** or using a temporary file otherwise. +*/ +SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ + int rc = SQLITE_OK; + + if( pPager->errCode ) return pPager->errCode; + assert( pPager->eState>=PAGER_READER && pPager->eStatesubjInMemory = (u8)subjInMemory; + + if( pPager->eState==PAGER_READER ){ + assert( pPager->pInJournal==0 ); + + if( pagerUseWal(pPager) ){ + /* If the pager is configured to use locking_mode=exclusive, and an + ** exclusive lock on the database is not already held, obtain it now. + */ + if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + (void)sqlite3WalExclusiveMode(pPager->pWal, 1); + } + + /* Grab the write lock on the log file. If successful, upgrade to + ** PAGER_RESERVED state. Otherwise, return an error code to the caller. + ** The busy-handler is not invoked if another connection already + ** holds the write-lock. If possible, the upper layer will call it. + */ + rc = sqlite3WalBeginWriteTransaction(pPager->pWal); + }else{ + /* Obtain a RESERVED lock on the database file. If the exFlag parameter + ** is true, then immediately upgrade this to an EXCLUSIVE lock. The + ** busy-handler callback can be used when upgrading to the EXCLUSIVE + ** lock, but not when obtaining the RESERVED lock. + */ + rc = pagerLockDb(pPager, RESERVED_LOCK); + if( rc==SQLITE_OK && exFlag ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + } + + if( rc==SQLITE_OK ){ + /* Change to WRITER_LOCKED state. + ** + ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD + ** when it has an open transaction, but never to DBMOD or FINISHED. + ** This is because in those states the code to roll back savepoint + ** transactions may copy data from the sub-journal into the database + ** file as well as into the page cache. Which would be incorrect in + ** WAL mode. + */ + pPager->eState = PAGER_WRITER_LOCKED; + pPager->dbHintSize = pPager->dbSize; + pPager->dbFileSize = pPager->dbSize; + pPager->dbOrigSize = pPager->dbSize; + pPager->journalOff = 0; + } + + assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); + assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + } + + PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); + return rc; +} + +/* +** Write page pPg onto the end of the rollback journal. +*/ +static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + int rc; + u32 cksum; + char *pData2; + i64 iOff = pPager->journalOff; + + /* We should never write to the journal file the page that + ** contains the database locks. The following assert verifies + ** that we do not. */ + assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) ); + + assert( pPager->journalHdr<=pPager->journalOff ); + pData2 = pPg->pData; + cksum = pager_cksum(pPager, (u8*)pData2); + + /* Even if an IO or diskfull error occurs while journalling the + ** page in the block above, set the need-sync flag for the page. + ** Otherwise, when the transaction is rolled back, the logic in + ** playback_one_page() will think that the page needs to be restored + ** in the database file. And if an IO error occurs while doing so, + ** then corruption may follow. + */ + pPg->flags |= PGHDR_NEED_SYNC; + + rc = write32bits(pPager->jfd, iOff, pPg->pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); + if( rc!=SQLITE_OK ) return rc; + rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); + if( rc!=SQLITE_OK ) return rc; + + IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, + pPager->journalOff, pPager->pageSize)); + PAGER_INCR(sqlite3_pager_writej_count); + PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); + + pPager->journalOff += 8 + pPager->pageSize; + pPager->nRec++; + assert( pPager->pInJournal!=0 ); + rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + rc |= addToSavepointBitvecs(pPager, pPg->pgno); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + return rc; +} + +/* +** Mark a single data page as writeable. The page is written into the +** main journal or sub-journal as required. If the page is written into +** one of the journals, the corresponding bit is set in the +** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs +** of any open savepoints as appropriate. +*/ +static int pager_write(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + int rc = SQLITE_OK; + + /* This routine is not called unless a write-transaction has already + ** been started. The journal file may or may not be open at this point. + ** It is never called in the ERROR state. + */ + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( pPager->errCode==0 ); + assert( pPager->readOnly==0 ); + CHECK_PAGE(pPg); + + /* The journal file needs to be opened. Higher level routines have already + ** obtained the necessary locks to begin the write-transaction, but the + ** rollback journal might not yet be open. Open it now if this is the case. + ** + ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then + ** an error might occur and the pager would end up in WRITER_LOCKED state + ** with pages marked as dirty in the cache. + */ + if( pPager->eState==PAGER_WRITER_LOCKED ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + assert( assert_pager_state(pPager) ); + + /* Mark the page that is about to be modified as dirty. */ + sqlite3PcacheMakeDirty(pPg); + + /* If a rollback journal is in use, them make sure the page that is about + ** to change is in the rollback journal, or if the page is a new page off + ** then end of the file, make sure it is marked as PGHDR_NEED_SYNC. + */ + assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) ); + if( pPager->pInJournal!=0 + && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0 + ){ + assert( pagerUseWal(pPager)==0 ); + if( pPg->pgno<=pPager->dbOrigSize ){ + rc = pagerAddPageToRollbackJournal(pPg); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + if( pPager->eState!=PAGER_WRITER_DBMOD ){ + pPg->flags |= PGHDR_NEED_SYNC; + } + PAGERTRACE(("APPEND %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); + } + } + + /* The PGHDR_DIRTY bit is set above when the page was added to the dirty-list + ** and before writing the page into the rollback journal. Wait until now, + ** after the page has been successfully journalled, before setting the + ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified. + */ + pPg->flags |= PGHDR_WRITEABLE; + + /* If the statement journal is open and the page is not in it, + ** then write the page into the statement journal. + */ + if( pPager->nSavepoint>0 ){ + rc = subjournalPageIfRequired(pPg); + } + + /* Update the database size and return. */ + if( pPager->dbSizepgno ){ + pPager->dbSize = pPg->pgno; + } + return rc; +} + +/* +** This is a variant of sqlite3PagerWrite() that runs when the sector size +** is larger than the page size. SQLite makes the (reasonable) assumption that +** all bytes of a sector are written together by hardware. Hence, all bytes of +** a sector need to be journalled in case of a power loss in the middle of +** a write. +** +** Usually, the sector size is less than or equal to the page size, in which +** case pages can be individually written. This routine only runs in the +** exceptional case where the page size is smaller than the sector size. +*/ +static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ + int rc = SQLITE_OK; /* Return code */ + Pgno nPageCount; /* Total number of pages in database file */ + Pgno pg1; /* First page of the sector pPg is located on. */ + int nPage = 0; /* Number of pages starting at pg1 to journal */ + int ii; /* Loop counter */ + int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ + Pager *pPager = pPg->pPager; /* The pager that owns pPg */ + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); + + /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow + ** a journal header to be written between the pages journaled by + ** this function. + */ + assert( !MEMDB ); + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); + pPager->doNotSpill |= SPILLFLAG_NOSYNC; + + /* This trick assumes that both the page-size and sector-size are + ** an integer power of 2. It sets variable pg1 to the identifier + ** of the first page of the sector pPg is located on. + */ + pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; + + nPageCount = pPager->dbSize; + if( pPg->pgno>nPageCount ){ + nPage = (pPg->pgno - pg1)+1; + }else if( (pg1+nPagePerSector-1)>nPageCount ){ + nPage = nPageCount+1-pg1; + }else{ + nPage = nPagePerSector; + } + assert(nPage>0); + assert(pg1<=pPg->pgno); + assert((pg1+nPage)>pPg->pgno); + + for(ii=0; iipgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ + if( pg!=PAGER_SJ_PGNO(pPager) ){ + rc = sqlite3PagerGet(pPager, pg, &pPage, 0); + if( rc==SQLITE_OK ){ + rc = pager_write(pPage); + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnrefNotNull(pPage); + } + } + }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnrefNotNull(pPage); + } + } + + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages + ** starting at pg1, then it needs to be set for all of them. Because + ** writing to any of these nPage pages may damage the others, the + ** journal file must contain sync()ed copies of all of them + ** before any of them can be written out to the database file. + */ + if( rc==SQLITE_OK && needSync ){ + assert( !MEMDB ); + for(ii=0; iiflags |= PGHDR_NEED_SYNC; + sqlite3PagerUnrefNotNull(pPage); + } + } + } + + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); + pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; + return rc; +} + +/* +** Mark a data page as writeable. This routine must be called before +** making changes to a page. The caller must check the return value +** of this function and be careful not to change any page data unless +** this routine returns SQLITE_OK. +** +** The difference between this function and pager_write() is that this +** function also deals with the special case where 2 or more pages +** fit on a single disk sector. In this case all co-resident pages +** must have been written to the journal file before returning. +** +** If an error occurs, SQLITE_NOMEM or an IO error code is returned +** as appropriate. Otherwise, SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( (pPg->flags & PGHDR_MMAP)==0 ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ + if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); + return SQLITE_OK; + }else if( pPager->errCode ){ + return pPager->errCode; + }else if( pPager->sectorSize > (u32)pPager->pageSize ){ + assert( pPager->tempFile==0 ); + return pagerWriteLargeSector(pPg); + }else{ + return pager_write(pPg); + } +} + +/* +** Return TRUE if the page given in the argument was previously passed +** to sqlite3PagerWrite(). In other words, return TRUE if it is ok +** to change the content of the page. +*/ +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){ + return pPg->flags & PGHDR_WRITEABLE; +} +#endif + +/* +** A call to this routine tells the pager that it is not necessary to +** write the information on page pPg back to the disk, even though +** that page might be marked as dirty. This happens, for example, when +** the page has been added as a leaf of the freelist and so its +** content no longer matters. +** +** The overlying software layer calls this routine when all of the data +** on the given page is unused. The pager marks the page as clean so +** that it does not get written to disk. +** +** Tests show that this optimization can quadruple the speed of large +** DELETE operations. +** +** This optimization cannot be used with a temp-file, as the page may +** have been dirty at the start of the transaction. In that case, if +** memory pressure forces page pPg out of the cache, the data does need +** to be written out to disk so that it may be read back in if the +** current transaction is rolled back. +*/ +SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ + PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); + IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) + pPg->flags |= PGHDR_DONT_WRITE; + pPg->flags &= ~PGHDR_WRITEABLE; + testcase( pPg->flags & PGHDR_NEED_SYNC ); + pager_set_pagehash(pPg); + } +} + +/* +** This routine is called to increment the value of the database file +** change-counter, stored as a 4-byte big-endian integer starting at +** byte offset 24 of the pager file. The secondary change counter at +** 92 is also updated, as is the SQLite version number at offset 96. +** +** But this only happens if the pPager->changeCountDone flag is false. +** To avoid excess churning of page 1, the update only happens once. +** See also the pager_write_changecounter() routine that does an +** unconditional update of the change counters. +** +** If the isDirectMode flag is zero, then this is done by calling +** sqlite3PagerWrite() on page 1, then modifying the contents of the +** page data. In this case the file will be updated when the current +** transaction is committed. +** +** The isDirectMode flag may only be non-zero if the library was compiled +** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, +** if isDirect is non-zero, then the database file is updated directly +** by writing an updated version of page 1 using a call to the +** sqlite3OsWrite() function. +*/ +static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ + int rc = SQLITE_OK; + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* Declare and initialize constant integer 'isDirect'. If the + ** atomic-write optimization is enabled in this build, then isDirect + ** is initialized to the value passed as the isDirectMode parameter + ** to this function. Otherwise, it is always set to zero. + ** + ** The idea is that if the atomic-write optimization is not + ** enabled at compile time, the compiler can omit the tests of + ** 'isDirect' below, as well as the block enclosed in the + ** "if( isDirect )" condition. + */ +#ifndef SQLITE_ENABLE_ATOMIC_WRITE +# define DIRECT_MODE 0 + assert( isDirectMode==0 ); + UNUSED_PARAMETER(isDirectMode); +#else +# define DIRECT_MODE isDirectMode +#endif + + if( !pPager->changeCountDone && pPager->dbSize>0 ){ + PgHdr *pPgHdr; /* Reference to page 1 */ + + assert( !pPager->tempFile && isOpen(pPager->fd) ); + + /* Open page 1 of the file for writing. */ + rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0); + assert( pPgHdr==0 || rc==SQLITE_OK ); + + /* If page one was fetched successfully, and this function is not + ** operating in direct-mode, make page 1 writable. When not in + ** direct mode, page 1 is always held in cache and hence the PagerGet() + ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. + */ + if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ + rc = sqlite3PagerWrite(pPgHdr); + } + + if( rc==SQLITE_OK ){ + /* Actually do the update of the change counter */ + pager_write_changecounter(pPgHdr); + + /* If running in direct mode, write the contents of page 1 to the file. */ + if( DIRECT_MODE ){ + const void *zBuf; + assert( pPager->dbFileSize>0 ); + zBuf = pPgHdr->pData; + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + pPager->aStat[PAGER_STAT_WRITE]++; + } + if( rc==SQLITE_OK ){ + /* Update the pager's copy of the change-counter. Otherwise, the + ** next time a read transaction is opened the cache will be + ** flushed (as the change-counter values will not match). */ + const void *pCopy = (const void *)&((const char *)zBuf)[24]; + memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers)); + pPager->changeCountDone = 1; + } + }else{ + pPager->changeCountDone = 1; + } + } + + /* Release the page reference. */ + sqlite3PagerUnref(pPgHdr); + } + return rc; +} + +/* +** Sync the database file to disk. This is a no-op for in-memory databases +** or pages with the Pager.noSync flag set. +** +** If successful, or if called on a pager for which it is a no-op, this +** function returns SQLITE_OK. Otherwise, an IO error code is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zSuper){ + int rc = SQLITE_OK; + void *pArg = (void*)zSuper; + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc==SQLITE_OK && !pPager->noSync ){ + assert( !MEMDB ); + rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); + } + return rc; +} + +/* +** This function may only be called while a write-transaction is active in +** rollback. If the connection is in WAL mode, this call is a no-op. +** Otherwise, if the connection does not already have an EXCLUSIVE lock on +** the database file, an attempt is made to obtain one. +** +** If the EXCLUSIVE lock is already held or the attempt to obtain it is +** successful, or the connection is in WAL mode, SQLITE_OK is returned. +** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +** returned. +*/ +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){ + int rc = pPager->errCode; + assert( assert_pager_state(pPager) ); + if( rc==SQLITE_OK ){ + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + } + return rc; +} + +/* +** Sync the database file for the pager pPager. zSuper points to the name +** of a super-journal file that should be written into the individual +** journal file. zSuper may be NULL, which is interpreted as no +** super-journal (a single database transaction). +** +** This routine ensures that: +** +** * The database file change-counter is updated, +** * the journal is synced (unless the atomic-write optimization is used), +** * all dirty pages are written to the database file, +** * the database file is truncated (if required), and +** * the database file synced. +** +** The only thing that remains to commit the transaction is to finalize +** (delete, truncate or zero the first part of) the journal file (or +** delete the super-journal file if specified). +** +** Note that if zSuper==NULL, this does not overwrite a previous value +** passed to an sqlite3PagerCommitPhaseOne() call. +** +** If the final parameter - noSync - is true, then the database file itself +** is not synced. The caller must call sqlite3PagerSync() directly to +** sync the database file before calling CommitPhaseTwo() to delete the +** journal file in this case. +*/ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( + Pager *pPager, /* Pager object */ + const char *zSuper, /* If not NULL, the super-journal name */ + int noSync /* True to omit the xSync on the db file */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_ERROR + ); + assert( assert_pager_state(pPager) ); + + /* If a prior error occurred, report that error again. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + /* Provide the ability to easily simulate an I/O error during testing */ + if( sqlite3FaultSim(400) ) return SQLITE_IOERR; + + PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", + pPager->zFilename, zSuper, pPager->dbSize)); + + /* If no database changes have been made, return early. */ + if( pPager->eStatetempFile ); + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( 0==pagerFlushOnCommit(pPager, 1) ){ + /* If this is an in-memory db, or no pages have been written to, or this + ** function has already been called, it is mostly a no-op. However, any + ** backup in progress needs to be restarted. */ + sqlite3BackupRestart(pPager->pBackup); + }else{ + PgHdr *pList; + if( pagerUseWal(pPager) ){ + PgHdr *pPageOne = 0; + pList = sqlite3PcacheDirtyList(pPager->pPCache); + if( pList==0 ){ + /* Must have at least one page for the WAL commit flag. + ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ + rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); + pList = pPageOne; + pList->pDirty = 0; + } + assert( rc==SQLITE_OK ); + if( ALWAYS(pList) ){ + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); + } + sqlite3PagerUnref(pPageOne); + if( rc==SQLITE_OK ){ + sqlite3PcacheCleanAll(pPager->pPCache); + } + }else{ + /* The bBatch boolean is true if the batch-atomic-write commit method + ** should be used. No rollback journal is created if batch-atomic-write + ** is enabled. + */ +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + sqlite3_file *fd = pPager->fd; + int bBatch = zSuper==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ + && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) + && !pPager->noSync + && sqlite3JournalIsInMemory(pPager->jfd); +#else +# define bBatch 0 +#endif + +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + /* The following block updates the change-counter. Exactly how it + ** does this depends on whether or not the atomic-update optimization + ** was enabled at compile time, and if this transaction meets the + ** runtime criteria to use the operation: + ** + ** * The file-system supports the atomic-write property for + ** blocks of size page-size, and + ** * This commit is not part of a multi-file transaction, and + ** * Exactly one page has been modified and store in the journal file. + ** + ** If the optimization was not enabled at compile time, then the + ** pager_incr_changecounter() function is called to update the change + ** counter in 'indirect-mode'. If the optimization is compiled in but + ** is not applicable to this transaction, call sqlite3JournalCreate() + ** to make sure the journal file has actually been created, then call + ** pager_incr_changecounter() to update the change-counter in indirect + ** mode. + ** + ** Otherwise, if the optimization is both enabled and applicable, + ** then call pager_incr_changecounter() to update the change-counter + ** in 'direct' mode. In this case the journal file will never be + ** created for this transaction. + */ + if( bBatch==0 ){ + PgHdr *pPg; + assert( isOpen(pPager->jfd) + || pPager->journalMode==PAGER_JOURNALMODE_OFF + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + if( !zSuper && isOpen(pPager->jfd) + && pPager->journalOff==jrnlBufferSize(pPager) + && pPager->dbSize>=pPager->dbOrigSize + && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) + ){ + /* Update the db file change counter via the direct-write method. The + ** following call will modify the in-memory representation of page 1 + ** to include the updated change counter and then write page 1 + ** directly to the database file. Because of the atomic-write + ** property of the host file-system, this is safe. + */ + rc = pager_incr_changecounter(pPager, 1); + }else{ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc==SQLITE_OK ){ + rc = pager_incr_changecounter(pPager, 0); + } + } + } +#else /* SQLITE_ENABLE_ATOMIC_WRITE */ +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( zSuper ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + assert( bBatch==0 ); + } +#endif + rc = pager_incr_changecounter(pPager, 0); +#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Write the super-journal name into the journal file. If a + ** super-journal file name has already been written to the journal file, + ** or if zSuper is NULL (no super-journal), then this call is a no-op. + */ + rc = writeSuperJournal(pPager, zSuper); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Sync the journal file and write all dirty pages to the database. + ** If the atomic-update optimization is being used, this sync will not + ** create the journal file or perform any real IO. + ** + ** Because the change-counter page was just modified, unless the + ** atomic-update optimization is used it is almost certain that the + ** journal requires a sync here. However, in locking_mode=exclusive + ** on a system under memory pressure it is just possible that this is + ** not the case. In this case it is likely enough that the redundant + ** xSync() call will be changed to a no-op by the OS anyhow. + */ + rc = syncJournal(pPager, 0); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + pList = sqlite3PcacheDirtyList(pPager->pPCache); +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( bBatch ){ + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); + if( rc==SQLITE_OK ){ + rc = pager_write_pagelist(pPager, pList); + if( rc==SQLITE_OK && pPager->dbSize>pPager->dbFileSize ){ + char *pTmp = pPager->pTmpSpace; + int szPage = (int)pPager->pageSize; + memset(pTmp, 0, szPage); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, + ((i64)pPager->dbSize*pPager->pageSize)-szPage); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + } + if( rc!=SQLITE_OK ){ + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + } + } + + if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->jfd); + goto commit_phase_one_exit; + } + bBatch = 0; + }else{ + sqlite3OsClose(pPager->jfd); + } + } +#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + + if( bBatch==0 ){ + rc = pager_write_pagelist(pPager, pList); + } + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_IOERR_BLOCKED ); + goto commit_phase_one_exit; + } + sqlite3PcacheCleanAll(pPager->pPCache); + + /* If the file on disk is smaller than the database image, use + ** pager_truncate to grow the file here. This can happen if the database + ** image was extended as part of the current transaction and then the + ** last page in the db image moved to the free-list. In this case the + ** last page is never written out to disk, leaving the database file + ** undersized. Fix this now if it is the case. */ + if( pPager->dbSize>pPager->dbFileSize ){ + Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager)); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + rc = pager_truncate(pPager, nNew); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + + /* Finally, sync the database file. */ + if( !noSync ){ + rc = sqlite3PagerSync(pPager, zSuper); + } + IOTRACE(("DBSYNC %p\n", pPager)) + } + } + +commit_phase_one_exit: + if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ + pPager->eState = PAGER_WRITER_FINISHED; + } + return rc; +} + + +/* +** When this function is called, the database file has been completely +** updated to reflect the changes made by the current transaction and +** synced to disk. The journal file still exists in the file-system +** though, and if a failure occurs at this point it will eventually +** be used as a hot-journal and the current transaction rolled back. +** +** This function finalizes the journal file, either by deleting, +** truncating or partially zeroing it, so that it cannot be used +** for hot-journal rollback. Once this is done the transaction is +** irrevocably committed. +** +** If an error occurs, an IO error code is returned and the pager +** moves into the error state. Otherwise, SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine should not be called if a prior error has occurred. + ** But if (due to a coding error elsewhere in the system) it does get + ** called, just return the same error code without doing anything. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + pPager->iDataVersion++; + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_FINISHED + || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD) + ); + assert( assert_pager_state(pPager) ); + + /* An optimization. If the database was not actually modified during + ** this transaction, the pager is running in exclusive-mode and is + ** using persistent journals, then this function is a no-op. + ** + ** The start of the journal file currently contains a single journal + ** header with the nRec field set to 0. If such a journal is used as + ** a hot-journal during hot-journal rollback, 0 changes will be made + ** to the database file. So there is no need to zero the journal + ** header. Since the pager is in exclusive mode, there is no need + ** to drop any locks either. + */ + if( pPager->eState==PAGER_WRITER_LOCKED + && pPager->exclusiveMode + && pPager->journalMode==PAGER_JOURNALMODE_PERSIST + ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); + pPager->eState = PAGER_READER; + return SQLITE_OK; + } + + PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); + rc = pager_end_transaction(pPager, pPager->setSuper, 1); + return pager_error(pPager, rc); +} + +/* +** If a write transaction is open, then all changes made within the +** transaction are reverted and the current write-transaction is closed. +** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR +** state if an error occurs. +** +** If the pager is already in PAGER_ERROR state when this function is called, +** it returns Pager.errCode immediately. No work is performed in this case. +** +** Otherwise, in rollback mode, this function performs two functions: +** +** 1) It rolls back the journal file, restoring all database file and +** in-memory cache pages to the state they were in when the transaction +** was opened, and +** +** 2) It finalizes the journal file, so that it is not used for hot +** rollback at any point in the future. +** +** Finalization of the journal file (task 2) is only performed if the +** rollback is successful. +** +** In WAL mode, all cache-entries containing data modified within the +** current transaction are either expelled from the cache or reverted to +** their pre-transaction state by re-reading data from the database or +** WAL files. The WAL transaction is then closed. +*/ +SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); + + /* PagerRollback() is a no-op if called in READER or OPEN state. If + ** the pager is already in the ERROR state, the rollback is not + ** attempted here. Instead, the error code is returned to the caller. + */ + assert( assert_pager_state(pPager) ); + if( pPager->eState==PAGER_ERROR ) return pPager->errCode; + if( pPager->eState<=PAGER_READER ) return SQLITE_OK; + + if( pagerUseWal(pPager) ){ + int rc2; + rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); + rc2 = pager_end_transaction(pPager, pPager->setSuper, 0); + if( rc==SQLITE_OK ) rc = rc2; + }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ + int eState = pPager->eState; + rc = pager_end_transaction(pPager, 0, 0); + if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ + /* This can happen using journal_mode=off. Move the pager to the error + ** state to indicate that the contents of the cache may not be trusted. + ** Any active readers will get SQLITE_ABORT. + */ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); + return rc; + } + }else{ + rc = pager_playback(pPager, 0); + } + + assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); + assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR + || rc==SQLITE_CANTOPEN + ); + + /* If an error occurs during a ROLLBACK, we can no longer trust the pager + ** cache. So call pager_error() on the way out to make any error persistent. + */ + return pager_error(pPager, rc); +} + +/* +** Return TRUE if the database file is opened read-only. Return FALSE +** if the database is (in theory) writable. +*/ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){ + return pPager->readOnly; +} + +#ifdef SQLITE_DEBUG +/* +** Return the sum of the reference counts for all pages held by pPager. +*/ +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ + return sqlite3PcacheRefCount(pPager->pPCache); +} +#endif + +/* +** Return the approximate number of bytes of memory currently +** used by the pager and its associated cache. +*/ +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ + int perPageSize = pPager->pageSize + pPager->nExtra + + (int)(sizeof(PgHdr) + 5*sizeof(void*)); + return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + + sqlite3MallocSize(pPager) + + pPager->pageSize; +} + +/* +** Return the number of references to the specified page. +*/ +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){ + return sqlite3PcachePageRefcount(pPage); +} + +#ifdef SQLITE_TEST +/* +** This routine is used for testing and analysis only. +*/ +SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ + static int a[11]; + a[0] = sqlite3PcacheRefCount(pPager->pPCache); + a[1] = sqlite3PcachePagecount(pPager->pPCache); + a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); + a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; + a[4] = pPager->eState; + a[5] = pPager->errCode; + a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff; + a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff; + a[8] = 0; /* Used to be pPager->nOvfl */ + a[9] = pPager->nRead; + a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff; + return a; +} +#endif + +/* +** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE, +** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation +** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because +** it was added later. +** +** Before returning, *pnVal is incremented by the +** current cache hit or miss count, according to the value of eStat. If the +** reset parameter is non-zero, the cache hit or miss count is zeroed before +** returning. +*/ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){ + + assert( eStat==SQLITE_DBSTATUS_CACHE_HIT + || eStat==SQLITE_DBSTATUS_CACHE_MISS + || eStat==SQLITE_DBSTATUS_CACHE_WRITE + || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1 + ); + + assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); + assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); + assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 + && PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 ); + + eStat -= SQLITE_DBSTATUS_CACHE_HIT; + *pnVal += pPager->aStat[eStat]; + if( reset ){ + pPager->aStat[eStat] = 0; + } +} + +/* +** Return true if this is an in-memory or temp-file backed pager. +*/ +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ + return pPager->tempFile || pPager->memVfs; +} + +/* +** Check that there are at least nSavepoint savepoints open. If there are +** currently less than nSavepoints open, then open one or more savepoints +** to make up the difference. If the number of savepoints is already +** equal to nSavepoint, then this function is a no-op. +** +** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +** occurs while opening the sub-journal file, then an IO error code is +** returned. Otherwise, SQLITE_OK. +*/ +static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ + int rc = SQLITE_OK; /* Return code */ + int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ + int ii; /* Iterator variable */ + PagerSavepoint *aNew; /* New Pager.aSavepoint array */ + + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + assert( nSavepoint>nCurrent && pPager->useJournal ); + + /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM + ** if the allocation fails. Otherwise, zero the new portion in case a + ** malloc failure occurs while populating it in the for(...) loop below. + */ + aNew = (PagerSavepoint *)sqlite3Realloc( + pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint + ); + if( !aNew ){ + return SQLITE_NOMEM_BKPT; + } + memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); + pPager->aSavepoint = aNew; + + /* Populate the PagerSavepoint structures just allocated. */ + for(ii=nCurrent; iidbSize; + if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ + aNew[ii].iOffset = pPager->journalOff; + }else{ + aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); + } + aNew[ii].iSubRec = pPager->nSubRec; + aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + aNew[ii].bTruncateOnRelease = 1; + if( !aNew[ii].pInSavepoint ){ + return SQLITE_NOMEM_BKPT; + } + if( pagerUseWal(pPager) ){ + sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); + } + pPager->nSavepoint = ii+1; + } + assert( pPager->nSavepoint==nSavepoint ); + assertTruncateConstraint(pPager); + return rc; +} +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + + if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){ + return pagerOpenSavepoint(pPager, nSavepoint); + }else{ + return SQLITE_OK; + } +} + + +/* +** This function is called to rollback or release (commit) a savepoint. +** The savepoint to release or rollback need not be the most recently +** created savepoint. +** +** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. +** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with +** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes +** that have occurred since the specified savepoint was created. +** +** The savepoint to rollback or release is identified by parameter +** iSavepoint. A value of 0 means to operate on the outermost savepoint +** (the first created). A value of (Pager.nSavepoint-1) means operate +** on the most recently created savepoint. If iSavepoint is greater than +** (Pager.nSavepoint-1), then this function is a no-op. +** +** If a negative value is passed to this function, then the current +** transaction is rolled back. This is different to calling +** sqlite3PagerRollback() because this function does not terminate +** the transaction or unlock the database, it just restores the +** contents of the database to its original state. +** +** In any case, all savepoints with an index greater than iSavepoint +** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), +** then savepoint iSavepoint is also destroyed. +** +** This function may return SQLITE_NOMEM if a memory allocation fails, +** or an IO error code if an IO error occurs while rolling back a +** savepoint. If no errors occur, SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ + int rc = pPager->errCode; + +#ifdef SQLITE_ENABLE_ZIPVFS + if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK; +#endif + + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); + + if( rc==SQLITE_OK && iSavepointnSavepoint ){ + int ii; /* Iterator variable */ + int nNew; /* Number of remaining savepoints after this op. */ + + /* Figure out how many savepoints will still be active after this + ** operation. Store this value in nNew. Then free resources associated + ** with any savepoints that are destroyed by this operation. + */ + nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); + for(ii=nNew; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + pPager->nSavepoint = nNew; + + /* Truncate the sub-journal so that it only includes the parts + ** that are still in use. */ + if( op==SAVEPOINT_RELEASE ){ + PagerSavepoint *pRel = &pPager->aSavepoint[nNew]; + if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){ + /* Only truncate if it is an in-memory sub-journal. */ + if( sqlite3JournalIsInMemory(pPager->sjfd) ){ + i64 sz = (pPager->pageSize+4)*(i64)pRel->iSubRec; + rc = sqlite3OsTruncate(pPager->sjfd, sz); + assert( rc==SQLITE_OK ); + } + pPager->nSubRec = pRel->iSubRec; + } + } + /* Else this is a rollback operation, playback the specified savepoint. + ** If this is a temp-file, it is possible that the journal file has + ** not yet been opened. In this case there have been no changes to + ** the database file, so the playback operation can be skipped. + */ + else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){ + PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1]; + rc = pagerPlaybackSavepoint(pPager, pSavepoint); + assert(rc!=SQLITE_DONE); + } + +#ifdef SQLITE_ENABLE_ZIPVFS + /* If the cache has been modified but the savepoint cannot be rolled + ** back journal_mode=off, put the pager in the error state. This way, + ** if the VFS used by this pager includes ZipVFS, the entire transaction + ** can be rolled back at the ZipVFS level. */ + else if( + pPager->journalMode==PAGER_JOURNALMODE_OFF + && pPager->eState>=PAGER_WRITER_CACHEMOD + ){ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); + } +#endif + } + + return rc; +} + +/* +** Return the full pathname of the database file. +** +** Except, if the pager is in-memory only, then return an empty string if +** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when +** used to report the filename to the user, for compatibility with legacy +** behavior. But when the Btree needs to know the filename for matching to +** shared cache, it uses nullIfMemDb==0 so that in-memory databases can +** participate in shared-cache. +** +** The return value to this routine is always safe to use with +** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. +*/ +SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ + static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + if( nullIfMemDb && (pPager->memDb || sqlite3IsMemdb(pPager->pVfs)) ){ + return &zFake[4]; + }else{ + return pPager->zFilename; + } +} + +/* +** Return the VFS structure for the pager. +*/ +SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ + return pPager->pVfs; +} + +/* +** Return the file handle for the database file associated +** with the pager. This might return NULL if the file has +** not yet been opened. +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ + return pPager->fd; +} + +/* +** Return the file handle for the journal file (if it exists). +** This will be either the rollback journal or the WAL file. +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ +#ifdef SQLITE_OMIT_WAL + return pPager->jfd; +#else + return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; +#endif +} + +/* +** Return the full pathname of the journal file. +*/ +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){ + return pPager->zJournal; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Move the page pPg to location pgno in the file. +** +** There must be no references to the page previously located at +** pgno (which we call pPgOld) though that page is allowed to be +** in cache. If the page previously located at pgno is not already +** in the rollback journal, it is not put there by by this routine. +** +** References to the page pPg remain valid. Updating any +** meta-data associated with pPg (i.e. data stored in the nExtra bytes +** allocated along with the page) is the responsibility of the caller. +** +** A transaction must be active when this routine is called. It used to be +** required that a statement transaction was not active, but this restriction +** has been removed (CREATE INDEX needs to move a page when a statement +** transaction is active). +** +** If the fourth argument, isCommit, is non-zero, then this page is being +** moved as part of a database reorganization just before the transaction +** is being committed. In this case, it is guaranteed that the database page +** pPg refers to will not be written to again within this transaction. +** +** This function may return SQLITE_NOMEM or an IO error code if an error +** occurs. Otherwise, it returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ + PgHdr *pPgOld; /* The page being overwritten. */ + Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ + int rc; /* Return code */ + Pgno origPgno; /* The original page number */ + + assert( pPg->nRef>0 ); + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* In order to be able to rollback, an in-memory database must journal + ** the page we are moving from. + */ + assert( pPager->tempFile || !MEMDB ); + if( pPager->tempFile ){ + rc = sqlite3PagerWrite(pPg); + if( rc ) return rc; + } + + /* If the page being moved is dirty and has not been saved by the latest + ** savepoint, then save the current contents of the page into the + ** sub-journal now. This is required to handle the following scenario: + ** + ** BEGIN; + ** + ** SAVEPOINT one; + ** + ** ROLLBACK TO one; + ** + ** If page X were not written to the sub-journal here, it would not + ** be possible to restore its contents when the "ROLLBACK TO one" + ** statement were is processed. + ** + ** subjournalPage() may need to allocate space to store pPg->pgno into + ** one or more savepoint bitvecs. This is the reason this function + ** may return SQLITE_NOMEM. + */ + if( (pPg->flags & PGHDR_DIRTY)!=0 + && SQLITE_OK!=(rc = subjournalPageIfRequired(pPg)) + ){ + return rc; + } + + PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); + IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) + + /* If the journal needs to be sync()ed before page pPg->pgno can + ** be written to, store pPg->pgno in local variable needSyncPgno. + ** + ** If the isCommit flag is set, there is no need to remember that + ** the journal needs to be sync()ed before database page pPg->pgno + ** can be written to. The caller has already promised not to write to it. + */ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ + needSyncPgno = pPg->pgno; + assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || + pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); + assert( pPg->flags&PGHDR_DIRTY ); + } + + /* If the cache contains a page with page-number pgno, remove it + ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for + ** page pgno before the 'move' operation, it needs to be retained + ** for the page moved there. + */ + pPg->flags &= ~PGHDR_NEED_SYNC; + pPgOld = sqlite3PagerLookup(pPager, pgno); + assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); + if( pPgOld ){ + if( NEVER(pPgOld->nRef>1) ){ + sqlite3PagerUnrefNotNull(pPgOld); + return SQLITE_CORRUPT_BKPT; + } + pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); + if( pPager->tempFile ){ + /* Do not discard pages from an in-memory database since we might + ** need to rollback later. Just move the page out of the way. */ + sqlite3PcacheMove(pPgOld, pPager->dbSize+1); + }else{ + sqlite3PcacheDrop(pPgOld); + } + } + + origPgno = pPg->pgno; + sqlite3PcacheMove(pPg, pgno); + sqlite3PcacheMakeDirty(pPg); + + /* For an in-memory database, make sure the original page continues + ** to exist, in case the transaction needs to roll back. Use pPgOld + ** as the original page since it has already been allocated. + */ + if( pPager->tempFile && pPgOld ){ + sqlite3PcacheMove(pPgOld, origPgno); + sqlite3PagerUnrefNotNull(pPgOld); + } + + if( needSyncPgno ){ + /* If needSyncPgno is non-zero, then the journal file needs to be + ** sync()ed before any data is written to database file page needSyncPgno. + ** Currently, no such page exists in the page-cache and the + ** "is journaled" bitvec flag has been set. This needs to be remedied by + ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC + ** flag. + ** + ** If the attempt to load the page into the page-cache fails, (due + ** to a malloc() or IO failure), clear the bit in the pInJournal[] + ** array. Otherwise, if the page is loaded and written again in + ** this transaction, it may be written to the database file before + ** it is synced into the journal file. This way, it may end up in + ** the journal file twice, but that is not a problem. + */ + PgHdr *pPgHdr; + rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0); + if( rc!=SQLITE_OK ){ + if( needSyncPgno<=pPager->dbOrigSize ){ + assert( pPager->pTmpSpace!=0 ); + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); + } + return rc; + } + pPgHdr->flags |= PGHDR_NEED_SYNC; + sqlite3PcacheMakeDirty(pPgHdr); + sqlite3PagerUnrefNotNull(pPgHdr); + } + + return SQLITE_OK; +} +#endif + +/* +** The page handle passed as the first argument refers to a dirty page +** with a page number other than iNew. This function changes the page's +** page number to iNew and sets the value of the PgHdr.flags field to +** the value passed as the third parameter. +*/ +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ + assert( pPg->pgno!=iNew ); + pPg->flags = flags; + sqlite3PcacheMove(pPg, iNew); +} + +/* +** Return a pointer to the data for the specified page. +*/ +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ + assert( pPg->nRef>0 || pPg->pPager->memDb ); + return pPg->pData; +} + +/* +** Return a pointer to the Pager.nExtra bytes of "extra" space +** allocated along with the specified page. +*/ +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ + return pPg->pExtra; +} + +/* +** Get/set the locking-mode for this pager. Parameter eMode must be one +** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then +** the locking-mode is set to the value specified. +** +** The returned value is either PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) +** locking-mode. +*/ +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ + assert( eMode==PAGER_LOCKINGMODE_QUERY + || eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_QUERY<0 ); + assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); + assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); + if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ + pPager->exclusiveMode = (u8)eMode; + } + return (int)pPager->exclusiveMode; +} + +/* +** Set the journal-mode for this pager. Parameter eMode must be one of: +** +** PAGER_JOURNALMODE_DELETE +** PAGER_JOURNALMODE_TRUNCATE +** PAGER_JOURNALMODE_PERSIST +** PAGER_JOURNALMODE_OFF +** PAGER_JOURNALMODE_MEMORY +** PAGER_JOURNALMODE_WAL +** +** The journalmode is set to the value specified if the change is allowed. +** The change may be disallowed for the following reasons: +** +** * An in-memory database can only have its journal_mode set to _OFF +** or _MEMORY. +** +** * Temporary databases cannot have _WAL journalmode. +** +** The returned indicate the current (possibly updated) journal-mode. +*/ +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ + u8 eOld = pPager->journalMode; /* Prior journalmode */ + + /* The eMode parameter is always valid */ + assert( eMode==PAGER_JOURNALMODE_DELETE /* 0 */ + || eMode==PAGER_JOURNALMODE_PERSIST /* 1 */ + || eMode==PAGER_JOURNALMODE_OFF /* 2 */ + || eMode==PAGER_JOURNALMODE_TRUNCATE /* 3 */ + || eMode==PAGER_JOURNALMODE_MEMORY /* 4 */ + || eMode==PAGER_JOURNALMODE_WAL /* 5 */ ); + + /* This routine is only called from the OP_JournalMode opcode, and + ** the logic there will never allow a temporary file to be changed + ** to WAL mode. + */ + assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL ); + + /* Do allow the journalmode of an in-memory database to be set to + ** anything other than MEMORY or OFF + */ + if( MEMDB ){ + assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF ); + if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){ + eMode = eOld; + } + } + + if( eMode!=eOld ){ + + /* Change the journal mode. */ + assert( pPager->eState!=PAGER_ERROR ); + pPager->journalMode = (u8)eMode; + + /* When transitioning from TRUNCATE or PERSIST to any other journal + ** mode except WAL, unless the pager is in locking_mode=exclusive mode, + ** delete the journal file. + */ + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); + assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); + assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); + assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); + + assert( isOpen(pPager->fd) || pPager->exclusiveMode ); + if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ + /* In this case we would like to delete the journal file. If it is + ** not possible, then that is not a problem. Deleting the journal file + ** here is an optimization only. + ** + ** Before deleting the journal file, obtain a RESERVED lock on the + ** database file. This ensures that the journal file is not deleted + ** while it is in use by some other client. + */ + sqlite3OsClose(pPager->jfd); + if( pPager->eLock>=RESERVED_LOCK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + }else{ + int rc = SQLITE_OK; + int state = pPager->eState; + assert( state==PAGER_OPEN || state==PAGER_READER ); + if( state==PAGER_OPEN ){ + rc = sqlite3PagerSharedLock(pPager); + } + if( pPager->eState==PAGER_READER ){ + assert( rc==SQLITE_OK ); + rc = pagerLockDb(pPager, RESERVED_LOCK); + } + if( rc==SQLITE_OK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + if( rc==SQLITE_OK && state==PAGER_READER ){ + pagerUnlockDb(pPager, SHARED_LOCK); + }else if( state==PAGER_OPEN ){ + pager_unlock(pPager); + } + assert( state==pPager->eState ); + } + }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3OsClose(pPager->jfd); + } + } + + /* Return the new journal mode */ + return (int)pPager->journalMode; +} + +/* +** Return the current journal mode. +*/ +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ + return (int)pPager->journalMode; +} + +/* +** Return TRUE if the pager is in a state where it is OK to change the +** journalmode. Journalmode changes can only happen when the database +** is unmodified. +*/ +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; + return 1; +} + +/* +** Get/set the size-limit used for persistent journal files. +** +** Setting the size limit to -1 means no limit is enforced. +** An attempt to set a limit smaller than -1 is a no-op. +*/ +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ + if( iLimit>=-1 ){ + pPager->journalSizeLimit = iLimit; + sqlite3WalLimit(pPager->pWal, iLimit); + } + return pPager->journalSizeLimit; +} + +/* +** Return a pointer to the pPager->pBackup variable. The backup module +** in backup.c maintains the content of this variable. This module +** uses it opaquely as an argument to sqlite3BackupRestart() and +** sqlite3BackupUpdate() only. +*/ +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ + return &pPager->pBackup; +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){ + assert( MEMDB==0 || pPager->tempFile ); + if( pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + + +#ifndef SQLITE_OMIT_WAL +/* +** This function is called when the user invokes "PRAGMA wal_checkpoint", +** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() +** or wal_blocking_checkpoint() API functions. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3PagerCheckpoint( + Pager *pPager, /* Checkpoint on this pager */ + sqlite3 *db, /* Db handle used to check for interrupts */ + int eMode, /* Type of checkpoint */ + int *pnLog, /* OUT: Final number of frames in log */ + int *pnCkpt /* OUT: Final number of checkpointed frames */ +){ + int rc = SQLITE_OK; + if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + /* This only happens when a database file is zero bytes in size opened and + ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint() + ** is invoked without any intervening transactions. We need to start + ** a transaction to initialize pWal. The PRAGMA table_list statement is + ** used for this since it starts transactions on every database file, + ** including all ATTACHed databases. This seems expensive for a single + ** sqlite3_wal_checkpoint() call, but it happens very rarely. + ** https://sqlite.org/forum/forumpost/fd0f19d229156939 + */ + sqlite3_exec(db, "PRAGMA table_list",0,0,0); + } + if( pPager->pWal ){ + rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, + (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), + pPager->pBusyHandlerArg, + pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pnLog, pnCkpt + ); + } + return rc; +} + +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ + return sqlite3WalCallback(pPager->pWal); +} + +/* +** Return true if the underlying VFS for the given pager supports the +** primitives necessary for write-ahead logging. +*/ +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ + const sqlite3_io_methods *pMethods = pPager->fd->pMethods; + if( pPager->noLock ) return 0; + return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); +} + +/* +** Attempt to take an exclusive lock on the database file. If a PENDING lock +** is obtained instead, immediately release it. +*/ +static int pagerExclusiveLock(Pager *pPager){ + int rc; /* Return code */ + u8 eOrigLock; /* Original lock */ + + assert( pPager->eLock>=SHARED_LOCK ); + eOrigLock = pPager->eLock; + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + /* If the attempt to grab the exclusive lock failed, release the + ** pending lock that may have been obtained instead. */ + pagerUnlockDb(pPager, eOrigLock); + } + + return rc; +} + +/* +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** exclusive-locking mode when this function is called, take an EXCLUSIVE +** lock on the database file and use heap-memory to store the wal-index +** in. Otherwise, use the normal shared-memory. +*/ +static int pagerOpenWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->pWal==0 && pPager->tempFile==0 ); + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + + /* If the pager is already in exclusive-mode, the WAL module will use + ** heap-memory for the wal-index instead of the VFS shared-memory + ** implementation. Take the exclusive lock now, before opening the WAL + ** file, to make sure this is safe. + */ + if( pPager->exclusiveMode ){ + rc = pagerExclusiveLock(pPager); + } + + /* Open the connection to the log file. If this operation fails, + ** (e.g. due to malloc() failure), return an error code. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3WalOpen(pPager->pVfs, + pPager->fd, pPager->zWal, pPager->exclusiveMode, + pPager->journalSizeLimit, &pPager->pWal + ); + } + pagerFixMaplimit(pPager); + + return rc; +} + + +/* +** The caller must be holding a SHARED lock on the database file to call +** this function. +** +** If the pager passed as the first argument is open on a real database +** file (not a temp file or an in-memory database), and the WAL file +** is not already open, make an attempt to open it now. If successful, +** return SQLITE_OK. If an error occurs or the VFS used by the pager does +** not support the xShmXXX() methods, return an error code. *pbOpen is +** not modified in either case. +** +** If the pager is open on a temp-file (or in-memory database), or if +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK +** without doing anything. +*/ +SQLITE_PRIVATE int sqlite3PagerOpenWal( + Pager *pPager, /* Pager object */ + int *pbOpen /* OUT: Set to true if call is a no-op */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pbOpen ); + assert( pPager->eState==PAGER_READER || !pbOpen ); + assert( pbOpen==0 || *pbOpen==0 ); + assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); + + if( !pPager->tempFile && !pPager->pWal ){ + if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; + + /* Close any rollback journal previously open */ + sqlite3OsClose(pPager->jfd); + + rc = pagerOpenWal(pPager); + if( rc==SQLITE_OK ){ + pPager->journalMode = PAGER_JOURNALMODE_WAL; + pPager->eState = PAGER_OPEN; + } + }else{ + *pbOpen = 1; + } + + return rc; +} + +/* +** This function is called to close the connection to the log file prior +** to switching from WAL to rollback mode. +** +** Before closing the log file, this function attempts to take an +** EXCLUSIVE lock on the database file. If this cannot be obtained, an +** error (SQLITE_BUSY) is returned and the log connection is not closed. +** If successful, the EXCLUSIVE lock is not released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ + int rc = SQLITE_OK; + + assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); + + /* If the log file is not already open, but does exist in the file-system, + ** it may need to be checkpointed before the connection can switch to + ** rollback mode. Open it now so this can happen. + */ + if( !pPager->pWal ){ + int logexists = 0; + rc = pagerLockDb(pPager, SHARED_LOCK); + if( rc==SQLITE_OK ){ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists + ); + } + if( rc==SQLITE_OK && logexists ){ + rc = pagerOpenWal(pPager); + } + } + + /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on + ** the database file, the log and log-summary files will be deleted. + */ + if( rc==SQLITE_OK && pPager->pWal ){ + rc = pagerExclusiveLock(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, + pPager->pageSize, (u8*)pPager->pTmpSpace); + pPager->pWal = 0; + pagerFixMaplimit(pPager); + if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); + } + } + return rc; +} + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +/* +** If pager pPager is a wal-mode database not in exclusive locking mode, +** invoke the sqlite3WalWriteLock() function on the associated Wal object +** with the same db and bLock parameters as were passed to this function. +** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. +*/ +SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ + int rc = SQLITE_OK; + if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){ + rc = sqlite3WalWriteLock(pPager->pWal, bLock); + } + return rc; +} + +/* +** Set the database handle used by the wal layer to determine if +** blocking locks are required. +*/ +SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ + if( pagerUseWal(pPager) ){ + sqlite3WalDb(pPager->pWal, db); + } +} +#endif + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** If this is a WAL database, obtain a snapshot handle for the snapshot +** currently open. Otherwise, return an error. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ + int rc = SQLITE_ERROR; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); + } + return rc; +} + +/* +** If this is a WAL database, store a pointer to pSnapshot. Next time a +** read transaction is opened, attempt to read from the snapshot it +** identifies. If this is not a WAL database, return an error. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotOpen( + Pager *pPager, + sqlite3_snapshot *pSnapshot +){ + int rc = SQLITE_OK; + if( pPager->pWal ){ + sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this +** is not a WAL database, return an error. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotRecover(pPager->pWal); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** The caller currently has a read transaction open on the database. +** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, +** this function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3PagerSnapshotCheck(). +*/ +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ + assert( pPager->pWal ); + sqlite3WalSnapshotUnlock(pPager->pWal); +} + +#endif /* SQLITE_ENABLE_SNAPSHOT */ +#endif /* !SQLITE_OMIT_WAL */ + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** A read-lock must be held on the pager when this function is called. If +** the pager is in WAL mode and the WAL file currently contains one or more +** frames, return the size in bytes of the page images stored within the +** WAL frames. Otherwise, if this is not a WAL database or the WAL file +** is empty, return 0. +*/ +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ + assert( pPager->eState>=PAGER_READER ); + return sqlite3WalFramesize(pPager->pWal); +} +#endif + +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) +SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ + return sqlite3WalSystemErrno(pPager->pWal); +} +#endif + +#endif /* SQLITE_OMIT_DISKIO */ + +/************** End of pager.c ***********************************************/ +/************** Begin file wal.c *********************************************/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the implementation of a write-ahead log (WAL) used in +** "journal_mode=WAL" mode. +** +** WRITE-AHEAD LOG (WAL) FILE FORMAT +** +** A WAL file consists of a header followed by zero or more "frames". +** Each frame records the revised content of a single page from the +** database file. All changes to the database are recorded by writing +** frames into the WAL. Transactions commit when a frame is written that +** contains a commit marker. A single WAL can and usually does record +** multiple transactions. Periodically, the content of the WAL is +** transferred back into the database file in an operation called a +** "checkpoint". +** +** A single WAL file can be used multiple times. In other words, the +** WAL can fill up with frames and then be checkpointed and then new +** frames can overwrite the old ones. A WAL always grows from beginning +** toward the end. Checksums and counters attached to each frame are +** used to determine which frames within the WAL are valid and which +** are leftovers from prior checkpoints. +** +** The WAL header is 32 bytes in size and consists of the following eight +** big-endian 32-bit unsigned integer values: +** +** 0: Magic number. 0x377f0682 or 0x377f0683 +** 4: File format version. Currently 3007000 +** 8: Database page size. Example: 1024 +** 12: Checkpoint sequence number +** 16: Salt-1, random integer incremented with each checkpoint +** 20: Salt-2, a different random integer changing with each ckpt +** 24: Checksum-1 (first part of checksum for first 24 bytes of header). +** 28: Checksum-2 (second part of checksum for first 24 bytes of header). +** +** Immediately following the wal-header are zero or more frames. Each +** frame consists of a 24-byte frame-header followed by a bytes +** of page data. The frame-header is six big-endian 32-bit unsigned +** integer values, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the header) +** 12: Salt-2 (copied from the header) +** 16: Checksum-1. +** 20: Checksum-2. +** +** A frame is considered valid if and only if the following conditions are +** true: +** +** (1) The salt-1 and salt-2 values in the frame-header match +** salt values in the wal-header +** +** (2) The checksum values in the final 8 bytes of the frame-header +** exactly match the checksum computed consecutively on the +** WAL header and the first 8 bytes and the content of all frames +** up to and including the current frame. +** +** The checksum is computed using 32-bit big-endian integers if the +** magic number in the first 4 bytes of the WAL is 0x377f0683 and it +** is computed using little-endian if the magic number is 0x377f0682. +** The checksum values are always stored in the frame header in a +** big-endian format regardless of which byte order is used to compute +** the checksum. The checksum is computed by interpreting the input as +** an even number of unsigned 32-bit integers: x[0] through x[N]. The +** algorithm used for the checksum is as follows: +** +** for i from 0 to n-1 step 2: +** s0 += x[i] + s1; +** s1 += x[i+1] + s0; +** endfor +** +** Note that s0 and s1 are both weighted checksums using fibonacci weights +** in reverse order (the largest fibonacci weight occurs on the first element +** of the sequence being summed.) The s1 value spans all 32-bit +** terms of the sequence whereas s0 omits the final term. +** +** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the +** WAL is transferred into the database, then the database is VFS.xSync-ed. +** The VFS.xSync operations serve as write barriers - all writes launched +** before the xSync must complete before any write that launches after the +** xSync begins. +** +** After each checkpoint, the salt-1 value is incremented and the salt-2 +** value is randomized. This prevents old and new frames in the WAL from +** being considered valid at the same time and being checkpointing together +** following a crash. +** +** READER ALGORITHM +** +** To read a page from the database (call it page number P), a reader +** first checks the WAL to see if it contains page P. If so, then the +** last valid instance of page P that is a followed by a commit frame +** or is a commit frame itself becomes the value read. If the WAL +** contains no copies of page P that are valid and which are a commit +** frame or are followed by a commit frame, then page P is read from +** the database file. +** +** To start a read transaction, the reader records the index of the last +** valid frame in the WAL. The reader uses this recorded "mxFrame" value +** for all subsequent read operations. New transactions can be appended +** to the WAL, but as long as the reader uses its original mxFrame value +** and ignores the newly appended content, it will see a consistent snapshot +** of the database from a single point in time. This technique allows +** multiple concurrent readers to view different versions of the database +** content simultaneously. +** +** The reader algorithm in the previous paragraphs works correctly, but +** because frames for page P can appear anywhere within the WAL, the +** reader has to scan the entire WAL looking for page P frames. If the +** WAL is large (multiple megabytes is typical) that scan can be slow, +** and read performance suffers. To overcome this problem, a separate +** data structure called the wal-index is maintained to expedite the +** search for frames of a particular page. +** +** WAL-INDEX FORMAT +** +** Conceptually, the wal-index is shared memory, though VFS implementations +** might choose to implement the wal-index using a mmapped file. Because +** the wal-index is shared memory, SQLite does not support journal_mode=WAL +** on a network filesystem. All users of the database must be able to +** share memory. +** +** In the default unix and windows implementation, the wal-index is a mmapped +** file whose name is the database name with a "-shm" suffix added. For that +** reason, the wal-index is sometimes called the "shm" file. +** +** The wal-index is transient. After a crash, the wal-index can (and should +** be) reconstructed from the original WAL file. In fact, the VFS is required +** to either truncate or zero the header of the wal-index when the last +** connection to it closes. Because the wal-index is transient, it can +** use an architecture-specific format; it does not have to be cross-platform. +** Hence, unlike the database and WAL file formats which store all values +** as big endian, the wal-index can store multi-byte values in the native +** byte order of the host computer. +** +** The purpose of the wal-index is to answer this question quickly: Given +** a page number P and a maximum frame index M, return the index of the +** last frame in the wal before frame M for page P in the WAL, or return +** NULL if there are no frames for page P in the WAL prior to M. +** +** The wal-index consists of a header region, followed by an one or +** more index blocks. +** +** The wal-index header contains the total number of frames within the WAL +** in the mxFrame field. +** +** Each index block except for the first contains information on +** HASHTABLE_NPAGE frames. The first index block contains information on +** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and +** HASHTABLE_NPAGE are selected so that together the wal-index header and +** first index block are the same size as all other index blocks in the +** wal-index. The values are: +** +** HASHTABLE_NPAGE 4096 +** HASHTABLE_NPAGE_ONE 4062 +** +** Each index block contains two sections, a page-mapping that contains the +** database page number associated with each wal frame, and a hash-table +** that allows readers to query an index block for a specific page number. +** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE +** for the first index block) 32-bit page numbers. The first entry in the +** first index-block contains the database page number corresponding to the +** first frame in the WAL file. The first entry in the second index block +** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in +** the log, and so on. +** +** The last index block in a wal-index usually contains less than the full +** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers, +** depending on the contents of the WAL file. This does not change the +** allocated size of the page-mapping array - the page-mapping array merely +** contains unused entries. +** +** Even without using the hash table, the last frame for page P +** can be found by scanning the page-mapping sections of each index block +** starting with the last index block and moving toward the first, and +** within each index block, starting at the end and moving toward the +** beginning. The first entry that equals P corresponds to the frame +** holding the content for that page. +** +** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers. +** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the +** hash table for each page number in the mapping section, so the hash +** table is never more than half full. The expected number of collisions +** prior to finding a match is 1. Each entry of the hash table is an +** 1-based index of an entry in the mapping section of the same +** index block. Let K be the 1-based index of the largest entry in +** the mapping section. (For index blocks other than the last, K will +** always be exactly HASHTABLE_NPAGE (4096) and for the last index block +** K will be (mxFrame%HASHTABLE_NPAGE).) Unused slots of the hash table +** contain a value of 0. +** +** To look for page P in the hash table, first compute a hash iKey on +** P as follows: +** +** iKey = (P * 383) % HASHTABLE_NSLOT +** +** Then start scanning entries of the hash table, starting with iKey +** (wrapping around to the beginning when the end of the hash table is +** reached) until an unused hash slot is found. Let the first unused slot +** be at index iUnused. (iUnused might be less than iKey if there was +** wrap-around.) Because the hash table is never more than half full, +** the search is guaranteed to eventually hit an unused entry. Let +** iMax be the value between iKey and iUnused, closest to iUnused, +** where aHash[iMax]==P. If there is no iMax entry (if there exists +** no hash slot such that aHash[i]==p) then page P is not in the +** current index block. Otherwise the iMax-th mapping entry of the +** current index block corresponds to the last entry that references +** page P. +** +** A hash search begins with the last index block and moves toward the +** first index block, looking for entries corresponding to page P. On +** average, only two or three slots in each index block need to be +** examined in order to either find the last entry for page P, or to +** establish that no such entry exists in the block. Each index block +** holds over 4000 entries. So two or three index blocks are sufficient +** to cover a typical 10 megabyte WAL file, assuming 1K pages. 8 or 10 +** comparisons (on average) suffice to either locate a frame in the +** WAL or to establish that the frame does not exist in the WAL. This +** is much faster than scanning the entire 10MB WAL. +** +** Note that entries are added in order of increasing K. Hence, one +** reader might be using some value K0 and a second reader that started +** at a later time (after additional transactions were added to the WAL +** and to the wal-index) might be using a different value K1, where K1>K0. +** Both readers can use the same hash table and mapping section to get +** the correct result. There may be entries in the hash table with +** K>K0 but to the first reader, those entries will appear to be unused +** slots in the hash table and so the first reader will get an answer as +** if no values greater than K0 had ever been inserted into the hash table +** in the first place - which is what reader one wants. Meanwhile, the +** second reader using K1 will see additional values that were inserted +** later, which is exactly what reader two wants. +** +** When a rollback occurs, the value of K is decreased. Hash table entries +** that correspond to frames greater than the new K value are removed +** from the hash table at this point. +*/ +#ifndef SQLITE_OMIT_WAL + +/* #include "wal.h" */ + +/* +** Trace output macros +*/ +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3WalTrace = 0; +# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X +#else +# define WALTRACE(X) +#endif + +/* +** The maximum (and only) versions of the wal and wal-index formats +** that may be interpreted by this version of SQLite. +** +** If a client begins recovering a WAL file and finds that (a) the checksum +** values in the wal-header are correct and (b) the version field is not +** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN. +** +** Similarly, if a client successfully reads a wal-index header (i.e. the +** checksum test is successful) and finds that the version field is not +** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite +** returns SQLITE_CANTOPEN. +*/ +#define WAL_MAX_VERSION 3007000 +#define WALINDEX_MAX_VERSION 3007000 + +/* +** Index numbers for various locking bytes. WAL_NREADER is the number +** of available reader locks and should be at least 3. The default +** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. +** +** Technically, the various VFSes are free to implement these locks however +** they see fit. However, compatibility is encouraged so that VFSes can +** interoperate. The standard implementation used on both unix and windows +** is for the index number to indicate a byte offset into the +** WalCkptInfo.aLock[] array in the wal-index header. In other words, all +** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which +** should be 120) is the location in the shm file for the first locking +** byte. +*/ +#define WAL_WRITE_LOCK 0 +#define WAL_ALL_BUT_WRITE 1 +#define WAL_CKPT_LOCK 1 +#define WAL_RECOVER_LOCK 2 +#define WAL_READ_LOCK(I) (3+(I)) +#define WAL_NREADER (SQLITE_SHM_NLOCK-3) + + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object followed by one instance of the WalCkptInfo object. +** For all versions of SQLite through 3.10.0 and probably beyond, +** the locking bytes (WalCkptInfo.aLock) start at offset 120 and +** the total header size is 136 bytes. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + u32 iVersion; /* Wal-index version */ + u32 unused; /* Unused (padding) field */ + u32 iChange; /* Counter incremented each transaction */ + u8 isInit; /* 1 when initialized */ + u8 bigEndCksum; /* True if checksums in WAL are big-endian */ + u16 szPage; /* Database page size in bytes. 1==64K */ + u32 mxFrame; /* Index of last valid frame in the WAL */ + u32 nPage; /* Size of database in pages */ + u32 aFrameCksum[2]; /* Checksum of last frame in log */ + u32 aSalt[2]; /* Two salt values copied from WAL header */ + u32 aCksum[2]; /* Checksum over all prior fields */ +}; + +/* +** A copy of the following object occurs in the wal-index immediately +** following the second copy of the WalIndexHdr. This object stores +** information used by checkpoint. +** +** nBackfill is the number of frames in the WAL that have been written +** back into the database. (We call the act of moving content from WAL to +** database "backfilling".) The nBackfill number is never greater than +** WalIndexHdr.mxFrame. nBackfill can only be increased by threads +** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). +** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from +** mxFrame back to zero when the WAL is reset. +** +** nBackfillAttempted is the largest value of nBackfill that a checkpoint +** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however +** the nBackfillAttempted is set before any backfilling is done and the +** nBackfill is only set after all backfilling completes. So if a checkpoint +** crashes, nBackfillAttempted might be larger than nBackfill. The +** WalIndexHdr.mxFrame must never be less than nBackfillAttempted. +** +** The aLock[] field is a set of bytes used for locking. These bytes should +** never be read or written. +** +** There is one entry in aReadMark[] for each reader lock. If a reader +** holds read-lock K, then the value in aReadMark[K] is no greater than +** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) +** for any aReadMark[] means that entry is unused. aReadMark[0] is +** a special case; its value is never used and it exists as a place-holder +** to avoid having to offset aReadMark[] indexes by one. Readers holding +** WAL_READ_LOCK(0) always ignore the entire WAL and read all content +** directly from the database. +** +** The value of aReadMark[K] may only be changed by a thread that +** is holding an exclusive lock on WAL_READ_LOCK(K). Thus, the value of +** aReadMark[K] cannot changed while there is a reader is using that mark +** since the reader will be holding a shared lock on WAL_READ_LOCK(K). +** +** The checkpointer may only transfer frames from WAL to database where +** the frame numbers are less than or equal to every aReadMark[] that is +** in use (that is, every aReadMark[j] for which there is a corresponding +** WAL_READ_LOCK(j)). New readers (usually) pick the aReadMark[] with the +** largest value and will increase an unused aReadMark[] to mxFrame if there +** is not already an aReadMark[] equal to mxFrame. The exception to the +** previous sentence is when nBackfill equals mxFrame (meaning that everything +** in the WAL has been backfilled into the database) then new readers +** will choose aReadMark[0] which has value 0 and hence such reader will +** get all their all content directly from the database file and ignore +** the WAL. +** +** Writers normally append new frames to the end of the WAL. However, +** if nBackfill equals mxFrame (meaning that all WAL content has been +** written back into the database) and if no readers are using the WAL +** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then +** the writer will first "reset" the WAL back to the beginning and start +** writing new content beginning at frame 1. +** +** We assume that 32-bit loads are atomic and so no locks are needed in +** order to read from any aReadMark[] entries. +*/ +struct WalCkptInfo { + u32 nBackfill; /* Number of WAL frames backfilled into DB */ + u32 aReadMark[WAL_NREADER]; /* Reader marks */ + u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */ + u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */ + u32 notUsed0; /* Available for future enhancements */ +}; +#define READMARK_NOT_USED 0xffffffff + +/* +** This is a schematic view of the complete 136-byte header of the +** wal-index file (also known as the -shm file): +** +** +-----------------------------+ +** 0: | iVersion | \ +** +-----------------------------+ | +** 4: | (unused padding) | | +** +-----------------------------+ | +** 8: | iChange | | +** +-------+-------+-------------+ | +** 12: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | +** 16: | mxFrame | | First copy of the +** +-----------------------------+ | WalIndexHdr object +** 20: | nPage | | +** +-----------------------------+ | +** 24: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 32: | aSalt | | +** | | | +** +-----------------------------+ | +** 40: | aCksum | | +** | | / +** +-----------------------------+ +** 48: | iVersion | \ +** +-----------------------------+ | +** 52: | (unused padding) | | +** +-----------------------------+ | +** 56: | iChange | | +** +-------+-------+-------------+ | +** 60: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | Second copy of the +** 64: | mxFrame | | WalIndexHdr +** +-----------------------------+ | +** 68: | nPage | | +** +-----------------------------+ | +** 72: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 80: | aSalt | | +** | | | +** +-----------------------------+ | +** 88: | aCksum | | +** | | / +** +-----------------------------+ +** 96: | nBackfill | +** +-----------------------------+ +** 100: | 5 read marks | +** | | +** | | +** | | +** | | +** +-------+-------+------+------+ +** 120: | Write | Ckpt | Rcvr | Rd0 | \ +** +-------+-------+------+------+ ) 8 lock bytes +** | Read1 | Read2 | Rd3 | Rd4 | / +** +-------+-------+------+------+ +** 128: | nBackfillAttempted | +** +-----------------------------+ +** 132: | (unused padding) | +** +-----------------------------+ +*/ + +/* A block of WALINDEX_LOCK_RESERVED bytes beginning at +** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems +** only support mandatory file-locks, we do not read or write data +** from the region of the file on which locks are applied. +*/ +#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock)) +#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo)) + +/* Size of header before each frame in wal */ +#define WAL_FRAME_HDRSIZE 24 + +/* Size of write ahead log header, including checksum. */ +#define WAL_HDRSIZE 32 + +/* WAL magic value. Either this value, or the same value with the least +** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit +** big-endian format in the first 4 bytes of a WAL file. +** +** If the LSB is set, then the checksums for each frame within the WAL +** file are calculated by treating all data as an array of 32-bit +** big-endian words. Otherwise, they are calculated by interpreting +** all data as 32-bit little-endian words. +*/ +#define WAL_MAGIC 0x377f0682 + +/* +** Return the offset of frame iFrame in the write-ahead log file, +** assuming a database page size of szPage bytes. The offset returned +** is to the start of the write-ahead log frame-header. +*/ +#define walFrameOffset(iFrame, szPage) ( \ + WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ +) + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +struct Wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + u32 iCallback; /* Value to pass to log callback (or 0) */ + i64 mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile u32 **apWiData; /* Pointer to wal-index content in memory */ + u32 szPage; /* Database page size */ + i16 readLock; /* Which read lock is being held. -1 for none */ + u8 syncFlags; /* Flags to use to sync header writes */ + u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ + u8 writeLock; /* True if in a write transaction */ + u8 ckptLock; /* True if holding a checkpoint lock */ + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + u8 truncateOnCommit; /* True to truncate WAL file on commit */ + u8 syncHeader; /* Fsync the WAL header if true */ + u8 padToSectorBoundary; /* Pad transactions out to the next sector */ + u8 bShmUnreliable; /* SHM content is read-only and unreliable */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + u32 minFrame; /* Ignore wal frames before this one */ + u32 iReCksum; /* On commit, recalculate checksums from here */ + const char *zWalName; /* Name of WAL file */ + u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ +#ifdef SQLITE_USE_SEH + u32 lockMask; /* Mask of locks held */ + void *pFree; /* Pointer to sqlite3_free() if exception thrown */ + u32 *pWiValue; /* Value to write into apWiData[iWiPg] */ + int iWiPg; /* Write pWiValue into apWiData[iWiPg] */ + int iSysErrno; /* System error code following exception */ +#endif +#ifdef SQLITE_DEBUG + int nSehTry; /* Number of nested SEH_TRY{} blocks */ + u8 lockError; /* True if a locking error has occurred */ +#endif +#ifdef SQLITE_ENABLE_SNAPSHOT + WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3 *db; +#endif +}; + +/* +** Candidate values for Wal.exclusiveMode. +*/ +#define WAL_NORMAL_MODE 0 +#define WAL_EXCLUSIVE_MODE 1 +#define WAL_HEAPMEMORY_MODE 2 + +/* +** Possible values for WAL.readOnly +*/ +#define WAL_RDWR 0 /* Normal read/write connection */ +#define WAL_RDONLY 1 /* The WAL file is readonly */ +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ + +/* +** Each page of the wal-index mapping contains a hash-table made up of +** an array of HASHTABLE_NSLOT elements of the following type. +*/ +typedef u16 ht_slot; + +/* +** This structure is used to implement an iterator that loops through +** all frames in the WAL in database page order. Where two or more frames +** correspond to the same database page, the iterator visits only the +** frame most recently written to the WAL (in other words, the frame with +** the largest index). +** +** The internals of this structure are only accessed by: +** +** walIteratorInit() - Create a new iterator, +** walIteratorNext() - Step an iterator, +** walIteratorFree() - Free an iterator. +** +** This functionality is used by the checkpoint code (see walCheckpoint()). +*/ +struct WalIterator { + u32 iPrior; /* Last result returned from the iterator */ + int nSegment; /* Number of entries in aSegment[] */ + struct WalSegment { + int iNext; /* Next slot in aIndex[] not yet returned */ + ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ + u32 *aPgno; /* Array of page numbers. */ + int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ + int iZero; /* Frame number associated with aPgno[0] */ + } aSegment[1]; /* One for every 32KB page in the wal-index */ +}; + +/* +** Define the parameters of the hash tables in the wal-index file. There +** is a hash-table following every HASHTABLE_NPAGE page numbers in the +** wal-index. +** +** Changing any of these constants will alter the wal-index format and +** create incompatibilities. +*/ +#define HASHTABLE_NPAGE 4096 /* Must be power of 2 */ +#define HASHTABLE_HASH_1 383 /* Should be prime */ +#define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ + +/* +** The block of page numbers associated with the first hash-table in a +** wal-index is smaller than usual. This is so that there is a complete +** hash-table on each aligned 32KB page of the wal-index. +*/ +#define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32))) + +/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */ +#define WALINDEX_PGSZ ( \ + sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \ +) + +/* +** Structured Exception Handling (SEH) is a Windows-specific technique +** for catching exceptions raised while accessing memory-mapped files. +** +** The -DSQLITE_USE_SEH compile-time option means to use SEH to catch and +** deal with system-level errors that arise during WAL -shm file processing. +** Without this compile-time option, any system-level faults that appear +** while accessing the memory-mapped -shm file will cause a process-wide +** signal to be deliver, which will more than likely cause the entire +** process to exit. +*/ +#ifdef SQLITE_USE_SEH +#include + +/* Beginning of a block of code in which an exception might occur */ +# define SEH_TRY __try { \ + assert( walAssertLockmask(pWal) && pWal->nSehTry==0 ); \ + VVA_ONLY(pWal->nSehTry++); + +/* The end of a block of code in which an exception might occur */ +# define SEH_EXCEPT(X) \ + VVA_ONLY(pWal->nSehTry--); \ + assert( pWal->nSehTry==0 ); \ + } __except( sehExceptionFilter(pWal, GetExceptionCode(), GetExceptionInformation() ) ){ X } + +/* Simulate a memory-mapping fault in the -shm file for testing purposes */ +# define SEH_INJECT_FAULT sehInjectFault(pWal) + +/* +** The second argument is the return value of GetExceptionCode() for the +** current exception. Return EXCEPTION_EXECUTE_HANDLER if the exception code +** indicates that the exception may have been caused by accessing the *-shm +** file mapping. Or EXCEPTION_CONTINUE_SEARCH otherwise. +*/ +static int sehExceptionFilter(Wal *pWal, int eCode, EXCEPTION_POINTERS *p){ + VVA_ONLY(pWal->nSehTry--); + if( eCode==EXCEPTION_IN_PAGE_ERROR ){ + if( p && p->ExceptionRecord && p->ExceptionRecord->NumberParameters>=3 ){ + /* From MSDN: For this type of exception, the first element of the + ** ExceptionInformation[] array is a read-write flag - 0 if the exception + ** was thrown while reading, 1 if while writing. The second element is + ** the virtual address being accessed. The "third array element specifies + ** the underlying NTSTATUS code that resulted in the exception". */ + pWal->iSysErrno = (int)p->ExceptionRecord->ExceptionInformation[2]; + } + return EXCEPTION_EXECUTE_HANDLER; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +/* +** If one is configured, invoke the xTestCallback callback with 650 as +** the argument. If it returns true, throw the same exception that is +** thrown by the system if the *-shm file mapping is accessed after it +** has been invalidated. +*/ +static void sehInjectFault(Wal *pWal){ + int res; + assert( pWal->nSehTry>0 ); + + res = sqlite3FaultSim(650); + if( res!=0 ){ + ULONG_PTR aArg[3]; + aArg[0] = 0; + aArg[1] = 0; + aArg[2] = (ULONG_PTR)res; + RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 3, (const ULONG_PTR*)aArg); + } +} + +/* +** There are two ways to use this macro. To set a pointer to be freed +** if an exception is thrown: +** +** SEH_FREE_ON_ERROR(0, pPtr); +** +** and to cancel the same: +** +** SEH_FREE_ON_ERROR(pPtr, 0); +** +** In the first case, there must not already be a pointer registered to +** be freed. In the second case, pPtr must be the registered pointer. +*/ +#define SEH_FREE_ON_ERROR(X,Y) \ + assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y + +/* +** There are two ways to use this macro. To arrange for pWal->apWiData[iPg] +** to be set to pValue if an exception is thrown: +** +** SEH_SET_ON_ERROR(iPg, pValue); +** +** and to cancel the same: +** +** SEH_SET_ON_ERROR(0, 0); +*/ +#define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y + +#else +# define SEH_TRY VVA_ONLY(pWal->nSehTry++); +# define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 ); +# define SEH_INJECT_FAULT assert( pWal->nSehTry>0 ); +# define SEH_FREE_ON_ERROR(X,Y) +# define SEH_SET_ON_ERROR(X,Y) +#endif /* ifdef SQLITE_USE_SEH */ + + +/* +** Obtain a pointer to the iPage'th page of the wal-index. The wal-index +** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are +** numbered from zero. +** +** If the wal-index is currently smaller the iPage pages then the size +** of the wal-index might be increased, but only if it is safe to do +** so. It is safe to enlarge the wal-index if pWal->writeLock is true +** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. +** +** Three possible result scenarios: +** +** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page +** (2) rc>=SQLITE_ERROR and *ppPage==NULL +** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0 +** +** Scenario (3) can only occur when pWal->writeLock is false and iPage==0 +*/ +static SQLITE_NOINLINE int walIndexPageRealloc( + Wal *pWal, /* The WAL context */ + int iPage, /* The page we seek */ + volatile u32 **ppPage /* Write the page pointer here */ +){ + int rc = SQLITE_OK; + + /* Enlarge the pWal->apWiData[] array if required */ + if( pWal->nWiData<=iPage ){ + sqlite3_int64 nByte = sizeof(u32*)*(iPage+1); + volatile u32 **apNew; + apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte); + if( !apNew ){ + *ppPage = 0; + return SQLITE_NOMEM_BKPT; + } + memset((void*)&apNew[pWal->nWiData], 0, + sizeof(u32*)*(iPage+1-pWal->nWiData)); + pWal->apWiData = apNew; + pWal->nWiData = iPage+1; + } + + /* Request a pointer to the required page from the VFS */ + assert( pWal->apWiData[iPage]==0 ); + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); + if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] + ); + assert( pWal->apWiData[iPage]!=0 + || rc!=SQLITE_OK + || (pWal->writeLock==0 && iPage==0) ); + testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK ); + if( rc==SQLITE_OK ){ + if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM; + }else if( (rc&0xff)==SQLITE_READONLY ){ + pWal->readOnly |= WAL_SHM_RDONLY; + if( rc==SQLITE_READONLY ){ + rc = SQLITE_OK; + } + } + } + + *ppPage = pWal->apWiData[iPage]; + assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); + return rc; +} +static int walIndexPage( + Wal *pWal, /* The WAL context */ + int iPage, /* The page we seek */ + volatile u32 **ppPage /* Write the page pointer here */ +){ + SEH_INJECT_FAULT; + if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ + return walIndexPageRealloc(pWal, iPage, ppPage); + } + return SQLITE_OK; +} + +/* +** Return a pointer to the WalCkptInfo structure in the wal-index. +*/ +static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + SEH_INJECT_FAULT; + return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); +} + +/* +** Return a pointer to the WalIndexHdr structure in the wal-index. +*/ +static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + SEH_INJECT_FAULT; + return (volatile WalIndexHdr*)pWal->apWiData[0]; +} + +/* +** The argument to this macro must be of type u32. On a little-endian +** architecture, it returns the u32 value that results from interpreting +** the 4 bytes as a big-endian value. On a big-endian architecture, it +** returns the value that would be produced by interpreting the 4 bytes +** of the input value as a little-endian integer. +*/ +#define BYTESWAP32(x) ( \ + (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \ + + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \ +) + +/* +** Generate or extend an 8 byte checksum based on the data in +** array aByte[] and the initial values of aIn[0] and aIn[1] (or +** initial values of 0 and 0 if aIn==NULL). +** +** The checksum is written back into aOut[] before returning. +** +** nByte must be a positive multiple of 8. +*/ +static void walChecksumBytes( + int nativeCksum, /* True for native byte-order, false for non-native */ + u8 *a, /* Content to be checksummed */ + int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */ + const u32 *aIn, /* Initial checksum value input */ + u32 *aOut /* OUT: Final checksum value output */ +){ + u32 s1, s2; + u32 *aData = (u32 *)a; + u32 *aEnd = (u32 *)&a[nByte]; + + if( aIn ){ + s1 = aIn[0]; + s2 = aIn[1]; + }else{ + s1 = s2 = 0; + } + + assert( nByte>=8 ); + assert( (nByte&0x00000007)==0 ); + assert( nByte<=65536 ); + assert( nByte%4==0 ); + + if( !nativeCksum ){ + do { + s1 += BYTESWAP32(aData[0]) + s2; + s2 += BYTESWAP32(aData[1]) + s1; + aData += 2; + }while( aDataexclusiveMode!=WAL_HEAPMEMORY_MODE ){ + sqlite3OsShmBarrier(pWal->pDbFd); + } +} + +/* +** Add the SQLITE_NO_TSAN as part of the return-type of a function +** definition as a hint that the function contains constructs that +** might give false-positive TSAN warnings. +** +** See tag-20200519-1. +*/ +#if defined(__clang__) && !defined(SQLITE_NO_TSAN) +# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread)) +#else +# define SQLITE_NO_TSAN +#endif + +/* +** Write the header information in pWal->hdr into the wal-index. +** +** The checksum on pWal->hdr is updated before it is written. +*/ +static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){ + volatile WalIndexHdr *aHdr = walIndexHdr(pWal); + const int nCksum = offsetof(WalIndexHdr, aCksum); + + assert( pWal->writeLock ); + pWal->hdr.isInit = 1; + pWal->hdr.iVersion = WALINDEX_MAX_VERSION; + walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); + /* Possible TSAN false-positive. See tag-20200519-1 */ + memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); + walShmBarrier(pWal); + memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); +} + +/* +** This function encodes a single frame header and writes it to a buffer +** supplied by the caller. A frame-header is made up of a series of +** 4-byte big-endian integers, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the wal-header) +** 12: Salt-2 (copied from the wal-header) +** 16: Checksum-1. +** 20: Checksum-2. +*/ +static void walEncodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 iPage, /* Database page number for frame */ + u32 nTruncate, /* New db size (or 0 for non-commit frames) */ + u8 *aData, /* Pointer to page data */ + u8 *aFrame /* OUT: Write encoded frame here */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + assert( WAL_FRAME_HDRSIZE==24 ); + sqlite3Put4byte(&aFrame[0], iPage); + sqlite3Put4byte(&aFrame[4], nTruncate); + if( pWal->iReCksum==0 ){ + memcpy(&aFrame[8], pWal->hdr.aSalt, 8); + + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + + sqlite3Put4byte(&aFrame[16], aCksum[0]); + sqlite3Put4byte(&aFrame[20], aCksum[1]); + }else{ + memset(&aFrame[8], 0, 16); + } +} + +/* +** Check to see if the frame with header in aFrame[] and content +** in aData[] is valid. If it is a valid frame, fill *piPage and +** *pnTruncate and return true. Return if the frame is not valid. +*/ +static int walDecodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 *piPage, /* OUT: Database page number for frame */ + u32 *pnTruncate, /* OUT: New db size (or 0 if not commit) */ + u8 *aData, /* Pointer to page data (for checksum) */ + u8 *aFrame /* Frame data */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + u32 pgno; /* Page number of the frame */ + assert( WAL_FRAME_HDRSIZE==24 ); + + /* A frame is only valid if the salt values in the frame-header + ** match the salt values in the wal-header. + */ + if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ + return 0; + } + + /* A frame is only valid if the page number is greater than zero. + */ + pgno = sqlite3Get4byte(&aFrame[0]); + if( pgno==0 ){ + return 0; + } + + /* A frame is only valid if a checksum of the WAL header, + ** all prior frames, the first 16 bytes of this frame-header, + ** and the frame-data matches the checksum in the last 8 + ** bytes of this frame-header. + */ + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) + || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) + ){ + /* Checksum failed. */ + return 0; + } + + /* If we reach this point, the frame is valid. Return the page number + ** and the new database size. + */ + *piPage = pgno; + *pnTruncate = sqlite3Get4byte(&aFrame[4]); + return 1; +} + + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +/* +** Names of locks. This routine is used to provide debugging output and is not +** a part of an ordinary build. +*/ +static const char *walLockName(int lockIdx){ + if( lockIdx==WAL_WRITE_LOCK ){ + return "WRITE-LOCK"; + }else if( lockIdx==WAL_CKPT_LOCK ){ + return "CKPT-LOCK"; + }else if( lockIdx==WAL_RECOVER_LOCK ){ + return "RECOVER-LOCK"; + }else{ + static char zName[15]; + sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", + lockIdx-WAL_READ_LOCK(0)); + return zName; + } +} +#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ + + +/* +** Set or release locks on the WAL. Locks are either shared or exclusive. +** A lock cannot be moved directly between shared and exclusive - it must go +** through the unlocked state first. +** +** In locking_mode=EXCLUSIVE, all of these routines become no-ops. +*/ +static int walLockShared(Wal *pWal, int lockIdx){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); + WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, + walLockName(lockIdx), rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_OK ) pWal->lockMask |= (1 << lockIdx); +#endif + return rc; +} +static void walUnlockShared(Wal *pWal, int lockIdx){ + if( pWal->exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); +#ifdef SQLITE_USE_SEH + pWal->lockMask &= ~(1 << lockIdx); +#endif + WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); +} +static int walLockExclusive(Wal *pWal, int lockIdx, int n){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); + WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, + walLockName(lockIdx), n, rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_OK ){ + pWal->lockMask |= (((1<exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); +#ifdef SQLITE_USE_SEH + pWal->lockMask &= ~(((1<0 ); + assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 ); + return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1); +} +static int walNextHash(int iPriorHash){ + return (iPriorHash+1)&(HASHTABLE_NSLOT-1); +} + +/* +** An instance of the WalHashLoc object is used to describe the location +** of a page hash table in the wal-index. This becomes the return value +** from walHashGet(). +*/ +typedef struct WalHashLoc WalHashLoc; +struct WalHashLoc { + volatile ht_slot *aHash; /* Start of the wal-index hash table */ + volatile u32 *aPgno; /* aPgno[1] is the page of first frame indexed */ + u32 iZero; /* One less than the frame number of first indexed*/ +}; + +/* +** Return pointers to the hash table and page number array stored on +** page iHash of the wal-index. The wal-index is broken into 32KB pages +** numbered starting from 0. +** +** Set output variable pLoc->aHash to point to the start of the hash table +** in the wal-index file. Set pLoc->iZero to one less than the frame +** number of the first frame indexed by this hash table. If a +** slot in the hash table is set to N, it refers to frame number +** (pLoc->iZero+N) in the log. +** +** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the +** first frame indexed by the hash table, frame (pLoc->iZero). +*/ +static int walHashGet( + Wal *pWal, /* WAL handle */ + int iHash, /* Find the iHash'th table */ + WalHashLoc *pLoc /* OUT: Hash table location */ +){ + int rc; /* Return code */ + + rc = walIndexPage(pWal, iHash, &pLoc->aPgno); + assert( rc==SQLITE_OK || iHash>0 ); + + if( pLoc->aPgno ){ + pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE]; + if( iHash==0 ){ + pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; + pLoc->iZero = 0; + }else{ + pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; + } + }else if( NEVER(rc==SQLITE_OK) ){ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Return the number of the wal-index page that contains the hash-table +** and page-number array that contain entries corresponding to WAL frame +** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages +** are numbered starting from 0. +*/ +static int walFramePage(u32 iFrame){ + int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE; + assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE) + && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE) + && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)) + && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE) + && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE)) + ); + assert( iHash>=0 ); + return iHash; +} + +/* +** Return the page number associated with frame iFrame in this WAL. +*/ +static u32 walFramePgno(Wal *pWal, u32 iFrame){ + int iHash = walFramePage(iFrame); + SEH_INJECT_FAULT; + if( iHash==0 ){ + return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; + } + return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE]; +} + +/* +** Remove entries from the hash table that point to WAL slots greater +** than pWal->hdr.mxFrame. +** +** This function is called whenever pWal->hdr.mxFrame is decreased due +** to a rollback or savepoint. +** +** At most only the hash table containing pWal->hdr.mxFrame needs to be +** updated. Any later hash tables will be automatically cleared when +** pWal->hdr.mxFrame advances to the point where those hash tables are +** actually needed. +*/ +static void walCleanupHash(Wal *pWal){ + WalHashLoc sLoc; /* Hash table location */ + int iLimit = 0; /* Zero values greater than this */ + int nByte; /* Number of bytes to zero in aPgno[] */ + int i; /* Used to iterate through aHash[] */ + + assert( pWal->writeLock ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 ); + + if( pWal->hdr.mxFrame==0 ) return; + + /* Obtain pointers to the hash-table and page-number array containing + ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed + ** that the page said hash-table and array reside on is already mapped.(1) + */ + assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); + assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); + i = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); + if( NEVER(i) ) return; /* Defense-in-depth, in case (1) above is wrong */ + + /* Zero all hash-table entries that correspond to frame numbers greater + ** than pWal->hdr.mxFrame. + */ + iLimit = pWal->hdr.mxFrame - sLoc.iZero; + assert( iLimit>0 ); + for(i=0; iiLimit ){ + sLoc.aHash[i] = 0; + } + } + + /* Zero the entries in the aPgno array that correspond to frames with + ** frame numbers greater than pWal->hdr.mxFrame. + */ + nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]); + assert( nByte>=0 ); + memset((void *)&sLoc.aPgno[iLimit], 0, nByte); + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the every entry in the mapping region is still reachable + ** via the hash table even after the cleanup. + */ + if( iLimit ){ + int j; /* Loop counter */ + int iKey; /* Hash key */ + for(j=0; j=0 ); + memset((void*)sLoc.aPgno, 0, nByte); + } + + /* If the entry in aPgno[] is already set, then the previous writer + ** must have exited unexpectedly in the middle of a transaction (after + ** writing one or more dirty pages to the WAL to free up memory). + ** Remove the remnants of that writers uncommitted transaction from + ** the hash-table before writing any new entries. + */ + if( sLoc.aPgno[idx-1] ){ + walCleanupHash(pWal); + assert( !sLoc.aPgno[idx-1] ); + } + + /* Write the aPgno[] array entry and the hash-table slot. */ + nCollide = idx; + for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ + if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; + } + sLoc.aPgno[idx-1] = iPage; + AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx); + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the number of entries in the hash table exactly equals + ** the number of entries in the mapping region. + */ + { + int i; /* Loop counter */ + int nEntry = 0; /* Number of entries in the hash table */ + for(i=0; ickptLock==1 || pWal->ckptLock==0 ); + assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); + assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); + assert( pWal->writeLock ); + iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; + rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + if( rc ){ + return rc; + } + + WALTRACE(("WAL%p: recovery begin...\n", pWal)); + + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + + rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + if( nSize>WAL_HDRSIZE ){ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u32 *aPrivate = 0; /* Heap copy of *-shm hash being populated */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + int szPage; /* Page size according to the log */ + u32 magic; /* Magic value read from WAL header */ + u32 version; /* Magic value read from WAL header */ + int isValid; /* True if this frame is valid */ + u32 iPg; /* Current 32KB wal-index page */ + u32 iLastFrame; /* Last frame in wal, based on nSize alone */ + + /* Read in the WAL header. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + /* If the database page size is not a power of two, or is greater than + ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid + ** data. Similarly, if the 'magic' value is invalid, ignore the whole + ** WAL file. + */ + magic = sqlite3Get4byte(&aBuf[0]); + szPage = sqlite3Get4byte(&aBuf[8]); + if( (magic&0xFFFFFFFE)!=WAL_MAGIC + || szPage&(szPage-1) + || szPage>SQLITE_MAX_PAGE_SIZE + || szPage<512 + ){ + goto finished; + } + pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); + pWal->szPage = szPage; + pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); + memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); + + /* Verify that the WAL header checksum is correct */ + walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, + aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum + ); + if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) + || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28]) + ){ + goto finished; + } + + /* Verify that the version number on the WAL format is one that + ** are able to understand */ + version = sqlite3Get4byte(&aBuf[4]); + if( version!=WAL_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + goto finished; + } + + /* Malloc a buffer to read frames into. */ + szFrame = szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ); + SEH_FREE_ON_ERROR(0, aFrame); + if( !aFrame ){ + rc = SQLITE_NOMEM_BKPT; + goto recovery_error; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + aPrivate = (u32*)&aData[szPage]; + + /* Read all frames from the log file. */ + iLastFrame = (nSize - WAL_HDRSIZE) / szFrame; + for(iPg=0; iPg<=(u32)walFramePage(iLastFrame); iPg++){ + u32 *aShare; + u32 iFrame; /* Index of last frame read */ + u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE); + u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE); + u32 nHdr, nHdr32; + rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); + assert( aShare!=0 || rc!=SQLITE_OK ); + if( aShare==0 ) break; + SEH_SET_ON_ERROR(iPg, aShare); + pWal->apWiData[iPg] = aPrivate; + + for(iFrame=iFirst; iFrame<=iLast; iFrame++){ + i64 iOffset = walFrameOffset(iFrame, szPage); + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + + /* Read and decode the next log frame. */ + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); + if( !isValid ) break; + rc = walIndexAppend(pWal, iFrame, pgno); + if( NEVER(rc!=SQLITE_OK) ) break; + + /* If nTruncate is non-zero, this is a commit record. */ + if( nTruncate ){ + pWal->hdr.mxFrame = iFrame; + pWal->hdr.nPage = nTruncate; + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; + aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; + } + } + pWal->apWiData[iPg] = aShare; + SEH_SET_ON_ERROR(0,0); + nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); + nHdr32 = nHdr / sizeof(u32); +#ifndef SQLITE_SAFER_WALINDEX_RECOVERY + /* Memcpy() should work fine here, on all reasonable implementations. + ** Technically, memcpy() might change the destination to some + ** intermediate value before setting to the final value, and that might + ** cause a concurrent reader to malfunction. Memcpy() is allowed to + ** do that, according to the spec, but no memcpy() implementation that + ** we know of actually does that, which is why we say that memcpy() + ** is safe for this. Memcpy() is certainly a lot faster. + */ + memcpy(&aShare[nHdr32], &aPrivate[nHdr32], WALINDEX_PGSZ-nHdr); +#else + /* In the event that some platform is found for which memcpy() + ** changes the destination to some intermediate value before + ** setting the final value, this alternative copy routine is + ** provided. + */ + { + int i; + for(i=nHdr32; ihdr.aFrameCksum[0] = aFrameCksum[0]; + pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; + walIndexWriteHdr(pWal); + + /* Reset the checkpoint-header. This is safe because this thread is + ** currently holding locks that exclude all other writers and + ** checkpointers. Then set the values of read-mark slots 1 through N. + */ + pInfo = walCkptInfo(pWal); + pInfo->nBackfill = 0; + pInfo->nBackfillAttempted = pWal->hdr.mxFrame; + pInfo->aReadMark[0] = 0; + for(i=1; ihdr.mxFrame ){ + pInfo->aReadMark[i] = pWal->hdr.mxFrame; + }else{ + pInfo->aReadMark[i] = READMARK_NOT_USED; + } + SEH_INJECT_FAULT; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + }else if( rc!=SQLITE_BUSY ){ + goto recovery_error; + } + } + + /* If more than one frame was recovered from the log file, report an + ** event via sqlite3_log(). This is to help with identifying performance + ** problems caused by applications routinely shutting down without + ** checkpointing the log file. + */ + if( pWal->hdr.nPage ){ + sqlite3_log(SQLITE_NOTICE_RECOVER_WAL, + "recovered %d frames from WAL file %s", + pWal->hdr.mxFrame, pWal->zWalName + ); + } + } + +recovery_error: + WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); + walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + return rc; +} + +/* +** Close an open wal-index. +*/ +static void walIndexClose(Wal *pWal, int isDelete){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){ + int i; + for(i=0; inWiData; i++){ + sqlite3_free((void *)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + } + if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ + sqlite3OsShmUnmap(pWal->pDbFd, isDelete); + } +} + +/* +** Open a connection to the WAL file zWalName. The database file must +** already be opened on connection pDbFd. The buffer that zWalName points +** to must remain valid for the lifetime of the returned Wal* handle. +** +** A SHARED lock should be held on the database file when this function +** is called. The purpose of this SHARED lock is to prevent any other +** client from unlinking the WAL or wal-index file. If another process +** were to do this just after this client opened one of these files, the +** system would be badly broken. +** +** If the log file is successfully opened, SQLITE_OK is returned and +** *ppWal is set to point to a new WAL handle. If an error occurs, +** an SQLite error code is returned and *ppWal is left unmodified. +*/ +SQLITE_PRIVATE int sqlite3WalOpen( + sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ + sqlite3_file *pDbFd, /* The open database file */ + const char *zWalName, /* Name of the WAL file */ + int bNoShm, /* True to run in heap-memory mode */ + i64 mxWalSize, /* Truncate WAL to this size on reset */ + Wal **ppWal /* OUT: Allocated Wal handle */ +){ + int rc; /* Return Code */ + Wal *pRet; /* Object to allocate and return */ + int flags; /* Flags passed to OsOpen() */ + + assert( zWalName && zWalName[0] ); + assert( pDbFd ); + + /* Verify the values of various constants. Any changes to the values + ** of these constants would result in an incompatible on-disk format + ** for the -shm file. Any change that causes one of these asserts to + ** fail is a backward compatibility problem, even if the change otherwise + ** works. + ** + ** This table also serves as a helpful cross-reference when trying to + ** interpret hex dumps of the -shm file. + */ + assert( 48 == sizeof(WalIndexHdr) ); + assert( 40 == sizeof(WalCkptInfo) ); + assert( 120 == WALINDEX_LOCK_OFFSET ); + assert( 136 == WALINDEX_HDR_SIZE ); + assert( 4096 == HASHTABLE_NPAGE ); + assert( 4062 == HASHTABLE_NPAGE_ONE ); + assert( 8192 == HASHTABLE_NSLOT ); + assert( 383 == HASHTABLE_HASH_1 ); + assert( 32768 == WALINDEX_PGSZ ); + assert( 8 == SQLITE_SHM_NLOCK ); + assert( 5 == WAL_NREADER ); + assert( 24 == WAL_FRAME_HDRSIZE ); + assert( 32 == WAL_HDRSIZE ); + assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); + assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); + assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); + assert( 123 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(0) ); + assert( 124 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(1) ); + assert( 125 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(2) ); + assert( 126 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(3) ); + assert( 127 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(4) ); + + /* In the amalgamation, the os_unix.c and os_win.c source files come before + ** this source file. Verify that the #defines of the locking byte offsets + ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. + ** For that matter, if the lock offset ever changes from its initial design + ** value of 120, we need to know that so there is an assert() to check it. + */ +#ifdef WIN_SHM_BASE + assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif +#ifdef UNIX_SHM_BASE + assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif + + + /* Allocate an instance of struct Wal to return. */ + *ppWal = 0; + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); + if( !pRet ){ + return SQLITE_NOMEM_BKPT; + } + + pRet->pVfs = pVfs; + pRet->pWalFd = (sqlite3_file *)&pRet[1]; + pRet->pDbFd = pDbFd; + pRet->readLock = -1; + pRet->mxWalSize = mxWalSize; + pRet->zWalName = zWalName; + pRet->syncHeader = 1; + pRet->padToSectorBoundary = 1; + pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); + + /* Open file handle on the write-ahead log file. */ + flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); + rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); + if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ + pRet->readOnly = WAL_RDONLY; + } + + if( rc!=SQLITE_OK ){ + walIndexClose(pRet, 0); + sqlite3OsClose(pRet->pWalFd); + sqlite3_free(pRet); + }else{ + int iDC = sqlite3OsDeviceCharacteristics(pDbFd); + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } + if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ + pRet->padToSectorBoundary = 0; + } + *ppWal = pRet; + WALTRACE(("WAL%d: opened\n", pRet)); + } + return rc; +} + +/* +** Change the size to which the WAL file is truncated on each reset. +*/ +SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ + if( pWal ) pWal->mxWalSize = iLimit; +} + +/* +** Find the smallest page number out of all pages held in the WAL that +** has not been returned by any prior invocation of this method on the +** same WalIterator object. Write into *piFrame the frame index where +** that page was last written into the WAL. Write into *piPage the page +** number. +** +** Return 0 on success. If there are no pages in the WAL with a page +** number larger than *piPage, then return 1. +*/ +static int walIteratorNext( + WalIterator *p, /* Iterator */ + u32 *piPage, /* OUT: The page number of the next page */ + u32 *piFrame /* OUT: Wal frame index of next page */ +){ + u32 iMin; /* Result pgno must be greater than iMin */ + u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ + int i; /* For looping through segments */ + + iMin = p->iPrior; + assert( iMin<0xffffffff ); + for(i=p->nSegment-1; i>=0; i--){ + struct WalSegment *pSegment = &p->aSegment[i]; + while( pSegment->iNextnEntry ){ + u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; + if( iPg>iMin ){ + if( iPgiZero + pSegment->aIndex[pSegment->iNext]; + } + break; + } + pSegment->iNext++; + } + } + + *piPage = p->iPrior = iRet; + return (iRet==0xFFFFFFFF); +} + +/* +** This function merges two sorted lists into a single sorted list. +** +** aLeft[] and aRight[] are arrays of indices. The sort key is +** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following +** is guaranteed for all J0 && nRight>0 ); + while( iRight=nRight || aContent[aLeft[iLeft]]=nLeft || aContent[aLeft[iLeft]]>dbpage ); + assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); + } + + *paRight = aLeft; + *pnRight = iOut; + memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); +} + +/* +** Sort the elements in list aList using aContent[] as the sort key. +** Remove elements with duplicate keys, preferring to keep the +** larger aList[] values. +** +** The aList[] entries are indices into aContent[]. The values in +** aList[] are to be sorted so that for all J0 ); + assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); + + for(iList=0; iListaList && p->nList<=(1<aList==&aList[iList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + aSub[iSub].aList = aMerge; + aSub[iSub].nList = nMerge; + } + + for(iSub++; iSubnList<=(1<aList==&aList[nList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + } + assert( aMerge==aList ); + *pnList = nMerge; + +#ifdef SQLITE_DEBUG + { + int i; + for(i=1; i<*pnList; i++){ + assert( aContent[aList[i]] > aContent[aList[i-1]] ); + } + } +#endif +} + +/* +** Free an iterator allocated by walIteratorInit(). +*/ +static void walIteratorFree(WalIterator *p){ + sqlite3_free(p); +} + +/* +** Construct a WalInterator object that can be used to loop over all +** pages in the WAL following frame nBackfill in ascending order. Frames +** nBackfill or earlier may be included - excluding them is an optimization +** only. The caller must hold the checkpoint lock. +** +** On success, make *pp point to the newly allocated WalInterator object +** return SQLITE_OK. Otherwise, return an error code. If this routine +** returns an error, the value of *pp is undefined. +** +** The calling routine should invoke walIteratorFree() to destroy the +** WalIterator object when it has finished with it. +*/ +static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ + WalIterator *p; /* Return value */ + int nSegment; /* Number of segments to merge */ + u32 iLast; /* Last frame in log */ + sqlite3_int64 nByte; /* Number of bytes to allocate */ + int i; /* Iterator variable */ + ht_slot *aTmp; /* Temp space used by merge-sort */ + int rc = SQLITE_OK; /* Return Code */ + + /* This routine only runs while holding the checkpoint lock. And + ** it only runs if there is actually content in the log (mxFrame>0). + */ + assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); + iLast = pWal->hdr.mxFrame; + + /* Allocate space for the WalIterator object. */ + nSegment = walFramePage(iLast) + 1; + nByte = sizeof(WalIterator) + + (nSegment-1)*sizeof(struct WalSegment) + + iLast*sizeof(ht_slot); + p = (WalIterator *)sqlite3_malloc64(nByte + + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) + ); + if( !p ){ + return SQLITE_NOMEM_BKPT; + } + memset(p, 0, nByte); + p->nSegment = nSegment; + aTmp = (ht_slot*)&(((u8*)p)[nByte]); + SEH_FREE_ON_ERROR(0, p); + for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && iaSegment[p->nSegment])[sLoc.iZero]; + sLoc.iZero++; + + for(j=0; jaSegment[i].iZero = sLoc.iZero; + p->aSegment[i].nEntry = nEntry; + p->aSegment[i].aIndex = aIndex; + p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; + } + } + if( rc!=SQLITE_OK ){ + SEH_FREE_ON_ERROR(p, 0); + walIteratorFree(p); + p = 0; + } + *pp = p; + return rc; +} + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + + +/* +** Attempt to enable blocking locks that block for nMs ms. Return 1 if +** blocking locks are successfully enabled, or 0 otherwise. +*/ +static int walEnableBlockingMs(Wal *pWal, int nMs){ + int rc = sqlite3OsFileControl( + pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs + ); + return (rc==SQLITE_OK); +} + +/* +** Attempt to enable blocking locks. Blocking locks are enabled only if (a) +** they are supported by the VFS, and (b) the database handle is configured +** with a busy-timeout. Return 1 if blocking locks are successfully enabled, +** or 0 otherwise. +*/ +static int walEnableBlocking(Wal *pWal){ + int res = 0; + if( pWal->db ){ + int tmout = pWal->db->busyTimeout; + if( tmout ){ + res = walEnableBlockingMs(pWal, tmout); + } + } + return res; +} + +/* +** Disable blocking locks. +*/ +static void walDisableBlocking(Wal *pWal){ + int tmout = 0; + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout); +} + +/* +** If parameter bLock is true, attempt to enable blocking locks, take +** the WRITER lock, and then disable blocking locks. If blocking locks +** cannot be enabled, no attempt to obtain the WRITER lock is made. Return +** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not +** an error if blocking locks can not be enabled. +** +** If the bLock parameter is false and the WRITER lock is held, release it. +*/ +SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){ + int rc = SQLITE_OK; + assert( pWal->readLock<0 || bLock==0 ); + if( bLock ){ + assert( pWal->db ); + if( walEnableBlocking(pWal) ){ + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + } + walDisableBlocking(pWal); + } + }else if( pWal->writeLock ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + } + return rc; +} + +/* +** Set the database handle used to determine if blocking locks are required. +*/ +SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ + pWal->db = db; +} + +#else +# define walEnableBlocking(x) 0 +# define walDisableBlocking(x) +# define walEnableBlockingMs(pWal, ms) 0 +# define sqlite3WalDb(pWal, db) +#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ + + +/* +** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and +** n. If the attempt fails and parameter xBusy is not NULL, then it is a +** busy-handler function. Invoke it and retry the lock until either the +** lock is successfully obtained or the busy-handler returns 0. +*/ +static int walBusyLock( + Wal *pWal, /* WAL connection */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int lockIdx, /* Offset of first byte to lock */ + int n /* Number of bytes to lock */ +){ + int rc; + do { + rc = walLockExclusive(pWal, lockIdx, n); + }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + walDisableBlocking(pWal); + rc = SQLITE_BUSY; + } +#endif + return rc; +} + +/* +** The cache of the wal-index header must be valid to call this function. +** Return the page-size in bytes used by the database. +*/ +static int walPagesize(Wal *pWal){ + return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); +} + +/* +** The following is guaranteed when this function is called: +** +** a) the WRITER lock is held, +** b) the entire log file has been checkpointed, and +** c) any existing readers are reading exclusively from the database +** file - there are no readers that may attempt to read a frame from +** the log file. +** +** This function updates the shared-memory structures so that the next +** client to write to the database (which may be this one) does so by +** writing frames into the start of the log file. +** +** The value of parameter salt1 is used as the aSalt[1] value in the +** new wal-index header. It should be passed a pseudo-random value (i.e. +** one obtained from sqlite3_randomness()). +*/ +static void walRestartHdr(Wal *pWal, u32 salt1){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + int i; /* Loop counter */ + u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ + pWal->nCkpt++; + pWal->hdr.mxFrame = 0; + sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); + memcpy(&pWal->hdr.aSalt[1], &salt1, 4); + walIndexWriteHdr(pWal); + AtomicStore(&pInfo->nBackfill, 0); + pInfo->nBackfillAttempted = 0; + pInfo->aReadMark[1] = 0; + for(i=2; iaReadMark[i] = READMARK_NOT_USED; + assert( pInfo->aReadMark[0]==0 ); +} + +/* +** Copy as much content as we can from the WAL back into the database file +** in response to an sqlite3_wal_checkpoint() request or the equivalent. +** +** The amount of information copies from WAL to database might be limited +** by active readers. This routine will never overwrite a database page +** that a concurrent reader might be using. +** +** All I/O barrier operations (a.k.a fsyncs) occur in this routine when +** SQLite is in WAL-mode in synchronous=NORMAL. That means that if +** checkpoints are always run by a background thread or background +** process, foreground threads will never block on a lengthy fsync call. +** +** Fsync is called on the WAL before writing content out of the WAL and +** into the database. This ensures that if the new content is persistent +** in the WAL and can be recovered following a power-loss or hard reset. +** +** Fsync is also called on the database file if (and only if) the entire +** WAL content is copied into the database file. This second fsync makes +** it safe to delete the WAL since the new content will persist in the +** database file. +** +** This routine uses and updates the nBackfill field of the wal-index header. +** This is the only routine that will increase the value of nBackfill. +** (A WAL reset or recovery will revert nBackfill to zero, but not increase +** its value.) +** +** The caller must be holding sufficient locks to ensure that no other +** checkpoint is running (in any other thread or process) at the same +** time. +*/ +static int walCheckpoint( + Wal *pWal, /* Wal connection */ + sqlite3 *db, /* Check for interrupts on this handle */ + int eMode, /* One of PASSIVE, FULL or RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags for OsSync() (or 0) */ + u8 *zBuf /* Temporary buffer to use */ +){ + int rc = SQLITE_OK; /* Return code */ + int szPage; /* Database page-size */ + WalIterator *pIter = 0; /* Wal iterator context */ + u32 iDbpage = 0; /* Next database page to write */ + u32 iFrame = 0; /* Wal frame containing data for iDbpage */ + u32 mxSafeFrame; /* Max frame that can be backfilled */ + u32 mxPage; /* Max database page to write */ + int i; /* Loop counter */ + volatile WalCkptInfo *pInfo; /* The checkpoint status information */ + + szPage = walPagesize(pWal); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pInfo = walCkptInfo(pWal); + if( pInfo->nBackfillhdr.mxFrame ){ + + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); + + /* Compute in mxSafeFrame the index of the last frame of the WAL that is + ** safe to write into the database. Frames beyond mxSafeFrame might + ** overwrite database pages that are in use by active readers and thus + ** cannot be backfilled from the WAL. + */ + mxSafeFrame = pWal->hdr.mxFrame; + mxPage = pWal->hdr.nPage; + for(i=1; iaReadMark+i); SEH_INJECT_FAULT; + if( mxSafeFrame>y ){ + assert( y<=pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); + AtomicStore(pInfo->aReadMark+i, iMark); SEH_INJECT_FAULT; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + }else if( rc==SQLITE_BUSY ){ + mxSafeFrame = y; + xBusy = 0; + }else{ + goto walcheckpoint_out; + } + } + } + + /* Allocate the iterator */ + if( pInfo->nBackfillnBackfill, &pIter); + assert( rc==SQLITE_OK || pIter==0 ); + } + + if( pIter + && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK + ){ + u32 nBackfill = pInfo->nBackfill; + pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; + + /* Sync the WAL to disk */ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + + /* If the database may grow as a result of this checkpoint, hint + ** about the eventual size of the db file to the VFS layer. + */ + if( rc==SQLITE_OK ){ + i64 nReq = ((i64)mxPage * szPage); + i64 nSize; /* Current size of database file */ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0); + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); + if( rc==SQLITE_OK && nSizehdr.mxFrame*szPage)pDbFd, SQLITE_FCNTL_SIZE_HINT,&nReq); + } + } + + } + + /* Iterate through the contents of the WAL, copying data to the db file */ + while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ + i64 iOffset; + assert( walFramePgno(pWal, iFrame)==iDbpage ); + SEH_INJECT_FAULT; + if( AtomicLoad(&db->u1.isInterrupted) ){ + rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; + break; + } + if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ + continue; + } + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + iOffset = (iDbpage-1)*(i64)szPage; + testcase( IS_BIG_INT(iOffset) ); + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + } + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); + + /* If work was actually accomplished... */ + if( rc==SQLITE_OK ){ + if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ + i64 szDb = pWal->hdr.nPage*(i64)szPage; + testcase( IS_BIG_INT(szDb) ); + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); + if( rc==SQLITE_OK ){ + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); + } + } + if( rc==SQLITE_OK ){ + AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; + } + } + + /* Release the reader lock held while backfilling */ + walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); + } + + if( rc==SQLITE_BUSY ){ + /* Reset the return code so as not to report a checkpoint failure + ** just because there are active readers. */ + rc = SQLITE_OK; + } + } + + /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the + ** entire wal file has been copied into the database file, then block + ** until all readers have finished using the wal file. This ensures that + ** the next process to write to the database restarts the wal file. + */ + if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + assert( pWal->writeLock ); + SEH_INJECT_FAULT; + if( pInfo->nBackfillhdr.mxFrame ){ + rc = SQLITE_BUSY; + }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ + /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as + ** SQLITE_CHECKPOINT_RESTART with the addition that it also + ** truncates the log file to zero bytes just prior to a + ** successful return. + ** + ** In theory, it might be safe to do this without updating the + ** wal-index header in shared memory, as all subsequent reader or + ** writer clients should see that the entire log file has been + ** checkpointed and behave accordingly. This seems unsafe though, + ** as it would leave the system in a state where the contents of + ** the wal-index header do not match the contents of the + ** file-system. To avoid this, update the wal-index header to + ** indicate that the log file contains zero valid frames. */ + walRestartHdr(pWal, salt1); + rc = sqlite3OsTruncate(pWal->pWalFd, 0); + } + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + } + } + } + + walcheckpoint_out: + SEH_FREE_ON_ERROR(pIter, 0); + walIteratorFree(pIter); + return rc; +} + +/* +** If the WAL file is currently larger than nMax bytes in size, truncate +** it to exactly nMax bytes. If an error occurs while doing so, ignore it. +*/ +static void walLimitSize(Wal *pWal, i64 nMax){ + i64 sz; + int rx; + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); + if( rx==SQLITE_OK && (sz > nMax ) ){ + rx = sqlite3OsTruncate(pWal->pWalFd, nMax); + } + sqlite3EndBenignMalloc(); + if( rx ){ + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); + } +} + +#ifdef SQLITE_USE_SEH +/* +** This is the "standard" exception handler used in a few places to handle +** an exception thrown by reading from the *-shm mapping after it has become +** invalid in SQLITE_USE_SEH builds. It is used as follows: +** +** SEH_TRY { ... } +** SEH_EXCEPT( rc = walHandleException(pWal); ) +** +** This function does three things: +** +** 1) Determines the locks that should be held, based on the contents of +** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other +** held locks are assumed to be transient locks that would have been +** released had the exception not been thrown and are dropped. +** +** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). +** +** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL +** +** 4) Returns SQLITE_IOERR. +*/ +static int walHandleException(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<lockMask & ~( + (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) + ); + for(ii=0; iipFree); + pWal->pFree = 0; + if( pWal->pWiValue ){ + pWal->apWiData[pWal->iWiPg] = pWal->pWiValue; + pWal->pWiValue = 0; + } + return SQLITE_IOERR_IN_PAGE; +} + +/* +** Assert that the Wal.lockMask mask, which indicates the locks held +** by the connenction, is consistent with the Wal.readLock, Wal.writeLock +** and Wal.ckptLock variables. To be used as: +** +** assert( walAssertLockmask(pWal) ); +*/ +static int walAssertLockmask(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) +#ifdef SQLITE_ENABLE_SNAPSHOT + | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) +#endif + ); + assert( mExpect==pWal->lockMask ); + } + return 1; +} + +/* +** Return and zero the "system error" field set when an +** EXCEPTION_IN_PAGE_ERROR exception is caught. +*/ +SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal *pWal){ + int iRet = 0; + if( pWal ){ + iRet = pWal->iSysErrno; + pWal->iSysErrno = 0; + } + return iRet; +} + +#else +# define walAssertLockmask(x) 1 +#endif /* ifdef SQLITE_USE_SEH */ + +/* +** Close a connection to a log file. +*/ +SQLITE_PRIVATE int sqlite3WalClose( + Wal *pWal, /* Wal to close */ + sqlite3 *db, /* For interrupt flag */ + int sync_flags, /* Flags to pass to OsSync() (or 0) */ + int nBuf, + u8 *zBuf /* Buffer of at least nBuf bytes */ +){ + int rc = SQLITE_OK; + if( pWal ){ + int isDelete = 0; /* True to unlink wal and wal-index files */ + + assert( walAssertLockmask(pWal) ); + + /* If an EXCLUSIVE lock can be obtained on the database file (using the + ** ordinary, rollback-mode locking methods, this guarantees that the + ** connection associated with this log file is the only connection to + ** the database. In this case checkpoint the database and unlink both + ** the wal and wal-index files. + ** + ** The EXCLUSIVE lock is not released before returning. + */ + if( zBuf!=0 + && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE)) + ){ + if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + } + rc = sqlite3WalCheckpoint(pWal, db, + SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 + ); + if( rc==SQLITE_OK ){ + int bPersist = -1; + sqlite3OsFileControlHint( + pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist + ); + if( bPersist!=1 ){ + /* Try to delete the WAL file if the checkpoint completed and + ** fsynced (rc==SQLITE_OK) and if we are not in persistent-wal + ** mode (!bPersist) */ + isDelete = 1; + }else if( pWal->mxWalSize>=0 ){ + /* Try to truncate the WAL file to zero bytes if the checkpoint + ** completed and fsynced (rc==SQLITE_OK) and we are in persistent + ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a + ** non-negative value (pWal->mxWalSize>=0). Note that we truncate + ** to zero bytes as truncating to the journal_size_limit might + ** leave a corrupt WAL file on disk. */ + walLimitSize(pWal, 0); + } + } + } + + walIndexClose(pWal, isDelete); + sqlite3OsClose(pWal->pWalFd); + if( isDelete ){ + sqlite3BeginBenignMalloc(); + sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); + sqlite3EndBenignMalloc(); + } + WALTRACE(("WAL%p: closed\n", pWal)); + sqlite3_free((void *)pWal->apWiData); + sqlite3_free(pWal); + } + return rc; +} + +/* +** Try to read the wal-index header. Return 0 on success and 1 if +** there is a problem. +** +** The wal-index is in shared memory. Another thread or process might +** be writing the header at the same time this procedure is trying to +** read it, which might result in inconsistency. A dirty read is detected +** by verifying that both copies of the header are the same and also by +** a checksum on the header. +** +** If and only if the read is consistent and the header is different from +** pWal->hdr, then pWal->hdr is updated to the content of the new header +** and *pChanged is set to 1. +** +** If the checksum cannot be verified return non-zero. If the header +** is read successfully and the checksum verified, return zero. +*/ +static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){ + u32 aCksum[2]; /* Checksum on the header content */ + WalIndexHdr h1, h2; /* Two copies of the header content */ + WalIndexHdr volatile *aHdr; /* Header in shared memory */ + + /* The first page of the wal-index must be mapped at this point. */ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Read the header. This might happen concurrently with a write to the + ** same area of shared memory on a different CPU in a SMP, + ** meaning it is possible that an inconsistent snapshot is read + ** from the file. If this happens, return non-zero. + ** + ** tag-20200519-1: + ** There are two copies of the header at the beginning of the wal-index. + ** When reading, read [0] first then [1]. Writes are in the reverse order. + ** Memory barriers are used to prevent the compiler or the hardware from + ** reordering the reads and writes. TSAN and similar tools can sometimes + ** give false-positive warnings about these accesses because the tools do not + ** account for the double-read and the memory barrier. The use of mutexes + ** here would be problematic as the memory being accessed is potentially + ** shared among multiple processes and not all mutex implementations work + ** reliably in that environment. + */ + aHdr = walIndexHdr(pWal); + memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */ + walShmBarrier(pWal); + memcpy(&h2, (void *)&aHdr[1], sizeof(h2)); + + if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ + return 1; /* Dirty read */ + } + if( h1.isInit==0 ){ + return 1; /* Malformed header - probably all zeros */ + } + walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum); + if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){ + return 1; /* Checksum does not match */ + } + + if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){ + *pChanged = 1; + memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); + pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); + testcase( pWal->szPage<=32768 ); + testcase( pWal->szPage>=65536 ); + } + + /* The header was successfully read. Return zero. */ + return 0; +} + +/* +** This is the value that walTryBeginRead returns when it needs to +** be retried. +*/ +#define WAL_RETRY (-1) + +/* +** Read the wal-index header from the wal-index and into pWal->hdr. +** If the wal-header appears to be corrupt, try to reconstruct the +** wal-index from the WAL before returning. +** +** Set *pChanged to 1 if the wal-index header value in pWal->hdr is +** changed by this operation. If pWal->hdr is unchanged, set *pChanged +** to 0. +** +** If the wal-index header is successfully read, return SQLITE_OK. +** Otherwise an SQLite error code. +*/ +static int walIndexReadHdr(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int badHdr; /* True if a header read failed */ + volatile u32 *page0; /* Chunk of wal-index containing header */ + + /* Ensure that page 0 of the wal-index (the page that contains the + ** wal-index header) is mapped. Return early if an error occurs here. + */ + assert( pChanged ); + rc = walIndexPage(pWal, 0, &page0); + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */ + if( rc==SQLITE_READONLY_CANTINIT ){ + /* The SQLITE_READONLY_CANTINIT return means that the shared-memory + ** was openable but is not writable, and this thread is unable to + ** confirm that another write-capable connection has the shared-memory + ** open, and hence the content of the shared-memory is unreliable, + ** since the shared-memory might be inconsistent with the WAL file + ** and there is no writer on hand to fix it. */ + assert( page0==0 ); + assert( pWal->writeLock==0 ); + assert( pWal->readOnly & WAL_SHM_RDONLY ); + pWal->bShmUnreliable = 1; + pWal->exclusiveMode = WAL_HEAPMEMORY_MODE; + *pChanged = 1; + }else{ + return rc; /* Any other non-OK return is just an error */ + } + }else{ + /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock + ** is zero, which prevents the SHM from growing */ + testcase( page0!=0 ); + } + assert( page0!=0 || pWal->writeLock==0 ); + + /* If the first page of the wal-index has been mapped, try to read the + ** wal-index header immediately, without holding any lock. This usually + ** works, but may fail if the wal-index header is corrupt or currently + ** being modified by another thread or process. + */ + badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); + + /* If the first attempt failed, it might have been due to a race + ** with a writer. So get a WRITE lock and try again. + */ + if( badHdr ){ + if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){ + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ + walUnlockShared(pWal, WAL_WRITE_LOCK); + rc = SQLITE_READONLY_RECOVERY; + } + }else{ + int bWriteLock = pWal->writeLock; + if( bWriteLock + || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) + ){ + pWal->writeLock = 1; + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ + badHdr = walIndexTryHdr(pWal, pChanged); + if( badHdr ){ + /* If the wal-index header is still malformed even while holding + ** a WRITE lock, it can only mean that the header is corrupted and + ** needs to be reconstructed. So run recovery to do exactly that. + ** Disable blocking locks first. */ + walDisableBlocking(pWal); + rc = walIndexRecover(pWal); + *pChanged = 1; + } + } + if( bWriteLock==0 ){ + pWal->writeLock = 0; + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + } + } + } + } + + /* If the header is read successfully, check the version number to make + ** sure the wal-index was not constructed with some future format that + ** this version of SQLite cannot understand. + */ + if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + } + if( pWal->bShmUnreliable ){ + if( rc!=SQLITE_OK ){ + walIndexClose(pWal, 0); + pWal->bShmUnreliable = 0; + assert( pWal->nWiData>0 && pWal->apWiData[0]==0 ); + /* walIndexRecover() might have returned SHORT_READ if a concurrent + ** writer truncated the WAL out from under it. If that happens, it + ** indicates that a writer has fixed the SHM file for us, so retry */ + if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY; + } + pWal->exclusiveMode = WAL_NORMAL_MODE; + } + + return rc; +} + +/* +** Open a transaction in a connection where the shared-memory is read-only +** and where we cannot verify that there is a separate write-capable connection +** on hand to keep the shared-memory up-to-date with the WAL file. +** +** This can happen, for example, when the shared-memory is implemented by +** memory-mapping a *-shm file, where a prior writer has shut down and +** left the *-shm file on disk, and now the present connection is trying +** to use that database but lacks write permission on the *-shm file. +** Other scenarios are also possible, depending on the VFS implementation. +** +** Precondition: +** +** The *-wal file has been read and an appropriate wal-index has been +** constructed in pWal->apWiData[] using heap memory instead of shared +** memory. +** +** If this function returns SQLITE_OK, then the read transaction has +** been successfully opened. In this case output variable (*pChanged) +** is set to true before returning if the caller should discard the +** contents of the page cache before proceeding. Or, if it returns +** WAL_RETRY, then the heap memory wal-index has been discarded and +** the caller should retry opening the read transaction from the +** beginning (including attempting to map the *-shm file). +** +** If an error occurs, an SQLite error code is returned. +*/ +static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ + i64 szWal; /* Size of wal file on disk in bytes */ + i64 iOffset; /* Current offset when reading wal file */ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + volatile void *pDummy; /* Dummy argument for xShmMap */ + int rc; /* Return code */ + u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */ + + assert( pWal->bShmUnreliable ); + assert( pWal->readOnly & WAL_SHM_RDONLY ); + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Take WAL_READ_LOCK(0). This has the effect of preventing any + ** writers from running a checkpoint, but does not stop them + ** from running recovery. */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_BUSY ) rc = WAL_RETRY; + goto begin_unreliable_shm_out; + } + pWal->readLock = 0; + + /* Check to see if a separate writer has attached to the shared-memory area, + ** thus making the shared-memory "reliable" again. Do this by invoking + ** the xShmMap() routine of the VFS and looking to see if the return + ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT. + ** + ** If the shared-memory is now "reliable" return WAL_RETRY, which will + ** cause the heap-memory WAL-index to be discarded and the actual + ** shared memory to be used in its place. + ** + ** This step is important because, even though this connection is holding + ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might + ** have already checkpointed the WAL file and, while the current + ** is active, wrap the WAL and start overwriting frames that this + ** process wants to use. + ** + ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has + ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY + ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations, + ** even if some external agent does a "chmod" to make the shared-memory + ** writable by us, until sqlite3OsShmUnmap() has been called. + ** This is a requirement on the VFS implementation. + */ + rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); + assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */ + if( rc!=SQLITE_READONLY_CANTINIT ){ + rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); + goto begin_unreliable_shm_out; + } + + /* We reach this point only if the real shared-memory is still unreliable. + ** Assume the in-memory WAL-index substitute is correct and load it + ** into pWal->hdr. + */ + memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + /* Make sure some writer hasn't come in and changed the WAL file out + ** from under us, then disconnected, while we were not looking. + */ + rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); + if( rc!=SQLITE_OK ){ + goto begin_unreliable_shm_out; + } + if( szWalhdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY); + goto begin_unreliable_shm_out; + } + + /* Check the salt keys at the start of the wal file still match. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto begin_unreliable_shm_out; + } + if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){ + /* Some writer has wrapped the WAL file while we were not looking. + ** Return WAL_RETRY which will cause the in-memory WAL-index to be + ** rebuilt. */ + rc = WAL_RETRY; + goto begin_unreliable_shm_out; + } + + /* Allocate a buffer to read frames into */ + assert( (pWal->szPage & (pWal->szPage-1))==0 ); + assert( pWal->szPage>=512 && pWal->szPage<=65536 ); + szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame); + if( aFrame==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto begin_unreliable_shm_out; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + + /* Check to see if a complete transaction has been appended to the + ** wal file since the heap-memory wal-index was created. If so, the + ** heap-memory wal-index is discarded and WAL_RETRY returned to + ** the caller. */ + aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; + aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage); + iOffset+szFrame<=szWal; + iOffset+=szFrame + ){ + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + + /* Read and decode the next log frame. */ + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; + + /* If nTruncate is non-zero, then a complete transaction has been + ** appended to this wal file. Set rc to WAL_RETRY and break out of + ** the loop. */ + if( nTruncate ){ + rc = WAL_RETRY; + break; + } + } + pWal->hdr.aFrameCksum[0] = aSaveCksum[0]; + pWal->hdr.aFrameCksum[1] = aSaveCksum[1]; + + begin_unreliable_shm_out: + sqlite3_free(aFrame); + if( rc!=SQLITE_OK ){ + int i; + for(i=0; inWiData; i++){ + sqlite3_free((void*)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + pWal->bShmUnreliable = 0; + sqlite3WalEndReadTransaction(pWal); + *pChanged = 1; + } + return rc; +} + +/* +** The final argument passed to walTryBeginRead() is of type (int*). The +** caller should invoke walTryBeginRead as follows: +** +** int cnt = 0; +** do { +** rc = walTryBeginRead(..., &cnt); +** }while( rc==WAL_RETRY ); +** +** The final value of "cnt" is of no use to the caller. It is used by +** the implementation of walTryBeginRead() as follows: +** +** + Each time walTryBeginRead() is called, it is incremented. Once +** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead() +** has many times been invoked and failed with WAL_RETRY - walTryBeginRead() +** returns SQLITE_PROTOCOL. +** +** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed +** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS +** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case +** the next invocation of walTryBeginRead() may omit an expected call to +** sqlite3OsSleep(). There has already been a delay when the previous call +** waited on a lock. +*/ +#define WAL_RETRY_PROTOCOL_LIMIT 100 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +# define WAL_RETRY_BLOCKED_MASK 0x10000000 +#else +# define WAL_RETRY_BLOCKED_MASK 0 +#endif + +/* +** Attempt to start a read transaction. This might fail due to a race or +** other transient condition. When that happens, it returns WAL_RETRY to +** indicate to the caller that it is safe to retry immediately. +** +** On success return SQLITE_OK. On a permanent failure (such an +** I/O error or an SQLITE_BUSY because another process is running +** recovery) return a positive error code. +** +** The useWal parameter is true to force the use of the WAL and disable +** the case where the WAL is bypassed because it has been completely +** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() +** to make a copy of the wal-index header into pWal->hdr. If the +** wal-index header has changed, *pChanged is set to 1 (as an indication +** to the caller that the local page cache is obsolete and needs to be +** flushed.) When useWal==1, the wal-index header is assumed to already +** be loaded and the pChanged parameter is unused. +** +** The caller must set the cnt parameter to the number of prior calls to +** this routine during the current read attempt that returned WAL_RETRY. +** This routine will start taking more aggressive measures to clear the +** race conditions after multiple WAL_RETRY returns, and after an excessive +** number of errors will ultimately return SQLITE_PROTOCOL. The +** SQLITE_PROTOCOL return indicates that some other process has gone rogue +** and is not honoring the locking protocol. There is a vanishingly small +** chance that SQLITE_PROTOCOL could be returned because of a run of really +** bad luck when there is lots of contention for the wal-index, but that +** possibility is so small that it can be safely neglected, we believe. +** +** On success, this routine obtains a read lock on +** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is +** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1) +** that means the Wal does not hold any read lock. The reader must not +** access any database page that is modified by a WAL frame up to and +** including frame number aReadMark[pWal->readLock]. The reader will +** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0 +** Or if pWal->readLock==0, then the reader will ignore the WAL +** completely and get all content directly from the database file. +** If the useWal parameter is 1 then the WAL will never be ignored and +** this routine will always set pWal->readLock>0 on success. +** When the read transaction is completed, the caller must release the +** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1. +** +** This routine uses the nBackfill and aReadMark[] fields of the header +** to select a particular WAL_READ_LOCK() that strives to let the +** checkpoint process do as much work as possible. This routine might +** update values of the aReadMark[] array in the header, but if it does +** so it takes care to hold an exclusive lock on the corresponding +** WAL_READ_LOCK() while changing values. +*/ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ + volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + int rc = SQLITE_OK; /* Return code */ + u32 mxFrame; /* Wal frame to lock to */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int nBlockTmout = 0; +#endif + + assert( pWal->readLock<0 ); /* Not currently locked */ + + /* useWal may only be set for read/write connections */ + assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 ); + + /* Take steps to avoid spinning forever if there is a protocol error. + ** + ** Circumstances that cause a RETRY should only last for the briefest + ** instances of time. No I/O or other system calls are done while the + ** locks are held, so the locks should not be held for very long. But + ** if we are unlucky, another process that is holding a lock might get + ** paged out or take a page-fault that is time-consuming to resolve, + ** during the few nanoseconds that it is holding the lock. In that case, + ** it might take longer than normal for the lock to free. + ** + ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few + ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this + ** is more of a scheduler yield than an actual delay. But on the 10th + ** an subsequent retries, the delays start becoming longer and longer, + ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. + ** The total delay time before giving up is less than 10 seconds. + */ + (*pCnt)++; + if( *pCnt>5 ){ + int nDelay = 1; /* Pause time in microseconds */ + int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK); + if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){ + VVA_ONLY( pWal->lockError = 1; ) + return SQLITE_PROTOCOL; + } + if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor + ** to block for locks for approximately nDelay us. This affects three + ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if + ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the + ** first attempted read fails, and (c) the shared lock taken on the + ** read-mark. + ** + ** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error, + ** then sleep for the minimum of 1us. The previous call already provided + ** an extra delay while it was blocking on the lock. + */ + nBlockTmout = (nDelay+998) / 1000; + if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){ + if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1; + } +#endif + sqlite3OsSleep(pWal->pVfs, nDelay); + *pCnt &= ~WAL_RETRY_BLOCKED_MASK; + } + + if( !useWal ){ + assert( rc==SQLITE_OK ); + if( pWal->bShmUnreliable==0 ){ + rc = walIndexReadHdr(pWal, pChanged); + } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + walDisableBlocking(pWal); + if( rc==SQLITE_BUSY_TIMEOUT ){ + rc = SQLITE_BUSY; + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#endif + if( rc==SQLITE_BUSY ){ + /* If there is not a recovery running in another thread or process + ** then convert BUSY errors to WAL_RETRY. If recovery is known to + ** be running, convert BUSY to BUSY_RECOVERY. There is a race here + ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY + ** would be technically correct. But the race is benign since with + ** WAL_RETRY this routine will be called again and will probably be + ** right on the second iteration. + */ + if( pWal->apWiData[0]==0 ){ + /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. + ** We assume this is a transient condition, so return WAL_RETRY. The + ** xShmMap() implementation used by the default unix and win32 VFS + ** modules may return SQLITE_BUSY due to a race condition in the + ** code that determines whether or not the shared-memory region + ** must be zeroed before the requested page is returned. + */ + rc = WAL_RETRY; + }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){ + walUnlockShared(pWal, WAL_RECOVER_LOCK); + rc = WAL_RETRY; + }else if( rc==SQLITE_BUSY ){ + rc = SQLITE_BUSY_RECOVERY; + } + } + if( rc!=SQLITE_OK ){ + return rc; + } + else if( pWal->bShmUnreliable ){ + return walBeginShmUnreliable(pWal, pChanged); + } + } + + assert( pWal->nWiData>0 ); + assert( pWal->apWiData[0]!=0 ); + pInfo = walCkptInfo(pWal); + SEH_INJECT_FAULT; + if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame +#ifdef SQLITE_ENABLE_SNAPSHOT + && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) +#endif + ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + mxFrame = pWal->hdr.mxFrame; +#ifdef SQLITE_ENABLE_SNAPSHOT + if( pWal->pSnapshot && pWal->pSnapshot->mxFramepSnapshot->mxFrame; + } +#endif + for(i=1; iaReadMark+i); SEH_INJECT_FAULT; + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; + mxI = i; + } + } + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMarkaReadMark+i,mxFrame); + mxReadMark = mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; + } + + (void)walEnableBlockingMs(pWal, nBlockTmout); + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); + if( rc ){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#else + assert( rc!=SQLITE_BUSY_TIMEOUT ); +#endif + assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** Before checking that the live wal-index header has not changed + ** since it was read, set Wal.minFrame to the first frame in the wal + ** file that has not yet been checkpointed. This client will not need + ** to read any frames earlier than minFrame from the wal file - they + ** can be safely read directly from the database file. + ** + ** Because a ShmBarrier() call is made between taking the copy of + ** nBackfill and checking that the wal-header in shared-memory still + ** matches the one cached in pWal->hdr, it is guaranteed that the + ** checkpointer that set nBackfill was not working with a wal-index + ** header newer than that cached in pWal->hdr. If it were, that could + ** cause a problem. The checkpointer could omit to checkpoint + ** a version of page X that lies before pWal->minFrame (call that version + ** A) on the basis that there is a newer version (version B) of the same + ** page later in the wal file. But if version B happens to like past + ** frame pWal->hdr.mxFrame - then the client would incorrectly assume + ** that it can read version A from the database file. However, since + ** we can guarantee that the checkpointer that set nBackfill could not + ** see any pages past pWal->hdr.mxFrame, this problem does not come up. + */ + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + walShmBarrier(pWal); + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } + return rc; +} + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** This function does the work of sqlite3WalSnapshotRecover(). +*/ +static int walSnapshotRecover( + Wal *pWal, /* WAL handle */ + void *pBuf1, /* Temp buffer pWal->szPage bytes in size */ + void *pBuf2 /* Temp buffer pWal->szPage bytes in size */ +){ + int szPage = (int)pWal->szPage; + int rc; + i64 szDb; /* Size of db file in bytes */ + + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); + if( rc==SQLITE_OK ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ + WalHashLoc sLoc; /* Hash table location */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ + + rc = walHashGet(pWal, walFramePage(i), &sLoc); + if( rc!=SQLITE_OK ) break; + assert( i - sLoc.iZero - 1 >=0 ); + pgno = sLoc.aPgno[i-sLoc.iZero-1]; + iDbOff = (i64)(pgno-1) * szPage; + + if( iDbOff+szPage<=szDb ){ + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); + + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + } + + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } + } + + pInfo->nBackfillAttempted = i-1; + } + } + + return rc; +} + +/* +** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted +** variable so that older snapshots can be accessed. To do this, loop +** through all wal frames from nBackfillAttempted to (nBackfill+1), +** comparing their content to the corresponding page with the database +** file, if any. Set nBackfillAttempted to the frame number of the +** first frame for which the wal file content matches the db file. +** +** This is only really safe if the file-system is such that any page +** writes made by earlier checkpointers were atomic operations, which +** is not always true. It is also possible that nBackfillAttempted +** may be left set to a value larger than expected, if a wal frame +** contains content that duplicate of an earlier version of the same +** page. +** +** SQLITE_OK is returned if successful, or an SQLite error code if an +** error occurs. It is not an error if nBackfillAttempted cannot be +** decreased at all. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ + int rc; + + assert( pWal->readLock>=0 ); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + if( rc==SQLITE_OK ){ + void *pBuf1 = sqlite3_malloc(pWal->szPage); + void *pBuf2 = sqlite3_malloc(pWal->szPage); + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + pWal->ckptLock = 1; + SEH_TRY { + rc = walSnapshotRecover(pWal, pBuf1, pBuf2); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + pWal->ckptLock = 0; + } + + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + } + + return rc; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +/* +** This function does the work of sqlite3WalBeginReadTransaction() (see +** below). That function simply calls this one inside an SEH_TRY{...} block. +*/ +static int walBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int cnt = 0; /* Number of TryBeginRead attempts */ +#ifdef SQLITE_ENABLE_SNAPSHOT + int ckptLock = 0; + int bChanged = 0; + WalIndexHdr *pSnapshot = pWal->pSnapshot; +#endif + + assert( pWal->ckptLock==0 ); + assert( pWal->nSehTry>0 ); + +#ifdef SQLITE_ENABLE_SNAPSHOT + if( pSnapshot ){ + if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ + bChanged = 1; + } + + /* It is possible that there is a checkpointer thread running + ** concurrent with this code. If this is the case, it may be that the + ** checkpointer has already determined that it will checkpoint + ** snapshot X, where X is later in the wal file than pSnapshot, but + ** has not yet set the pInfo->nBackfillAttempted variable to indicate + ** its intent. To avoid the race condition this leads to, ensure that + ** there is no checkpointer process by taking a shared CKPT lock + ** before checking pInfo->nBackfillAttempted. */ + (void)walEnableBlocking(pWal); + rc = walLockShared(pWal, WAL_CKPT_LOCK); + walDisableBlocking(pWal); + + if( rc!=SQLITE_OK ){ + return rc; + } + ckptLock = 1; + } +#endif + + do{ + rc = walTryBeginRead(pWal, pChanged, 0, &cnt); + }while( rc==WAL_RETRY ); + testcase( (rc&0xff)==SQLITE_BUSY ); + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + +#ifdef SQLITE_ENABLE_SNAPSHOT + if( rc==SQLITE_OK ){ + if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ + /* At this point the client has a lock on an aReadMark[] slot holding + ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr + ** is populated with the wal-index header corresponding to the head + ** of the wal file. Verify that pSnapshot is still valid before + ** continuing. Reasons why pSnapshot might no longer be valid: + ** + ** (1) The WAL file has been reset since the snapshot was taken. + ** In this case, the salt will have changed. + ** + ** (2) A checkpoint as been attempted that wrote frames past + ** pSnapshot->mxFrame into the database file. Note that the + ** checkpoint need not have completed for this to cause problems. + */ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + + assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 ); + assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame ); + + /* Check that the wal file has not been wrapped. Assuming that it has + ** not, also check that no checkpointer has attempted to checkpoint any + ** frames beyond pSnapshot->mxFrame. If either of these conditions are + ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr + ** with *pSnapshot and set *pChanged as appropriate for opening the + ** snapshot. */ + if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + && pSnapshot->mxFrame>=pInfo->nBackfillAttempted + ){ + assert( pWal->readLock>0 ); + memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); + *pChanged = bChanged; + }else{ + rc = SQLITE_ERROR_SNAPSHOT; + } + + /* A client using a non-current snapshot may not ignore any frames + ** from the start of the wal file. This is because, for a system + ** where (minFrame < iSnapshot < maxFrame), a checkpointer may + ** have omitted to checkpoint a frame earlier than minFrame in + ** the file because there exists a frame after iSnapshot that + ** is the same database page. */ + pWal->minFrame = 1; + + if( rc!=SQLITE_OK ){ + sqlite3WalEndReadTransaction(pWal); + } + } + } + + /* Release the shared CKPT lock obtained above. */ + if( ckptLock ){ + assert( pSnapshot ); + walUnlockShared(pWal, WAL_CKPT_LOCK); + } +#endif + return rc; +} + +/* +** Begin a read transaction on the database. +** +** This routine used to be called sqlite3OpenSnapshot() and with good reason: +** it takes a snapshot of the state of the WAL and wal-index for the current +** instant in time. The current thread will continue to use this snapshot. +** Other threads might append new content to the WAL and wal-index but +** that extra content is ignored by the current thread. +** +** If the database contents have changes since the previous read +** transaction, then *pChanged is set to 1 before returning. The +** Pager layer will use this to know that its cache is stale and +** needs to be flushed. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; + SEH_TRY { + rc = walBeginReadTransaction(pWal, pChanged); + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* +** Finish with a read transaction. All this does is release the +** read-lock. +*/ +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ + sqlite3WalEndWriteTransaction(pWal); + if( pWal->readLock>=0 ){ + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->readLock = -1; + } +} + +/* +** Search the wal file for page pgno. If found, set *piRead to the frame that +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead +** to zero. +** +** Return SQLITE_OK if successful, or an error code if an error occurs. If an +** error does occur, the final value of *piRead is undefined. +*/ +static int walFindFrame( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + u32 *piRead /* OUT: Frame number (or zero) */ +){ + u32 iRead = 0; /* If !=0, WAL frame to return data from */ + u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ + int iHash; /* Used to loop through N hash tables */ + int iMinHash; + + /* This routine is only be called from within a read transaction. */ + assert( pWal->readLock>=0 || pWal->lockError ); + + /* If the "last page" field of the wal-index header snapshot is 0, then + ** no data will be read from the wal under any circumstances. Return early + ** in this case as an optimization. Likewise, if pWal->readLock==0, + ** then the WAL is ignored by the reader so return early, as if the + ** WAL were empty. + */ + if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){ + *piRead = 0; + return SQLITE_OK; + } + + /* Search the hash table or tables for an entry matching page number + ** pgno. Each iteration of the following for() loop searches one + ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). + ** + ** This code might run concurrently to the code in walIndexAppend() + ** that adds entries to the wal-index (and possibly to this hash + ** table). This means the value just read from the hash + ** slot (aHash[iKey]) may have been added before or after the + ** current read transaction was opened. Values added after the + ** read transaction was opened may have been written incorrectly - + ** i.e. these slots may contain garbage data. However, we assume + ** that any slots written before the current read transaction was + ** opened remain unmodified. + ** + ** For the reasons above, the if(...) condition featured in the inner + ** loop of the following block is more stringent that would be required + ** if we had exclusive access to the hash-table: + ** + ** (aPgno[iFrame]==pgno): + ** This condition filters out normal hash-table collisions. + ** + ** (iFrame<=iLast): + ** This condition filters out entries that were added to the hash + ** table after the current read-transaction had started. + */ + iMinHash = walFramePage(pWal->minFrame); + for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){ + WalHashLoc sLoc; /* Hash table location */ + int iKey; /* Hash slot index */ + int nCollide; /* Number of hash collisions remaining */ + int rc; /* Error code */ + u32 iH; + + rc = walHashGet(pWal, iHash, &sLoc); + if( rc!=SQLITE_OK ){ + return rc; + } + nCollide = HASHTABLE_NSLOT; + iKey = walHash(pgno); + SEH_INJECT_FAULT; + while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ + u32 iFrame = iH + sLoc.iZero; + if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ + assert( iFrame>iRead || CORRUPT_DB ); + iRead = iFrame; + } + if( (nCollide--)==0 ){ + *piRead = 0; + return SQLITE_CORRUPT_BKPT; + } + iKey = walNextHash(iKey); + } + if( iRead ) break; + } + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* If expensive assert() statements are available, do a linear search + ** of the wal-index file content. Make sure the results agree with the + ** result obtained using the hash indexes above. */ + { + u32 iRead2 = 0; + u32 iTest; + assert( pWal->bShmUnreliable || pWal->minFrame>0 ); + for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){ + if( walFramePgno(pWal, iTest)==pgno ){ + iRead2 = iTest; + break; + } + } + assert( iRead==iRead2 ); + } +#endif + + *piRead = iRead; + return SQLITE_OK; +} + +/* +** Search the wal file for page pgno. If found, set *piRead to the frame that +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead +** to zero. +** +** Return SQLITE_OK if successful, or an error code if an error occurs. If an +** error does occur, the final value of *piRead is undefined. +** +** The difference between this function and walFindFrame() is that this +** function wraps walFindFrame() in an SEH_TRY{...} block. +*/ +SQLITE_PRIVATE int sqlite3WalFindFrame( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + u32 *piRead /* OUT: Frame number (or zero) */ +){ + int rc; + SEH_TRY { + rc = walFindFrame(pWal, pgno, piRead); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + return rc; +} + +/* +** Read the contents of frame iRead from the wal file into buffer pOut +** (which is nOut bytes in size). Return SQLITE_OK if successful, or an +** error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3WalReadFrame( + Wal *pWal, /* WAL handle */ + u32 iRead, /* Frame to read */ + int nOut, /* Size of buffer pOut in bytes */ + u8 *pOut /* Buffer to write page data to */ +){ + int sz; + i64 iOffset; + sz = pWal->hdr.szPage; + sz = (sz&0xfe00) + ((sz&0x0001)<<16); + testcase( sz<=32768 ); + testcase( sz>=65536 ); + iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); +} + +/* +** Return the size of the database in pages (or zero, if unknown). +*/ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ + if( pWal && ALWAYS(pWal->readLock>=0) ){ + return pWal->hdr.nPage; + } + return 0; +} + + +/* +** This function starts a write transaction on the WAL. +** +** A read transaction must have already been started by a prior call +** to sqlite3WalBeginReadTransaction(). +** +** If another thread or process has written into the database since +** the read transaction was started, then it is not possible for this +** thread to write as doing so would cause a fork. So this routine +** returns SQLITE_BUSY in that case and no write transaction is started. +** +** There can only be a single writer active at a time. +*/ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ + int rc; + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* If the write-lock is already held, then it was obtained before the + ** read-transaction was even opened, making this call a no-op. + ** Return early. */ + if( pWal->writeLock ){ + assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) ); + return SQLITE_OK; + } +#endif + + /* Cannot start a write transaction without first holding a read + ** transaction. */ + assert( pWal->readLock>=0 ); + assert( pWal->writeLock==0 && pWal->iReCksum==0 ); + + if( pWal->readOnly ){ + return SQLITE_READONLY; + } + + /* Only one writer allowed at a time. Get the write lock. Return + ** SQLITE_BUSY if unable. + */ + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + if( rc ){ + return rc; + } + pWal->writeLock = 1; + + /* If another connection has written to the database file since the + ** time the read transaction on this connection was started, then + ** the write is disallowed. + */ + SEH_TRY { + if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ + rc = SQLITE_BUSY_SNAPSHOT; + } + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + + if( rc!=SQLITE_OK ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + } + return rc; +} + +/* +** End a write transaction. The commit has already been done. This +** routine merely releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ + if( pWal->writeLock ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + pWal->iReCksum = 0; + pWal->truncateOnCommit = 0; + } + return SQLITE_OK; +} + +/* +** If any data has been written (but not committed) to the log file, this +** function moves the write-pointer back to the start of the transaction. +** +** Additionally, the callback function is invoked for each frame written +** to the WAL since the start of the transaction. If the callback returns +** other than SQLITE_OK, it is not invoked again and the error code is +** returned to the caller. +** +** Otherwise, if the callback function does not return an error, this +** function returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ + int rc = SQLITE_OK; + if( ALWAYS(pWal->writeLock) ){ + Pgno iMax = pWal->hdr.mxFrame; + Pgno iFrame; + + SEH_TRY { + /* Restore the clients cache of the wal-index header to the state it + ** was in before the client began writing to the database. + */ + memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + iFrame++ + ){ + /* This call cannot fail. Unless the page for which the page number + ** is passed as the second argument is (a) in the cache and + ** (b) has an outstanding reference, then xUndo is either a no-op + ** (if (a) is false) or simply expels the page from the cache (if (b) + ** is false). + ** + ** If the upper layer is doing a rollback, it is guaranteed that there + ** are no outstanding references to any page other than page 1. And + ** page 1 is never written to the log until the transaction is + ** committed. As a result, the call to xUndo may not fail. + */ + assert( walFramePgno(pWal, iFrame)!=1 ); + rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); + } + if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + } + return rc; +} + +/* +** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 +** values. This function populates the array with values required to +** "rollback" the write position of the WAL handle back to the current +** point in the event of a savepoint rollback (via WalSavepointUndo()). +*/ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ + assert( pWal->writeLock ); + aWalData[0] = pWal->hdr.mxFrame; + aWalData[1] = pWal->hdr.aFrameCksum[0]; + aWalData[2] = pWal->hdr.aFrameCksum[1]; + aWalData[3] = pWal->nCkpt; +} + +/* +** Move the write position of the WAL back to the point identified by +** the values in the aWalData[] array. aWalData must point to an array +** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated +** by a call to WalSavepoint(). +*/ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ + int rc = SQLITE_OK; + + assert( pWal->writeLock ); + assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame ); + + if( aWalData[3]!=pWal->nCkpt ){ + /* This savepoint was opened immediately after the write-transaction + ** was started. Right after that, the writer decided to wrap around + ** to the start of the log. Update the savepoint values to match. + */ + aWalData[0] = 0; + aWalData[3] = pWal->nCkpt; + } + + if( aWalData[0]hdr.mxFrame ){ + pWal->hdr.mxFrame = aWalData[0]; + pWal->hdr.aFrameCksum[0] = aWalData[1]; + pWal->hdr.aFrameCksum[1] = aWalData[2]; + SEH_TRY { + walCleanupHash(pWal); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + } + + return rc; +} + +/* +** This function is called just before writing a set of frames to the log +** file (see sqlite3WalFrames()). It checks to see if, instead of appending +** to the current log file, it is possible to overwrite the start of the +** existing log file with the new frames (i.e. "reset" the log). If so, +** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left +** unchanged. +** +** SQLITE_OK is returned if no error is encountered (regardless of whether +** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned +** if an error occurs. +*/ +static int walRestartLog(Wal *pWal){ + int rc = SQLITE_OK; + int cnt; + + if( pWal->readLock==0 ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + if( pInfo->nBackfill>0 ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + /* If all readers are using WAL_READ_LOCK(0) (in other words if no + ** readers are currently using the WAL), then the transactions + ** frames will overwrite the start of the existing log. Update the + ** wal-index header to reflect this. + ** + ** In theory it would be Ok to update the cache of the header only + ** at this point. But updating the actual wal-index header is also + ** safe and means there is no special case for sqlite3WalUndo() + ** to handle if this transaction is rolled back. */ + walRestartHdr(pWal, salt1); + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + walUnlockShared(pWal, WAL_READ_LOCK(0)); + pWal->readLock = -1; + cnt = 0; + do{ + int notUsed; + rc = walTryBeginRead(pWal, ¬Used, 1, &cnt); + }while( rc==WAL_RETRY ); + assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + } + return rc; +} + +/* +** Information about the current state of the WAL file and where +** the next fsync should occur - passed from sqlite3WalFrames() into +** walWriteToLog(). +*/ +typedef struct WalWriter { + Wal *pWal; /* The complete WAL information */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ + int syncFlags; /* Flags for the fsync */ + int szPage; /* Size of one page */ +} WalWriter; + +/* +** Write iAmt bytes of content into the WAL file beginning at iOffset. +** Do a sync when crossing the p->iSyncPoint boundary. +** +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, +** first write the part before iSyncPoint, then sync, then write the +** rest. +*/ +static int walWriteToLog( + WalWriter *p, /* WAL to write to */ + void *pContent, /* Content to be written */ + int iAmt, /* Number of bytes to write */ + sqlite3_int64 iOffset /* Start writing at this offset */ +){ + int rc; + if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ + int iFirstAmt = (int)(p->iSyncPoint - iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); + if( rc ) return rc; + iOffset += iFirstAmt; + iAmt -= iFirstAmt; + pContent = (void*)(iFirstAmt + (char*)pContent); + assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); + rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); + if( iAmt==0 || rc ) return rc; + } + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + return rc; +} + +/* +** Write out a single frame of the WAL +*/ +static int walWriteOneFrame( + WalWriter *p, /* Where to write the frame */ + PgHdr *pPage, /* The page of the frame to be written */ + int nTruncate, /* The commit flag. Usually 0. >0 for commit */ + sqlite3_int64 iOffset /* Byte offset at which to write */ +){ + int rc; /* Result code from subfunctions */ + void *pData; /* Data actually written */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ + pData = pPage->pData; + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); + if( rc ) return rc; + /* Write the page data */ + rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); + return rc; +} + +/* +** This function is called as part of committing a transaction within which +** one or more frames have been overwritten. It updates the checksums for +** all frames written to the wal file by the current transaction starting +** with the earliest to have been overwritten. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int walRewriteChecksums(Wal *pWal, u32 iLast){ + const int szPage = pWal->szPage;/* Database page size */ + int rc = SQLITE_OK; /* Return code */ + u8 *aBuf; /* Buffer to load data from wal file into */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */ + u32 iRead; /* Next frame to read from wal file */ + i64 iCksumOff; + + aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE); + if( aBuf==0 ) return SQLITE_NOMEM_BKPT; + + /* Find the checksum values to use as input for the recalculating the + ** first checksum. If the first frame is frame 1 (implying that the current + ** transaction restarted the wal file), these values must be read from the + ** wal-file header. Otherwise, read them from the frame header of the + ** previous frame. */ + assert( pWal->iReCksum>0 ); + if( pWal->iReCksum==1 ){ + iCksumOff = 24; + }else{ + iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16; + } + rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff); + pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf); + pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]); + + iRead = pWal->iReCksum; + pWal->iReCksum = 0; + for(; rc==SQLITE_OK && iRead<=iLast; iRead++){ + i64 iOff = walFrameOffset(iRead, szPage); + rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff); + if( rc==SQLITE_OK ){ + u32 iPgno, nDbSize; + iPgno = sqlite3Get4byte(aBuf); + nDbSize = sqlite3Get4byte(&aBuf[4]); + + walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame); + rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff); + } + } + + sqlite3_free(aBuf); + return rc; +} + +/* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +*/ +static int walFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; /* Used to catch return codes */ + u32 iFrame; /* Next frame address */ + PgHdr *p; /* Iterator to run through pList with. */ + PgHdr *pLast = 0; /* Last frame in list */ + int nExtra = 0; /* Number of extra copies of last page */ + int szFrame; /* The size of a single frame */ + i64 iOffset; /* Next byte to write in WAL file */ + WalWriter w; /* The writer */ + u32 iFirst = 0; /* First frame that may be overwritten */ + WalIndexHdr *pLive; /* Pointer to shared header */ + + assert( pList ); + assert( pWal->writeLock ); + + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) + { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} + WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", + pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill")); + } +#endif + + pLive = (WalIndexHdr*)walIndexHdr(pWal); + if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){ + iFirst = pLive->mxFrame+1; + } + + /* See if it is possible to write these frames into the start of the + ** log file, instead of appending to it at pWal->hdr.mxFrame. + */ + if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ + return rc; + } + + /* If this is the first frame written into the log, write the WAL + ** header to the start of the WAL file. See comments at the top of + ** this source file for a description of the WAL header format. + */ + iFrame = pWal->hdr.mxFrame; + if( iFrame==0 ){ + u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ + u32 aCksum[2]; /* Checksum for wal-header */ + + sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); + sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); + sqlite3Put4byte(&aWalHdr[8], szPage); + sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); + if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); + memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); + walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); + sqlite3Put4byte(&aWalHdr[24], aCksum[0]); + sqlite3Put4byte(&aWalHdr[28], aCksum[1]); + + pWal->szPage = szPage; + pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; + pWal->hdr.aFrameCksum[0] = aCksum[0]; + pWal->hdr.aFrameCksum[1] = aCksum[1]; + pWal->truncateOnCommit = 1; + + rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); + WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless + ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise + ** an out-of-order write following a WAL restart could result in + ** database corruption. See the ticket: + ** + ** https://sqlite.org/src/info/ff5be73dee + */ + if( pWal->syncHeader ){ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + if( rc ) return rc; + } + } + if( (int)pWal->szPage!=szPage ){ + return SQLITE_CORRUPT_BKPT; /* TH3 test case: cov1/corrupt155.test */ + } + + /* Setup information needed to write frames into the WAL */ + w.pWal = pWal; + w.pFd = pWal->pWalFd; + w.iSyncPoint = 0; + w.syncFlags = sync_flags; + w.szPage = szPage; + iOffset = walFrameOffset(iFrame+1, szPage); + szFrame = szPage + WAL_FRAME_HDRSIZE; + + /* Write all frames into the log file exactly once */ + for(p=pList; p; p=p->pDirty){ + int nDbSize; /* 0 normally. Positive == commit flag */ + + /* Check if this page has already been written into the wal file by + ** the current transaction. If so, overwrite the existing frame and + ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that + ** checksums must be recomputed when the transaction is committed. */ + if( iFirst && (p->pDirty || isCommit==0) ){ + u32 iWrite = 0; + VVA_ONLY(rc =) walFindFrame(pWal, p->pgno, &iWrite); + assert( rc==SQLITE_OK || iWrite==0 ); + if( iWrite>=iFirst ){ + i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; + void *pData; + if( pWal->iReCksum==0 || iWriteiReCksum ){ + pWal->iReCksum = iWrite; + } + pData = p->pData; + rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff); + if( rc ) return rc; + p->flags &= ~PGHDR_WAL_APPEND; + continue; + } + } + + iFrame++; + assert( iOffset==walFrameOffset(iFrame, szPage) ); + nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; + rc = walWriteOneFrame(&w, p, nDbSize, iOffset); + if( rc ) return rc; + pLast = p; + iOffset += szFrame; + p->flags |= PGHDR_WAL_APPEND; + } + + /* Recalculate checksums within the wal file if required. */ + if( isCommit && pWal->iReCksum ){ + rc = walRewriteChecksums(pWal, iFrame); + if( rc ) return rc; + } + + /* If this is the end of a transaction, then we might need to pad + ** the transaction and/or sync the WAL file. + ** + ** Padding and syncing only occur if this set of frames complete a + ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL + ** or synchronous==OFF, then no padding or syncing are needed. + ** + ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not + ** needed and only the sync is done. If padding is needed, then the + ** final frame is repeated (with its commit mark) until the next sector + ** boundary is crossed. Only the part of the WAL prior to the last + ** sector boundary is synced; the part of the last frame that extends + ** past the sector boundary is written after the sync. + */ + if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ + int bSync = 1; + if( pWal->padToSectorBoundary ){ + int sectorSize = sqlite3SectorSize(pWal->pWalFd); + w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + bSync = (w.iSyncPoint==iOffset); + testcase( bSync ); + while( iOffsettruncateOnCommit && pWal->mxWalSize>=0 ){ + i64 sz = pWal->mxWalSize; + if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nExtra+1, szPage); + } + walLimitSize(pWal, sz); + pWal->truncateOnCommit = 0; + } + + /* Append data to the wal-index. It is not necessary to lock the + ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index + ** guarantees that there are no other writers, and no data that may + ** be in use by existing readers is being overwritten. + */ + iFrame = pWal->hdr.mxFrame; + for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ + if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; + iFrame++; + rc = walIndexAppend(pWal, iFrame, p->pgno); + } + assert( pLast!=0 || nExtra==0 ); + while( rc==SQLITE_OK && nExtra>0 ){ + iFrame++; + nExtra--; + rc = walIndexAppend(pWal, iFrame, pLast->pgno); + } + + if( rc==SQLITE_OK ){ + /* Update the private copy of the header. */ + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pWal->hdr.mxFrame = iFrame; + if( isCommit ){ + pWal->hdr.iChange++; + pWal->hdr.nPage = nTruncate; + } + /* If this is a commit, update the wal-index header too. */ + if( isCommit ){ + walIndexWriteHdr(pWal); + pWal->iCallback = iFrame; + } + } + + WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); + return rc; +} + +/* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +** +** The difference between this function and walFrames() is that this +** function wraps walFrames() in an SEH_TRY{...} block. +*/ +SQLITE_PRIVATE int sqlite3WalFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; + SEH_TRY { + rc = walFrames(pWal, szPage, pList, nTruncate, isCommit, sync_flags); + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* +** This routine is called to implement sqlite3_wal_checkpoint() and +** related interfaces. +** +** Obtain a CHECKPOINT lock and then backfill as much information as +** we can from WAL into the database. +** +** If parameter xBusy is not NULL, it is a pointer to a busy-handler +** callback. In this case this function runs a blocking checkpoint. +*/ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Wal connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of temporary buffer */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +){ + int rc; /* Return code */ + int isChanged = 0; /* True if a new wal-index header is loaded */ + int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ + int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */ + + assert( pWal->ckptLock==0 ); + assert( pWal->writeLock==0 ); + + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); + + if( pWal->readOnly ) return SQLITE_READONLY; + WALTRACE(("WAL%p: checkpoint begins\n", pWal)); + + /* Enable blocking locks, if possible. */ + sqlite3WalDb(pWal, db); + if( xBusy2 ) (void)walEnableBlocking(pWal); + + /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive + ** "checkpoint" lock on the database file. + ** EVIDENCE-OF: R-10421-19736 If any other process is running a + ** checkpoint operation at the same time, the lock cannot be obtained and + ** SQLITE_BUSY is returned. + ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured, + ** it will not be invoked in this case. + */ + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + testcase( rc==SQLITE_BUSY ); + testcase( rc!=SQLITE_OK && xBusy2!=0 ); + if( rc==SQLITE_OK ){ + pWal->ckptLock = 1; + + /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and + ** TRUNCATE modes also obtain the exclusive "writer" lock on the database + ** file. + ** + ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained + ** immediately, and a busy-handler is configured, it is invoked and the + ** writer lock retried until either the busy-handler returns 0 or the + ** lock is successfully obtained. + */ + if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + }else if( rc==SQLITE_BUSY ){ + eMode2 = SQLITE_CHECKPOINT_PASSIVE; + xBusy2 = 0; + rc = SQLITE_OK; + } + } + } + + + /* Read the wal-index header. */ + SEH_TRY { + if( rc==SQLITE_OK ){ + /* For a passive checkpoint, do not re-enable blocking locks after + ** reading the wal-index header. A passive checkpoint should not block + ** or invoke the busy handler. The only lock such a checkpoint may + ** attempt to obtain is a lock on a read-slot, and it should give up + ** immediately and do a partial checkpoint if it cannot obtain it. */ + walDisableBlocking(pWal); + rc = walIndexReadHdr(pWal, &isChanged); + if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal); + if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); + } + } + + /* Copy data from the log to the database file. */ + if( rc==SQLITE_OK ){ + if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf); + } + + /* If no error occurred, set the output variables. */ + if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ + if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + SEH_INJECT_FAULT; + if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); + } + } + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + + if( isChanged ){ + /* If a new wal-index header was loaded before the checkpoint was + ** performed, then the pager-cache associated with pWal is now + ** out of date. So zero the cached wal-index header to ensure that + ** next time the pager opens a snapshot on this database it knows that + ** the cache needs to be reset. + */ + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + } + + walDisableBlocking(pWal); + sqlite3WalDb(pWal, 0); + + /* Release the locks. */ + sqlite3WalEndWriteTransaction(pWal); + if( pWal->ckptLock ){ + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + pWal->ckptLock = 0; + } + WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; +#endif + return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc); +} + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ + u32 ret = 0; + if( pWal ){ + ret = pWal->iCallback; + pWal->iCallback = 0; + } + return (int)ret; +} + +/* +** This function is called to change the WAL subsystem into or out +** of locking_mode=EXCLUSIVE. +** +** If op is zero, then attempt to change from locking_mode=EXCLUSIVE +** into locking_mode=NORMAL. This means that we must acquire a lock +** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL +** or if the acquisition of the lock fails, then return 0. If the +** transition out of exclusive-mode is successful, return 1. This +** operation must occur while the pager is still holding the exclusive +** lock on the main database file. +** +** If op is one, then change from locking_mode=NORMAL into +** locking_mode=EXCLUSIVE. This means that the pWal->readLock must +** be released. Return 1 if the transition is made and 0 if the +** WAL is already in exclusive-locking mode - meaning that this +** routine is a no-op. The pager must already hold the exclusive lock +** on the main database file before invoking this operation. +** +** If op is negative, then do a dry-run of the op==1 case but do +** not actually change anything. The pager uses this to see if it +** should acquire the database exclusive lock prior to invoking +** the op==1 case. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ + int rc; + assert( pWal->writeLock==0 ); + assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); + + /* pWal->readLock is usually set, but might be -1 if there was a + ** prior error while attempting to acquire are read-lock. This cannot + ** happen if the connection is actually in exclusive mode (as no xShmLock + ** locks are taken in this case). Nor should the pager attempt to + ** upgrade to exclusive-mode following such an error. + */ +#ifndef SQLITE_USE_SEH + assert( pWal->readLock>=0 || pWal->lockError ); +#endif + assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); + + if( op==0 ){ + if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_NORMAL_MODE; + if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + } + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; + }else{ + /* Already in locking_mode=NORMAL */ + rc = 0; + } + }else if( op>0 ){ + assert( pWal->exclusiveMode==WAL_NORMAL_MODE ); + assert( pWal->readLock>=0 ); + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + rc = 1; + }else{ + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; + } + return rc; +} + +/* +** Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ + return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); +} + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* Create a snapshot object. The content of a snapshot is opaque to +** every other subsystem, so the WAL module can put whatever it needs +** in the object. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ + int rc = SQLITE_OK; + WalIndexHdr *pRet; + static const u32 aZero[4] = { 0, 0, 0, 0 }; + + assert( pWal->readLock>=0 && pWal->writeLock==0 ); + + if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){ + *ppSnapshot = 0; + return SQLITE_ERROR; + } + pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr)); + if( pRet==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr)); + *ppSnapshot = (sqlite3_snapshot*)pRet; + } + + return rc; +} + +/* Try to open on pSnapshot when the next read-transaction starts +*/ +SQLITE_PRIVATE void sqlite3WalSnapshotOpen( + Wal *pWal, + sqlite3_snapshot *pSnapshot +){ + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; +} + +/* +** Return a +ve value if snapshot p1 is newer than p2. A -ve value if +** p1 is older than p2 and zero if p1 and p2 are the same snapshot. +*/ +SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ + WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; + WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; + + /* aSalt[0] is a copy of the value stored in the wal file header. It + ** is incremented each time the wal file is restarted. */ + if( pHdr1->aSalt[0]aSalt[0] ) return -1; + if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1; + if( pHdr1->mxFramemxFrame ) return -1; + if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; + return 0; +} + +/* +** The caller currently has a read transaction open on the database. +** This function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ + int rc; + SEH_TRY { + rc = walLockShared(pWal, WAL_CKPT_LOCK); + if( rc==SQLITE_OK ){ + WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; + if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + || pNew->mxFramenBackfillAttempted + ){ + rc = SQLITE_ERROR_SNAPSHOT; + walUnlockShared(pWal, WAL_CKPT_LOCK); + } + } + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3WalSnapshotCheck(). +*/ +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ + assert( pWal ); + walUnlockShared(pWal, WAL_CKPT_LOCK); +} + + +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** If the argument is not NULL, it points to a Wal object that holds a +** read-lock. This function returns the database page-size if it is known, +** or zero if it is not (or if pWal is NULL). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ + assert( pWal==0 || pWal->readLock>=0 ); + return (pWal ? pWal->szPage : 0); +} +#endif + +/* Return the sqlite3_file object for the WAL file +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ + return pWal->pWalFd; +} + +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/************** End of wal.c *************************************************/ +/************** Begin file btmutex.c *****************************************/ +/* +** 2007 August 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to implement mutexes on Btree objects. +** This code really belongs in btree.c. But btree.c is getting too +** big and we want to break it down some. This packaged seemed like +** a good breakout. +*/ +/************** Include btreeInt.h in the middle of btmutex.c ****************/ +/************** Begin file btreeInt.h ****************************************/ +/* +** 2004 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements an external (disk-based) database using BTrees. +** For a detailed discussion of BTrees, refer to +** +** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: +** "Sorting And Searching", pages 473-480. Addison-Wesley +** Publishing Company, Reading, Massachusetts. +** +** The basic idea is that each page of the file contains N database +** entries and N+1 pointers to subpages. +** +** ---------------------------------------------------------------- +** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) | +** ---------------------------------------------------------------- +** +** All of the keys on the page that Ptr(0) points to have values less +** than Key(0). All of the keys on page Ptr(1) and its subpages have +** values greater than Key(0) and less than Key(1). All of the keys +** on Ptr(N) and its subpages have values greater than Key(N-1). And +** so forth. +** +** Finding a particular key requires reading O(log(M)) pages from the +** disk where M is the number of entries in the tree. +** +** In this implementation, a single file can hold one or more separate +** BTrees. Each BTree is identified by the index of its root page. The +** key and data for any entry are combined to form the "payload". A +** fixed amount of payload can be carried directly on the database +** page. If the payload is larger than the preset amount then surplus +** bytes are stored on overflow pages. The payload for an entry +** and the preceding pointer are combined to form a "Cell". Each +** page has a small header which contains the Ptr(N) pointer and other +** information such as the size of key and data. +** +** FORMAT DETAILS +** +** The file is divided into pages. The first page is called page 1, +** the second is page 2, and so forth. A page number of zero indicates +** "no such page". The page size can be any power of 2 between 512 and 65536. +** Each page can be either a btree page, a freelist page, an overflow +** page, or a pointer-map page. +** +** The first page is always a btree page. The first 100 bytes of the first +** page contain a special header (the "file header") that describes the file. +** The format of the file header is as follows: +** +** OFFSET SIZE DESCRIPTION +** 0 16 Header string: "SQLite format 3\000" +** 16 2 Page size in bytes. (1 means 65536) +** 18 1 File format write version +** 19 1 File format read version +** 20 1 Bytes of unused space at the end of each page +** 21 1 Max embedded payload fraction (must be 64) +** 22 1 Min embedded payload fraction (must be 32) +** 23 1 Min leaf payload fraction (must be 32) +** 24 4 File change counter +** 28 4 The size of the database in pages +** 32 4 First freelist page +** 36 4 Number of freelist pages in the file +** 40 60 15 4-byte meta values passed to higher layers +** +** 40 4 Schema cookie +** 44 4 File format of schema layer +** 48 4 Size of page cache +** 52 4 Largest root-page (auto/incr_vacuum) +** 56 4 1=UTF-8 2=UTF16le 3=UTF16be +** 60 4 User version +** 64 4 Incremental vacuum mode +** 68 4 Application-ID +** 72 20 unused +** 92 4 The version-valid-for number +** 96 4 SQLITE_VERSION_NUMBER +** +** All of the integer values are big-endian (most significant byte first). +** +** The file change counter is incremented when the database is changed +** This counter allows other processes to know when the file has changed +** and thus when they need to flush their cache. +** +** The max embedded payload fraction is the amount of the total usable +** space in a page that can be consumed by a single cell for standard +** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default +** is to limit the maximum cell size so that at least 4 cells will fit +** on one page. Thus the default max embedded payload fraction is 64. +** +** If the payload for a cell is larger than the max payload, then extra +** payload is spilled to overflow pages. Once an overflow page is allocated, +** as many bytes as possible are moved into the overflow pages without letting +** the cell size drop below the min embedded payload fraction. +** +** The min leaf payload fraction is like the min embedded payload fraction +** except that it applies to leaf nodes in a LEAFDATA tree. The maximum +** payload fraction for a LEAFDATA tree is always 100% (or 255) and it +** not specified in the header. +** +** Each btree pages is divided into three sections: The header, the +** cell pointer array, and the cell content area. Page 1 also has a 100-byte +** file header that occurs before the page header. +** +** |----------------| +** | file header | 100 bytes. Page 1 only. +** |----------------| +** | page header | 8 bytes for leaves. 12 bytes for interior nodes +** |----------------| +** | cell pointer | | 2 bytes per cell. Sorted order. +** | array | | Grows downward +** | | v +** |----------------| +** | unallocated | +** | space | +** |----------------| ^ Grows upwards +** | cell content | | Arbitrary order interspersed with freeblocks. +** | area | | and free space fragments. +** |----------------| +** +** The page headers looks like this: +** +** OFFSET SIZE DESCRIPTION +** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf +** 1 2 byte offset to the first freeblock +** 3 2 number of cells on this page +** 5 2 first byte of the cell content area +** 7 1 number of fragmented free bytes +** 8 4 Right child (the Ptr(N) value). Omitted on leaves. +** +** The flags define the format of this btree page. The leaf flag means that +** this page has no children. The zerodata flag means that this page carries +** only keys and no data. The intkey flag means that the key is an integer +** which is stored in the key size entry of the cell header rather than in +** the payload area. +** +** The cell pointer array begins on the first byte after the page header. +** The cell pointer array contains zero or more 2-byte numbers which are +** offsets from the beginning of the page to the cell content in the cell +** content area. The cell pointers occur in sorted order. The system strives +** to keep free space after the last cell pointer so that new cells can +** be easily added without having to defragment the page. +** +** Cell content is stored at the very end of the page and grows toward the +** beginning of the page. +** +** Unused space within the cell content area is collected into a linked list of +** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset +** to the first freeblock is given in the header. Freeblocks occur in +** increasing order. Because a freeblock must be at least 4 bytes in size, +** any group of 3 or fewer unused bytes in the cell content area cannot +** exist on the freeblock chain. A group of 3 or fewer free bytes is called +** a fragment. The total number of bytes in all fragments is recorded. +** in the page header at offset 7. +** +** SIZE DESCRIPTION +** 2 Byte offset of the next freeblock +** 2 Bytes in this freeblock +** +** Cells are of variable length. Cells are stored in the cell content area at +** the end of the page. Pointers to the cells are in the cell pointer array +** that immediately follows the page header. Cells is not necessarily +** contiguous or in order, but cell pointers are contiguous and in order. +** +** Cell content makes use of variable length integers. A variable +** length integer is 1 to 9 bytes where the lower 7 bits of each +** byte are used. The integer consists of all bytes that have bit 8 set and +** the first byte with bit 8 clear. The most significant byte of the integer +** appears first. A variable-length integer may not be more than 9 bytes long. +** As a special case, all 8 bits of the 9th byte are used as data. This +** allows a 64-bit integer to be encoded in 9 bytes. +** +** 0x00 becomes 0x00000000 +** 0x7f becomes 0x0000007f +** 0x81 0x00 becomes 0x00000080 +** 0x82 0x00 becomes 0x00000100 +** 0x80 0x7f becomes 0x0000007f +** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 +** +** Variable length integers are used for rowids and to hold the number of +** bytes of key and data in a btree cell. +** +** The content of a cell looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of the left child. Omitted if leaf flag is set. +** var Number of bytes of data. Omitted if the zerodata flag is set. +** var Number of bytes of key. Or the key itself if intkey flag is set. +** * Payload +** 4 First page of the overflow chain. Omitted if no overflow +** +** Overflow pages form a linked list. Each page except the last is completely +** filled with data (pagesize - 4 bytes). The last page can have as little +** as 1 byte of data. +** +** SIZE DESCRIPTION +** 4 Page number of next overflow page +** * Data +** +** Freelist pages come in two subtypes: trunk pages and leaf pages. The +** file header points to the first in a linked list of trunk page. Each trunk +** page points to multiple leaf pages. The content of a leaf page is +** unspecified. A trunk page looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of next trunk page +** 4 Number of leaf pointers on this page +** * zero or more pages numbers of leaves +*/ +/* #include "sqliteInt.h" */ + + +/* The following value is the maximum cell size assuming a maximum page +** size give above. +*/ +#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) + +/* The maximum number of cells on a single page of the database. This +** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself +** plus 2 bytes for the index to the cell in the page header). Such +** small cells will be rare, but they are possible. +*/ +#define MX_CELL(pBt) ((pBt->pageSize-8)/6) + +/* Forward declarations */ +typedef struct MemPage MemPage; +typedef struct BtLock BtLock; +typedef struct CellInfo CellInfo; + +/* +** This is a magic string that appears at the beginning of every +** SQLite database in order to identify the file as a real database. +** +** You can change this value at compile-time by specifying a +** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The +** header must be exactly 16 bytes including the zero-terminator so +** the string itself should be 15 characters long. If you change +** the header, then your custom library will not be able to read +** databases generated by the standard tools and the standard tools +** will not be able to read databases created by your custom library. +*/ +#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */ +# define SQLITE_FILE_HEADER "SQLite format 3" +#endif + +/* +** Page type flags. An ORed combination of these flags appear as the +** first byte of on-disk image of every BTree page. +*/ +#define PTF_INTKEY 0x01 +#define PTF_ZERODATA 0x02 +#define PTF_LEAFDATA 0x04 +#define PTF_LEAF 0x08 + +/* +** An instance of this object stores information about each a single database +** page that has been loaded into memory. The information in this object +** is derived from the raw on-disk page content. +** +** As each database page is loaded into memory, the pager allocates an +** instance of this object and zeros the first 8 bytes. (This is the +** "extra" information associated with each page of the pager.) +** +** Access to all fields of this structure is controlled by the mutex +** stored in MemPage.pBt->mutex. +*/ +struct MemPage { + u8 isInit; /* True if previously initialized. MUST BE FIRST! */ + u8 intKey; /* True if table b-trees. False for index b-trees */ + u8 intKeyLeaf; /* True if the leaf of an intKey table */ + Pgno pgno; /* Page number for this page */ + /* Only the first 8 bytes (above) are zeroed by pager.c when a new page + ** is allocated. All fields that follow must be initialized before use */ + u8 leaf; /* True if a leaf page */ + u8 hdrOffset; /* 100 for page 1. 0 otherwise */ + u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ + u8 max1bytePayload; /* min(maxLocal,127) */ + u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ + u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ + u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ + u16 cellOffset; /* Index in aData of first cell pointer */ + int nFree; /* Number of free bytes on the page. -1 for unknown */ + u16 nCell; /* Number of cells on this page, local and ovfl */ + u16 maskPage; /* Mask for page offset */ + u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th + ** non-overflow cell */ + u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ + BtShared *pBt; /* Pointer to BtShared that this page is part of */ + u8 *aData; /* Pointer to disk image of the page data */ + u8 *aDataEnd; /* One byte past the end of the entire page - not just + ** the usable space, the entire page. Used to prevent + ** corruption-induced buffer overflow. */ + u8 *aCellIdx; /* The cell index area */ + u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ + DbPage *pDbPage; /* Pager page handle */ + u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ + void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */ +}; + +/* +** A linked list of the following structures is stored at BtShared.pLock. +** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor +** is opened on the table with root page BtShared.iTable. Locks are removed +** from this list when a transaction is committed or rolled back, or when +** a btree handle is closed. +*/ +struct BtLock { + Btree *pBtree; /* Btree handle holding this lock */ + Pgno iTable; /* Root page of table */ + u8 eLock; /* READ_LOCK or WRITE_LOCK */ + BtLock *pNext; /* Next in BtShared.pLock list */ +}; + +/* Candidate values for BtLock.eLock */ +#define READ_LOCK 1 +#define WRITE_LOCK 2 + +/* A Btree handle +** +** A database connection contains a pointer to an instance of +** this object for every database file that it has open. This structure +** is opaque to the database connection. The database connection cannot +** see the internals of this structure and only deals with pointers to +** this structure. +** +** For some database files, the same underlying database cache might be +** shared between multiple connections. In that case, each connection +** has it own instance of this object. But each instance of this object +** points to the same BtShared object. The database cache and the +** schema associated with the database file are all contained within +** the BtShared object. +** +** All fields in this structure are accessed under sqlite3.mutex. +** The pBt pointer itself may not be changed while there exists cursors +** in the referenced BtShared that point back to this Btree since those +** cursors have to go through this Btree to find their BtShared and +** they often do so without holding sqlite3.mutex. +*/ +struct Btree { + sqlite3 *db; /* The database connection holding this btree */ + BtShared *pBt; /* Sharable content of this btree */ + u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ + u8 sharable; /* True if we can share pBt with another db */ + u8 locked; /* True if db currently has pBt locked */ + u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */ + int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ + int nBackup; /* Number of backup operations reading this btree */ + u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */ + Btree *pNext; /* List of other sharable Btrees from the same db */ + Btree *pPrev; /* Back pointer of the same list */ +#ifdef SQLITE_DEBUG + u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */ +#endif +#ifndef SQLITE_OMIT_SHARED_CACHE + BtLock lock; /* Object used to lock page 1 */ +#endif +}; + +/* +** Btree.inTrans may take one of the following values. +** +** If the shared-data extension is enabled, there may be multiple users +** of the Btree structure. At most one of these may open a write transaction, +** but any number may have active read transactions. +** +** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and +** SQLITE_TXN_WRITE +*/ +#define TRANS_NONE 0 +#define TRANS_READ 1 +#define TRANS_WRITE 2 + +#if TRANS_NONE!=SQLITE_TXN_NONE +# error wrong numeric code for no-transaction +#endif +#if TRANS_READ!=SQLITE_TXN_READ +# error wrong numeric code for read-transaction +#endif +#if TRANS_WRITE!=SQLITE_TXN_WRITE +# error wrong numeric code for write-transaction +#endif + + +/* +** An instance of this object represents a single database file. +** +** A single database file can be in use at the same time by two +** or more database connections. When two or more connections are +** sharing the same database file, each connection has it own +** private Btree object for the file and each of those Btrees points +** to this one BtShared object. BtShared.nRef is the number of +** connections currently sharing this database file. +** +** Fields in this structure are accessed under the BtShared.mutex +** mutex, except for nRef and pNext which are accessed under the +** global SQLITE_MUTEX_STATIC_MAIN mutex. The pPager field +** may not be modified once it is initially set as long as nRef>0. +** The pSchema field may be set once under BtShared.mutex and +** thereafter is unchanged as long as nRef>0. +** +** isPending: +** +** If a BtShared client fails to obtain a write-lock on a database +** table (because there exists one or more read-locks on the table), +** the shared-cache enters 'pending-lock' state and isPending is +** set to true. +** +** The shared-cache leaves the 'pending lock' state when either of +** the following occur: +** +** 1) The current writer (BtShared.pWriter) concludes its transaction, OR +** 2) The number of locks held by other connections drops to zero. +** +** while in the 'pending-lock' state, no connection may start a new +** transaction. +** +** This feature is included to help prevent writer-starvation. +*/ +struct BtShared { + Pager *pPager; /* The page cache */ + sqlite3 *db; /* Database connection currently using this Btree */ + BtCursor *pCursor; /* A list of all open cursors */ + MemPage *pPage1; /* First page of the database */ + u8 openFlags; /* Flags to sqlite3BtreeOpen() */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 autoVacuum; /* True if auto-vacuum is enabled */ + u8 incrVacuum; /* True if incr-vacuum is enabled */ + u8 bDoTruncate; /* True to truncate db on commit */ +#endif + u8 inTransaction; /* Transaction state */ + u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ + u8 nReserveWanted; /* Desired number of extra bytes per page */ + u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ + u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ + u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ + u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ + u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ + u32 pageSize; /* Total number of bytes on a page */ + u32 usableSize; /* Number of usable bytes on each page */ + int nTransaction; /* Number of open transactions (read + write) */ + u32 nPage; /* Number of pages in the database */ + void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ + void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ + sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ + Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ +#ifndef SQLITE_OMIT_SHARED_CACHE + int nRef; /* Number of references to this structure */ + BtShared *pNext; /* Next on a list of sharable BtShared structs */ + BtLock *pLock; /* List of locks held on this shared-btree struct */ + Btree *pWriter; /* Btree with currently open write transaction */ +#endif + u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ + int nPreformatSize; /* Size of last cell written by TransferRow() */ +}; + +/* +** Allowed values for BtShared.btsFlags +*/ +#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ +#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ +#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ +#define BTS_OVERWRITE 0x0008 /* Overwrite deleted content with zeros */ +#define BTS_FAST_SECURE 0x000c /* Combination of the previous two */ +#define BTS_INITIALLY_EMPTY 0x0010 /* Database was empty at trans start */ +#define BTS_NO_WAL 0x0020 /* Do not open write-ahead-log files */ +#define BTS_EXCLUSIVE 0x0040 /* pWriter has an exclusive lock */ +#define BTS_PENDING 0x0080 /* Waiting for read-locks to clear */ + +/* +** An instance of the following structure is used to hold information +** about a cell. The parseCellPtr() function fills in this structure +** based on information extract from the raw disk page. +*/ +struct CellInfo { + i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */ + u8 *pPayload; /* Pointer to the start of payload */ + u32 nPayload; /* Bytes of payload */ + u16 nLocal; /* Amount of payload held locally, not on overflow */ + u16 nSize; /* Size of the cell content on the main b-tree page */ +}; + +/* +** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than +** this will be declared corrupt. This value is calculated based on a +** maximum database size of 2^31 pages a minimum fanout of 2 for a +** root-node and 3 for all other internal nodes. +** +** If a tree that appears to be taller than this is encountered, it is +** assumed that the database is corrupt. +*/ +#define BTCURSOR_MAX_DEPTH 20 + +/* +** A cursor is a pointer to a particular entry within a particular +** b-tree within a database file. +** +** The entry is identified by its MemPage and the index in +** MemPage.aCell[] of the entry. +** +** A single database file can be shared by two more database connections, +** but cursors cannot be shared. Each cursor is associated with a +** particular database connection identified BtCursor.pBtree.db. +** +** Fields in this structure are accessed under the BtShared.mutex +** found at self->pBt->mutex. +** +** skipNext meaning: +** The meaning of skipNext depends on the value of eState: +** +** eState Meaning of skipNext +** VALID skipNext is meaningless and is ignored +** INVALID skipNext is meaningless and is ignored +** SKIPNEXT sqlite3BtreeNext() is a no-op if skipNext>0 and +** sqlite3BtreePrevious() is no-op if skipNext<0. +** REQUIRESEEK restoreCursorPosition() restores the cursor to +** eState=SKIPNEXT if skipNext!=0 +** FAULT skipNext holds the cursor fault error code. +*/ +struct BtCursor { + u8 eState; /* One of the CURSOR_XXX constants (see below) */ + u8 curFlags; /* zero or more BTCF_* flags defined below */ + u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ + u8 hints; /* As configured by CursorSetHints() */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive. + ** Error code if eState==CURSOR_FAULT */ + Btree *pBtree; /* The Btree to which this cursor belongs */ + Pgno *aOverflow; /* Cache of overflow page locations */ + void *pKey; /* Saved key that was cursor last known position */ + /* All fields above are zeroed when the cursor is allocated. See + ** sqlite3BtreeCursorZero(). Fields that follow must be manually + ** initialized. */ +#define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */ + BtShared *pBt; /* The BtShared this cursor points to */ + BtCursor *pNext; /* Forms a linked list of all cursors */ + CellInfo info; /* A parse of the cell we are pointing at */ + i64 nKey; /* Size of pKey, or last integer key */ + Pgno pgnoRoot; /* The root page of this tree */ + i8 iPage; /* Index of current page in apPage */ + u8 curIntKey; /* Value of apPage[0]->intKey */ + u16 ix; /* Current index for apPage[iPage] */ + u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ + struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ + MemPage *pPage; /* Current page */ + MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */ +}; + +/* +** Legal values for BtCursor.curFlags +*/ +#define BTCF_WriteFlag 0x01 /* True if a write cursor */ +#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ +#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ +#define BTCF_AtLast 0x08 /* Cursor is pointing to the last entry */ +#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ +#define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ +#define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ + +/* +** Potential values for BtCursor.eState. +** +** CURSOR_INVALID: +** Cursor does not point to a valid entry. This can happen (for example) +** because the table is empty or because BtreeCursorFirst() has not been +** called. +** +** CURSOR_VALID: +** Cursor points to a valid entry. getPayload() etc. may be called. +** +** CURSOR_SKIPNEXT: +** Cursor is valid except that the Cursor.skipNext field is non-zero +** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious() +** operation should be a no-op. +** +** CURSOR_REQUIRESEEK: +** The table that this cursor was opened on still exists, but has been +** modified since the cursor was last used. The cursor position is saved +** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in +** this state, restoreCursorPosition() can be called to attempt to +** seek the cursor to the saved position. +** +** CURSOR_FAULT: +** An unrecoverable error (an I/O error or a malloc failure) has occurred +** on a different connection that shares the BtShared cache with this +** cursor. The error has left the cache in an inconsistent state. +** Do nothing else with this cursor. Any attempt to use the cursor +** should return the error code stored in BtCursor.skipNext +*/ +#define CURSOR_VALID 0 +#define CURSOR_INVALID 1 +#define CURSOR_SKIPNEXT 2 +#define CURSOR_REQUIRESEEK 3 +#define CURSOR_FAULT 4 + +/* +** The database page the PENDING_BYTE occupies. This page is never used. +*/ +#define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1)) + +/* +** These macros define the location of the pointer-map entry for a +** database page. The first argument to each is the number of usable +** bytes on each page of the database (often 1024). The second is the +** page number to look up in the pointer map. +** +** PTRMAP_PAGENO returns the database page number of the pointer-map +** page that stores the required pointer. PTRMAP_PTROFFSET returns +** the offset of the requested map entry. +** +** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, +** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be +** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements +** this test. +*/ +#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno) +#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1)) +#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno)) + +/* +** The pointer map is a lookup table that identifies the parent page for +** each child page in the database file. The parent page is the page that +** contains a pointer to the child. Every page in the database contains +** 0 or 1 parent pages. (In this context 'database page' refers +** to any page that is not part of the pointer map itself.) Each pointer map +** entry consists of a single byte 'type' and a 4 byte parent page number. +** The PTRMAP_XXX identifiers below are the valid types. +** +** The purpose of the pointer map is to facility moving pages from one +** position in the file to another as part of autovacuum. When a page +** is moved, the pointer in its parent must be updated to point to the +** new location. The pointer map is used to locate the parent page quickly. +** +** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not +** used in this case. +** +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** is not used in this case. +** +** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** overflow pages. The page number identifies the page that +** contains the cell with a pointer to this overflow page. +** +** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of +** overflow pages. The page-number identifies the previous +** page in the overflow page list. +** +** PTRMAP_BTREE: The database page is a non-root btree page. The page number +** identifies the parent page in the btree. +*/ +#define PTRMAP_ROOTPAGE 1 +#define PTRMAP_FREEPAGE 2 +#define PTRMAP_OVERFLOW1 3 +#define PTRMAP_OVERFLOW2 4 +#define PTRMAP_BTREE 5 + +/* A bunch of assert() statements to check the transaction state variables +** of handle p (type Btree*) are internally consistent. +*/ +#define btreeIntegrity(p) \ + assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ + assert( p->pBt->inTransaction>=p->inTrans ); + + +/* +** The ISAUTOVACUUM macro is used within balance_nonroot() to determine +** if the database supports auto-vacuum or not. Because it is used +** within an expression that is an argument to another macro +** (sqliteMallocRaw), it is not possible to use conditional compilation. +** So, this macro is defined instead. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define ISAUTOVACUUM(pBt) (pBt->autoVacuum) +#else +#define ISAUTOVACUUM(pBt) 0 +#endif + + +/* +** This structure is passed around through all the PRAGMA integrity_check +** checking routines in order to keep track of some global state information. +** +** The aRef[] array is allocated so that there is 1 bit for each page in +** the database. As the integrity-check proceeds, for each page used in +** the database the corresponding bit is set. This allows integrity-check to +** detect pages that are used twice and orphaned pages (both of which +** indicate corruption). +*/ +typedef struct IntegrityCk IntegrityCk; +struct IntegrityCk { + BtShared *pBt; /* The tree being checked out */ + Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ + u8 *aPgRef; /* 1 bit per page in the db (see above) */ + Pgno nCkPage; /* Pages in the database. 0 for partial check */ + int mxErr; /* Stop accumulating errors when this reaches zero */ + int nErr; /* Number of messages written to zErrMsg so far */ + int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ + u32 nStep; /* Number of steps into the integrity_check process */ + const char *zPfx; /* Error message prefix */ + Pgno v0; /* Value for first %u substitution in zPfx (root page) */ + Pgno v1; /* Value for second %u substitution in zPfx (current pg) */ + int v2; /* Value for third %d substitution in zPfx */ + StrAccum errMsg; /* Accumulate the error message text here */ + u32 *heap; /* Min-heap used for analyzing cell coverage */ + sqlite3 *db; /* Database connection running the check */ +}; + +/* +** Routines to read or write a two- and four-byte big-endian integer values. +*/ +#define get2byte(x) ((x)[0]<<8 | (x)[1]) +#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) +#define get4byte sqlite3Get4byte +#define put4byte sqlite3Put4byte + +/* +** get2byteAligned(), unlike get2byte(), requires that its argument point to a +** two-byte aligned address. get2byteAligned() is only used for accessing the +** cell addresses in a btree header. +*/ +#if SQLITE_BYTEORDER==4321 +# define get2byteAligned(x) (*(u16*)(x)) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000 +# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 +# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x)) +#else +# define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) +#endif + +/************** End of btreeInt.h ********************************************/ +/************** Continuing where we left off in btmutex.c ********************/ +#ifndef SQLITE_OMIT_SHARED_CACHE +#if SQLITE_THREADSAFE + +/* +** Obtain the BtShared mutex associated with B-Tree handle p. Also, +** set BtShared.db to the database handle associated with p and the +** p->locked boolean to true. +*/ +static void lockBtreeMutex(Btree *p){ + assert( p->locked==0 ); + assert( sqlite3_mutex_notheld(p->pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + + sqlite3_mutex_enter(p->pBt->mutex); + p->pBt->db = p->db; + p->locked = 1; +} + +/* +** Release the BtShared mutex associated with B-Tree handle p and +** clear the p->locked boolean. +*/ +static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){ + BtShared *pBt = p->pBt; + assert( p->locked==1 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + assert( p->db==pBt->db ); + + sqlite3_mutex_leave(pBt->mutex); + p->locked = 0; +} + +/* Forward reference */ +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p); + +/* +** Enter a mutex on the given BTree object. +** +** If the object is not sharable, then no mutex is ever required +** and this routine is a no-op. The underlying mutex is non-recursive. +** But we keep a reference count in Btree.wantToLock so the behavior +** of this interface is recursive. +** +** To avoid deadlocks, multiple Btrees are locked in the same order +** by all database connections. The p->pNext is a list of other +** Btrees belonging to the same database connection as the p Btree +** which need to be locked after p. If we cannot get a lock on +** p, then first unlock all of the others on p->pNext, then wait +** for the lock to become available on p, then relock all of the +** subsequent Btrees that desire a lock. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ + /* Some basic sanity checking on the Btree. The list of Btrees + ** connected by pNext and pPrev should be in sorted order by + ** Btree.pBt value. All elements of the list should belong to + ** the same connection. Only shared Btrees are on the list. */ + assert( p->pNext==0 || p->pNext->pBt>p->pBt ); + assert( p->pPrev==0 || p->pPrev->pBtpBt ); + assert( p->pNext==0 || p->pNext->db==p->db ); + assert( p->pPrev==0 || p->pPrev->db==p->db ); + assert( p->sharable || (p->pNext==0 && p->pPrev==0) ); + + /* Check for locking consistency */ + assert( !p->locked || p->wantToLock>0 ); + assert( p->sharable || p->wantToLock==0 ); + + /* We should already hold a lock on the database connection */ + assert( sqlite3_mutex_held(p->db->mutex) ); + + /* Unless the database is sharable and unlocked, then BtShared.db + ** should already be set correctly. */ + assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); + + if( !p->sharable ) return; + p->wantToLock++; + if( p->locked ) return; + btreeLockCarefully(p); +} + +/* This is a helper function for sqlite3BtreeLock(). By moving +** complex, but seldom used logic, out of sqlite3BtreeLock() and +** into this routine, we avoid unnecessary stack pointer changes +** and thus help the sqlite3BtreeLock() routine to run much faster +** in the common case. +*/ +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ + Btree *pLater; + + /* In most cases, we should be able to acquire the lock we + ** want without having to go through the ascending lock + ** procedure that follows. Just be sure not to block. + */ + if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ + p->pBt->db = p->db; + p->locked = 1; + return; + } + + /* To avoid deadlock, first release all locks with a larger + ** BtShared address. Then acquire our lock. Then reacquire + ** the other BtShared locks that we used to hold in ascending + ** order. + */ + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + assert( pLater->sharable ); + assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt ); + assert( !pLater->locked || pLater->wantToLock>0 ); + if( pLater->locked ){ + unlockBtreeMutex(pLater); + } + } + lockBtreeMutex(p); + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + if( pLater->wantToLock ){ + lockBtreeMutex(pLater); + } + } +} + + +/* +** Exit the recursive mutex on a Btree. +*/ +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ + assert( sqlite3_mutex_held(p->db->mutex) ); + if( p->sharable ){ + assert( p->wantToLock>0 ); + p->wantToLock--; + if( p->wantToLock==0 ){ + unlockBtreeMutex(p); + } + } +} + +#ifndef NDEBUG +/* +** Return true if the BtShared mutex is held on the btree, or if the +** B-Tree is not marked as sharable. +** +** This routine is used only from within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ + assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 ); + assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) ); + + return (p->sharable==0 || p->locked); +} +#endif + + +/* +** Enter the mutex on every Btree associated with a database +** connection. This is needed (for example) prior to parsing +** a statement since we will be comparing table and column names +** against all schemas and we do not want those schemas being +** reset out from under us. +** +** There is a corresponding leave-all procedures. +** +** Enter the mutexes in ascending order by BtShared pointer address +** to avoid the possibility of deadlock when two threads with +** two or more btrees in common both try to lock all their btrees +** at the same instant. +*/ +static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ + int i; + int skipOk = 1; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p && p->sharable ){ + sqlite3BtreeEnter(p); + skipOk = 0; + } + } + db->noSharedCache = skipOk; +} +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ + if( db->noSharedCache==0 ) btreeEnterAll(db); +} +static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ + int i; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p ) sqlite3BtreeLeave(p); + } +} +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ + if( db->noSharedCache==0 ) btreeLeaveAll(db); +} + +#ifndef NDEBUG +/* +** Return true if the current thread holds the database connection +** mutex and all required BtShared mutexes. +** +** This routine is used inside assert() statements only. +*/ +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ + int i; + if( !sqlite3_mutex_held(db->mutex) ){ + return 0; + } + for(i=0; inDb; i++){ + Btree *p; + p = db->aDb[i].pBt; + if( p && p->sharable && + (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ + return 0; + } + } + return 1; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Return true if the correct mutexes are held for accessing the +** db->aDb[iDb].pSchema structure. The mutexes required for schema +** access are: +** +** (1) The mutex on db +** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. +** +** If pSchema is not NULL, then iDb is computed from pSchema and +** db using sqlite3SchemaToIndex(). +*/ +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ + Btree *p; + assert( db!=0 ); + if( db->pVfs==0 && db->nDb==0 ) return 1; + if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); + assert( iDb>=0 && iDbnDb ); + if( !sqlite3_mutex_held(db->mutex) ) return 0; + if( iDb==1 ) return 1; + p = db->aDb[iDb].pBt; + assert( p!=0 ); + return p->sharable==0 || p->locked==1; +} +#endif /* NDEBUG */ + +#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */ +/* +** The following are special cases for mutex enter routines for use +** in single threaded applications that use shared cache. Except for +** these two routines, all mutex operations are no-ops in that case and +** are null #defines in btree.h. +** +** If shared cache is disabled, then all btree mutex routines, including +** the ones below, are no-ops and are null #defines in btree.h. +*/ + +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ + p->pBt->db = p->db; +} +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ + int i; + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + p->pBt->db = p->db; + } + } +} +#endif /* if SQLITE_THREADSAFE */ + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Enter a mutex on a Btree given a cursor owned by that Btree. +** +** These entry points are used by incremental I/O only. Enter() is required +** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not +** the build is threadsafe. Leave() is only required by threadsafe builds. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){ + sqlite3BtreeEnter(pCur->pBtree); +} +# if SQLITE_THREADSAFE +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ + sqlite3BtreeLeave(pCur->pBtree); +} +# endif +#endif /* ifndef SQLITE_OMIT_INCRBLOB */ + +#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */ + +/************** End of btmutex.c *********************************************/ +/************** Begin file btree.c *******************************************/ +/* +** 2004 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements an external (disk-based) database using BTrees. +** See the header comment on "btreeInt.h" for additional information. +** Including a description of file format and an overview of operation. +*/ +/* #include "btreeInt.h" */ + +/* +** The header string that appears at the beginning of every +** SQLite database. +*/ +static const char zMagicHeader[] = SQLITE_FILE_HEADER; + +/* +** Set this global variable to 1 to enable tracing using the TRACE +** macro. +*/ +#if 0 +int sqlite3BtreeTrace=1; /* True to enable tracing */ +# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} +#else +# define TRACE(X) +#endif + +/* +** Extract a 2-byte big-endian integer from an array of unsigned bytes. +** But if the value is zero, make it 65536. +** +** This routine is used to extract the "offset to cell content area" value +** from the header of a btree page. If the page size is 65536 and the page +** is empty, the offset should be 65536, but the 2-byte value stores zero. +** This routine makes the necessary adjustment to 65536. +*/ +#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1) + +/* +** Values passed as the 5th argument to allocateBtreePage() +*/ +#define BTALLOC_ANY 0 /* Allocate any page */ +#define BTALLOC_EXACT 1 /* Allocate exact page if possible */ +#define BTALLOC_LE 2 /* Allocate any page <= the parameter */ + +/* +** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not +** defined, or 0 if it is. For example: +** +** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum); +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define IfNotOmitAV(expr) (expr) +#else +#define IfNotOmitAV(expr) 0 +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** A list of BtShared objects that are eligible for participation +** in shared cache. This variable has file scope during normal builds, +** but the test harness needs to access it so we make it global for +** test builds. +** +** Access to this variable is protected by SQLITE_MUTEX_STATIC_MAIN. +*/ +#ifdef SQLITE_TEST +SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#else +static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#endif +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Enable or disable the shared pager and schema features. +** +** This routine has no effect on existing database connections. +** The shared cache setting effects only future calls to +** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). +*/ +SQLITE_API int sqlite3_enable_shared_cache(int enable){ + sqlite3GlobalConfig.sharedCacheEnabled = enable; + return SQLITE_OK; +} +#endif + + + +#ifdef SQLITE_OMIT_SHARED_CACHE + /* + ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), + ** and clearAllSharedCacheTableLocks() + ** manipulate entries in the BtShared.pLock linked list used to store + ** shared-cache table level locks. If the library is compiled with the + ** shared-cache feature disabled, then there is only ever one user + ** of each BtShared structure and so this locking is not necessary. + ** So define the lock related functions as no-ops. + */ + #define querySharedCacheTableLock(a,b,c) SQLITE_OK + #define setSharedCacheTableLock(a,b,c) SQLITE_OK + #define clearAllSharedCacheTableLocks(a) + #define downgradeAllSharedCacheTableLocks(a) + #define hasSharedCacheTableLock(a,b,c,d) 1 + #define hasReadConflicts(a, b) 0 +#endif + +#ifdef SQLITE_DEBUG +/* +** Return and reset the seek counter for a Btree object. +*/ +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){ + u64 n = pBt->nSeek; + pBt->nSeek = 0; + return n; +} +#endif + +/* +** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single +** (MemPage*) as an argument. The (MemPage*) must not be NULL. +** +** If SQLITE_DEBUG is not defined, then this macro is equivalent to +** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message +** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented +** with the page number and filename associated with the (MemPage*). +*/ +#ifdef SQLITE_DEBUG +int corruptPageError(int lineno, MemPage *p){ + char *zMsg; + sqlite3BeginBenignMalloc(); + zMsg = sqlite3_mprintf("database corruption page %u of %s", + p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) + ); + sqlite3EndBenignMalloc(); + if( zMsg ){ + sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); + } + sqlite3_free(zMsg); + return SQLITE_CORRUPT_BKPT; +} +# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage) +#else +# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE + +#ifdef SQLITE_DEBUG +/* +**** This function is only used as part of an assert() statement. *** +** +** Check to see if pBtree holds the required locks to read or write to the +** table with root page iRoot. Return 1 if it does and 0 if not. +** +** For example, when writing to a table with root-page iRoot via +** Btree connection pBtree: +** +** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); +** +** When writing to an index that resides in a sharable database, the +** caller should have first obtained a lock specifying the root page of +** the corresponding table. This makes things a bit more complicated, +** as this module treats each table as a separate structure. To determine +** the table corresponding to the index being written, this +** function has to search through the database schema. +** +** Instead of a lock on the table/index rooted at page iRoot, the caller may +** hold a write-lock on the schema table (root page 1). This is also +** acceptable. +*/ +static int hasSharedCacheTableLock( + Btree *pBtree, /* Handle that must hold lock */ + Pgno iRoot, /* Root page of b-tree */ + int isIndex, /* True if iRoot is the root of an index b-tree */ + int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */ +){ + Schema *pSchema = (Schema *)pBtree->pBt->pSchema; + Pgno iTab = 0; + BtLock *pLock; + + /* If this database is not shareable, or if the client is reading + ** and has the read-uncommitted flag set, then no lock is required. + ** Return true immediately. + */ + if( (pBtree->sharable==0) + || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit)) + ){ + return 1; + } + + /* If the client is reading or writing an index and the schema is + ** not loaded, then it is too difficult to actually check to see if + ** the correct locks are held. So do not bother - just return true. + ** This case does not come up very often anyhow. + */ + if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){ + return 1; + } + + /* Figure out the root-page that the lock should be held on. For table + ** b-trees, this is just the root page of the b-tree being read or + ** written. For index b-trees, it is the root page of the associated + ** table. */ + if( isIndex ){ + HashElem *p; + int bSeen = 0; + for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ + Index *pIdx = (Index *)sqliteHashData(p); + if( pIdx->tnum==iRoot ){ + if( bSeen ){ + /* Two or more indexes share the same root page. There must + ** be imposter tables. So just return true. The assert is not + ** useful in that case. */ + return 1; + } + iTab = pIdx->pTable->tnum; + bSeen = 1; + } + } + }else{ + iTab = iRoot; + } + + /* Search for the required lock. Either a write-lock on root-page iTab, a + ** write-lock on the schema table, or (if the client is reading) a + ** read-lock on iTab will suffice. Return 1 if any of these are found. */ + for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ + if( pLock->pBtree==pBtree + && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) + && pLock->eLock>=eLockType + ){ + return 1; + } + } + + /* Failed to find the required lock. */ + return 0; +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +**** This function may be used as part of assert() statements only. **** +** +** Return true if it would be illegal for pBtree to write into the +** table or index rooted at iRoot because other shared connections are +** simultaneously reading that same table or index. +** +** It is illegal for pBtree to write if some other Btree object that +** shares the same BtShared object is currently reading or writing +** the iRoot table. Except, if the other Btree object has the +** read-uncommitted flag set, then it is OK for the other object to +** have a read cursor. +** +** For example, before writing to any part of the table or index +** rooted at page iRoot, one should call: +** +** assert( !hasReadConflicts(pBtree, iRoot) ); +*/ +static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ + BtCursor *p; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( p->pgnoRoot==iRoot + && p->pBtree!=pBtree + && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit) + ){ + return 1; + } + } + return 0; +} +#endif /* #ifdef SQLITE_DEBUG */ + +/* +** Query to see if Btree handle p may obtain a lock of type eLock +** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return +** SQLITE_OK if the lock may be obtained (by calling +** setSharedCacheTableLock()), or SQLITE_LOCKED if not. +*/ +static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 ); + + /* If requesting a write-lock, then the Btree must have an open write + ** transaction on this file. And, obviously, for this to be so there + ** must be an open write transaction on the file itself. + */ + assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); + assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); + + /* This routine is a no-op if the shared-cache is not enabled */ + if( !p->sharable ){ + return SQLITE_OK; + } + + /* If some other connection is holding an exclusive lock, the + ** requested lock may not be obtained. + */ + if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ + sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); + return SQLITE_LOCKED_SHAREDCACHE; + } + + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + /* The condition (pIter->eLock!=eLock) in the following if(...) + ** statement is a simplification of: + ** + ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) + ** + ** since we know that if eLock==WRITE_LOCK, then no other connection + ** may hold a WRITE_LOCK on any table in this file (since there can + ** only be a single writer). + */ + assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); + assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); + if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ + sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); + if( eLock==WRITE_LOCK ){ + assert( p==pBt->pWriter ); + pBt->btsFlags |= BTS_PENDING; + } + return SQLITE_LOCKED_SHAREDCACHE; + } + } + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Add a lock on the table with root-page iTable to the shared-btree used +** by Btree handle p. Parameter eLock must be either READ_LOCK or +** WRITE_LOCK. +** +** This function assumes the following: +** +** (a) The specified Btree object p is connected to a sharable +** database (one with the BtShared.sharable flag set), and +** +** (b) No other Btree objects hold a lock that conflicts +** with the requested lock (i.e. querySharedCacheTableLock() has +** already been called and returned SQLITE_OK). +** +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** is returned if a malloc attempt fails. +*/ +static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pLock = 0; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + + /* A connection with the read-uncommitted flag set will never try to + ** obtain a read-lock using this function. The only read-lock obtained + ** by a connection in read-uncommitted mode is on the sqlite_schema + ** table, and that lock is obtained in BtreeBeginTrans(). */ + assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK ); + + /* This function should only be called on a sharable b-tree after it + ** has been determined that no other b-tree holds a conflicting lock. */ + assert( p->sharable ); + assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); + + /* First search the list for an existing lock on this table. */ + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->iTable==iTable && pIter->pBtree==p ){ + pLock = pIter; + break; + } + } + + /* If the above search did not find a BtLock struct associating Btree p + ** with table iTable, allocate one and link it into the list. + */ + if( !pLock ){ + pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); + if( !pLock ){ + return SQLITE_NOMEM_BKPT; + } + pLock->iTable = iTable; + pLock->pBtree = p; + pLock->pNext = pBt->pLock; + pBt->pLock = pLock; + } + + /* Set the BtLock.eLock variable to the maximum of the current lock + ** and the requested lock. This means if a write-lock was already held + ** and a read-lock requested, we don't incorrectly downgrade the lock. + */ + assert( WRITE_LOCK>READ_LOCK ); + if( eLock>pLock->eLock ){ + pLock->eLock = eLock; + } + + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Release all the table locks (locks obtained via calls to +** the setSharedCacheTableLock() procedure) held by Btree object p. +** +** This function assumes that Btree p has an open read or write +** transaction. If it does not, then the BTS_PENDING flag +** may be incorrectly cleared. +*/ +static void clearAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + BtLock **ppIter = &pBt->pLock; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->sharable || 0==*ppIter ); + assert( p->inTrans>0 ); + + while( *ppIter ){ + BtLock *pLock = *ppIter; + assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); + assert( pLock->pBtree->inTrans>=pLock->eLock ); + if( pLock->pBtree==p ){ + *ppIter = pLock->pNext; + assert( pLock->iTable!=1 || pLock==&p->lock ); + if( pLock->iTable!=1 ){ + sqlite3_free(pLock); + } + }else{ + ppIter = &pLock->pNext; + } + } + + assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter ); + if( pBt->pWriter==p ){ + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + }else if( pBt->nTransaction==2 ){ + /* This function is called when Btree p is concluding its + ** transaction. If there currently exists a writer, and p is not + ** that writer, then the number of locks held by connections other + ** than the writer must be about to drop to zero. In this case + ** set the BTS_PENDING flag to 0. + ** + ** If there is not currently a writer, then BTS_PENDING must + ** be zero already. So this next line is harmless in that case. + */ + pBt->btsFlags &= ~BTS_PENDING; + } +} + +/* +** This function changes all write-locks held by Btree p into read-locks. +*/ +static void downgradeAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->pWriter==p ){ + BtLock *pLock; + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); + pLock->eLock = READ_LOCK; + } + } +} + +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +static void releasePage(MemPage *pPage); /* Forward reference */ +static void releasePageOne(MemPage *pPage); /* Forward reference */ +static void releasePageNotNull(MemPage *pPage); /* Forward reference */ + +/* +***** This routine is used inside of assert() only **** +** +** Verify that the cursor holds the mutex on its BtShared +*/ +#ifdef SQLITE_DEBUG +static int cursorHoldsMutex(BtCursor *p){ + return sqlite3_mutex_held(p->pBt->mutex); +} + +/* Verify that the cursor and the BtShared agree about what is the current +** database connetion. This is important in shared-cache mode. If the database +** connection pointers get out-of-sync, it is possible for routines like +** btreeInitPage() to reference an stale connection pointer that references a +** a connection that has already closed. This routine is used inside assert() +** statements only and for the purpose of double-checking that the btree code +** does keep the database connection pointers up-to-date. +*/ +static int cursorOwnsBtShared(BtCursor *p){ + assert( cursorHoldsMutex(p) ); + return (p->pBtree->db==p->pBt->db); +} +#endif + +/* +** Invalidate the overflow cache of the cursor passed as the first argument. +** on the shared btree structure pBt. +*/ +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) + +/* +** Invalidate the overflow page-list cache for all cursors opened +** on the shared btree structure pBt. +*/ +static void invalidateAllOverflowCache(BtShared *pBt){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + for(p=pBt->pCursor; p; p=p->pNext){ + invalidateOverflowCache(p); + } +} + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** This function is called before modifying the contents of a table +** to invalidate any incrblob cursors that are open on the +** row or one of the rows being modified. +** +** If argument isClearTable is true, then the entire contents of the +** table is about to be deleted. In this case invalidate all incrblob +** cursors open on any row within the table with root-page pgnoRoot. +** +** Otherwise, if argument isClearTable is false, then the row with +** rowid iRow is being replaced or deleted. In this case invalidate +** only those incrblob cursors open on that specific row. +*/ +static void invalidateIncrblobCursors( + Btree *pBtree, /* The database file to check */ + Pgno pgnoRoot, /* The table that might be changing */ + i64 iRow, /* The rowid that might be changing */ + int isClearTable /* True if all rows are being deleted */ +){ + BtCursor *p; + assert( pBtree->hasIncrblobCur ); + assert( sqlite3BtreeHoldsMutex(pBtree) ); + pBtree->hasIncrblobCur = 0; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( (p->curFlags & BTCF_Incrblob)!=0 ){ + pBtree->hasIncrblobCur = 1; + if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){ + p->eState = CURSOR_INVALID; + } + } + } +} + +#else + /* Stub function when INCRBLOB is omitted */ + #define invalidateIncrblobCursors(w,x,y,z) +#endif /* SQLITE_OMIT_INCRBLOB */ + +/* +** Set bit pgno of the BtShared.pHasContent bitvec. This is called +** when a page that previously contained data becomes a free-list leaf +** page. +** +** The BtShared.pHasContent bitvec exists to work around an obscure +** bug caused by the interaction of two useful IO optimizations surrounding +** free-list leaf pages: +** +** 1) When all data is deleted from a page and the page becomes +** a free-list leaf page, the page is not written to the database +** (as free-list leaf pages contain no meaningful data). Sometimes +** such a page is not even journalled (as it will not be modified, +** why bother journalling it?). +** +** 2) When a free-list leaf page is reused, its content is not read +** from the database or written to the journal file (why should it +** be, if it is not at all meaningful?). +** +** By themselves, these optimizations work fine and provide a handy +** performance boost to bulk delete or insert operations. However, if +** a page is moved to the free-list and then reused within the same +** transaction, a problem comes up. If the page is not journalled when +** it is moved to the free-list and it is also not journalled when it +** is extracted from the free-list and reused, then the original data +** may be lost. In the event of a rollback, it may not be possible +** to restore the database to its original configuration. +** +** The solution is the BtShared.pHasContent bitvec. Whenever a page is +** moved to become a free-list leaf page, the corresponding bit is +** set in the bitvec. Whenever a leaf page is extracted from the free-list, +** optimization 2 above is omitted if the corresponding bit is already +** set in BtShared.pHasContent. The contents of the bitvec are cleared +** at the end of every transaction. +*/ +static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ + int rc = SQLITE_OK; + if( !pBt->pHasContent ){ + assert( pgno<=pBt->nPage ); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); + if( !pBt->pHasContent ){ + rc = SQLITE_NOMEM_BKPT; + } + } + if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ + rc = sqlite3BitvecSet(pBt->pHasContent, pgno); + } + return rc; +} + +/* +** Query the BtShared.pHasContent vector. +** +** This function is called when a free-list leaf page is removed from the +** free-list for reuse. It returns false if it is safe to retrieve the +** page from the pager layer with the 'no-content' flag set. True otherwise. +*/ +static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ + Bitvec *p = pBt->pHasContent; + return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno)); +} + +/* +** Clear (destroy) the BtShared.pHasContent bitvec. This should be +** invoked at the conclusion of each write-transaction. +*/ +static void btreeClearHasContent(BtShared *pBt){ + sqlite3BitvecDestroy(pBt->pHasContent); + pBt->pHasContent = 0; +} + +/* +** Release all of the apPage[] pages for a cursor. +*/ +static void btreeReleaseAllCursorPages(BtCursor *pCur){ + int i; + if( pCur->iPage>=0 ){ + for(i=0; iiPage; i++){ + releasePageNotNull(pCur->apPage[i]); + } + releasePageNotNull(pCur->pPage); + pCur->iPage = -1; + } +} + +/* +** The cursor passed as the only argument must point to a valid entry +** when this function is called (i.e. have eState==CURSOR_VALID). This +** function saves the current cursor key in variables pCur->nKey and +** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error +** code otherwise. +** +** If the cursor is open on an intkey table, then the integer key +** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to +** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is +** set to point to a malloced buffer pCur->nKey bytes in size containing +** the key. +*/ +static int saveCursorKey(BtCursor *pCur){ + int rc = SQLITE_OK; + assert( CURSOR_VALID==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->curIntKey ){ + /* Only the rowid is required for a table btree */ + pCur->nKey = sqlite3BtreeIntegerKey(pCur); + }else{ + /* For an index btree, save the complete key content. It is possible + ** that the current key is corrupt. In that case, it is possible that + ** the sqlite3VdbeRecordUnpack() function may overread the buffer by + ** up to the size of 1 varint plus 1 8-byte value when the cursor + ** position is restored. Hence the 17 bytes of padding allocated + ** below. */ + void *pKey; + pCur->nKey = sqlite3BtreePayloadSize(pCur); + pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); + if( pKey ){ + rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); + if( rc==SQLITE_OK ){ + memset(((u8*)pKey)+pCur->nKey, 0, 9+8); + pCur->pKey = pKey; + }else{ + sqlite3_free(pKey); + } + }else{ + rc = SQLITE_NOMEM_BKPT; + } + } + assert( !pCur->curIntKey || !pCur->pKey ); + return rc; +} + +/* +** Save the current cursor position in the variables BtCursor.nKey +** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. +** +** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) +** prior to calling this routine. +*/ +static int saveCursorPosition(BtCursor *pCur){ + int rc; + + assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->curFlags & BTCF_Pinned ){ + return SQLITE_CONSTRAINT_PINNED; + } + if( pCur->eState==CURSOR_SKIPNEXT ){ + pCur->eState = CURSOR_VALID; + }else{ + pCur->skipNext = 0; + } + + rc = saveCursorKey(pCur); + if( rc==SQLITE_OK ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = CURSOR_REQUIRESEEK; + } + + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast); + return rc; +} + +/* Forward reference */ +static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*); + +/* +** Save the positions of all cursors (except pExcept) that are open on +** the table with root-page iRoot. "Saving the cursor position" means that +** the location in the btree is remembered in such a way that it can be +** moved back to the same spot after the btree has been modified. This +** routine is called just before cursor pExcept is used to modify the +** table, for example in BtreeDelete() or BtreeInsert(). +** +** If there are two or more cursors on the same btree, then all such +** cursors should have their BTCF_Multiple flag set. The btreeCursor() +** routine enforces that rule. This routine only needs to be called in +** the uncommon case when pExpect has the BTCF_Multiple flag set. +** +** If pExpect!=NULL and if no other cursors are found on the same root-page, +** then the BTCF_Multiple flag on pExpect is cleared, to avoid another +** pointless call to this routine. +** +** Implementation note: This routine merely checks to see if any cursors +** need to be saved. It calls out to saveCursorsOnList() in the (unusual) +** event that cursors are in need to being saved. +*/ +static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pExcept==0 || pExcept->pBt==pBt ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; + } + if( p ) return saveCursorsOnList(p, iRoot, pExcept); + if( pExcept ) pExcept->curFlags &= ~BTCF_Multiple; + return SQLITE_OK; +} + +/* This helper routine to saveAllCursors does the actual work of saving +** the cursors if and when a cursor is found that actually requires saving. +** The common case is that no cursors need to be saved, so this routine is +** broken out from its caller to avoid unnecessary stack pointer movement. +*/ +static int SQLITE_NOINLINE saveCursorsOnList( + BtCursor *p, /* The first cursor that needs saving */ + Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */ + BtCursor *pExcept /* Do not save this cursor */ +){ + do{ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ + int rc = saveCursorPosition(p); + if( SQLITE_OK!=rc ){ + return rc; + } + }else{ + testcase( p->iPage>=0 ); + btreeReleaseAllCursorPages(p); + } + } + p = p->pNext; + }while( p ); + return SQLITE_OK; +} + +/* +** Clear the current cursor position. +*/ +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + pCur->eState = CURSOR_INVALID; +} + +/* +** In this version of BtreeMoveto, pKey is a packed index record +** such as is generated by the OP_MakeRecord opcode. Unpack the +** record and then call sqlite3BtreeIndexMoveto() to do the work. +*/ +static int btreeMoveto( + BtCursor *pCur, /* Cursor open on the btree to be searched */ + const void *pKey, /* Packed key if the btree is an index */ + i64 nKey, /* Integer key for tables. Size of pKey for indices */ + int bias, /* Bias search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; /* Status code */ + UnpackedRecord *pIdxKey; /* Unpacked index key */ + + if( pKey ){ + KeyInfo *pKeyInfo = pCur->pKeyInfo; + assert( nKey==(i64)(int)nKey ); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; + sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); + if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); + } + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); + }else{ + pIdxKey = 0; + rc = sqlite3BtreeTableMoveto(pCur, nKey, bias, pRes); + } + return rc; +} + +/* +** Restore the cursor to the position it was in (or as close to as possible) +** when saveCursorPosition() was called. Note that this call deletes the +** saved position info stored by saveCursorPosition(), so there can be +** at most one effective restoreCursorPosition() call after each +** saveCursorPosition(). +*/ +static int btreeRestoreCursorPosition(BtCursor *pCur){ + int rc; + int skipNext = 0; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState>=CURSOR_REQUIRESEEK ); + if( pCur->eState==CURSOR_FAULT ){ + return pCur->skipNext; + } + pCur->eState = CURSOR_INVALID; + if( sqlite3FaultSim(410) ){ + rc = SQLITE_IOERR; + }else{ + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); + } + if( rc==SQLITE_OK ){ + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); + if( skipNext ) pCur->skipNext = skipNext; + if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ + pCur->eState = CURSOR_SKIPNEXT; + } + } + return rc; +} + +#define restoreCursorPosition(p) \ + (p->eState>=CURSOR_REQUIRESEEK ? \ + btreeRestoreCursorPosition(p) : \ + SQLITE_OK) + +/* +** Determine whether or not a cursor has moved from the position where +** it was last placed, or has been invalidated for any other reason. +** Cursors can move when the row they are pointing at is deleted out +** from under them, for example. Cursor might also move if a btree +** is rebalanced. +** +** Calling this routine with a NULL cursor pointer returns false. +** +** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor +** back to where it ought to be if this routine returns true. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ + assert( EIGHT_BYTE_ALIGNMENT(pCur) + || pCur==sqlite3BtreeFakeValidCursor() ); + assert( offsetof(BtCursor, eState)==0 ); + assert( sizeof(pCur->eState)==1 ); + return CURSOR_VALID != *(u8*)pCur; +} + +/* +** Return a pointer to a fake BtCursor object that will always answer +** false to the sqlite3BtreeCursorHasMoved() routine above. The fake +** cursor returned must not be used with any other Btree interface. +*/ +SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){ + static u8 fakeCursor = CURSOR_VALID; + assert( offsetof(BtCursor, eState)==0 ); + return (BtCursor*)&fakeCursor; +} + +/* +** This routine restores a cursor back to its original position after it +** has been moved by some outside activity (such as a btree rebalance or +** a row having been deleted out from under the cursor). +** +** On success, the *pDifferentRow parameter is false if the cursor is left +** pointing at exactly the same row. *pDifferntRow is the row the cursor +** was pointing to has been deleted, forcing the cursor to point to some +** nearby row. +** +** This routine should only be called for a cursor that just returned +** TRUE from sqlite3BtreeCursorHasMoved(). +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ + int rc; + + assert( pCur!=0 ); + assert( pCur->eState!=CURSOR_VALID ); + rc = restoreCursorPosition(pCur); + if( rc ){ + *pDifferentRow = 1; + return rc; + } + if( pCur->eState!=CURSOR_VALID ){ + *pDifferentRow = 1; + }else{ + *pDifferentRow = 0; + } + return SQLITE_OK; +} + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Provide hints to the cursor. The particular hint given (and the type +** and number of the varargs parameters) is determined by the eHintType +** parameter. See the definitions of the BTREE_HINT_* macros for details. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ + /* Used only by system that substitute their own storage engine */ +#ifdef SQLITE_DEBUG + if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ + va_list ap; + Expr *pExpr; + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3CursorRangeHintExprCheck; + va_start(ap, eHintType); + pExpr = va_arg(ap, Expr*); + w.u.aMem = va_arg(ap, Mem*); + va_end(ap); + assert( pExpr!=0 ); + assert( w.u.aMem!=0 ); + sqlite3WalkExpr(&w, pExpr); + } +#endif /* SQLITE_DEBUG */ +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + + +/* +** Provide flag hints to the cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ + assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); + pCur->hints = x; +} + + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Given a page number of a regular database page, return the page +** number for the pointer-map page that contains the entry for the +** input page number. +** +** Return 0 (not a valid page) for pgno==1 since there is +** no pointer map associated with page 1. The integrity_check logic +** requires that ptrmapPageno(*,1)!=1. +*/ +static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ + int nPagesPerMapPage; + Pgno iPtrMap, ret; + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno<2 ) return 0; + nPagesPerMapPage = (pBt->usableSize/5)+1; + iPtrMap = (pgno-2)/nPagesPerMapPage; + ret = (iPtrMap*nPagesPerMapPage) + 2; + if( ret==PENDING_BYTE_PAGE(pBt) ){ + ret++; + } + return ret; +} + +/* +** Write an entry into the pointer map. +** +** This routine updates the pointer map entry for page number 'key' +** so that it maps to type 'eType' and parent page number 'pgno'. +** +** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is +** a no-op. If an error occurs, the appropriate error code is written +** into *pRC. +*/ +static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ + DbPage *pDbPage; /* The pointer map page */ + u8 *pPtrmap; /* The pointer map data */ + Pgno iPtrmap; /* The pointer map page number */ + int offset; /* Offset in pointer map page */ + int rc; /* Return code from subfunctions */ + + if( *pRC ) return; + + assert( sqlite3_mutex_held(pBt->mutex) ); + /* The super-journal page number must never be used as a pointer map page */ + assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); + + assert( pBt->autoVacuum ); + if( key==0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){ + /* The first byte of the extra data is the MemPage.isInit byte. + ** If that byte is set, it means this page is also being used + ** as a btree page. */ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } + assert( offset <= (int)pBt->usableSize-5 ); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ + TRACE(("PTRMAP_UPDATE: %u->(%u,%u)\n", key, eType, parent)); + *pRC= rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + pPtrmap[offset] = eType; + put4byte(&pPtrmap[offset+1], parent); + } + } + +ptrmap_exit: + sqlite3PagerUnref(pDbPage); +} + +/* +** Read an entry from the pointer map. +** +** This routine retrieves the pointer map entry for page 'key', writing +** the type and parent page number to *pEType and *pPgno respectively. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ + DbPage *pDbPage; /* The pointer map page */ + int iPtrmap; /* Pointer map page index */ + u8 *pPtrmap; /* Pointer map page data */ + int offset; /* Offset of entry in pointer map */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + if( rc!=0 ){ + return rc; + } + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_BKPT; + } + assert( offset <= (int)pBt->usableSize-5 ); + assert( pEType!=0 ); + *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); + + sqlite3PagerUnref(pDbPage); + if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap); + return SQLITE_OK; +} + +#else /* if defined SQLITE_OMIT_AUTOVACUUM */ + #define ptrmapPut(w,x,y,z,rc) + #define ptrmapGet(w,x,y,z) SQLITE_OK + #define ptrmapPutOvflPtr(x, y, z, rc) +#endif + +/* +** Given a btree page and a cell index (0 means the first cell on +** the page, 1 means the second cell, and so forth) return a pointer +** to the cell content. +** +** findCellPastPtr() does the same except it skips past the initial +** 4-byte child pointer found on interior pages, if there is one. +** +** This routine works only for pages that do not contain overflow cells. +*/ +#define findCell(P,I) \ + ((P)->aData + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) +#define findCellPastPtr(P,I) \ + ((P)->aDataOfst + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) + + +/* +** This is common tail processing for btreeParseCellPtr() and +** btreeParseCellPtrIndex() for the case when the cell does not fit entirely +** on a single B-tree page. Make necessary adjustments to the CellInfo +** structure. +*/ +static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + /* If the payload will not fit completely on the local page, we have + ** to decide how much to store locally and how much to spill onto + ** overflow pages. The strategy is to minimize the amount of unused + ** space on overflow pages while keeping the amount of local storage + ** in between minLocal and maxLocal. + ** + ** Warning: changing the way overflow payload is distributed in any + ** way will result in an incompatible file format. + */ + int minLocal; /* Minimum amount of payload held locally */ + int maxLocal; /* Maximum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + + minLocal = pPage->minLocal; + maxLocal = pPage->maxLocal; + surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4); + testcase( surplus==maxLocal ); + testcase( surplus==maxLocal+1 ); + if( surplus <= maxLocal ){ + pInfo->nLocal = (u16)surplus; + }else{ + pInfo->nLocal = (u16)minLocal; + } + pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; +} + +/* +** Given a record with nPayload bytes of payload stored within btree +** page pPage, return the number of bytes of payload stored locally. +*/ +static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ + int maxLocal; /* Maximum amount of payload held locally */ + maxLocal = pPage->maxLocal; + if( nPayload<=maxLocal ){ + return nPayload; + }else{ + int minLocal; /* Minimum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + minLocal = pPage->minLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4); + return ( surplus <= maxLocal ) ? surplus : minLocal; + } +} + +/* +** The following routines are implementations of the MemPage.xParseCell() +** method. +** +** Parse a cell content block and fill in the CellInfo structure. +** +** btreeParseCellPtr() => table btree leaf nodes +** btreeParseCellNoPayload() => table btree internal nodes +** btreeParseCellPtrIndex() => index btree nodes +** +** There is also a wrapper function btreeParseCell() that works for +** all MemPage types and that references the cell by index rather than +** by pointer. +*/ +static void btreeParseCellPtrNoPayload( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 ); + assert( pPage->childPtrSize==4 ); +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER(pPage); +#endif + pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey); + pInfo->nPayload = 0; + pInfo->nLocal = 0; + pInfo->pPayload = 0; + return; +} +static void btreeParseCellPtr( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + u8 *pIter; /* For scanning through pCell */ + u32 nPayload; /* Number of bytes of cell payload */ + u64 iKey; /* Extracted Key value */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + assert( pPage->intKeyLeaf ); + assert( pPage->childPtrSize==0 ); + pIter = pCell; + + /* The next block of code is equivalent to: + ** + ** pIter += getVarint32(pIter, nPayload); + ** + ** The code is inlined to avoid a function call. + */ + nPayload = *pIter; + if( nPayload>=0x80 ){ + u8 *pEnd = &pIter[8]; + nPayload &= 0x7f; + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( (*pIter)>=0x80 && pIternKey); + ** + ** The code is inlined and the loop is unrolled for performance. + ** This routine is a high-runner. + */ + iKey = *pIter; + if( iKey>=0x80 ){ + u8 x; + iKey = (iKey<<7) ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<8) ^ 0x8000 ^ (*++pIter); + } + } + } + } + } + }else{ + iKey ^= 0x204000; + } + }else{ + iKey ^= 0x4000; + } + } + pIter++; + + pInfo->nKey = *(i64*)&iKey; + pInfo->nPayload = nPayload; + pInfo->pPayload = pIter; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); + if( nPayload<=pPage->maxLocal ){ + /* This is the (easy) common case where the entire payload fits + ** on the local page. No overflow is required. + */ + pInfo->nSize = nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + }else{ + btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); + } +} +static void btreeParseCellPtrIndex( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + u8 *pIter; /* For scanning through pCell */ + u32 nPayload; /* Number of bytes of cell payload */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + assert( pPage->intKeyLeaf==0 ); + pIter = pCell + pPage->childPtrSize; + nPayload = *pIter; + if( nPayload>=0x80 ){ + u8 *pEnd = &pIter[8]; + nPayload &= 0x7f; + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIternKey = nPayload; + pInfo->nPayload = nPayload; + pInfo->pPayload = pIter; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); + if( nPayload<=pPage->maxLocal ){ + /* This is the (easy) common case where the entire payload fits + ** on the local page. No overflow is required. + */ + pInfo->nSize = nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + }else{ + btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); + } +} +static void btreeParseCell( + MemPage *pPage, /* Page containing the cell */ + int iCell, /* The cell index. First cell is 0 */ + CellInfo *pInfo /* Fill in this structure */ +){ + pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo); +} + +/* +** The following routines are implementations of the MemPage.xCellSize +** method. +** +** Compute the total number of bytes that a Cell needs in the cell +** data area of the btree-page. The return number includes the cell +** data header and the local payload, but not any overflow page or +** the space used by the cell pointer. +** +** cellSizePtrNoPayload() => table internal nodes +** cellSizePtrTableLeaf() => table leaf nodes +** cellSizePtr() => index internal nodes +** cellSizeIdxLeaf() => index leaf nodes +*/ +static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + pPage->xParseCell(pPage, pCell, &debuginfo); +#endif + + assert( pPage->childPtrSize==4 ); + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pItermaxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + assert( nSize>4 ); + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} +static u16 cellSizePtrIdxLeaf(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + pPage->xParseCell(pPage, pCell, &debuginfo); +#endif + + assert( pPage->childPtrSize==0 ); + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pItermaxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} +static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + pPage->xParseCell(pPage, pCell, &debuginfo); +#else + UNUSED_PARAMETER(pPage); +#endif + + assert( pPage->childPtrSize==4 ); + pEnd = pIter + 9; + while( (*pIter++)&0x80 && pIterxParseCell(pPage, pCell, &debuginfo); +#endif + + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pItermaxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} + + +#ifdef SQLITE_DEBUG +/* This variation on cellSizePtr() is used inside of assert() statements +** only. */ +static u16 cellSize(MemPage *pPage, int iCell){ + return pPage->xCellSize(pPage, findCell(pPage, iCell)); +} +#endif + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** The cell pCell is currently part of page pSrc but will ultimately be part +** of pPage. (pSrc and pPage are often the same.) If pCell contains a +** pointer to an overflow page, insert an entry into the pointer-map for +** the overflow page that will be valid after pCell has been moved to pPage. +*/ +static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ + CellInfo info; + if( *pRC ) return; + assert( pCell!=0 ); + pPage->xParseCell(pPage, pCell, &info); + if( info.nLocalaDataEnd, pCell, pCell+info.nLocal) ){ + testcase( pSrc!=pPage ); + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + ovfl = get4byte(&pCell[info.nSize-4]); + ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); + } +} +#endif + + +/* +** Defragment the page given. This routine reorganizes cells within the +** page so that there are no free-blocks on the free-block list. +** +** Parameter nMaxFrag is the maximum amount of fragmented space that may be +** present in the page after this routine returns. +** +** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a +** b-tree page so that there are no freeblocks or fragment bytes, all +** unused bytes are contained in the unallocated space region, and all +** cells are packed tightly at the end of the page. +*/ +static int defragmentPage(MemPage *pPage, int nMaxFrag){ + int i; /* Loop counter */ + int pc; /* Address of the i-th cell */ + int hdr; /* Offset to the page header */ + int size; /* Size of a cell */ + int usableSize; /* Number of usable bytes on a page */ + int cellOffset; /* Offset to the cell pointer array */ + int cbrk; /* Offset to the cell content area */ + int nCell; /* Number of cells on the page */ + unsigned char *data; /* The page data */ + unsigned char *temp; /* Temp area for cell content */ + unsigned char *src; /* Source of content */ + int iCellFirst; /* First allowable cell index */ + int iCellLast; /* Last possible cell index */ + int iCellStart; /* First cell offset in input */ + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt!=0 ); + assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); + assert( pPage->nOverflow==0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + data = pPage->aData; + hdr = pPage->hdrOffset; + cellOffset = pPage->cellOffset; + nCell = pPage->nCell; + assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB ); + iCellFirst = cellOffset + 2*nCell; + usableSize = pPage->pBt->usableSize; + + /* This block handles pages with two or fewer free blocks and nMaxFrag + ** or fewer fragmented bytes. In this case it is faster to move the + ** two (or one) blocks of cells using memmove() and add the required + ** offsets to each pointer in the cell-pointer array than it is to + ** reconstruct the entire page. */ + if( (int)data[hdr+7]<=nMaxFrag ){ + int iFree = get2byte(&data[hdr+1]); + if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage); + if( iFree ){ + int iFree2 = get2byte(&data[iFree]); + if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage); + if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ + u8 *pEnd = &data[cellOffset + nCell*2]; + u8 *pAddr; + int sz2 = 0; + int sz = get2byte(&data[iFree+2]); + int top = get2byte(&data[hdr+5]); + if( top>=iFree ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( iFree2 ){ + if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage); + sz2 = get2byte(&data[iFree2+2]); + if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); + memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); + sz += sz2; + }else if( iFree+sz>usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + + cbrk = top+sz; + assert( cbrk+(iFree-top) <= usableSize ); + memmove(&data[cbrk], &data[top], iFree-top); + for(pAddr=&data[cellOffset]; pAddr0 ){ + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + memcpy(temp, data, usableSize); + src = temp; + for(i=0; iiCellLast ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( pc>=0 && pc<=iCellLast ); + size = pPage->xCellSize(pPage, &src[pc]); + cbrk -= size; + if( cbrkusableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cbrk+size<=usableSize && cbrk>=iCellStart ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); + put2byte(pAddr, cbrk); + memcpy(&data[cbrk], &src[pc], size); + } + } + data[hdr+7] = 0; + +defragment_out: + assert( pPage->nFree>=0 ); + if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cbrk>=iCellFirst ); + put2byte(&data[hdr+5], cbrk); + data[hdr+1] = 0; + data[hdr+2] = 0; + memset(&data[iCellFirst], 0, cbrk-iCellFirst); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + return SQLITE_OK; +} + +/* +** Search the free-list on page pPg for space to store a cell nByte bytes in +** size. If one can be found, return a pointer to the space and remove it +** from the free-list. +** +** If no suitable space can be found on the free-list, return NULL. +** +** This function may detect corruption within pPg. If corruption is +** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned. +** +** Slots on the free list that are between 1 and 3 bytes larger than nByte +** will be ignored if adding the extra space to the fragmentation count +** causes the fragmentation count to exceed 60. +*/ +static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ + const int hdr = pPg->hdrOffset; /* Offset to page header */ + u8 * const aData = pPg->aData; /* Page data */ + int iAddr = hdr + 1; /* Address of ptr to pc */ + u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */ + int pc = get2byte(pTmp); /* Address of a free slot */ + int x; /* Excess size of the slot */ + int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */ + int size; /* Size of the free slot */ + + assert( pc>0 ); + while( pc<=maxPC ){ + /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each + ** freeblock form a big-endian integer which is the size of the freeblock + ** in bytes, including the 4-byte header. */ + pTmp = &aData[pc+2]; + size = get2byte(pTmp); + if( (x = size - nByte)>=0 ){ + testcase( x==4 ); + testcase( x==3 ); + if( x<4 ){ + /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total + ** number of bytes in fragments may not exceed 60. */ + if( aData[hdr+7]>57 ) return 0; + + /* Remove the slot from the free-list. Update the number of + ** fragmented bytes within the page. */ + memcpy(&aData[iAddr], &aData[pc], 2); + aData[hdr+7] += (u8)x; + return &aData[pc]; + }else if( x+pc > maxPC ){ + /* This slot extends off the end of the usable part of the page */ + *pRc = SQLITE_CORRUPT_PAGE(pPg); + return 0; + }else{ + /* The slot remains on the free-list. Reduce its size to account + ** for the portion used by the new allocation. */ + put2byte(&aData[pc+2], x); + } + return &aData[pc + x]; + } + iAddr = pc; + pTmp = &aData[pc]; + pc = get2byte(pTmp); + if( pc<=iAddr ){ + if( pc ){ + /* The next slot in the chain comes before the current slot */ + *pRc = SQLITE_CORRUPT_PAGE(pPg); + } + return 0; + } + } + if( pc>maxPC+nByte-4 ){ + /* The free slot chain extends off the end of the page */ + *pRc = SQLITE_CORRUPT_PAGE(pPg); + } + return 0; +} + +/* +** Allocate nByte bytes of space from within the B-Tree page passed +** as the first argument. Write into *pIdx the index into pPage->aData[] +** of the first byte of allocated space. Return either SQLITE_OK or +** an error code (usually SQLITE_CORRUPT). +** +** The caller guarantees that there is sufficient space to make the +** allocation. This routine might need to defragment in order to bring +** all the space together, however. This routine will avoid using +** the first two bytes past the cell pointer area since presumably this +** allocation is being made in order to insert a new cell, so we will +** also end up needing a new cell pointer. +*/ +static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ + const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ + u8 * const data = pPage->aData; /* Local cache of pPage->aData */ + int top; /* First byte of cell content area */ + int rc = SQLITE_OK; /* Integer return code */ + u8 *pTmp; /* Temp ptr into data[] */ + int gap; /* First byte of gap between cell pointers and cell content */ + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( nByte>=0 ); /* Minimum cell size is 4 */ + assert( pPage->nFree>=nByte ); + assert( pPage->nOverflow==0 ); + assert( nByte < (int)(pPage->pBt->usableSize-8) ); + + assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); + gap = pPage->cellOffset + 2*pPage->nCell; + assert( gap<=65536 ); + /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size + ** and the reserved space is zero (the usual value for reserved space) + ** then the cell content offset of an empty page wants to be 65536. + ** However, that integer is too large to be stored in a 2-byte unsigned + ** integer, so a value of 0 is used in its place. */ + pTmp = &data[hdr+5]; + top = get2byte(pTmp); + if( gap>top ){ + if( top==0 && pPage->pBt->usableSize==65536 ){ + top = 65536; + }else{ + return SQLITE_CORRUPT_PAGE(pPage); + } + }else if( top>(int)pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + + /* If there is enough space between gap and top for one more cell pointer, + ** and if the freelist is not empty, then search the + ** freelist looking for a slot big enough to satisfy the request. + */ + testcase( gap+2==top ); + testcase( gap+1==top ); + testcase( gap==top ); + if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ + u8 *pSpace = pageFindSlot(pPage, nByte, &rc); + if( pSpace ){ + int g2; + assert( pSpace+nByte<=data+pPage->pBt->usableSize ); + *pIdx = g2 = (int)(pSpace-data); + if( g2<=gap ){ + return SQLITE_CORRUPT_PAGE(pPage); + }else{ + return SQLITE_OK; + } + }else if( rc ){ + return rc; + } + } + + /* The request could not be fulfilled using a freelist slot. Check + ** to see if defragmentation is necessary. + */ + testcase( gap+2+nByte==top ); + if( gap+2+nByte>top ){ + assert( pPage->nCell>0 || CORRUPT_DB ); + assert( pPage->nFree>=0 ); + rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte))); + if( rc ) return rc; + top = get2byteNotZero(&data[hdr+5]); + assert( gap+2+nByte<=top ); + } + + + /* Allocate memory from the gap in between the cell pointer array + ** and the cell content area. The btreeComputeFreeSpace() call has already + ** validated the freelist. Given that the freelist is valid, there + ** is no way that the allocation can extend off the end of the page. + ** The assert() below verifies the previous sentence. + */ + top -= nByte; + put2byte(&data[hdr+5], top); + assert( top+nByte <= (int)pPage->pBt->usableSize ); + *pIdx = top; + return SQLITE_OK; +} + +/* +** Return a section of the pPage->aData to the freelist. +** The first byte of the new free block is pPage->aData[iStart] +** and the size of the block is iSize bytes. +** +** Adjacent freeblocks are coalesced. +** +** Even though the freeblock list was checked by btreeComputeFreeSpace(), +** that routine will not detect overlap between cells or freeblocks. Nor +** does it detect cells or freeblocks that encroach into the reserved bytes +** at the end of the page. So do additional corruption checks inside this +** routine and return SQLITE_CORRUPT if any problems are found. +*/ +static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ + u16 iPtr; /* Address of ptr to next freeblock */ + u16 iFreeBlk; /* Address of the next freeblock */ + u8 hdr; /* Page header size. 0 or 100 */ + u8 nFrag = 0; /* Reduction in fragmentation */ + u16 iOrigSize = iSize; /* Original value of iSize */ + u16 x; /* Offset to cell content area */ + u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ + unsigned char *data = pPage->aData; /* Page content */ + u8 *pTmp; /* Temporary ptr into data[] */ + + assert( pPage->pBt!=0 ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); + assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( iSize>=4 ); /* Minimum cell size is 4 */ + assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); + + /* The list of freeblocks must be in ascending order. Find the + ** spot on the list where iStart should be inserted. + */ + hdr = pPage->hdrOffset; + iPtr = hdr + 1; + if( data[iPtr+1]==0 && data[iPtr]==0 ){ + iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ + }else{ + while( (iFreeBlk = get2byte(&data[iPtr]))pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); + + /* At this point: + ** iFreeBlk: First freeblock after iStart, or zero if none + ** iPtr: The address of a pointer to iFreeBlk + ** + ** Check to see if iFreeBlk should be coalesced onto the end of iStart. + */ + if( iFreeBlk && iEnd+3>=iFreeBlk ){ + nFrag = iFreeBlk - iEnd; + if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); + iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); + if( iEnd > pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + iSize = iEnd - iStart; + iFreeBlk = get2byte(&data[iFreeBlk]); + } + + /* If iPtr is another freeblock (that is, if iPtr is not the freelist + ** pointer in the page header) then check to see if iStart should be + ** coalesced onto the end of iPtr. + */ + if( iPtr>hdr+1 ){ + int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); + if( iPtrEnd+3>=iStart ){ + if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage); + nFrag += iStart - iPtrEnd; + iSize = iEnd - iPtr; + iStart = iPtr; + } + } + if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); + data[hdr+7] -= nFrag; + } + pTmp = &data[hdr+5]; + x = get2byte(pTmp); + if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[iStart], 0, iSize); + } + if( iStart<=x ){ + /* The new freeblock is at the beginning of the cell content area, + ** so just extend the cell content area rather than create another + ** freelist entry */ + if( iStartnFree += iOrigSize; + return SQLITE_OK; +} + +/* +** Decode the flags byte (the first byte of the header) for a page +** and initialize fields of the MemPage structure accordingly. +** +** Only the following combinations are supported. Anything different +** indicates a corrupt database files: +** +** PTF_ZERODATA (0x02, 2) +** PTF_LEAFDATA | PTF_INTKEY (0x05, 5) +** PTF_ZERODATA | PTF_LEAF (0x0a, 10) +** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF (0x0d, 13) +*/ +static int decodeFlags(MemPage *pPage, int flagByte){ + BtShared *pBt; /* A copy of pPage->pBt */ + + assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pBt = pPage->pBt; + pPage->max1bytePayload = pBt->max1bytePayload; + if( flagByte>=(PTF_ZERODATA | PTF_LEAF) ){ + pPage->childPtrSize = 0; + pPage->leaf = 1; + if( flagByte==(PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF) ){ + pPage->intKeyLeaf = 1; + pPage->xCellSize = cellSizePtrTableLeaf; + pPage->xParseCell = btreeParseCellPtr; + pPage->intKey = 1; + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrIdxLeaf; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrIdxLeaf; + pPage->xParseCell = btreeParseCellPtrIndex; + return SQLITE_CORRUPT_PAGE(pPage); + } + }else{ + pPage->childPtrSize = 4; + pPage->leaf = 0; + if( flagByte==(PTF_ZERODATA) ){ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtr; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrNoPayload; + pPage->xParseCell = btreeParseCellPtrNoPayload; + pPage->intKey = 1; + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else{ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtr; + pPage->xParseCell = btreeParseCellPtrIndex; + return SQLITE_CORRUPT_PAGE(pPage); + } + } + return SQLITE_OK; +} + +/* +** Compute the amount of freespace on the page. In other words, fill +** in the pPage->nFree field. +*/ +static int btreeComputeFreeSpace(MemPage *pPage){ + int pc; /* Address of a freeblock within pPage->aData[] */ + u8 hdr; /* Offset to beginning of page header */ + u8 *data; /* Equal to pPage->aData */ + int usableSize; /* Amount of usable space on each page */ + int nFree; /* Number of unused bytes on the page */ + int top; /* First byte of the cell content area */ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ + + assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + assert( pPage->isInit==1 ); + assert( pPage->nFree<0 ); + + usableSize = pPage->pBt->usableSize; + hdr = pPage->hdrOffset; + data = pPage->aData; + /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates + ** the start of the cell content area. A zero value for this integer is + ** interpreted as 65536. */ + top = get2byteNotZero(&data[hdr+5]); + iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell; + iCellLast = usableSize - 4; + + /* Compute the total free space on the page + ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the + ** start of the first freeblock on the page, or is zero if there are no + ** freeblocks. */ + pc = get2byte(&data[hdr+1]); + nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ + if( pc>0 ){ + u32 next, size; + if( pciCellLast ){ + /* Freeblock off the end of the page */ + return SQLITE_CORRUPT_PAGE(pPage); + } + next = get2byte(&data[pc]); + size = get2byte(&data[pc+2]); + nFree = nFree + size; + if( next<=pc+size+3 ) break; + pc = next; + } + if( next>0 ){ + /* Freeblock not in ascending order */ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( pc+size>(unsigned int)usableSize ){ + /* Last freeblock extends past page end */ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + + /* At this point, nFree contains the sum of the offset to the start + ** of the cell-content area plus the number of free bytes within + ** the cell-content area. If this is greater than the usable-size + ** of the page, then the page must be corrupted. This check also + ** serves to verify that the offset to the start of the cell-content + ** area, according to the page header, lies within the page. + */ + if( nFree>usableSize || nFreenFree = (u16)(nFree - iCellFirst); + return SQLITE_OK; +} + +/* +** Do additional sanity check after btreeInitPage() if +** PRAGMA cell_size_check=ON +*/ +static SQLITE_NOINLINE int btreeCellSizeCheck(MemPage *pPage){ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ + int i; /* Index into the cell pointer array */ + int sz; /* Size of a cell */ + int pc; /* Address of a freeblock within pPage->aData[] */ + u8 *data; /* Equal to pPage->aData */ + int usableSize; /* Maximum usable space on the page */ + int cellOffset; /* Start of cell content area */ + + iCellFirst = pPage->cellOffset + 2*pPage->nCell; + usableSize = pPage->pBt->usableSize; + iCellLast = usableSize - 4; + data = pPage->aData; + cellOffset = pPage->cellOffset; + if( !pPage->leaf ) iCellLast--; + for(i=0; inCell; i++){ + pc = get2byteAligned(&data[cellOffset+i*2]); + testcase( pc==iCellFirst ); + testcase( pc==iCellLast ); + if( pciCellLast ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + sz = pPage->xCellSize(pPage, &data[pc]); + testcase( pc+sz==usableSize ); + if( pc+sz>usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + return SQLITE_OK; +} + +/* +** Initialize the auxiliary information for a disk block. +** +** Return SQLITE_OK on success. If we see that the page does +** not contain a well-formed database page, then return +** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not +** guarantee that the page is well-formed. It only shows that +** we failed to detect any corruption. +*/ +static int btreeInitPage(MemPage *pPage){ + u8 *data; /* Equal to pPage->aData */ + BtShared *pBt; /* The main btree structure */ + + assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + assert( pPage->isInit==0 ); + + pBt = pPage->pBt; + data = pPage->aData + pPage->hdrOffset; + /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating + ** the b-tree page type. */ + if( decodeFlags(pPage, data[0]) ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nOverflow = 0; + pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; + pPage->aCellIdx = data + pPage->childPtrSize + 8; + pPage->aDataEnd = pPage->aData + pBt->pageSize; + pPage->aDataOfst = pPage->aData + pPage->childPtrSize; + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ + pPage->nCell = get2byte(&data[3]); + if( pPage->nCell>MX_CELL(pBt) ){ + /* To many cells for a single page. The page must be corrupt */ + return SQLITE_CORRUPT_PAGE(pPage); + } + testcase( pPage->nCell==MX_CELL(pBt) ); + /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only + ** possible for a root page of a table that contains no rows) then the + ** offset to the cell content area will equal the page size minus the + ** bytes of reserved space. */ + assert( pPage->nCell>0 + || get2byteNotZero(&data[5])==(int)pBt->usableSize + || CORRUPT_DB ); + pPage->nFree = -1; /* Indicate that this value is yet uncomputed */ + pPage->isInit = 1; + if( pBt->db->flags & SQLITE_CellSizeCk ){ + return btreeCellSizeCheck(pPage); + } + return SQLITE_OK; +} + +/* +** Set up a raw page so that it looks like a database page holding +** no entries. +*/ +static void zeroPage(MemPage *pPage, int flags){ + unsigned char *data = pPage->aData; + BtShared *pBt = pPage->pBt; + u8 hdr = pPage->hdrOffset; + u16 first; + + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage) == data ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->btsFlags & BTS_FAST_SECURE ){ + memset(&data[hdr], 0, pBt->usableSize - hdr); + } + data[hdr] = (char)flags; + first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pBt->usableSize); + pPage->nFree = (u16)(pBt->usableSize - first); + decodeFlags(pPage, flags); + pPage->cellOffset = first; + pPage->aDataEnd = &data[pBt->pageSize]; + pPage->aCellIdx = &data[first]; + pPage->aDataOfst = &data[pPage->childPtrSize]; + pPage->nOverflow = 0; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nCell = 0; + pPage->isInit = 1; +} + + +/* +** Convert a DbPage obtained from the pager into a MemPage used by +** the btree layer. +*/ +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( pgno!=pPage->pgno ){ + pPage->aData = sqlite3PagerGetData(pDbPage); + pPage->pDbPage = pDbPage; + pPage->pBt = pBt; + pPage->pgno = pgno; + pPage->hdrOffset = pgno==1 ? 100 : 0; + } + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); + return pPage; +} + +/* +** Get a page from the pager. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. See also: btreeGetUnusedPage(). +** +** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care +** about the content of the page at this time. So do not go to the disk +** to fetch the content. Just fill in the content with zeros for now. +** If in the future we call sqlite3PagerWrite() on this page, that +** means we have started to be concerned about content and the disk +** read should occur at that point. +*/ +static int btreeGetPage( + BtShared *pBt, /* The btree */ + Pgno pgno, /* Number of the page to fetch */ + MemPage **ppPage, /* Return the page in this parameter */ + int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ +){ + int rc; + DbPage *pDbPage; + + assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY ); + assert( sqlite3_mutex_held(pBt->mutex) ); + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); + if( rc ) return rc; + *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); + return SQLITE_OK; +} + +/* +** Retrieve a page from the pager cache. If the requested page is not +** already in the pager cache return NULL. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. +*/ +static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ + DbPage *pDbPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); + if( pDbPage ){ + return btreePageFromDbPage(pDbPage, pgno, pBt); + } + return 0; +} + +/* +** Return the size of the database file in pages. If there is any kind of +** error, return ((unsigned int)-1). +*/ +static Pgno btreePagecount(BtShared *pBt){ + return pBt->nPage; +} +SQLITE_PRIVATE Pgno sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); + return btreePagecount(p->pBt); +} + +/* +** Get a page from the pager and initialize it. +*/ +static int getAndInitPage( + BtShared *pBt, /* The database file */ + Pgno pgno, /* Number of the page to get */ + MemPage **ppPage, /* Write the page pointer here */ + int bReadOnly /* True for a read-only page */ +){ + int rc; + DbPage *pDbPage; + MemPage *pPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + + if( pgno>btreePagecount(pBt) ){ + *ppPage = 0; + return SQLITE_CORRUPT_BKPT; + } + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); + if( rc ){ + *ppPage = 0; + return rc; + } + pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( pPage->isInit==0 ){ + btreePageFromDbPage(pDbPage, pgno, pBt); + rc = btreeInitPage(pPage); + if( rc!=SQLITE_OK ){ + releasePage(pPage); + *ppPage = 0; + return rc; + } + } + assert( pPage->pgno==pgno || CORRUPT_DB ); + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); + *ppPage = pPage; + return SQLITE_OK; +} + +/* +** Release a MemPage. This should be called once for each prior +** call to btreeGetPage. +** +** Page1 is a special case and must be released using releasePageOne(). +*/ +static void releasePageNotNull(MemPage *pPage){ + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefNotNull(pPage->pDbPage); +} +static void releasePage(MemPage *pPage){ + if( pPage ) releasePageNotNull(pPage); +} +static void releasePageOne(MemPage *pPage){ + assert( pPage!=0 ); + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefPageOne(pPage->pDbPage); +} + +/* +** Get an unused page. +** +** This works just like btreeGetPage() with the addition: +** +** * If the page is already in use for some other purpose, immediately +** release it and return an SQLITE_CURRUPT error. +** * Make sure the isInit flag is clear +*/ +static int btreeGetUnusedPage( + BtShared *pBt, /* The btree */ + Pgno pgno, /* Number of the page to fetch */ + MemPage **ppPage, /* Return the page in this parameter */ + int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ +){ + int rc = btreeGetPage(pBt, pgno, ppPage, flags); + if( rc==SQLITE_OK ){ + if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ + releasePage(*ppPage); + *ppPage = 0; + return SQLITE_CORRUPT_BKPT; + } + (*ppPage)->isInit = 0; + }else{ + *ppPage = 0; + } + return rc; +} + + +/* +** During a rollback, when the pager reloads information into the cache +** so that the cache is restored to its original state at the start of +** the transaction, for each page restored this routine is called. +** +** This routine needs to reset the extra data section at the end of the +** page to agree with the restored data. +*/ +static void pageReinit(DbPage *pData){ + MemPage *pPage; + pPage = (MemPage *)sqlite3PagerGetExtra(pData); + assert( sqlite3PagerPageRefcount(pData)>0 ); + if( pPage->isInit ){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->isInit = 0; + if( sqlite3PagerPageRefcount(pData)>1 ){ + /* pPage might not be a btree page; it might be an overflow page + ** or ptrmap page or a free page. In those cases, the following + ** call to btreeInitPage() will likely return SQLITE_CORRUPT. + ** But no harm is done by this. And it is very important that + ** btreeInitPage() be called on every btree page so we make + ** the call for every page that comes in for re-initializing. */ + btreeInitPage(pPage); + } + } +} + +/* +** Invoke the busy handler for a btree. +*/ +static int btreeInvokeBusyHandler(void *pArg){ + BtShared *pBt = (BtShared*)pArg; + assert( pBt->db ); + assert( sqlite3_mutex_held(pBt->db->mutex) ); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); +} + +/* +** Open a database file. +** +** zFilename is the name of the database file. If zFilename is NULL +** then an ephemeral database is created. The ephemeral database might +** be exclusively in memory, or it might use a disk-based memory cache. +** Either way, the ephemeral database will be automatically deleted +** when sqlite3BtreeClose() is called. +** +** If zFilename is ":memory:" then an in-memory database is created +** that is automatically destroyed when it is closed. +** +** The "flags" parameter is a bitmask that might contain bits like +** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY. +** +** If the database is already opened in the same database connection +** and we are in shared cache mode, then the open will fail with an +** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared +** objects in the same database connection since doing so will lead +** to problems with locking. +*/ +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ + const char *zFilename, /* Name of the file containing the BTree database */ + sqlite3 *db, /* Associated database handle */ + Btree **ppBtree, /* Pointer to new Btree object written here */ + int flags, /* Options */ + int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ +){ + BtShared *pBt = 0; /* Shared part of btree structure */ + Btree *p; /* Handle to return */ + sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ + int rc = SQLITE_OK; /* Result code from this function */ + u8 nReserve; /* Byte of unused space on each page */ + unsigned char zDbHeader[100]; /* Database header content */ + + /* True if opening an ephemeral, temporary database */ + const int isTempDb = zFilename==0 || zFilename[0]==0; + + /* Set the variable isMemdb to true for an in-memory database, or + ** false for a file-based database. + */ +#ifdef SQLITE_OMIT_MEMORYDB + const int isMemdb = 0; +#else + const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) + || (isTempDb && sqlite3TempInMemory(db)) + || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; +#endif + + assert( db!=0 ); + assert( pVfs!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ + + /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ + assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); + + /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ + assert( (flags & BTREE_SINGLE)==0 || isTempDb ); + + if( isMemdb ){ + flags |= BTREE_MEMORY; + } + if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ + vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; + } + p = sqlite3MallocZero(sizeof(Btree)); + if( !p ){ + return SQLITE_NOMEM_BKPT; + } + p->inTrans = TRANS_NONE; + p->db = db; +#ifndef SQLITE_OMIT_SHARED_CACHE + p->lock.pBtree = p; + p->lock.iTable = 1; +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* + ** If this Btree is a candidate for shared cache, try to find an + ** existing BtShared object that we can share with + */ + if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ + if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ + int nFilename = sqlite3Strlen30(zFilename)+1; + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename)); + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + + p->sharable = 1; + if( !zFullPathname ){ + sqlite3_free(p); + return SQLITE_NOMEM_BKPT; + } + if( isMemdb ){ + memcpy(zFullPathname, zFilename, nFilename); + }else{ + rc = sqlite3OsFullPathname(pVfs, zFilename, + nFullPathname, zFullPathname); + if( rc ){ + if( rc==SQLITE_OK_SYMLINK ){ + rc = SQLITE_OK; + }else{ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } + } + } +#if SQLITE_THREADSAFE + mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); + sqlite3_mutex_enter(mutexOpen); + mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); + sqlite3_mutex_enter(mutexShared); +#endif + for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ + assert( pBt->nRef>0 ); + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) + && sqlite3PagerVfs(pBt->pPager)==pVfs ){ + int iDb; + for(iDb=db->nDb-1; iDb>=0; iDb--){ + Btree *pExisting = db->aDb[iDb].pBt; + if( pExisting && pExisting->pBt==pBt ){ + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); + return SQLITE_CONSTRAINT; + } + } + p->pBt = pBt; + pBt->nRef++; + break; + } + } + sqlite3_mutex_leave(mutexShared); + sqlite3_free(zFullPathname); + } +#ifdef SQLITE_DEBUG + else{ + /* In debug mode, we mark all persistent databases as sharable + ** even when they are not. This exercises the locking code and + ** gives more opportunity for asserts(sqlite3_mutex_held()) + ** statements to find locking problems. + */ + p->sharable = 1; + } +#endif + } +#endif + if( pBt==0 ){ + /* + ** The following asserts make sure that structures used by the btree are + ** the right size. This is to guard against size changes that result + ** when compiling on a different architecture. + */ + assert( sizeof(i64)==8 ); + assert( sizeof(u64)==8 ); + assert( sizeof(u32)==4 ); + assert( sizeof(u16)==2 ); + assert( sizeof(Pgno)==4 ); + + /* Suppress false-positive compiler warning from PVS-Studio */ + memset(&zDbHeader[16], 0, 8); + + pBt = sqlite3MallocZero( sizeof(*pBt) ); + if( pBt==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto btree_open_out; + } + rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + sizeof(MemPage), flags, vfsFlags, pageReinit); + if( rc==SQLITE_OK ){ + sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); + rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + } + if( rc!=SQLITE_OK ){ + goto btree_open_out; + } + pBt->openFlags = (u8)flags; + pBt->db = db; + sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + p->pBt = pBt; + + pBt->pCursor = 0; + pBt->pPage1 = 0; + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; +#if defined(SQLITE_SECURE_DELETE) + pBt->btsFlags |= BTS_SECURE_DELETE; +#elif defined(SQLITE_FAST_SECURE_DELETE) + pBt->btsFlags |= BTS_OVERWRITE; +#endif + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); + if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE + || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ + pBt->pageSize = 0; +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the magic name ":memory:" will create an in-memory database, then + ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if + ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if + ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a + ** regular file-name. In this case the auto-vacuum applies as per normal. + */ + if( zFilename && !isMemdb ){ + pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0); + pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0); + } +#endif + nReserve = 0; + }else{ + /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ + nReserve = zDbHeader[20]; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); +#endif + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + if( rc ) goto btree_open_out; + pBt->usableSize = pBt->pageSize - nReserve; + assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* Add the new BtShared object to the linked list sharable BtShareds. + */ + pBt->nRef = 1; + if( p->sharable ){ + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);) + if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ + pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); + if( pBt->mutex==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto btree_open_out; + } + } + sqlite3_mutex_enter(mutexShared); + pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; + sqlite3_mutex_leave(mutexShared); + } +#endif + } + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* If the new Btree uses a sharable pBtShared, then link the new + ** Btree into the list of all sharable Btrees for the same connection. + ** The list is kept in ascending order by pBt address. + */ + if( p->sharable ){ + int i; + Btree *pSib; + for(i=0; inDb; i++){ + if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ + while( pSib->pPrev ){ pSib = pSib->pPrev; } + if( (uptr)p->pBt<(uptr)pSib->pBt ){ + p->pNext = pSib; + p->pPrev = 0; + pSib->pPrev = p; + }else{ + while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){ + pSib = pSib->pNext; + } + p->pNext = pSib->pNext; + p->pPrev = pSib; + if( p->pNext ){ + p->pNext->pPrev = p; + } + pSib->pNext = p; + } + break; + } + } + } +#endif + *ppBtree = p; + +btree_open_out: + if( rc!=SQLITE_OK ){ + if( pBt && pBt->pPager ){ + sqlite3PagerClose(pBt->pPager, 0); + } + sqlite3_free(pBt); + sqlite3_free(p); + *ppBtree = 0; + }else{ + sqlite3_file *pFile; + + /* If the B-Tree was successfully opened, set the pager-cache size to the + ** default value. Except, when opening on an existing shared pager-cache, + ** do not change the pager-cache size. + */ + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE); + } + + pFile = sqlite3PagerFile(pBt->pPager); + if( pFile->pMethods ){ + sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db); + } + } + if( mutexOpen ){ + assert( sqlite3_mutex_held(mutexOpen) ); + sqlite3_mutex_leave(mutexOpen); + } + assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 ); + return rc; +} + +/* +** Decrement the BtShared.nRef counter. When it reaches zero, +** remove the BtShared structure from the sharing list. Return +** true if the BtShared.nRef counter reaches zero and return +** false if it is still positive. +*/ +static int removeFromSharingList(BtShared *pBt){ +#ifndef SQLITE_OMIT_SHARED_CACHE + MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) + BtShared *pList; + int removed = 0; + + assert( sqlite3_mutex_notheld(pBt->mutex) ); + MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(pMainMtx); + pBt->nRef--; + if( pBt->nRef<=0 ){ + if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; + }else{ + pList = GLOBAL(BtShared*,sqlite3SharedCacheList); + while( ALWAYS(pList) && pList->pNext!=pBt ){ + pList=pList->pNext; + } + if( ALWAYS(pList) ){ + pList->pNext = pBt->pNext; + } + } + if( SQLITE_THREADSAFE ){ + sqlite3_mutex_free(pBt->mutex); + } + removed = 1; + } + sqlite3_mutex_leave(pMainMtx); + return removed; +#else + return 1; +#endif +} + +/* +** Make sure pBt->pTmpSpace points to an allocation of +** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child +** pointer. +*/ +static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ + assert( pBt!=0 ); + assert( pBt->pTmpSpace==0 ); + /* This routine is called only by btreeCursor() when allocating the + ** first write cursor for the BtShared object */ + assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 ); + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + if( pBt->pTmpSpace==0 ){ + BtCursor *pCur = pBt->pCursor; + pBt->pCursor = pCur->pNext; /* Unlink the cursor */ + memset(pCur, 0, sizeof(*pCur)); + return SQLITE_NOMEM_BKPT; + } + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of uninitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. + ** + ** Also: Provide four bytes of initialized space before the + ** beginning of pTmpSpace as an area available to prepend the + ** left-child pointer to the beginning of a cell. + */ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; + return SQLITE_OK; +} + +/* +** Free the pBt->pTmpSpace allocation +*/ +static void freeTempSpace(BtShared *pBt){ + if( pBt->pTmpSpace ){ + pBt->pTmpSpace -= 4; + sqlite3PageFree(pBt->pTmpSpace); + pBt->pTmpSpace = 0; + } +} + +/* +** Close an open database and invalidate all cursors. +*/ +SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ + BtShared *pBt = p->pBt; + + /* Close all cursors opened via this handle. */ + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + + /* Verify that no other cursors have this Btree open */ +#ifdef SQLITE_DEBUG + { + BtCursor *pCur = pBt->pCursor; + while( pCur ){ + BtCursor *pTmp = pCur; + pCur = pCur->pNext; + assert( pTmp->pBtree!=p ); + + } + } +#endif + + /* Rollback any active transaction and free the handle structure. + ** The call to sqlite3BtreeRollback() drops any table-locks held by + ** this handle. + */ + sqlite3BtreeRollback(p, SQLITE_OK, 0); + sqlite3BtreeLeave(p); + + /* If there are still other outstanding references to the shared-btree + ** structure, return now. The remainder of this procedure cleans + ** up the shared-btree. + */ + assert( p->wantToLock==0 && p->locked==0 ); + if( !p->sharable || removeFromSharingList(pBt) ){ + /* The pBt is no longer on the sharing list, so we can access + ** it without having to hold the mutex. + ** + ** Clean out and delete the BtShared object. + */ + assert( !pBt->pCursor ); + sqlite3PagerClose(pBt->pPager, p->db); + if( pBt->xFreeSchema && pBt->pSchema ){ + pBt->xFreeSchema(pBt->pSchema); + } + sqlite3DbFree(0, pBt->pSchema); + freeTempSpace(pBt); + sqlite3_free(pBt); + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( p->wantToLock==0 ); + assert( p->locked==0 ); + if( p->pPrev ) p->pPrev->pNext = p->pNext; + if( p->pNext ) p->pNext->pPrev = p->pPrev; +#endif + + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Change the "soft" limit on the number of pages in the cache. +** Unused and unmodified pages will be recycled when the number of +** pages in the cache exceeds this soft limit. But the size of the +** cache is allowed to grow larger than this limit if it contains +** dirty pages or pages still in active use. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetCachesize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Change the "spill" limit on the number of pages in the cache. +** If the number of pages exceeds this limit during a write transaction, +** the pager might attempt to "spill" pages to the journal early in +** order to free up memory. +** +** The value returned is the current spill size. If zero is passed +** as an argument, no changes are made to the spill size setting, so +** using mxPage of 0 is a way to query the current spill size. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + int res; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return res; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** Change the limit on the amount of the database file that may be +** memory mapped. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** Change the way data is synced to disk in order to increase or decrease +** how well the database resists damage due to OS crashes and power +** failures. Level 1 is the same as asynchronous (no syncs() occur and +** there is a high probability of damage) Level 2 is the default. There +** is a very low but non-zero probability of damage. Level 3 reduces the +** probability of damage to near zero but with a write performance reduction. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags( + Btree *p, /* The btree to set the safety level on */ + unsigned pgFlags /* Various PAGER_* flags */ +){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetFlags(pBt->pPager, pgFlags); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} +#endif + +/* +** Change the default pages size and the number of reserved bytes per page. +** Or, if the page size has already been fixed, return SQLITE_READONLY +** without changing anything. +** +** The page size must be a power of 2 between 512 and 65536. If the page +** size supplied does not meet this constraint then the page size is not +** changed. +** +** Page sizes are constrained to be a power of two so that the region +** of the database file used for locking (beginning at PENDING_BYTE, +** the first byte past the 1GB boundary, 0x40000000) needs to occur +** at the beginning of a page. +** +** If parameter nReserve is less than zero, then the number of reserved +** bytes per page is left unchanged. +** +** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size +** and autovacuum mode can no longer be changed. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ + int rc = SQLITE_OK; + int x; + BtShared *pBt = p->pBt; + assert( nReserve>=0 && nReserve<=255 ); + sqlite3BtreeEnter(p); + pBt->nReserveWanted = nReserve; + x = pBt->pageSize - pBt->usableSize; + if( nReservebtsFlags & BTS_PAGESIZE_FIXED ){ + sqlite3BtreeLeave(p); + return SQLITE_READONLY; + } + assert( nReserve>=0 && nReserve<=255 ); + if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && + ((pageSize-1)&pageSize)==0 ){ + assert( (pageSize & 7)==0 ); + assert( !pBt->pCursor ); + if( nReserve>32 && pageSize==512 ) pageSize = 1024; + pBt->pageSize = (u32)pageSize; + freeTempSpace(pBt); + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + pBt->usableSize = pBt->pageSize - (u16)nReserve; + if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Return the currently defined page size +*/ +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ + return p->pBt->pageSize; +} + +/* +** This function is similar to sqlite3BtreeGetReserve(), except that it +** may only be called if it is guaranteed that the b-tree mutex is already +** held. +** +** This is useful in one special case in the backup API code where it is +** known that the shared b-tree mutex is held, but the mutex on the +** database handle that owns *p is not. In this case if sqlite3BtreeEnter() +** were to be called, it might collide with some other operation on the +** database handle that owns *p, causing undefined behavior. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ + int n; + assert( sqlite3_mutex_held(p->pBt->mutex) ); + n = p->pBt->pageSize - p->pBt->usableSize; + return n; +} + +/* +** Return the number of bytes of space at the end of every page that +** are intentionally left unused. This is the "reserved" space that is +** sometimes used by extensions. +** +** The value returned is the larger of the current reserve size and +** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES. +** The amount of reserve can only grow - never shrink. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){ + int n1, n2; + sqlite3BtreeEnter(p); + n1 = (int)p->pBt->nReserveWanted; + n2 = sqlite3BtreeGetReserveNoMutex(p); + sqlite3BtreeLeave(p); + return n1>n2 ? n1 : n2; +} + + +/* +** Set the maximum page count for a database if mxPage is positive. +** No changes are made if mxPage is 0 or negative. +** Regardless of the value of mxPage, return the maximum page count. +*/ +SQLITE_PRIVATE Pgno sqlite3BtreeMaxPageCount(Btree *p, Pgno mxPage){ + Pgno n; + sqlite3BtreeEnter(p); + n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return n; +} + +/* +** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags: +** +** newFlag==0 Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared +** newFlag==1 BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared +** newFlag==2 BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set +** newFlag==(-1) No changes +** +** This routine acts as a query if newFlag is less than zero +** +** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but +** freelist leaf pages are not written back to the database. Thus in-page +** deleted content is cleared, but freelist deleted content is not. +** +** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition +** that freelist leaf pages are written back into the database, increasing +** the amount of disk I/O. +*/ +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ + int b; + if( p==0 ) return 0; + sqlite3BtreeEnter(p); + assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 ); + assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); + if( newFlag>=0 ){ + p->pBt->btsFlags &= ~BTS_FAST_SECURE; + p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag; + } + b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; + sqlite3BtreeLeave(p); + return b; +} + +/* +** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' +** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it +** is disabled. The default value for the auto-vacuum property is +** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return SQLITE_READONLY; +#else + BtShared *pBt = p->pBt; + int rc = SQLITE_OK; + u8 av = (u8)autoVacuum; + + sqlite3BtreeEnter(p); + if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ + rc = SQLITE_READONLY; + }else{ + pBt->autoVacuum = av ?1:0; + pBt->incrVacuum = av==2 ?1:0; + } + sqlite3BtreeLeave(p); + return rc; +#endif +} + +/* +** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** enabled 1 is returned. Otherwise 0. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return BTREE_AUTOVACUUM_NONE; +#else + int rc; + sqlite3BtreeEnter(p); + rc = ( + (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: + (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: + BTREE_AUTOVACUUM_INCR + ); + sqlite3BtreeLeave(p); + return rc; +#endif +} + +/* +** If the user has not set the safety-level for this database connection +** using "PRAGMA synchronous", and if the safety-level is not already +** set to the value passed to this function as the second parameter, +** set it so. +*/ +#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \ + && !defined(SQLITE_OMIT_WAL) +static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ + sqlite3 *db; + Db *pDb; + if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ + while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } + if( pDb->bSyncSet==0 + && pDb->safety_level!=safety_level + && pDb!=&db->aDb[1] + ){ + pDb->safety_level = safety_level; + sqlite3PagerSetFlags(pBt->pPager, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); + } + } +} +#else +# define setDefaultSyncFlag(pBt,safety_level) +#endif + +/* Forward declaration */ +static int newDatabase(BtShared*); + + +/* +** Get a reference to pPage1 of the database file. This will +** also acquire a readlock on that file. +** +** SQLITE_OK is returned on success. If the file is not a +** well-formed database file, then SQLITE_CORRUPT is returned. +** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM +** is returned if we run out of memory. +*/ +static int lockBtree(BtShared *pBt){ + int rc; /* Result code from subfunctions */ + MemPage *pPage1; /* Page 1 of the database file */ + u32 nPage; /* Number of pages in the database */ + u32 nPageFile = 0; /* Number of pages in the database file */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pBt->pPage1==0 ); + rc = sqlite3PagerSharedLock(pBt->pPager); + if( rc!=SQLITE_OK ) return rc; + rc = btreeGetPage(pBt, 1, &pPage1, 0); + if( rc!=SQLITE_OK ) return rc; + + /* Do some checking to help insure the file we opened really is + ** a valid database file. + */ + nPage = get4byte(28+(u8*)pPage1->aData); + sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); + if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ + nPage = nPageFile; + } + if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){ + nPage = 0; + } + if( nPage>0 ){ + u32 pageSize; + u32 usableSize; + u8 *page1 = pPage1->aData; + rc = SQLITE_NOTADB; + /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins + ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d + ** 61 74 20 33 00. */ + if( memcmp(page1, zMagicHeader, 16)!=0 ){ + goto page1_init_failed; + } + +#ifdef SQLITE_OMIT_WAL + if( page1[18]>1 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>1 ){ + goto page1_init_failed; + } +#else + if( page1[18]>2 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>2 ){ + goto page1_init_failed; + } + + /* If the read version is set to 2, this database should be accessed + ** in WAL mode. If the log is not already open, open it now. Then + ** return SQLITE_OK and return without populating BtShared.pPage1. + ** The caller detects this and calls this function again. This is + ** required as the version of page 1 currently in the page1 buffer + ** may not be the latest version - there may be a newer one in the log + ** file. + */ + if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ + int isOpen = 0; + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); + if( rc!=SQLITE_OK ){ + goto page1_init_failed; + }else{ + setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1); + if( isOpen==0 ){ + releasePageOne(pPage1); + return SQLITE_OK; + } + } + rc = SQLITE_NOTADB; + }else{ + setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1); + } +#endif + + /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload + ** fractions and the leaf payload fraction values must be 64, 32, and 32. + ** + ** The original design allowed these amounts to vary, but as of + ** version 3.6.0, we require them to be fixed. + */ + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ + pageSize = (page1[16]<<8) | (page1[17]<<16); + /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two + ** between 512 and 65536 inclusive. */ + if( ((pageSize-1)&pageSize)!=0 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 + ){ + goto page1_init_failed; + } + assert( (pageSize & 7)==0 ); + /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte + ** integer at offset 20 is the number of bytes of space at the end of + ** each page to reserve for extensions. + ** + ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ + usableSize = pageSize - page1[20]; + if( (u32)pageSize!=pBt->pageSize ){ + /* After reading the first page of the database assuming a page size + ** of BtShared.pageSize, we have discovered that the page-size is + ** actually pageSize. Unlock the database, leave pBt->pPage1 at + ** zero and return SQLITE_OK. The caller will call this function + ** again with the correct page-size. + */ + releasePageOne(pPage1); + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; + freeTempSpace(pBt); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); + return rc; + } + if( nPage>nPageFile ){ + if( sqlite3WritableSchema(pBt->db)==0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + }else{ + nPage = nPageFile; + } + } + /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to + ** be less than 480. In other words, if the page size is 512, then the + ** reserved space size cannot exceed 32. */ + if( usableSize<480 ){ + goto page1_init_failed; + } + pBt->btsFlags |= BTS_PAGESIZE_FIXED; + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); +#endif + } + + /* maxLocal is the maximum amount of payload to store locally for + ** a cell. Make sure it is small enough so that at least minFanout + ** cells can will fit on one page. We assume a 10-byte page header. + ** Besides the payload, the cell must store: + ** 2-byte pointer to the cell + ** 4-byte child pointer + ** 9-byte nKey value + ** 4-byte nData value + ** 4-byte overflow page pointer + ** So a cell consists of a 2-byte pointer, a header which is as much as + ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow + ** page pointer. + */ + pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); + pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); + pBt->maxLeaf = (u16)(pBt->usableSize - 35); + pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); + if( pBt->maxLocal>127 ){ + pBt->max1bytePayload = 127; + }else{ + pBt->max1bytePayload = (u8)pBt->maxLocal; + } + assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); + pBt->pPage1 = pPage1; + pBt->nPage = nPage; + return SQLITE_OK; + +page1_init_failed: + releasePageOne(pPage1); + pBt->pPage1 = 0; + return rc; +} + +#ifndef NDEBUG +/* +** Return the number of cursors open on pBt. This is for use +** in assert() expressions, so it is only compiled if NDEBUG is not +** defined. +** +** Only write cursors are counted if wrOnly is true. If wrOnly is +** false then all cursors are counted. +** +** For the purposes of this routine, a cursor is any cursor that +** is capable of reading or writing to the database. Cursors that +** have been tripped into the CURSOR_FAULT state are not counted. +*/ +static int countValidCursors(BtShared *pBt, int wrOnly){ + BtCursor *pCur; + int r = 0; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) + && pCur->eState!=CURSOR_FAULT ) r++; + } + return r; +} +#endif + +/* +** If there are no outstanding cursors and we are not in the middle +** of a transaction but there is a read lock on the database, then +** this routine unrefs the first page of the database file which +** has the effect of releasing the read lock. +** +** If there is a transaction in progress, this routine is a no-op. +*/ +static void unlockBtreeIfUnused(BtShared *pBt){ + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); + if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ + MemPage *pPage1 = pBt->pPage1; + assert( pPage1->aData ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); + pBt->pPage1 = 0; + releasePageOne(pPage1); + } +} + +/* +** If pBt points to an empty file then convert that empty file +** into a new empty database by initializing the first page of +** the database. +*/ +static int newDatabase(BtShared *pBt){ + MemPage *pP1; + unsigned char *data; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->nPage>0 ){ + return SQLITE_OK; + } + pP1 = pBt->pPage1; + assert( pP1!=0 ); + data = pP1->aData; + rc = sqlite3PagerWrite(pP1->pDbPage); + if( rc ) return rc; + memcpy(data, zMagicHeader, sizeof(zMagicHeader)); + assert( sizeof(zMagicHeader)==16 ); + data[16] = (u8)((pBt->pageSize>>8)&0xff); + data[17] = (u8)((pBt->pageSize>>16)&0xff); + data[18] = 1; + data[19] = 1; + assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); + data[20] = (u8)(pBt->pageSize - pBt->usableSize); + data[21] = 64; + data[22] = 32; + data[23] = 32; + memset(&data[24], 0, 100-24); + zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); + assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); + put4byte(&data[36 + 4*4], pBt->autoVacuum); + put4byte(&data[36 + 7*4], pBt->incrVacuum); +#endif + pBt->nPage = 1; + data[31] = 1; + return SQLITE_OK; +} + +/* +** Initialize the first page of the database file (creating a database +** consisting of a single page and no schema objects). Return SQLITE_OK +** if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + p->pBt->nPage = 0; + rc = newDatabase(p->pBt); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Attempt to start a new transaction. A write-transaction +** is started if the second argument is nonzero, otherwise a read- +** transaction. If the second argument is 2 or more and exclusive +** transaction is started, meaning that no other process is allowed +** to access the database. A preexisting transaction may not be +** upgraded to exclusive by calling this routine a second time - the +** exclusivity flag only works for a new transaction. +** +** A write-transaction must be started before attempting any +** changes to the database. None of the following routines +** will work unless a transaction is started first: +** +** sqlite3BtreeCreateTable() +** sqlite3BtreeCreateIndex() +** sqlite3BtreeClearTable() +** sqlite3BtreeDropTable() +** sqlite3BtreeInsert() +** sqlite3BtreeDelete() +** sqlite3BtreeUpdateMeta() +** +** If an initial attempt to acquire the lock fails because of lock contention +** and the database was previously unlocked, then invoke the busy handler +** if there is one. But if there was previously a read-lock, do not +** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is +** returned when there is already a read-lock in order to avoid a deadlock. +** +** Suppose there are two processes A and B. A has a read lock and B has +** a reserved lock. B tries to promote to exclusive but is blocked because +** of A's read lock. A tries to promote to reserved but is blocked by B. +** One or the other of the two processes must give way or there can be +** no progress. By returning SQLITE_BUSY and not invoking the busy callback +** when A already has a read lock, we encourage A to give up and let B +** proceed. +*/ +static SQLITE_NOINLINE int btreeBeginTrans( + Btree *p, /* The btree in which to start the transaction */ + int wrflag, /* True to start a write transaction */ + int *pSchemaVersion /* Put schema version number here, if not NULL */ +){ + BtShared *pBt = p->pBt; + Pager *pPager = pBt->pPager; + int rc = SQLITE_OK; + + sqlite3BtreeEnter(p); + btreeIntegrity(p); + + /* If the btree is already in a write-transaction, or it + ** is already in a read-transaction and a read-transaction + ** is requested, this is a no-op. + */ + if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ + goto trans_begun; + } + assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); + + if( (p->db->flags & SQLITE_ResetDatabase) + && sqlite3PagerIsreadonly(pPager)==0 + ){ + pBt->btsFlags &= ~BTS_READ_ONLY; + } + + /* Write transactions are not possible on a read-only database */ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ + rc = SQLITE_READONLY; + goto trans_begun; + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + { + sqlite3 *pBlock = 0; + /* If another database handle has already opened a write transaction + ** on this shared-btree structure and a second write transaction is + ** requested, return SQLITE_LOCKED. + */ + if( (wrflag && pBt->inTransaction==TRANS_WRITE) + || (pBt->btsFlags & BTS_PENDING)!=0 + ){ + pBlock = pBt->pWriter->db; + }else if( wrflag>1 ){ + BtLock *pIter; + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->pBtree!=p ){ + pBlock = pIter->pBtree->db; + break; + } + } + } + if( pBlock ){ + sqlite3ConnectionBlocked(p->db, pBlock); + rc = SQLITE_LOCKED_SHAREDCACHE; + goto trans_begun; + } + } +#endif + + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock + ** on page 1, the transaction cannot be opened. */ + rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); + if( SQLITE_OK!=rc ) goto trans_begun; + + pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; + if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY; + do { + sqlite3PagerWalDb(pPager, p->db); + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* If transitioning from no transaction directly to a write transaction, + ** block for the WRITER lock first if possible. */ + if( pBt->pPage1==0 && wrflag ){ + assert( pBt->inTransaction==TRANS_NONE ); + rc = sqlite3PagerWalWriteLock(pPager, 1); + if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break; + } +#endif + + /* Call lockBtree() until either pBt->pPage1 is populated or + ** lockBtree() returns something other than SQLITE_OK. lockBtree() + ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after + ** reading page 1 it discovers that the page-size of the database + ** file is not pBt->pageSize. In this case lockBtree() will update + ** pBt->pageSize to the page-size of the file on disk. + */ + while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) ); + + if( rc==SQLITE_OK && wrflag ){ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ + rc = SQLITE_READONLY; + }else{ + rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db)); + if( rc==SQLITE_OK ){ + rc = newDatabase(pBt); + }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){ + /* if there was no transaction opened when this function was + ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error + ** code to SQLITE_BUSY. */ + rc = SQLITE_BUSY; + } + } + } + + if( rc!=SQLITE_OK ){ + (void)sqlite3PagerWalWriteLock(pPager, 0); + unlockBtreeIfUnused(pBt); + } + }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && + btreeInvokeBusyHandler(pBt) ); + sqlite3PagerWalDb(pPager, 0); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; +#endif + + if( rc==SQLITE_OK ){ + if( p->inTrans==TRANS_NONE ){ + pBt->nTransaction++; +#ifndef SQLITE_OMIT_SHARED_CACHE + if( p->sharable ){ + assert( p->lock.pBtree==p && p->lock.iTable==1 ); + p->lock.eLock = READ_LOCK; + p->lock.pNext = pBt->pLock; + pBt->pLock = &p->lock; + } +#endif + } + p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); + if( p->inTrans>pBt->inTransaction ){ + pBt->inTransaction = p->inTrans; + } + if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( !pBt->pWriter ); + pBt->pWriter = p; + pBt->btsFlags &= ~BTS_EXCLUSIVE; + if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE; +#endif + + /* If the db-size header field is incorrect (as it may be if an old + ** client has been writing the database file), update it now. Doing + ** this sooner rather than later means the database size can safely + ** re-read the database size from page 1 if a savepoint or transaction + ** rollback occurs within the transaction. + */ + if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } + } + +trans_begun: + if( rc==SQLITE_OK ){ + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint); + } + } + + btreeIntegrity(p); + sqlite3BtreeLeave(p); + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ + BtShared *pBt; + if( p->sharable + || p->inTrans==TRANS_NONE + || (p->inTrans==TRANS_READ && wrflag!=0) + ){ + return btreeBeginTrans(p,wrflag,pSchemaVersion); + } + pBt = p->pBt; + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + return sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + }else{ + return SQLITE_OK; + } +} + +#ifndef SQLITE_OMIT_AUTOVACUUM + +/* +** Set the pointer-map entries for all children of page pPage. Also, if +** pPage contains cells that point to overflow pages, set the pointer +** map entries for the overflow pages as well. +*/ +static int setChildPtrmaps(MemPage *pPage){ + int i; /* Counter variable */ + int nCell; /* Number of cells in page pPage */ + int rc; /* Return code */ + BtShared *pBt = pPage->pBt; + Pgno pgno = pPage->pgno; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage); + if( rc!=SQLITE_OK ) return rc; + nCell = pPage->nCell; + + for(i=0; ileaf ){ + Pgno childPgno = get4byte(pCell); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + } + + if( !pPage->leaf ){ + Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + + return rc; +} + +/* +** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so +** that it points to iTo. Parameter eType describes the type of pointer to +** be modified, as follows: +** +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** page of pPage. +** +** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow +** page pointed to by one of the cells on pPage. +** +** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next +** overflow page in the list. +*/ +static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + if( eType==PTRMAP_OVERFLOW2 ){ + /* The pointer is always the first 4 bytes of the page in this case. */ + if( get4byte(pPage->aData)!=iFrom ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + put4byte(pPage->aData, iTo); + }else{ + int i; + int nCell; + int rc; + + rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage); + if( rc ) return rc; + nCell = pPage->nCell; + + for(i=0; ixParseCell(pPage, pCell, &info); + if( info.nLocal pPage->aData+pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( iFrom==get4byte(pCell+info.nSize-4) ){ + put4byte(pCell+info.nSize-4, iTo); + break; + } + } + }else{ + if( pCell+4 > pPage->aData+pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( get4byte(pCell)==iFrom ){ + put4byte(pCell, iTo); + break; + } + } + } + + if( i==nCell ){ + if( eType!=PTRMAP_BTREE || + get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); + } + } + return SQLITE_OK; +} + + +/* +** Move the open database page pDbPage to location iFreePage in the +** database. The pDbPage reference remains valid. +** +** The isCommit flag indicates that there is no need to remember that +** the journal needs to be sync()ed before database page pDbPage->pgno +** can be written to. The caller has already promised not to write to that +** page. +*/ +static int relocatePage( + BtShared *pBt, /* Btree */ + MemPage *pDbPage, /* Open page to move */ + u8 eType, /* Pointer map 'type' entry for pDbPage */ + Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ + Pgno iFreePage, /* The location to move pDbPage to */ + int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ +){ + MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pDbPage->pBt==pBt ); + if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; + + /* Move page iDbPage from its current location to page number iFreePage */ + TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", + iDbPage, iFreePage, iPtrPage, eType)); + rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); + if( rc!=SQLITE_OK ){ + return rc; + } + pDbPage->pgno = iFreePage; + + /* If pDbPage was a btree-page, then it may have child pages and/or cells + ** that point to overflow pages. The pointer map entries for all these + ** pages need to be changed. + ** + ** If pDbPage is an overflow page, then the first 4 bytes may store a + ** pointer to a subsequent overflow page. If this is the case, then + ** the pointer map needs to be updated for the subsequent overflow page. + */ + if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + Pgno nextOvfl = get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + /* Fix the database pointer on page iPtrPage that pointed at iDbPage so + ** that it points at iFreePage. Also fix the pointer map entry for + ** iPtrPage. + */ + if( eType!=PTRMAP_ROOTPAGE ){ + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pPtrPage->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==SQLITE_OK ){ + ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); + } + } + return rc; +} + +/* Forward declaration required by incrVacuumStep(). */ +static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); + +/* +** Perform a single step of an incremental-vacuum. If successful, return +** SQLITE_OK. If there is no work to do (and therefore no point in +** calling this function again), return SQLITE_DONE. Or, if an error +** occurs, return some other error code. +** +** More specifically, this function attempts to re-organize the database so +** that the last page of the file currently in use is no longer in use. +** +** Parameter nFin is the number of pages that this database would contain +** were this function called until it returns SQLITE_DONE. +** +** If the bCommit parameter is non-zero, this function assumes that the +** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE +** or an error. bCommit is passed true for an auto-vacuum-on-commit +** operation, or false for an incremental vacuum. +*/ +static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ + Pgno nFreeList; /* Number of pages still on the free-list */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iLastPg>nFin ); + + if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ + u8 eType; + Pgno iPtrPage; + + nFreeList = get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + return SQLITE_DONE; + } + + rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); + if( rc!=SQLITE_OK ){ + return rc; + } + if( eType==PTRMAP_ROOTPAGE ){ + return SQLITE_CORRUPT_BKPT; + } + + if( eType==PTRMAP_FREEPAGE ){ + if( bCommit==0 ){ + /* Remove the page from the files free-list. This is not required + ** if bCommit is non-zero. In that case, the free-list will be + ** truncated to zero after this function returns, so it doesn't + ** matter if it still contains some garbage entries. + */ + Pgno iFreePg; + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( iFreePg==iLastPg ); + releasePage(pFreePg); + } + } else { + Pgno iFreePg; /* Index of free page to move pLastPg to */ + MemPage *pLastPg; + u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */ + Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */ + + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If bCommit is zero, this loop runs exactly once and page pLastPg + ** is swapped with the first free page pulled off the free list. + ** + ** On the other hand, if bCommit is greater than zero, then keep + ** looping until a free-page located within the first nFin pages + ** of the file is found. + */ + if( bCommit==0 ){ + eMode = BTALLOC_LE; + iNear = nFin; + } + do { + MemPage *pFreePg; + Pgno dbSize = btreePagecount(pBt); + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode); + if( rc!=SQLITE_OK ){ + releasePage(pLastPg); + return rc; + } + releasePage(pFreePg); + if( iFreePg>dbSize ){ + releasePage(pLastPg); + return SQLITE_CORRUPT_BKPT; + } + }while( bCommit && iFreePg>nFin ); + assert( iFreePgbDoTruncate = 1; + pBt->nPage = iLastPg; + } + return SQLITE_OK; +} + +/* +** The database opened by the first argument is an auto-vacuum database +** nOrig pages in size containing nFree free pages. Return the expected +** size of the database in pages following an auto-vacuum operation. +*/ +static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){ + int nEntry; /* Number of entries on one ptrmap page */ + Pgno nPtrmap; /* Number of PtrMap pages to be freed */ + Pgno nFin; /* Return value */ + + nEntry = pBt->usableSize/5; + nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry; + nFin = nOrig - nFree - nPtrmap; + if( nOrig>PENDING_BYTE_PAGE(pBt) && nFinpBt; + + sqlite3BtreeEnter(p); + assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); + if( !pBt->autoVacuum ){ + rc = SQLITE_DONE; + }else{ + Pgno nOrig = btreePagecount(pBt); + Pgno nFree = get4byte(&pBt->pPage1->aData[36]); + Pgno nFin = finalDbSize(pBt, nOrig, nFree); + + if( nOrig=nOrig ){ + rc = SQLITE_CORRUPT_BKPT; + }else if( nFree>0 ){ + rc = saveAllCursors(pBt, 0, 0); + if( rc==SQLITE_OK ){ + invalidateAllOverflowCache(pBt); + rc = incrVacuumStep(pBt, nFin, nOrig, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[28], pBt->nPage); + } + }else{ + rc = SQLITE_DONE; + } + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine is called prior to sqlite3PagerCommit when a transaction +** is committed for an auto-vacuum database. +*/ +static int autoVacuumCommit(Btree *p){ + int rc = SQLITE_OK; + Pager *pPager; + BtShared *pBt; + sqlite3 *db; + VVA_ONLY( int nRef ); + + assert( p!=0 ); + pBt = p->pBt; + pPager = pBt->pPager; + VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); ) + + assert( sqlite3_mutex_held(pBt->mutex) ); + invalidateAllOverflowCache(pBt); + assert(pBt->autoVacuum); + if( !pBt->incrVacuum ){ + Pgno nFin; /* Number of pages in database after autovacuuming */ + Pgno nFree; /* Number of pages on the freelist initially */ + Pgno nVac; /* Number of pages to vacuum */ + Pgno iFree; /* The next page to be freed */ + Pgno nOrig; /* Database size before freeing */ + + nOrig = btreePagecount(pBt); + if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ + /* It is not possible to create a database for which the final page + ** is either a pointer-map page or the pending-byte page. If one + ** is encountered, this indicates corruption. + */ + return SQLITE_CORRUPT_BKPT; + } + + nFree = get4byte(&pBt->pPage1->aData[36]); + db = p->db; + if( db->xAutovacPages ){ + int iDb; + for(iDb=0; ALWAYS(iDbnDb); iDb++){ + if( db->aDb[iDb].pBt==p ) break; + } + nVac = db->xAutovacPages( + db->pAutovacPagesArg, + db->aDb[iDb].zDbSName, + nOrig, + nFree, + pBt->pageSize + ); + if( nVac>nFree ){ + nVac = nFree; + } + if( nVac==0 ){ + return SQLITE_OK; + } + }else{ + nVac = nFree; + } + nFin = finalDbSize(pBt, nOrig, nVac); + if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT; + if( nFinnFin && rc==SQLITE_OK; iFree--){ + rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree); + } + if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( nVac==nFree ){ + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + } + put4byte(&pBt->pPage1->aData[28], nFin); + pBt->bDoTruncate = 1; + pBt->nPage = nFin; + } + if( rc!=SQLITE_OK ){ + sqlite3PagerRollback(pPager); + } + } + + assert( nRef>=sqlite3PagerRefcount(pPager) ); + return rc; +} + +#else /* ifndef SQLITE_OMIT_AUTOVACUUM */ +# define setChildPtrmaps(x) SQLITE_OK +#endif + +/* +** This routine does the first phase of a two-phase commit. This routine +** causes a rollback journal to be created (if it does not already exist) +** and populated with enough information so that if a power loss occurs +** the database can be restored to its original state by playing back +** the journal. Then the contents of the journal are flushed out to +** the disk. After the journal is safely on oxide, the changes to the +** database are written into the database file and flushed to oxide. +** At the end of this call, the rollback journal still exists on the +** disk and we are still holding all locks, so the transaction has not +** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the +** commit process. +** +** This call is a no-op if no write-transaction is currently active on pBt. +** +** Otherwise, sync the database file for the btree pBt. zSuperJrnl points to +** the name of a super-journal file that should be written into the +** individual journal file, or is NULL, indicating no super-journal file +** (single database transaction). +** +** When this is called, the super-journal should already have been +** created, populated with this journal pointer and synced to disk. +** +** Once this is routine has returned, the only thing required to commit +** the write-transaction for this database file is to delete the journal. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){ + int rc = SQLITE_OK; + if( p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + rc = autoVacuumCommit(p); + if( rc!=SQLITE_OK ){ + sqlite3BtreeLeave(p); + return rc; + } + } + if( pBt->bDoTruncate ){ + sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); + } +#endif + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zSuperJrnl, 0); + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback() +** at the conclusion of a transaction. +*/ +static void btreeEndTransaction(Btree *p){ + BtShared *pBt = p->pBt; + sqlite3 *db = p->db; + assert( sqlite3BtreeHoldsMutex(p) ); + +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->bDoTruncate = 0; +#endif + if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){ + /* If there are other active statements that belong to this database + ** handle, downgrade to a read-only transaction. The other statements + ** may still be reading from the database. */ + downgradeAllSharedCacheTableLocks(p); + p->inTrans = TRANS_READ; + }else{ + /* If the handle had any kind of transaction open, decrement the + ** transaction count of the shared btree. If the transaction count + ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() + ** call below will unlock the pager. */ + if( p->inTrans!=TRANS_NONE ){ + clearAllSharedCacheTableLocks(p); + pBt->nTransaction--; + if( 0==pBt->nTransaction ){ + pBt->inTransaction = TRANS_NONE; + } + } + + /* Set the current transaction state to TRANS_NONE and unlock the + ** pager if this call closed the only read or write transaction. */ + p->inTrans = TRANS_NONE; + unlockBtreeIfUnused(pBt); + } + + btreeIntegrity(p); +} + +/* +** Commit the transaction currently in progress. +** +** This routine implements the second phase of a 2-phase commit. The +** sqlite3BtreeCommitPhaseOne() routine does the first phase and should +** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne() +** routine did all the work of writing information out to disk and flushing the +** contents so that they are written onto the disk platter. All this +** routine has to do is delete or truncate or zero the header in the +** the rollback journal (which causes the transaction to commit) and +** drop locks. +** +** Normally, if an error occurs while the pager layer is attempting to +** finalize the underlying journal file, this function returns an error and +** the upper layer will attempt a rollback. However, if the second argument +** is non-zero then this b-tree transaction is part of a multi-file +** transaction. In this case, the transaction has already been committed +** (by deleting a super-journal file) and the caller will ignore this +** functions return code. So, even if an error occurs in the pager layer, +** reset the b-tree objects internal state to indicate that the write +** transaction has been closed. This is quite safe, as the pager will have +** transitioned to the error state. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ + + if( p->inTrans==TRANS_NONE ) return SQLITE_OK; + sqlite3BtreeEnter(p); + btreeIntegrity(p); + + /* If the handle has a write-transaction open, commit the shared-btrees + ** transaction and set the shared state to TRANS_READ. + */ + if( p->inTrans==TRANS_WRITE ){ + int rc; + BtShared *pBt = p->pBt; + assert( pBt->inTransaction==TRANS_WRITE ); + assert( pBt->nTransaction>0 ); + rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); + if( rc!=SQLITE_OK && bCleanup==0 ){ + sqlite3BtreeLeave(p); + return rc; + } + p->iBDataVersion--; /* Compensate for pPager->iDataVersion++; */ + pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Do both phases of a commit. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + rc = sqlite3BtreeCommitPhaseOne(p, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeCommitPhaseTwo(p, 0); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine sets the state to CURSOR_FAULT and the error +** code to errCode for every cursor on any BtShared that pBtree +** references. Or if the writeOnly flag is set to 1, then only +** trip write cursors and leave read cursors unchanged. +** +** Every cursor is a candidate to be tripped, including cursors +** that belong to other database connections that happen to be +** sharing the cache with pBtree. +** +** This routine gets called when a rollback occurs. If the writeOnly +** flag is true, then only write-cursors need be tripped - read-only +** cursors save their current positions so that they may continue +** following the rollback. Or, if writeOnly is false, all cursors are +** tripped. In general, writeOnly is false if the transaction being +** rolled back modified the database schema. In this case b-tree root +** pages may be moved or deleted from the database altogether, making +** it unsafe for read cursors to continue. +** +** If the writeOnly flag is true and an error is encountered while +** saving the current position of a read-only cursor, all cursors, +** including all read-cursors are tripped. +** +** SQLITE_OK is returned if successful, or if an error occurs while +** saving a cursor position, an SQLite error code. +*/ +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ + BtCursor *p; + int rc = SQLITE_OK; + + assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 ); + if( pBtree ){ + sqlite3BtreeEnter(pBtree); + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ + rc = saveCursorPosition(p); + if( rc!=SQLITE_OK ){ + (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); + break; + } + } + }else{ + sqlite3BtreeClearCursor(p); + p->eState = CURSOR_FAULT; + p->skipNext = errCode; + } + btreeReleaseAllCursorPages(p); + } + sqlite3BtreeLeave(pBtree); + } + return rc; +} + +/* +** Set the pBt->nPage field correctly, according to the current +** state of the database. Assume pBt->pPage1 is valid. +*/ +static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ + int nPage = get4byte(&pPage1->aData[28]); + testcase( nPage==0 ); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + testcase( pBt->nPage!=(u32)nPage ); + pBt->nPage = nPage; +} + +/* +** Rollback the transaction in progress. +** +** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped). +** Only write cursors are tripped if writeOnly is true but all cursors are +** tripped if writeOnly is false. Any attempt to use +** a tripped cursor will result in an error. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ + int rc; + BtShared *pBt = p->pBt; + MemPage *pPage1; + + assert( writeOnly==1 || writeOnly==0 ); + assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK ); + sqlite3BtreeEnter(p); + if( tripCode==SQLITE_OK ){ + rc = tripCode = saveAllCursors(pBt, 0, 0); + if( rc ) writeOnly = 0; + }else{ + rc = SQLITE_OK; + } + if( tripCode ){ + int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly); + assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) ); + if( rc2!=SQLITE_OK ) rc = rc2; + } + btreeIntegrity(p); + + if( p->inTrans==TRANS_WRITE ){ + int rc2; + + assert( TRANS_WRITE==pBt->inTransaction ); + rc2 = sqlite3PagerRollback(pBt->pPager); + if( rc2!=SQLITE_OK ){ + rc = rc2; + } + + /* The rollback may have destroyed the pPage1->aData value. So + ** call btreeGetPage() on page 1 again to make + ** sure pPage1->aData is set correctly. */ + if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ + btreeSetNPage(pBt, pPage1); + releasePageOne(pPage1); + } + assert( countValidCursors(pBt, 1)==0 ); + pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Start a statement subtransaction. The subtransaction can be rolled +** back independently of the main transaction. You must start a transaction +** before starting a subtransaction. The subtransaction is ended automatically +** if the main transaction commits or rolls back. +** +** Statement subtransactions are used around individual SQL statements +** that are contained within a BEGIN...COMMIT block. If a constraint +** error occurs within the statement, the effect of that one statement +** can be rolled back without having to rollback the entire transaction. +** +** A statement sub-transaction is implemented as an anonymous savepoint. The +** value passed as the second parameter is the total number of savepoints, +** including the new anonymous savepoint, open on the B-Tree. i.e. if there +** are no active savepoints and no other statement-transactions open, +** iStatement is 1. This anonymous savepoint can be released or rolled back +** using the sqlite3BtreeSavepoint() function. +*/ +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( iStatement>0 ); + assert( iStatement>p->db->nSavepoint ); + assert( pBt->inTransaction==TRANS_WRITE ); + /* At the pager level, a statement transaction is a savepoint with + ** an index greater than all savepoints created explicitly using + ** SQL statements. It is illegal to open, release or rollback any + ** such savepoints while the statement transaction savepoint is active. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** The second argument to this function, op, is always SAVEPOINT_ROLLBACK +** or SAVEPOINT_RELEASE. This function either releases or rolls back the +** savepoint identified by parameter iSavepoint, depending on the value +** of op. +** +** Normally, iSavepoint is greater than or equal to zero. However, if op is +** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the +** contents of the entire transaction are rolled back. This is different +** from a normal transaction rollback, as no locks are released and the +** transaction remains open. +*/ +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ + int rc = SQLITE_OK; + if( p && p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); + sqlite3BtreeEnter(p); + if( op==SAVEPOINT_ROLLBACK ){ + rc = saveAllCursors(pBt, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + } + if( rc==SQLITE_OK ){ + if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ + pBt->nPage = 0; + } + rc = newDatabase(pBt); + btreeSetNPage(pBt, pBt->pPage1); + + /* pBt->nPage might be zero if the database was corrupt when + ** the transaction was started. Otherwise, it must be at least 1. */ + assert( CORRUPT_DB || pBt->nPage>0 ); + } + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** Create a new cursor for the BTree whose root is on the page +** iTable. If a read-only cursor is requested, it is assumed that +** the caller already has at least a read-only transaction open +** on the database already. If a write-cursor is requested, then +** the caller is assumed to have an open write transaction. +** +** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only +** be used for reading. If the BTREE_WRCSR bit is set, then the cursor +** can be used for reading or for writing if other conditions for writing +** are also met. These are the conditions that must be met in order +** for writing to be allowed: +** +** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR +** +** 2: Other database connections that share the same pager cache +** but which are not in the READ_UNCOMMITTED state may not have +** cursors open with wrFlag==0 on the same table. Otherwise +** the changes made by this write cursor would be visible to +** the read cursors in the other database connection. +** +** 3: The database must be writable (not on read-only media) +** +** 4: There must be an active transaction. +** +** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR +** is set. If FORDELETE is set, that is a hint to the implementation that +** this cursor will only be used to seek to and delete entries of an index +** as part of a larger DELETE statement. The FORDELETE hint is not used by +** this implementation. But in a hypothetical alternative storage engine +** in which index entries are automatically deleted when corresponding table +** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE +** operations on this cursor can be no-ops and all READ operations can +** return a null row (2-bytes: 0x01 0x00). +** +** No checking is done to make sure that page iTable really is the +** root page of a b-tree. If it is not, then the cursor acquired +** will not work correctly. +** +** It is assumed that the sqlite3BtreeCursorZero() has been called +** on pCur to initialize the memory space prior to invoking this routine. +*/ +static int btreeCursor( + Btree *p, /* The btree */ + Pgno iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + BtShared *pBt = p->pBt; /* Shared b-tree handle */ + BtCursor *pX; /* Looping over other all cursors */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( wrFlag==0 + || wrFlag==BTREE_WRCSR + || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) + ); + + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with + ** this lock. The iTable<1 term disables the check for corrupt schemas. */ + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) + || iTable<1 ); + assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); + + /* Assert that the caller has opened the required transaction. */ + assert( p->inTrans>TRANS_NONE ); + assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1 && pBt->pPage1->aData ); + assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 ); + + if( iTable<=1 ){ + if( iTable<1 ){ + return SQLITE_CORRUPT_BKPT; + }else if( btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; + } + } + + /* Now that no other errors can occur, finish filling in the BtCursor + ** variables and link the cursor into the BtShared list. */ + pCur->pgnoRoot = iTable; + pCur->iPage = -1; + pCur->pKeyInfo = pKeyInfo; + pCur->pBtree = p; + pCur->pBt = pBt; + pCur->curFlags = 0; + /* If there are two or more cursors on the same btree, then all such + ** cursors *must* have the BTCF_Multiple flag set. */ + for(pX=pBt->pCursor; pX; pX=pX->pNext){ + if( pX->pgnoRoot==iTable ){ + pX->curFlags |= BTCF_Multiple; + pCur->curFlags = BTCF_Multiple; + } + } + pCur->eState = CURSOR_INVALID; + pCur->pNext = pBt->pCursor; + pBt->pCursor = pCur; + if( wrFlag ){ + pCur->curFlags |= BTCF_WriteFlag; + pCur->curPagerFlags = 0; + if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt); + }else{ + pCur->curPagerFlags = PAGER_GET_READONLY; + } + return SQLITE_OK; +} +static int btreeCursorWithLock( + Btree *p, /* The btree */ + Pgno iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + sqlite3BtreeLeave(p); + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeCursor( + Btree *p, /* The btree */ + Pgno iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ + BtCursor *pCur /* Write new cursor here */ +){ + if( p->sharable ){ + return btreeCursorWithLock(p, iTable, wrFlag, pKeyInfo, pCur); + }else{ + return btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + } +} + +/* +** Return the size of a BtCursor object in bytes. +** +** This interfaces is needed so that users of cursors can preallocate +** sufficient storage to hold a cursor. The BtCursor object is opaque +** to users so they cannot do the sizeof() themselves - they must call +** this routine. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ + return ROUND8(sizeof(BtCursor)); +} + +/* +** Initialize memory that will be converted into a BtCursor object. +** +** The simple approach here would be to memset() the entire object +** to zero. But it turns out that the apPage[] and aiIdx[] arrays +** do not need to be zeroed and they are large, so we can save a lot +** of run-time by skipping the initialization of those elements. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){ + memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT)); +} + +/* +** Close a cursor. The read lock on the database file is released +** when the last cursor is closed. +*/ +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ + Btree *pBtree = pCur->pBtree; + if( pBtree ){ + BtShared *pBt = pCur->pBt; + sqlite3BtreeEnter(pBtree); + assert( pBt->pCursor!=0 ); + if( pBt->pCursor==pCur ){ + pBt->pCursor = pCur->pNext; + }else{ + BtCursor *pPrev = pBt->pCursor; + do{ + if( pPrev->pNext==pCur ){ + pPrev->pNext = pCur->pNext; + break; + } + pPrev = pPrev->pNext; + }while( ALWAYS(pPrev) ); + } + btreeReleaseAllCursorPages(pCur); + unlockBtreeIfUnused(pBt); + sqlite3_free(pCur->aOverflow); + sqlite3_free(pCur->pKey); + if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){ + /* Since the BtShared is not sharable, there is no need to + ** worry about the missing sqlite3BtreeLeave() call here. */ + assert( pBtree->sharable==0 ); + sqlite3BtreeClose(pBtree); + }else{ + sqlite3BtreeLeave(pBtree); + } + pCur->pBtree = 0; + } + return SQLITE_OK; +} + +/* +** Make sure the BtCursor* given in the argument has a valid +** BtCursor.info structure. If it is not already valid, call +** btreeParseCell() to fill it in. +** +** BtCursor.info is a cache of the information in the current cell. +** Using this cache reduces the number of calls to btreeParseCell(). +*/ +#ifndef NDEBUG + static int cellInfoEqual(CellInfo *a, CellInfo *b){ + if( a->nKey!=b->nKey ) return 0; + if( a->pPayload!=b->pPayload ) return 0; + if( a->nPayload!=b->nPayload ) return 0; + if( a->nLocal!=b->nLocal ) return 0; + if( a->nSize!=b->nSize ) return 0; + return 1; + } + static void assertCellInfo(BtCursor *pCur){ + CellInfo info; + memset(&info, 0, sizeof(info)); + btreeParseCell(pCur->pPage, pCur->ix, &info); + assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) ); + } +#else + #define assertCellInfo(x) +#endif +static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ + if( pCur->info.nSize==0 ){ + pCur->curFlags |= BTCF_ValidNKey; + btreeParseCell(pCur->pPage,pCur->ix,&pCur->info); + }else{ + assertCellInfo(pCur); + } +} + +#ifndef NDEBUG /* The next routine used only within assert() statements */ +/* +** Return true if the given BtCursor is valid. A valid cursor is one +** that is currently pointing to a row in a (non-empty) table. +** This is a verification routine is used only within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ + return pCur && pCur->eState==CURSOR_VALID; +} +#endif /* NDEBUG */ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){ + assert( pCur!=0 ); + return pCur->eState==CURSOR_VALID; +} + +/* +** Return the value of the integer key or "rowid" for a table btree. +** This routine is only valid for a cursor that is pointing into a +** ordinary table btree. If the cursor points to an index btree or +** is invalid, the result of this routine is undefined. +*/ +SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->curIntKey ); + getCellInfo(pCur); + return pCur->info.nKey; +} + +/* +** Pin or unpin a cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor *pCur){ + assert( (pCur->curFlags & BTCF_Pinned)==0 ); + pCur->curFlags |= BTCF_Pinned; +} +SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){ + assert( (pCur->curFlags & BTCF_Pinned)!=0 ); + pCur->curFlags &= ~BTCF_Pinned; +} + +/* +** Return the offset into the database file for the start of the +** payload to which the cursor is pointing. +*/ +SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + + (i64)(pCur->info.pPayload - pCur->pPage->aData); +} + +/* +** Return the number of bytes of payload for the entry that pCur is +** currently pointing to. For table btrees, this will be the amount +** of data. For index btrees, this will be the size of the key. +** +** The caller must guarantee that the cursor is pointing to a non-NULL +** valid entry. In other words, the calling procedure must guarantee +** that the cursor has Cursor.eState==CURSOR_VALID. +*/ +SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + return pCur->info.nPayload; +} + +/* +** Return an upper bound on the size of any record for the table +** that the cursor is pointing into. +** +** This is an optimization. Everything will still work if this +** routine always returns 2147483647 (which is the largest record +** that SQLite can handle) or more. But returning a smaller value might +** prevent large memory allocations when trying to interpret a +** corrupt database. +** +** The current implementation merely returns the size of the underlying +** database file. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage; +} + +/* +** Given the page number of an overflow page in the database (parameter +** ovfl), this function finds the page number of the next page in the +** linked list of overflow pages. If possible, it uses the auto-vacuum +** pointer-map data instead of reading the content of page ovfl to do so. +** +** If an error occurs an SQLite error code is returned. Otherwise: +** +** The page number of the next overflow page in the linked list is +** written to *pPgnoNext. If page ovfl is the last page in its linked +** list, *pPgnoNext is set to zero. +** +** If ppPage is not NULL, and a reference to the MemPage object corresponding +** to page number pOvfl was obtained, then *ppPage is set to point to that +** reference. It is the responsibility of the caller to call releasePage() +** on *ppPage to free the reference. In no reference was obtained (because +** the pointer-map was used to obtain the value for *pPgnoNext), then +** *ppPage is set to zero. +*/ +static int getOverflowPage( + BtShared *pBt, /* The database file */ + Pgno ovfl, /* Current overflow page number */ + MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */ + Pgno *pPgnoNext /* OUT: Next overflow page number */ +){ + Pgno next = 0; + MemPage *pPage = 0; + int rc = SQLITE_OK; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert(pPgnoNext); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* Try to find the next page in the overflow list using the + ** autovacuum pointer-map pages. Guess that the next page in + ** the overflow list is page number (ovfl+1). If that guess turns + ** out to be wrong, fall back to loading the data of page + ** number ovfl to determine the next page number. + */ + if( pBt->autoVacuum ){ + Pgno pgno; + Pgno iGuess = ovfl+1; + u8 eType; + + while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ + iGuess++; + } + + if( iGuess<=btreePagecount(pBt) ){ + rc = ptrmapGet(pBt, iGuess, &eType, &pgno); + if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ + next = iGuess; + rc = SQLITE_DONE; + } + } + } +#endif + + assert( next==0 || rc==SQLITE_DONE ); + if( rc==SQLITE_OK ){ + rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0); + assert( rc==SQLITE_OK || pPage==0 ); + if( rc==SQLITE_OK ){ + next = get4byte(pPage->aData); + } + } + + *pPgnoNext = next; + if( ppPage ){ + *ppPage = pPage; + }else{ + releasePage(pPage); + } + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Copy data from a buffer to a page, or from a page to a buffer. +** +** pPayload is a pointer to data stored on database page pDbPage. +** If argument eOp is false, then nByte bytes of data are copied +** from pPayload to the buffer pointed at by pBuf. If eOp is true, +** then sqlite3PagerWrite() is called on pDbPage and nByte bytes +** of data are copied from the buffer pBuf to pPayload. +** +** SQLITE_OK is returned on success, otherwise an error code. +*/ +static int copyPayload( + void *pPayload, /* Pointer to page data */ + void *pBuf, /* Pointer to buffer */ + int nByte, /* Number of bytes to copy */ + int eOp, /* 0 -> copy from page, 1 -> copy to page */ + DbPage *pDbPage /* Page containing pPayload */ +){ + if( eOp ){ + /* Copy data from buffer to page (a write operation) */ + int rc = sqlite3PagerWrite(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + memcpy(pPayload, pBuf, nByte); + }else{ + /* Copy data from page to buffer (a read operation) */ + memcpy(pBuf, pPayload, nByte); + } + return SQLITE_OK; +} + +/* +** This function is used to read or overwrite payload information +** for the entry that the pCur cursor is pointing to. The eOp +** argument is interpreted as follows: +** +** 0: The operation is a read. Populate the overflow cache. +** 1: The operation is a write. Populate the overflow cache. +** +** A total of "amt" bytes are read or written beginning at "offset". +** Data is read to or from the buffer pBuf. +** +** The content being read or written might appear on the main page +** or be scattered out on multiple overflow pages. +** +** If the current cursor entry uses one or more overflow pages +** this function may allocate space for and lazily populate +** the overflow page-list cache array (BtCursor.aOverflow). +** Subsequent calls use this cache to make seeking to the supplied offset +** more efficient. +** +** Once an overflow page-list cache has been allocated, it must be +** invalidated if some other cursor writes to the same table, or if +** the cursor is moved to a different row. Additionally, in auto-vacuum +** mode, the following events may invalidate an overflow page-list cache. +** +** * An incremental vacuum, +** * A commit in auto_vacuum="full" mode, +** * Creating a table (may require moving an overflow page). +*/ +static int accessPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 offset, /* Begin reading this far into payload */ + u32 amt, /* Read this many bytes */ + unsigned char *pBuf, /* Write the bytes into this buffer */ + int eOp /* zero to read. non-zero to write. */ +){ + unsigned char *aPayload; + int rc = SQLITE_OK; + int iIdx = 0; + MemPage *pPage = pCur->pPage; /* Btree page of current entry */ + BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ +#ifdef SQLITE_DIRECT_OVERFLOW_READ + unsigned char * const pBufStart = pBuf; /* Start of original out buffer */ +#endif + + assert( pPage ); + assert( eOp==0 || eOp==1 ); + assert( pCur->eState==CURSOR_VALID ); + if( pCur->ix>=pPage->nCell ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cursorHoldsMutex(pCur) ); + + getCellInfo(pCur); + aPayload = pCur->info.pPayload; + assert( offset+amt <= pCur->info.nPayload ); + + assert( aPayload > pPage->aData ); + if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ + /* Trying to read or write past the end of the data is an error. The + ** conditional above is really: + ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] + ** but is recast into its current form to avoid integer overflow problems + */ + return SQLITE_CORRUPT_PAGE(pPage); + } + + /* Check if data must be read/written to/from the btree page itself. */ + if( offsetinfo.nLocal ){ + int a = amt; + if( a+offset>pCur->info.nLocal ){ + a = pCur->info.nLocal - offset; + } + rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); + offset = 0; + pBuf += a; + amt -= a; + }else{ + offset -= pCur->info.nLocal; + } + + + if( rc==SQLITE_OK && amt>0 ){ + const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ + Pgno nextPage; + + nextPage = get4byte(&aPayload[pCur->info.nLocal]); + + /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. + ** + ** The aOverflow[] array is sized at one entry for each overflow page + ** in the overflow chain. The page number of the first overflow page is + ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array + ** means "not yet known" (the cache is lazily populated). + */ + if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ + int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; + if( pCur->aOverflow==0 + || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) + ){ + Pgno *aNew = (Pgno*)sqlite3Realloc( + pCur->aOverflow, nOvfl*2*sizeof(Pgno) + ); + if( aNew==0 ){ + return SQLITE_NOMEM_BKPT; + }else{ + pCur->aOverflow = aNew; + } + } + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); + pCur->curFlags |= BTCF_ValidOvfl; + }else{ + /* If the overflow page-list cache has been allocated and the + ** entry for the first required overflow page is valid, skip + ** directly to it. + */ + if( pCur->aOverflow[offset/ovflSize] ){ + iIdx = (offset/ovflSize); + nextPage = pCur->aOverflow[iIdx]; + offset = (offset%ovflSize); + } + } + + assert( rc==SQLITE_OK && amt>0 ); + while( nextPage ){ + /* If required, populate the overflow page-list cache. */ + if( nextPage > pBt->nPage ) return SQLITE_CORRUPT_BKPT; + assert( pCur->aOverflow[iIdx]==0 + || pCur->aOverflow[iIdx]==nextPage + || CORRUPT_DB ); + pCur->aOverflow[iIdx] = nextPage; + + if( offset>=ovflSize ){ + /* The only reason to read this page is to obtain the page + ** number for the next page in the overflow chain. The page + ** data is not required. So first try to lookup the overflow + ** page-list cache, if any, then fall back to the getOverflowPage() + ** function. + */ + assert( pCur->curFlags & BTCF_ValidOvfl ); + assert( pCur->pBtree->db==pBt->db ); + if( pCur->aOverflow[iIdx+1] ){ + nextPage = pCur->aOverflow[iIdx+1]; + }else{ + rc = getOverflowPage(pBt, nextPage, 0, &nextPage); + } + offset -= ovflSize; + }else{ + /* Need to read this page properly. It contains some of the + ** range of data that is being read (eOp==0) or written (eOp!=0). + */ + int a = amt; + if( a + offset > ovflSize ){ + a = ovflSize - offset; + } + +#ifdef SQLITE_DIRECT_OVERFLOW_READ + /* If all the following are true: + ** + ** 1) this is a read operation, and + ** 2) data is required from the start of this overflow page, and + ** 3) there are no dirty pages in the page-cache + ** 4) the database is file-backed, and + ** 5) the page is not in the WAL file + ** 6) at least 4 bytes have already been read into the output buffer + ** + ** then data can be read directly from the database file into the + ** output buffer, bypassing the page-cache altogether. This speeds + ** up loading large records that span many overflow pages. + */ + if( eOp==0 /* (1) */ + && offset==0 /* (2) */ + && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */ + && &pBuf[-4]>=pBufStart /* (6) */ + ){ + sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); + u8 aSave[4]; + u8 *aWrite = &pBuf[-4]; + assert( aWrite>=pBufStart ); /* due to (6) */ + memcpy(aSave, aWrite, 4); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + nextPage = get4byte(aWrite); + memcpy(aWrite, aSave, 4); + }else +#endif + + { + DbPage *pDbPage; + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, + (eOp==0 ? PAGER_GET_READONLY : 0) + ); + if( rc==SQLITE_OK ){ + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; + } + } + amt -= a; + if( amt==0 ) return rc; + pBuf += a; + } + if( rc ) break; + iIdx++; + } + } + + if( rc==SQLITE_OK && amt>0 ){ + /* Overflow chain ends prematurely */ + return SQLITE_CORRUPT_PAGE(pPage); + } + return rc; +} + +/* +** Read part of the payload for the row at which that cursor pCur is currently +** pointing. "amt" bytes will be transferred into pBuf[]. The transfer +** begins at "offset". +** +** pCur can be pointing to either a table or an index b-tree. +** If pointing to a table btree, then the content section is read. If +** pCur is pointing to an index b-tree then the key section is read. +** +** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing +** to a valid row in the table. For sqlite3BtreePayloadChecked(), the +** cursor might be invalid or might need to be restored before being read. +** +** Return SQLITE_OK on success or an error code if anything goes +** wrong. An error is returned if "offset+amt" is larger than +** the available payload. +*/ +SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->pPage ); + return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); +} + +/* +** This variant of sqlite3BtreePayload() works even if the cursor has not +** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read() +** interface. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +static SQLITE_NOINLINE int accessPayloadChecked( + BtCursor *pCur, + u32 offset, + u32 amt, + void *pBuf +){ + int rc; + if ( pCur->eState==CURSOR_INVALID ){ + return SQLITE_ABORT; + } + assert( cursorOwnsBtShared(pCur) ); + rc = btreeRestoreCursorPosition(pCur); + return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0); +} +SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + if( pCur->eState==CURSOR_VALID ){ + assert( cursorOwnsBtShared(pCur) ); + return accessPayload(pCur, offset, amt, pBuf, 0); + }else{ + return accessPayloadChecked(pCur, offset, amt, pBuf); + } +} +#endif /* SQLITE_OMIT_INCRBLOB */ + +/* +** Return a pointer to payload information from the entry that the +** pCur cursor is pointing to. The pointer is to the beginning of +** the key if index btrees (pPage->intKey==0) and is the data for +** table btrees (pPage->intKey==1). The number of bytes of available +** key/data is written into *pAmt. If *pAmt==0, then the value +** returned will not be a valid pointer. +** +** This routine is an optimization. It is common for the entire key +** and data to fit on the local page and for there to be no overflow +** pages. When that is so, this routine can be used to access the +** key and data without making a copy. If the key and/or data spills +** onto overflow pages, then accessPayload() must be used to reassemble +** the key/data and copy it into a preallocated buffer. +** +** The pointer returned by this routine looks directly into the cached +** page of the database. The data might change or move the next time +** any btree routine is called. +*/ +static const void *fetchPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 *pAmt /* Write the number of available bytes here */ +){ + int amt; + assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); + assert( pCur->eState==CURSOR_VALID ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); + assert( pCur->info.nSize>0 ); + assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB ); + assert( pCur->info.pPayloadpPage->aDataEnd ||CORRUPT_DB); + amt = pCur->info.nLocal; + if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){ + /* There is too little space on the page for the expected amount + ** of local content. Database must be corrupt. */ + assert( CORRUPT_DB ); + amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload)); + } + *pAmt = (u32)amt; + return (void*)pCur->info.pPayload; +} + + +/* +** For the entry that cursor pCur is point to, return as +** many bytes of the key or data as are available on the local +** b-tree page. Write the number of available bytes into *pAmt. +** +** The pointer returned is ephemeral. The key/data may move +** or be destroyed on the next call to any Btree routine, +** including calls from other threads against the same cache. +** Hence, a mutex on the BtShared should be held prior to calling +** this routine. +** +** These routines is used to get quick access to key and data +** in the common case where no overflow pages are used. +*/ +SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ + return fetchPayload(pCur, pAmt); +} + + +/* +** Move the cursor down to a new child page. The newPgno argument is the +** page number of the child page to move to. +** +** This function returns SQLITE_CORRUPT if the page-header flags field of +** the new child page does not match the flags field of the parent (i.e. +** if an intkey page appears to be the parent of a non-intkey page, or +** vice-versa). +*/ +static int moveToChild(BtCursor *pCur, u32 newPgno){ + int rc; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPageiPage>=0 ); + if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + pCur->aiIdx[pCur->iPage] = pCur->ix; + pCur->apPage[pCur->iPage] = pCur->pPage; + pCur->ix = 0; + pCur->iPage++; + rc = getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur->curPagerFlags); + assert( pCur->pPage!=0 || rc!=SQLITE_OK ); + if( rc==SQLITE_OK + && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) + ){ + releasePage(pCur->pPage); + rc = SQLITE_CORRUPT_PGNO(newPgno); + } + if( rc ){ + pCur->pPage = pCur->apPage[--pCur->iPage]; + } + return rc; +} + +#ifdef SQLITE_DEBUG +/* +** Page pParent is an internal (non-leaf) tree page. This function +** asserts that page number iChild is the left-child if the iIdx'th +** cell in page pParent. Or, if iIdx is equal to the total number of +** cells in pParent, that page number iChild is the right-child of +** the page. +*/ +static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ + if( CORRUPT_DB ) return; /* The conditions tested below might not be true + ** in a corrupt database */ + assert( iIdx<=pParent->nCell ); + if( iIdx==pParent->nCell ){ + assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild ); + }else{ + assert( get4byte(findCell(pParent, iIdx))==iChild ); + } +} +#else +# define assertParentIndex(x,y,z) +#endif + +/* +** Move the cursor up to the parent page. +** +** pCur->idx is set to the cell index that contains the pointer +** to the page we are coming from. If we are coming from the +** right-most child page then pCur->idx is set to one more than +** the largest cell index. +*/ +static void moveToParent(BtCursor *pCur){ + MemPage *pLeaf; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>0 ); + assert( pCur->pPage ); + assertParentIndex( + pCur->apPage[pCur->iPage-1], + pCur->aiIdx[pCur->iPage-1], + pCur->pPage->pgno + ); + testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + pCur->ix = pCur->aiIdx[pCur->iPage-1]; + pLeaf = pCur->pPage; + pCur->pPage = pCur->apPage[--pCur->iPage]; + releasePageNotNull(pLeaf); +} + +/* +** Move the cursor to point to the root page of its b-tree structure. +** +** If the table has a virtual root page, then the cursor is moved to point +** to the virtual root page instead of the actual root page. A table has a +** virtual root page when the actual root page contains no cells and a +** single child page. This can only happen with the table rooted at page 1. +** +** If the b-tree structure is empty, the cursor state is set to +** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise, +** the cursor is set to point to the first cell located on the root +** (or virtual root) page and the cursor state is set to CURSOR_VALID. +** +** If this function returns successfully, it may be assumed that the +** page-header flags indicate that the [virtual] root-page is the expected +** kind of b-tree page (i.e. if when opening the cursor the caller did not +** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, +** indicating a table b-tree, or if the caller did specify a KeyInfo +** structure the flags byte is set to 0x02 or 0x0A, indicating an index +** b-tree). +*/ +static int moveToRoot(BtCursor *pCur){ + MemPage *pRoot; + int rc = SQLITE_OK; + + assert( cursorOwnsBtShared(pCur) ); + assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); + assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 ); + assert( pCur->pgnoRoot>0 || pCur->iPage<0 ); + + if( pCur->iPage>=0 ){ + if( pCur->iPage ){ + releasePageNotNull(pCur->pPage); + while( --pCur->iPage ){ + releasePageNotNull(pCur->apPage[pCur->iPage]); + } + pRoot = pCur->pPage = pCur->apPage[0]; + goto skip_init; + } + }else if( pCur->pgnoRoot==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_EMPTY; + }else{ + assert( pCur->iPage==(-1) ); + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + if( pCur->eState==CURSOR_FAULT ){ + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + sqlite3BtreeClearCursor(pCur); + } + rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, + pCur->curPagerFlags); + if( rc!=SQLITE_OK ){ + pCur->eState = CURSOR_INVALID; + return rc; + } + pCur->iPage = 0; + pCur->curIntKey = pCur->pPage->intKey; + } + pRoot = pCur->pPage; + assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB ); + + /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor + ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is + ** NULL, the caller expects a table b-tree. If this is not the case, + ** return an SQLITE_CORRUPT error. + ** + ** Earlier versions of SQLite assumed that this test could not fail + ** if the root page was already loaded when this function was called (i.e. + ** if pCur->iPage>=0). But this is not so if the database is corrupted + ** in such a way that page pRoot is linked into a second b-tree table + ** (or the freelist). */ + assert( pRoot->intKey==1 || pRoot->intKey==0 ); + if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ + return SQLITE_CORRUPT_PAGE(pCur->pPage); + } + +skip_init: + pCur->ix = 0; + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); + + if( pRoot->nCell>0 ){ + pCur->eState = CURSOR_VALID; + }else if( !pRoot->leaf ){ + Pgno subpage; + if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; + subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); + pCur->eState = CURSOR_VALID; + rc = moveToChild(pCur, subpage); + }else{ + pCur->eState = CURSOR_INVALID; + rc = SQLITE_EMPTY; + } + return rc; +} + +/* +** Move the cursor down to the left-most leaf entry beneath the +** entry to which it is currently pointing. +** +** The left-most leaf is the one with the smallest key - the first +** in ascending order. +*/ +static int moveToLeftmost(BtCursor *pCur){ + Pgno pgno; + int rc = SQLITE_OK; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ + assert( pCur->ixnCell ); + pgno = get4byte(findCell(pPage, pCur->ix)); + rc = moveToChild(pCur, pgno); + } + return rc; +} + +/* +** Move the cursor down to the right-most leaf entry beneath the +** page to which it is currently pointing. Notice the difference +** between moveToLeftmost() and moveToRightmost(). moveToLeftmost() +** finds the left-most entry beneath the *entry* whereas moveToRightmost() +** finds the right-most entry beneath the *page*. +** +** The right-most entry is the one with the largest key - the last +** key in ascending order. +*/ +static int moveToRightmost(BtCursor *pCur){ + Pgno pgno; + int rc = SQLITE_OK; + MemPage *pPage = 0; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( !(pPage = pCur->pPage)->leaf ){ + pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + pCur->ix = pPage->nCell; + rc = moveToChild(pCur, pgno); + if( rc ) return rc; + } + pCur->ix = pPage->nCell-1; + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & BTCF_ValidNKey)==0 ); + return SQLITE_OK; +} + +/* Move the cursor to the first entry in the table. Return SQLITE_OK +** on success. Set *pRes to 0 if the cursor actually points to something +** or set *pRes to 1 if the table is empty. +*/ +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->pPage->nCell>0 ); + *pRes = 0; + rc = moveToLeftmost(pCur); + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) ); + *pRes = 1; + rc = SQLITE_OK; + } + return rc; +} + +/* Move the cursor to the last entry in the table. Return SQLITE_OK +** on success. Set *pRes to 0 if the cursor actually points to something +** or set *pRes to 1 if the table is empty. +*/ +static SQLITE_NOINLINE int btreeLast(BtCursor *pCur, int *pRes){ + int rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; + }else{ + pCur->curFlags &= ~BTCF_AtLast; + } + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; + } + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* If the cursor already points to the last entry, this is a no-op. */ + if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ +#ifdef SQLITE_DEBUG + /* This block serves to assert() that the cursor really does point + ** to the last entry in the b-tree. */ + int ii; + for(ii=0; iiiPage; ii++){ + assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); + } + assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB ); + testcase( pCur->ix!=pCur->pPage->nCell-1 ); + /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */ + assert( pCur->pPage->leaf ); +#endif + *pRes = 0; + return SQLITE_OK; + } + return btreeLast(pCur, pRes); +} + +/* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) +** table near the key intKey. Return a success code. +** +** If an exact match is not found, then the cursor is always +** left pointing at a leaf page which would hold the entry if it +** were present. The cursor might point to an entry that comes +** before or after the key. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than intKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches intKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than intKey. +*/ +SQLITE_PRIVATE int sqlite3BtreeTableMoveto( + BtCursor *pCur, /* The cursor to be moved */ + i64 intKey, /* The table key */ + int biasRight, /* If true, bias the search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( pCur->pKeyInfo==0 ); + assert( pCur->eState!=CURSOR_VALID || pCur->curIntKey!=0 ); + + /* If the cursor is already positioned at the point we are trying + ** to move to, then just return without doing any work */ + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 ){ + if( pCur->info.nKey==intKey ){ + *pRes = 0; + return SQLITE_OK; + } + if( pCur->info.nKeycurFlags & BTCF_AtLast)!=0 ){ + *pRes = -1; + return SQLITE_OK; + } + /* If the requested key is one more than the previous key, then + ** try to get there using sqlite3BtreeNext() rather than a full + ** binary search. This is an optimization only. The correct answer + ** is still obtained without this case, only a little more slowly. */ + if( pCur->info.nKey+1==intKey ){ + *pRes = 0; + rc = sqlite3BtreeNext(pCur, 0); + if( rc==SQLITE_OK ){ + getCellInfo(pCur); + if( pCur->info.nKey==intKey ){ + return SQLITE_OK; + } + }else if( rc!=SQLITE_DONE ){ + return rc; + } + } + } + } + +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif + + rc = moveToRoot(pCur); + if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } + return rc; + } + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->curIntKey ); + + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->pPage; + u8 *pCell; /* Pointer to current cell in pPage */ + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey ); + lwr = 0; + upr = pPage->nCell-1; + assert( biasRight==0 || biasRight==1 ); + idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ + for(;;){ + i64 nCellKey; + pCell = findCellPastPtr(pPage, idx); + if( pPage->intKeyLeaf ){ + while( 0x80 <= *(pCell++) ){ + if( pCell>=pPage->aDataEnd ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + } + getVarint(pCell, (u64*)&nCellKey); + if( nCellKeyupr ){ c = -1; break; } + }else if( nCellKey>intKey ){ + upr = idx-1; + if( lwr>upr ){ c = +1; break; } + }else{ + assert( nCellKey==intKey ); + pCur->ix = (u16)idx; + if( !pPage->leaf ){ + lwr = idx; + goto moveto_table_next_layer; + }else{ + pCur->curFlags |= BTCF_ValidNKey; + pCur->info.nKey = nCellKey; + pCur->info.nSize = 0; + *pRes = 0; + return SQLITE_OK; + } + } + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ + } + assert( lwr==upr+1 || !pPage->leaf ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->ixpPage->nCell ); + pCur->ix = (u16)idx; + *pRes = c; + rc = SQLITE_OK; + goto moveto_table_finish; + } +moveto_table_next_layer: + if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + pCur->ix = (u16)lwr; + rc = moveToChild(pCur, chldPg); + if( rc ) break; + } +moveto_table_finish: + pCur->info.nSize = 0; + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + return rc; +} + +/* +** Compare the "idx"-th cell on the page the cursor pCur is currently +** pointing to to pIdxKey using xRecordCompare. Return negative or +** zero if the cell is less than or equal pIdxKey. Return positive +** if unknown. +** +** Return value negative: Cell at pCur[idx] less than pIdxKey +** +** Return value is zero: Cell at pCur[idx] equals pIdxKey +** +** Return value positive: Nothing is known about the relationship +** of the cell at pCur[idx] and pIdxKey. +** +** This routine is part of an optimization. It is always safe to return +** a positive value as that will cause the optimization to be skipped. +*/ +static int indexCellCompare( + BtCursor *pCur, + int idx, + UnpackedRecord *pIdxKey, + RecordCompare xRecordCompare +){ + MemPage *pPage = pCur->pPage; + int c; + int nCell; /* Size of the pCell cell in bytes */ + u8 *pCell = findCellPastPtr(pPage, idx); + + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* If the record extends into overflow pages, do not attempt + ** the optimization. */ + c = 99; + } + return c; +} + +/* +** Return true (non-zero) if pCur is current pointing to the last +** page of a table. +*/ +static int cursorOnLastPage(BtCursor *pCur){ + int i; + assert( pCur->eState==CURSOR_VALID ); + for(i=0; iiPage; i++){ + MemPage *pPage = pCur->apPage[i]; + if( pCur->aiIdx[i]nCell ) return 0; + } + return 1; +} + +/* Move the cursor so that it points to an entry in an index table +** near the key pIdxKey. Return a success code. +** +** If an exact match is not found, then the cursor is always +** left pointing at a leaf page which would hold the entry if it +** were present. The cursor might point to an entry that comes +** before or after the key. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than pIdxKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches pIdxKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than pIdxKey. +** +** The pIdxKey->eqSeen field is set to 1 if there +** exists an entry in the table that exactly matches pIdxKey. +*/ +SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( + BtCursor *pCur, /* The cursor to be moved */ + UnpackedRecord *pIdxKey, /* Unpacked index key */ + int *pRes /* Write search results here */ +){ + int rc; + RecordCompare xRecordCompare; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( pCur->pKeyInfo!=0 ); + +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif + + xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); + pIdxKey->errCode = 0; + assert( pIdxKey->default_rc==1 + || pIdxKey->default_rc==0 + || pIdxKey->default_rc==-1 + ); + + + /* Check to see if we can skip a lot of work. Two cases: + ** + ** (1) If the cursor is already pointing to the very last cell + ** in the table and the pIdxKey search key is greater than or + ** equal to that last cell, then no movement is required. + ** + ** (2) If the cursor is on the last page of the table and the first + ** cell on that last page is less than or equal to the pIdxKey + ** search key, then we can start the search on the current page + ** without needing to go back to root. + */ + if( pCur->eState==CURSOR_VALID + && pCur->pPage->leaf + && cursorOnLastPage(pCur) + ){ + int c; + if( pCur->ix==pCur->pPage->nCell-1 + && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 + && pIdxKey->errCode==SQLITE_OK + ){ + *pRes = c; + return SQLITE_OK; /* Cursor already pointing at the correct spot */ + } + if( pCur->iPage>0 + && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 + && pIdxKey->errCode==SQLITE_OK + ){ + pCur->curFlags &= ~BTCF_ValidOvfl; + if( !pCur->pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } + goto bypass_moveto_root; /* Start search on the current page */ + } + pIdxKey->errCode = SQLITE_OK; + } + + rc = moveToRoot(pCur); + if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } + return rc; + } + +bypass_moveto_root: + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->curIntKey==0 ); + assert( pIdxKey!=0 ); + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->pPage; + u8 *pCell; /* Pointer to current cell in pPage */ + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey==0 ); + lwr = 0; + upr = pPage->nCell-1; + idx = upr>>1; /* idx = (lwr+upr)/2; */ + for(;;){ + int nCell; /* Size of the pCell cell in bytes */ + pCell = findCellPastPtr(pPage, idx); + + /* The maximum supported page-size is 65536 bytes. This means that + ** the maximum number of record bytes stored on an index B-Tree + ** page is less than 16384 bytes and may be stored as a 2-byte + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first + ** 2 bytes of the cell. + */ + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* The record flows over onto one or more overflow pages. In + ** this case the whole cell needs to be parsed, a buffer allocated + ** and accessPayload() used to retrieve the record into the + ** buffer before VdbeRecordCompare() can be called. + ** + ** If the record is corrupt, the xRecordCompare routine may read + ** up to two varints past the end of the buffer. An extra 18 + ** bytes of padding is allocated at the end of the buffer in + ** case this happens. */ + void *pCellKey; + u8 * const pCellBody = pCell - pPage->childPtrSize; + const int nOverrun = 18; /* Size of the overrun padding */ + pPage->xParseCell(pPage, pCellBody, &pCur->info); + nCell = (int)pCur->info.nKey; + testcase( nCell<0 ); /* True if key size is 2^32 or more */ + testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */ + testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ + testcase( nCell==2 ); /* Minimum legal index key size */ + if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + goto moveto_index_finish; + } + pCellKey = sqlite3Malloc( nCell+nOverrun ); + if( pCellKey==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto moveto_index_finish; + } + pCur->ix = (u16)idx; + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */ + pCur->curFlags &= ~BTCF_ValidOvfl; + if( rc ){ + sqlite3_free(pCellKey); + goto moveto_index_finish; + } + c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); + } + assert( + (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) + && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) + ); + if( c<0 ){ + lwr = idx+1; + }else if( c>0 ){ + upr = idx-1; + }else{ + assert( c==0 ); + *pRes = 0; + rc = SQLITE_OK; + pCur->ix = (u16)idx; + if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT; + goto moveto_index_finish; + } + if( lwr>upr ) break; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ + } + assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->ixpPage->nCell || CORRUPT_DB ); + pCur->ix = (u16)idx; + *pRes = c; + rc = SQLITE_OK; + goto moveto_index_finish; + } + if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + + /* This block is similar to an in-lined version of: + ** + ** pCur->ix = (u16)lwr; + ** rc = moveToChild(pCur, chldPg); + ** if( rc ) break; + */ + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + pCur->aiIdx[pCur->iPage] = (u16)lwr; + pCur->apPage[pCur->iPage] = pCur->pPage; + pCur->ix = 0; + pCur->iPage++; + rc = getAndInitPage(pCur->pBt, chldPg, &pCur->pPage, pCur->curPagerFlags); + if( rc==SQLITE_OK + && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) + ){ + releasePage(pCur->pPage); + rc = SQLITE_CORRUPT_PGNO(chldPg); + } + if( rc ){ + pCur->pPage = pCur->apPage[--pCur->iPage]; + break; + } + /* + ***** End of in-lined moveToChild() call */ + } +moveto_index_finish: + pCur->info.nSize = 0; + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + return rc; +} + + +/* +** Return TRUE if the cursor is not pointing at an entry of the table. +** +** TRUE will be returned after a call to sqlite3BtreeNext() moves +** past the last entry in the table or sqlite3BtreePrev() moves past +** the first entry. TRUE is also returned if the table is empty. +*/ +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){ + /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries + ** have been deleted? This API will need to change to return an error code + ** as well as the boolean result value. + */ + return (CURSOR_VALID!=pCur->eState); +} + +/* +** Return an estimate for the number of rows in the table that pCur is +** pointing to. Return a negative number if no estimate is currently +** available. +*/ +SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ + i64 n; + u8 i; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* Currently this interface is only called by the OP_IfSmaller + ** opcode, and it that case the cursor will always be valid and + ** will always point to a leaf node. */ + if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; + if( NEVER(pCur->pPage->leaf==0) ) return -1; + + n = pCur->pPage->nCell; + for(i=0; iiPage; i++){ + n *= pCur->apPage[i]->nCell; + } + return n; +} + +/* +** Advance the cursor to the next entry in the database. +** Return value: +** +** SQLITE_OK success +** SQLITE_DONE cursor is already pointing at the last element +** otherwise some kind of error occurred +** +** The main entry point is sqlite3BtreeNext(). That routine is optimized +** for the common case of merely incrementing the cell counter BtCursor.aiIdx +** to the next cell on the current page. The (slower) btreeNext() helper +** routine is called when it is necessary to move to a different page or +** to restore the cursor. +** +** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the +** cursor corresponds to an SQL index and this routine could have been +** skipped if the SQL index had been a unique index. The F argument +** is a hint to the implement. SQLite btree implementation does not use +** this hint, but COMDB2 does. +*/ +static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ + int rc; + int idx; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + if( pCur->eState!=CURSOR_VALID ){ + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + if( CURSOR_INVALID==pCur->eState ){ + return SQLITE_DONE; + } + if( pCur->eState==CURSOR_SKIPNEXT ){ + pCur->eState = CURSOR_VALID; + if( pCur->skipNext>0 ) return SQLITE_OK; + } + } + + pPage = pCur->pPage; + idx = ++pCur->ix; + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } + + if( idx>=pPage->nCell ){ + if( !pPage->leaf ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + if( rc ) return rc; + return moveToLeftmost(pCur); + } + do{ + if( pCur->iPage==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_DONE; + } + moveToParent(pCur); + pPage = pCur->pPage; + }while( pCur->ix>=pPage->nCell ); + if( pPage->intKey ){ + return sqlite3BtreeNext(pCur, 0); + }else{ + return SQLITE_OK; + } + } + if( pPage->leaf ){ + return SQLITE_OK; + }else{ + return moveToLeftmost(pCur); + } +} +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){ + MemPage *pPage; + UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ + assert( cursorOwnsBtShared(pCur) ); + assert( flags==0 || flags==1 ); + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); + pPage = pCur->pPage; + if( (++pCur->ix)>=pPage->nCell ){ + pCur->ix--; + return btreeNext(pCur); + } + if( pPage->leaf ){ + return SQLITE_OK; + }else{ + return moveToLeftmost(pCur); + } +} + +/* +** Step the cursor to the back to the previous entry in the database. +** Return values: +** +** SQLITE_OK success +** SQLITE_DONE the cursor is already on the first element of the table +** otherwise some kind of error occurred +** +** The main entry point is sqlite3BtreePrevious(). That routine is optimized +** for the common case of merely decrementing the cell counter BtCursor.aiIdx +** to the previous cell on the current page. The (slower) btreePrevious() +** helper routine is called when it is necessary to move to a different page +** or to restore the cursor. +** +** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then +** the cursor corresponds to an SQL index and this routine could have been +** skipped if the SQL index had been a unique index. The F argument is a +** hint to the implement. The native SQLite btree implementation does not +** use this hint, but COMDB2 does. +*/ +static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ + int rc; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); + assert( pCur->info.nSize==0 ); + if( pCur->eState!=CURSOR_VALID ){ + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + if( CURSOR_INVALID==pCur->eState ){ + return SQLITE_DONE; + } + if( CURSOR_SKIPNEXT==pCur->eState ){ + pCur->eState = CURSOR_VALID; + if( pCur->skipNext<0 ) return SQLITE_OK; + } + } + + pPage = pCur->pPage; + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } + if( !pPage->leaf ){ + int idx = pCur->ix; + rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); + if( rc ) return rc; + rc = moveToRightmost(pCur); + }else{ + while( pCur->ix==0 ){ + if( pCur->iPage==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_DONE; + } + moveToParent(pCur); + } + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); + + pCur->ix--; + pPage = pCur->pPage; + if( pPage->intKey && !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, 0); + }else{ + rc = SQLITE_OK; + } + } + return rc; +} +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){ + assert( cursorOwnsBtShared(pCur) ); + assert( flags==0 || flags==1 ); + UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); + pCur->info.nSize = 0; + if( pCur->eState!=CURSOR_VALID + || pCur->ix==0 + || pCur->pPage->leaf==0 + ){ + return btreePrevious(pCur); + } + pCur->ix--; + return SQLITE_OK; +} + +/* +** Allocate a new page from the database file. +** +** The new page is marked as dirty. (In other words, sqlite3PagerWrite() +** has already been called on the new page.) The new page has also +** been referenced and the calling routine is responsible for calling +** sqlite3PagerUnref() on the new page when it is done. +** +** SQLITE_OK is returned on success. Any other return value indicates +** an error. *ppPage is set to NULL in the event of an error. +** +** If the "nearby" parameter is not 0, then an effort is made to +** locate a page close to the page number "nearby". This can be used in an +** attempt to keep related pages close to each other in the database file, +** which in turn can make database access faster. +** +** If the eMode parameter is BTALLOC_EXACT and the nearby page exists +** anywhere on the free-list, then it is guaranteed to be returned. If +** eMode is BTALLOC_LT then the page returned will be less than or equal +** to nearby if any such page exists. If eMode is BTALLOC_ANY then there +** are no restrictions on which page is returned. +*/ +static int allocateBtreePage( + BtShared *pBt, /* The btree */ + MemPage **ppPage, /* Store pointer to the allocated page here */ + Pgno *pPgno, /* Store the page number here */ + Pgno nearby, /* Search for a page near this one */ + u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */ +){ + MemPage *pPage1; + int rc; + u32 n; /* Number of pages on the freelist */ + u32 k; /* Number of leaves on the trunk of the freelist */ + MemPage *pTrunk = 0; + MemPage *pPrevTrunk = 0; + Pgno mxPage; /* Total size of the database file */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); + pPage1 = pBt->pPage1; + mxPage = btreePagecount(pBt); + /* EVIDENCE-OF: R-21003-45125 The 4-byte big-endian integer at offset 36 + ** stores the total number of pages on the freelist. */ + n = get4byte(&pPage1->aData[36]); + testcase( n==mxPage-1 ); + if( n>=mxPage ){ + return SQLITE_CORRUPT_BKPT; + } + if( n>0 ){ + /* There are pages on the freelist. Reuse one of those pages. */ + Pgno iTrunk; + u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ + u32 nSearch = 0; /* Count of the number of search attempts */ + + /* If eMode==BTALLOC_EXACT and a query of the pointer-map + ** shows that the page 'nearby' is somewhere on the free-list, then + ** the entire-list will be searched for that page. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( eMode==BTALLOC_EXACT ){ + if( nearby<=mxPage ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==PTRMAP_FREEPAGE ){ + searchList = 1; + } + } + }else if( eMode==BTALLOC_LE ){ + searchList = 1; + } +#endif + + /* Decrement the free-list count by 1. Set iTrunk to the index of the + ** first free-list trunk page. iPrevTrunk is initially 1. + */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) return rc; + put4byte(&pPage1->aData[36], n-1); + + /* The code within this loop is run only once if the 'searchList' variable + ** is not true. Otherwise, it runs once for each trunk-page on the + ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT) + ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT) + */ + do { + pPrevTrunk = pTrunk; + if( pPrevTrunk ){ + /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page + ** is the page number of the next freelist trunk page in the list or + ** zero if this is the last freelist trunk page. */ + iTrunk = get4byte(&pPrevTrunk->aData[0]); + }else{ + /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32 + ** stores the page number of the first page of the freelist, or zero if + ** the freelist is empty. */ + iTrunk = get4byte(&pPage1->aData[32]); + } + testcase( iTrunk==mxPage ); + if( iTrunk>mxPage || nSearch++ > n ){ + rc = SQLITE_CORRUPT_PGNO(pPrevTrunk ? pPrevTrunk->pgno : 1); + }else{ + rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0); + } + if( rc ){ + pTrunk = 0; + goto end_allocate_page; + } + assert( pTrunk!=0 ); + assert( pTrunk->aData!=0 ); + /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page + ** is the number of leaf page pointers to follow. */ + k = get4byte(&pTrunk->aData[4]); + if( k==0 && !searchList ){ + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly + ** allocated page */ + assert( pPrevTrunk==0 ); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + *pPgno = iTrunk; + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + *ppPage = pTrunk; + pTrunk = 0; + TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); + }else if( k>(u32)(pBt->usableSize/4 - 2) ){ + /* Value of k is out of range. Database corruption */ + rc = SQLITE_CORRUPT_PGNO(iTrunk); + goto end_allocate_page; +#ifndef SQLITE_OMIT_AUTOVACUUM + }else if( searchList + && (nearby==iTrunk || (iTrunkpDbPage); + if( rc ){ + goto end_allocate_page; + } + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + /* The trunk page is required by the caller but it contains + ** pointers to free-list leaves. The first leaf becomes a trunk + ** page in this case. + */ + MemPage *pNewTrunk; + Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); + if( iNewTrunk>mxPage ){ + rc = SQLITE_CORRUPT_PGNO(iTrunk); + goto end_allocate_page; + } + testcase( iNewTrunk==mxPage ); + rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + rc = sqlite3PagerWrite(pNewTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pNewTrunk); + goto end_allocate_page; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + releasePage(pNewTrunk); + if( !pPrevTrunk ){ + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); + put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + } + pTrunk = 0; + TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); +#endif + }else if( k>0 ){ + /* Extract a leaf from the trunk */ + u32 closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + u32 i; + closest = 0; + if( eMode==BTALLOC_LE ){ + for(i=0; imxPage || iPage<2 ){ + rc = SQLITE_CORRUPT_PGNO(iTrunk); + goto end_allocate_page; + } + testcase( iPage==mxPage ); + if( !searchList + || (iPage==nearby || (iPagepgno, n-1)); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ) goto end_allocate_page; + if( closestpDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + *ppPage = 0; + } + } + searchList = 0; + } + } + releasePage(pPrevTrunk); + pPrevTrunk = 0; + }while( searchList ); + }else{ + /* There are no pages on the freelist, so append a new page to the + ** database image. + ** + ** Normally, new pages allocated by this block can be requested from the + ** pager layer with the 'no-content' flag set. This prevents the pager + ** from trying to read the pages content from disk. However, if the + ** current transaction has already run one or more incremental-vacuum + ** steps, then the page we are about to allocate may contain content + ** that is required in the event of a rollback. In this case, do + ** not set the no-content flag. This causes the pager to load and journal + ** the current page content before overwriting it. + ** + ** Note that the pager will not actually attempt to load or journal + ** content for any page that really does lie past the end of the database + ** file on disk. So the effects of disabling the no-content optimization + ** here are confined to those pages that lie between the end of the + ** database image and the end of the database file. + */ + int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0; + + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){ + /* If *pPgno refers to a pointer-map page, allocate two new pages + ** at the end of the file instead of one. The first allocated page + ** becomes a new pointer-map page, the second is used by the caller. + */ + MemPage *pPg = 0; + TRACE(("ALLOCATE: %u from end of file (pointer-map page)\n", pBt->nPage)); + assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg->pDbPage); + releasePage(pPg); + } + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } + } +#endif + put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); + *pPgno = pBt->nPage; + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent); + if( rc ) return rc; + rc = sqlite3PagerWrite((*ppPage)->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + *ppPage = 0; + } + TRACE(("ALLOCATE: %u from end of file\n", *pPgno)); + } + + assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); + +end_allocate_page: + releasePage(pTrunk); + releasePage(pPrevTrunk); + assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 ); + assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 ); + return rc; +} + +/* +** This function is used to add page iPage to the database file free-list. +** It is assumed that the page is not already a part of the free-list. +** +** The value passed as the second argument to this function is optional. +** If the caller happens to have a pointer to the MemPage object +** corresponding to page iPage handy, it may pass it as the second value. +** Otherwise, it may pass NULL. +** +** If a pointer to a MemPage object is passed as the second argument, +** its reference count is not altered by this function. +*/ +static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ + MemPage *pTrunk = 0; /* Free-list trunk page */ + Pgno iTrunk = 0; /* Page number of free-list trunk page */ + MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */ + MemPage *pPage; /* Page being freed. May be NULL. */ + int rc; /* Return Code */ + u32 nFree; /* Initial number of pages on free-list */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( CORRUPT_DB || iPage>1 ); + assert( !pMemPage || pMemPage->pgno==iPage ); + + if( iPage<2 || iPage>pBt->nPage ){ + return SQLITE_CORRUPT_BKPT; + } + if( pMemPage ){ + pPage = pMemPage; + sqlite3PagerRef(pPage->pDbPage); + }else{ + pPage = btreePageLookup(pBt, iPage); + } + + /* Increment the free page count on pPage1 */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) goto freepage_out; + nFree = get4byte(&pPage1->aData[36]); + put4byte(&pPage1->aData[36], nFree+1); + + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + /* If the secure_delete option is enabled, then + ** always fully overwrite deleted information with zeros. + */ + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) + || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) + ){ + goto freepage_out; + } + memset(pPage->aData, 0, pPage->pBt->pageSize); + } + + /* If the database supports auto-vacuum, write an entry in the pointer-map + ** to indicate that the page is free. + */ + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); + if( rc ) goto freepage_out; + } + + /* Now manipulate the actual database free-list structure. There are two + ** possibilities. If the free-list is currently empty, or if the first + ** trunk page in the free-list is full, then this page will become a + ** new free-list trunk page. Otherwise, it will become a leaf of the + ** first trunk page in the current free-list. This block tests if it + ** is possible to add the page as a new free-list leaf. + */ + if( nFree!=0 ){ + u32 nLeaf; /* Initial number of leaf cells on trunk page */ + + iTrunk = get4byte(&pPage1->aData[32]); + if( iTrunk>btreePagecount(pBt) ){ + rc = SQLITE_CORRUPT_BKPT; + goto freepage_out; + } + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + + nLeaf = get4byte(&pTrunk->aData[4]); + assert( pBt->usableSize>32 ); + if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ + rc = SQLITE_CORRUPT_BKPT; + goto freepage_out; + } + if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ + /* In this case there is room on the trunk page to insert the page + ** being freed as a new leaf. + ** + ** Note that the trunk page is not really full until it contains + ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have + ** coded. But due to a coding error in versions of SQLite prior to + ** 3.6.0, databases with freelist trunk pages holding more than + ** usableSize/4 - 8 entries will be reported as corrupt. In order + ** to maintain backwards compatibility with older versions of SQLite, + ** we will continue to restrict the number of entries to usableSize/4 - 8 + ** for now. At some point in the future (once everyone has upgraded + ** to 3.6.0 or later) we should consider fixing the conditional above + ** to read "usableSize/4-2" instead of "usableSize/4-8". + ** + ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still + ** avoid using the last six entries in the freelist trunk page array in + ** order that database files created by newer versions of SQLite can be + ** read by older versions of SQLite. + */ + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pTrunk->aData[4], nLeaf+1); + put4byte(&pTrunk->aData[8+nLeaf*4], iPage); + if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ + sqlite3PagerDontWrite(pPage->pDbPage); + } + rc = btreeSetHasContent(pBt, iPage); + } + TRACE(("FREE-PAGE: %u leaf on trunk page %u\n",pPage->pgno,pTrunk->pgno)); + goto freepage_out; + } + } + + /* If control flows to this point, then it was not possible to add the + ** the page being freed as a leaf page of the first trunk in the free-list. + ** Possibly because the free-list is empty, or possibly because the + ** first trunk in the free-list is full. Either way, the page being freed + ** will become the new first trunk page in the free-list. + */ + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ + goto freepage_out; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + put4byte(pPage->aData, iTrunk); + put4byte(&pPage->aData[4], 0); + put4byte(&pPage1->aData[32], iPage); + TRACE(("FREE-PAGE: %u new trunk page replacing %u\n", pPage->pgno, iTrunk)); + +freepage_out: + if( pPage ){ + pPage->isInit = 0; + } + releasePage(pPage); + releasePage(pTrunk); + return rc; +} +static void freePage(MemPage *pPage, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); + } +} + +/* +** Free the overflow pages associated with the given Cell. +*/ +static SQLITE_NOINLINE int clearCellOverflow( + MemPage *pPage, /* The page that contains the Cell */ + unsigned char *pCell, /* First byte of the Cell */ + CellInfo *pInfo /* Size information about the cell */ +){ + BtShared *pBt; + Pgno ovflPgno; + int rc; + int nOvfl; + u32 ovflPageSize; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pInfo->nLocal!=pInfo->nPayload ); + testcase( pCell + pInfo->nSize == pPage->aDataEnd ); + testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd ); + if( pCell + pInfo->nSize > pPage->aDataEnd ){ + /* Cell extends past end of page */ + return SQLITE_CORRUPT_PAGE(pPage); + } + ovflPgno = get4byte(pCell + pInfo->nSize - 4); + pBt = pPage->pBt; + assert( pBt->usableSize > 4 ); + ovflPageSize = pBt->usableSize - 4; + nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; + assert( nOvfl>0 || + (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)btreePagecount(pBt) ){ + /* 0 is not a legal page number and page 1 cannot be an + ** overflow page. Therefore if ovflPgno<2 or past the end of the + ** file the database must be corrupt. */ + return SQLITE_CORRUPT_BKPT; + } + if( nOvfl ){ + rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext); + if( rc ) return rc; + } + + if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) + && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 + ){ + /* There is no reason any cursor should have an outstanding reference + ** to an overflow page belonging to a cell that is being deleted/updated. + ** So if there exists more than one reference to this page, then it + ** must not really be an overflow page and the database must be corrupt. + ** It is helpful to detect this before calling freePage2(), as + ** freePage2() may zero the page contents if secure-delete mode is + ** enabled. If this 'overflow' page happens to be a page that the + ** caller is iterating through or using in some other way, this + ** can be problematic. + */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = freePage2(pBt, pOvfl, ovflPgno); + } + + if( pOvfl ){ + sqlite3PagerUnref(pOvfl->pDbPage); + } + if( rc ) return rc; + ovflPgno = iNext; + } + return SQLITE_OK; +} + +/* Call xParseCell to compute the size of a cell. If the cell contains +** overflow, then invoke cellClearOverflow to clear out that overflow. +** Store the result code (SQLITE_OK or some error code) in rc. +** +** Implemented as macro to force inlining for performance. +*/ +#define BTREE_CLEAR_CELL(rc, pPage, pCell, sInfo) \ + pPage->xParseCell(pPage, pCell, &sInfo); \ + if( sInfo.nLocal!=sInfo.nPayload ){ \ + rc = clearCellOverflow(pPage, pCell, &sInfo); \ + }else{ \ + rc = SQLITE_OK; \ + } + + +/* +** Create the byte sequence used to represent a cell on page pPage +** and write that byte sequence into pCell[]. Overflow pages are +** allocated and filled in as necessary. The calling procedure +** is responsible for making sure sufficient space has been allocated +** for pCell[]. +** +** Note that pCell does not necessary need to point to the pPage->aData +** area. pCell might point to some temporary storage. The cell will +** be constructed in this temporary area then copied into pPage->aData +** later. +*/ +static int fillInCell( + MemPage *pPage, /* The page that contains the cell */ + unsigned char *pCell, /* Complete text of the cell */ + const BtreePayload *pX, /* Payload with which to construct the cell */ + int *pnSize /* Write cell size here */ +){ + int nPayload; + const u8 *pSrc; + int nSrc, n, rc, mn; + int spaceLeft; + MemPage *pToRelease; + unsigned char *pPrior; + unsigned char *pPayload; + BtShared *pBt; + Pgno pgnoOvfl; + int nHeader; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + /* pPage is not necessarily writeable since pCell might be auxiliary + ** buffer space that is separate from the pPage buffer area */ + assert( pCellaData || pCell>=&pPage->aData[pPage->pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + /* Fill in the header. */ + nHeader = pPage->childPtrSize; + if( pPage->intKey ){ + nPayload = pX->nData + pX->nZero; + pSrc = pX->pData; + nSrc = pX->nData; + assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */ + nHeader += putVarint32(&pCell[nHeader], nPayload); + nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); + }else{ + assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); + nSrc = nPayload = (int)pX->nKey; + pSrc = pX->pKey; + nHeader += putVarint32(&pCell[nHeader], nPayload); + } + + /* Fill in the payload */ + pPayload = &pCell[nHeader]; + if( nPayload<=pPage->maxLocal ){ + /* This is the common case where everything fits on the btree page + ** and no overflow pages are required. */ + n = nHeader + nPayload; + testcase( n==3 ); + testcase( n==4 ); + if( n<4 ){ + n = 4; + pPayload[nPayload] = 0; + } + *pnSize = n; + assert( nSrc<=nPayload ); + testcase( nSrcminLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + testcase( n==pPage->maxLocal ); + testcase( n==pPage->maxLocal+1 ); + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + pToRelease = 0; + pgnoOvfl = 0; + pBt = pPage->pBt; + + /* At this point variables should be set as follows: + ** + ** nPayload Total payload size in bytes + ** pPayload Begin writing payload here + ** spaceLeft Space available at pPayload. If nPayload>spaceLeft, + ** that means content must spill into overflow pages. + ** *pnSize Size of the local cell (not counting overflow pages) + ** pPrior Where to write the pgno of the first overflow page + ** + ** Use a call to btreeParseCellPtr() to verify that the values above + ** were computed correctly. + */ +#ifdef SQLITE_DEBUG + { + CellInfo info; + pPage->xParseCell(pPage, pCell, &info); + assert( nHeader==(int)(info.pPayload - pCell) ); + assert( info.nKey==pX->nKey ); + assert( *pnSize == info.nSize ); + assert( spaceLeft == info.nLocal ); + } +#endif + + /* Write the payload into the local Cell and any extra into overflow pages */ + while( 1 ){ + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>=n ){ + memcpy(pPayload, pSrc, n); + }else if( nSrc>0 ){ + n = nSrc; + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + if( nPayload<=0 ) break; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; + if( spaceLeft==0 ){ + MemPage *pOvfl = 0; +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ + if( pBt->autoVacuum ){ + do{ + pgnoOvfl++; + } while( + PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) + ); + } +#endif + rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, and the second or subsequent + ** overflow page is being allocated, add an entry to the pointer-map + ** for that page now. + ** + ** If this is the first overflow page, then write a partial entry + ** to the pointer-map. If we write nothing to this pointer-map slot, + ** then the optimistic overflow chain processing in clearCell() + ** may misinterpret the uninitialized values and delete the + ** wrong pages from the database. + */ + if( pBt->autoVacuum && rc==SQLITE_OK ){ + u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); + ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); + if( rc ){ + releasePage(pOvfl); + } + } +#endif + if( rc ){ + releasePage(pToRelease); + return rc; + } + + /* If pToRelease is not zero than pPrior points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPrior is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + put4byte(pPrior, pgnoOvfl); + releasePage(pToRelease); + pToRelease = pOvfl; + pPrior = pOvfl->aData; + put4byte(pPrior, 0); + pPayload = &pOvfl->aData[4]; + spaceLeft = pBt->usableSize - 4; + } + } + releasePage(pToRelease); + return SQLITE_OK; +} + +/* +** Remove the i-th cell from pPage. This routine effects pPage only. +** The cell content is not freed or deallocated. It is assumed that +** the cell content has been copied someplace else. This routine just +** removes the reference to the cell from pPage. +** +** "sz" must be the number of bytes in the cell. +*/ +static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ + u32 pc; /* Offset to cell content of cell being deleted */ + u8 *data; /* pPage->aData */ + u8 *ptr; /* Used to move bytes around within data[] */ + int rc; /* The return code */ + int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ + + if( *pRC ) return; + assert( idx>=0 ); + assert( idxnCell ); + assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->nFree>=0 ); + data = pPage->aData; + ptr = &pPage->aCellIdx[2*idx]; + assert( pPage->pBt->usableSize > (u32)(ptr-data) ); + pc = get2byte(ptr); + hdr = pPage->hdrOffset; + testcase( pc==(u32)get2byte(&data[hdr+5]) ); + testcase( pc+sz==pPage->pBt->usableSize ); + if( pc+sz > pPage->pBt->usableSize ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + rc = freeSpace(pPage, pc, sz); + if( rc ){ + *pRC = rc; + return; + } + pPage->nCell--; + if( pPage->nCell==0 ){ + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pPage->pBt->usableSize); + pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset + - pPage->childPtrSize - 8; + }else{ + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); + put2byte(&data[hdr+3], pPage->nCell); + pPage->nFree += 2; + } +} + +/* +** Insert a new cell on pPage at cell index "i". pCell points to the +** content of the cell. +** +** If the cell content will fit on the page, then put it there. If it +** will not fit, then make a copy of the cell content into pTemp if +** pTemp is not null. Regardless of pTemp, allocate a new entry +** in pPage->apOvfl[] and make it point to the cell content (either +** in pTemp or the original pCell) and also record its index. +** Allocating a new entry in pPage->aCell[] implies that +** pPage->nOverflow is incremented. +** +** The insertCellFast() routine below works exactly the same as +** insertCell() except that it lacks the pTemp and iChild parameters +** which are assumed zero. Other than that, the two routines are the +** same. +** +** Fixes or enhancements to this routine should be reflected in +** insertCellFast()! +*/ +static int insertCell( + MemPage *pPage, /* Page into which we are copying */ + int i, /* New cell becomes the i-th cell of the page */ + u8 *pCell, /* Content of the new cell */ + int sz, /* Bytes of content in pCell */ + u8 *pTemp, /* Temp storage space for pCell, if needed */ + Pgno iChild /* If non-zero, replace first 4 bytes with this value */ +){ + int idx = 0; /* Where to write new cell content in data[] */ + int j; /* Loop counter */ + u8 *data; /* The content of the whole page */ + u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ + + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( MX_CELL(pPage->pBt)<=10921 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); + assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); + assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); + assert( pPage->nFree>=0 ); + assert( iChild>0 ); + if( pPage->nOverflow || sz+2>pPage->nFree ){ + if( pTemp ){ + memcpy(pTemp, pCell, sz); + pCell = pTemp; + } + put4byte(pCell, iChild); + j = pPage->nOverflow++; + /* Comparison against ArraySize-1 since we hold back one extra slot + ** as a contingency. In other words, never need more than 3 overflow + ** slots but 4 are allocated, just to be safe. */ + assert( j < ArraySize(pPage->apOvfl)-1 ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; + + /* When multiple overflows occur, they are always sequential and in + ** sorted order. This invariants arise because multiple overflows can + ** only occur when inserting divider cells into the parent page during + ** balancing, and the dividers are adjacent and sorted. + */ + assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ + assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( NEVER(rc!=SQLITE_OK) ){ + return rc; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + assert( &data[pPage->cellOffset]==pPage->aCellIdx ); + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ return rc; } + /* The allocateSpace() routine guarantees the following properties + ** if it returns successfully */ + assert( idx >= 0 ); + assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nFree -= (u16)(2 + sz); + /* In a corrupt database where an entry in the cell index section of + ** a btree page has a value of 3 or less, the pCell value might point + ** as many as 4 bytes in front of the start of the aData buffer for + ** the source page. Make sure this does not cause problems by not + ** reading the first 4 bytes */ + memcpy(&data[idx+4], pCell+4, sz-4); + put4byte(&data[idx], iChild); + pIns = pPage->aCellIdx + i*2; + memmove(pIns+2, pIns, 2*(pPage->nCell - i)); + put2byte(pIns, idx); + pPage->nCell++; + /* increment the cell count */ + if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; + assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + int rc2 = SQLITE_OK; + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); + if( rc2 ) return rc2; + } +#endif + } + return SQLITE_OK; +} + +/* +** This variant of insertCell() assumes that the pTemp and iChild +** parameters are both zero. Use this variant in sqlite3BtreeInsert() +** for performance improvement, and also so that this variant is only +** called from that one place, and is thus inlined, and thus runs must +** faster. +** +** Fixes or enhancements to this routine should be reflected into +** the insertCell() routine. +*/ +static int insertCellFast( + MemPage *pPage, /* Page into which we are copying */ + int i, /* New cell becomes the i-th cell of the page */ + u8 *pCell, /* Content of the new cell */ + int sz /* Bytes of content in pCell */ +){ + int idx = 0; /* Where to write new cell content in data[] */ + int j; /* Loop counter */ + u8 *data; /* The content of the whole page */ + u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ + + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( MX_CELL(pPage->pBt)<=10921 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); + assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); + assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); + assert( pPage->nFree>=0 ); + assert( pPage->nOverflow==0 ); + if( sz+2>pPage->nFree ){ + j = pPage->nOverflow++; + /* Comparison against ArraySize-1 since we hold back one extra slot + ** as a contingency. In other words, never need more than 3 overflow + ** slots but 4 are allocated, just to be safe. */ + assert( j < ArraySize(pPage->apOvfl)-1 ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; + + /* When multiple overflows occur, they are always sequential and in + ** sorted order. This invariants arise because multiple overflows can + ** only occur when inserting divider cells into the parent page during + ** balancing, and the dividers are adjacent and sorted. + */ + assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ + assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + assert( &data[pPage->cellOffset]==pPage->aCellIdx ); + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ return rc; } + /* The allocateSpace() routine guarantees the following properties + ** if it returns successfully */ + assert( idx >= 0 ); + assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nFree -= (u16)(2 + sz); + memcpy(&data[idx], pCell, sz); + pIns = pPage->aCellIdx + i*2; + memmove(pIns+2, pIns, 2*(pPage->nCell - i)); + put2byte(pIns, idx); + pPage->nCell++; + /* increment the cell count */ + if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; + assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + int rc2 = SQLITE_OK; + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); + if( rc2 ) return rc2; + } +#endif + } + return SQLITE_OK; +} + +/* +** The following parameters determine how many adjacent pages get involved +** in a balancing operation. NN is the number of neighbors on either side +** of the page that participate in the balancing operation. NB is the +** total number of pages that participate, including the target page and +** NN neighbors on either side. +** +** The minimum value of NN is 1 (of course). Increasing NN above 1 +** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance +** in exchange for a larger degradation in INSERT and UPDATE performance. +** The value of NN appears to give the best results overall. +** +** (Later:) The description above makes it seem as if these values are +** tunable - as if you could change them and recompile and it would all work. +** But that is unlikely. NB has been 3 since the inception of SQLite and +** we have never tested any other value. +*/ +#define NN 1 /* Number of neighbors on either side of pPage */ +#define NB 3 /* (NN*2+1): Total pages involved in the balance */ + +/* +** A CellArray object contains a cache of pointers and sizes for a +** consecutive sequence of cells that might be held on multiple pages. +** +** The cells in this array are the divider cell or cells from the pParent +** page plus up to three child pages. There are a total of nCell cells. +** +** pRef is a pointer to one of the pages that contributes cells. This is +** used to access information such as MemPage.intKey and MemPage.pBt->pageSize +** which should be common to all pages that contribute cells to this array. +** +** apCell[] and szCell[] hold, respectively, pointers to the start of each +** cell and the size of each cell. Some of the apCell[] pointers might refer +** to overflow cells. In other words, some apCel[] pointers might not point +** to content area of the pages. +** +** A szCell[] of zero means the size of that cell has not yet been computed. +** +** The cells come from as many as four different pages: +** +** ----------- +** | Parent | +** ----------- +** / | \ +** / | \ +** --------- --------- --------- +** |Child-1| |Child-2| |Child-3| +** --------- --------- --------- +** +** The order of cells is in the array is for an index btree is: +** +** 1. All cells from Child-1 in order +** 2. The first divider cell from Parent +** 3. All cells from Child-2 in order +** 4. The second divider cell from Parent +** 5. All cells from Child-3 in order +** +** For a table-btree (with rowids) the items 2 and 4 are empty because +** content exists only in leaves and there are no divider cells. +** +** For an index btree, the apEnd[] array holds pointer to the end of page +** for Child-1, the Parent, Child-2, the Parent (again), and Child-3, +** respectively. The ixNx[] array holds the number of cells contained in +** each of these 5 stages, and all stages to the left. Hence: +** +** ixNx[0] = Number of cells in Child-1. +** ixNx[1] = Number of cells in Child-1 plus 1 for first divider. +** ixNx[2] = Number of cells in Child-1 and Child-2 + 1 for 1st divider. +** ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells +** ixNx[4] = Total number of cells. +** +** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2] +** are used and they point to the leaf pages only, and the ixNx value are: +** +** ixNx[0] = Number of cells in Child-1. +** ixNx[1] = Number of cells in Child-1 and Child-2. +** ixNx[2] = Total number of cells. +** +** Sometimes when deleting, a child page can have zero cells. In those +** cases, ixNx[] entries with higher indexes, and the corresponding apEnd[] +** entries, shift down. The end result is that each ixNx[] entry should +** be larger than the previous +*/ +typedef struct CellArray CellArray; +struct CellArray { + int nCell; /* Number of cells in apCell[] */ + MemPage *pRef; /* Reference page */ + u8 **apCell; /* All cells begin balanced */ + u16 *szCell; /* Local size of all cells in apCell[] */ + u8 *apEnd[NB*2]; /* MemPage.aDataEnd values */ + int ixNx[NB*2]; /* Index of at which we move to the next apEnd[] */ +}; + +/* +** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been +** computed. +*/ +static void populateCellCache(CellArray *p, int idx, int N){ + MemPage *pRef = p->pRef; + u16 *szCell = p->szCell; + assert( idx>=0 && idx+N<=p->nCell ); + while( N>0 ){ + assert( p->apCell[idx]!=0 ); + if( szCell[idx]==0 ){ + szCell[idx] = pRef->xCellSize(pRef, p->apCell[idx]); + }else{ + assert( CORRUPT_DB || + szCell[idx]==pRef->xCellSize(pRef, p->apCell[idx]) ); + } + idx++; + N--; + } +} + +/* +** Return the size of the Nth element of the cell array +*/ +static SQLITE_NOINLINE u16 computeCellSize(CellArray *p, int N){ + assert( N>=0 && NnCell ); + assert( p->szCell[N]==0 ); + p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]); + return p->szCell[N]; +} +static u16 cachedCellSize(CellArray *p, int N){ + assert( N>=0 && NnCell ); + if( p->szCell[N] ) return p->szCell[N]; + return computeCellSize(p, N); +} + +/* +** Array apCell[] contains pointers to nCell b-tree page cells. The +** szCell[] array contains the size in bytes of each cell. This function +** replaces the current contents of page pPg with the contents of the cell +** array. +** +** Some of the cells in apCell[] may currently be stored in pPg. This +** function works around problems caused by this by making a copy of any +** such cells before overwriting the page data. +** +** The MemPage.nFree field is invalidated by this function. It is the +** responsibility of the caller to set it correctly. +*/ +static int rebuildPage( + CellArray *pCArray, /* Content to be added to page pPg */ + int iFirst, /* First cell in pCArray to use */ + int nCell, /* Final number of cells on page */ + MemPage *pPg /* The page to be reconstructed */ +){ + const int hdr = pPg->hdrOffset; /* Offset of header on pPg */ + u8 * const aData = pPg->aData; /* Pointer to data for pPg */ + const int usableSize = pPg->pBt->usableSize; + u8 * const pEnd = &aData[usableSize]; + int i = iFirst; /* Which cell to copy from pCArray*/ + u32 j; /* Start of cell content area */ + int iEnd = i+nCell; /* Loop terminator */ + u8 *pCellptr = pPg->aCellIdx; + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + u8 *pData; + int k; /* Current slot in pCArray->apEnd[] */ + u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ + + assert( nCell>0 ); + assert( i(u32)usableSize ){ j = 0; } + memcpy(&pTmp[j], &aData[j], usableSize - j); + + for(k=0; ALWAYS(kixNx[k]<=i; k++){} + pSrcEnd = pCArray->apEnd[k]; + + pData = pEnd; + while( 1/*exit by break*/ ){ + u8 *pCell = pCArray->apCell[i]; + u16 sz = pCArray->szCell[i]; + assert( sz>0 ); + if( SQLITE_WITHIN(pCell,aData+j,pEnd) ){ + if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT; + pCell = &pTmp[pCell - aData]; + }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd + && (uptr)(pCell)<(uptr)pSrcEnd + ){ + return SQLITE_CORRUPT_BKPT; + } + + pData -= sz; + put2byte(pCellptr, (pData - aData)); + pCellptr += 2; + if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; + memmove(pData, pCell, sz); + assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pSrcEnd = pCArray->apEnd[k]; + } + } + + /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ + pPg->nCell = nCell; + pPg->nOverflow = 0; + + put2byte(&aData[hdr+1], 0); + put2byte(&aData[hdr+3], pPg->nCell); + put2byte(&aData[hdr+5], pData - aData); + aData[hdr+7] = 0x00; + return SQLITE_OK; +} + +/* +** The pCArray objects contains pointers to b-tree cells and the cell sizes. +** This function attempts to add the cells stored in the array to page pPg. +** If it cannot (because the page needs to be defragmented before the cells +** will fit), non-zero is returned. Otherwise, if the cells are added +** successfully, zero is returned. +** +** Argument pCellptr points to the first entry in the cell-pointer array +** (part of page pPg) to populate. After cell apCell[0] is written to the +** page body, a 16-bit offset is written to pCellptr. And so on, for each +** cell in the array. It is the responsibility of the caller to ensure +** that it is safe to overwrite this part of the cell-pointer array. +** +** When this function is called, *ppData points to the start of the +** content area on page pPg. If the size of the content area is extended, +** *ppData is updated to point to the new start of the content area +** before returning. +** +** Finally, argument pBegin points to the byte immediately following the +** end of the space required by this page for the cell-pointer area (for +** all cells - not just those inserted by the current call). If the content +** area must be extended to before this point in order to accommodate all +** cells in apCell[], then the cells do not fit and non-zero is returned. +*/ +static int pageInsertArray( + MemPage *pPg, /* Page to add cells to */ + u8 *pBegin, /* End of cell-pointer array */ + u8 **ppData, /* IN/OUT: Page content-area pointer */ + u8 *pCellptr, /* Pointer to cell-pointer area */ + int iFirst, /* Index of first cell to add */ + int nCell, /* Number of cells to add to pPg */ + CellArray *pCArray /* Array of cells */ +){ + int i = iFirst; /* Loop counter - cell index to insert */ + u8 *aData = pPg->aData; /* Complete page */ + u8 *pData = *ppData; /* Content area. A subset of aData[] */ + int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */ + int k; /* Current slot in pCArray->apEnd[] */ + u8 *pEnd; /* Maximum extent of cell data */ + assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ + if( iEnd<=iFirst ) return 0; + for(k=0; ALWAYS(kixNx[k]<=i ; k++){} + pEnd = pCArray->apEnd[k]; + while( 1 /*Exit by break*/ ){ + int sz, rc; + u8 *pSlot; + assert( pCArray->szCell[i]!=0 ); + sz = pCArray->szCell[i]; + if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ + if( (pData - pBegin)apCell[i] will never overlap on a well-formed + ** database. But they might for a corrupt database. Hence use memmove() + ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */ + assert( (pSlot+sz)<=pCArray->apCell[i] + || pSlot>=(pCArray->apCell[i]+sz) + || CORRUPT_DB ); + if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd + && (uptr)(pCArray->apCell[i])<(uptr)pEnd + ){ + assert( CORRUPT_DB ); + (void)SQLITE_CORRUPT_BKPT; + return 1; + } + memmove(pSlot, pCArray->apCell[i], sz); + put2byte(pCellptr, (pSlot - aData)); + pCellptr += 2; + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pEnd = pCArray->apEnd[k]; + } + } + *ppData = pData; + return 0; +} + +/* +** The pCArray object contains pointers to b-tree cells and their sizes. +** +** This function adds the space associated with each cell in the array +** that is currently stored within the body of pPg to the pPg free-list. +** The cell-pointers and other fields of the page are not updated. +** +** This function returns the total number of cells added to the free-list. +*/ +static int pageFreeArray( + MemPage *pPg, /* Page to edit */ + int iFirst, /* First cell to delete */ + int nCell, /* Cells to delete */ + CellArray *pCArray /* Array of cells */ +){ + u8 * const aData = pPg->aData; + u8 * const pEnd = &aData[pPg->pBt->usableSize]; + u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; + int nRet = 0; + int i, j; + int iEnd = iFirst + nCell; + int nFree = 0; + int aOfst[10]; + int aAfter[10]; + + for(i=iFirst; iapCell[i]; + if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ + int sz; + int iAfter; + int iOfst; + /* No need to use cachedCellSize() here. The sizes of all cells that + ** are to be freed have already been computing while deciding which + ** cells need freeing */ + sz = pCArray->szCell[i]; assert( sz>0 ); + iOfst = (u16)(pCell - aData); + iAfter = iOfst+sz; + for(j=0; j=nFree ){ + if( nFree>=(int)(sizeof(aOfst)/sizeof(aOfst[0])) ){ + for(j=0; jpEnd ) return 0; + nFree++; + } + nRet++; + } + } + for(j=0; jnCell cells starting with +** pCArray->apCell[iOld]. After balancing, this page should hold nNew cells +** starting at apCell[iNew]. +** +** This routine makes the necessary adjustments to pPg so that it contains +** the correct cells after being balanced. +** +** The pPg->nFree field is invalid when this function returns. It is the +** responsibility of the caller to set it correctly. +*/ +static int editPage( + MemPage *pPg, /* Edit this page */ + int iOld, /* Index of first cell currently on page */ + int iNew, /* Index of new first cell on page */ + int nNew, /* Final number of cells on page */ + CellArray *pCArray /* Array of cells and sizes */ +){ + u8 * const aData = pPg->aData; + const int hdr = pPg->hdrOffset; + u8 *pBegin = &pPg->aCellIdx[nNew * 2]; + int nCell = pPg->nCell; /* Cells stored on pPg */ + u8 *pData; + u8 *pCellptr; + int i; + int iOldEnd = iOld + pPg->nCell + pPg->nOverflow; + int iNewEnd = iNew + nNew; + +#ifdef SQLITE_DEBUG + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + memcpy(pTmp, aData, pPg->pBt->usableSize); +#endif + + /* Remove cells from the start and end of the page */ + assert( nCell>=0 ); + if( iOldnCell) ) return SQLITE_CORRUPT_BKPT; + memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2); + nCell -= nShift; + } + if( iNewEnd < iOldEnd ){ + int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray); + assert( nCell>=nTail ); + nCell -= nTail; + } + + pData = &aData[get2byte(&aData[hdr+5])]; + if( pDatapPg->aDataEnd) ) goto editpage_fail; + + /* Add cells to the start of the page */ + if( iNew=0 ); + pCellptr = pPg->aCellIdx; + memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iNew, nAdd, pCArray + ) ) goto editpage_fail; + nCell += nAdd; + } + + /* Add any overflow cells */ + for(i=0; inOverflow; i++){ + int iCell = (iOld + pPg->aiOvfl[i]) - iNew; + if( iCell>=0 && iCellaCellIdx[iCell * 2]; + if( nCell>iCell ){ + memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); + } + nCell++; + cachedCellSize(pCArray, iCell+iNew); + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iCell+iNew, 1, pCArray + ) ) goto editpage_fail; + } + } + + /* Append cells to the end of the page */ + assert( nCell>=0 ); + pCellptr = &pPg->aCellIdx[nCell*2]; + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iNew+nCell, nNew-nCell, pCArray + ) ) goto editpage_fail; + + pPg->nCell = nNew; + pPg->nOverflow = 0; + + put2byte(&aData[hdr+3], pPg->nCell); + put2byte(&aData[hdr+5], pData - aData); + +#ifdef SQLITE_DEBUG + for(i=0; iapCell[i+iNew]; + int iOff = get2byteAligned(&pPg->aCellIdx[i*2]); + if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){ + pCell = &pTmp[pCell - aData]; + } + assert( 0==memcmp(pCell, &aData[iOff], + pCArray->pRef->xCellSize(pCArray->pRef, pCArray->apCell[i+iNew])) ); + } +#endif + + return SQLITE_OK; + editpage_fail: + /* Unable to edit this page. Rebuild it from scratch instead. */ + if( nNew<1 ) return SQLITE_CORRUPT_BKPT; + populateCellCache(pCArray, iNew, nNew); + return rebuildPage(pCArray, iNew, nNew, pPg); +} + + +#ifndef SQLITE_OMIT_QUICKBALANCE +/* +** This version of balance() handles the common special case where +** a new entry is being inserted on the extreme right-end of the +** tree, in other words, when the new entry will become the largest +** entry in the tree. +** +** Instead of trying to balance the 3 right-most leaf pages, just add +** a new page to the right-hand side and put the one new entry in +** that page. This leaves the right side of the tree somewhat +** unbalanced. But odds are that we will be inserting new entries +** at the end soon afterwards so the nearly empty page will quickly +** fill up. On average. +** +** pPage is the leaf page which is the right-most page in the tree. +** pParent is its parent. pPage must have a single overflow entry +** which is also the right-most entry on the page. +** +** The pSpace buffer is used to store a temporary copy of the divider +** cell that will be inserted into pParent. Such a cell consists of a 4 +** byte page number followed by a variable length integer. In other +** words, at most 13 bytes. Hence the pSpace buffer must be at +** least 13 bytes in size. +*/ +static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ + BtShared *const pBt = pPage->pBt; /* B-Tree Database */ + MemPage *pNew; /* Newly allocated page */ + int rc; /* Return Code */ + Pgno pgnoNew; /* Page number of pNew */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( pPage->nOverflow==1 ); + + if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */ + assert( pPage->nFree>=0 ); + assert( pParent->nFree>=0 ); + + /* Allocate a new page. This page will become the right-sibling of + ** pPage. Make the parent page writable, so that the new divider cell + ** may be inserted. If both these operations are successful, proceed. + */ + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + + if( rc==SQLITE_OK ){ + + u8 *pOut = &pSpace[4]; + u8 *pCell = pPage->apOvfl[0]; + u16 szCell = pPage->xCellSize(pPage, pCell); + u8 *pStop; + CellArray b; + + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); + assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); + zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); + b.nCell = 1; + b.pRef = pPage; + b.apCell = &pCell; + b.szCell = &szCell; + b.apEnd[0] = pPage->aDataEnd; + b.ixNx[0] = 2; + rc = rebuildPage(&b, 0, 1, pNew); + if( NEVER(rc) ){ + releasePage(pNew); + return rc; + } + pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; + + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. If either of these + ** operations fails, the return code is set, but the contents + ** of the parent page are still manipulated by the code below. + ** That is Ok, at this point the parent page is guaranteed to + ** be marked as dirty. Returning an error code will cause a + ** rollback, undoing any changes made to the parent page. + */ + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); + if( szCell>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); + } + } + + /* Create a divider cell to insert into pParent. The divider cell + ** consists of a 4-byte page number (the page number of pPage) and + ** a variable length key value (which must be the same value as the + ** largest key on pPage). + ** + ** To find the largest key value on pPage, first find the right-most + ** cell on pPage. The first two fields of this cell are the + ** record-length (a variable length integer at most 32-bits in size) + ** and the key value (a variable length integer, may have any value). + ** The first of the while(...) loops below skips over the record-length + ** field. The second while(...) loop copies the key value from the + ** cell on pPage into the pSpace buffer. + */ + pCell = findCell(pPage, pPage->nCell-1); + pStop = &pCell[9]; + while( (*(pCell++)&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno); + } + + /* Set the right-child pointer of pParent to point to the new page. */ + put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + + /* Release the reference to the new page. */ + releasePage(pNew); + } + + return rc; +} +#endif /* SQLITE_OMIT_QUICKBALANCE */ + +#if 0 +/* +** This function does not contribute anything to the operation of SQLite. +** it is sometimes activated temporarily while debugging code responsible +** for setting pointer-map entries. +*/ +static int ptrmapCheckPages(MemPage **apPage, int nPage){ + int i, j; + for(i=0; ipBt; + assert( pPage->isInit ); + + for(j=0; jnCell; j++){ + CellInfo info; + u8 *z; + + z = findCell(pPage, j); + pPage->xParseCell(pPage, z, &info); + if( info.nLocalpgno && e==PTRMAP_OVERFLOW1 ); + } + if( !pPage->leaf ){ + Pgno child = get4byte(z); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + if( !pPage->leaf ){ + Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + return 1; +} +#endif + +/* +** This function is used to copy the contents of the b-tree node stored +** on page pFrom to page pTo. If page pFrom was not a leaf page, then +** the pointer-map entries for each child page are updated so that the +** parent page stored in the pointer map is page pTo. If pFrom contained +** any cells with overflow page pointers, then the corresponding pointer +** map entries are also updated so that the parent page is page pTo. +** +** If pFrom is currently carrying any overflow cells (entries in the +** MemPage.apOvfl[] array), they are not copied to pTo. +** +** Before returning, page pTo is reinitialized using btreeInitPage(). +** +** The performance of this function is not critical. It is only used by +** the balance_shallower() and balance_deeper() procedures, neither of +** which are called often under normal circumstances. +*/ +static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + int rc; + int iData; + + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); + + /* Copy the b-tree node content from page pFrom to page pTo. */ + iData = get2byte(&aFrom[iFromHdr+5]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + /* Reinitialize page pTo so that the contents of the MemPage structure + ** match the new data. The initialization of pTo can actually fail under + ** fairly obscure circumstances, even though it is a copy of initialized + ** page pFrom. + */ + pTo->isInit = 0; + rc = btreeInitPage(pTo); + if( rc==SQLITE_OK ) rc = btreeComputeFreeSpace(pTo); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + + /* If this is an auto-vacuum database, update the pointer-map entries + ** for any b-tree or overflow pages that pTo now contains the pointers to. + */ + if( ISAUTOVACUUM(pBt) ){ + *pRC = setChildPtrmaps(pTo); + } + } +} + +/* +** This routine redistributes cells on the iParentIdx'th child of pParent +** (hereafter "the page") and up to 2 siblings so that all pages have about the +** same amount of free space. Usually a single sibling on either side of the +** page are used in the balancing, though both siblings might come from one +** side if the page is the first or last child of its parent. If the page +** has fewer than 2 siblings (something which can only happen if the page +** is a root page or a child of a root page) then all available siblings +** participate in the balancing. +** +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. +** +** Note that when this routine is called, some of the cells on the page +** might not actually be stored in MemPage.aData[]. This can happen +** if the page is overfull. This routine ensures that all cells allocated +** to the page and its siblings fit into MemPage.aData[] before returning. +** +** In the course of balancing the page and its siblings, cells may be +** inserted into or removed from the parent page (pParent). Doing so +** may cause the parent page to become overfull or underfull. If this +** happens, it is the responsibility of the caller to invoke the correct +** balancing routine to fix this problem (see the balance() routine). +** +** If this routine fails for any reason, it might leave the database +** in a corrupted state. So if this routine fails, the database should +** be rolled back. +** +** The third argument to this function, aOvflSpace, is a pointer to a +** buffer big enough to hold one page. If while inserting cells into the parent +** page (pParent) the parent page becomes overfull, this buffer is +** used to store the parent's overflow cells. Because this function inserts +** a maximum of four divider cells into the parent page, and the maximum +** size of a cell stored within an internal node is always less than 1/4 +** of the page-size, the aOvflSpace[] buffer is guaranteed to be large +** enough for all overflow cells. +** +** If aOvflSpace is set to a null pointer, this function returns +** SQLITE_NOMEM. +*/ +static int balance_nonroot( + MemPage *pParent, /* Parent page of siblings being balanced */ + int iParentIdx, /* Index of "the page" in pParent */ + u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ + int isRoot, /* True if pParent is a root-page */ + int bBulk /* True if this call is part of a bulk load */ +){ + BtShared *pBt; /* The whole database */ + int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ + int nNew = 0; /* Number of pages in apNew[] */ + int nOld; /* Number of pages in apOld[] */ + int i, j, k; /* Loop counters */ + int nxDiv; /* Next divider slot in pParent->aCell[] */ + int rc = SQLITE_OK; /* The return code */ + u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ + int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ + int usableSpace; /* Bytes in pPage beyond the header */ + int pageFlags; /* Value of pPage->aData[0] */ + int iSpace1 = 0; /* First unused byte of aSpace1[] */ + int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ + int szScratch; /* Size of scratch memory requested */ + MemPage *apOld[NB]; /* pPage and up to two siblings */ + MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ + u8 *pRight; /* Location in parent of right-sibling pointer */ + u8 *apDiv[NB-1]; /* Divider cells in pParent */ + int cntNew[NB+2]; /* Index in b.paCell[] of cell after i-th page */ + int cntOld[NB+2]; /* Old index in b.apCell[] */ + int szNew[NB+2]; /* Combined size of cells placed on i-th page */ + u8 *aSpace1; /* Space for copies of dividers cells */ + Pgno pgno; /* Temp var to store a page number in */ + u8 abDone[NB+2]; /* True after i'th new page is populated */ + Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ + CellArray b; /* Parsed information on cells being balanced */ + + memset(abDone, 0, sizeof(abDone)); + memset(&b, 0, sizeof(b)); + pBt = pParent->pBt; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + + /* At this point pParent may have at most one overflow cell. And if + ** this overflow cell is present, it must be the cell with + ** index iParentIdx. This scenario comes about when this function + ** is called (indirectly) from sqlite3BtreeDelete(). + */ + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); + + if( !aOvflSpace ){ + return SQLITE_NOMEM_BKPT; + } + assert( pParent->nFree>=0 ); + + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, + ** if there are fewer than NN siblings on the other side. If pParent + ** has NB or fewer children then all children of pParent are taken. + ** + ** This loop also drops the divider cells from the parent page. This + ** way, the remainder of the function does not have to deal with any + ** overflow cells in the parent page, since if any existed they will + ** have already been removed. + */ + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ + nxDiv = 0; + }else{ + assert( bBulk==0 || bBulk==1 ); + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2+bBulk; + }else{ + nxDiv = iParentIdx-1; + } + i = 2-bBulk; + } + nOld = i+1; + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); + } + pgno = get4byte(pRight); + while( 1 ){ + if( rc==SQLITE_OK ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0); + } + if( rc ){ + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + } + if( apOld[i]->nFree<0 ){ + rc = btreeComputeFreeSpace(apOld[i]); + if( rc ){ + memset(apOld, 0, (i)*sizeof(MemPage*)); + goto balance_cleanup; + } + } + nMaxCells += apOld[i]->nCell + ArraySize(pParent->apOvfl); + if( (i--)==0 ) break; + + if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){ + apDiv[i] = pParent->apOvfl[0]; + pgno = get4byte(apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); + pgno = get4byte(apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); + + /* Drop the cell from the parent page. apDiv[i] still points to + ** the cell within the parent, even though it has been dropped. + ** This is safe because dropping a cell only overwrites the first + ** four bytes of it, and this function does not need the first + ** four bytes of the divider cell. So the pointer is safe to use + ** later on. + ** + ** But not if we are in secure-delete mode. In secure-delete mode, + ** the dropCell() routine will overwrite the entire cell with zeroes. + ** In this case, temporarily copy the cell into the aOvflSpace[] + ** buffer. It will be copied out again as soon as the aSpace[] buffer + ** is allocated. */ + if( pBt->btsFlags & BTS_FAST_SECURE ){ + int iOff; + + /* If the following if() condition is not true, the db is corrupted. + ** The call to dropCell() below will detect this. */ + iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); + if( (iOff+szNew[i])<=(int)pBt->usableSize ){ + memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; + } + } + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); + } + } + + /* Make nMaxCells a multiple of 4 in order to preserve 8-byte + ** alignment */ + nMaxCells = (nMaxCells + 3)&~3; + + /* + ** Allocate space for memory structures + */ + szScratch = + nMaxCells*sizeof(u8*) /* b.apCell */ + + nMaxCells*sizeof(u16) /* b.szCell */ + + pBt->pageSize; /* aSpace1 */ + + assert( szScratch<=7*(int)pBt->pageSize ); + b.apCell = sqlite3StackAllocRaw(0, szScratch ); + if( b.apCell==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto balance_cleanup; + } + b.szCell = (u16*)&b.apCell[nMaxCells]; + aSpace1 = (u8*)&b.szCell[nMaxCells]; + assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); + + /* + ** Load pointers to all cells on sibling pages and the divider cells + ** into the local b.apCell[] array. Make copies of the divider cells + ** into space obtained from aSpace1[]. The divider cells have already + ** been removed from pParent. + ** + ** If the siblings are on leaf pages, then the child pointers of the + ** divider cells are stripped from the cells before they are copied + ** into aSpace1[]. In this way, all cells in b.apCell[] are without + ** child pointers. If siblings are not leaves, then all cell in + ** b.apCell[] include child pointers. Either way, all cells in b.apCell[] + ** are alike. + ** + ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. + ** leafData: 1 if pPage holds key+data and pParent holds only keys. + */ + b.pRef = apOld[0]; + leafCorrection = b.pRef->leaf*4; + leafData = b.pRef->intKeyLeaf; + for(i=0; inCell; + u8 *aData = pOld->aData; + u16 maskPage = pOld->maskPage; + u8 *piCell = aData + pOld->cellOffset; + u8 *piEnd; + VVA_ONLY( int nCellAtStart = b.nCell; ) + + /* Verify that all sibling pages are of the same "type" (table-leaf, + ** table-interior, index-leaf, or index-interior). + */ + if( pOld->aData[0]!=apOld[0]->aData[0] ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + + /* Load b.apCell[] with pointers to all cells in pOld. If pOld + ** contains overflow cells, include them in the b.apCell[] array + ** in the correct spot. + ** + ** Note that when there are multiple overflow cells, it is always the + ** case that they are sequential and adjacent. This invariant arises + ** because multiple overflows can only occurs when inserting divider + ** cells into a parent on a prior balance, and divider cells are always + ** adjacent and are inserted in order. There is an assert() tagged + ** with "NOTE 1" in the overflow cell insertion loop to prove this + ** invariant. + ** + ** This must be done in advance. Once the balance starts, the cell + ** offset section of the btree page will be overwritten and we will no + ** long be able to find the cells if a pointer to each cell is not saved + ** first. + */ + memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); + if( pOld->nOverflow>0 ){ + if( NEVER(limitaiOvfl[0]) ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + limit = pOld->aiOvfl[0]; + for(j=0; jnOverflow; k++){ + assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */ + b.apCell[b.nCell] = pOld->apOvfl[k]; + b.nCell++; + } + } + piEnd = aData + pOld->cellOffset + 2*pOld->nCell; + while( piCellnCell+pOld->nOverflow) ); + + cntOld[i] = b.nCell; + if( imaxLocal+23 ); + assert( iSpace1 <= (int)pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + b.apCell[b.nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 || CORRUPT_DB ); + /* The right pointer of the child page pOld becomes the left + ** pointer of the divider cell */ + memcpy(b.apCell[b.nCell], &pOld->aData[8], 4); + }else{ + assert( leafCorrection==4 ); + while( b.szCell[b.nCell]<4 ){ + /* Do not allow any cells smaller than 4 bytes. If a smaller cell + ** does exist, pad it with 0x00 bytes. */ + assert( b.szCell[b.nCell]==3 || CORRUPT_DB ); + assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB ); + aSpace1[iSpace1++] = 0x00; + b.szCell[b.nCell]++; + } + } + b.nCell++; + } + } + + /* + ** Figure out the number of pages needed to hold all b.nCell cells. + ** Store this number in "k". Also compute szNew[] which is the total + ** size of all cells on the i-th page and cntNew[] which is the index + ** in b.apCell[] of the cell that divides page i from page i+1. + ** cntNew[k] should equal b.nCell. + ** + ** Values computed by this block: + ** + ** k: The total number of sibling pages + ** szNew[i]: Spaced used on the i-th sibling page. + ** cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to + ** the right of the i-th sibling page. + ** usableSpace: Number of bytes of space available on each sibling. + ** + */ + usableSpace = pBt->usableSize - 12 + leafCorrection; + for(i=k=0; iaDataEnd; + b.ixNx[k] = cntOld[i]; + if( k && b.ixNx[k]==b.ixNx[k-1] ){ + k--; /* Omit b.ixNx[] entry for child pages with no cells */ + } + if( !leafData ){ + k++; + b.apEnd[k] = pParent->aDataEnd; + b.ixNx[k] = cntOld[i]+1; + } + assert( p->nFree>=0 ); + szNew[i] = usableSpace - p->nFree; + for(j=0; jnOverflow; j++){ + szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); + } + cntNew[i] = cntOld[i]; + } + k = nOld; + for(i=0; iusableSpace ){ + if( i+1>=k ){ + k = i+2; + if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } + szNew[k-1] = 0; + cntNew[k-1] = b.nCell; + } + sz = 2 + cachedCellSize(&b, cntNew[i]-1); + szNew[i] -= sz; + if( !leafData ){ + if( cntNew[i]usableSpace ) break; + szNew[i] += sz; + cntNew[i]++; + if( !leafData ){ + if( cntNew[i]=b.nCell ){ + k = i+1; + }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + } + + /* + ** The packing computed by the previous block is biased toward the siblings + ** on the left side (siblings with smaller keys). The left siblings are + ** always nearly full, while the right-most sibling might be nearly empty. + ** The next block of code attempts to adjust the packing of siblings to + ** get a better balance. + ** + ** This adjustment is more than an optimization. The packing above might + ** be so out of balance as to be illegal. For example, the right-most + ** sibling might be completely empty. This adjustment is not optional. + */ + for(i=k-1; i>0; i--){ + int szRight = szNew[i]; /* Size of sibling on the right */ + int szLeft = szNew[i-1]; /* Size of sibling on the left */ + int r; /* Index of right-most cell in left sibling */ + int d; /* Index of first cell to the left of right sibling */ + + r = cntNew[i-1] - 1; + d = r + 1 - leafData; + (void)cachedCellSize(&b, d); + do{ + int szR, szD; + assert( d szLeft-(szR+(i==k-1?0:2)))){ + break; + } + szRight += szD + 2; + szLeft -= szR + 2; + cntNew[i-1] = r; + r--; + d--; + }while( r>=0 ); + szNew[i] = szRight; + szNew[i-1] = szLeft; + if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + } + + /* Sanity check: For a non-corrupt database file one of the following + ** must be true: + ** (1) We found one or more cells (cntNew[0])>0), or + ** (2) pPage is a virtual root page. A virtual root page is when + ** the real root page is page 1 and we are the only child of + ** that page. + */ + assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); + TRACE(("BALANCE: old: %u(nc=%u) %u(nc=%u) %u(nc=%u)\n", + apOld[0]->pgno, apOld[0]->nCell, + nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, + nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 + )); + + /* + ** Allocate k new pages. Reuse old pages where possible. + */ + pageFlags = apOld[0]->aData[0]; + for(i=0; ipDbPage); + nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) + && rc==SQLITE_OK + ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc ) goto balance_cleanup; + }else{ + assert( i>0 ); + rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); + if( rc ) goto balance_cleanup; + zeroPage(pNew, pageFlags); + apNew[i] = pNew; + nNew++; + cntOld[i] = b.nCell; + + /* Set the pointer-map entry for the new sibling page. */ + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } + } + } + + /* + ** Reassign page numbers so that the new pages are in ascending order. + ** This helps to keep entries in the disk file in order so that a scan + ** of the table is closer to a linear scan through the file. That in turn + ** helps the operating system to deliver pages from the disk more rapidly. + ** + ** An O(N*N) sort algorithm is used, but since N is never more than NB+2 + ** (5), that is not a performance concern. + ** + ** When NB==3, this one optimization makes the database about 25% faster + ** for large insertions and deletions. + */ + for(i=0; ipgno; + assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE ); + assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY ); + } + for(i=0; ipgno < apNew[iB]->pgno ) iB = j; + } + + /* If apNew[i] has a page number that is bigger than any of the + ** subsequence apNew[i] entries, then swap apNew[i] with the subsequent + ** entry that has the smallest page number (which we know to be + ** entry apNew[iB]). + */ + if( iB!=i ){ + Pgno pgnoA = apNew[i]->pgno; + Pgno pgnoB = apNew[iB]->pgno; + Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1; + u16 fgA = apNew[i]->pDbPage->flags; + u16 fgB = apNew[iB]->pDbPage->flags; + sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB); + sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA); + sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB); + apNew[i]->pgno = pgnoB; + apNew[iB]->pgno = pgnoA; + } + } + + TRACE(("BALANCE: new: %u(%u nc=%u) %u(%u nc=%u) %u(%u nc=%u) " + "%u(%u nc=%u) %u(%u nc=%u)\n", + apNew[0]->pgno, szNew[0], cntNew[0], + nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, + nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, + nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, + nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0, + nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, + nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0, + nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0, + nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 + )); + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( nNew>=1 && nNew<=ArraySize(apNew) ); + assert( apNew[nNew-1]!=0 ); + put4byte(pRight, apNew[nNew-1]->pgno); + + /* If the sibling pages are not leaves, ensure that the right-child pointer + ** of the right-most new sibling page is set to the value that was + ** originally in the same field of the right-most old sibling page. */ + if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ + MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; + memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4); + } + + /* Make any required updates to pointer map entries associated with + ** cells stored on sibling pages following the balance operation. Pointer + ** map entries associated with divider cells are set by the insertCell() + ** routine. The associated pointer map entries are: + ** + ** a) if the cell contains a reference to an overflow chain, the + ** entry associated with the first page in the overflow chain, and + ** + ** b) if the sibling pages are not leaves, the child page associated + ** with the cell. + ** + ** If the sibling pages are not leaves, then the pointer map entry + ** associated with the right-child of each sibling may also need to be + ** updated. This happens below, after the sibling pages have been + ** populated, not here. + */ + if( ISAUTOVACUUM(pBt) ){ + MemPage *pOld; + MemPage *pNew = pOld = apNew[0]; + int cntOldNext = pNew->nCell + pNew->nOverflow; + int iNew = 0; + int iOld = 0; + + for(i=0; i=0 && iOldnCell + pOld->nOverflow + !leafData; + } + if( i==cntNew[iNew] ){ + pNew = apNew[++iNew]; + if( !leafData ) continue; + } + + /* Cell pCell is destined for new sibling page pNew. Originally, it + ** was either part of sibling page iOld (possibly an overflow cell), + ** or else the divider cell to the left of sibling page iOld. So, + ** if sibling page iOld had the same page number as pNew, and if + ** pCell really was a part of sibling page iOld (not a divider or + ** overflow cell), we can skip updating the pointer map entries. */ + if( iOld>=nNew + || pNew->pgno!=aPgno[iOld] + || !SQLITE_WITHIN(pCell,pOld->aData,pOld->aDataEnd) + ){ + if( !leafCorrection ){ + ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); + } + if( cachedCellSize(&b,i)>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pOld, pCell, &rc); + } + if( rc ) goto balance_cleanup; + } + } + } + + /* Insert new divider cells into pParent. */ + for(i=0; ileaf ){ + memcpy(&pNew->aData[8], pCell, 4); + }else if( leafData ){ + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in b.apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of + ** the sibling-page assembled above only. + */ + CellInfo info; + j--; + pNew->xParseCell(pNew, b.apCell[j], &info); + pCell = pTemp; + sz = 4 + putVarint(&pCell[4], info.nKey); + pTemp = 0; + }else{ + pCell -= 4; + /* Obscure case for non-leaf-data trees: If the cell at pCell was + ** previously stored on a leaf node, and its reported size was 4 + ** bytes, then it may actually be smaller than this + ** (see btreeParseCellPtr(), 4 bytes is the minimum size of + ** any cell). But it is important to pass the correct size to + ** insertCell(), so reparse the cell now. + ** + ** This can only happen for b-trees used to evaluate "IN (SELECT ...)" + ** and WITHOUT ROWID tables with exactly one column which is the + ** primary key. + */ + if( b.szCell[j]==4 ){ + assert(leafCorrection==4); + sz = pParent->xCellSize(pParent, pCell); + } + } + iOvflSpace += sz; + assert( sz<=pBt->maxLocal+23 ); + assert( iOvflSpace <= (int)pBt->pageSize ); + for(k=0; ALWAYS(kpgno); + if( rc!=SQLITE_OK ) goto balance_cleanup; + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + } + + /* Now update the actual sibling pages. The order in which they are updated + ** is important, as this code needs to avoid disrupting any page from which + ** cells may still to be read. In practice, this means: + ** + ** (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1]) + ** then it is not safe to update page apNew[iPg] until after + ** the left-hand sibling apNew[iPg-1] has been updated. + ** + ** (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1]) + ** then it is not safe to update page apNew[iPg] until after + ** the right-hand sibling apNew[iPg+1] has been updated. + ** + ** If neither of the above apply, the page is safe to update. + ** + ** The iPg value in the following loop starts at nNew-1 goes down + ** to 0, then back up to nNew-1 again, thus making two passes over + ** the pages. On the initial downward pass, only condition (1) above + ** needs to be tested because (2) will always be true from the previous + ** step. On the upward pass, both conditions are always true, so the + ** upwards pass simply processes pages that were missed on the downward + ** pass. + */ + for(i=1-nNew; i=0 && iPg=1 || i>=0 ); + assert( iPg=0 /* On the upwards pass, or... */ + || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ + ){ + int iNew; + int iOld; + int nNewCell; + + /* Verify condition (1): If cells are moving left, update iPg + ** only after iPg-1 has already been updated. */ + assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] ); + + /* Verify condition (2): If cells are moving right, update iPg + ** only after iPg+1 has already been updated. */ + assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] ); + + if( iPg==0 ){ + iNew = iOld = 0; + nNewCell = cntNew[0]; + }else{ + iOld = iPgnFree = usableSpace-szNew[iPg]; + assert( apNew[iPg]->nOverflow==0 ); + assert( apNew[iPg]->nCell==nNewCell ); + } + } + + /* All pages have been processed exactly once */ + assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 ); + + assert( nOld>0 ); + assert( nNew>0 ); + + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ + /* The root page of the b-tree now contains no cells. The only sibling + ** page is the right-child of the parent. Copy the contents of the + ** child page into the parent, decreasing the overall height of the + ** b-tree structure by one. This is described as the "balance-shallower" + ** sub-algorithm in some documentation. + ** + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages + ** for which the pointer is stored within the content being copied. + ** + ** It is critical that the child page be defragmented before being + ** copied into the parent, because if the parent is page 1 then it will + ** by smaller than the child due to the database header, and so all the + ** free space needs to be up front. + */ + assert( nNew==1 || CORRUPT_DB ); + rc = defragmentPage(apNew[0], -1); + testcase( rc!=SQLITE_OK ); + assert( apNew[0]->nFree == + (get2byteNotZero(&apNew[0]->aData[5]) - apNew[0]->cellOffset + - apNew[0]->nCell*2) + || rc!=SQLITE_OK + ); + copyNodeContent(apNew[0], pParent, &rc); + freePage(apNew[0], &rc); + }else if( ISAUTOVACUUM(pBt) && !leafCorrection ){ + /* Fix the pointer map entries associated with the right-child of each + ** sibling page. All other pointer map entries have already been taken + ** care of. */ + for(i=0; iaData[8]); + ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); + } + } + + assert( pParent->isInit ); + TRACE(("BALANCE: finished: old=%u new=%u cells=%u\n", + nOld, nNew, b.nCell)); + + /* Free any old pages that were not reused as new pages. + */ + for(i=nNew; iisInit ){ + /* The ptrmapCheckPages() contains assert() statements that verify that + ** all pointer map pages are set correctly. This is helpful while + ** debugging. This is usually disabled because a corrupt database may + ** cause an assert() statement to fail. */ + ptrmapCheckPages(apNew, nNew); + ptrmapCheckPages(&pParent, 1); + } +#endif + + /* + ** Cleanup before returning. + */ +balance_cleanup: + sqlite3StackFree(0, b.apCell); + for(i=0; ipBt; /* The BTree */ + + assert( pRoot->nOverflow>0 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + + /* Make pRoot, the root page of the b-tree, writable. Allocate a new + ** page that will become the new right-child of pPage. Copy the contents + ** of the node stored on pRoot into the new child page. + */ + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc==SQLITE_OK ){ + rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); + copyNodeContent(pRoot, pChild, &rc); + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); + } + } + if( rc ){ + *ppChild = 0; + releasePage(pChild); + return rc; + } + assert( sqlite3PagerIswriteable(pChild->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); + + TRACE(("BALANCE: copy root %u into %u\n", pRoot->pgno, pChild->pgno)); + + /* Copy the overflow cells from pRoot to pChild */ + memcpy(pChild->aiOvfl, pRoot->aiOvfl, + pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); + memcpy(pChild->apOvfl, pRoot->apOvfl, + pRoot->nOverflow*sizeof(pRoot->apOvfl[0])); + pChild->nOverflow = pRoot->nOverflow; + + /* Zero the contents of pRoot. Then install pChild as the right-child. */ + zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); + put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); + + *ppChild = pChild; + return SQLITE_OK; +} + +/* +** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid +** on the same B-tree as pCur. +** +** This can occur if a database is corrupt with two or more SQL tables +** pointing to the same b-tree. If an insert occurs on one SQL table +** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL +** table linked to the same b-tree. If the secondary insert causes a +** rebalance, that can change content out from under the cursor on the +** first SQL table, violating invariants on the first insert. +*/ +static int anotherValidCursor(BtCursor *pCur){ + BtCursor *pOther; + for(pOther=pCur->pBt->pCursor; pOther; pOther=pOther->pNext){ + if( pOther!=pCur + && pOther->eState==CURSOR_VALID + && pOther->pPage==pCur->pPage + ){ + return SQLITE_CORRUPT_BKPT; + } + } + return SQLITE_OK; +} + +/* +** The page that pCur currently points to has just been modified in +** some way. This function figures out if this modification means the +** tree needs to be balanced, and if so calls the appropriate balancing +** routine. Balancing routines are: +** +** balance_quick() +** balance_deeper() +** balance_nonroot() +*/ +static int balance(BtCursor *pCur){ + int rc = SQLITE_OK; + u8 aBalanceQuickSpace[13]; + u8 *pFree = 0; + + VVA_ONLY( int balance_quick_called = 0 ); + VVA_ONLY( int balance_deeper_called = 0 ); + + do { + int iPage; + MemPage *pPage = pCur->pPage; + + if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; + if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ + /* No rebalance required as long as: + ** (1) There are no overflow cells + ** (2) The amount of free space on the page is less than 2/3rds of + ** the total usable space on the page. */ + break; + }else if( (iPage = pCur->iPage)==0 ){ + if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){ + /* The root page of the b-tree is overfull. In this case call the + ** balance_deeper() function to create a new child for the root-page + ** and copy the current contents of the root-page to it. The + ** next iteration of the do-loop will balance the child page. + */ + assert( balance_deeper_called==0 ); + VVA_ONLY( balance_deeper_called++ ); + rc = balance_deeper(pPage, &pCur->apPage[1]); + if( rc==SQLITE_OK ){ + pCur->iPage = 1; + pCur->ix = 0; + pCur->aiIdx[0] = 0; + pCur->apPage[0] = pPage; + pCur->pPage = pCur->apPage[1]; + assert( pCur->pPage->nOverflow ); + } + }else{ + break; + } + }else if( sqlite3PagerPageRefcount(pPage->pDbPage)>1 ){ + /* The page being written is not a root page, and there is currently + ** more than one reference to it. This only happens if the page is one + ** of its own ancestor pages. Corruption. */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + MemPage * const pParent = pCur->apPage[iPage-1]; + int const iIdx = pCur->aiIdx[iPage-1]; + + rc = sqlite3PagerWrite(pParent->pDbPage); + if( rc==SQLITE_OK && pParent->nFree<0 ){ + rc = btreeComputeFreeSpace(pParent); + } + if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_QUICKBALANCE + if( pPage->intKeyLeaf + && pPage->nOverflow==1 + && pPage->aiOvfl[0]==pPage->nCell + && pParent->pgno!=1 + && pParent->nCell==iIdx + ){ + /* Call balance_quick() to create a new sibling of pPage on which + ** to store the overflow cell. balance_quick() inserts a new cell + ** into pParent, which may cause pParent overflow. If this + ** happens, the next iteration of the do-loop will balance pParent + ** use either balance_nonroot() or balance_deeper(). Until this + ** happens, the overflow cell is stored in the aBalanceQuickSpace[] + ** buffer. + ** + ** The purpose of the following assert() is to check that only a + ** single call to balance_quick() is made for each call to this + ** function. If this were not verified, a subtle bug involving reuse + ** of the aBalanceQuickSpace[] might sneak in. + */ + assert( balance_quick_called==0 ); + VVA_ONLY( balance_quick_called++ ); + rc = balance_quick(pParent, pPage, aBalanceQuickSpace); + }else +#endif + { + /* In this case, call balance_nonroot() to redistribute cells + ** between pPage and up to 2 of its sibling pages. This involves + ** modifying the contents of pParent, which may cause pParent to + ** become overfull or underfull. The next iteration of the do-loop + ** will balance the parent page to correct this. + ** + ** If the parent page becomes overfull, the overflow cell or cells + ** are stored in the pSpace buffer allocated immediately below. + ** A subsequent iteration of the do-loop will deal with this by + ** calling balance_nonroot() (balance_deeper() may be called first, + ** but it doesn't deal with overflow cells - just moves them to a + ** different page). Once this subsequent call to balance_nonroot() + ** has completed, it is safe to release the pSpace buffer used by + ** the previous call, as the overflow cell data will have been + ** copied either into the body of a database page or into the new + ** pSpace buffer passed to the latter call to balance_nonroot(). + */ + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, + pCur->hints&BTREE_BULKLOAD); + if( pFree ){ + /* If pFree is not NULL, it points to the pSpace buffer used + ** by a previous call to balance_nonroot(). Its contents are + ** now stored either on real database pages or within the + ** new pSpace buffer, so it may be safely freed here. */ + sqlite3PageFree(pFree); + } + + /* The pSpace buffer will be freed after the next call to + ** balance_nonroot(), or just before this function returns, whichever + ** comes first. */ + pFree = pSpace; + } + } + + pPage->nOverflow = 0; + + /* The next iteration of the do-loop balances the parent page. */ + releasePage(pPage); + pCur->iPage--; + assert( pCur->iPage>=0 ); + pCur->pPage = pCur->apPage[pCur->iPage]; + } + }while( rc==SQLITE_OK ); + + if( pFree ){ + sqlite3PageFree(pFree); + } + return rc; +} + +/* Overwrite content from pX into pDest. Only do the write if the +** content is different from what is already there. +*/ +static int btreeOverwriteContent( + MemPage *pPage, /* MemPage on which writing will occur */ + u8 *pDest, /* Pointer to the place to start writing */ + const BtreePayload *pX, /* Source of data to write */ + int iOffset, /* Offset of first byte to write */ + int iAmt /* Number of bytes to be written */ +){ + int nData = pX->nData - iOffset; + if( nData<=0 ){ + /* Overwriting with zeros */ + int i; + for(i=0; ipDbPage); + if( rc ) return rc; + memset(pDest + i, 0, iAmt - i); + } + }else{ + if( nDatapData) + iOffset, iAmt)!=0 ){ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + /* In a corrupt database, it is possible for the source and destination + ** buffers to overlap. This is harmless since the database is already + ** corrupt but it does cause valgrind and ASAN warnings. So use + ** memmove(). */ + memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt); + } + } + return SQLITE_OK; +} + +/* +** Overwrite the cell that cursor pCur is pointing to with fresh content +** contained in pX. In this variant, pCur is pointing to an overflow +** cell. +*/ +static SQLITE_NOINLINE int btreeOverwriteOverflowCell( + BtCursor *pCur, /* Cursor pointing to cell to overwrite */ + const BtreePayload *pX /* Content to write into the cell */ +){ + int iOffset; /* Next byte of pX->pData to write */ + int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ + int rc; /* Return code */ + MemPage *pPage = pCur->pPage; /* Page being written */ + BtShared *pBt; /* Btree */ + Pgno ovflPgno; /* Next overflow page to write */ + u32 ovflPageSize; /* Size to write on overflow page */ + + assert( pCur->info.nLocalinfo.pPayload, pX, + 0, pCur->info.nLocal); + if( rc ) return rc; + + /* Now overwrite the overflow pages */ + iOffset = pCur->info.nLocal; + assert( nTotal>=0 ); + assert( iOffset>=0 ); + ovflPgno = get4byte(pCur->info.pPayload + iOffset); + pBt = pPage->pBt; + ovflPageSize = pBt->usableSize - 4; + do{ + rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); + if( rc ) return rc; + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + if( iOffset+ovflPageSize<(u32)nTotal ){ + ovflPgno = get4byte(pPage->aData); + }else{ + ovflPageSize = nTotal - iOffset; + } + rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, + iOffset, ovflPageSize); + } + sqlite3PagerUnref(pPage->pDbPage); + if( rc ) return rc; + iOffset += ovflPageSize; + }while( iOffsetnData + pX->nZero; /* Total bytes of to write */ + MemPage *pPage = pCur->pPage; /* Page being written */ + + if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd + || pCur->info.pPayload < pPage->aData + pPage->cellOffset + ){ + return SQLITE_CORRUPT_BKPT; + } + if( pCur->info.nLocal==nTotal ){ + /* The entire cell is local */ + return btreeOverwriteContent(pPage, pCur->info.pPayload, pX, + 0, pCur->info.nLocal); + }else{ + /* The cell contains overflow content */ + return btreeOverwriteOverflowCell(pCur, pX); + } +} + + +/* +** Insert a new record into the BTree. The content of the new record +** is described by the pX object. The pCur cursor is used only to +** define what table the record should be inserted into, and is left +** pointing at a random location. +** +** For a table btree (used for rowid tables), only the pX.nKey value of +** the key is used. The pX.pKey value must be NULL. The pX.nKey is the +** rowid or INTEGER PRIMARY KEY of the row. The pX.nData,pData,nZero fields +** hold the content of the row. +** +** For an index btree (used for indexes and WITHOUT ROWID tables), the +** key is an arbitrary byte sequence stored in pX.pKey,nKey. The +** pX.pData,nData,nZero fields must be zero. +** +** If the seekResult parameter is non-zero, then a successful call to +** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already +** been performed. In other words, if seekResult!=0 then the cursor +** is currently pointing to a cell that will be adjacent to the cell +** to be inserted. If seekResult<0 then pCur points to a cell that is +** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell +** that is larger than (pKey,nKey). +** +** If seekResult==0, that means pCur is pointing at some unknown location. +** In that case, this routine must seek the cursor to the correct insertion +** point for (pKey,nKey) before doing the insertion. For index btrees, +** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked +** key values and pX->aMem can be used instead of pX->pKey to avoid having +** to decode the key. +*/ +SQLITE_PRIVATE int sqlite3BtreeInsert( + BtCursor *pCur, /* Insert data into the table of this cursor */ + const BtreePayload *pX, /* Content of the row to be inserted */ + int flags, /* True if this is likely an append */ + int seekResult /* Result of prior IndexMoveto() call */ +){ + int rc; + int loc = seekResult; /* -1: before desired location +1: after */ + int szNew = 0; + int idx; + MemPage *pPage; + Btree *p = pCur->pBtree; + unsigned char *oldCell; + unsigned char *newCell = 0; + + assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); + assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); + + /* Save the positions of any other cursors open on this table. + ** + ** In some cases, the call to btreeMoveto() below is a no-op. For + ** example, when inserting data into a table with auto-generated integer + ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the + ** integer key to use. It then calls this function to actually insert the + ** data into the intkey B-Tree. In this case btreeMoveto() recognizes + ** that the cursor is already where it needs to be and returns without + ** doing any work. To avoid thwarting these optimizations, it is important + ** not to clear the cursor here. + */ + if( pCur->curFlags & BTCF_Multiple ){ + rc = saveAllCursors(p->pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + if( loc && pCur->iPage<0 ){ + /* This can only happen if the schema is corrupt such that there is more + ** than one table or index with the same root page as used by the cursor. + ** Which can only happen if the SQLITE_NoSchemaError flag was set when + ** the schema was loaded. This cannot be asserted though, as a user might + ** set the flag, load the schema, and then unset the flag. */ + return SQLITE_CORRUPT_BKPT; + } + } + + /* Ensure that the cursor is not in the CURSOR_FAULT state and that it + ** points to a valid cell. + */ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + testcase( pCur->eState==CURSOR_REQUIRESEEK ); + testcase( pCur->eState==CURSOR_FAULT ); + rc = moveToRoot(pCur); + if( rc && rc!=SQLITE_EMPTY ) return rc; + } + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 + && p->pBt->inTransaction==TRANS_WRITE + && (p->pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); + + if( pCur->pKeyInfo==0 ){ + assert( pX->pKey==0 ); + /* If this is an insert into a table b-tree, invalidate any incrblob + ** cursors open on the row being replaced */ + if( p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); + } + + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. + */ +#ifdef SQLITE_DEBUG + if( flags & BTREE_SAVEPOSITION ){ + assert( pCur->curFlags & BTCF_ValidNKey ); + assert( pX->nKey==pCur->info.nKey ); + assert( loc==0 ); + } +#endif + + /* On the other hand, BTREE_SAVEPOSITION==0 does not imply + ** that the cursor is not pointing to a row to be overwritten. + ** So do a complete check. + */ + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ + /* The cursor is pointing to the entry that is to be + ** overwritten */ + assert( pX->nData>=0 && pX->nZero>=0 ); + if( pCur->info.nSize!=0 + && pCur->info.nPayload==(u32)pX->nData+pX->nZero + ){ + /* New entry is the same size as the old. Do an overwrite */ + return btreeOverwriteCell(pCur, pX); + } + assert( loc==0 ); + }else if( loc==0 ){ + /* The cursor is *not* pointing to the cell to be overwritten, nor + ** to an adjacent cell. Move the cursor so that it is pointing either + ** to the cell to be overwritten or an adjacent cell. + */ + rc = sqlite3BtreeTableMoveto(pCur, pX->nKey, + (flags & BTREE_APPEND)!=0, &loc); + if( rc ) return rc; + } + }else{ + /* This is an index or a WITHOUT ROWID table */ + + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. + */ + assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 ); + + /* If the cursor is not already pointing either to the cell to be + ** overwritten, or if a new cell is being inserted, if the cursor is + ** not pointing to an immediately adjacent cell, then move the cursor + ** so that it does. + */ + if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ + if( pX->nMem ){ + UnpackedRecord r; + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + r.default_rc = 0; + r.eqSeen = 0; + rc = sqlite3BtreeIndexMoveto(pCur, &r, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, + (flags & BTREE_APPEND)!=0, &loc); + } + if( rc ) return rc; + } + + /* If the cursor is currently pointing to an entry to be overwritten + ** and the new content is the same as as the old, then use the + ** overwrite optimization. + */ + if( loc==0 ){ + getCellInfo(pCur); + if( pCur->info.nKey==pX->nKey ){ + BtreePayload x2; + x2.pData = pX->pKey; + x2.nData = pX->nKey; + x2.nZero = 0; + return btreeOverwriteCell(pCur, &x2); + } + } + } + assert( pCur->eState==CURSOR_VALID + || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); + + pPage = pCur->pPage; + assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); + assert( pPage->leaf || !pPage->intKey ); + if( pPage->nFree<0 ){ + if( NEVER(pCur->eState>CURSOR_INVALID) ){ + /* ^^^^^--- due to the moveToRoot() call above */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = btreeComputeFreeSpace(pPage); + } + if( rc ) return rc; + } + + TRACE(("INSERT: table=%u nkey=%lld ndata=%u page=%u %s\n", + pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, + loc==0 ? "overwrite" : "new entry")); + assert( pPage->isInit || CORRUPT_DB ); + newCell = p->pBt->pTmpSpace; + assert( newCell!=0 ); + assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); + if( flags & BTREE_PREFORMAT ){ + rc = SQLITE_OK; + szNew = p->pBt->nPreformatSize; + if( szNew<4 ){ + szNew = 4; + newCell[3] = 0; + } + if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ + CellInfo info; + pPage->xParseCell(pPage, newCell, &info); + if( info.nPayload!=info.nLocal ){ + Pgno ovfl = get4byte(&newCell[szNew-4]); + ptrmapPut(p->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); + if( NEVER(rc) ) goto end_insert; + } + } + }else{ + rc = fillInCell(pPage, newCell, pX, &szNew); + if( rc ) goto end_insert; + } + assert( szNew==pPage->xCellSize(pPage, newCell) ); + assert( szNew <= MX_CELL_SIZE(p->pBt) ); + idx = pCur->ix; + pCur->info.nSize = 0; + if( loc==0 ){ + CellInfo info; + assert( idx>=0 ); + if( idx>=pPage->nCell ){ + return SQLITE_CORRUPT_BKPT; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ){ + goto end_insert; + } + oldCell = findCell(pPage, idx); + if( !pPage->leaf ){ + memcpy(newCell, oldCell, 4); + } + BTREE_CLEAR_CELL(rc, pPage, oldCell, info); + testcase( pCur->curFlags & BTCF_ValidOvfl ); + invalidateOverflowCache(pCur); + if( info.nSize==szNew && info.nLocal==info.nPayload + && (!ISAUTOVACUUM(p->pBt) || szNewminLocal) + ){ + /* Overwrite the old cell with the new if they are the same size. + ** We could also try to do this if the old cell is smaller, then add + ** the leftover space to the free list. But experiments show that + ** doing that is no faster then skipping this optimization and just + ** calling dropCell() and insertCell(). + ** + ** This optimization cannot be used on an autovacuum database if the + ** new entry uses overflow pages, as the insertCell() call below is + ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ + assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ + if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ + return SQLITE_CORRUPT_BKPT; + } + if( oldCell+szNew > pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + memcpy(oldCell, newCell, szNew); + return SQLITE_OK; + } + dropCell(pPage, idx, info.nSize, &rc); + if( rc ) goto end_insert; + }else if( loc<0 && pPage->nCell>0 ){ + assert( pPage->leaf ); + idx = ++pCur->ix; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + }else{ + assert( pPage->leaf ); + } + rc = insertCellFast(pPage, idx, newCell, szNew); + assert( pPage->nOverflow==0 || rc==SQLITE_OK ); + assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); + + /* If no error has occurred and pPage has an overflow cell, call balance() + ** to redistribute the cells within the tree. Since balance() may move + ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey + ** variables. + ** + ** Previous versions of SQLite called moveToRoot() to move the cursor + ** back to the root page as balance() used to invalidate the contents + ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, + ** set the cursor state to "invalid". This makes common insert operations + ** slightly faster. + ** + ** There is a subtle but important optimization here too. When inserting + ** multiple records into an intkey b-tree using a single cursor (as can + ** happen while processing an "INSERT INTO ... SELECT" statement), it + ** is advantageous to leave the cursor pointing to the last entry in + ** the b-tree if possible. If the cursor is left pointing to the last + ** entry in the table, and the next row inserted has an integer key + ** larger than the largest existing key, it is possible to insert the + ** row without seeking the cursor. This can be a big performance boost. + */ + if( pPage->nOverflow ){ + assert( rc==SQLITE_OK ); + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + rc = balance(pCur); + + /* Must make sure nOverflow is reset to zero even if the balance() + ** fails. Internal data structure corruption will result otherwise. + ** Also, set the cursor state to invalid. This stops saveCursorPosition() + ** from trying to save the current position of the cursor. */ + pCur->pPage->nOverflow = 0; + pCur->eState = CURSOR_INVALID; + if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ + btreeReleaseAllCursorPages(pCur); + if( pCur->pKeyInfo ){ + assert( pCur->pKey==0 ); + pCur->pKey = sqlite3Malloc( pX->nKey ); + if( pCur->pKey==0 ){ + rc = SQLITE_NOMEM; + }else{ + memcpy(pCur->pKey, pX->pKey, pX->nKey); + } + } + pCur->eState = CURSOR_REQUIRESEEK; + pCur->nKey = pX->nKey; + } + } + assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 ); + +end_insert: + return rc; +} + +/* +** This function is used as part of copying the current row from cursor +** pSrc into cursor pDest. If the cursors are open on intkey tables, then +** parameter iKey is used as the rowid value when the record is copied +** into pDest. Otherwise, the record is copied verbatim. +** +** This function does not actually write the new value to cursor pDest. +** Instead, it creates and populates any required overflow pages and +** writes the data for the new cell into the BtShared.pTmpSpace buffer +** for the destination database. The size of the cell, in bytes, is left +** in BtShared.nPreformatSize. The caller completes the insertion by +** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ + BtShared *pBt = pDest->pBt; + u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ + const u8 *aIn; /* Pointer to next input buffer */ + u32 nIn; /* Size of input buffer aIn[] */ + u32 nRem; /* Bytes of data still to copy */ + + getCellInfo(pSrc); + if( pSrc->info.nPayload<0x80 ){ + *(aOut++) = pSrc->info.nPayload; + }else{ + aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); + } + if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); + nIn = pSrc->info.nLocal; + aIn = pSrc->info.pPayload; + if( aIn+nIn>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + nRem = pSrc->info.nPayload; + if( nIn==nRem && nInpPage->maxLocal ){ + memcpy(aOut, aIn, nIn); + pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); + return SQLITE_OK; + }else{ + int rc = SQLITE_OK; + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; + u32 nOut; /* Size of output buffer aOut[] */ + + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); + if( nOutinfo.nPayload ){ + pPgnoOut = &aOut[nOut]; + pBt->nPreformatSize += 4; + } + + if( nRem>nIn ){ + if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ + Pgno pgnoNew; + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + if( ISAUTOVACUUM(pBt) && pPageOut ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); + } + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pBt->usableSize - 4, nRem); + } + } + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); + return rc; + } +} + +/* +** Delete the entry that the cursor is pointing to. +** +** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then +** the cursor is left pointing at an arbitrary location after the delete. +** But if that bit is set, then the cursor is left in a state such that +** the next call to BtreeNext() or BtreePrev() moves it to the same row +** as it would have been on if the call to BtreeDelete() had been omitted. +** +** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes +** associated with a single table entry and its indexes. Only one of those +** deletes is considered the "primary" delete. The primary delete occurs +** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete +** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag. +** The BTREE_AUXDELETE bit is a hint that is not used by this implementation, +** but which might be used by alternative storage engines. +*/ +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ + CellInfo info; /* Size of the cell being deleted */ + u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */ + + assert( cursorOwnsBtShared(pCur) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( pCur->curFlags & BTCF_WriteFlag ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + assert( !hasReadConflicts(p, pCur->pgnoRoot) ); + assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); + if( pCur->eState!=CURSOR_VALID ){ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = btreeRestoreCursorPosition(pCur); + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; + }else{ + return SQLITE_CORRUPT_BKPT; + } + } + assert( pCur->eState==CURSOR_VALID ); + + iCellDepth = pCur->iPage; + iCellIdx = pCur->ix; + pPage = pCur->pPage; + if( pPage->nCell<=iCellIdx ){ + return SQLITE_CORRUPT_BKPT; + } + pCell = findCell(pPage, iCellIdx); + if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ + return SQLITE_CORRUPT_BKPT; + } + if( pCell<&pPage->aCellIdx[pPage->nCell] ){ + return SQLITE_CORRUPT_BKPT; + } + + /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must + ** be preserved following this delete operation. If the current delete + ** will cause a b-tree rebalance, then this is done by saving the cursor + ** key and leaving the cursor in CURSOR_REQUIRESEEK state before + ** returning. + ** + ** If the current delete will not cause a rebalance, then the cursor + ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately + ** before or after the deleted entry. + ** + ** The bPreserve value records which path is required: + ** + ** bPreserve==0 Not necessary to save the cursor position + ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position + ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. + */ + bPreserve = (flags & BTREE_SAVEPOSITION)!=0; + if( bPreserve ){ + if( !pPage->leaf + || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) > + (int)(pBt->usableSize*2/3) + || pPage->nCell==1 /* See dbfuzz001.test for a test case */ + ){ + /* A b-tree rebalance will be required after deleting this entry. + ** Save the cursor key. */ + rc = saveCursorKey(pCur); + if( rc ) return rc; + }else{ + bPreserve = 2; + } + } + + /* If the page containing the entry to delete is not a leaf page, move + ** the cursor to the largest entry in the tree that is smaller than + ** the entry being deleted. This cell will replace the cell being deleted + ** from the internal node. The 'previous' entry is used for this instead + ** of the 'next' entry, as the previous entry is always a part of the + ** sub-tree headed by the child page of the cell being deleted. This makes + ** balancing the tree following the delete operation easier. */ + if( !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, 0); + assert( rc!=SQLITE_DONE ); + if( rc ) return rc; + } + + /* Save the positions of any other cursors open on this table before + ** making any modifications. */ + if( pCur->curFlags & BTCF_Multiple ){ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + } + + /* If this is a delete operation to remove a row from a table b-tree, + ** invalidate any incrblob cursors open on the row being deleted. */ + if( pCur->pKeyInfo==0 && p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0); + } + + /* Make the page containing the entry to be deleted writable. Then free any + ** overflow pages associated with the entry and finally remove the cell + ** itself from within the page. */ + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + BTREE_CLEAR_CELL(rc, pPage, pCell, info); + dropCell(pPage, iCellIdx, info.nSize, &rc); + if( rc ) return rc; + + /* If the cell deleted was not located on a leaf page, then the cursor + ** is currently pointing to the largest entry in the sub-tree headed + ** by the child-page of the cell that was just deleted from an internal + ** node. The cell from the leaf node needs to be moved to the internal + ** node to replace the deleted cell. */ + if( !pPage->leaf ){ + MemPage *pLeaf = pCur->pPage; + int nCell; + Pgno n; + unsigned char *pTmp; + + if( pLeaf->nFree<0 ){ + rc = btreeComputeFreeSpace(pLeaf); + if( rc ) return rc; + } + if( iCellDepthiPage-1 ){ + n = pCur->apPage[iCellDepth+1]->pgno; + }else{ + n = pCur->pPage->pgno; + } + pCell = findCell(pLeaf, pLeaf->nCell-1); + if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; + nCell = pLeaf->xCellSize(pLeaf, pCell); + assert( MX_CELL_SIZE(pBt) >= nCell ); + pTmp = pBt->pTmpSpace; + assert( pTmp!=0 ); + rc = sqlite3PagerWrite(pLeaf->pDbPage); + if( rc==SQLITE_OK ){ + rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n); + } + dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); + if( rc ) return rc; + } + + /* Balance the tree. If the entry deleted was located on a leaf page, + ** then the cursor still points to that page. In this case the first + ** call to balance() repairs the tree, and the if(...) condition is + ** never true. + ** + ** Otherwise, if the entry deleted was on an internal node page, then + ** pCur is pointing to the leaf page from which a cell was removed to + ** replace the cell deleted from the internal node. This is slightly + ** tricky as the leaf node may be underfull, and the internal node may + ** be either under or overfull. In this case run the balancing algorithm + ** on the leaf node first. If the balance proceeds far enough up the + ** tree that we can be sure that any problem in the internal node has + ** been corrected, so be it. Otherwise, after balancing the leaf node, + ** walk the cursor up the tree to the internal node and balance it as + ** well. */ + assert( pCur->pPage->nOverflow==0 ); + assert( pCur->pPage->nFree>=0 ); + if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ + /* Optimization: If the free space is less than 2/3rds of the page, + ** then balance() will always be a no-op. No need to invoke it. */ + rc = SQLITE_OK; + }else{ + rc = balance(pCur); + } + if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + releasePageNotNull(pCur->pPage); + pCur->iPage--; + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); + } + pCur->pPage = pCur->apPage[pCur->iPage]; + rc = balance(pCur); + } + + if( rc==SQLITE_OK ){ + if( bPreserve>1 ){ + assert( (pCur->iPage==iCellDepth || CORRUPT_DB) ); + assert( pPage==pCur->pPage || CORRUPT_DB ); + assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); + pCur->eState = CURSOR_SKIPNEXT; + if( iCellIdx>=pPage->nCell ){ + pCur->skipNext = -1; + pCur->ix = pPage->nCell-1; + }else{ + pCur->skipNext = 1; + } + }else{ + rc = moveToRoot(pCur); + if( bPreserve ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = CURSOR_REQUIRESEEK; + } + if( rc==SQLITE_EMPTY ) rc = SQLITE_OK; + } + } + return rc; +} + +/* +** Create a new BTree table. Write into *piTable the page +** number for the root page of the new table. +** +** The type of type is determined by the flags parameter. Only the +** following values of flags are currently in use. Other values for +** flags might not work: +** +** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys +** BTREE_ZERODATA Used for SQL indices +*/ +static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ + BtShared *pBt = p->pBt; + MemPage *pRoot; + Pgno pgnoRoot; + int rc; + int ptfFlags; /* Page-type flags for the root page of new table */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ){ + return rc; + } +#else + if( pBt->autoVacuum ){ + Pgno pgnoMove; /* Move a page here to make room for the root-page */ + MemPage *pPageMove; /* The page to move to. */ + + /* Creating a new table may probably require moving an existing database + ** to make room for the new tables root page. In case this page turns + ** out to be an overflow page, delete all overflow page-map caches + ** held by open cursors. + */ + invalidateAllOverflowCache(pBt); + + /* Read the value of meta[3] from the database to determine where the + ** root page of the new table should go. meta[3] is the largest root-page + ** created so far, so the new root-page is (meta[3]+1). + */ + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); + if( pgnoRoot>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_BKPT; + } + pgnoRoot++; + + /* The new root-page may not be allocated on a pointer-map page, or the + ** PENDING_BYTE page. + */ + while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) || + pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 ); + + /* Allocate a page. The page that currently resides at pgnoRoot will + ** be moved to the allocated page (unless the allocated page happens + ** to reside at pgnoRoot). + */ + rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT); + if( rc!=SQLITE_OK ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + /* pgnoRoot is the page that will be used for the root-page of + ** the new table (assuming an error did not occur). But we were + ** allocated pgnoMove. If required (i.e. if it was not allocated + ** by extending the file), the current page at position pgnoMove + ** is already journaled. + */ + u8 eType = 0; + Pgno iPtrPage = 0; + + /* Save the positions of any open cursors. This is required in + ** case they are holding a reference to an xFetch reference + ** corresponding to page pgnoRoot. */ + rc = saveAllCursors(pBt, 0, 0); + releasePage(pPageMove); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Move the page currently at pgnoRoot to pgnoMove. */ + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + assert( eType!=PTRMAP_ROOTPAGE ); + assert( eType!=PTRMAP_FREEPAGE ); + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0); + releasePage(pRoot); + + /* Obtain the page at pgnoRoot */ + if( rc!=SQLITE_OK ){ + return rc; + } + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + /* Update the pointer-map and meta-data with the new root-page number. */ + ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); + if( rc ){ + releasePage(pRoot); + return rc; + } + + /* When the new root page was allocated, page 1 was made writable in + ** order either to increase the database filesize, or to decrement the + ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. + */ + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); + rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); + if( NEVER(rc) ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } +#endif + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + if( createTabFlags & BTREE_INTKEY ){ + ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; + }else{ + ptfFlags = PTF_ZERODATA | PTF_LEAF; + } + zeroPage(pRoot, ptfFlags); + sqlite3PagerUnref(pRoot->pDbPage); + assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); + *piTable = pgnoRoot; + return SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, Pgno *piTable, int flags){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCreateTable(p, piTable, flags); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Erase the given database page and all its children. Return +** the page to the freelist. +*/ +static int clearDatabasePage( + BtShared *pBt, /* The BTree that contains the table */ + Pgno pgno, /* Page number to clear */ + int freePageFlag, /* Deallocate page if true */ + i64 *pnChange /* Add number of Cells freed to this counter */ +){ + MemPage *pPage; + int rc; + unsigned char *pCell; + int i; + int hdr; + CellInfo info; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_BKPT; + } + rc = getAndInitPage(pBt, pgno, &pPage, 0); + if( rc ) return rc; + if( (pBt->openFlags & BTREE_SINGLE)==0 + && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) + ){ + rc = SQLITE_CORRUPT_BKPT; + goto cleardatabasepage_out; + } + hdr = pPage->hdrOffset; + for(i=0; inCell; i++){ + pCell = findCell(pPage, i); + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + } + BTREE_CLEAR_CELL(rc, pPage, pCell, info); + if( rc ) goto cleardatabasepage_out; + } + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + if( pPage->intKey ) pnChange = 0; + } + if( pnChange ){ + testcase( !pPage->intKey ); + *pnChange += pPage->nCell; + } + if( freePageFlag ){ + freePage(pPage, &rc); + }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ + zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); + } + +cleardatabasepage_out: + releasePage(pPage); + return rc; +} + +/* +** Delete all information from a single table in the database. iTable is +** the page number of the root of the table. After this routine returns, +** the root page is empty, but still exists. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** read cursors on the table. Open write cursors are moved to the +** root of the table. +** +** If pnChange is not NULL, then the integer value pointed to by pnChange +** is incremented by the number of entries in the table. +*/ +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, i64 *pnChange){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + + rc = saveAllCursors(pBt, (Pgno)iTable, 0); + + if( SQLITE_OK==rc ){ + /* Invalidate all incrblob cursors open on table iTable (assuming iTable + ** is the root of a table b-tree - if it is not, the following call is + ** a no-op). */ + if( p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); + } + rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Delete all information from the single table that pCur is open on. +** +** This routine only work for pCur on an ephemeral table. +*/ +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ + return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); +} + +/* +** Erase all information in a table and add the root of the table to +** the freelist. Except, the root of the principle table (the one on +** page 1) is never added to the freelist. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** cursors on the table. +** +** If AUTOVACUUM is enabled and the page at iTable is not the last +** root page in the database file, then the last root page +** in the database file is moved into the slot formerly occupied by +** iTable and that last slot formerly occupied by the last root page +** is added to the freelist instead of iTable. In this say, all +** root pages are kept at the beginning of the database file, which +** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** page number that used to be the last root page in the file before +** the move. If no page gets moved, *piMoved is set to 0. +** The last root page is recorded in meta[3] and the value of +** meta[3] is updated by this procedure. +*/ +static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ + int rc; + MemPage *pPage = 0; + BtShared *pBt = p->pBt; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->inTrans==TRANS_WRITE ); + assert( iTable>=2 ); + if( iTable>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_BKPT; + } + + rc = sqlite3BtreeClearTable(p, iTable, 0); + if( rc ) return rc; + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + if( NEVER(rc) ){ + releasePage(pPage); + return rc; + } + + *piMoved = 0; + +#ifdef SQLITE_OMIT_AUTOVACUUM + freePage(pPage, &rc); + releasePage(pPage); +#else + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); + + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. + */ + freePage(pPage, &rc); + releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; + } + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. + */ + maxRootPgno--; + while( maxRootPgno==PENDING_BYTE_PAGE(pBt) + || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + }else{ + freePage(pPage, &rc); + releasePage(pPage); + } +#endif + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeDropTable(p, iTable, piMoved); + sqlite3BtreeLeave(p); + return rc; +} + + +/* +** This function may only be called if the b-tree connection already +** has a read or write transaction open on the database. +** +** Read the meta-information out of a database file. Meta[0] +** is the number of free pages currently in the database. Meta[1] +** through meta[15] are available for use by higher layers. Meta[0] +** is read-only, the others are read/write. +** +** The schema layer numbers meta values differently. At the schema +** layer (and the SetCookie and ReadCookie opcodes) the number of +** free pages is not visible. So Cookie[0] is the same as Meta[1]. +** +** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead +** of reading the value out of the header, it instead loads the "DataVersion" +** from the pager. The BTREE_DATA_VERSION value is not actually stored in the +** database file. It is a number computed by the pager. But its access +** pattern is the same as header meta values, and so it is convenient to +** read it from this routine. +*/ +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE ); + assert( SQLITE_OK==querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK) ); + assert( pBt->pPage1 ); + assert( idx>=0 && idx<=15 ); + + if( idx==BTREE_DATA_VERSION ){ + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iBDataVersion; + }else{ + *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); + } + + /* If auto-vacuum is disabled in this build and this is an auto-vacuum + ** database, mark the database as read-only. */ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } +#endif + + sqlite3BtreeLeave(p); +} + +/* +** Write meta-information back into the database. Meta[0] is +** read-only and may not be written. +*/ +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ + BtShared *pBt = p->pBt; + unsigned char *pP1; + int rc; + assert( idx>=1 && idx<=15 ); + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1!=0 ); + pP1 = pBt->pPage1->aData; + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pP1[36 + idx*4], iMeta); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_INCR_VACUUM ){ + assert( pBt->autoVacuum || iMeta==0 ); + assert( iMeta==0 || iMeta==1 ); + pBt->incrVacuum = (u8)iMeta; + } +#endif + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** The first argument, pCur, is a cursor opened on some b-tree. Count the +** number of entries in the b-tree and write the result to *pnEntry. +** +** SQLITE_OK is returned if the operation is successfully executed. +** Otherwise, if an error is encountered (i.e. an IO error or database +** corruption) an SQLite error code is returned. +*/ +SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){ + i64 nEntry = 0; /* Value to return in *pnEntry */ + int rc; /* Return code */ + + rc = moveToRoot(pCur); + if( rc==SQLITE_EMPTY ){ + *pnEntry = 0; + return SQLITE_OK; + } + + /* Unless an error occurs, the following loop runs one iteration for each + ** page in the B-Tree structure (not including overflow pages). + */ + while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){ + int iIdx; /* Index of child node in parent */ + MemPage *pPage; /* Current page of the b-tree */ + + /* If this is a leaf page or the tree is not an int-key tree, then + ** this page contains countable entries. Increment the entry counter + ** accordingly. + */ + pPage = pCur->pPage; + if( pPage->leaf || !pPage->intKey ){ + nEntry += pPage->nCell; + } + + /* pPage is a leaf node. This loop navigates the cursor so that it + ** points to the first interior cell that it points to the parent of + ** the next page in the tree that has not yet been visited. The + ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell + ** of the page, or to the number of cells in the page if the next page + ** to visit is the right-child of its parent. + ** + ** If all pages in the tree have been visited, return SQLITE_OK to the + ** caller. + */ + if( pPage->leaf ){ + do { + if( pCur->iPage==0 ){ + /* All pages of the b-tree have been visited. Return successfully. */ + *pnEntry = nEntry; + return moveToRoot(pCur); + } + moveToParent(pCur); + }while ( pCur->ix>=pCur->pPage->nCell ); + + pCur->ix++; + pPage = pCur->pPage; + } + + /* Descend to the child node of the cell that the cursor currently + ** points at. This is the right-child if (iIdx==pPage->nCell). + */ + iIdx = pCur->ix; + if( iIdx==pPage->nCell ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + }else{ + rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx))); + } + } + + /* An error has occurred. Return an error code. */ + return rc; +} + +/* +** Return the pager associated with a BTree. This routine is used for +** testing and debugging only. +*/ +SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ + return p->pBt->pPager; +} + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** Record an OOM error during integrity_check +*/ +static void checkOom(IntegrityCk *pCheck){ + pCheck->rc = SQLITE_NOMEM; + pCheck->mxErr = 0; /* Causes integrity_check processing to stop */ + if( pCheck->nErr==0 ) pCheck->nErr++; +} + +/* +** Invoke the progress handler, if appropriate. Also check for an +** interrupt. +*/ +static void checkProgress(IntegrityCk *pCheck){ + sqlite3 *db = pCheck->db; + if( AtomicLoad(&db->u1.isInterrupted) ){ + pCheck->rc = SQLITE_INTERRUPT; + pCheck->nErr++; + pCheck->mxErr = 0; + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + assert( db->nProgressOps>0 ); + pCheck->nStep++; + if( (pCheck->nStep % db->nProgressOps)==0 + && db->xProgress(db->pProgressArg) + ){ + pCheck->rc = SQLITE_INTERRUPT; + pCheck->nErr++; + pCheck->mxErr = 0; + } + } +#endif +} + +/* +** Append a message to the error message string. +*/ +static void checkAppendMsg( + IntegrityCk *pCheck, + const char *zFormat, + ... +){ + va_list ap; + checkProgress(pCheck); + if( !pCheck->mxErr ) return; + pCheck->mxErr--; + pCheck->nErr++; + va_start(ap, zFormat); + if( pCheck->errMsg.nChar ){ + sqlite3_str_append(&pCheck->errMsg, "\n", 1); + } + if( pCheck->zPfx ){ + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, + pCheck->v0, pCheck->v1, pCheck->v2); + } + sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); + va_end(ap); + if( pCheck->errMsg.accError==SQLITE_NOMEM ){ + checkOom(pCheck); + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + +/* +** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that +** corresponds to page iPg is already set. +*/ +static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); + return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); +} + +/* +** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. +*/ +static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); + pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); +} + + +/* +** Add 1 to the reference count for page iPage. If this is the second +** reference to the page, add an error message to pCheck->zErrMsg. +** Return 1 if there are 2 or more references to the page and 0 if +** if this is the first reference to the page. +** +** Also check that the page number is in bounds. +*/ +static int checkRef(IntegrityCk *pCheck, Pgno iPage){ + if( iPage>pCheck->nCkPage || iPage==0 ){ + checkAppendMsg(pCheck, "invalid page number %u", iPage); + return 1; + } + if( getPageReferenced(pCheck, iPage) ){ + checkAppendMsg(pCheck, "2nd reference to page %u", iPage); + return 1; + } + setPageReferenced(pCheck, iPage); + return 0; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Check that the entry in the pointer-map for page iChild maps to +** page iParent, pointer type ptrType. If not, append an error message +** to pCheck. +*/ +static void checkPtrmap( + IntegrityCk *pCheck, /* Integrity check context */ + Pgno iChild, /* Child page number */ + u8 eType, /* Expected pointer map type */ + Pgno iParent /* Expected pointer map parent page number */ +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck); + checkAppendMsg(pCheck, "Failed to read ptrmap key=%u", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, + "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} +#endif + +/* +** Check the integrity of the freelist or of an overflow page list. +** Verify that the number of pages on the list is N. +*/ +static void checkList( + IntegrityCk *pCheck, /* Integrity checking context */ + int isFreeList, /* True for a freelist. False for overflow page list */ + Pgno iPage, /* Page number for first page in the list */ + u32 N /* Expected number of pages in the list */ +){ + int i; + u32 expected = N; + int nErrAtStart = pCheck->nErr; + while( iPage!=0 && pCheck->mxErr ){ + DbPage *pOvflPage; + unsigned char *pOvflData; + if( checkRef(pCheck, iPage) ) break; + N--; + if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ + checkAppendMsg(pCheck, "failed to get page %u", iPage); + break; + } + pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); + if( isFreeList ){ + u32 n = (u32)get4byte(&pOvflData[4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); + } +#endif + if( n>pCheck->pBt->usableSize/4-2 ){ + checkAppendMsg(pCheck, + "freelist leaf count too big on page %u", iPage); + N--; + }else{ + for(i=0; i<(int)n; i++){ + Pgno iFreePage = get4byte(&pOvflData[8+i*4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0); + } +#endif + checkRef(pCheck, iFreePage); + } + N -= n; + } + } +#ifndef SQLITE_OMIT_AUTOVACUUM + else{ + /* If this database supports auto-vacuum and iPage is not the last + ** page in this overflow list, check that the pointer-map entry for + ** the following page matches iPage. + */ + if( pCheck->pBt->autoVacuum && N>0 ){ + i = get4byte(pOvflData); + checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage); + } + } +#endif + iPage = get4byte(pOvflData); + sqlite3PagerUnref(pOvflPage); + } + if( N && nErrAtStart==pCheck->nErr ){ + checkAppendMsg(pCheck, + "%s is %u but should be %u", + isFreeList ? "size" : "overflow list length", + expected-N, expected); + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** An implementation of a min-heap. +** +** aHeap[0] is the number of elements on the heap. aHeap[1] is the +** root element. The daughter nodes of aHeap[N] are aHeap[N*2] +** and aHeap[N*2+1]. +** +** The heap property is this: Every node is less than or equal to both +** of its daughter nodes. A consequence of the heap property is that the +** root node aHeap[1] is always the minimum value currently in the heap. +** +** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto +** the heap, preserving the heap property. The btreeHeapPull() routine +** removes the root element from the heap (the minimum value in the heap) +** and then moves other nodes around as necessary to preserve the heap +** property. +** +** This heap is used for cell overlap and coverage testing. Each u32 +** entry represents the span of a cell or freeblock on a btree page. +** The upper 16 bits are the index of the first byte of a range and the +** lower 16 bits are the index of the last byte of that range. +*/ +static void btreeHeapInsert(u32 *aHeap, u32 x){ + u32 j, i; + assert( aHeap!=0 ); + i = ++aHeap[0]; + aHeap[i] = x; + while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ + x = aHeap[j]; + aHeap[j] = aHeap[i]; + aHeap[i] = x; + i = j; + } +} +static int btreeHeapPull(u32 *aHeap, u32 *pOut){ + u32 j, i, x; + if( (x = aHeap[0])==0 ) return 0; + *pOut = aHeap[1]; + aHeap[1] = aHeap[x]; + aHeap[x] = 0xffffffff; + aHeap[0]--; + i = 1; + while( (j = i*2)<=aHeap[0] ){ + if( aHeap[j]>aHeap[j+1] ) j++; + if( aHeap[i]zPfx; + int saved_v1 = pCheck->v1; + int saved_v2 = pCheck->v2; + u8 savedIsInit = 0; + + /* Check that the page exists + */ + checkProgress(pCheck); + if( pCheck->mxErr==0 ) goto end_of_check; + pBt = pCheck->pBt; + usableSize = pBt->usableSize; + if( iPage==0 ) return 0; + if( checkRef(pCheck, iPage) ) return 0; + pCheck->zPfx = "Tree %u page %u: "; + pCheck->v1 = iPage; + if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ + checkAppendMsg(pCheck, + "unable to get the page. error code=%d", rc); + if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; + goto end_of_check; + } + + /* Clear MemPage.isInit to make sure the corruption detection code in + ** btreeInitPage() is executed. */ + savedIsInit = pPage->isInit; + pPage->isInit = 0; + if( (rc = btreeInitPage(pPage))!=0 ){ + assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ + checkAppendMsg(pCheck, + "btreeInitPage() returns error code %d", rc); + goto end_of_check; + } + if( (rc = btreeComputeFreeSpace(pPage))!=0 ){ + assert( rc==SQLITE_CORRUPT ); + checkAppendMsg(pCheck, "free space corruption", rc); + goto end_of_check; + } + data = pPage->aData; + hdr = pPage->hdrOffset; + + /* Set up for cell analysis */ + pCheck->zPfx = "Tree %u page %u cell %u: "; + contentOffset = get2byteNotZero(&data[hdr+5]); + assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ + + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ + nCell = get2byte(&data[hdr+3]); + assert( pPage->nCell==nCell ); + + /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page + ** immediately follows the b-tree page header. */ + cellStart = hdr + 12 - 4*pPage->leaf; + assert( pPage->aCellIdx==&data[cellStart] ); + pCellIdx = &data[cellStart + 2*(nCell-1)]; + + if( !pPage->leaf ){ + /* Analyze the right-child page of internal pages */ + pgno = get4byte(&data[hdr+8]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + pCheck->zPfx = "Tree %u page %u right child: "; + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); + } +#endif + depth = checkTreePage(pCheck, pgno, &maxKey, maxKey); + keyCanBeEqual = 0; + }else{ + /* For leaf pages, the coverage check will occur in the same loop + ** as the other cell checks, so initialize the heap. */ + heap = pCheck->heap; + heap[0] = 0; + } + + /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte + ** integer offsets to the cell contents. */ + for(i=nCell-1; i>=0 && pCheck->mxErr; i--){ + CellInfo info; + + /* Check cell size */ + pCheck->v2 = i; + assert( pCellIdx==&data[cellStart + i*2] ); + pc = get2byteAligned(pCellIdx); + pCellIdx -= 2; + if( pcusableSize-4 ){ + checkAppendMsg(pCheck, "Offset %u out of range %u..%u", + pc, contentOffset, usableSize-4); + doCoverageCheck = 0; + continue; + } + pCell = &data[pc]; + pPage->xParseCell(pPage, pCell, &info); + if( pc+info.nSize>usableSize ){ + checkAppendMsg(pCheck, "Extends off end of page"); + doCoverageCheck = 0; + continue; + } + + /* Check for integer primary key out of range */ + if( pPage->intKey ){ + if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){ + checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey); + } + maxKey = info.nKey; + keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */ + } + + /* Check the content overflow list */ + if( info.nPayload>info.nLocal ){ + u32 nPage; /* Number of pages on the overflow chain */ + Pgno pgnoOvfl; /* First page of the overflow chain */ + assert( pc + info.nSize - 4 <= usableSize ); + nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4); + pgnoOvfl = get4byte(&pCell[info.nSize - 4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage); + } +#endif + checkList(pCheck, 0, pgnoOvfl, nPage); + } + + if( !pPage->leaf ){ + /* Check sanity of left child page for internal pages */ + pgno = get4byte(pCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); + } +#endif + d2 = checkTreePage(pCheck, pgno, &maxKey, maxKey); + keyCanBeEqual = 0; + if( d2!=depth ){ + checkAppendMsg(pCheck, "Child page depth differs"); + depth = d2; + } + }else{ + /* Populate the coverage-checking heap for leaf pages */ + btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); + } + } + *piMinKey = maxKey; + + /* Check for complete coverage of the page + */ + pCheck->zPfx = 0; + if( doCoverageCheck && pCheck->mxErr>0 ){ + /* For leaf pages, the min-heap has already been initialized and the + ** cells have already been inserted. But for internal pages, that has + ** not yet been done, so do it now */ + if( !pPage->leaf ){ + heap = pCheck->heap; + heap[0] = 0; + for(i=nCell-1; i>=0; i--){ + u32 size; + pc = get2byteAligned(&data[cellStart+i*2]); + size = pPage->xCellSize(pPage, &data[pc]); + btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); + } + } + /* Add the freeblocks to the min-heap + ** + ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header + ** is the offset of the first freeblock, or zero if there are no + ** freeblocks on the page. + */ + i = get2byte(&data[hdr+1]); + while( i>0 ){ + int size, j; + assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ + size = get2byte(&data[i+2]); + assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */ + btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1)); + /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a + ** big-endian integer which is the offset in the b-tree page of the next + ** freeblock in the chain, or zero if the freeblock is the last on the + ** chain. */ + j = get2byte(&data[i]); + /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of + ** increasing offset. */ + assert( j==0 || j>i+size ); /* Enforced by btreeComputeFreeSpace() */ + assert( (u32)j<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ + i = j; + } + /* Analyze the min-heap looking for overlap between cells and/or + ** freeblocks, and counting the number of untracked bytes in nFrag. + ** + ** Each min-heap entry is of the form: (start_address<<16)|end_address. + ** There is an implied first entry the covers the page header, the cell + ** pointer index, and the gap between the cell pointer index and the start + ** of cell content. + ** + ** The loop below pulls entries from the min-heap in order and compares + ** the start_address against the previous end_address. If there is an + ** overlap, that means bytes are used multiple times. If there is a gap, + ** that gap is added to the fragmentation count. + */ + nFrag = 0; + prev = contentOffset - 1; /* Implied first min-heap entry */ + while( btreeHeapPull(heap,&x) ){ + if( (prev&0xffff)>=(x>>16) ){ + checkAppendMsg(pCheck, + "Multiple uses for byte %u of page %u", x>>16, iPage); + break; + }else{ + nFrag += (x>>16) - (prev&0xffff) - 1; + prev = x; + } + } + nFrag += usableSize - (prev&0xffff) - 1; + /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments + ** is stored in the fifth field of the b-tree page header. + ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the + ** number of fragmented free bytes within the cell content area. + */ + if( heap[0]==0 && nFrag!=data[hdr+7] ){ + checkAppendMsg(pCheck, + "Fragmentation of %u bytes reported as %u on page %u", + nFrag, data[hdr+7], iPage); + } + } + +end_of_check: + if( !doCoverageCheck ) pPage->isInit = savedIsInit; + releasePage(pPage); + pCheck->zPfx = saved_zPfx; + pCheck->v1 = saved_v1; + pCheck->v2 = saved_v2; + return depth+1; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** This routine does a complete check of the given BTree file. aRoot[] is +** an array of pages numbers were each page number is the root page of +** a table. nRoot is the number of entries in aRoot. +** +** A read-only or read-write transaction must be opened before calling +** this function. +** +** Write the number of error seen in *pnErr. Except for some memory +** allocation errors, an error message held in memory obtained from +** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is +** returned. If a memory allocation error occurs, NULL is returned. +** +** If the first entry in aRoot[] is 0, that indicates that the list of +** root pages is incomplete. This is a "partial integrity-check". This +** happens when performing an integrity check on a single table. The +** zero is skipped, of course. But in addition, the freelist checks +** and the checks to make sure every page is referenced are also skipped, +** since obviously it is not possible to know which pages are covered by +** the unverified btrees. Except, if aRoot[1] is 1, then the freelist +** checks are still performed. +*/ +SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( + sqlite3 *db, /* Database connection that is running the check */ + Btree *p, /* The btree to be checked */ + Pgno *aRoot, /* An array of root pages numbers for individual trees */ + int nRoot, /* Number of entries in aRoot[] */ + int mxErr, /* Stop reporting errors after this many */ + int *pnErr, /* OUT: Write number of errors seen to this variable */ + char **pzOut /* OUT: Write the error message string here */ +){ + Pgno i; + IntegrityCk sCheck; + BtShared *pBt = p->pBt; + u64 savedDbFlags = pBt->db->flags; + char zErr[100]; + int bPartial = 0; /* True if not checking all btrees */ + int bCkFreelist = 1; /* True to scan the freelist */ + VVA_ONLY( int nRef ); + assert( nRoot>0 ); + + /* aRoot[0]==0 means this is a partial check */ + if( aRoot[0]==0 ){ + assert( nRoot>1 ); + bPartial = 1; + if( aRoot[1]!=1 ) bCkFreelist = 0; + } + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); + VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); + assert( nRef>=0 ); + memset(&sCheck, 0, sizeof(sCheck)); + sCheck.db = db; + sCheck.pBt = pBt; + sCheck.pPager = pBt->pPager; + sCheck.nCkPage = btreePagecount(sCheck.pBt); + sCheck.mxErr = mxErr; + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); + sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; + if( sCheck.nCkPage==0 ){ + goto integrity_ck_cleanup; + } + + sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); + if( !sCheck.aPgRef ){ + checkOom(&sCheck); + goto integrity_ck_cleanup; + } + sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); + if( sCheck.heap==0 ){ + checkOom(&sCheck); + goto integrity_ck_cleanup; + } + + i = PENDING_BYTE_PAGE(pBt); + if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i); + + /* Check the integrity of the freelist + */ + if( bCkFreelist ){ + sCheck.zPfx = "Freelist: "; + checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), + get4byte(&pBt->pPage1->aData[36])); + sCheck.zPfx = 0; + } + + /* Check all the tables. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( !bPartial ){ + if( pBt->autoVacuum ){ + Pgno mx = 0; + Pgno mxInHdr; + for(i=0; (int)ipPage1->aData[52]); + if( mx!=mxInHdr ){ + checkAppendMsg(&sCheck, + "max rootpage (%u) disagrees with header (%u)", + mx, mxInHdr + ); + } + }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){ + checkAppendMsg(&sCheck, + "incremental_vacuum enabled with a max rootpage of zero" + ); + } + } +#endif + testcase( pBt->db->flags & SQLITE_CellSizeCk ); + pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; + for(i=0; (int)iautoVacuum && aRoot[i]>1 && !bPartial ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); + } +#endif + sCheck.v0 = aRoot[i]; + checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); + } + pBt->db->flags = savedDbFlags; + + /* Make sure every page in the file is referenced + */ + if( !bPartial ){ + for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( getPageReferenced(&sCheck, i)==0 ){ + checkAppendMsg(&sCheck, "Page %u: never used", i); + } +#else + /* If the database supports auto-vacuum, make sure no tables contain + ** references to pointer-map pages. + */ + if( getPageReferenced(&sCheck, i)==0 && + (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Page %u: never used", i); + } + if( getPageReferenced(&sCheck, i)!=0 && + (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i); + } +#endif + } + } + + /* Clean up and report errors. + */ +integrity_ck_cleanup: + sqlite3PageFree(sCheck.heap); + sqlite3_free(sCheck.aPgRef); + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ){ + sqlite3_str_reset(&sCheck.errMsg); + *pzOut = 0; + }else{ + *pzOut = sqlite3StrAccumFinish(&sCheck.errMsg); + } + /* Make sure this analysis did not leave any unref() pages. */ + assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); + sqlite3BtreeLeave(p); + return sCheck.rc; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** Return the full pathname of the underlying database file. Return +** an empty string if the database is in-memory or a TEMP database. +** +** The pager filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerFilename(p->pBt->pPager, 1); +} + +/* +** Return the pathname of the journal file for this database. The return +** value of this routine is the same regardless of whether the journal file +** has been created or not. +** +** The pager journal filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerJournalname(p->pBt->pPager); +} + +/* +** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE +** to describe the current transaction state of Btree p. +*/ +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree *p){ + assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); + return p ? p->inTrans : 0; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on the Btree passed as the first argument. +** +** Return SQLITE_LOCKED if this or any other connection has an open +** transaction on the shared-cache the argument Btree is connected to. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( p ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( pBt->inTransaction!=TRANS_NONE ){ + rc = SQLITE_LOCKED; + }else{ + rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +/* +** Return true if there is currently a backup running on Btree p. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->nBackup!=0; +} + +/* +** This function returns a pointer to a blob of memory associated with +** a single shared-btree. The memory is used by client code for its own +** purposes (for example, to store a high-level schema associated with +** the shared-btree). The btree layer manages reference counting issues. +** +** The first time this is called on a shared-btree, nBytes bytes of memory +** are allocated, zeroed, and returned to the caller. For each subsequent +** call the nBytes parameter is ignored and a pointer to the same blob +** of memory returned. +** +** If the nBytes parameter is 0 and the blob of memory has not yet been +** allocated, a null pointer is returned. If the blob has already been +** allocated, it is returned as normal. +** +** Just before the shared-btree is closed, the function passed as the +** xFree argument when the memory allocation was made is invoked on the +** blob of allocated memory. The xFree function should not call sqlite3_free() +** on the memory, the btree layer does that. +*/ +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( !pBt->pSchema && nBytes ){ + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); + pBt->xFreeSchema = xFree; + } + sqlite3BtreeLeave(p); + return pBt->pSchema; +} + +/* +** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared +** btree as the argument handle holds an exclusive lock on the +** sqlite_schema table. Otherwise SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ + int rc; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); + assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); + sqlite3BtreeLeave(p); + return rc; +} + + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Obtain a lock on the table whose root page is iTab. The +** lock is a write lock if isWritelock is true or a read lock +** if it is false. +*/ +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ + int rc = SQLITE_OK; + assert( p->inTrans!=TRANS_NONE ); + if( p->sharable ){ + u8 lockType = READ_LOCK + isWriteLock; + assert( READ_LOCK+1==WRITE_LOCK ); + assert( isWriteLock==0 || isWriteLock==1 ); + + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, iTab, lockType); + if( rc==SQLITE_OK ){ + rc = setSharedCacheTableLock(p, iTab, lockType); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Argument pCsr must be a cursor opened for writing on an +** INTKEY table currently pointing at a valid table entry. +** This function modifies the data stored as part of that entry. +** +** Only the data content may only be modified, it is not possible to +** change the length of the data stored. If this function is called with +** parameters that attempt to write past the end of the existing data, +** no modifications are made and SQLITE_CORRUPT is returned. +*/ +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ + int rc; + assert( cursorOwnsBtShared(pCsr) ); + assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); + assert( pCsr->curFlags & BTCF_Incrblob ); + + rc = restoreCursorPosition(pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pCsr->eState!=CURSOR_REQUIRESEEK ); + if( pCsr->eState!=CURSOR_VALID ){ + return SQLITE_ABORT; + } + + /* Save the positions of all other cursors open on this table. This is + ** required in case any of them are holding references to an xFetch + ** version of the b-tree page modified by the accessPayload call below. + ** + ** Note that pCsr must be open on a INTKEY table and saveCursorPosition() + ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence + ** saveAllCursors can only return SQLITE_OK. + */ + VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); + assert( rc==SQLITE_OK ); + + /* Check some assumptions: + ** (a) the cursor is open for writing, + ** (b) there is a read/write transaction open, + ** (c) the connection holds a write-lock on the table (if required), + ** (d) there are no conflicting read-locks, and + ** (e) the cursor points at a valid row of an intKey table. + */ + if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ + return SQLITE_READONLY; + } + assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 + && pCsr->pBt->inTransaction==TRANS_WRITE ); + assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); + assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); + assert( pCsr->pPage->intKey ); + + return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); +} + +/* +** Mark this cursor as an incremental blob cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ + pCur->curFlags |= BTCF_Incrblob; + pCur->pBtree->hasIncrblobCur = 1; +} +#endif + +/* +** Set both the "read version" (single byte at byte offset 18) and +** "write version" (single byte at byte offset 19) fields in the database +** header to iVersion. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ + BtShared *pBt = pBtree->pBt; + int rc; /* Return code */ + + assert( iVersion==1 || iVersion==2 ); + + /* If setting the version fields to 1, do not automatically open the + ** WAL connection, even if the version fields are currently set to 2. + */ + pBt->btsFlags &= ~BTS_NO_WAL; + if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; + + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); + if( rc==SQLITE_OK ){ + u8 *aData = pBt->pPage1->aData; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } + } + + pBt->btsFlags &= ~BTS_NO_WAL; + return rc; +} + +/* +** Return true if the cursor has a hint specified. This routine is +** only used from within assert() statements +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ + return (pCsr->hints & mask)!=0; +} + +/* +** Return true if the given Btree is read-only. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ + return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; +} + +/* +** Return the size of the header added to each page by this module. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } + +/* +** If no transaction is active and the database is not a temp-db, clear +** the in-memory pager cache. +*/ +SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->inTransaction==TRANS_NONE ){ + sqlite3PagerClearCache(pBt->pPager); + } +} + +#if !defined(SQLITE_OMIT_SHARED_CACHE) +/* +** Return true if the Btree passed as the only argument is sharable. +*/ +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ + return p->sharable; +} + +/* +** Return the number of connections to the BtShared object accessed by +** the Btree handle passed as the only argument. For private caches +** this is always 1. For shared caches it may be 1 or greater. +*/ +SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ + testcase( p->sharable ); + return p->pBt->nRef; +} +#endif + +/************** End of btree.c ***********************************************/ +/************** Begin file backup.c ******************************************/ +/* +** 2009 January 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the implementation of the sqlite3_backup_XXX() +** API functions and the related features. +*/ +/* #include "sqliteInt.h" */ +/* #include "btreeInt.h" */ + +/* +** Structure allocated for each backup operation. +*/ +struct sqlite3_backup { + sqlite3* pDestDb; /* Destination database handle */ + Btree *pDest; /* Destination b-tree file */ + u32 iDestSchema; /* Original schema cookie in destination */ + int bDestLocked; /* True once a write-transaction is open on pDest */ + + Pgno iNext; /* Page number of the next source page to copy */ + sqlite3* pSrcDb; /* Source database handle */ + Btree *pSrc; /* Source b-tree file */ + + int rc; /* Backup process error code */ + + /* These two variables are set by every call to backup_step(). They are + ** read by calls to backup_remaining() and backup_pagecount(). + */ + Pgno nRemaining; /* Number of pages left to copy */ + Pgno nPagecount; /* Total number of pages to copy */ + + int isAttached; /* True once backup has been registered with pager */ + sqlite3_backup *pNext; /* Next backup associated with source pager */ +}; + +/* +** THREAD SAFETY NOTES: +** +** Once it has been created using backup_init(), a single sqlite3_backup +** structure may be accessed via two groups of thread-safe entry points: +** +** * Via the sqlite3_backup_XXX() API function backup_step() and +** backup_finish(). Both these functions obtain the source database +** handle mutex and the mutex associated with the source BtShared +** structure, in that order. +** +** * Via the BackupUpdate() and BackupRestart() functions, which are +** invoked by the pager layer to report various state changes in +** the page cache associated with the source database. The mutex +** associated with the source database BtShared structure will always +** be held when either of these functions are invoked. +** +** The other sqlite3_backup_XXX() API functions, backup_remaining() and +** backup_pagecount() are not thread-safe functions. If they are called +** while some other thread is calling backup_step() or backup_finish(), +** the values returned may be invalid. There is no way for a call to +** BackupUpdate() or BackupRestart() to interfere with backup_remaining() +** or backup_pagecount(). +** +** Depending on the SQLite configuration, the database handles and/or +** the Btree objects may have their own mutexes that require locking. +** Non-sharable Btrees (in-memory databases for example), do not have +** associated mutexes. +*/ + +/* +** Return a pointer corresponding to database zDb (i.e. "main", "temp") +** in connection handle pDb. If such a database cannot be found, return +** a NULL pointer and write an error message to pErrorDb. +** +** If the "temp" database is requested, it may need to be opened by this +** function. If an error occurs while doing so, return 0 and write an +** error message to pErrorDb. +*/ +static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ + int i = sqlite3FindDbName(pDb, zDb); + + if( i==1 ){ + Parse sParse; + int rc = 0; + sqlite3ParseObjectInit(&sParse,pDb); + if( sqlite3OpenTempDatabase(&sParse) ){ + sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); + rc = SQLITE_ERROR; + } + sqlite3DbFree(pErrorDb, sParse.zErrMsg); + sqlite3ParseObjectReset(&sParse); + if( rc ){ + return 0; + } + } + + if( i<0 ){ + sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); + return 0; + } + + return pDb->aDb[i].pBt; +} + +/* +** Attempt to set the page size of the destination to match the page size +** of the source. +*/ +static int setDestPgsz(sqlite3_backup *p){ + int rc; + rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0); + return rc; +} + +/* +** Check that there is no open read-transaction on the b-tree passed as the +** second argument. If there is not, return SQLITE_OK. Otherwise, if there +** is an open read-transaction, return SQLITE_ERROR and leave an error +** message in database handle db. +*/ +static int checkReadTransaction(sqlite3 *db, Btree *p){ + if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + +/* +** Create an sqlite3_backup process to copy the contents of zSrcDb from +** connection handle pSrcDb to zDestDb in pDestDb. If successful, return +** a pointer to the new sqlite3_backup object. +** +** If an error occurs, NULL is returned and an error code and error message +** stored in database handle pDestDb. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3* pDestDb, /* Database to write to */ + const char *zDestDb, /* Name of database within pDestDb */ + sqlite3* pSrcDb, /* Database connection to read from */ + const char *zSrcDb /* Name of database within pSrcDb */ +){ + sqlite3_backup *p; /* Value to return */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + /* Lock the source database handle. The destination database + ** handle is not locked in this routine, but it is locked in + ** sqlite3_backup_step(). The user is required to ensure that no + ** other thread accesses the destination handle for the duration + ** of the backup operation. Any attempt to use the destination + ** database connection while a backup is in progress may cause + ** a malfunction or a deadlock. + */ + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3_mutex_enter(pDestDb->mutex); + + if( pSrcDb==pDestDb ){ + sqlite3ErrorWithMsg( + pDestDb, SQLITE_ERROR, "source and destination must be distinct" + ); + p = 0; + }else { + /* Allocate space for a new sqlite3_backup object... + ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); + if( !p ){ + sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); + } + } + + /* If the allocation succeeded, populate the new object. */ + if( p ){ + p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); + p->pDest = findBtree(pDestDb, pDestDb, zDestDb); + p->pDestDb = pDestDb; + p->pSrcDb = pSrcDb; + p->iNext = 1; + p->isAttached = 0; + + if( 0==p->pSrc || 0==p->pDest + || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK + ){ + /* One (or both) of the named databases did not exist or an OOM + ** error was hit. Or there is a transaction open on the destination + ** database. The error has already been written into the pDestDb + ** handle. All that is left to do here is free the sqlite3_backup + ** structure. */ + sqlite3_free(p); + p = 0; + } + } + if( p ){ + p->pSrc->nBackup++; + } + + sqlite3_mutex_leave(pDestDb->mutex); + sqlite3_mutex_leave(pSrcDb->mutex); + return p; +} + +/* +** Argument rc is an SQLite error code. Return true if this error is +** considered fatal if encountered during a backup operation. All errors +** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED. +*/ +static int isFatalError(int rc){ + return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED)); +} + +/* +** Parameter zSrcData points to a buffer containing the data for +** page iSrcPg from the source database. Copy this data into the +** destination database. +*/ +static int backupOnePage( + sqlite3_backup *p, /* Backup handle */ + Pgno iSrcPg, /* Source database page to backup */ + const u8 *zSrcData, /* Source database page data */ + int bUpdate /* True for an update, false otherwise */ +){ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); + const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); + int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); + const int nCopy = MIN(nSrcPgsz, nDestPgsz); + const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; + int rc = SQLITE_OK; + i64 iOff; + + assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); + assert( p->bDestLocked ); + assert( !isFatalError(p->rc) ); + assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); + assert( zSrcData ); + assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 ); + + /* This loop runs once for each destination page spanned by the source + ** page. For each iteration, variable iOff is set to the byte offset + ** of the destination page. + */ + for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOffpDest->pBt) ) continue; + if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0)) + && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) + ){ + const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; + u8 *zDestData = sqlite3PagerGetData(pDestPg); + u8 *zOut = &zDestData[iOff%nDestPgsz]; + + /* Copy the data from the source page into the destination page. + ** Then clear the Btree layer MemPage.isInit flag. Both this module + ** and the pager code use this trick (clearing the first byte + ** of the page 'extra' space to invalidate the Btree layers + ** cached parse of the page). MemPage.isInit is marked + ** "MUST BE FIRST" for this purpose. + */ + memcpy(zOut, zIn, nCopy); + ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; + if( iOff==0 && bUpdate==0 ){ + sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc)); + } + } + sqlite3PagerUnref(pDestPg); + } + + return rc; +} + +/* +** If pFile is currently larger than iSize bytes, then truncate it to +** exactly iSize bytes. If pFile is not larger than iSize bytes, then +** this function is a no-op. +** +** Return SQLITE_OK if everything is successful, or an SQLite error +** code if an error occurs. +*/ +static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ + i64 iCurrent; + int rc = sqlite3OsFileSize(pFile, &iCurrent); + if( rc==SQLITE_OK && iCurrent>iSize ){ + rc = sqlite3OsTruncate(pFile, iSize); + } + return rc; +} + +/* +** Register this backup object with the associated source pager for +** callbacks when pages are changed or the cache invalidated. +*/ +static void attachBackupObject(sqlite3_backup *p){ + sqlite3_backup **pp; + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + p->pNext = *pp; + *pp = p; + p->isAttached = 1; +} + +/* +** Copy nPage pages from the source b-tree to the destination. +*/ +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + int rc; + int destMode; /* Destination journal mode */ + int pgszSrc = 0; /* Source page size */ + int pgszDest = 0; /* Destination page size */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(p->pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + rc = p->rc; + if( !isFatalError(rc) ){ + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ + int ii; /* Iterator variable */ + int nSrcPage = -1; /* Size of source db in pages */ + int bCloseTrans = 0; /* True if src db requires unlocking */ + + /* If the source pager is currently in a write-transaction, return + ** SQLITE_BUSY immediately. + */ + if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){ + rc = SQLITE_BUSY; + }else{ + rc = SQLITE_OK; + } + + /* If there is no open read-transaction on the source database, open + ** one now. If a transaction is opened here, then it will be closed + ** before this function exits. + */ + if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){ + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); + bCloseTrans = 1; + } + + /* If the destination database has not yet been locked (i.e. if this + ** is the first call to backup_step() for the current backup operation), + ** try to set its page size to the same as the source database. This + ** is especially important on ZipVFS systems, as in that case it is + ** not possible to create a database file that uses one page size by + ** writing to it with another. */ + if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){ + rc = SQLITE_NOMEM; + } + + /* Lock the destination database, if it is not locked already. */ + if( SQLITE_OK==rc && p->bDestLocked==0 + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, + (int*)&p->iDestSchema)) + ){ + p->bDestLocked = 1; + } + + /* Do not allow backup if the destination database is in WAL mode + ** and the page sizes are different between source and destination */ + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); + if( SQLITE_OK==rc + && (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) + && pgszSrc!=pgszDest + ){ + rc = SQLITE_READONLY; + } + + /* Now that there is a read-lock on the source database, query the + ** source pager for the number of pages in the database. + */ + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); + assert( nSrcPage>=0 ); + for(ii=0; (nPage<0 || iiiNext<=(Pgno)nSrcPage && !rc; ii++){ + const Pgno iSrcPg = p->iNext; /* Source page number */ + if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ + DbPage *pSrcPg; /* Source page object */ + rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); + sqlite3PagerUnref(pSrcPg); + } + } + p->iNext++; + } + if( rc==SQLITE_OK ){ + p->nPagecount = nSrcPage; + p->nRemaining = nSrcPage+1-p->iNext; + if( p->iNext>(Pgno)nSrcPage ){ + rc = SQLITE_DONE; + }else if( !p->isAttached ){ + attachBackupObject(p); + } + } + + /* Update the schema version field in the destination database. This + ** is to make sure that the schema-version really does change in + ** the case where the source and destination databases have the + ** same schema version. + */ + if( rc==SQLITE_DONE ){ + if( nSrcPage==0 ){ + rc = sqlite3BtreeNewDb(p->pDest); + nSrcPage = 1; + } + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); + } + if( rc==SQLITE_OK ){ + if( p->pDestDb ){ + sqlite3ResetAllSchemasOfConnection(p->pDestDb); + } + if( destMode==PAGER_JOURNALMODE_WAL ){ + rc = sqlite3BtreeSetVersion(p->pDest, 2); + } + } + if( rc==SQLITE_OK ){ + int nDestTruncate; + /* Set nDestTruncate to the final number of pages in the destination + ** database. The complication here is that the destination page + ** size may be different to the source page size. + ** + ** If the source page size is smaller than the destination page size, + ** round up. In this case the call to sqlite3OsTruncate() below will + ** fix the size of the file. However it is important to call + ** sqlite3PagerTruncateImage() here so that any pages in the + ** destination file that lie beyond the nDestTruncate page mark are + ** journalled by PagerCommitPhaseOne() before they are destroyed + ** by the file truncation. + */ + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); + if( pgszSrcpDest->pBt) ){ + nDestTruncate--; + } + }else{ + nDestTruncate = nSrcPage * (pgszSrc/pgszDest); + } + assert( nDestTruncate>0 ); + + if( pgszSrc= iSize || ( + nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) + && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest + )); + + /* This block ensures that all data required to recreate the original + ** database has been stored in the journal for pDestPager and the + ** journal synced to disk. So at this point we may safely modify + ** the database file in any way, knowing that if a power failure + ** occurs, the original database will be reconstructed from the + ** journal file. */ + sqlite3PagerPagecount(pDestPager, &nDstPage); + for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){ + if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){ + DbPage *pPg; + rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg); + sqlite3PagerUnref(pPg); + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); + } + + /* Write the extra pages and truncate the database file as required */ + iEnd = MIN(PENDING_BYTE + pgszDest, iSize); + for( + iOff=PENDING_BYTE+pgszSrc; + rc==SQLITE_OK && iOffpDest, 0)) + ){ + rc = SQLITE_DONE; + } + } + } + + /* If bCloseTrans is true, then this function opened a read transaction + ** on the source database. Close the read transaction here. There is + ** no need to check the return values of the btree methods here, as + ** "committing" a read-only transaction cannot fail. + */ + if( bCloseTrans ){ + TESTONLY( int rc2 ); + TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); + assert( rc2==SQLITE_OK ); + } + + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM_BKPT; + } + p->rc = rc; + } + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } + sqlite3BtreeLeave(p->pSrc); + sqlite3_mutex_leave(p->pSrcDb->mutex); + return rc; +} + +/* +** Release all resources associated with an sqlite3_backup* handle. +*/ +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ + sqlite3_backup **pp; /* Ptr to head of pagers backup list */ + sqlite3 *pSrcDb; /* Source database connection */ + int rc; /* Value to return */ + + /* Enter the mutexes */ + if( p==0 ) return SQLITE_OK; + pSrcDb = p->pSrcDb; + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + /* Detach this backup from the source pager. */ + if( p->pDestDb ){ + p->pSrc->nBackup--; + } + if( p->isAttached ){ + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + assert( pp!=0 ); + while( *pp!=p ){ + pp = &(*pp)->pNext; + assert( pp!=0 ); + } + *pp = p->pNext; + } + + /* If a transaction is still open on the Btree, roll it back. */ + sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); + + /* Set the error code of the destination database handle. */ + rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; + if( p->pDestDb ){ + sqlite3Error(p->pDestDb, rc); + + /* Exit the mutexes and free the backup context structure. */ + sqlite3LeaveMutexAndCloseZombie(p->pDestDb); + } + sqlite3BtreeLeave(p->pSrc); + if( p->pDestDb ){ + /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + sqlite3_free(p); + } + sqlite3LeaveMutexAndCloseZombie(pSrcDb); + return rc; +} + +/* +** Return the number of pages still to be backed up as of the most recent +** call to sqlite3_backup_step(). +*/ +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return p->nRemaining; +} + +/* +** Return the total number of pages in the source database as of the most +** recent call to sqlite3_backup_step(). +*/ +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return p->nPagecount; +} + +/* +** This function is called after the contents of page iPage of the +** source database have been modified. If page iPage has already been +** copied into the destination database, then the data written to the +** destination is now invalidated. The destination copy of iPage needs +** to be updated with the new data before the backup operation is +** complete. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +static SQLITE_NOINLINE void backupUpdate( + sqlite3_backup *p, + Pgno iPage, + const u8 *aData +){ + assert( p!=0 ); + do{ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + if( !isFatalError(p->rc) && iPageiNext ){ + /* The backup process p has already copied page iPage. But now it + ** has been modified by a transaction on the source pager. Copy + ** the new data into the backup. + */ + int rc; + assert( p->pDestDb ); + sqlite3_mutex_enter(p->pDestDb->mutex); + rc = backupOnePage(p, iPage, aData, 1); + sqlite3_mutex_leave(p->pDestDb->mutex); + assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); + if( rc!=SQLITE_OK ){ + p->rc = rc; + } + } + }while( (p = p->pNext)!=0 ); +} +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ + if( pBackup ) backupUpdate(pBackup, iPage, aData); +} + +/* +** Restart the backup process. This is called when the pager layer +** detects that the database has been modified by an external database +** connection. In this case there is no way of knowing which of the +** pages that have been copied into the destination database are still +** valid and which are not, so the entire process needs to be restarted. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ + sqlite3_backup *p; /* Iterator variable */ + for(p=pBackup; p; p=p->pNext){ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + p->iNext = 1; + } +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Copy the complete content of pBtFrom into pBtTo. A transaction +** must be active for both files. +** +** The size of file pTo may be reduced by this operation. If anything +** goes wrong, the transaction on pTo is rolled back. If successful, the +** transaction is committed before returning. +*/ +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ + int rc; + sqlite3_file *pFd; /* File descriptor for database pTo */ + sqlite3_backup b; + sqlite3BtreeEnter(pTo); + sqlite3BtreeEnter(pFrom); + + assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); + if( pFd->pMethods ){ + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc ) goto copy_finished; + } + + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set + ** to 0. This is used by the implementations of sqlite3_backup_step() + ** and sqlite3_backup_finish() to detect that they are being called + ** from this function, not directly by the user. + */ + memset(&b, 0, sizeof(b)); + b.pSrcDb = pFrom->db; + b.pSrc = pFrom; + b.pDest = pTo; + b.iNext = 1; + + /* 0x7FFFFFFF is the hard limit for the number of pages in a database + ** file. By passing this as the number of pages to copy to + ** sqlite3_backup_step(), we can guarantee that the copy finishes + ** within a single call (unless an error occurs). The assert() statement + ** checks this assumption - (p->rc) should be set to either SQLITE_DONE + ** or an error code. */ + sqlite3_backup_step(&b, 0x7FFFFFFF); + assert( b.rc!=SQLITE_OK ); + + rc = sqlite3_backup_finish(&b); + if( rc==SQLITE_OK ){ + pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; + }else{ + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); + } + + assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE ); +copy_finished: + sqlite3BtreeLeave(pFrom); + sqlite3BtreeLeave(pTo); + return rc; +} +#endif /* SQLITE_OMIT_VACUUM */ + +/************** End of backup.c **********************************************/ +/************** Begin file vdbemem.c *****************************************/ +/* +** 2004 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to manipulate "Mem" structure. A "Mem" +** stores a single value in the VDBE. Mem is an opaque structure visible +** only within the VDBE. Interface routines refer to a Mem using the +** name sqlite_value +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* True if X is a power of two. 0 is considered a power of two here. +** In other words, return true if X has at most one bit set. +*/ +#define ISPOWEROF2(X) (((X)&((X)-1))==0) + +#ifdef SQLITE_DEBUG +/* +** Check invariants on a Mem object. +** +** This routine is intended for use inside of assert() statements, like +** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ + /* If MEM_Dyn is set then Mem.xDel!=0. + ** Mem.xDel might not be initialized if MEM_Dyn is clear. + */ + assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); + + /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we + ** ensure that if Mem.szMalloc>0 then it is safe to do + ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. + ** That saves a few cycles in inner loops. */ + assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); + + /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */ + assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) ); + + if( p->flags & MEM_Null ){ + /* Cannot be both MEM_Null and some other type */ + assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); + + /* If MEM_Null is set, then either the value is a pure NULL (the usual + ** case) or it is a pointer set using sqlite3_bind_pointer() or + ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be + ** set. + */ + if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){ + /* This is a pointer type. There may be a flag to indicate what to + ** do with the pointer. */ + assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + + ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 ); + + /* No other bits set */ + assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind + |MEM_Dyn|MEM_Ephem|MEM_Static))==0 ); + }else{ + /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn, + ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */ + } + }else{ + /* The MEM_Cleared bit is only allowed on NULLs */ + assert( (p->flags & MEM_Cleared)==0 ); + } + + /* The szMalloc field holds the correct memory allocation size */ + assert( p->szMalloc==0 + || (p->flags==MEM_Undefined + && p->szMalloc<=sqlite3DbMallocSize(p->db,p->zMalloc)) + || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc)); + + /* If p holds a string or blob, the Mem.z must point to exactly + ** one of the following: + ** + ** (1) Memory in Mem.zMalloc and managed by the Mem object + ** (2) Memory to be freed using Mem.xDel + ** (3) An ephemeral string or blob + ** (4) A static string or blob + */ + if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){ + assert( + ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) + + ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + + ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 + ); + } + return 1; +} +#endif + +/* +** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal +** into a buffer. +*/ +static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ + StrAccum acc; + assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) ); + assert( sz>22 ); + if( p->flags & MEM_Int ){ +#if GCC_VERSION>=7000000 + /* Work-around for GCC bug + ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 */ + i64 x; + assert( (p->flags&MEM_Int)*2==sizeof(x) ); + memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); + p->n = sqlite3Int64ToText(x, zBuf); +#else + p->n = sqlite3Int64ToText(p->u.i, zBuf); +#endif + }else{ + sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); + sqlite3_str_appendf(&acc, "%!.15g", + (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); + assert( acc.zText==zBuf && acc.mxAlloc<=0 ); + zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ + p->n = acc.nChar; + } +} + +#ifdef SQLITE_DEBUG +/* +** Validity checks on pMem. pMem holds a string. +** +** (1) Check that string value of pMem agrees with its integer or real value. +** (2) Check that the string is correctly zero terminated +** +** A single int or real value always converts to the same strings. But +** many different strings can be converted into the same int or real. +** If a table contains a numeric value and an index is based on the +** corresponding string value, then it is important that the string be +** derived from the numeric value, not the other way around, to ensure +** that the index and table are consistent. See ticket +** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for +** an example. +** +** This routine looks at pMem to verify that if it has both a numeric +** representation and a string representation then the string rep has +** been derived from the numeric and not the other way around. It returns +** true if everything is ok and false if there is a problem. +** +** This routine is for use inside of assert() statements only. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ + Mem tmp; + char zBuf[100]; + char *z; + int i, j, incr; + if( (p->flags & MEM_Str)==0 ) return 1; + if( p->db && p->db->mallocFailed ) return 1; + if( p->flags & MEM_Term ){ + /* Insure that the string is properly zero-terminated. Pay particular + ** attention to the case where p->n is odd */ + if( p->szMalloc>0 && p->z==p->zMalloc ){ + assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 ); + assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 ); + } + assert( p->z[p->n]==0 ); + assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 ); + assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); + } + if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; + memcpy(&tmp, p, sizeof(tmp)); + vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); + z = p->z; + i = j = 0; + incr = 1; + if( p->enc!=SQLITE_UTF8 ){ + incr = 2; + if( p->enc==SQLITE_UTF16BE ) z++; + } + while( zBuf[j] ){ + if( zBuf[j++]!=z[i] ) return 0; + i += incr; + } + return 1; +} +#endif /* SQLITE_DEBUG */ + +/* +** If pMem is an object with a valid string representation, this routine +** ensures the internal encoding for the string representation is +** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. +** +** If pMem is not a string object, or the encoding of the string +** representation is already stored using the requested encoding, then this +** routine is a no-op. +** +** SQLITE_OK is returned if the conversion is successful (or not required). +** SQLITE_NOMEM may be returned if a malloc() fails during conversion +** between formats. +*/ +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ +#ifndef SQLITE_OMIT_UTF16 + int rc; +#endif + assert( pMem!=0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE + || desiredEnc==SQLITE_UTF16BE ); + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; + return SQLITE_OK; + } + if( pMem->enc==desiredEnc ){ + return SQLITE_OK; + } + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); +#ifdef SQLITE_OMIT_UTF16 + return SQLITE_ERROR; +#else + + /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, + ** then the encoding of the value may not have changed. + */ + rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); + assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); + assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); + assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); + return rc; +#endif +} + +/* +** Make sure pMem->z points to a writable allocation of at least n bytes. +** +** If the bPreserve argument is true, then copy of the content of +** pMem->z into the new allocation. pMem must be either a string or +** blob if bPreserve is true. If bPreserve is false, any prior content +** in pMem->z is discarded. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ + assert( sqlite3VdbeCheckMemInvariants(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + testcase( pMem->db==0 ); + + /* If the bPreserve flag is set to true, then the memory cell must already + ** contain a valid string or blob value. */ + assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); + testcase( bPreserve && pMem->z==0 ); + + assert( pMem->szMalloc==0 + || (pMem->flags==MEM_Undefined + && pMem->szMalloc<=sqlite3DbMallocSize(pMem->db,pMem->zMalloc)) + || pMem->szMalloc==sqlite3DbMallocSize(pMem->db,pMem->zMalloc)); + if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ + if( pMem->db ){ + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); + }else{ + pMem->zMalloc = sqlite3Realloc(pMem->z, n); + if( pMem->zMalloc==0 ) sqlite3_free(pMem->z); + pMem->z = pMem->zMalloc; + } + bPreserve = 0; + }else{ + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); + } + if( pMem->zMalloc==0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + pMem->szMalloc = 0; + return SQLITE_NOMEM_BKPT; + }else{ + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + } + + if( bPreserve && pMem->z ){ + assert( pMem->z!=pMem->zMalloc ); + memcpy(pMem->zMalloc, pMem->z, pMem->n); + } + if( (pMem->flags&MEM_Dyn)!=0 ){ + assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); + pMem->xDel((void *)(pMem->z)); + } + + pMem->z = pMem->zMalloc; + pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static); + return SQLITE_OK; +} + +/* +** Change the pMem->zMalloc allocation to be at least szNew bytes. +** If pMem->zMalloc already meets or exceeds the requested size, this +** routine is a no-op. +** +** Any prior string or blob content in the pMem object may be discarded. +** The pMem->xDel destructor is called, if it exists. Though MEM_Str +** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal, +** and MEM_Null values are preserved. +** +** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) +** if unable to complete the resizing. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ + assert( CORRUPT_DB || szNew>0 ); + assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); + if( pMem->szMallocflags & MEM_Dyn)==0 ); + pMem->z = pMem->zMalloc; + pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal); + return SQLITE_OK; +} + +/* +** If pMem is already a string, detect if it is a zero-terminated +** string, or make it into one if possible, and mark it as such. +** +** This is an optimization. Correct operation continues even if +** this routine is a no-op. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ + if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){ + /* pMem must be a string, and it cannot be an ephemeral or static string */ + return; + } + if( pMem->enc!=SQLITE_UTF8 ) return; + if( NEVER(pMem->z==0) ) return; + if( pMem->flags & MEM_Dyn ){ + if( pMem->xDel==sqlite3_free + && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) + ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; + return; + } + if( pMem->xDel==sqlite3RCStrUnref ){ + /* Blindly assume that all RCStr objects are zero-terminated */ + pMem->flags |= MEM_Term; + return; + } + }else if( pMem->szMalloc >= pMem->n+1 ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; + return; + } +} + +/* +** It is already known that pMem contains an unterminated string. +** Add the zero terminator. +** +** Three bytes of zero are added. In this way, there is guaranteed +** to be a double-zero byte at an even byte boundary in order to +** terminate a UTF16 string, even if the initial size of the buffer +** is an odd number of bytes. +*/ +static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ + if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){ + return SQLITE_NOMEM_BKPT; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->z[pMem->n+2] = 0; + pMem->flags |= MEM_Term; + return SQLITE_OK; +} + +/* +** Change pMem so that its MEM_Str or MEM_Blob value is stored in +** MEM.zMalloc, where it can be safely written. +** +** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ + if( ExpandBlob(pMem) ) return SQLITE_NOMEM; + if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ + int rc = vdbeMemAddTerminator(pMem); + if( rc ) return rc; + } + } + pMem->flags &= ~MEM_Ephem; +#ifdef SQLITE_DEBUG + pMem->pScopyFrom = 0; +#endif + + return SQLITE_OK; +} + +/* +** If the given Mem* has a zero-filled tail, turn it into an ordinary +** blob stored in dynamically allocated space. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ + int nByte; + assert( pMem!=0 ); + assert( pMem->flags & MEM_Zero ); + assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) ); + testcase( sqlite3_value_nochange(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + + /* Set nByte to the number of bytes required to store the expanded blob. */ + nByte = pMem->n + pMem->u.nZero; + if( nByte<=0 ){ + if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK; + nByte = 1; + } + if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte ); + + memset(&pMem->z[pMem->n], 0, pMem->u.nZero); + pMem->n += pMem->u.nZero; + pMem->flags &= ~(MEM_Zero|MEM_Term); + return SQLITE_OK; +} +#endif + +/* +** Make sure the given Mem is \u0000 terminated. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); + testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); + if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ + return SQLITE_OK; /* Nothing to do */ + }else{ + return vdbeMemAddTerminator(pMem); + } +} + +/* +** Add MEM_Str to the set of representations for the given Mem. This +** routine is only called if pMem is a number of some kind, not a NULL +** or a BLOB. +** +** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated +** if bForce is true but are retained if bForce is false. +** +** A MEM_Null value will never be passed to this function. This function is +** used for converting values to text for returning to the user (i.e. via +** sqlite3_value_text()), or for ensuring that values to be used as btree +** keys are strings. In the former case a NULL pointer is returned the +** user and the latter is an internal programming error. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ + const int nByte = 32; + + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !(pMem->flags&MEM_Zero) ); + assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); + assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + + if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ + pMem->enc = 0; + return SQLITE_NOMEM_BKPT; + } + + vdbeMemRenderNum(nByte, pMem->z, pMem); + assert( pMem->z!=0 ); + assert( pMem->n==(int)sqlite3Strlen30NN(pMem->z) ); + pMem->enc = SQLITE_UTF8; + pMem->flags |= MEM_Str|MEM_Term; + if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + sqlite3VdbeChangeEncoding(pMem, enc); + return SQLITE_OK; +} + +/* +** Memory cell pMem contains the context of an aggregate function. +** This routine calls the finalize method for that function. The +** result of the aggregate is stored back into pMem. +** +** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK +** otherwise. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ + sqlite3_context ctx; + Mem t; + assert( pFunc!=0 ); + assert( pMem!=0 ); + assert( pMem->db!=0 ); + assert( pFunc->xFinalize!=0 ); + assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); + assert( sqlite3_mutex_held(pMem->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + memset(&t, 0, sizeof(t)); + t.flags = MEM_Null; + t.db = pMem->db; + ctx.pOut = &t; + ctx.pMem = pMem; + ctx.pFunc = pFunc; + ctx.enc = ENC(t.db); + pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ + assert( (pMem->flags & MEM_Dyn)==0 ); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + memcpy(pMem, &t, sizeof(t)); + return ctx.isError; +} + +/* +** Memory cell pAccum contains the context of an aggregate function. +** This routine calls the xValue method for that function and stores +** the results in memory cell pMem. +** +** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK +** otherwise. +*/ +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ + sqlite3_context ctx; + assert( pFunc!=0 ); + assert( pFunc->xValue!=0 ); + assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); + assert( pAccum->db!=0 ); + assert( sqlite3_mutex_held(pAccum->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + sqlite3VdbeMemSetNull(pOut); + ctx.pOut = pOut; + ctx.pMem = pAccum; + ctx.pFunc = pFunc; + ctx.enc = ENC(pAccum->db); + pFunc->xValue(&ctx); + return ctx.isError; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** If the memory cell contains a value that must be freed by +** invoking the external callback in Mem.xDel, then this routine +** will free that value. It also sets Mem.flags to MEM_Null. +** +** This is a helper routine for sqlite3VdbeMemSetNull() and +** for sqlite3VdbeMemRelease(). Use those other routines as the +** entry point for releasing Mem resources. +*/ +static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ + assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); + assert( VdbeMemDynamic(p) ); + if( p->flags&MEM_Agg ){ + sqlite3VdbeMemFinalize(p, p->u.pDef); + assert( (p->flags & MEM_Agg)==0 ); + testcase( p->flags & MEM_Dyn ); + } + if( p->flags&MEM_Dyn ){ + assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); + p->xDel((void *)p->z); + } + p->flags = MEM_Null; +} + +/* +** Release memory held by the Mem p, both external memory cleared +** by p->xDel and memory in p->zMalloc. +** +** This is a helper routine invoked by sqlite3VdbeMemRelease() in +** the unusual case where there really is memory in p that needs +** to be freed. +*/ +static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ + if( VdbeMemDynamic(p) ){ + vdbeMemClearExternAndSetNull(p); + } + if( p->szMalloc ){ + sqlite3DbFreeNN(p->db, p->zMalloc); + p->szMalloc = 0; + } + p->z = 0; +} + +/* +** Release any memory resources held by the Mem. Both the memory that is +** free by Mem.xDel and the Mem.zMalloc allocation are freed. +** +** Use this routine prior to clean up prior to abandoning a Mem, or to +** reset a Mem back to its minimum memory utilization. +** +** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space +** prior to inserting new content into the Mem. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ + assert( sqlite3VdbeCheckMemInvariants(p) ); + if( VdbeMemDynamic(p) || p->szMalloc ){ + vdbeMemClear(p); + } +} + +/* Like sqlite3VdbeMemRelease() but faster for cases where we +** know in advance that the Mem is not MEM_Dyn or MEM_Agg. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){ + assert( !VdbeMemDynamic(p) ); + if( p->szMalloc ) vdbeMemClear(p); +} + +/* +** Return some kind of integer value which is the best we can do +** at representing the value that *pMem describes as an integer. +** If pMem is an integer, then the value is exact. If pMem is +** a floating-point then the value returned is the integer part. +** If pMem is a string or blob, then we make an attempt to convert +** it into an integer and return that. If pMem represents an +** an SQL-NULL value, return 0. +** +** If pMem represents a string value, its encoding might be changed. +*/ +static SQLITE_NOINLINE i64 memIntValue(const Mem *pMem){ + i64 value = 0; + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); + return value; +} +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ + int flags; + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + flags = pMem->flags; + if( flags & (MEM_Int|MEM_IntReal) ){ + testcase( flags & MEM_IntReal ); + return pMem->u.i; + }else if( flags & MEM_Real ){ + return sqlite3RealToI64(pMem->u.r); + }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ + return memIntValue(pMem); + }else{ + return 0; + } +} + +/* +** Return the best representation of pMem that we can get into a +** double. If pMem is already a double or an integer, return its +** value. If it is a string or blob, try to convert it to a double. +** If it is a NULL, return 0.0. +*/ +static SQLITE_NOINLINE double memRealValue(Mem *pMem){ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + double val = (double)0; + sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); + return val; +} +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + if( pMem->flags & MEM_Real ){ + return pMem->u.r; + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_IntReal ); + return (double)pMem->u.i; + }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ + return memRealValue(pMem); + }else{ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + return (double)0; + } +} + +/* +** Return 1 if pMem represents true, and return 0 if pMem represents false. +** Return the value ifNull if pMem is NULL. +*/ +SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ + testcase( pMem->flags & MEM_IntReal ); + if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0; + if( pMem->flags & MEM_Null ) return ifNull; + return sqlite3VdbeRealValue(pMem)!=0.0; +} + +/* +** The MEM structure is already a MEM_Real or MEM_IntReal. Try to +** make it a MEM_Int if we can. +*/ +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->flags & (MEM_Real|MEM_IntReal) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + if( pMem->flags & MEM_IntReal ){ + MemSetTypeFlag(pMem, MEM_Int); + }else{ + i64 ix = sqlite3RealToI64(pMem->u.r); + + /* Only mark the value as an integer if + ** + ** (1) the round-trip conversion real->int->real is a no-op, and + ** (2) The integer is neither the largest nor the smallest + ** possible integer (ticket #3922) + ** + ** The second and third terms in the following conditional enforces + ** the second condition under the assumption that addition overflow causes + ** values to wrap around. + */ + if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; + MemSetTypeFlag(pMem, MEM_Int); + } + } +} + +/* +** Convert pMem to type integer. Invalidate any prior representations. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + pMem->u.i = sqlite3VdbeIntValue(pMem); + MemSetTypeFlag(pMem, MEM_Int); + return SQLITE_OK; +} + +/* +** Convert pMem so that it is of type MEM_Real. +** Invalidate any prior representations. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + pMem->u.r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + return SQLITE_OK; +} + +/* Compare a floating point value to an integer. Return true if the two +** values are the same within the precision of the floating point value. +** +** This function assumes that i was obtained by assignment from r1. +** +** For some versions of GCC on 32-bit machines, if you do the more obvious +** comparison of "r1==(double)i" you sometimes get an answer of false even +** though the r1 and (double)i values are bit-for-bit the same. +*/ +SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ + double r2 = (double)i; + return r1==0.0 + || (memcmp(&r1, &r2, sizeof(r1))==0 + && i >= -2251799813685248LL && i < 2251799813685248LL); +} + +/* Convert a floating point value to its closest integer. Do so in +** a way that avoids 'outside the range of representable values' warnings +** from UBSAN. +*/ +SQLITE_PRIVATE i64 sqlite3RealToI64(double r){ + if( r<-9223372036854774784.0 ) return SMALLEST_INT64; + if( r>+9223372036854774784.0 ) return LARGEST_INT64; + return (i64)r; +} + +/* +** Convert pMem so that it has type MEM_Real or MEM_Int. +** Invalidate any prior representations. +** +** Every effort is made to force the conversion, even if the input +** is a string that does not look completely like a number. Convert +** as much of the string as we can and ignore the rest. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ + assert( pMem!=0 ); + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_Real ); + testcase( pMem->flags & MEM_IntReal ); + testcase( pMem->flags & MEM_Null ); + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ + int rc; + sqlite3_int64 ix; + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); + if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) + || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) + ){ + pMem->u.i = ix; + MemSetTypeFlag(pMem, MEM_Int); + }else{ + MemSetTypeFlag(pMem, MEM_Real); + } + } + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 ); + pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); + return SQLITE_OK; +} + +/* +** Cast the datatype of the value in pMem according to the affinity +** "aff". Casting is different from applying affinity in that a cast +** is forced. In other words, the value is converted into the desired +** affinity even if that results in loss of data. This routine is +** used (for example) to implement the SQL "cast()" operator. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ + if( pMem->flags & MEM_Null ) return SQLITE_OK; + switch( aff ){ + case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */ + if( (pMem->flags & MEM_Blob)==0 ){ + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); + if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob); + }else{ + pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); + } + break; + } + case SQLITE_AFF_NUMERIC: { + sqlite3VdbeMemNumerify(pMem); + break; + } + case SQLITE_AFF_INTEGER: { + sqlite3VdbeMemIntegerify(pMem); + break; + } + case SQLITE_AFF_REAL: { + sqlite3VdbeMemRealify(pMem); + break; + } + default: { + int rc; + assert( aff==SQLITE_AFF_TEXT ); + assert( MEM_Str==(MEM_Blob>>3) ); + pMem->flags |= (pMem->flags&MEM_Blob)>>3; + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); + pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); + if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1; + rc = sqlite3VdbeChangeEncoding(pMem, encoding); + if( rc ) return rc; + sqlite3VdbeMemZeroTerminateIfAble(pMem); + } + } + return SQLITE_OK; +} + +/* +** Initialize bulk memory to be a consistent Mem object. +** +** The minimum amount of initialization feasible is performed. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ + assert( (flags & ~MEM_TypeMask)==0 ); + pMem->flags = flags; + pMem->db = db; + pMem->szMalloc = 0; +} + + +/* +** Delete any previous value and set the value stored in *pMem to NULL. +** +** This routine calls the Mem.xDel destructor to dispose of values that +** require the destructor. But it preserves the Mem.zMalloc memory allocation. +** To free all resources, use sqlite3VdbeMemRelease(), which both calls this +** routine to invoke the destructor and deallocates Mem.zMalloc. +** +** Use this routine to reset the Mem prior to insert a new value. +** +** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ + if( VdbeMemDynamic(pMem) ){ + vdbeMemClearExternAndSetNull(pMem); + }else{ + pMem->flags = MEM_Null; + } +} +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){ + sqlite3VdbeMemSetNull((Mem*)p); +} + +/* +** Delete any previous value and set the value to be a BLOB of length +** n containing all zeros. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Blob|MEM_Zero; + pMem->n = 0; + if( n<0 ) n = 0; + pMem->u.nZero = n; + pMem->enc = SQLITE_UTF8; + pMem->z = 0; +} +#else +SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + int nByte = n>0?n:1; + if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte ); + memset(pMem->z, 0, nByte); + pMem->n = n>0?n:0; + pMem->flags = MEM_Blob; + pMem->enc = SQLITE_UTF8; + return SQLITE_OK; +} +#endif + +/* +** The pMem is known to contain content that needs to be destroyed prior +** to a value change. So invoke the destructor, then set the value to +** a 64-bit integer. +*/ +static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ + sqlite3VdbeMemSetNull(pMem); + pMem->u.i = val; + pMem->flags = MEM_Int; +} + +/* +** Delete any previous value and set the value stored in *pMem to val, +** manifest type INTEGER. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ + if( VdbeMemDynamic(pMem) ){ + vdbeReleaseAndSetInt64(pMem, val); + }else{ + pMem->u.i = val; + pMem->flags = MEM_Int; + } +} + +/* A no-op destructor */ +SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } + +/* +** Set the value stored in *pMem should already be a NULL. +** Also store a pointer to go with it. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( + Mem *pMem, + void *pPtr, + const char *zPType, + void (*xDestructor)(void*) +){ + assert( pMem->flags==MEM_Null ); + vdbeMemClear(pMem); + pMem->u.zPType = zPType ? zPType : ""; + pMem->z = pPtr; + pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; + pMem->eSubtype = 'p'; + pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Delete any previous value and set the value stored in *pMem to val, +** manifest type REAL. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ + sqlite3VdbeMemSetNull(pMem); + if( !sqlite3IsNaN(val) ){ + pMem->u.r = val; + pMem->flags = MEM_Real; + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Return true if the Mem holds a RowSet object. This routine is intended +** for use inside of assert() statements. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){ + return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) + && pMem->xDel==sqlite3RowSetDelete; +} +#endif + +/* +** Delete any previous value and set the value of pMem to be an +** empty boolean index. +** +** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation +** error occurs. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){ + sqlite3 *db = pMem->db; + RowSet *p; + assert( db!=0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + sqlite3VdbeMemRelease(pMem); + p = sqlite3RowSetInit(db); + if( p==0 ) return SQLITE_NOMEM; + pMem->z = (char*)p; + pMem->flags = MEM_Blob|MEM_Dyn; + pMem->xDel = sqlite3RowSetDelete; + return SQLITE_OK; +} + +/* +** Return true if the Mem object contains a TEXT or BLOB that is +** too large - whose size exceeds SQLITE_MAX_LENGTH. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ + assert( p->db!=0 ); + if( p->flags & (MEM_Str|MEM_Blob) ){ + int n = p->n; + if( p->flags & MEM_Zero ){ + n += p->u.nZero; + } + return n>p->db->aLimit[SQLITE_LIMIT_LENGTH]; + } + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** This routine prepares a memory cell for modification by breaking +** its link to a shallow copy and by marking any current shallow +** copies of this cell as invalid. +** +** This is used for testing and debugging only - to help ensure that shallow +** copies (created by OP_SCopy) are not misused. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ + int i; + Mem *pX; + for(i=1, pX=pVdbe->aMem+1; inMem; i++, pX++){ + if( pX->pScopyFrom==pMem ){ + u16 mFlags; + if( pVdbe->db->flags & SQLITE_VdbeTrace ){ + sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n", + (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem)); + } + /* If pX is marked as a shallow copy of pMem, then try to verify that + ** no significant changes have been made to pX since the OP_SCopy. + ** A significant change would indicated a missed call to this + ** function for pX. Minor changes, such as adding or removing a + ** dual type, are allowed, as long as the underlying value is the + ** same. */ + mFlags = pMem->flags & pX->flags & pX->mScopyFlags; + assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i ); + + /* pMem is the register that is changing. But also mark pX as + ** undefined so that we can quickly detect the shallow-copy error */ + pX->flags = MEM_Undefined; + pX->pScopyFrom = 0; + } + } + pMem->pScopyFrom = 0; +} +#endif /* SQLITE_DEBUG */ + +/* +** Make an shallow copy of pFrom into pTo. Prior contents of +** pTo are freed. The pFrom->z field is not duplicated. If +** pFrom->z is used, then pTo->z points to the same thing as pFrom->z +** and flags gets srcType (either MEM_Ephem or MEM_Static). +*/ +static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){ + vdbeMemClearExternAndSetNull(pTo); + assert( !VdbeMemDynamic(pTo) ); + sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); +} +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); + assert( pTo->db==pFrom->db ); + if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } + memcpy(pTo, pFrom, MEMCELLSIZE); + if( (pFrom->flags&MEM_Static)==0 ){ + pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); + assert( srcType==MEM_Ephem || srcType==MEM_Static ); + pTo->flags |= srcType; + } +} + +/* +** Make a full copy of pFrom into pTo. Prior contents of pTo are +** freed before the copy is made. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ + int rc = SQLITE_OK; + + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); + memcpy(pTo, pFrom, MEMCELLSIZE); + pTo->flags &= ~MEM_Dyn; + if( pTo->flags&(MEM_Str|MEM_Blob) ){ + if( 0==(pFrom->flags&MEM_Static) ){ + pTo->flags |= MEM_Ephem; + rc = sqlite3VdbeMemMakeWriteable(pTo); + } + } + + return rc; +} + +/* +** Transfer the contents of pFrom to pTo. Any existing value in pTo is +** freed. If pFrom contains ephemeral data, a copy is made. +** +** pFrom contains an SQL NULL when this routine returns. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ + assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); + assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); + assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); + + sqlite3VdbeMemRelease(pTo); + memcpy(pTo, pFrom, sizeof(Mem)); + pFrom->flags = MEM_Null; + pFrom->szMalloc = 0; +} + +/* +** Change the value of a Mem to be a string or a BLOB. +** +** The memory management strategy depends on the value of the xDel +** parameter. If the value passed is SQLITE_TRANSIENT, then the +** string is copied into a (possibly existing) buffer managed by the +** Mem structure. Otherwise, any existing buffer is freed and the +** pointer copied. +** +** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH +** size limit) then no memory allocation occurs. If the string can be +** stored without allocating memory, then it is. If a memory allocation +** is required to store the string, then value of pMem is unchanged. In +** either case, SQLITE_TOOBIG is returned. +** +** The "enc" parameter is the text encoding for the string, or zero +** to store a blob. +** +** If n is negative, then the string consists of all bytes up to but +** excluding the first zero character. The n parameter must be +** non-negative for blobs. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetStr( + Mem *pMem, /* Memory cell to set to string value */ + const char *z, /* String pointer */ + i64 n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + i64 nByte = n; /* New value for pMem->n */ + int iLimit; /* Maximum allowed string or blob size */ + u16 flags; /* New value for pMem->flags */ + + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( enc!=0 || n>=0 ); + + /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ + if( !z ){ + sqlite3VdbeMemSetNull(pMem); + return SQLITE_OK; + } + + if( pMem->db ){ + iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH]; + }else{ + iLimit = SQLITE_MAX_LENGTH; + } + if( nByte<0 ){ + assert( enc!=0 ); + if( enc==SQLITE_UTF8 ){ + nByte = strlen(z); + }else{ + for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} + } + flags= MEM_Str|MEM_Term; + }else if( enc==0 ){ + flags = MEM_Blob; + enc = SQLITE_UTF8; + }else{ + flags = MEM_Str; + } + if( nByte>iLimit ){ + if( xDel && xDel!=SQLITE_TRANSIENT ){ + if( xDel==SQLITE_DYNAMIC ){ + sqlite3DbFree(pMem->db, (void*)z); + }else{ + xDel((void*)z); + } + } + sqlite3VdbeMemSetNull(pMem); + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + } + + /* The following block sets the new values of Mem.z and Mem.xDel. It + ** also sets a flag in local variable "flags" to indicate the memory + ** management (one of MEM_Dyn or MEM_Static). + */ + if( xDel==SQLITE_TRANSIENT ){ + i64 nAlloc = nByte; + if( flags&MEM_Term ){ + nAlloc += (enc==SQLITE_UTF8?1:2); + } + testcase( nAlloc==0 ); + testcase( nAlloc==31 ); + testcase( nAlloc==32 ); + if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ + return SQLITE_NOMEM_BKPT; + } + memcpy(pMem->z, z, nAlloc); + }else{ + sqlite3VdbeMemRelease(pMem); + pMem->z = (char *)z; + if( xDel==SQLITE_DYNAMIC ){ + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + }else{ + pMem->xDel = xDel; + flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); + } + } + + pMem->n = (int)(nByte & 0x7fffffff); + pMem->flags = flags; + pMem->enc = enc; + +#ifndef SQLITE_OMIT_UTF16 + if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ + return SQLITE_NOMEM_BKPT; + } +#endif + + + return SQLITE_OK; +} + +/* +** Move data out of a btree key or data field and into a Mem structure. +** The data is payload from the entry that pCur is currently pointing +** to. offset and amt determine what portion of the data or key to retrieve. +** The result is written into the pMem element. +** +** The pMem object must have been initialized. This routine will use +** pMem->zMalloc to hold the content from the btree, if possible. New +** pMem->zMalloc space will be allocated if necessary. The calling routine +** is responsible for making sure that the pMem object is eventually +** destroyed. +** +** If this routine fails for any reason (malloc returns NULL or unable +** to read from the disk) then the pMem is left in an inconsistent state. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( + BtCursor *pCur, /* Cursor pointing at record to retrieve. */ + u32 offset, /* Offset from the start of data to return bytes from. */ + u32 amt, /* Number of bytes to return. */ + Mem *pMem /* OUT: Return data in this Mem structure. */ +){ + int rc; + pMem->flags = MEM_Null; + if( sqlite3BtreeMaxRecordSize(pCur)z); + if( rc==SQLITE_OK ){ + pMem->z[amt] = 0; /* Overrun area used when reading malformed records */ + pMem->flags = MEM_Blob; + pMem->n = (int)amt; + }else{ + sqlite3VdbeMemRelease(pMem); + } + } + return rc; +} +SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset( + BtCursor *pCur, /* Cursor pointing at record to retrieve. */ + u32 amt, /* Number of bytes to return. */ + Mem *pMem /* OUT: Return data in this Mem structure. */ +){ + u32 available = 0; /* Number of bytes available on the local btree page */ + int rc = SQLITE_OK; /* Return code */ + + assert( sqlite3BtreeCursorIsValid(pCur) ); + assert( !VdbeMemDynamic(pMem) ); + + /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() + ** that both the BtShared and database handle mutexes are held. */ + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + pMem->z = (char *)sqlite3BtreePayloadFetch(pCur, &available); + assert( pMem->z!=0 ); + + if( amt<=available ){ + pMem->flags = MEM_Blob|MEM_Ephem; + pMem->n = (int)amt; + }else{ + rc = sqlite3VdbeMemFromBtree(pCur, 0, amt, pMem); + } + + return rc; +} + +/* +** The pVal argument is known to be a value other than NULL. +** Convert it into a string with encoding enc and return a pointer +** to a zero-terminated version of that string. +*/ +static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ + assert( pVal!=0 ); + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); + assert( (pVal->flags & (MEM_Null))==0 ); + if( pVal->flags & (MEM_Blob|MEM_Str) ){ + if( ExpandBlob(pVal) ) return 0; + pVal->flags |= MEM_Str; + if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ + sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); + } + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ + assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); + if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ + return 0; + } + } + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ + }else{ + sqlite3VdbeMemStringify(pVal, enc, 0); + assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); + } + assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 + || pVal->db->mallocFailed ); + if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ + assert( sqlite3VdbeMemValidStrRep(pVal) ); + return pVal->z; + }else{ + return 0; + } +} + +/* This function is only available internally, it is not part of the +** external API. It works in a similar way to sqlite3_value_text(), +** except the data returned is in the encoding specified by the second +** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or +** SQLITE_UTF8. +** +** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. +** If that is the case, then the result must be aligned on an even byte +** boundary. +*/ +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ + if( !pVal ) return 0; + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); + if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ + assert( sqlite3VdbeMemValidStrRep(pVal) ); + return pVal->z; + } + if( pVal->flags&MEM_Null ){ + return 0; + } + return valueToText(pVal, enc); +} + +/* Return true if sqlit3_value object pVal is a string or blob value +** that uses the destructor specified in the second argument. +** +** TODO: Maybe someday promote this interface into a published API so +** that third-party extensions can get access to it? +*/ +SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){ + if( ALWAYS(pVal!=0) + && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0) + && (pVal->flags & MEM_Dyn)!=0 + && pVal->xDel==xFree + ){ + return 1; + }else{ + return 0; + } +} + +/* +** Create a new sqlite3_value object. +*/ +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){ + Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p ){ + p->flags = MEM_Null; + p->db = db; + } + return p; +} + +/* +** Context object passed by sqlite3Stat4ProbeSetValue() through to +** valueNew(). See comments above valueNew() for details. +*/ +struct ValueNewStat4Ctx { + Parse *pParse; + Index *pIdx; + UnpackedRecord **ppRec; + int iVal; +}; + +/* +** Allocate and return a pointer to a new sqlite3_value object. If +** the second argument to this function is NULL, the object is allocated +** by calling sqlite3ValueNew(). +** +** Otherwise, if the second argument is non-zero, then this function is +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not +** already been allocated, allocate the UnpackedRecord structure that +** that function will return to its caller here. Then return a pointer to +** an sqlite3_value within the UnpackedRecord.a[] array. +*/ +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ +#ifdef SQLITE_ENABLE_STAT4 + if( p ){ + UnpackedRecord *pRec = p->ppRec[0]; + + if( pRec==0 ){ + Index *pIdx = p->pIdx; /* Index being probed */ + int nByte; /* Bytes of space to allocate */ + int i; /* Counter variable */ + int nCol = pIdx->nColumn; /* Number of index columns including rowid */ + + nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); + if( pRec ){ + pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); + if( pRec->pKeyInfo ){ + assert( pRec->pKeyInfo->nAllField==nCol ); + assert( pRec->pKeyInfo->enc==ENC(db) ); + pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); + for(i=0; iaMem[i].flags = MEM_Null; + pRec->aMem[i].db = db; + } + }else{ + sqlite3DbFreeNN(db, pRec); + pRec = 0; + } + } + if( pRec==0 ) return 0; + p->ppRec[0] = pRec; + } + + pRec->nField = p->iVal+1; + sqlite3VdbeMemSetNull(&pRec->aMem[p->iVal]); + return &pRec->aMem[p->iVal]; + } +#else + UNUSED_PARAMETER(p); +#endif /* defined(SQLITE_ENABLE_STAT4) */ + return sqlite3ValueNew(db); +} + +/* +** The expression object indicated by the second argument is guaranteed +** to be a scalar SQL function. If +** +** * all function arguments are SQL literals, +** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and +** * the SQLITE_FUNC_NEEDCOLL function flag is not set, +** +** then this routine attempts to invoke the SQL function. Assuming no +** error occurs, output parameter (*ppVal) is set to point to a value +** object containing the result before returning SQLITE_OK. +** +** Affinity aff is applied to the result of the function before returning. +** If the result is a text value, the sqlite3_value object uses encoding +** enc. +** +** If the conditions above are not met, this function returns SQLITE_OK +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to +** NULL and an SQLite error code returned. +*/ +#ifdef SQLITE_ENABLE_STAT4 +static int valueFromFunction( + sqlite3 *db, /* The database connection */ + const Expr *p, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 aff, /* Affinity to use */ + sqlite3_value **ppVal, /* Write the new value here */ + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ +){ + sqlite3_context ctx; /* Context object for function invocation */ + sqlite3_value **apVal = 0; /* Function arguments */ + int nVal = 0; /* Size of apVal[] array */ + FuncDef *pFunc = 0; /* Function definition */ + sqlite3_value *pVal = 0; /* New value */ + int rc = SQLITE_OK; /* Return code */ + ExprList *pList = 0; /* Function arguments */ + int i; /* Iterator variable */ + + assert( pCtx!=0 ); + assert( (p->flags & EP_TokenOnly)==0 ); + assert( ExprUseXList(p) ); + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; + assert( !ExprHasProperty(p, EP_IntValue) ); + pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pFunc==0 ) return SQLITE_OK; +#endif + assert( pFunc ); + if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 + || (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0 + ){ + return SQLITE_OK; + } + + if( pList ){ + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); + if( apVal==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto value_from_function_out; + } + for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); + if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; + } + } + + pVal = valueNew(db, pCtx); + if( pVal==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto value_from_function_out; + } + + memset(&ctx, 0, sizeof(ctx)); + ctx.pOut = pVal; + ctx.pFunc = pFunc; + ctx.enc = ENC(db); + pFunc->xSFunc(&ctx, nVal, apVal); + if( ctx.isError ){ + rc = ctx.isError; + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + }else{ + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); + assert( rc==SQLITE_OK ); + rc = sqlite3VdbeChangeEncoding(pVal, enc); + if( NEVER(rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal)) ){ + rc = SQLITE_TOOBIG; + pCtx->pParse->nErr++; + } + } + + value_from_function_out: + if( rc!=SQLITE_OK ){ + pVal = 0; + pCtx->pParse->rc = rc; + } + if( apVal ){ + for(i=0; iop)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; + if( op==TK_REGISTER ) op = pExpr->op2; + + /* Compressed expressions only appear when parsing the DEFAULT clause + ** on a table column definition, and hence only when pCtx==0. This + ** check ensures that an EP_TokenOnly expression is never passed down + ** into valueFromFunction(). */ + assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); + + if( op==TK_CAST ){ + u8 aff; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + aff = sqlite3AffinityType(pExpr->u.zToken,0); + rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); + testcase( rc!=SQLITE_OK ); + if( *ppVal ){ +#ifdef SQLITE_ENABLE_STAT4 + rc = ExpandBlob(*ppVal); +#else + /* zero-blobs only come from functions, not literal values. And + ** functions are only processed under STAT4 */ + assert( (ppVal[0][0].flags & MEM_Zero)==0 ); +#endif + sqlite3VdbeMemCast(*ppVal, aff, enc); + sqlite3ValueApplyAffinity(*ppVal, affinity, enc); + } + return rc; + } + + /* Handle negative integers in a single step. This is needed in the + ** case when the value is -9223372036854775808. + */ + if( op==TK_UMINUS + && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ + pExpr = pExpr->pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + + if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ + pVal = valueNew(db, pCtx); + if( pVal==0 ) goto no_mem; + if( ExprHasProperty(pExpr, EP_IntValue) ){ + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); + }else{ + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); + if( zVal==0 ) goto no_mem; + sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + } + if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ + sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + }else{ + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); + } + assert( (pVal->flags & MEM_IntReal)==0 ); + if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){ + testcase( pVal->flags & MEM_Int ); + testcase( pVal->flags & MEM_Real ); + pVal->flags &= ~MEM_Str; + } + if( enc!=SQLITE_UTF8 ){ + rc = sqlite3VdbeChangeEncoding(pVal, enc); + } + }else if( op==TK_UMINUS ) { + /* This branch happens for multiple negative signs. Ex: -(-5) */ + if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) + && pVal!=0 + ){ + sqlite3VdbeMemNumerify(pVal); + if( pVal->flags & MEM_Real ){ + pVal->u.r = -pVal->u.r; + }else if( pVal->u.i==SMALLEST_INT64 ){ +#ifndef SQLITE_OMIT_FLOATING_POINT + pVal->u.r = -(double)SMALLEST_INT64; +#else + pVal->u.r = LARGEST_INT64; +#endif + MemSetTypeFlag(pVal, MEM_Real); + }else{ + pVal->u.i = -pVal->u.i; + } + sqlite3ValueApplyAffinity(pVal, affinity, enc); + } + }else if( op==TK_NULL ){ + pVal = valueNew(db, pCtx); + if( pVal==0 ) goto no_mem; + sqlite3VdbeMemSetNull(pVal); + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + else if( op==TK_BLOB ){ + int nVal; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + pVal = valueNew(db, pCtx); + if( !pVal ) goto no_mem; + zVal = &pExpr->u.zToken[2]; + nVal = sqlite3Strlen30(zVal)-1; + assert( zVal[nVal]=='\'' ); + sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, + 0, SQLITE_DYNAMIC); + } +#endif +#ifdef SQLITE_ENABLE_STAT4 + else if( op==TK_FUNCTION && pCtx!=0 ){ + rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); + } +#endif + else if( op==TK_TRUEFALSE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pVal = valueNew(db, pCtx); + if( pVal ){ + pVal->flags = MEM_Int; + pVal->u.i = pExpr->u.zToken[4]==0; + sqlite3ValueApplyAffinity(pVal, affinity, enc); + } + } + + *ppVal = pVal; + return rc; + +no_mem: +#ifdef SQLITE_ENABLE_STAT4 + if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) ) +#endif + sqlite3OomFault(db); + sqlite3DbFree(db, zVal); + assert( *ppVal==0 ); +#ifdef SQLITE_ENABLE_STAT4 + if( pCtx==0 ) sqlite3ValueFree(pVal); +#else + assert( pCtx==0 ); sqlite3ValueFree(pVal); +#endif + return SQLITE_NOMEM_BKPT; +} + +/* +** Create a new sqlite3_value object, containing the value of pExpr. +** +** This only works for very simple expressions that consist of one constant +** token (i.e. "5", "5.1", "'a string'"). If the expression can +** be converted directly into a value, then the value is allocated and +** a pointer written to *ppVal. The caller is responsible for deallocating +** the value by passing it to sqlite3ValueFree() later on. If the expression +** cannot be converted to a value, then *ppVal is set to NULL. +*/ +SQLITE_PRIVATE int sqlite3ValueFromExpr( + sqlite3 *db, /* The database connection */ + const Expr *pExpr, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 affinity, /* Affinity to use */ + sqlite3_value **ppVal /* Write the new value here */ +){ + return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; +} + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Attempt to extract a value from pExpr and use it to construct *ppVal. +** +** If pAlloc is not NULL, then an UnpackedRecord object is created for +** pAlloc if one does not exist and the new value is added to the +** UnpackedRecord object. +** +** A value is extracted in the following cases: +** +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, +** +** * The expression is a bound variable, and this is a reprepare, or +** +** * The expression is a literal value. +** +** On success, *ppVal is made to point to the extracted value. The caller +** is responsible for ensuring that the value is eventually freed. +*/ +static int stat4ValueFromExpr( + Parse *pParse, /* Parse context */ + Expr *pExpr, /* The expression to extract a value from */ + u8 affinity, /* Affinity to use */ + struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ +){ + int rc = SQLITE_OK; + sqlite3_value *pVal = 0; + sqlite3 *db = pParse->db; + + /* Skip over any TK_COLLATE nodes */ + pExpr = sqlite3ExprSkipCollate(pExpr); + + assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE ); + if( !pExpr ){ + pVal = valueNew(db, pAlloc); + if( pVal ){ + sqlite3VdbeMemSetNull((Mem*)pVal); + } + }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ + Vdbe *v; + int iBindVar = pExpr->iColumn; + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); + if( (v = pParse->pReprepare)!=0 ){ + pVal = valueNew(db, pAlloc); + if( pVal ){ + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); + sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); + pVal->db = pParse->db; + } + } + }else{ + rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc); + } + + assert( pVal==0 || pVal->db==db ); + *ppVal = pVal; + return rc; +} + +/* +** This function is used to allocate and populate UnpackedRecord +** structures intended to be compared against sample index keys stored +** in the sqlite_stat4 table. +** +** A single call to this function populates zero or more fields of the +** record starting with field iVal (fields are numbered from left to +** right starting with 0). A single field is populated if: +** +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, +** +** * The expression is a bound variable, and this is a reprepare, or +** +** * The sqlite3ValueFromExpr() function is able to extract a value +** from the expression (i.e. the expression is a literal value). +** +** Or, if pExpr is a TK_VECTOR, one field is populated for each of the +** vector components that match either of the two latter criteria listed +** above. +** +** Before any value is appended to the record, the affinity of the +** corresponding column within index pIdx is applied to it. Before +** this function returns, output parameter *pnExtract is set to the +** number of values appended to the record. +** +** When this function is called, *ppRec must either point to an object +** allocated by an earlier call to this function, or must be NULL. If it +** is NULL and a value can be successfully extracted, a new UnpackedRecord +** is allocated (and *ppRec set to point to it) before returning. +** +** Unless an error is encountered, SQLITE_OK is returned. It is not an +** error if a value cannot be extracted from pExpr. If an error does +** occur, an SQLite error code is returned. +*/ +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Index being probed */ + UnpackedRecord **ppRec, /* IN/OUT: Probe record */ + Expr *pExpr, /* The expression to extract a value from */ + int nElem, /* Maximum number of values to append */ + int iVal, /* Array element to populate */ + int *pnExtract /* OUT: Values appended to the record */ +){ + int rc = SQLITE_OK; + int nExtract = 0; + + if( pExpr==0 || pExpr->op!=TK_SELECT ){ + int i; + struct ValueNewStat4Ctx alloc; + + alloc.pParse = pParse; + alloc.pIdx = pIdx; + alloc.ppRec = ppRec; + + for(i=0; idb, pIdx, iVal+i); + alloc.iVal = iVal+i; + rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); + if( !pVal ) break; + nExtract++; + } + } + + *pnExtract = nExtract; + return rc; +} + +/* +** Attempt to extract a value from expression pExpr using the methods +** as described for sqlite3Stat4ProbeSetValue() above. +** +** If successful, set *ppVal to point to a new value object and return +** SQLITE_OK. If no value can be extracted, but no other error occurs +** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error +** does occur, return an SQLite error code. The final value of *ppVal +** is undefined in this case. +*/ +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( + Parse *pParse, /* Parse context */ + Expr *pExpr, /* The expression to extract a value from */ + u8 affinity, /* Affinity to use */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ +){ + return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal); +} + +/* +** Extract the iCol-th column from the nRec-byte record in pRec. Write +** the column value into *ppVal. If *ppVal is initially NULL then a new +** sqlite3_value object is allocated. +** +** If *ppVal is initially NULL then the caller is responsible for +** ensuring that the value written into *ppVal is eventually freed. +*/ +SQLITE_PRIVATE int sqlite3Stat4Column( + sqlite3 *db, /* Database handle */ + const void *pRec, /* Pointer to buffer containing record */ + int nRec, /* Size of buffer pRec in bytes */ + int iCol, /* Column to extract */ + sqlite3_value **ppVal /* OUT: Extracted value */ +){ + u32 t = 0; /* a column type code */ + int nHdr; /* Size of the header in the record */ + int iHdr; /* Next unread header byte */ + int iField; /* Next unread data byte */ + int szField = 0; /* Size of the current data field */ + int i; /* Column index */ + u8 *a = (u8*)pRec; /* Typecast byte array */ + Mem *pMem = *ppVal; /* Write result into this Mem object */ + + assert( iCol>0 ); + iHdr = getVarint32(a, nHdr); + if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; + iField = nHdr; + for(i=0; i<=iCol; i++){ + iHdr += getVarint32(&a[iHdr], t); + testcase( iHdr==nHdr ); + testcase( iHdr==nHdr+1 ); + if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT; + szField = sqlite3VdbeSerialTypeLen(t); + iField += szField; + } + testcase( iField==nRec ); + testcase( iField==nRec+1 ); + if( iField>nRec ) return SQLITE_CORRUPT_BKPT; + if( pMem==0 ){ + pMem = *ppVal = sqlite3ValueNew(db); + if( pMem==0 ) return SQLITE_NOMEM_BKPT; + } + sqlite3VdbeSerialGet(&a[iField-szField], t, pMem); + pMem->enc = ENC(db); + return SQLITE_OK; +} + +/* +** Unless it is NULL, the argument must be an UnpackedRecord object returned +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes +** the object. +*/ +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ + if( pRec ){ + int i; + int nCol = pRec->pKeyInfo->nAllField; + Mem *aMem = pRec->aMem; + sqlite3 *db = aMem[0].db; + for(i=0; ipKeyInfo); + sqlite3DbFreeNN(db, pRec); + } +} +#endif /* ifdef SQLITE_ENABLE_STAT4 */ + +/* +** Change the string value of an sqlite3_value object +*/ +SQLITE_PRIVATE void sqlite3ValueSetStr( + sqlite3_value *v, /* Value to be set */ + int n, /* Length of string z */ + const void *z, /* Text of the new string */ + u8 enc, /* Encoding to use */ + void (*xDel)(void*) /* Destructor for the string */ +){ + if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel); +} + +/* +** Free an sqlite3_value object +*/ +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ + if( !v ) return; + sqlite3VdbeMemRelease((Mem *)v); + sqlite3DbFreeNN(((Mem*)v)->db, v); +} + +/* +** The sqlite3ValueBytes() routine returns the number of bytes in the +** sqlite3_value object assuming that it uses the encoding "enc". +** The valueBytes() routine is a helper function. +*/ +static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){ + return valueToText(pVal, enc)!=0 ? pVal->n : 0; +} +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ + Mem *p = (Mem*)pVal; + assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 ); + if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ + return p->n; + } + if( (p->flags & MEM_Str)!=0 && enc!=SQLITE_UTF8 && pVal->enc!=SQLITE_UTF8 ){ + return p->n; + } + if( (p->flags & MEM_Blob)!=0 ){ + if( p->flags & MEM_Zero ){ + return p->n + p->u.nZero; + }else{ + return p->n; + } + } + if( p->flags & MEM_Null ) return 0; + return valueBytes(pVal, enc); +} + +/************** End of vdbemem.c *********************************************/ +/************** Begin file vdbeaux.c *****************************************/ +/* +** 2003 September 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used for creating, destroying, and populating +** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* Forward references */ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef); +static void vdbeFreeOpArray(sqlite3 *, Op *, int); + +/* +** Create a new virtual database engine. +*/ +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ + sqlite3 *db = pParse->db; + Vdbe *p; + p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); + if( p==0 ) return 0; + memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); + p->db = db; + if( db->pVdbe ){ + db->pVdbe->ppVPrev = &p->pVNext; + } + p->pVNext = db->pVdbe; + p->ppVPrev = &db->pVdbe; + db->pVdbe = p; + assert( p->eVdbeState==VDBE_INIT_STATE ); + p->pParse = pParse; + pParse->pVdbe = p; + assert( pParse->aLabel==0 ); + assert( pParse->nLabel==0 ); + assert( p->nOpAlloc==0 ); + assert( pParse->szOpAlloc==0 ); + sqlite3VdbeAddOp2(p, OP_Init, 0, 1); + return p; +} + +/* +** Return the Parse object that owns a Vdbe object. +*/ +SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe *p){ + return p->pParse; +} + +/* +** Change the error string stored in Vdbe.zErrMsg +*/ +SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ + va_list ap; + sqlite3DbFree(p->db, p->zErrMsg); + va_start(ap, zFormat); + p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap); + va_end(ap); +} + +/* +** Remember the SQL string for a prepared statement. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){ + if( p==0 ) return; + p->prepFlags = prepFlags; + if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ + p->expmask = 0; + } + assert( p->zSql==0 ); + p->zSql = sqlite3DbStrNDup(p->db, z, n); +} + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Add a new element to the Vdbe->pDblStr list. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){ + if( p ){ + int n = sqlite3Strlen30(z); + DblquoteStr *pStr = sqlite3DbMallocRawNN(db, + sizeof(*pStr)+n+1-sizeof(pStr->z)); + if( pStr ){ + pStr->pNextStr = p->pDblStr; + p->pDblStr = pStr; + memcpy(pStr->z, z, n+1); + } + } +} +#endif + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** zId of length nId is a double-quoted identifier. Check to see if +** that identifier is really used as a string literal. +*/ +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString( + Vdbe *pVdbe, /* The prepared statement */ + const char *zId /* The double-quoted identifier, already dequoted */ +){ + DblquoteStr *pStr; + assert( zId!=0 ); + if( pVdbe->pDblStr==0 ) return 0; + for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){ + if( strcmp(zId, pStr->z)==0 ) return 1; + } + return 0; +} +#endif + +/* +** Swap byte-code between two VDBE structures. +** +** This happens after pB was previously run and returned +** SQLITE_SCHEMA. The statement was then reprepared in pA. +** This routine transfers the new bytecode in pA over to pB +** so that pB can be run again. The old pB byte code is +** moved back to pA so that it will be cleaned up when pA is +** finalized. +*/ +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ + Vdbe tmp, *pTmp, **ppTmp; + char *zTmp; + assert( pA->db==pB->db ); + tmp = *pA; + *pA = *pB; + *pB = tmp; + pTmp = pA->pVNext; + pA->pVNext = pB->pVNext; + pB->pVNext = pTmp; + ppTmp = pA->ppVPrev; + pA->ppVPrev = pB->ppVPrev; + pB->ppVPrev = ppTmp; + zTmp = pA->zSql; + pA->zSql = pB->zSql; + pB->zSql = zTmp; +#ifdef SQLITE_ENABLE_NORMALIZE + zTmp = pA->zNormSql; + pA->zNormSql = pB->zNormSql; + pB->zNormSql = zTmp; +#endif + pB->expmask = pA->expmask; + pB->prepFlags = pA->prepFlags; + memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter)); + pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++; +} + +/* +** Resize the Vdbe.aOp array so that it is at least nOp elements larger +** than its current size. nOp is guaranteed to be less than or equal +** to 1024/sizeof(Op). +** +** If an out-of-memory error occurs while resizing the array, return +** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain +** unchanged (this is so that any opcodes already allocated can be +** correctly deallocated along with the rest of the Vdbe). +*/ +static int growOpArray(Vdbe *v, int nOp){ + VdbeOp *pNew; + Parse *p = v->pParse; + + /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force + ** more frequent reallocs and hence provide more opportunities for + ** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used + ** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array + ** by the minimum* amount required until the size reaches 512. Normal + ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current + ** size of the op array or add 1KB of space, whichever is smaller. */ +#ifdef SQLITE_TEST_REALLOC_STRESS + sqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(sqlite3_int64)v->nOpAlloc + : (sqlite3_int64)v->nOpAlloc+nOp); +#else + sqlite3_int64 nNew = (v->nOpAlloc ? 2*(sqlite3_int64)v->nOpAlloc + : (sqlite3_int64)(1024/sizeof(Op))); + UNUSED_PARAMETER(nOp); +#endif + + /* Ensure that the size of a VDBE does not grow too large */ + if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){ + sqlite3OomFault(p->db); + return SQLITE_NOMEM; + } + + assert( nOp<=(int)(1024/sizeof(Op)) ); + assert( nNew>=(v->nOpAlloc+nOp) ); + pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); + if( pNew ){ + p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); + v->nOpAlloc = p->szOpAlloc/sizeof(Op); + v->aOp = pNew; + } + return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT); +} + +#ifdef SQLITE_DEBUG +/* This routine is just a convenient place to set a breakpoint that will +** fire after each opcode is inserted and displayed using +** "PRAGMA vdbe_addoptrace=on". Parameters "pc" (program counter) and +** pOp are available to make the breakpoint conditional. +** +** Other useful labels for breakpoints include: +** test_trace_breakpoint(pc,pOp) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) +*/ +static void test_addop_breakpoint(int pc, Op *pOp){ + static u64 n = 0; + (void)pc; + (void)pOp; + n++; + if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ +} +#endif + +/* +** Slow paths for sqlite3VdbeAddOp3() and sqlite3VdbeAddOp4Int() for the +** unusual case when we need to increase the size of the Vdbe.aOp[] array +** before adding the new opcode. +*/ +static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ + assert( p->nOpAlloc<=p->nOp ); + if( growOpArray(p, 1) ) return 1; + assert( p->nOpAlloc>p->nOp ); + return sqlite3VdbeAddOp3(p, op, p1, p2, p3); +} +static SQLITE_NOINLINE int addOp4IntSlow( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + if( p->db->mallocFailed==0 ){ + VdbeOp *pOp = &p->aOp[addr]; + pOp->p4type = P4_INT32; + pOp->p4.i = p4; + } + return addr; +} + + +/* +** Add a new instruction to the list of instructions current in the +** VDBE. Return the address of the new instruction. +** +** Parameters: +** +** p Pointer to the VDBE +** +** op The opcode for this instruction +** +** p1, p2, p3, p4 Operands +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ + return sqlite3VdbeAddOp3(p, op, 0, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ + return sqlite3VdbeAddOp3(p, op, p1, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ + return sqlite3VdbeAddOp3(p, op, p1, p2, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ + int i; + VdbeOp *pOp; + + i = p->nOp; + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( op>=0 && op<0xff ); + if( p->nOpAlloc<=i ){ + return growOp3(p, op, p1, p2, p3); + } + assert( p->aOp!=0 ); + p->nOp++; + pOp = &p->aOp[i]; + assert( pOp!=0 ); + pOp->opcode = (u8)op; + pOp->p5 = 0; + pOp->p1 = p1; + pOp->p2 = p2; + pOp->p3 = p3; + pOp->p4.p = 0; + pOp->p4type = P4_NOTUSED; + + /* Replicate this logic in sqlite3VdbeAddOp4Int() + ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOp->zComment = 0; +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + pOp->nExec = 0; + pOp->nCycle = 0; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + test_addop_breakpoint(i, &p->aOp[i]); + } +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; +#endif + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ** Replicate in sqlite3VdbeAddOp4Int() */ + + return i; +} +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int i; + VdbeOp *pOp; + + i = p->nOp; + if( p->nOpAlloc<=i ){ + return addOp4IntSlow(p, op, p1, p2, p3, p4); + } + p->nOp++; + pOp = &p->aOp[i]; + assert( pOp!=0 ); + pOp->opcode = (u8)op; + pOp->p5 = 0; + pOp->p1 = p1; + pOp->p2 = p2; + pOp->p3 = p3; + pOp->p4.i = p4; + pOp->p4type = P4_INT32; + + /* Replicate this logic in sqlite3VdbeAddOp3() + ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOp->zComment = 0; +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + pOp->nExec = 0; + pOp->nCycle = 0; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + test_addop_breakpoint(i, &p->aOp[i]); + } +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; +#endif + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ** Replicate in sqlite3VdbeAddOp3() */ + + return i; +} + +/* Generate code for an unconditional jump to instruction iDest +*/ +SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){ + return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0); +} + +/* Generate code to cause the string zStr to be loaded into +** register iDest +*/ +SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ + return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); +} + +/* +** Generate code that initializes multiple registers to string or integer +** constants. The registers begin with iDest and increase consecutively. +** One register is initialized for each characgter in zTypes[]. For each +** "s" character in zTypes[], the register is a string if the argument is +** not NULL, or OP_Null if the value is a null pointer. For each "i" character +** in zTypes[], the register is initialized to an integer. +** +** If the input string does not end with "X" then an OP_ResultRow instruction +** is generated for the values inserted. +*/ +SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ + va_list ap; + int i; + char c; + va_start(ap, zTypes); + for(i=0; (c = zTypes[i])!=0; i++){ + if( c=='s' ){ + const char *z = va_arg(ap, const char*); + sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0); + }else if( c=='i' ){ + sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i); + }else{ + goto skip_op_resultrow; + } + } + sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i); +skip_op_resultrow: + va_end(ap); +} + +/* +** Add an opcode that includes the p4 value as a pointer. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + const char *zP4, /* The P4 operand */ + int p4type /* P4 operand type */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + sqlite3VdbeChangeP4(p, addr, zP4, p4type); + return addr; +} + +/* +** Add an OP_Function or OP_PureFunc opcode. +** +** The eCallCtx argument is information (typically taken from Expr.op2) +** that describes the calling context of the function. 0 means a general +** function call. NC_IsCheck means called by a check constraint, +** NC_IdxExpr means called as part of an index expression. NC_PartIdx +** means in the WHERE clause of a partial index. NC_GenCol means called +** while computing a generated column value. 0 is the usual case. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall( + Parse *pParse, /* Parsing context */ + int p1, /* Constant argument mask */ + int p2, /* First argument register */ + int p3, /* Register into which results are written */ + int nArg, /* Number of argument */ + const FuncDef *pFunc, /* The function to be invoked */ + int eCallCtx /* Calling context */ +){ + Vdbe *v = pParse->pVdbe; + int nByte; + int addr; + sqlite3_context *pCtx; + assert( v ); + nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*); + pCtx = sqlite3DbMallocRawNN(pParse->db, nByte); + if( pCtx==0 ){ + assert( pParse->db->mallocFailed ); + freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); + return 0; + } + pCtx->pOut = 0; + pCtx->pFunc = (FuncDef*)pFunc; + pCtx->pVdbe = 0; + pCtx->isError = 0; + pCtx->argc = nArg; + pCtx->iOp = sqlite3VdbeCurrentAddr(v); + addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, + p1, p2, p3, (char*)pCtx, P4_FUNCCTX); + sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); + sqlite3MayAbort(pParse); + return addr; +} + +/* +** Add an opcode that includes the p4 value with a P4_INT64 or +** P4_REAL type. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + const u8 *zP4, /* The P4 operand */ + int p4type /* P4 operand type */ +){ + char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); + if( p4copy ) memcpy(p4copy, zP4, 8); + return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Return the address of the current EXPLAIN QUERY PLAN baseline. +** 0 means "none". +*/ +SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){ + VdbeOp *pOp; + if( pParse->addrExplain==0 ) return 0; + pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain); + return pOp->p2; +} + +/* +** Set a debugger breakpoint on the following routine in order to +** monitor the EXPLAIN QUERY PLAN code generation. +*/ +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ + (void)z1; + (void)z2; +} +#endif + +/* +** Add a new OP_Explain opcode. +** +** If the bPush flag is true, then make this opcode the parent for +** subsequent Explains until sqlite3VdbeExplainPop() is called. +*/ +SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ + int addr = 0; +#if !defined(SQLITE_DEBUG) + /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. + ** But omit them (for performance) during production builds */ + if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + char *zMsg; + Vdbe *v; + va_list ap; + int iThis; + va_start(ap, zFmt); + zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); + va_end(ap); + v = pParse->pVdbe; + iThis = v->nOp; + addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + zMsg, P4_DYNAMIC); + sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z); + if( bPush){ + pParse->addrExplain = iThis; + } + sqlite3VdbeScanStatus(v, iThis, -1, -1, 0, 0); + } + return addr; +} + +/* +** Pop the EXPLAIN QUERY PLAN stack one level. +*/ +SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ + sqlite3ExplainBreakpoint("POP", 0); + pParse->addrExplain = sqlite3VdbeExplainParent(pParse); +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +/* +** Add an OP_ParseSchema opcode. This routine is broken out from +** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees +** as having been used. +** +** The zWhere string must have been obtained from sqlite3_malloc(). +** This routine will take ownership of the allocated memory. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ + int j; + sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeChangeP5(p, p5); + for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); + sqlite3MayAbort(p->pParse); +} + +/* Insert the end of a co-routine +*/ +SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + + /* Clear the temporary register cache, thereby ensuring that each + ** co-routine has its own independent set of registers, because co-routines + ** might expect their registers to be preserved across an OP_Yield, and + ** that could cause problems if two or more co-routines are using the same + ** temporary register. + */ + v->pParse->nTempReg = 0; + v->pParse->nRangeReg = 0; +} + +/* +** Create a new symbolic label for an instruction that has yet to be +** coded. The symbolic label is really just a negative number. The +** label can be used as the P2 value of an operation. Later, when +** the label is resolved to a specific address, the VDBE will scan +** through its operation list and change all values of P2 which match +** the label into the resolved address. +** +** The VDBE knows that a P2 value is a label because labels are +** always negative and P2 values are suppose to be non-negative. +** Hence, a negative P2 value is a label that has yet to be resolved. +** (Later:) This is only true for opcodes that have the OPFLG_JUMP +** property. +** +** Variable usage notes: +** +** Parse.aLabel[x] Stores the address that the x-th label resolves +** into. For testing (SQLITE_DEBUG), unresolved +** labels stores -1, but that is not required. +** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[] +** Parse.nLabel The *negative* of the number of labels that have +** been issued. The negative is stored because +** that gives a performance improvement over storing +** the equivalent positive value. +*/ +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){ + return --pParse->nLabel; +} + +/* +** Resolve label "x" to be the address of the next instruction to +** be inserted. The parameter "x" must have been obtained from +** a prior call to sqlite3VdbeMakeLabel(). +*/ +static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ + int nNewSize = 10 - p->nLabel; + p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, + nNewSize*sizeof(p->aLabel[0])); + if( p->aLabel==0 ){ + p->nLabelAlloc = 0; + }else{ +#ifdef SQLITE_DEBUG + int i; + for(i=p->nLabelAlloc; iaLabel[i] = -1; +#endif + if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){ + sqlite3ProgressCheck(p); + } + p->nLabelAlloc = nNewSize; + p->aLabel[j] = v->nOp; + } +} +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ + Parse *p = v->pParse; + int j = ADDR(x); + assert( v->eVdbeState==VDBE_INIT_STATE ); + assert( j<-p->nLabel ); + assert( j>=0 ); +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + printf("RESOLVE LABEL %d to %d\n", x, v->nOp); + } +#endif + if( p->nLabelAlloc + p->nLabel < 0 ){ + resizeResolveLabel(p,v,j); + }else{ + assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */ + p->aLabel[j] = v->nOp; + } +} + +/* +** Mark the VDBE as one that can only be run one time. +*/ +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ + sqlite3VdbeAddOp2(p, OP_Expire, 1, 1); +} + +/* +** Mark the VDBE as one that can be run multiple times. +*/ +SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){ + int i; + for(i=1; ALWAYS(inOp); i++){ + if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){ + p->aOp[1].opcode = OP_Noop; + break; + } + } +} + +#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ + +/* +** The following type and function are used to iterate through all opcodes +** in a Vdbe main program and each of the sub-programs (triggers) it may +** invoke directly or indirectly. It should be used as follows: +** +** Op *pOp; +** VdbeOpIter sIter; +** +** memset(&sIter, 0, sizeof(sIter)); +** sIter.v = v; // v is of type Vdbe* +** while( (pOp = opIterNext(&sIter)) ){ +** // Do something with pOp +** } +** sqlite3DbFree(v->db, sIter.apSub); +** +*/ +typedef struct VdbeOpIter VdbeOpIter; +struct VdbeOpIter { + Vdbe *v; /* Vdbe to iterate through the opcodes of */ + SubProgram **apSub; /* Array of subprograms */ + int nSub; /* Number of entries in apSub */ + int iAddr; /* Address of next instruction to return */ + int iSub; /* 0 = main program, 1 = first sub-program etc. */ +}; +static Op *opIterNext(VdbeOpIter *p){ + Vdbe *v = p->v; + Op *pRet = 0; + Op *aOp; + int nOp; + + if( p->iSub<=p->nSub ){ + + if( p->iSub==0 ){ + aOp = v->aOp; + nOp = v->nOp; + }else{ + aOp = p->apSub[p->iSub-1]->aOp; + nOp = p->apSub[p->iSub-1]->nOp; + } + assert( p->iAddriAddr]; + p->iAddr++; + if( p->iAddr==nOp ){ + p->iSub++; + p->iAddr = 0; + } + + if( pRet->p4type==P4_SUBPROGRAM ){ + int nByte = (p->nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jnSub; j++){ + if( p->apSub[j]==pRet->p4.pProgram ) break; + } + if( j==p->nSub ){ + p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte); + if( !p->apSub ){ + pRet = 0; + }else{ + p->apSub[p->nSub++] = pRet->p4.pProgram; + } + } + } + } + + return pRet; +} + +/* +** Check if the program stored in the VM associated with pParse may +** throw an ABORT exception (causing the statement, but not entire transaction +** to be rolled back). This condition is true if the main program or any +** sub-programs contains any of the following: +** +** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_Destroy +** * OP_VUpdate +** * OP_VCreate +** * OP_VRename +** * OP_FkCounter with P2==0 (immediate foreign key constraint) +** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine +** (for CREATE TABLE AS SELECT ...) +** +** Then check that the value of Parse.mayAbort is true if an +** ABORT may be thrown, or false otherwise. Return true if it does +** match, or false otherwise. This function is intended to be used as +** part of an assert statement in the compiler. Similar to: +** +** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ + int hasAbort = 0; + int hasFkCounter = 0; + int hasCreateTable = 0; + int hasCreateIndex = 0; + int hasInitCoroutine = 0; + Op *pOp; + VdbeOpIter sIter; + + if( v==0 ) return 0; + memset(&sIter, 0, sizeof(sIter)); + sIter.v = v; + + while( (pOp = opIterNext(&sIter))!=0 ){ + int opcode = pOp->opcode; + if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename + || opcode==OP_VDestroy + || opcode==OP_VCreate + || opcode==OP_ParseSchema + || opcode==OP_Function || opcode==OP_PureFunc + || ((opcode==OP_Halt || opcode==OP_HaltIfNull) + && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) + ){ + hasAbort = 1; + break; + } + if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1; + if( mayAbort ){ + /* hasCreateIndex may also be set for some DELETE statements that use + ** OP_Clear. So this routine may end up returning true in the case + ** where a "DELETE FROM tbl" has a statement-journal but does not + ** require one. This is not so bad - it is an inefficiency, not a bug. */ + if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1; + if( opcode==OP_Clear ) hasCreateIndex = 1; + } + if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ + hasFkCounter = 1; + } +#endif + } + sqlite3DbFree(v->db, sIter.apSub); + + /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred. + ** If malloc failed, then the while() loop above may not have iterated + ** through all opcodes and hasAbort may be set incorrectly. Return + ** true for this case to prevent the assert() in the callers frame + ** from failing. */ + return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter + || (hasCreateTable && hasInitCoroutine) || hasCreateIndex + ); +} +#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ + +#ifdef SQLITE_DEBUG +/* +** Increment the nWrite counter in the VDBE if the cursor is not an +** ephemeral cursor, or if the cursor argument is NULL. +*/ +SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ + if( pC==0 + || (pC->eCurType!=CURTYPE_SORTER + && pC->eCurType!=CURTYPE_PSEUDO + && !pC->isEphemeral) + ){ + p->nWrite++; + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Assert if an Abort at this point in time might result in a corrupt +** database. +*/ +SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ + assert( p->nWrite==0 || p->usesStmtJournal ); +} +#endif + +/* +** This routine is called after all opcodes have been inserted. It loops +** through all the opcodes and fixes up some details. +** +** (1) For each jump instruction with a negative P2 value (a label) +** resolve the P2 value to an actual address. +** +** (2) Compute the maximum number of arguments used by any SQL function +** and store that value in *pMaxFuncArgs. +** +** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately +** indicate what the prepared statement actually does. +** +** (4) (discontinued) +** +** (5) Reclaim the memory allocated for storing labels. +** +** This routine will only function correctly if the mkopcodeh.tcl generator +** script numbers the opcodes correctly. Changes to this routine must be +** coordinated with changes to mkopcodeh.tcl. +*/ +static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ + int nMaxArgs = *pMaxFuncArgs; + Op *pOp; + Parse *pParse = p->pParse; + int *aLabel = pParse->aLabel; + + assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */ + p->readOnly = 1; + p->bIsReader = 0; + pOp = &p->aOp[p->nOp-1]; + assert( p->aOp[0].opcode==OP_Init ); + while( 1 /* Loop terminates when it reaches the OP_Init opcode */ ){ + /* Only JUMP opcodes and the short list of special opcodes in the switch + ** below need to be considered. The mkopcodeh.tcl generator script groups + ** all these opcodes together near the front of the opcode list. Skip + ** any opcode that does not need processing by virtual of the fact that + ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. + */ + if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){ + /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing + ** cases from this switch! */ + switch( pOp->opcode ){ + case OP_Transaction: { + if( pOp->p2!=0 ) p->readOnly = 0; + /* no break */ deliberate_fall_through + } + case OP_AutoCommit: + case OP_Savepoint: { + p->bIsReader = 1; + break; + } +#ifndef SQLITE_OMIT_WAL + case OP_Checkpoint: +#endif + case OP_Vacuum: + case OP_JournalMode: { + p->readOnly = 0; + p->bIsReader = 1; + break; + } + case OP_Init: { + assert( pOp->p2>=0 ); + goto resolve_p2_values_loop_exit; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case OP_VUpdate: { + if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; + break; + } + case OP_VFilter: { + int n; + assert( (pOp - p->aOp) >= 3 ); + assert( pOp[-1].opcode==OP_Integer ); + n = pOp[-1].p1; + if( n>nMaxArgs ) nMaxArgs = n; + /* Fall through into the default case */ + /* no break */ deliberate_fall_through + } +#endif + default: { + if( pOp->p2<0 ){ + /* The mkopcodeh.tcl script has so arranged things that the only + ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to + ** have non-negative values for P2. */ + assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); + assert( ADDR(pOp->p2)<-pParse->nLabel ); + assert( aLabel!=0 ); /* True because of tag-20230419-1 */ + pOp->p2 = aLabel[ADDR(pOp->p2)]; + } + break; + } + } + /* The mkopcodeh.tcl script has so arranged things that the only + ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to + ** have non-negative values for P2. */ + assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); + } + assert( pOp>p->aOp ); + pOp--; + } +resolve_p2_values_loop_exit: + if( aLabel ){ + sqlite3DbNNFreeNN(p->db, pParse->aLabel); + pParse->aLabel = 0; + } + pParse->nLabel = 0; + *pMaxFuncArgs = nMaxArgs; + assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); +} + +#ifdef SQLITE_DEBUG +/* +** Check to see if a subroutine contains a jump to a location outside of +** the subroutine. If a jump outside the subroutine is detected, add code +** that will cause the program to halt with an error message. +** +** The subroutine consists of opcodes between iFirst and iLast. Jumps to +** locations within the subroutine are acceptable. iRetReg is a register +** that contains the return address. Jumps to outside the range of iFirst +** through iLast are also acceptable as long as the jump destination is +** an OP_Return to iReturnAddr. +** +** A jump to an unresolved label means that the jump destination will be +** beyond the current address. That is normally a jump to an early +** termination and is consider acceptable. +** +** This routine only runs during debug builds. The purpose is (of course) +** to detect invalid escapes out of a subroutine. The OP_Halt opcode +** is generated rather than an assert() or other error, so that ".eqp full" +** will still work to show the original bytecode, to aid in debugging. +*/ +SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn( + Vdbe *v, /* The byte-code program under construction */ + int iFirst, /* First opcode of the subroutine */ + int iLast, /* Last opcode of the subroutine */ + int iRetReg /* Subroutine return address register */ +){ + VdbeOp *pOp; + Parse *pParse; + int i; + sqlite3_str *pErr = 0; + assert( v!=0 ); + pParse = v->pParse; + assert( pParse!=0 ); + if( pParse->nErr ) return; + assert( iLast>=iFirst ); + assert( iLastnOp ); + pOp = &v->aOp[iFirst]; + for(i=iFirst; i<=iLast; i++, pOp++){ + if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ){ + int iDest = pOp->p2; /* Jump destination */ + if( iDest==0 ) continue; + if( pOp->opcode==OP_Gosub ) continue; + if( pOp->p3==20230325 && pOp->opcode==OP_NotNull ){ + /* This is a deliberately taken illegal branch. tag-20230325-2 */ + continue; + } + if( iDest<0 ){ + int j = ADDR(iDest); + assert( j>=0 ); + if( j>=-pParse->nLabel || pParse->aLabel[j]<0 ){ + continue; + } + iDest = pParse->aLabel[j]; + } + if( iDestiLast ){ + int j = iDest; + for(; jnOp; j++){ + VdbeOp *pX = &v->aOp[j]; + if( pX->opcode==OP_Return ){ + if( pX->p1==iRetReg ) break; + continue; + } + if( pX->opcode==OP_Noop ) continue; + if( pX->opcode==OP_Explain ) continue; + if( pErr==0 ){ + pErr = sqlite3_str_new(0); + }else{ + sqlite3_str_appendchar(pErr, 1, '\n'); + } + sqlite3_str_appendf(pErr, + "Opcode at %d jumps to %d which is outside the " + "subroutine at %d..%d", + i, iDest, iFirst, iLast); + break; + } + } + } + } + if( pErr ){ + char *zErr = sqlite3_str_finish(pErr); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_INTERNAL, OE_Abort, 0, zErr, 0); + sqlite3_free(zErr); + sqlite3MayAbort(pParse); + } +} +#endif /* SQLITE_DEBUG */ + +/* +** Return the address of the next instruction to be inserted. +*/ +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ + assert( p->eVdbeState==VDBE_INIT_STATE ); + return p->nOp; +} + +/* +** Verify that at least N opcode slots are available in p without +** having to malloc for more space (except when compiled using +** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing +** to verify that certain calls to sqlite3VdbeAddOpList() can never +** fail due to a OOM fault and hence that the return value from +** sqlite3VdbeAddOpList() will always be non-NULL. +*/ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ + assert( p->nOp + N <= p->nOpAlloc ); +} +#endif + +/* +** Verify that the VM passed as the only argument does not contain +** an OP_ResultRow opcode. Fail an assert() if it does. This is used +** by code in pragma.c to ensure that the implementation of certain +** pragmas comports with the flags specified in the mkpragmatab.tcl +** script. +*/ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){ + int i; + for(i=0; inOp; i++){ + assert( p->aOp[i].opcode!=OP_ResultRow ); + } +} +#endif + +/* +** Generate code (a single OP_Abortable opcode) that will +** verify that the VDBE program can safely call Abort in the current +** context. +*/ +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ + if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable); +} +#endif + +/* +** This function returns a pointer to the array of opcodes associated with +** the Vdbe passed as the first argument. It is the callers responsibility +** to arrange for the returned array to be eventually freed using the +** vdbeFreeOpArray() function. +** +** Before returning, *pnOp is set to the number of entries in the returned +** array. Also, *pnMaxArg is set to the larger of its current value and +** the number of entries in the Vdbe.apArg[] array required to execute the +** returned program. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ + VdbeOp *aOp = p->aOp; + assert( aOp && !p->db->mallocFailed ); + + /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ + assert( DbMaskAllZero(p->btreeMask) ); + + resolveP2Values(p, pnMaxArg); + *pnOp = p->nOp; + p->aOp = 0; + return aOp; +} + +/* +** Add a whole list of operations to the operation stack. Return a +** pointer to the first operation inserted. +** +** Non-zero P2 arguments to jump instructions are automatically adjusted +** so that the jump target is relative to the first operation inserted. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( + Vdbe *p, /* Add opcodes to the prepared statement */ + int nOp, /* Number of opcodes to add */ + VdbeOpList const *aOp, /* The opcodes to be added */ + int iLineno /* Source-file line number of first opcode */ +){ + int i; + VdbeOp *pOut, *pFirst; + assert( nOp>0 ); + assert( p->eVdbeState==VDBE_INIT_STATE ); + if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ + return 0; + } + pFirst = pOut = &p->aOp[p->nOp]; + for(i=0; iopcode = aOp->opcode; + pOut->p1 = aOp->p1; + pOut->p2 = aOp->p2; + assert( aOp->p2>=0 ); + if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ + pOut->p2 += p->nOp; + } + pOut->p3 = aOp->p3; + pOut->p4type = P4_NOTUSED; + pOut->p4.p = 0; + pOut->p5 = 0; +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOut->zComment = 0; +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOut->iSrcLine = iLineno+i; +#else + (void)iLineno; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]); + } +#endif + } + p->nOp += nOp; + return pFirst; +} + +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/* +** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus(). +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatus( + Vdbe *p, /* VM to add scanstatus() to */ + int addrExplain, /* Address of OP_Explain (or 0) */ + int addrLoop, /* Address of loop counter */ + int addrVisit, /* Address of rows visited counter */ + LogEst nEst, /* Estimated number of output rows */ + const char *zName /* Name of table or index being scanned */ +){ + if( IS_STMT_SCANSTATUS(p->db) ){ + sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); + ScanStatus *aNew; + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); + if( aNew ){ + ScanStatus *pNew = &aNew[p->nScan++]; + memset(pNew, 0, sizeof(ScanStatus)); + pNew->addrExplain = addrExplain; + pNew->addrLoop = addrLoop; + pNew->addrVisit = addrVisit; + pNew->nEst = nEst; + pNew->zName = sqlite3DbStrDup(p->db, zName); + p->aScan = aNew; + } + } +} + +/* +** Add the range of instructions from addrStart to addrEnd (inclusive) to +** the set of those corresponding to the sqlite3_stmt_scanstatus() counters +** associated with the OP_Explain instruction at addrExplain. The +** sum of the sqlite3Hwtime() values for each of these instructions +** will be returned for SQLITE_SCANSTAT_NCYCLE requests. +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatusRange( + Vdbe *p, + int addrExplain, + int addrStart, + int addrEnd +){ + if( IS_STMT_SCANSTATUS(p->db) ){ + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; + for(ii=0; iiaAddrRange); ii+=2){ + if( pScan->aAddrRange[ii]==0 ){ + pScan->aAddrRange[ii] = addrStart; + pScan->aAddrRange[ii+1] = addrEnd; + break; + } + } + } + } +} + +/* +** Set the addresses for the SQLITE_SCANSTAT_NLOOP and SQLITE_SCANSTAT_NROW +** counters for the query element associated with the OP_Explain at +** addrExplain. +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( + Vdbe *p, + int addrExplain, + int addrLoop, + int addrVisit +){ + if( IS_STMT_SCANSTATUS(p->db) ){ + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + if( addrLoop>0 ) pScan->addrLoop = addrLoop; + if( addrVisit>0 ) pScan->addrVisit = addrVisit; + } + } +} +#endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */ + + +/* +** Change the value of the opcode, or P1, P2, P3, or P5 operands +** for a specific instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ + assert( addr>=0 ); + sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ + assert( addr>=0 ); + sqlite3VdbeGetOp(p,addr)->p1 = val; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ + assert( addr>=0 || p->db->mallocFailed ); + sqlite3VdbeGetOp(p,addr)->p2 = val; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ + assert( addr>=0 ); + sqlite3VdbeGetOp(p,addr)->p3 = val; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ + assert( p->nOp>0 || p->db->mallocFailed ); + if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; +} + +/* +** If the previous opcode is an OP_Column that delivers results +** into register iDest, then add the OPFLAG_TYPEOFARG flag to that +** opcode. +*/ +SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ + VdbeOp *pOp = sqlite3VdbeGetLastOp(p); + if( pOp->p3==iDest && pOp->opcode==OP_Column ){ + pOp->p5 |= OPFLAG_TYPEOFARG; + } +} + +/* +** Change the P2 operand of instruction addr so that it points to +** the address of the next instruction to be coded. +*/ +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ + sqlite3VdbeChangeP2(p, addr, p->nOp); +} + +/* +** Change the P2 operand of the jump instruction at addr so that +** the jump lands on the next opcode. Or if the jump instruction was +** the previous opcode (and is thus a no-op) then simply back up +** the next instruction counter by one slot so that the jump is +** overwritten by the next inserted opcode. +** +** This routine is an optimization of sqlite3VdbeJumpHere() that +** strives to omit useless byte-code like this: +** +** 7 Once 0 8 0 +** 8 ... +*/ +SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ + if( addr==p->nOp-1 ){ + assert( p->aOp[addr].opcode==OP_Once + || p->aOp[addr].opcode==OP_If + || p->aOp[addr].opcode==OP_FkIfZero ); + assert( p->aOp[addr].p4type==0 ); +#ifdef SQLITE_VDBE_COVERAGE + sqlite3VdbeGetLastOp(p)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ +#endif + p->nOp--; + }else{ + sqlite3VdbeChangeP2(p, addr, p->nOp); + } +} + + +/* +** If the input FuncDef structure is ephemeral, then free it. If +** the FuncDef is not ephemeral, then do nothing. +*/ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ + assert( db!=0 ); + if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ + sqlite3DbNNFreeNN(db, pDef); + } +} + +/* +** Delete a P4 value if necessary. +*/ +static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + sqlite3DbNNFreeNN(db, p); +} +static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ + assert( db!=0 ); + freeEphemeralFunction(db, p->pFunc); + sqlite3DbNNFreeNN(db, p); +} +static void freeP4(sqlite3 *db, int p4type, void *p4){ + assert( db ); + switch( p4type ){ + case P4_FUNCCTX: { + freeP4FuncCtx(db, (sqlite3_context*)p4); + break; + } + case P4_REAL: + case P4_INT64: + case P4_DYNAMIC: + case P4_INTARRAY: { + if( p4 ) sqlite3DbNNFreeNN(db, p4); + break; + } + case P4_KEYINFO: { + if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); + break; + } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + case P4_EXPR: { + sqlite3ExprDelete(db, (Expr*)p4); + break; + } +#endif + case P4_FUNCDEF: { + freeEphemeralFunction(db, (FuncDef*)p4); + break; + } + case P4_MEM: { + if( db->pnBytesFreed==0 ){ + sqlite3ValueFree((sqlite3_value*)p4); + }else{ + freeP4Mem(db, (Mem*)p4); + } + break; + } + case P4_VTAB : { + if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); + break; + } + case P4_TABLEREF: { + if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); + break; + } + } +} + +/* +** Free the space allocated for aOp and any p4 values allocated for the +** opcodes contained within. If aOp is not NULL it is assumed to contain +** nOp entries. +*/ +static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ + assert( nOp>=0 ); + assert( db!=0 ); + if( aOp ){ + Op *pOp = &aOp[nOp-1]; + while(1){ /* Exit via break */ + if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + sqlite3DbFree(db, pOp->zComment); +#endif + if( pOp==aOp ) break; + pOp--; + } + sqlite3DbNNFreeNN(db, aOp); + } +} + +/* +** Link the SubProgram object passed as the second argument into the linked +** list at Vdbe.pSubProgram. This list is used to delete all sub-program +** objects when the VM is no longer required. +*/ +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ + p->pNext = pVdbe->pProgram; + pVdbe->pProgram = p; +} + +/* +** Return true if the given Vdbe has any SubPrograms. +*/ +SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){ + return pVdbe->pProgram!=0; +} + +/* +** Change the opcode at addr into OP_Noop +*/ +SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ + VdbeOp *pOp; + if( p->db->mallocFailed ) return 0; + assert( addr>=0 && addrnOp ); + pOp = &p->aOp[addr]; + freeP4(p->db, pOp->p4type, pOp->p4.p); + pOp->p4type = P4_NOTUSED; + pOp->p4.z = 0; + pOp->opcode = OP_Noop; + return 1; +} + +/* +** If the last opcode is "op" and it is not a jump destination, +** then remove it. Return true if and only if an opcode was removed. +*/ +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ + if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){ + return sqlite3VdbeChangeToNoop(p, p->nOp-1); + }else{ + return 0; + } +} + +#ifdef SQLITE_DEBUG +/* +** Generate an OP_ReleaseReg opcode to indicate that a range of +** registers, except any identified by mask, are no longer in use. +*/ +SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters( + Parse *pParse, /* Parsing context */ + int iFirst, /* Index of first register to be released */ + int N, /* Number of registers to release */ + u32 mask, /* Mask of registers to NOT release */ + int bUndefine /* If true, mark registers as undefined */ +){ + if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return; + assert( pParse->pVdbe ); + assert( iFirst>=1 ); + assert( iFirst+N-1<=pParse->nMem ); + if( N<=31 && mask!=0 ){ + while( N>0 && (mask&1)!=0 ){ + mask >>= 1; + iFirst++; + N--; + } + while( N>0 && N<=32 && (mask & MASKBIT32(N-1))!=0 ){ + mask &= ~MASKBIT32(N-1); + N--; + } + } + if( N>0 ){ + sqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask); + if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1); + } +} +#endif /* SQLITE_DEBUG */ + +/* +** Change the value of the P4 operand for a specific instruction. +** This routine is useful when a large program is loaded from a +** static array using sqlite3VdbeAddOpList but we want to make a +** few minor changes to the program. +** +** If n>=0 then the P4 operand is dynamic, meaning that a copy of +** the string is made into memory obtained from sqlite3_malloc(). +** A value of n==0 means copy bytes of zP4 up to and including the +** first null byte. If n>0 then copy n+1 bytes of zP4. +** +** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points +** to a string or structure that is guaranteed to exist for the lifetime of +** the Vdbe. In these cases we can just copy the pointer. +** +** If addr<0 then change P4 on the most recently inserted instruction. +*/ +static void SQLITE_NOINLINE vdbeChangeP4Full( + Vdbe *p, + Op *pOp, + const char *zP4, + int n +){ + if( pOp->p4type ){ + assert( pOp->p4type > P4_FREE_IF_LE ); + pOp->p4type = 0; + pOp->p4.p = 0; + } + if( n<0 ){ + sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n); + }else{ + if( n==0 ) n = sqlite3Strlen30(zP4); + pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n); + pOp->p4type = P4_DYNAMIC; + } +} +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ + Op *pOp; + sqlite3 *db; + assert( p!=0 ); + db = p->db; + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->aOp!=0 || db->mallocFailed ); + if( db->mallocFailed ){ + if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); + return; + } + assert( p->nOp>0 ); + assert( addrnOp ); + if( addr<0 ){ + addr = p->nOp - 1; + } + pOp = &p->aOp[addr]; + if( n>=0 || pOp->p4type ){ + vdbeChangeP4Full(p, pOp, zP4, n); + return; + } + if( n==P4_INT32 ){ + /* Note: this cast is safe, because the origin data point was an int + ** that was cast to a (const char *). */ + pOp->p4.i = SQLITE_PTR_TO_INT(zP4); + pOp->p4type = P4_INT32; + }else if( zP4!=0 ){ + assert( n<0 ); + pOp->p4.p = (void*)zP4; + pOp->p4type = (signed char)n; + if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4); + } +} + +/* +** Change the P4 operand of the most recently coded instruction +** to the value defined by the arguments. This is a high-speed +** version of sqlite3VdbeChangeP4(). +** +** The P4 operand must not have been previously defined. And the new +** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of +** those cases. +*/ +SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ + VdbeOp *pOp; + assert( n!=P4_INT32 && n!=P4_VTAB ); + assert( n<=0 ); + if( p->db->mallocFailed ){ + freeP4(p->db, n, pP4); + }else{ + assert( pP4!=0 || n==P4_DYNAMIC ); + assert( p->nOp>0 ); + pOp = &p->aOp[p->nOp-1]; + assert( pOp->p4type==P4_NOTUSED ); + pOp->p4type = n; + pOp->p4.p = pP4; + } +} + +/* +** Set the P4 on the most recently added opcode to the KeyInfo for the +** index given. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ + Vdbe *v = pParse->pVdbe; + KeyInfo *pKeyInfo; + assert( v!=0 ); + assert( pIdx!=0 ); + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx); + if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* +** Change the comment on the most recently coded instruction. Or +** insert a No-op and add the comment to that new instruction. This +** makes the code easier to read during debugging. None of this happens +** in a production build. +*/ +static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ + assert( p->nOp>0 || p->aOp==0 ); + assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 ); + if( p->nOp ){ + assert( p->aOp ); + sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); + p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap); + } +} +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + if( p ){ + va_start(ap, zFormat); + vdbeVComment(p, zFormat, ap); + va_end(ap); + } +} +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + if( p ){ + sqlite3VdbeAddOp0(p, OP_Noop); + va_start(ap, zFormat); + vdbeVComment(p, zFormat, ap); + va_end(ap); + } +} +#endif /* NDEBUG */ + +#ifdef SQLITE_VDBE_COVERAGE +/* +** Set the value if the iSrcLine field for the previously coded instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ + sqlite3VdbeGetLastOp(v)->iSrcLine = iLine; +} +#endif /* SQLITE_VDBE_COVERAGE */ + +/* +** Return the opcode for a given address. The address must be non-negative. +** See sqlite3VdbeGetLastOp() to get the most recently added opcode. +** +** If a memory allocation error has occurred prior to the calling of this +** routine, then a pointer to a dummy VdbeOp will be returned. That opcode +** is readable but not writable, though it is cast to a writable value. +** The return of a dummy opcode allows the call to continue functioning +** after an OOM fault without having to check to see if the return from +** this routine is a valid pointer. But because the dummy.opcode is 0, +** dummy will never be written to. This is verified by code inspection and +** by running with Valgrind. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ + /* C89 specifies that the constant "dummy" will be initialized to all + ** zeros, which is correct. MSVC generates a warning, nevertheless. */ + static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); + if( p->db->mallocFailed ){ + return (VdbeOp*)&dummy; + }else{ + return &p->aOp[addr]; + } +} + +/* Return the most recently added opcode +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe *p){ + return sqlite3VdbeGetOp(p, p->nOp - 1); +} + +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) +/* +** Return an integer value for one of the parameters to the opcode pOp +** determined by character c. +*/ +static int translateP(char c, const Op *pOp){ + if( c=='1' ) return pOp->p1; + if( c=='2' ) return pOp->p2; + if( c=='3' ) return pOp->p3; + if( c=='4' ) return pOp->p4.i; + return pOp->p5; +} + +/* +** Compute a string for the "comment" field of a VDBE opcode listing. +** +** The Synopsis: field in comments in the vdbe.c source file gets converted +** to an extra string that is appended to the sqlite3OpcodeName(). In the +** absence of other comments, this synopsis becomes the comment on the opcode. +** Some translation occurs: +** +** "PX" -> "r[X]" +** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 +** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 +** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x +*/ +SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( + sqlite3 *db, /* Optional - Oom error reporting only */ + const Op *pOp, /* The opcode to be commented */ + const char *zP4 /* Previously obtained value for P4 */ +){ + const char *zOpName; + const char *zSynopsis; + int nOpName; + int ii; + char zAlt[50]; + StrAccum x; + + sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH); + zOpName = sqlite3OpcodeName(pOp->opcode); + nOpName = sqlite3Strlen30(zOpName); + if( zOpName[nOpName+1] ){ + int seenCom = 0; + char c; + zSynopsis = zOpName + nOpName + 1; + if( strncmp(zSynopsis,"IF ",3)==0 ){ + sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); + zSynopsis = zAlt; + } + for(ii=0; (c = zSynopsis[ii])!=0; ii++){ + if( c=='P' ){ + c = zSynopsis[++ii]; + if( c=='4' ){ + sqlite3_str_appendall(&x, zP4); + }else if( c=='X' ){ + if( pOp->zComment && pOp->zComment[0] ){ + sqlite3_str_appendall(&x, pOp->zComment); + seenCom = 1; + break; + } + }else{ + int v1 = translateP(c, pOp); + int v2; + if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ + ii += 3; + v2 = translateP(zSynopsis[ii], pOp); + if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){ + ii += 2; + v2++; + } + if( v2<2 ){ + sqlite3_str_appendf(&x, "%d", v1); + }else{ + sqlite3_str_appendf(&x, "%d..%d", v1, v1+v2-1); + } + }else if( strncmp(zSynopsis+ii+1, "@NP", 3)==0 ){ + sqlite3_context *pCtx = pOp->p4.pCtx; + if( pOp->p4type!=P4_FUNCCTX || pCtx->argc==1 ){ + sqlite3_str_appendf(&x, "%d", v1); + }else if( pCtx->argc>1 ){ + sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1); + }else if( x.accError==0 ){ + assert( x.nChar>2 ); + x.nChar -= 2; + ii++; + } + ii += 3; + }else{ + sqlite3_str_appendf(&x, "%d", v1); + if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ + ii += 4; + } + } + } + }else{ + sqlite3_str_appendchar(&x, 1, c); + } + } + if( !seenCom && pOp->zComment ){ + sqlite3_str_appendf(&x, "; %s", pOp->zComment); + } + }else if( pOp->zComment ){ + sqlite3_str_appendall(&x, pOp->zComment); + } + if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){ + sqlite3OomFault(db); + } + return sqlite3StrAccumFinish(&x); +} +#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */ + +#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) +/* +** Translate the P4.pExpr value for an OP_CursorHint opcode into text +** that can be displayed in the P4 column of EXPLAIN output. +*/ +static void displayP4Expr(StrAccum *p, Expr *pExpr){ + const char *zOp = 0; + switch( pExpr->op ){ + case TK_STRING: + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3_str_appendf(p, "%Q", pExpr->u.zToken); + break; + case TK_INTEGER: + sqlite3_str_appendf(p, "%d", pExpr->u.iValue); + break; + case TK_NULL: + sqlite3_str_appendf(p, "NULL"); + break; + case TK_REGISTER: { + sqlite3_str_appendf(p, "r[%d]", pExpr->iTable); + break; + } + case TK_COLUMN: { + if( pExpr->iColumn<0 ){ + sqlite3_str_appendf(p, "rowid"); + }else{ + sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn); + } + break; + } + case TK_LT: zOp = "LT"; break; + case TK_LE: zOp = "LE"; break; + case TK_GT: zOp = "GT"; break; + case TK_GE: zOp = "GE"; break; + case TK_NE: zOp = "NE"; break; + case TK_EQ: zOp = "EQ"; break; + case TK_IS: zOp = "IS"; break; + case TK_ISNOT: zOp = "ISNOT"; break; + case TK_AND: zOp = "AND"; break; + case TK_OR: zOp = "OR"; break; + case TK_PLUS: zOp = "ADD"; break; + case TK_STAR: zOp = "MUL"; break; + case TK_MINUS: zOp = "SUB"; break; + case TK_REM: zOp = "REM"; break; + case TK_BITAND: zOp = "BITAND"; break; + case TK_BITOR: zOp = "BITOR"; break; + case TK_SLASH: zOp = "DIV"; break; + case TK_LSHIFT: zOp = "LSHIFT"; break; + case TK_RSHIFT: zOp = "RSHIFT"; break; + case TK_CONCAT: zOp = "CONCAT"; break; + case TK_UMINUS: zOp = "MINUS"; break; + case TK_UPLUS: zOp = "PLUS"; break; + case TK_BITNOT: zOp = "BITNOT"; break; + case TK_NOT: zOp = "NOT"; break; + case TK_ISNULL: zOp = "ISNULL"; break; + case TK_NOTNULL: zOp = "NOTNULL"; break; + + default: + sqlite3_str_appendf(p, "%s", "expr"); + break; + } + + if( zOp ){ + sqlite3_str_appendf(p, "%s(", zOp); + displayP4Expr(p, pExpr->pLeft); + if( pExpr->pRight ){ + sqlite3_str_append(p, ",", 1); + displayP4Expr(p, pExpr->pRight); + } + sqlite3_str_append(p, ")", 1); + } +} +#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ + + +#if VDBE_DISPLAY_P4 +/* +** Compute a string that describes the P4 parameter for an opcode. +** Use zTemp for any required temporary buffer space. +*/ +SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ + char *zP4 = 0; + StrAccum x; + + sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH); + switch( pOp->p4type ){ + case P4_KEYINFO: { + int j; + KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->aSortFlags!=0 ); + sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); + for(j=0; jnKeyField; j++){ + CollSeq *pColl = pKeyInfo->aColl[j]; + const char *zColl = pColl ? pColl->zName : ""; + if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; + sqlite3_str_appendf(&x, ",%s%s%s", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", + zColl); + } + sqlite3_str_append(&x, ")", 1); + break; + } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + case P4_EXPR: { + displayP4Expr(&x, pOp->p4.pExpr); + break; + } +#endif + case P4_COLLSEQ: { + static const char *const encnames[] = {"?", "8", "16LE", "16BE"}; + CollSeq *pColl = pOp->p4.pColl; + assert( pColl->enc<4 ); + sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName, + encnames[pColl->enc]); + break; + } + case P4_FUNCDEF: { + FuncDef *pDef = pOp->p4.pFunc; + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); + break; + } + case P4_FUNCCTX: { + FuncDef *pDef = pOp->p4.pCtx->pFunc; + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); + break; + } + case P4_INT64: { + sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); + break; + } + case P4_INT32: { + sqlite3_str_appendf(&x, "%d", pOp->p4.i); + break; + } + case P4_REAL: { + sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); + break; + } + case P4_MEM: { + Mem *pMem = pOp->p4.pMem; + if( pMem->flags & MEM_Str ){ + zP4 = pMem->z; + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + sqlite3_str_appendf(&x, "%lld", pMem->u.i); + }else if( pMem->flags & MEM_Real ){ + sqlite3_str_appendf(&x, "%.16g", pMem->u.r); + }else if( pMem->flags & MEM_Null ){ + zP4 = "NULL"; + }else{ + assert( pMem->flags & MEM_Blob ); + zP4 = "(blob)"; + } + break; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case P4_VTAB: { + sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; + sqlite3_str_appendf(&x, "vtab:%p", pVtab); + break; + } +#endif + case P4_INTARRAY: { + u32 i; + u32 *ai = pOp->p4.ai; + u32 n = ai[0]; /* The first element of an INTARRAY is always the + ** count of the number of elements to follow */ + for(i=1; i<=n; i++){ + sqlite3_str_appendf(&x, "%c%u", (i==1 ? '[' : ','), ai[i]); + } + sqlite3_str_append(&x, "]", 1); + break; + } + case P4_SUBPROGRAM: { + zP4 = "program"; + break; + } + case P4_TABLE: { + zP4 = pOp->p4.pTab->zName; + break; + } + default: { + zP4 = pOp->p4.z; + } + } + if( zP4 ) sqlite3_str_appendall(&x, zP4); + if( (x.accError & SQLITE_NOMEM)!=0 ){ + sqlite3OomFault(db); + } + return sqlite3StrAccumFinish(&x); +} +#endif /* VDBE_DISPLAY_P4 */ + +/* +** Declare to the Vdbe that the BTree object at db->aDb[i] is used. +** +** The prepared statements need to know in advance the complete set of +** attached databases that will be use. A mask of these databases +** is maintained in p->btreeMask. The p->lockMask value is the subset of +** p->btreeMask of databases that will require a lock. +*/ +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ + assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); + assert( i<(int)sizeof(p->btreeMask)*8 ); + DbMaskSet(p->btreeMask, i); + if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ + DbMaskSet(p->lockMask, i); + } +} + +#if !defined(SQLITE_OMIT_SHARED_CACHE) +/* +** If SQLite is compiled to support shared-cache mode and to be threadsafe, +** this routine obtains the mutex associated with each BtShared structure +** that may be accessed by the VM passed as an argument. In doing so it also +** sets the BtShared.db member of each of the BtShared structures, ensuring +** that the correct busy-handler callback is invoked if required. +** +** If SQLite is not threadsafe but does support shared-cache mode, then +** sqlite3BtreeEnter() is invoked to set the BtShared.db variables +** of all of BtShared structures accessible via the database handle +** associated with the VM. +** +** If SQLite is not threadsafe and does not support shared-cache mode, this +** function is a no-op. +** +** The p->btreeMask field is a bitmask of all btrees that the prepared +** statement p will ever use. Let N be the number of bits in p->btreeMask +** corresponding to btrees that use shared cache. Then the runtime of +** this routine is N*N. But as N is rarely more than 1, this should not +** be a problem. +*/ +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ + int i; + sqlite3 *db; + Db *aDb; + int nDb; + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeEnter(aDb[i].pBt); + } + } +} +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +/* +** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). +*/ +static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){ + int i; + sqlite3 *db; + Db *aDb; + int nDb; + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeLeave(aDb[i].pBt); + } + } +} +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ + vdbeLeave(p); +} +#endif + +#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +/* +** Print a single opcode. This routine is used for debugging only. +*/ +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ + char *zP4; + char *zCom; + sqlite3 dummyDb; + static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n"; + if( pOut==0 ) pOut = stdout; + sqlite3BeginBenignMalloc(); + dummyDb.mallocFailed = 1; + zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + zCom = sqlite3VdbeDisplayComment(0, pOp, zP4); +#else + zCom = 0; +#endif + /* NB: The sqlite3OpcodeName() function is implemented by code created + ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the + ** information from the vdbe.c source text */ + fprintf(pOut, zFormat1, pc, + sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, + zP4 ? zP4 : "", pOp->p5, + zCom ? zCom : "" + ); + fflush(pOut); + sqlite3_free(zP4); + sqlite3_free(zCom); + sqlite3EndBenignMalloc(); +} +#endif + +/* +** Initialize an array of N Mem element. +** +** This is a high-runner, so only those fields that really do need to +** be initialized are set. The Mem structure is organized so that +** the fields that get initialized are nearby and hopefully on the same +** cache line. +** +** Mem.flags = flags +** Mem.db = db +** Mem.szMalloc = 0 +** +** All other fields of Mem can safely remain uninitialized for now. They +** will be initialized before use. +*/ +static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + if( N>0 ){ + do{ + p->flags = flags; + p->db = db; + p->szMalloc = 0; +#ifdef SQLITE_DEBUG + p->pScopyFrom = 0; +#endif + p++; + }while( (--N)>0 ); + } +} + +/* +** Release auxiliary memory held in an array of N Mem elements. +** +** After this routine returns, all Mem elements in the array will still +** be valid. Those Mem elements that were not holding auxiliary resources +** will be unchanged. Mem elements which had something freed will be +** set to MEM_Undefined. +*/ +static void releaseMemArray(Mem *p, int N){ + if( p && N ){ + Mem *pEnd = &p[N]; + sqlite3 *db = p->db; + if( db->pnBytesFreed ){ + do{ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + }while( (++p)flags & MEM_Agg ); + testcase( p->flags & MEM_Dyn ); + if( p->flags&(MEM_Agg|MEM_Dyn) ){ + testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); + sqlite3VdbeMemRelease(p); + p->flags = MEM_Undefined; + }else if( p->szMalloc ){ + sqlite3DbNNFreeNN(db, p->zMalloc); + p->szMalloc = 0; + p->flags = MEM_Undefined; + } +#ifdef SQLITE_DEBUG + else{ + p->flags = MEM_Undefined; + } +#endif + }while( (++p)iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; + return 1; +} +#endif + + +/* +** This is a destructor on a Mem object (which is really an sqlite3_value) +** that deletes the Frame object that is attached to it as a blob. +** +** This routine does not delete the Frame right away. It merely adds the +** frame to a list of frames to be deleted when the Vdbe halts. +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){ + VdbeFrame *pFrame = (VdbeFrame*)pArg; + assert( sqlite3VdbeFrameIsValid(pFrame) ); + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; +} + +#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN) +/* +** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN +** QUERY PLAN output. +** +** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no +** more opcodes to be displayed. +*/ +SQLITE_PRIVATE int sqlite3VdbeNextOpcode( + Vdbe *p, /* The statement being explained */ + Mem *pSub, /* Storage for keeping track of subprogram nesting */ + int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */ + int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */ + int *piAddr, /* OUT: Write index into (*paOp)[] here */ + Op **paOp /* OUT: Write the opcode array here */ +){ + int nRow; /* Stop when row count reaches this */ + int nSub = 0; /* Number of sub-vdbes seen so far */ + SubProgram **apSub = 0; /* Array of sub-vdbes */ + int i; /* Next instruction address */ + int rc = SQLITE_OK; /* Result code */ + Op *aOp = 0; /* Opcode array */ + int iPc; /* Rowid. Copy of value in *piPc */ + + /* When the number of output rows reaches nRow, that means the + ** listing has finished and sqlite3_step() should return SQLITE_DONE. + ** nRow is the sum of the number of rows in the main program, plus + ** the sum of the number of rows in all trigger subprograms encountered + ** so far. The nRow value will increase as new trigger subprograms are + ** encountered, but p->pc will eventually catch up to nRow. + */ + nRow = p->nOp; + if( pSub!=0 ){ + if( pSub->flags&MEM_Blob ){ + /* pSub is initiallly NULL. It is initialized to a BLOB by + ** the P4_SUBPROGRAM processing logic below */ + nSub = pSub->n/sizeof(Vdbe*); + apSub = (SubProgram **)pSub->z; + } + for(i=0; inOp; + } + } + iPc = *piPc; + while(1){ /* Loop exits via break */ + i = iPc++; + if( i>=nRow ){ + p->rc = SQLITE_OK; + rc = SQLITE_DONE; + break; + } + if( inOp ){ + /* The rowid is small enough that we are still in the + ** main program. */ + aOp = p->aOp; + }else{ + /* We are currently listing subprograms. Figure out which one and + ** pick up the appropriate opcode. */ + int j; + i -= p->nOp; + assert( apSub!=0 ); + assert( nSub>0 ); + for(j=0; i>=apSub[j]->nOp; j++){ + i -= apSub[j]->nOp; + assert( inOp || j+1aOp; + } + + /* When an OP_Program opcode is encounter (the only opcode that has + ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms + ** kept in p->aMem[9].z to hold the new program - assuming this subprogram + ** has not already been seen. + */ + if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){ + int nByte = (nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jrc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + break; + } + apSub = (SubProgram **)pSub->z; + apSub[nSub++] = aOp[i].p4.pProgram; + MemSetTypeFlag(pSub, MEM_Blob); + pSub->n = nSub*sizeof(SubProgram*); + nRow += aOp[i].p4.pProgram->nOp; + } + } + if( eMode==0 ) break; +#ifdef SQLITE_ENABLE_BYTECODE_VTAB + if( eMode==2 ){ + Op *pOp = aOp + i; + if( pOp->opcode==OP_OpenRead ) break; + if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break; + if( pOp->opcode==OP_ReopenIdx ) break; + }else +#endif + { + assert( eMode==1 ); + if( aOp[i].opcode==OP_Explain ) break; + if( aOp[i].opcode==OP_Init && iPc>1 ) break; + } + } + *piPc = iPc; + *piAddr = i; + *paOp = aOp; + return rc; +} +#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */ + + +/* +** Delete a VdbeFrame object and its contents. VdbeFrame objects are +** allocated by the OP_Program opcode in sqlite3VdbeExec(). +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ + int i; + Mem *aMem = VdbeFrameMem(p); + VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; + assert( sqlite3VdbeFrameIsValid(p) ); + for(i=0; inChildCsr; i++){ + if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]); + } + releaseMemArray(aMem, p->nChildMem); + sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); + sqlite3DbFree(p->v->db, p); +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Give a listing of the program in the virtual machine. +** +** The interface is the same as sqlite3VdbeExec(). But instead of +** running the code, it invokes the callback once for each instruction. +** This feature is used to implement "EXPLAIN". +** +** When p->explain==1, each instruction is listed. When +** p->explain==2, only OP_Explain instructions are listed and these +** are shown in a different format. p->explain==2 is used to implement +** EXPLAIN QUERY PLAN. +** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers +** are also shown, so that the boundaries between the main program and +** each trigger are clear. +** +** When p->explain==1, first the main program is listed, then each of +** the trigger subprograms are listed one by one. +*/ +SQLITE_PRIVATE int sqlite3VdbeList( + Vdbe *p /* The VDBE */ +){ + Mem *pSub = 0; /* Memory cell hold array of subprogs */ + sqlite3 *db = p->db; /* The database connection */ + int i; /* Loop counter */ + int rc = SQLITE_OK; /* Return code */ + Mem *pMem = &p->aMem[1]; /* First Mem of result set */ + int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0); + Op *aOp; /* Array of opcodes */ + Op *pOp; /* Current opcode */ + + assert( p->explain ); + assert( p->eVdbeState==VDBE_RUN_STATE ); + assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); + + /* Even though this opcode does not use dynamic strings for + ** the result, result columns may become dynamic if the user calls + ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. + */ + releaseMemArray(pMem, 8); + + if( p->rc==SQLITE_NOMEM ){ + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ + sqlite3OomFault(db); + return SQLITE_ERROR; + } + + if( bListSubprogs ){ + /* The first 8 memory cells are used for the result set. So we will + ** commandeer the 9th cell to use as storage for an array of pointers + ** to trigger subprograms. The VDBE is guaranteed to have at least 9 + ** cells. */ + assert( p->nMem>9 ); + pSub = &p->aMem[9]; + }else{ + pSub = 0; + } + + /* Figure out which opcode is next to display */ + rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp); + + if( rc==SQLITE_OK ){ + pOp = aOp + i; + if( AtomicLoad(&db->u1.isInterrupted) ){ + p->rc = SQLITE_INTERRUPT; + rc = SQLITE_ERROR; + sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); + }else{ + char *zP4 = sqlite3VdbeDisplayP4(db, pOp); + if( p->explain==2 ){ + sqlite3VdbeMemSetInt64(pMem, pOp->p1); + sqlite3VdbeMemSetInt64(pMem+1, pOp->p2); + sqlite3VdbeMemSetInt64(pMem+2, pOp->p3); + sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); + assert( p->nResColumn==4 ); + }else{ + sqlite3VdbeMemSetInt64(pMem+0, i); + sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode), + -1, SQLITE_UTF8, SQLITE_STATIC); + sqlite3VdbeMemSetInt64(pMem+2, pOp->p1); + sqlite3VdbeMemSetInt64(pMem+3, pOp->p2); + sqlite3VdbeMemSetInt64(pMem+4, pOp->p3); + /* pMem+5 for p4 is done last */ + sqlite3VdbeMemSetInt64(pMem+6, pOp->p5); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + { + char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4); + sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free); + } +#else + sqlite3VdbeMemSetNull(pMem+7); +#endif + sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); + assert( p->nResColumn==8 ); + } + p->pResultRow = pMem; + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM; + rc = SQLITE_ERROR; + }else{ + p->rc = SQLITE_OK; + rc = SQLITE_ROW; + } + } + } + return rc; +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +#ifdef SQLITE_DEBUG +/* +** Print the SQL that was used to generate a VDBE program. +*/ +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ + const char *z = 0; + if( p->zSql ){ + z = p->zSql; + }else if( p->nOp>=1 ){ + const VdbeOp *pOp = &p->aOp[0]; + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ + z = pOp->p4.z; + while( sqlite3Isspace(*z) ) z++; + } + } + if( z ) printf("SQL: [%s]\n", z); +} +#endif + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** Print an IOTRACE message showing SQL content. +*/ +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ + int nOp = p->nOp; + VdbeOp *pOp; + if( sqlite3IoTrace==0 ) return; + if( nOp<1 ) return; + pOp = &p->aOp[0]; + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ + int i, j; + char z[1000]; + sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); + for(i=0; sqlite3Isspace(z[i]); i++){} + for(j=0; z[i]; i++){ + if( sqlite3Isspace(z[i]) ){ + if( z[i-1]!=' ' ){ + z[j++] = ' '; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; + sqlite3IoTrace("SQL %s\n", z); + } +} +#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ + +/* An instance of this object describes bulk memory available for use +** by subcomponents of a prepared statement. Space is allocated out +** of a ReusableSpace object by the allocSpace() routine below. +*/ +struct ReusableSpace { + u8 *pSpace; /* Available memory */ + sqlite3_int64 nFree; /* Bytes of available memory */ + sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */ +}; + +/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf +** from the ReusableSpace object. Return a pointer to the allocated +** memory on success. If insufficient memory is available in the +** ReusableSpace object, increase the ReusableSpace.nNeeded +** value by the amount needed and return NULL. +** +** If pBuf is not initially NULL, that means that the memory has already +** been allocated by a prior call to this routine, so just return a copy +** of pBuf and leave ReusableSpace unchanged. +** +** This allocator is employed to repurpose unused slots at the end of the +** opcode array of prepared state for other memory needs of the prepared +** statement. +*/ +static void *allocSpace( + struct ReusableSpace *p, /* Bulk memory available for allocation */ + void *pBuf, /* Pointer to a prior allocation */ + sqlite3_int64 nByte /* Bytes of memory needed. */ +){ + assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); + if( pBuf==0 ){ + nByte = ROUND8P(nByte); + if( nByte <= p->nFree ){ + p->nFree -= nByte; + pBuf = &p->pSpace[p->nFree]; + }else{ + p->nNeeded += nByte; + } + } + assert( EIGHT_BYTE_ALIGNMENT(pBuf) ); + return pBuf; +} + +/* +** Rewind the VDBE back to the beginning in preparation for +** running it. +*/ +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ +#if defined(SQLITE_DEBUG) + int i; +#endif + assert( p!=0 ); + assert( p->eVdbeState==VDBE_INIT_STATE + || p->eVdbeState==VDBE_READY_STATE + || p->eVdbeState==VDBE_HALT_STATE ); + + /* There should be at least one opcode. + */ + assert( p->nOp>0 ); + + p->eVdbeState = VDBE_READY_STATE; + +#ifdef SQLITE_DEBUG + for(i=0; inMem; i++){ + assert( p->aMem[i].db==p->db ); + } +#endif + p->pc = -1; + p->rc = SQLITE_OK; + p->errorAction = OE_Abort; + p->nChange = 0; + p->cacheCtr = 1; + p->minWriteFileFormat = 255; + p->iStatement = 0; + p->nFkConstraint = 0; +#ifdef VDBE_PROFILE + for(i=0; inOp; i++){ + p->aOp[i].nExec = 0; + p->aOp[i].nCycle = 0; + } +#endif +} + +/* +** Prepare a virtual machine for execution for the first time after +** creating the virtual machine. This involves things such +** as allocating registers and initializing the program counter. +** After the VDBE has be prepped, it can be executed by one or more +** calls to sqlite3VdbeExec(). +** +** This function may be called exactly once on each virtual machine. +** After this routine is called the VM has been "packaged" and is ready +** to run. After this routine is called, further calls to +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects +** the Vdbe from the Parse object that helped generate it so that the +** the Vdbe becomes an independent entity and the Parse object can be +** destroyed. +** +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back +** to its initial state after it has been run. +*/ +SQLITE_PRIVATE void sqlite3VdbeMakeReady( + Vdbe *p, /* The VDBE */ + Parse *pParse /* Parsing context */ +){ + sqlite3 *db; /* The database connection */ + int nVar; /* Number of parameters */ + int nMem; /* Number of VM memory registers */ + int nCursor; /* Number of cursors required */ + int nArg; /* Number of arguments in subprograms */ + int n; /* Loop counter */ + struct ReusableSpace x; /* Reusable bulk memory */ + + assert( p!=0 ); + assert( p->nOp>0 ); + assert( pParse!=0 ); + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( pParse==p->pParse ); + p->pVList = pParse->pVList; + pParse->pVList = 0; + db = p->db; + assert( db->mallocFailed==0 ); + nVar = pParse->nVar; + nMem = pParse->nMem; + nCursor = pParse->nTab; + nArg = pParse->nMaxArg; + + /* Each cursor uses a memory cell. The first cursor (cursor 0) can + ** use aMem[0] which is not otherwise used by the VDBE program. Allocate + ** space at the end of aMem[] for cursors 1 and greater. + ** See also: allocateCursor(). + */ + nMem += nCursor; + if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */ + + /* Figure out how much reusable memory is available at the end of the + ** opcode array. This extra memory will be reallocated for other elements + ** of the prepared statement. + */ + n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ + x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ + assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); + x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ + assert( x.nFree>=0 ); + assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); + + resolveP2Values(p, &nArg); + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); + if( pParse->explain ){ + if( nMem<10 ) nMem = 10; + p->explain = pParse->explain; + p->nResColumn = 12 - 4*p->explain; + } + p->expired = 0; + + /* Memory for registers, parameters, cursor, etc, is allocated in one or two + ** passes. On the first pass, we try to reuse unused memory at the + ** end of the opcode array. If we are unable to satisfy all memory + ** requirements by reusing the opcode array tail, then the second + ** pass will fill in the remainder using a fresh memory allocation. + ** + ** This two-pass approach that reuses as much memory as possible from + ** the leftover memory at the end of the opcode array. This can significantly + ** reduce the amount of memory held by a prepared statement. + */ + x.nNeeded = 0; + p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); + if( x.nNeeded ){ + x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); + x.nFree = x.nNeeded; + if( !db->mallocFailed ){ + p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); + } + } + + if( db->mallocFailed ){ + p->nVar = 0; + p->nCursor = 0; + p->nMem = 0; + }else{ + p->nCursor = nCursor; + p->nVar = (ynVar)nVar; + initMemArray(p->aVar, nVar, db, MEM_Null); + p->nMem = nMem; + initMemArray(p->aMem, nMem, db, MEM_Undefined); + memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); + } + sqlite3VdbeRewind(p); +} + +/* +** Close a VDBE cursor and release all the resources that cursor +** happens to hold. +*/ +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ + if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); +} +static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){ + VdbeTxtBlbCache *pCache = pCx->pCache; + assert( pCx->colCache ); + pCx->colCache = 0; + pCx->pCache = 0; + if( pCache->pCValue ){ + sqlite3RCStrUnref(pCache->pCValue); + pCache->pCValue = 0; + } + sqlite3DbFree(p->db, pCache); + sqlite3VdbeFreeCursorNN(p, pCx); +} +SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ + if( pCx->colCache ){ + freeCursorWithCache(p, pCx); + return; + } + switch( pCx->eCurType ){ + case CURTYPE_SORTER: { + sqlite3VdbeSorterClose(p->db, pCx); + break; + } + case CURTYPE_BTREE: { + assert( pCx->uc.pCursor!=0 ); + sqlite3BtreeCloseCursor(pCx->uc.pCursor); + break; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case CURTYPE_VTAB: { + sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur; + const sqlite3_module *pModule = pVCur->pVtab->pModule; + assert( pVCur->pVtab->nRef>0 ); + pVCur->pVtab->nRef--; + pModule->xClose(pVCur); + break; + } +#endif + } +} + +/* +** Close all cursors in the current frame. +*/ +static void closeCursorsInFrame(Vdbe *p){ + int i; + for(i=0; inCursor; i++){ + VdbeCursor *pC = p->apCsr[i]; + if( pC ){ + sqlite3VdbeFreeCursorNN(p, pC); + p->apCsr[i] = 0; + } + } +} + +/* +** Copy the values stored in the VdbeFrame structure to its Vdbe. This +** is used, for example, when a trigger sub-program is halted to restore +** control to the main program. +*/ +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ + Vdbe *v = pFrame->v; + closeCursorsInFrame(v); + v->aOp = pFrame->aOp; + v->nOp = pFrame->nOp; + v->aMem = pFrame->aMem; + v->nMem = pFrame->nMem; + v->apCsr = pFrame->apCsr; + v->nCursor = pFrame->nCursor; + v->db->lastRowid = pFrame->lastRowid; + v->nChange = pFrame->nChange; + v->db->nChange = pFrame->nDbChange; + sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0); + v->pAuxData = pFrame->pAuxData; + pFrame->pAuxData = 0; + return pFrame->pc; +} + +/* +** Close all cursors. +** +** Also release any dynamic memory held by the VM in the Vdbe.aMem memory +** cell array. This is necessary as the memory cell array may contain +** pointers to VdbeFrame objects, which may in turn contain pointers to +** open cursors. +*/ +static void closeAllCursors(Vdbe *p){ + if( p->pFrame ){ + VdbeFrame *pFrame; + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + sqlite3VdbeFrameRestore(pFrame); + p->pFrame = 0; + p->nFrame = 0; + } + assert( p->nFrame==0 ); + closeCursorsInFrame(p); + releaseMemArray(p->aMem, p->nMem); + while( p->pDelFrame ){ + VdbeFrame *pDel = p->pDelFrame; + p->pDelFrame = pDel->pParent; + sqlite3VdbeFrameDelete(pDel); + } + + /* Delete any auxdata allocations made by the VM */ + if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0); + assert( p->pAuxData==0 ); +} + +/* +** Set the number of result columns that will be returned by this SQL +** statement. This is now set at compile time, rather than during +** execution of the vdbe program so that sqlite3_column_count() can +** be called on an SQL statement before sqlite3_step(). +*/ +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ + int n; + sqlite3 *db = p->db; + + if( p->nResAlloc ){ + releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); + sqlite3DbFree(db, p->aColName); + } + n = nResColumn*COLNAME_N; + p->nResColumn = p->nResAlloc = (u16)nResColumn; + p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); + if( p->aColName==0 ) return; + initMemArray(p->aColName, n, db, MEM_Null); +} + +/* +** Set the name of the idx'th column to be returned by the SQL statement. +** zName must be a pointer to a nul terminated string. +** +** This call must be made after a call to sqlite3VdbeSetNumCols(). +** +** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC +** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed +** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed. +*/ +SQLITE_PRIVATE int sqlite3VdbeSetColName( + Vdbe *p, /* Vdbe being configured */ + int idx, /* Index of column zName applies to */ + int var, /* One of the COLNAME_* constants */ + const char *zName, /* Pointer to buffer containing name */ + void (*xDel)(void*) /* Memory management strategy for zName */ +){ + int rc; + Mem *pColName; + assert( idxnResAlloc ); + assert( vardb->mallocFailed ){ + assert( !zName || xDel!=SQLITE_DYNAMIC ); + return SQLITE_NOMEM_BKPT; + } + assert( p->aColName!=0 ); + pColName = &(p->aColName[idx+var*p->nResAlloc]); + rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); + assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); + return rc; +} + +/* +** A read or write transaction may or may not be active on database handle +** db. If a transaction is active, commit it. If there is a +** write-transaction spanning more than one database file, this routine +** takes care of the super-journal trickery. +*/ +static int vdbeCommit(sqlite3 *db, Vdbe *p){ + int i; + int nTrans = 0; /* Number of databases with an active write-transaction + ** that are candidates for a two-phase commit using a + ** super-journal */ + int rc = SQLITE_OK; + int needXcommit = 0; + +#ifdef SQLITE_OMIT_VIRTUALTABLE + /* With this option, sqlite3VtabSync() is defined to be simply + ** SQLITE_OK so p is not used. + */ + UNUSED_PARAMETER(p); +#endif + + /* Before doing anything else, call the xSync() callback for any + ** virtual module tables written in this transaction. This has to + ** be done before determining whether a super-journal file is + ** required, as an xSync() callback may add an attached database + ** to the transaction. + */ + rc = sqlite3VtabSync(db, p); + + /* This loop determines (a) if the commit hook should be invoked and + ** (b) how many database files have open write transactions, not + ** including the temp database. (b) is important because if more than + ** one database file has an open write transaction, a super-journal + ** file is required for an atomic commit. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ + /* Whether or not a database might need a super-journal depends upon + ** its journal mode (among other things). This matrix determines which + ** journal modes use a super-journal and which do not */ + static const u8 aMJNeeded[] = { + /* DELETE */ 1, + /* PERSIST */ 1, + /* OFF */ 0, + /* TRUNCATE */ 1, + /* MEMORY */ 0, + /* WAL */ 0 + }; + Pager *pPager; /* Pager associated with pBt */ + needXcommit = 1; + sqlite3BtreeEnter(pBt); + pPager = sqlite3BtreePager(pBt); + if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF + && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] + && sqlite3PagerIsMemdb(pPager)==0 + ){ + assert( i!=1 ); + nTrans++; + } + rc = sqlite3PagerExclusiveLock(pPager); + sqlite3BtreeLeave(pBt); + } + } + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If there are any write-transactions at all, invoke the commit hook */ + if( needXcommit && db->xCommitCallback ){ + rc = db->xCommitCallback(db->pCommitArg); + if( rc ){ + return SQLITE_CONSTRAINT_COMMITHOOK; + } + } + + /* The simple case - no more than one database file (not counting the + ** TEMP database) has a transaction active. There is no need for the + ** super-journal. + ** + ** If the return value of sqlite3BtreeGetFilename() is a zero length + ** string, it means the main database is :memory: or a temp file. In + ** that case we do not support atomic multi-file commits, so use the + ** simple case then too. + */ + if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) + || nTrans<=1 + ){ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseOne(pBt, 0); + } + } + + /* Do the commit only if all databases successfully complete phase 1. + ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an + ** IO error while deleting or truncating a journal file. It is unlikely, + ** but could happen. In this case abandon processing and return the error. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); + } + } + if( rc==SQLITE_OK ){ + sqlite3VtabCommit(db); + } + } + + /* The complex case - There is a multi-file write-transaction active. + ** This requires a super-journal file to ensure the transaction is + ** committed atomically. + */ +#ifndef SQLITE_OMIT_DISKIO + else{ + sqlite3_vfs *pVfs = db->pVfs; + char *zSuper = 0; /* File-name for the super-journal */ + char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); + sqlite3_file *pSuperJrnl = 0; + i64 offset = 0; + int res; + int retryCount = 0; + int nMainFile; + + /* Select a super-journal file name */ + nMainFile = sqlite3Strlen30(zMainFile); + zSuper = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0); + if( zSuper==0 ) return SQLITE_NOMEM_BKPT; + zSuper += 4; + do { + u32 iRandom; + if( retryCount ){ + if( retryCount>100 ){ + sqlite3_log(SQLITE_FULL, "MJ delete: %s", zSuper); + sqlite3OsDelete(pVfs, zSuper, 0); + break; + }else if( retryCount==1 ){ + sqlite3_log(SQLITE_FULL, "MJ collide: %s", zSuper); + } + } + retryCount++; + sqlite3_randomness(sizeof(iRandom), &iRandom); + sqlite3_snprintf(13, &zSuper[nMainFile], "-mj%06X9%02X", + (iRandom>>8)&0xffffff, iRandom&0xff); + /* The antipenultimate character of the super-journal name must + ** be "9" to avoid name collisions when using 8+3 filenames. */ + assert( zSuper[sqlite3Strlen30(zSuper)-3]=='9' ); + sqlite3FileSuffix3(zMainFile, zSuper); + rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); + }while( rc==SQLITE_OK && res ); + if( rc==SQLITE_OK ){ + /* Open the super-journal. */ + rc = sqlite3OsOpenMalloc(pVfs, zSuper, &pSuperJrnl, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_SUPER_JOURNAL, 0 + ); + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, zSuper-4); + return rc; + } + + /* Write the name of each database file in the transaction into the new + ** super-journal file. If an error occurs at this point close + ** and delete the super-journal file. All the individual journal files + ** still have 'null' as the super-journal pointer, so they will roll + ** back independently if a failure occurs. + */ + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ + char const *zFile = sqlite3BtreeGetJournalname(pBt); + if( zFile==0 ){ + continue; /* Ignore TEMP and :memory: databases */ + } + assert( zFile[0]!=0 ); + rc = sqlite3OsWrite(pSuperJrnl, zFile, sqlite3Strlen30(zFile)+1,offset); + offset += sqlite3Strlen30(zFile)+1; + if( rc!=SQLITE_OK ){ + sqlite3OsCloseFree(pSuperJrnl); + sqlite3OsDelete(pVfs, zSuper, 0); + sqlite3DbFree(db, zSuper-4); + return rc; + } + } + } + + /* Sync the super-journal file. If the IOCAP_SEQUENTIAL device + ** flag is set this is not required. + */ + if( 0==(sqlite3OsDeviceCharacteristics(pSuperJrnl)&SQLITE_IOCAP_SEQUENTIAL) + && SQLITE_OK!=(rc = sqlite3OsSync(pSuperJrnl, SQLITE_SYNC_NORMAL)) + ){ + sqlite3OsCloseFree(pSuperJrnl); + sqlite3OsDelete(pVfs, zSuper, 0); + sqlite3DbFree(db, zSuper-4); + return rc; + } + + /* Sync all the db files involved in the transaction. The same call + ** sets the super-journal pointer in each individual journal. If + ** an error occurs here, do not delete the super-journal file. + ** + ** If the error occurs during the first call to + ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the + ** super-journal file will be orphaned. But we cannot delete it, + ** in case the super-journal file name was written into the journal + ** file before the failure occurred. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseOne(pBt, zSuper); + } + } + sqlite3OsCloseFree(pSuperJrnl); + assert( rc!=SQLITE_BUSY ); + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, zSuper-4); + return rc; + } + + /* Delete the super-journal file. This commits the transaction. After + ** doing this the directory is synced again before any individual + ** transaction files are deleted. + */ + rc = sqlite3OsDelete(pVfs, zSuper, 1); + sqlite3DbFree(db, zSuper-4); + zSuper = 0; + if( rc ){ + return rc; + } + + /* All files and directories have already been synced, so the following + ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and + ** deleting or truncating journals. If something goes wrong while + ** this is happening we don't really care. The integrity of the + ** transaction is already guaranteed, but some stray 'cold' journals + ** may be lying around. Returning an error code won't help matters. + */ + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + sqlite3BtreeCommitPhaseTwo(pBt, 1); + } + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + + sqlite3VtabCommit(db); + } +#endif + + return rc; +} + +/* +** This routine checks that the sqlite3.nVdbeActive count variable +** matches the number of vdbe's in the list sqlite3.pVdbe that are +** currently active. An assertion fails if the two counts do not match. +** This is an internal self-check only - it is not an essential processing +** step. +** +** This is a no-op if NDEBUG is defined. +*/ +#ifndef NDEBUG +static void checkActiveVdbeCnt(sqlite3 *db){ + Vdbe *p; + int cnt = 0; + int nWrite = 0; + int nRead = 0; + p = db->pVdbe; + while( p ){ + if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ + cnt++; + if( p->readOnly==0 ) nWrite++; + if( p->bIsReader ) nRead++; + } + p = p->pVNext; + } + assert( cnt==db->nVdbeActive ); + assert( nWrite==db->nVdbeWrite ); + assert( nRead==db->nVdbeRead ); +} +#else +#define checkActiveVdbeCnt(x) +#endif + +/* +** If the Vdbe passed as the first argument opened a statement-transaction, +** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or +** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement +** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the +** statement transaction is committed. +** +** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. +** Otherwise SQLITE_OK. +*/ +static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ + sqlite3 *const db = p->db; + int rc = SQLITE_OK; + int i; + const int iSavepoint = p->iStatement-1; + + assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE); + assert( db->nStatement>0 ); + assert( p->iStatement==(db->nStatement+db->nSavepoint) ); + + for(i=0; inDb; i++){ + int rc2 = SQLITE_OK; + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc2==SQLITE_OK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + db->nStatement--; + p->iStatement = 0; + + if( rc==SQLITE_OK ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + } + } + + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when + ** the statement transaction was opened. */ + if( eOp==SAVEPOINT_ROLLBACK ){ + db->nDeferredCons = p->nStmtDefCons; + db->nDeferredImmCons = p->nStmtDefImmCons; + } + return rc; +} +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ + if( p->db->nStatement && p->iStatement ){ + return vdbeCloseStatement(p, eOp); + } + return SQLITE_OK; +} + + +/* +** This function is called when a transaction opened by the database +** handle associated with the VM passed as an argument is about to be +** committed. If there are outstanding deferred foreign key constraint +** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. +** +** If there are outstanding FK violations and this function returns +** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY +** and write an error message to it. Then return SQLITE_ERROR. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ + sqlite3 *db = p->db; + if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) + || (!deferred && p->nFkConstraint>0) + ){ + p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; + p->errorAction = OE_Abort; + sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR; + return SQLITE_CONSTRAINT_FOREIGNKEY; + } + return SQLITE_OK; +} +#endif + +/* +** This routine is called the when a VDBE tries to halt. If the VDBE +** has made changes and is in autocommit mode, then commit those +** changes. If a rollback is needed, then do the rollback. +** +** This routine is the only way to move the sqlite3eOpenState of a VM from +** SQLITE_STATE_RUN to SQLITE_STATE_HALT. It is harmless to +** call this on a VM that is in the SQLITE_STATE_HALT state. +** +** Return an error code. If the commit could not complete because of +** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it +** means the close did not happen and needs to be repeated. +*/ +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ + int rc; /* Used to store transient return codes */ + sqlite3 *db = p->db; + + /* This function contains the logic that determines if a statement or + ** transaction will be committed or rolled back as a result of the + ** execution of this virtual machine. + ** + ** If any of the following errors occur: + ** + ** SQLITE_NOMEM + ** SQLITE_IOERR + ** SQLITE_FULL + ** SQLITE_INTERRUPT + ** + ** Then the internal cache might have been left in an inconsistent + ** state. We need to rollback the statement transaction, if there is + ** one, or the complete transaction if there is no statement transaction. + */ + + assert( p->eVdbeState==VDBE_RUN_STATE ); + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM_BKPT; + } + closeAllCursors(p); + checkActiveVdbeCnt(db); + + /* No commit or rollback needed if the program never started or if the + ** SQL statement does not read or write a database file. */ + if( p->bIsReader ){ + int mrc; /* Primary error code from p->rc */ + int eStatementOp = 0; + int isSpecialError; /* Set to true if a 'special' error */ + + /* Lock all btrees used by the statement */ + sqlite3VdbeEnter(p); + + /* Check for one of the special errors */ + if( p->rc ){ + mrc = p->rc & 0xff; + isSpecialError = mrc==SQLITE_NOMEM + || mrc==SQLITE_IOERR + || mrc==SQLITE_INTERRUPT + || mrc==SQLITE_FULL; + }else{ + mrc = isSpecialError = 0; + } + if( isSpecialError ){ + /* If the query was read-only and the error code is SQLITE_INTERRUPT, + ** no rollback is necessary. Otherwise, at least a savepoint + ** transaction must be rolled back to restore the database to a + ** consistent state. + ** + ** Even if the statement is read-only, it is important to perform + ** a statement or transaction rollback operation. If the error + ** occurred while writing to the journal, sub-journal or database + ** file as part of an effort to free up cache space (see function + ** pagerStress() in pager.c), the rollback is required to restore + ** the pager to a consistent state. + */ + if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ + if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ + eStatementOp = SAVEPOINT_ROLLBACK; + }else{ + /* We are forced to roll back the active transaction. Before doing + ** so, abort any other statements this handle currently has active. + */ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + } + + /* Check for immediate foreign key violations. */ + if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ + sqlite3VdbeCheckFk(p, 0); + } + + /* If the auto-commit flag is set and this is the only active writer + ** VM, then we do either a commit or rollback of the current transaction. + ** + ** Note: This block also runs if one of the special errors handled + ** above has occurred. + */ + if( !sqlite3VtabInSync(db) + && db->autoCommit + && db->nVdbeWrite==(p->readOnly==0) + ){ + if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ + rc = sqlite3VdbeCheckFk(p, 1); + if( rc!=SQLITE_OK ){ + if( NEVER(p->readOnly) ){ + sqlite3VdbeLeave(p); + return SQLITE_ERROR; + } + rc = SQLITE_CONSTRAINT_FOREIGNKEY; + }else if( db->flags & SQLITE_CorruptRdOnly ){ + rc = SQLITE_CORRUPT; + db->flags &= ~SQLITE_CorruptRdOnly; + }else{ + /* The auto-commit flag is true, the vdbe program was successful + ** or hit an 'OR FAIL' constraint and there are no deferred foreign + ** key constraints to hold up the transaction. This means a commit + ** is required. */ + rc = vdbeCommit(db, p); + } + if( rc==SQLITE_BUSY && p->readOnly ){ + sqlite3VdbeLeave(p); + return SQLITE_BUSY; + }else if( rc!=SQLITE_OK ){ + sqlite3SystemError(db, rc); + p->rc = rc; + sqlite3RollbackAll(db, SQLITE_OK); + p->nChange = 0; + }else{ + db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~(u64)SQLITE_DeferFKs; + sqlite3CommitInternalChanges(db); + } + }else if( p->rc==SQLITE_SCHEMA && db->nVdbeActive>1 ){ + p->nChange = 0; + }else{ + sqlite3RollbackAll(db, SQLITE_OK); + p->nChange = 0; + } + db->nStatement = 0; + }else if( eStatementOp==0 ){ + if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ + eStatementOp = SAVEPOINT_RELEASE; + }else if( p->errorAction==OE_Abort ){ + eStatementOp = SAVEPOINT_ROLLBACK; + }else{ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + + /* If eStatementOp is non-zero, then a statement transaction needs to + ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to + ** do so. If this operation returns an error, and the current statement + ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the + ** current statement error code. + */ + if( eStatementOp ){ + rc = sqlite3VdbeCloseStatement(p, eStatementOp); + if( rc ){ + if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){ + p->rc = rc; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + + /* If this was an INSERT, UPDATE or DELETE and no statement transaction + ** has been rolled back, update the database connection change-counter. + */ + if( p->changeCntOn ){ + if( eStatementOp!=SAVEPOINT_ROLLBACK ){ + sqlite3VdbeSetChanges(db, p->nChange); + }else{ + sqlite3VdbeSetChanges(db, 0); + } + p->nChange = 0; + } + + /* Release the locks */ + sqlite3VdbeLeave(p); + } + + /* We have successfully halted and closed the VM. Record this fact. */ + db->nVdbeActive--; + if( !p->readOnly ) db->nVdbeWrite--; + if( p->bIsReader ) db->nVdbeRead--; + assert( db->nVdbeActive>=db->nVdbeRead ); + assert( db->nVdbeRead>=db->nVdbeWrite ); + assert( db->nVdbeWrite>=0 ); + p->eVdbeState = VDBE_HALT_STATE; + checkActiveVdbeCnt(db); + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM_BKPT; + } + + /* If the auto-commit flag is set to true, then any locks that were held + ** by connection db have now been released. Call sqlite3ConnectionUnlocked() + ** to invoke any required unlock-notify callbacks. + */ + if( db->autoCommit ){ + sqlite3ConnectionUnlocked(db); + } + + assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); + return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); +} + + +/* +** Each VDBE holds the result of the most recent sqlite3_step() call +** in p->rc. This routine sets that result back to SQLITE_OK. +*/ +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){ + p->rc = SQLITE_OK; +} + +/* +** Copy the error code and error message belonging to the VDBE passed +** as the first argument to its database handle (so that they will be +** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). +** +** This function does not clear the VDBE error code or message, just +** copies them to the database handle. +*/ +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ + sqlite3 *db = p->db; + int rc = p->rc; + if( p->zErrMsg ){ + db->bBenignMalloc++; + sqlite3BeginBenignMalloc(); + if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); + sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); + sqlite3EndBenignMalloc(); + db->bBenignMalloc--; + }else if( db->pErr ){ + sqlite3ValueSetNull(db->pErr); + } + db->errCode = rc; + db->errByteOffset = -1; + return rc; +} + +#ifdef SQLITE_ENABLE_SQLLOG +/* +** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, +** invoke it. +*/ +static void vdbeInvokeSqllog(Vdbe *v){ + if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){ + char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql); + assert( v->db->init.busy==0 ); + if( zExpanded ){ + sqlite3GlobalConfig.xSqllog( + sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1 + ); + sqlite3DbFree(v->db, zExpanded); + } + } +} +#else +# define vdbeInvokeSqllog(x) +#endif + +/* +** Clean up a VDBE after execution but do not delete the VDBE just yet. +** Write any error messages into *pzErrMsg. Return the result code. +** +** After this routine is run, the VDBE should be ready to be executed +** again. +** +** To look at it another way, this routine resets the state of the +** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to +** VDBE_READY_STATE. +*/ +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + int i; +#endif + + sqlite3 *db; + db = p->db; + + /* If the VM did not run to completion or if it encountered an + ** error, then it might not have been halted properly. So halt + ** it now. + */ + if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); + + /* If the VDBE has been run even partially, then transfer the error code + ** and error message from the VDBE into the main database structure. But + ** if the VDBE has just been set to run but has not actually executed any + ** instructions yet, leave the main database error information unchanged. + */ + if( p->pc>=0 ){ + vdbeInvokeSqllog(p); + if( db->pErr || p->zErrMsg ){ + sqlite3VdbeTransferError(p); + }else{ + db->errCode = p->rc; + } + } + + /* Reset register contents and reclaim error message memory. + */ +#ifdef SQLITE_DEBUG + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + ** Vdbe.aMem[] arrays have already been cleaned up. */ + if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); + if( p->aMem ){ + for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); + } +#endif + if( p->zErrMsg ){ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + p->pResultRow = 0; +#ifdef SQLITE_DEBUG + p->nWrite = 0; +#endif + + /* Save profiling information from this VDBE run. + */ +#ifdef VDBE_PROFILE + { + FILE *out = fopen("vdbe_profile.out", "a"); + if( out ){ + fprintf(out, "---- "); + for(i=0; inOp; i++){ + fprintf(out, "%02x", p->aOp[i].opcode); + } + fprintf(out, "\n"); + if( p->zSql ){ + char c, pc = 0; + fprintf(out, "-- "); + for(i=0; (c = p->zSql[i])!=0; i++){ + if( pc=='\n' ) fprintf(out, "-- "); + putc(c, out); + pc = c; + } + if( pc!='\n' ) fprintf(out, "\n"); + } + for(i=0; inOp; i++){ + char zHdr[100]; + i64 cnt = p->aOp[i].nExec; + i64 cycles = p->aOp[i].nCycle; + sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", + cnt, + cycles, + cnt>0 ? cycles/cnt : 0 + ); + fprintf(out, "%s", zHdr); + sqlite3VdbePrintOp(out, i, &p->aOp[i]); + } + fclose(out); + } + } +#endif + return p->rc & db->errMask; +} + +/* +** Clean up and delete a VDBE after execution. Return an integer which is +** the result code. Write any error message text into *pzErrMsg. +*/ +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ + int rc = SQLITE_OK; + assert( VDBE_RUN_STATE>VDBE_READY_STATE ); + assert( VDBE_HALT_STATE>VDBE_READY_STATE ); + assert( VDBE_INIT_STATEeVdbeState>=VDBE_READY_STATE ){ + rc = sqlite3VdbeReset(p); + assert( (rc & p->db->errMask)==rc ); + } + sqlite3VdbeDelete(p); + return rc; +} + +/* +** If parameter iOp is less than zero, then invoke the destructor for +** all auxiliary data pointers currently cached by the VM passed as +** the first argument. +** +** Or, if iOp is greater than or equal to zero, then the destructor is +** only invoked for those auxiliary data pointers created by the user +** function invoked by the OP_Function opcode at instruction iOp of +** VM pVdbe, and only then if: +** +** * the associated function parameter is the 32nd or later (counting +** from left to right), or +** +** * the corresponding bit in argument mask is clear (where the first +** function parameter corresponds to bit 0 etc.). +*/ +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ + while( *pp ){ + AuxData *pAux = *pp; + if( (iOp<0) + || (pAux->iAuxOp==iOp + && pAux->iAuxArg>=0 + && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg)))) + ){ + testcase( pAux->iAuxArg==31 ); + if( pAux->xDeleteAux ){ + pAux->xDeleteAux(pAux->pAux); + } + *pp = pAux->pNextAux; + sqlite3DbFree(db, pAux); + }else{ + pp= &pAux->pNextAux; + } + } +} + +/* +** Free all memory associated with the Vdbe passed as the second argument, +** except for object itself, which is preserved. +** +** The difference between this function and sqlite3VdbeDelete() is that +** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with +** the database connection and frees the object itself. +*/ +static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ + SubProgram *pSub, *pNext; + assert( db!=0 ); + assert( p->db==0 || p->db==db ); + if( p->aColName ){ + releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); + sqlite3DbNNFreeNN(db, p->aColName); + } + for(pSub=p->pProgram; pSub; pSub=pNext){ + pNext = pSub->pNext; + vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); + sqlite3DbFree(db, pSub); + } + if( p->eVdbeState!=VDBE_INIT_STATE ){ + releaseMemArray(p->aVar, p->nVar); + if( p->pVList ) sqlite3DbNNFreeNN(db, p->pVList); + if( p->pFree ) sqlite3DbNNFreeNN(db, p->pFree); + } + vdbeFreeOpArray(db, p->aOp, p->nOp); + if( p->zSql ) sqlite3DbNNFreeNN(db, p->zSql); +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3DbFree(db, p->zNormSql); + { + DblquoteStr *pThis, *pNxt; + for(pThis=p->pDblStr; pThis; pThis=pNxt){ + pNxt = pThis->pNextStr; + sqlite3DbFree(db, pThis); + } + } +#endif +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + { + int i; + for(i=0; inScan; i++){ + sqlite3DbFree(db, p->aScan[i].zName); + } + sqlite3DbFree(db, p->aScan); + } +#endif +} + +/* +** Delete an entire VDBE. +*/ +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ + sqlite3 *db; + + assert( p!=0 ); + db = p->db; + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3VdbeClearObject(db, p); + if( db->pnBytesFreed==0 ){ + assert( p->ppVPrev!=0 ); + *p->ppVPrev = p->pVNext; + if( p->pVNext ){ + p->pVNext->ppVPrev = p->ppVPrev; + } + } + sqlite3DbNNFreeNN(db, p); +} + +/* +** The cursor "p" has a pending seek operation that has not yet been +** carried out. Seek the cursor now. If an error occurs, return +** the appropriate error code. +*/ +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){ + int res, rc; +#ifdef SQLITE_TEST + extern int sqlite3_search_count; +#endif + assert( p->deferredMoveto ); + assert( p->isTable ); + assert( p->eCurType==CURTYPE_BTREE ); + rc = sqlite3BtreeTableMoveto(p->uc.pCursor, p->movetoTarget, 0, &res); + if( rc ) return rc; + if( res!=0 ) return SQLITE_CORRUPT_BKPT; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + p->deferredMoveto = 0; + p->cacheStatus = CACHE_STALE; + return SQLITE_OK; +} + +/* +** Something has moved cursor "p" out of place. Maybe the row it was +** pointed to was deleted out from under it. Or maybe the btree was +** rebalanced. Whatever the cause, try to restore "p" to the place it +** is supposed to be pointing. If the row was deleted out from under the +** cursor, set the cursor to point to a NULL row. +*/ +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){ + int isDifferentRow, rc; + assert( p->eCurType==CURTYPE_BTREE ); + assert( p->uc.pCursor!=0 ); + assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); + rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); + p->cacheStatus = CACHE_STALE; + if( isDifferentRow ) p->nullRow = 1; + return rc; +} + +/* +** Check to ensure that the cursor is valid. Restore the cursor +** if need be. Return any I/O error from the restore operation. +*/ +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ + assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) ); + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return sqlite3VdbeHandleMovedCursor(p); + } + return SQLITE_OK; +} + +/* +** The following functions: +** +** sqlite3VdbeSerialType() +** sqlite3VdbeSerialTypeLen() +** sqlite3VdbeSerialLen() +** sqlite3VdbeSerialPut() <--- in-lined into OP_MakeRecord as of 2022-04-02 +** sqlite3VdbeSerialGet() +** +** encapsulate the code that serializes values for storage in SQLite +** data and index records. Each serialized value consists of a +** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned +** integer, stored as a varint. +** +** In an SQLite index record, the serial type is stored directly before +** the blob of data that it corresponds to. In a table record, all serial +** types are stored at the start of the record, and the blobs of data at +** the end. Hence these functions allow the caller to handle the +** serial-type and data blob separately. +** +** The following table describes the various storage classes for data: +** +** serial type bytes of data type +** -------------- --------------- --------------- +** 0 0 NULL +** 1 1 signed integer +** 2 2 signed integer +** 3 3 signed integer +** 4 4 signed integer +** 5 6 signed integer +** 6 8 signed integer +** 7 8 IEEE float +** 8 0 Integer constant 0 +** 9 0 Integer constant 1 +** 10,11 reserved for expansion +** N>=12 and even (N-12)/2 BLOB +** N>=13 and odd (N-13)/2 text +** +** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions +** of SQLite will not understand those serial types. +*/ + +#if 0 /* Inlined into the OP_MakeRecord opcode */ +/* +** Return the serial-type for the value stored in pMem. +** +** This routine might convert a large MEM_IntReal value into MEM_Real. +** +** 2019-07-11: The primary user of this subroutine was the OP_MakeRecord +** opcode in the byte-code engine. But by moving this routine in-line, we +** can omit some redundant tests and make that opcode a lot faster. So +** this routine is now only used by the STAT3 logic and STAT3 support has +** ended. The code is kept here for historical reference only. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ + int flags = pMem->flags; + u32 n; + + assert( pLen!=0 ); + if( flags&MEM_Null ){ + *pLen = 0; + return 0; + } + if( flags&(MEM_Int|MEM_IntReal) ){ + /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ +# define MAX_6BYTE ((((i64)0x00008000)<<32)-1) + i64 i = pMem->u.i; + u64 u; + testcase( flags & MEM_Int ); + testcase( flags & MEM_IntReal ); + if( i<0 ){ + u = ~i; + }else{ + u = i; + } + if( u<=127 ){ + if( (i&1)==i && file_format>=4 ){ + *pLen = 0; + return 8+(u32)u; + }else{ + *pLen = 1; + return 1; + } + } + if( u<=32767 ){ *pLen = 2; return 2; } + if( u<=8388607 ){ *pLen = 3; return 3; } + if( u<=2147483647 ){ *pLen = 4; return 4; } + if( u<=MAX_6BYTE ){ *pLen = 6; return 5; } + *pLen = 8; + if( flags&MEM_IntReal ){ + /* If the value is IntReal and is going to take up 8 bytes to store + ** as an integer, then we might as well make it an 8-byte floating + ** point value */ + pMem->u.r = (double)pMem->u.i; + pMem->flags &= ~MEM_IntReal; + pMem->flags |= MEM_Real; + return 7; + } + return 6; + } + if( flags&MEM_Real ){ + *pLen = 8; + return 7; + } + assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); + assert( pMem->n>=0 ); + n = (u32)pMem->n; + if( flags & MEM_Zero ){ + n += pMem->u.nZero; + } + *pLen = n; + return ((n*2) + 12 + ((flags&MEM_Str)!=0)); +} +#endif /* inlined into OP_MakeRecord */ + +/* +** The sizes for serial types less than 128 +*/ +SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[128] = { + /* 0 1 2 3 4 5 6 7 8 9 */ +/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, +/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, +/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, +/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, +/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, +/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, +/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, +/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, +/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, +/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, +/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, +/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, +/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57 +}; + +/* +** Return the length of the data corresponding to the supplied serial-type. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ + if( serial_type>=128 ){ + return (serial_type-12)/2; + }else{ + assert( serial_type<12 + || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); + return sqlite3SmallTypeSizes[serial_type]; + } +} +SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ + assert( serial_type<128 ); + return sqlite3SmallTypeSizes[serial_type]; +} + +/* +** If we are on an architecture with mixed-endian floating +** points (ex: ARM7) then swap the lower 4 bytes with the +** upper 4 bytes. Return the result. +** +** For most architectures, this is a no-op. +** +** (later): It is reported to me that the mixed-endian problem +** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems +** that early versions of GCC stored the two words of a 64-bit +** float in the wrong order. And that error has been propagated +** ever since. The blame is not necessarily with GCC, though. +** GCC might have just copying the problem from a prior compiler. +** I am also told that newer versions of GCC that follow a different +** ABI get the byte order right. +** +** Developers using SQLite on an ARM7 should compile and run their +** application using -DSQLITE_DEBUG=1 at least once. With DEBUG +** enabled, some asserts below will ensure that the byte order of +** floating point values is correct. +** +** (2007-08-30) Frank van Vugt has studied this problem closely +** and has send his findings to the SQLite developers. Frank +** writes that some Linux kernels offer floating point hardware +** emulation that uses only 32-bit mantissas instead of a full +** 48-bits as required by the IEEE standard. (This is the +** CONFIG_FPE_FASTFPE option.) On such systems, floating point +** byte swapping becomes very complicated. To avoid problems, +** the necessary byte swapping is carried out using a 64-bit integer +** rather than a 64-bit float. Frank assures us that the code here +** works for him. We, the developers, have no way to independently +** verify this, but Frank seems to know what he is talking about +** so we trust him. +*/ +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){ + union { + u64 r; + u32 i[2]; + } u; + u32 t; + + u.r = in; + t = u.i[0]; + u.i[0] = u.i[1]; + u.i[1] = t; + return u.r; +} +#endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */ + + +/* Input "x" is a sequence of unsigned characters that represent a +** big-endian integer. Return the equivalent native integer +*/ +#define ONE_BYTE_INT(x) ((i8)(x)[0]) +#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) +#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) +#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) +#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) + +/* +** Deserialize the data blob pointed to by buf as serial type serial_type +** and store the result in pMem. +** +** This function is implemented as two separate routines for performance. +** The few cases that require local variables are broken out into a separate +** routine so that in most cases the overhead of moving the stack pointer +** is avoided. +*/ +static void serialGet( + const unsigned char *buf, /* Buffer to deserialize from */ + u32 serial_type, /* Serial type to deserialize */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + if( serial_type==6 ){ + /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit + ** twos-complement integer. */ + pMem->u.i = *(i64*)&x; + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + }else{ + /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit + ** floating point number. */ +#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) + /* Verify that integers and floating point values use the same + ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is + ** defined that 64-bit floating point values really are mixed + ** endian. + */ + static const u64 t1 = ((u64)0x3ff00000)<<32; + static const double r1 = 1.0; + u64 t2 = t1; + swapMixedEndianFloat(t2); + assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); +#endif + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; + } +} +static int serialGet7( + const unsigned char *buf, /* Buffer to deserialize from */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + if( IsNaN(x) ){ + pMem->flags = MEM_Null; + return 1; + } + pMem->flags = MEM_Real; + return 0; +} +SQLITE_PRIVATE void sqlite3VdbeSerialGet( + const unsigned char *buf, /* Buffer to deserialize from */ + u32 serial_type, /* Serial type to deserialize */ + Mem *pMem /* Memory cell to write value into */ +){ + switch( serial_type ){ + case 10: { /* Internal use only: NULL with virtual table + ** UPDATE no-change flag set */ + pMem->flags = MEM_Null|MEM_Zero; + pMem->n = 0; + pMem->u.nZero = 0; + return; + } + case 11: /* Reserved for future use */ + case 0: { /* Null */ + /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ + pMem->flags = MEM_Null; + return; + } + case 1: { + /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement + ** integer. */ + pMem->u.i = ONE_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 2: { /* 2-byte signed integer */ + /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit + ** twos-complement integer. */ + pMem->u.i = TWO_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 3: { /* 3-byte signed integer */ + /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit + ** twos-complement integer. */ + pMem->u.i = THREE_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 4: { /* 4-byte signed integer */ + /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit + ** twos-complement integer. */ + pMem->u.i = FOUR_BYTE_INT(buf); +#ifdef __HP_cc + /* Work around a sign-extension bug in the HP compiler for HP/UX */ + if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL; +#endif + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 5: { /* 6-byte signed integer */ + /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit + ** twos-complement integer. */ + pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 6: /* 8-byte signed integer */ + case 7: { /* IEEE floating point */ + /* These use local variables, so do them in a separate routine + ** to avoid having to move the frame pointer in the common case */ + serialGet(buf,serial_type,pMem); + return; + } + case 8: /* Integer 0 */ + case 9: { /* Integer 1 */ + /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */ + /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ + pMem->u.i = serial_type-8; + pMem->flags = MEM_Int; + return; + } + default: { + /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in + ** length. + ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and + ** (N-13)/2 bytes in length. */ + static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; + pMem->z = (char *)buf; + pMem->n = (serial_type-12)/2; + pMem->flags = aFlag[serial_type&1]; + return; + } + } + return; +} +/* +** This routine is used to allocate sufficient space for an UnpackedRecord +** structure large enough to be used with sqlite3VdbeRecordUnpack() if +** the first argument is a pointer to KeyInfo structure pKeyInfo. +** +** The space is either allocated using sqlite3DbMallocRaw() or from within +** the unaligned buffer passed via the second and third arguments (presumably +** stack space). If the former, then *ppFree is set to a pointer that should +** be eventually freed by the caller using sqlite3DbFree(). Or, if the +** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL +** before returning. +** +** If an OOM error occurs, NULL is returned. +*/ +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( + KeyInfo *pKeyInfo /* Description of the record */ +){ + UnpackedRecord *p; /* Unpacked record to return */ + int nByte; /* Number of bytes required for *p */ + nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); + if( !p ) return 0; + p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; + assert( pKeyInfo->aSortFlags!=0 ); + p->pKeyInfo = pKeyInfo; + p->nField = pKeyInfo->nKeyField + 1; + return p; +} + +/* +** Given the nKey-byte encoding of a record in pKey[], populate the +** UnpackedRecord structure indicated by the fourth argument with the +** contents of the decoded record. +*/ +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( + KeyInfo *pKeyInfo, /* Information about the record format */ + int nKey, /* Size of the binary record */ + const void *pKey, /* The binary record */ + UnpackedRecord *p /* Populate this structure before returning. */ +){ + const unsigned char *aKey = (const unsigned char *)pKey; + u32 d; + u32 idx; /* Offset in aKey[] to read from */ + u16 u; /* Unsigned loop counter */ + u32 szHdr; + Mem *pMem = p->aMem; + + p->default_rc = 0; + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + idx = getVarint32(aKey, szHdr); + d = szHdr; + u = 0; + while( idxenc = pKeyInfo->enc; + pMem->db = pKeyInfo->db; + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ + pMem->szMalloc = 0; + pMem->z = 0; + sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + d += sqlite3VdbeSerialTypeLen(serial_type); + pMem++; + if( (++u)>=p->nField ) break; + } + if( d>(u32)nKey && u ){ + assert( CORRUPT_DB ); + /* In a corrupt record entry, the last pMem might have been set up using + ** uninitialized memory. Overwrite its value with NULL, to prevent + ** warnings from MSAN. */ + sqlite3VdbeMemSetNull(pMem-1); + } + assert( u<=pKeyInfo->nKeyField + 1 ); + p->nField = u; +} + +#ifdef SQLITE_DEBUG +/* +** This function compares two index or table record keys in the same way +** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), +** this function deserializes and compares values using the +** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used +** in assert() statements to ensure that the optimized code in +** sqlite3VdbeRecordCompare() returns results with these two primitives. +** +** Return true if the result of comparison is equivalent to desiredResult. +** Return false if there is a disagreement. +*/ +static int vdbeRecordCompareDebug( + int nKey1, const void *pKey1, /* Left key */ + const UnpackedRecord *pPKey2, /* Right key */ + int desiredResult /* Correct answer */ +){ + u32 d1; /* Offset into aKey[] of next data element */ + u32 idx1; /* Offset into aKey[] of next header element */ + u32 szHdr1; /* Number of bytes in header */ + int i = 0; + int rc = 0; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + KeyInfo *pKeyInfo; + Mem mem1; + + pKeyInfo = pPKey2->pKeyInfo; + if( pKeyInfo->db==0 ) return 1; + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ + + /* Compilers may complain that mem1.u.i is potentially uninitialized. + ** We could initialize it, as shown here, to silence those complaints. + ** But in fact, mem1.u.i will never actually be used uninitialized, and doing + ** the unnecessary initialization has a measurable negative performance + ** impact, since this routine is a very high runner. And so, we choose + ** to ignore the compiler warnings and leave this variable uninitialized. + */ + /* mem1.u.i = 0; // not needed, here to silence compiler warning */ + + idx1 = getVarint32(aKey1, szHdr1); + if( szHdr1>98307 ) return SQLITE_CORRUPT; + d1 = szHdr1; + assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); + assert( pKeyInfo->aSortFlags!=0 ); + assert( pKeyInfo->nKeyField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); + do{ + u32 serial_type1; + + /* Read the serial types for the next element in each key. */ + idx1 += getVarint32( aKey1+idx1, serial_type1 ); + + /* Verify that there is enough key space remaining to avoid + ** a buffer overread. The "d1+serial_type1+2" subexpression will + ** always be greater than or equal to the amount of required key space. + ** Use that approximation to avoid the more expensive call to + ** sqlite3VdbeSerialTypeLen() in the common case. + */ + if( d1+(u64)serial_type1+2>(u64)nKey1 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 + ){ + if( serial_type1>=1 + && serial_type1<=7 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)<=(u64)nKey1+8 + && CORRUPT_DB + ){ + return 1; /* corrupt record not detected by + ** sqlite3VdbeRecordCompareWithSkip(). Return true + ** to avoid firing the assert() */ + } + break; + } + + /* Extract the values to be compared. + */ + sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + d1 += sqlite3VdbeSerialTypeLen(serial_type1); + + /* Do the comparison + */ + rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], + pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); + if( rc!=0 ){ + assert( mem1.szMalloc==0 ); /* See comment below */ + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) + ){ + rc = -rc; + } + if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){ + rc = -rc; /* Invert the result for DESC sort order. */ + } + goto debugCompareEnd; + } + i++; + }while( idx1nField ); + + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). + */ + assert( mem1.szMalloc==0 ); + + /* rc==0 here means that one of the keys ran out of fields and + ** all the fields up to that point were equal. Return the default_rc + ** value. */ + rc = pPKey2->default_rc; + +debugCompareEnd: + if( desiredResult==0 && rc==0 ) return 1; + if( desiredResult<0 && rc<0 ) return 1; + if( desiredResult>0 && rc>0 ) return 1; + if( CORRUPT_DB ) return 1; + if( pKeyInfo->db->mallocFailed ) return 1; + return 0; +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Count the number of fields (a.k.a. columns) in the record given by +** pKey,nKey. The verify that this count is less than or equal to the +** limit given by pKeyInfo->nAllField. +** +** If this constraint is not satisfied, it means that the high-speed +** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will +** not work correctly. If this assert() ever fires, it probably means +** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed +** incorrectly. +*/ +static void vdbeAssertFieldCountWithinLimits( + int nKey, const void *pKey, /* The record to verify */ + const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */ +){ + int nField = 0; + u32 szHdr; + u32 idx; + u32 notUsed; + const unsigned char *aKey = (const unsigned char*)pKey; + + if( CORRUPT_DB ) return; + idx = getVarint32(aKey, szHdr); + assert( nKey>=0 ); + assert( szHdr<=(u32)nKey ); + while( idxnAllField ); +} +#else +# define vdbeAssertFieldCountWithinLimits(A,B,C) +#endif + +/* +** Both *pMem1 and *pMem2 contain string values. Compare the two values +** using the collation sequence pColl. As usual, return a negative , zero +** or positive value if *pMem1 is less than, equal to or greater than +** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". +*/ +static int vdbeCompareMemString( + const Mem *pMem1, + const Mem *pMem2, + const CollSeq *pColl, + u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ +){ + if( pMem1->enc==pColl->enc ){ + /* The strings are already in the correct encoding. Call the + ** comparison function directly */ + return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); + }else{ + int rc; + const void *v1, *v2; + Mem c1; + Mem c2; + sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); + sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); + sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); + v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); + v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); + if( (v1==0 || v2==0) ){ + if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; + rc = 0; + }else{ + rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); + } + sqlite3VdbeMemReleaseMalloc(&c1); + sqlite3VdbeMemReleaseMalloc(&c2); + return rc; + } +} + +/* +** The input pBlob is guaranteed to be a Blob that is not marked +** with MEM_Zero. Return true if it could be a zero-blob. +*/ +static int isAllZero(const char *z, int n){ + int i; + for(i=0; in; + int n2 = pB2->n; + + /* It is possible to have a Blob value that has some non-zero content + ** followed by zero content. But that only comes up for Blobs formed + ** by the OP_MakeRecord opcode, and such Blobs never get passed into + ** sqlite3MemCompare(). */ + assert( (pB1->flags & MEM_Zero)==0 || n1==0 ); + assert( (pB2->flags & MEM_Zero)==0 || n2==0 ); + + if( (pB1->flags|pB2->flags) & MEM_Zero ){ + if( pB1->flags & pB2->flags & MEM_Zero ){ + return pB1->u.nZero - pB2->u.nZero; + }else if( pB1->flags & MEM_Zero ){ + if( !isAllZero(pB2->z, pB2->n) ) return -1; + return pB1->u.nZero - n2; + }else{ + if( !isAllZero(pB1->z, pB1->n) ) return +1; + return n1 - pB2->u.nZero; + } + } + c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1); + if( c ) return c; + return n1 - n2; +} + +/* The following two functions are used only within testcase() to prove +** test coverage. These functions do no exist for production builds. +** We must use separate SQLITE_NOINLINE functions here, since otherwise +** optimizer code movement causes gcov to become very confused. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +static int SQLITE_NOINLINE doubleLt(double a, double b){ return ar ); + testcase( x==r ); + return (xr); + }else{ + i64 y; + double s; + if( r<-9223372036854775808.0 ) return +1; + if( r>=9223372036854775808.0 ) return -1; + y = (i64)r; + if( iy ) return +1; + s = (double)i; + testcase( doubleLt(s,r) ); + testcase( doubleLt(r,s) ); + testcase( doubleEq(r,s) ); + return (sr); + } +} + +/* +** Compare the values contained by the two memory cells, returning +** negative, zero or positive if pMem1 is less than, equal to, or greater +** than pMem2. Sorting order is NULL's first, followed by numbers (integers +** and reals) sorted numerically, followed by text ordered by the collating +** sequence pColl and finally blob's ordered by memcmp(). +** +** Two NULL values are considered equal by this function. +*/ +SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ + int f1, f2; + int combined_flags; + + f1 = pMem1->flags; + f2 = pMem2->flags; + combined_flags = f1|f2; + assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); + + /* If one value is NULL, it is less than the other. If both values + ** are NULL, return 0. + */ + if( combined_flags&MEM_Null ){ + return (f2&MEM_Null) - (f1&MEM_Null); + } + + /* At least one of the two values is a number + */ + if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){ + testcase( combined_flags & MEM_Int ); + testcase( combined_flags & MEM_Real ); + testcase( combined_flags & MEM_IntReal ); + if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){ + testcase( f1 & f2 & MEM_Int ); + testcase( f1 & f2 & MEM_IntReal ); + if( pMem1->u.i < pMem2->u.i ) return -1; + if( pMem1->u.i > pMem2->u.i ) return +1; + return 0; + } + if( (f1 & f2 & MEM_Real)!=0 ){ + if( pMem1->u.r < pMem2->u.r ) return -1; + if( pMem1->u.r > pMem2->u.r ) return +1; + return 0; + } + if( (f1&(MEM_Int|MEM_IntReal))!=0 ){ + testcase( f1 & MEM_Int ); + testcase( f1 & MEM_IntReal ); + if( (f2&MEM_Real)!=0 ){ + return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); + }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ + if( pMem1->u.i < pMem2->u.i ) return -1; + if( pMem1->u.i > pMem2->u.i ) return +1; + return 0; + }else{ + return -1; + } + } + if( (f1&MEM_Real)!=0 ){ + if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ + testcase( f2 & MEM_Int ); + testcase( f2 & MEM_IntReal ); + return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); + }else{ + return -1; + } + } + return +1; + } + + /* If one value is a string and the other is a blob, the string is less. + ** If both are strings, compare using the collating functions. + */ + if( combined_flags&MEM_Str ){ + if( (f1 & MEM_Str)==0 ){ + return 1; + } + if( (f2 & MEM_Str)==0 ){ + return -1; + } + + assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed ); + assert( pMem1->enc==SQLITE_UTF8 || + pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); + + /* The collation sequence must be defined at this point, even if + ** the user deletes the collation sequence after the vdbe program is + ** compiled (this was not always the case). + */ + assert( !pColl || pColl->xCmp ); + + if( pColl ){ + return vdbeCompareMemString(pMem1, pMem2, pColl, 0); + } + /* If a NULL pointer was passed as the collate function, fall through + ** to the blob case and use memcmp(). */ + } + + /* Both values must be blobs. Compare using memcmp(). */ + return sqlite3BlobCompare(pMem1, pMem2); +} + + +/* +** The first argument passed to this function is a serial-type that +** corresponds to an integer - all values between 1 and 9 inclusive +** except 7. The second points to a buffer containing an integer value +** serialized according to serial_type. This function deserializes +** and returns the value. +*/ +static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ + u32 y; + assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) ); + switch( serial_type ){ + case 0: + case 1: + testcase( aKey[0]&0x80 ); + return ONE_BYTE_INT(aKey); + case 2: + testcase( aKey[0]&0x80 ); + return TWO_BYTE_INT(aKey); + case 3: + testcase( aKey[0]&0x80 ); + return THREE_BYTE_INT(aKey); + case 4: { + testcase( aKey[0]&0x80 ); + y = FOUR_BYTE_UINT(aKey); + return (i64)*(int*)&y; + } + case 5: { + testcase( aKey[0]&0x80 ); + return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); + } + case 6: { + u64 x = FOUR_BYTE_UINT(aKey); + testcase( aKey[0]&0x80 ); + x = (x<<32) | FOUR_BYTE_UINT(aKey+4); + return (i64)*(i64*)&x; + } + } + + return (serial_type - 8); +} + +/* +** This function compares the two table rows or index records +** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero +** or positive integer if key1 is less than, equal to or +** greater than key2. The {nKey1, pKey1} key must be a blob +** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 +** key must be a parsed key such as obtained from +** sqlite3VdbeParseRecord. +** +** If argument bSkip is non-zero, it is assumed that the caller has already +** determined that the first fields of the keys are equal. +** +** Key1 and Key2 do not have to contain the same number of fields. If all +** fields that appear in both keys are equal, then pPKey2->default_rc is +** returned. +** +** If database corruption is discovered, set pPKey2->errCode to +** SQLITE_CORRUPT and return 0. If an OOM error is encountered, +** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the +** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). +*/ +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2, /* Right key */ + int bSkip /* If true, skip the first field */ +){ + u32 d1; /* Offset into aKey[] of next data element */ + int i; /* Index of next field to compare */ + u32 szHdr1; /* Size of record header in bytes */ + u32 idx1; /* Offset of first type in header */ + int rc = 0; /* Return value */ + Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ + KeyInfo *pKeyInfo; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + Mem mem1; + + /* If bSkip is true, then the caller has already determined that the first + ** two elements in the keys are equal. Fix the various stack variables so + ** that this routine begins comparing at the second field. */ + if( bSkip ){ + u32 s1 = aKey1[1]; + if( s1<0x80 ){ + idx1 = 2; + }else{ + idx1 = 1 + sqlite3GetVarint32(&aKey1[1], &s1); + } + szHdr1 = aKey1[0]; + d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1); + i = 1; + pRhs++; + }else{ + if( (szHdr1 = aKey1[0])<0x80 ){ + idx1 = 1; + }else{ + idx1 = sqlite3GetVarint32(aKey1, &szHdr1); + } + d1 = szHdr1; + i = 0; + } + if( d1>(unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } + + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ + assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField + || CORRUPT_DB ); + assert( pPKey2->pKeyInfo->aSortFlags!=0 ); + assert( pPKey2->pKeyInfo->nKeyField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); + while( 1 /*exit-by-break*/ ){ + u32 serial_type; + + /* RHS is an integer */ + if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pRhs->flags & MEM_Int ); + testcase( pRhs->flags & MEM_IntReal ); + serial_type = aKey1[idx1]; + testcase( serial_type==12 ); + if( serial_type>=10 ){ + rc = serial_type==10 ? -1 : +1; + }else if( serial_type==0 ){ + rc = -1; + }else if( serial_type==7 ){ + serialGet7(&aKey1[d1], &mem1); + rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); + }else{ + i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); + i64 rhs = pRhs->u.i; + if( lhsrhs ){ + rc = +1; + } + } + } + + /* RHS is real */ + else if( pRhs->flags & MEM_Real ){ + serial_type = aKey1[idx1]; + if( serial_type>=10 ){ + /* Serial types 12 or greater are strings and blobs (greater than + ** numbers). Types 10 and 11 are currently "reserved for future + ** use", so it doesn't really matter what the results of comparing + ** them to numeric values are. */ + rc = serial_type==10 ? -1 : +1; + }else if( serial_type==0 ){ + rc = -1; + }else{ + if( serial_type==7 ){ + if( serialGet7(&aKey1[d1], &mem1) ){ + rc = -1; /* mem1 is a NaN */ + }else if( mem1.u.ru.r ){ + rc = -1; + }else if( mem1.u.r>pRhs->u.r ){ + rc = +1; + }else{ + assert( rc==0 ); + } + }else{ + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); + } + } + } + + /* RHS is a string */ + else if( pRhs->flags & MEM_Str ){ + getVarint32NR(&aKey1[idx1], serial_type); + testcase( serial_type==12 ); + if( serial_type<12 ){ + rc = -1; + }else if( !(serial_type & 0x01) ){ + rc = +1; + }else{ + mem1.n = (serial_type - 12) / 2; + testcase( (d1+mem1.n)==(unsigned)nKey1 ); + testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); + if( (d1+mem1.n) > (unsigned)nKey1 + || (pKeyInfo = pPKey2->pKeyInfo)->nAllField<=i + ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + }else if( pKeyInfo->aColl[i] ){ + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + mem1.flags = MEM_Str; + mem1.z = (char*)&aKey1[d1]; + rc = vdbeCompareMemString( + &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode + ); + }else{ + int nCmp = MIN(mem1.n, pRhs->n); + rc = memcmp(&aKey1[d1], pRhs->z, nCmp); + if( rc==0 ) rc = mem1.n - pRhs->n; + } + } + } + + /* RHS is a blob */ + else if( pRhs->flags & MEM_Blob ){ + assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 ); + getVarint32NR(&aKey1[idx1], serial_type); + testcase( serial_type==12 ); + if( serial_type<12 || (serial_type & 0x01) ){ + rc = -1; + }else{ + int nStr = (serial_type - 12) / 2; + testcase( (d1+nStr)==(unsigned)nKey1 ); + testcase( (d1+nStr+1)==(unsigned)nKey1 ); + if( (d1+nStr) > (unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + }else if( pRhs->flags & MEM_Zero ){ + if( !isAllZero((const char*)&aKey1[d1],nStr) ){ + rc = 1; + }else{ + rc = nStr - pRhs->u.nZero; + } + }else{ + int nCmp = MIN(nStr, pRhs->n); + rc = memcmp(&aKey1[d1], pRhs->z, nCmp); + if( rc==0 ) rc = nStr - pRhs->n; + } + } + } + + /* RHS is null */ + else{ + serial_type = aKey1[idx1]; + if( serial_type==0 + || serial_type==10 + || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0) + ){ + assert( rc==0 ); + }else{ + rc = 1; + } + } + + if( rc!=0 ){ + int sortFlags = pPKey2->pKeyInfo->aSortFlags[i]; + if( sortFlags ){ + if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0 + || ((sortFlags & KEYINFO_ORDER_DESC) + !=(serial_type==0 || (pRhs->flags&MEM_Null))) + ){ + rc = -rc; + } + } + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); + assert( mem1.szMalloc==0 ); /* See comment below */ + return rc; + } + + i++; + if( i==pPKey2->nField ) break; + pRhs++; + d1 += sqlite3VdbeSerialTypeLen(serial_type); + if( d1>(unsigned)nKey1 ) break; + idx1 += sqlite3VarintLen(serial_type); + if( idx1>=(unsigned)szHdr1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corrupt index */ + } + } + + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ + assert( mem1.szMalloc==0 ); + + /* rc==0 here means that one or both of the keys ran out of fields and + ** all the fields up to that point were equal. Return the default_rc + ** value. */ + assert( CORRUPT_DB + || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) + || pPKey2->pKeyInfo->db->mallocFailed + ); + pPKey2->eqSeen = 1; + return pPKey2->default_rc; +} +SQLITE_PRIVATE int sqlite3VdbeRecordCompare( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); +} + + +/* +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is an integer, and (b) the +** size-of-header varint at the start of (pKey1/nKey1) fits in a single +** byte (i.e. is less than 128). +** +** To avoid concerns about buffer overreads, this routine is only used +** on schemas where the maximum valid header size is 63 bytes or less. +*/ +static int vdbeRecordCompareInt( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; + int serial_type = ((const u8*)pKey1)[1]; + int res; + u32 y; + u64 x; + i64 v; + i64 lhs; + + vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); + assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); + switch( serial_type ){ + case 1: { /* 1-byte signed integer */ + lhs = ONE_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 2: { /* 2-byte signed integer */ + lhs = TWO_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 3: { /* 3-byte signed integer */ + lhs = THREE_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 4: { /* 4-byte signed integer */ + y = FOUR_BYTE_UINT(aKey); + lhs = (i64)*(int*)&y; + testcase( lhs<0 ); + break; + } + case 5: { /* 6-byte signed integer */ + lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 6: { /* 8-byte signed integer */ + x = FOUR_BYTE_UINT(aKey); + x = (x<<32) | FOUR_BYTE_UINT(aKey+4); + lhs = *(i64*)&x; + testcase( lhs<0 ); + break; + } + case 8: + lhs = 0; + break; + case 9: + lhs = 1; + break; + + /* This case could be removed without changing the results of running + ** this code. Including it causes gcc to generate a faster switch + ** statement (since the range of switch targets now starts at zero and + ** is contiguous) but does not cause any duplicate code to be generated + ** (as gcc is clever enough to combine the two like cases). Other + ** compilers might be similar. */ + case 0: case 7: + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + + default: + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + } + + assert( pPKey2->u.i == pPKey2->aMem[0].u.i ); + v = pPKey2->u.i; + if( v>lhs ){ + res = pPKey2->r1; + }else if( vr2; + }else if( pPKey2->nField>1 ){ + /* The first fields of the two keys are equal. Compare the trailing + ** fields. */ + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + }else{ + /* The first fields of the two keys are equal and there are no trailing + ** fields. Return pPKey2->default_rc in this case. */ + res = pPKey2->default_rc; + pPKey2->eqSeen = 1; + } + + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) ); + return res; +} + +/* +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is a string, that (b) the first field +** uses the collation sequence BINARY and (c) that the size-of-header varint +** at the start of (pKey1/nKey1) fits in a single byte. +*/ +static int vdbeRecordCompareString( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + const u8 *aKey1 = (const u8*)pKey1; + int serial_type; + int res; + + assert( pPKey2->aMem[0].flags & MEM_Str ); + assert( pPKey2->aMem[0].n == pPKey2->n ); + assert( pPKey2->aMem[0].z == pPKey2->u.z ); + vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); + serial_type = (signed char)(aKey1[1]); + +vrcs_restart: + if( serial_type<12 ){ + if( serial_type<0 ){ + sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type); + if( serial_type>=12 ) goto vrcs_restart; + assert( CORRUPT_DB ); + } + res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ + }else if( !(serial_type & 0x01) ){ + res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ + }else{ + int nCmp; + int nStr; + int szHdr = aKey1[0]; + + nStr = (serial_type-12) / 2; + if( (szHdr + nStr) > nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } + nCmp = MIN( pPKey2->n, nStr ); + res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp); + + if( res>0 ){ + res = pPKey2->r2; + }else if( res<0 ){ + res = pPKey2->r1; + }else{ + res = nStr - pPKey2->n; + if( res==0 ){ + if( pPKey2->nField>1 ){ + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + }else{ + res = pPKey2->default_rc; + pPKey2->eqSeen = 1; + } + }else if( res>0 ){ + res = pPKey2->r2; + }else{ + res = pPKey2->r1; + } + } + } + + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) + || CORRUPT_DB + || pPKey2->pKeyInfo->db->mallocFailed + ); + return res; +} + +/* +** Return a pointer to an sqlite3VdbeRecordCompare() compatible function +** suitable for comparing serialized records to the unpacked record passed +** as the only argument. +*/ +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ + /* varintRecordCompareInt() and varintRecordCompareString() both assume + ** that the size-of-header varint that occurs at the start of each record + ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt() + ** also assumes that it is safe to overread a buffer by at least the + ** maximum possible legal header size plus 8 bytes. Because there is + ** guaranteed to be at least 74 (but not 136) bytes of padding following each + ** buffer passed to varintRecordCompareInt() this makes it convenient to + ** limit the size of the header to 64 bytes in cases where the first field + ** is an integer. + ** + ** The easiest way to enforce this limit is to consider only records with + ** 13 fields or less. If the first field is an integer, the maximum legal + ** header size is (12*5 + 1 + 1) bytes. */ + if( p->pKeyInfo->nAllField<=13 ){ + int flags = p->aMem[0].flags; + if( p->pKeyInfo->aSortFlags[0] ){ + if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ + return sqlite3VdbeRecordCompare; + } + p->r1 = 1; + p->r2 = -1; + }else{ + p->r1 = -1; + p->r2 = 1; + } + if( (flags & MEM_Int) ){ + p->u.i = p->aMem[0].u.i; + return vdbeRecordCompareInt; + } + testcase( flags & MEM_Real ); + testcase( flags & MEM_Null ); + testcase( flags & MEM_Blob ); + if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 + && p->pKeyInfo->aColl[0]==0 + ){ + assert( flags & MEM_Str ); + p->u.z = p->aMem[0].z; + p->n = p->aMem[0].n; + return vdbeRecordCompareString; + } + } + + return sqlite3VdbeRecordCompare; +} + +/* +** pCur points at an index entry created using the OP_MakeRecord opcode. +** Read the rowid (the last field in the record) and store it in *rowid. +** Return SQLITE_OK if everything works, or an error code otherwise. +** +** pCur might be pointing to text obtained from a corrupt database file. +** So the content cannot be trusted. Do appropriate checks on the content. +*/ +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ + i64 nCellKey = 0; + int rc; + u32 szHdr; /* Size of the header */ + u32 typeRowid; /* Serial type of the rowid */ + u32 lenRowid; /* Size of the rowid */ + Mem m, v; + + /* Get the size of the index entry. Only indices entries of less + ** than 2GiB are support - anything large must be database corruption. + ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so + ** this code can safely assume that nCellKey is 32-bits + */ + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); + + /* Read in the complete content of the index entry */ + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ){ + return rc; + } + + /* The index entry must begin with a header size */ + getVarint32NR((u8*)m.z, szHdr); + testcase( szHdr==3 ); + testcase( szHdr==(u32)m.n ); + testcase( szHdr>0x7fffffff ); + assert( m.n>=0 ); + if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ + goto idx_rowid_corruption; + } + + /* The last field of the index should be an integer - the ROWID. + ** Verify that the last entry really is an integer. */ + getVarint32NR((u8*)&m.z[szHdr-1], typeRowid); + testcase( typeRowid==1 ); + testcase( typeRowid==2 ); + testcase( typeRowid==3 ); + testcase( typeRowid==4 ); + testcase( typeRowid==5 ); + testcase( typeRowid==6 ); + testcase( typeRowid==8 ); + testcase( typeRowid==9 ); + if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){ + goto idx_rowid_corruption; + } + lenRowid = sqlite3SmallTypeSizes[typeRowid]; + testcase( (u32)m.n==szHdr+lenRowid ); + if( unlikely((u32)m.neCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + *res = 0; + return SQLITE_CORRUPT_BKPT; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ){ + return rc; + } + *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); + sqlite3VdbeMemReleaseMalloc(&m); + return SQLITE_OK; +} + +/* +** This routine sets the value to be returned by subsequent calls to +** sqlite3_changes() on the database handle 'db'. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, i64 nChange){ + assert( sqlite3_mutex_held(db->mutex) ); + db->nChange = nChange; + db->nTotalChange += nChange; +} + +/* +** Set a flag in the vdbe to update the change counter when it is finalised +** or reset. +*/ +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ + v->changeCntOn = 1; +} + +/* +** Mark every prepared statement associated with a database connection +** as expired. +** +** An expired statement means that recompilation of the statement is +** recommend. Statements expire when things happen that make their +** programs obsolete. Removing user-defined functions or collating +** sequences, or changing an authorization function are the types of +** things that make prepared statements obsolete. +** +** If iCode is 1, then expiration is advisory. The statement should +** be reprepared before being restarted, but if it is already running +** it is allowed to run to completion. +** +** Internally, this function just sets the Vdbe.expired flag on all +** prepared statements. The flag is set to 1 for an immediate expiration +** and set to 2 for an advisory expiration. +*/ +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ + Vdbe *p; + for(p = db->pVdbe; p; p=p->pVNext){ + p->expired = iCode+1; + } +} + +/* +** Return the database associated with the Vdbe. +*/ +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ + return v->db; +} + +/* +** Return the SQLITE_PREPARE flags for a Vdbe. +*/ +SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe *v){ + return v->prepFlags; +} + +/* +** Return a pointer to an sqlite3_value structure containing the value bound +** parameter iVar of VM v. Except, if the value is an SQL NULL, return +** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* +** constants) to the value before returning it. +** +** The returned value must be freed by the caller using sqlite3ValueFree(). +*/ +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ + assert( iVar>0 ); + if( v ){ + Mem *pMem = &v->aVar[iVar-1]; + assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); + if( 0==(pMem->flags & MEM_Null) ){ + sqlite3_value *pRet = sqlite3ValueNew(v->db); + if( pRet ){ + sqlite3VdbeMemCopy((Mem *)pRet, pMem); + sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); + } + return pRet; + } + } + return 0; +} + +/* +** Configure SQL variable iVar so that binding a new value to it signals +** to sqlite3_reoptimize() that re-preparing the statement may result +** in a better query plan. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ + assert( iVar>0 ); + assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); + if( iVar>=32 ){ + v->expmask |= 0x80000000; + }else{ + v->expmask |= ((u32)1 << (iVar-1)); + } +} + +/* +** Cause a function to throw an error if it was call from OP_PureFunc +** rather than OP_Function. +** +** OP_PureFunc means that the function must be deterministic, and should +** throw an error if it is given inputs that would make it non-deterministic. +** This routine is invoked by date/time functions that use non-deterministic +** features such as 'now'. +*/ +SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){ + const VdbeOp *pOp; +#ifdef SQLITE_ENABLE_STAT4 + if( pCtx->pVdbe==0 ) return 1; +#endif + pOp = pCtx->pVdbe->aOp + pCtx->iOp; + if( pOp->opcode==OP_PureFunc ){ + const char *zContext; + char *zMsg; + if( pOp->p5 & NC_IsCheck ){ + zContext = "a CHECK constraint"; + }else if( pOp->p5 & NC_GenCol ){ + zContext = "a generated column"; + }else{ + zContext = "an index"; + } + zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s", + pCtx->pFunc->zName, zContext); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); + return 0; + } + return 1; +} + +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) +/* +** This Walker callback is used to help verify that calls to +** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have +** byte-code register values correctly initialized. +*/ +SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_REGISTER ){ + assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); + } + return WRC_Continue; +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored +** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored +** in memory obtained from sqlite3DbMalloc). +*/ +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ + if( pVtab->zErrMsg ){ + sqlite3 *db = p->db; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; + } +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + +/* +** If the second argument is not NULL, release any allocations associated +** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord +** structure itself, using sqlite3DbFree(). +** +** This function is used to free UnpackedRecord structures allocated by +** the vdbeUnpackRecord() function found in vdbeapi.c. +*/ +static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ + assert( db!=0 ); + if( p ){ + int i; + for(i=0; iaMem[i]; + if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); + } + sqlite3DbNNFreeNN(db, p); + } +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, +** then cursor passed as the second argument should point to the row about +** to be update or deleted. If the application calls sqlite3_preupdate_old(), +** the required value will be read from the row the cursor points to. +*/ +SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( + Vdbe *v, /* Vdbe pre-update hook is invoked by */ + VdbeCursor *pCsr, /* Cursor to grab old.* values from */ + int op, /* SQLITE_INSERT, UPDATE or DELETE */ + const char *zDb, /* Database name */ + Table *pTab, /* Modified table */ + i64 iKey1, /* Initial key value */ + int iReg, /* Register for new.* record */ + int iBlobWrite +){ + sqlite3 *db = v->db; + i64 iKey2; + PreUpdate preupdate; + const char *zTbl = pTab->zName; + static const u8 fakeSortOrder = 0; +#ifdef SQLITE_DEBUG + int nRealCol; + if( pTab->tabFlags & TF_WithoutRowid ){ + nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; + }else if( pTab->tabFlags & TF_HasVirtual ){ + nRealCol = pTab->nNVCol; + }else{ + nRealCol = pTab->nCol; + } +#endif + + assert( db->pPreUpdate==0 ); + memset(&preupdate, 0, sizeof(PreUpdate)); + if( HasRowid(pTab)==0 ){ + iKey1 = iKey2 = 0; + preupdate.pPk = sqlite3PrimaryKeyIndex(pTab); + }else{ + if( op==SQLITE_UPDATE ){ + iKey2 = v->aMem[iReg].u.i; + }else{ + iKey2 = iKey1; + } + } + + assert( pCsr!=0 ); + assert( pCsr->eCurType==CURTYPE_BTREE ); + assert( pCsr->nField==nRealCol + || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) + ); + + preupdate.v = v; + preupdate.pCsr = pCsr; + preupdate.op = op; + preupdate.iNewReg = iReg; + preupdate.keyinfo.db = db; + preupdate.keyinfo.enc = ENC(db); + preupdate.keyinfo.nKeyField = pTab->nCol; + preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder; + preupdate.iKey1 = iKey1; + preupdate.iKey2 = iKey2; + preupdate.pTab = pTab; + preupdate.iBlobWrite = iBlobWrite; + + db->pPreUpdate = &preupdate; + db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); + db->pPreUpdate = 0; + sqlite3DbFree(db, preupdate.aRecord); + vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); + vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); + if( preupdate.aNew ){ + int i; + for(i=0; inField; i++){ + sqlite3VdbeMemRelease(&preupdate.aNew[i]); + } + sqlite3DbNNFreeNN(db, preupdate.aNew); + } +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +/************** End of vdbeaux.c *********************************************/ +/************** Begin file vdbeapi.c *****************************************/ +/* +** 2004 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to implement APIs that are part of the +** VDBE. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ +/* #include "opcodes.h" */ + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Return TRUE (non-zero) of the statement supplied as an argument needs +** to be recompiled. A statement needs to be recompiled whenever the +** execution environment changes in a way that would alter the program +** that sqlite3_prepare() generates. For example, if new functions or +** collating sequences are registered or if an authorizer function is +** added or changed. +*/ +SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p==0 || p->expired; +} +#endif + +/* +** Check on a Vdbe to make sure it has not been finalized. Log +** an error and return true if it has been finalized (or is otherwise +** invalid). Return false if it is ok. +*/ +static int vdbeSafety(Vdbe *p){ + if( p->db==0 ){ + sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement"); + return 1; + }else{ + return 0; + } +} +static int vdbeSafetyNotNull(Vdbe *p){ + if( p==0 ){ + sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); + return 1; + }else{ + return vdbeSafety(p); + } +} + +#ifndef SQLITE_OMIT_TRACE +/* +** Invoke the profile callback. This routine is only called if we already +** know that the profile callback is defined and needs to be invoked. +*/ +static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ + sqlite3_int64 iNow; + sqlite3_int64 iElapse; + assert( p->startTime>0 ); + assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 ); + assert( db->init.busy==0 ); + assert( p->zSql!=0 ); + sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); + iElapse = (iNow - p->startTime)*1000000; +#ifndef SQLITE_OMIT_DEPRECATED + if( db->xProfile ){ + db->xProfile(db->pProfileArg, p->zSql, iElapse); + } +#endif + if( db->mTrace & SQLITE_TRACE_PROFILE ){ + db->trace.xV2(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse); + } + p->startTime = 0; +} +/* +** The checkProfileCallback(DB,P) macro checks to see if a profile callback +** is needed, and it invokes the callback if it is needed. +*/ +# define checkProfileCallback(DB,P) \ + if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); } +#else +# define checkProfileCallback(DB,P) /*no-op*/ +#endif + +/* +** The following routine destroys a virtual machine that is created by +** the sqlite3_compile() routine. The integer returned is an SQLITE_ +** success/failure code that describes the result of executing the virtual +** machine. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL + ** pointer is a harmless no-op. */ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; + sqlite3_mutex_enter(db->mutex); + checkProfileCallback(db, v); + assert( v->eVdbeState>=VDBE_READY_STATE ); + rc = sqlite3VdbeReset(v); + sqlite3VdbeDelete(v); + rc = sqlite3ApiExit(db, rc); + sqlite3LeaveMutexAndCloseZombie(db); + } + return rc; +} + +/* +** Terminate the current execution of an SQL statement and reset it +** back to its starting state so that it can be reused. A success code from +** the prior execution is returned. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + sqlite3_mutex_enter(db->mutex); + checkProfileCallback(db, v); + rc = sqlite3VdbeReset(v); + sqlite3VdbeRewind(v); + assert( (rc & (db->errMask))==rc ); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + } + return rc; +} + +/* +** Set all the parameters in the compiled SQL statement to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ + int i; + int rc = SQLITE_OK; + Vdbe *p = (Vdbe*)pStmt; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif +#if SQLITE_THREADSAFE + mutex = p->db->mutex; +#endif + sqlite3_mutex_enter(mutex); + for(i=0; inVar; i++){ + sqlite3VdbeMemRelease(&p->aVar[i]); + p->aVar[i].flags = MEM_Null; + } + assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); + if( p->expmask ){ + p->expired = 1; + } + sqlite3_mutex_leave(mutex); + return rc; +} + + +/**************************** sqlite3_value_ ******************************* +** The following routines extract information from a Mem or sqlite3_value +** structure. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ + Mem *p = (Mem*)pVal; + if( p->flags & (MEM_Blob|MEM_Str) ){ + if( ExpandBlob(p)!=SQLITE_OK ){ + assert( p->flags==MEM_Null && p->z==0 ); + return 0; + } + p->flags |= MEM_Blob; + return p->n ? p->z : 0; + }else{ + return sqlite3_value_text(pVal); + } +} +SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF8); +} +SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); +} +SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){ + return sqlite3VdbeRealValue((Mem*)pVal); +} +SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){ + return (int)sqlite3VdbeIntValue((Mem*)pVal); +} +SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ + return sqlite3VdbeIntValue((Mem*)pVal); +} +SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ + Mem *pMem = (Mem*)pVal; + return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); +} +SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ + Mem *p = (Mem*)pVal; + if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == + (MEM_Null|MEM_Term|MEM_Subtype) + && zPType!=0 + && p->eSubtype=='p' + && strcmp(p->u.zPType, zPType)==0 + ){ + return (void*)p->z; + }else{ + return 0; + } +} +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ + return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); +} +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16BE); +} +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16LE); +} +#endif /* SQLITE_OMIT_UTF16 */ +/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five +** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating +** point number string BLOB NULL +*/ +SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ + static const u8 aType[] = { + SQLITE_BLOB, /* 0x00 (not possible) */ + SQLITE_NULL, /* 0x01 NULL */ + SQLITE_TEXT, /* 0x02 TEXT */ + SQLITE_NULL, /* 0x03 (not possible) */ + SQLITE_INTEGER, /* 0x04 INTEGER */ + SQLITE_NULL, /* 0x05 (not possible) */ + SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */ + SQLITE_NULL, /* 0x07 (not possible) */ + SQLITE_FLOAT, /* 0x08 FLOAT */ + SQLITE_NULL, /* 0x09 (not possible) */ + SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */ + SQLITE_NULL, /* 0x0b (not possible) */ + SQLITE_INTEGER, /* 0x0c (not possible) */ + SQLITE_NULL, /* 0x0d (not possible) */ + SQLITE_INTEGER, /* 0x0e (not possible) */ + SQLITE_NULL, /* 0x0f (not possible) */ + SQLITE_BLOB, /* 0x10 BLOB */ + SQLITE_NULL, /* 0x11 (not possible) */ + SQLITE_TEXT, /* 0x12 (not possible) */ + SQLITE_NULL, /* 0x13 (not possible) */ + SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */ + SQLITE_NULL, /* 0x15 (not possible) */ + SQLITE_INTEGER, /* 0x16 (not possible) */ + SQLITE_NULL, /* 0x17 (not possible) */ + SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */ + SQLITE_NULL, /* 0x19 (not possible) */ + SQLITE_FLOAT, /* 0x1a (not possible) */ + SQLITE_NULL, /* 0x1b (not possible) */ + SQLITE_INTEGER, /* 0x1c (not possible) */ + SQLITE_NULL, /* 0x1d (not possible) */ + SQLITE_INTEGER, /* 0x1e (not possible) */ + SQLITE_NULL, /* 0x1f (not possible) */ + SQLITE_FLOAT, /* 0x20 INTREAL */ + SQLITE_NULL, /* 0x21 (not possible) */ + SQLITE_FLOAT, /* 0x22 INTREAL + TEXT */ + SQLITE_NULL, /* 0x23 (not possible) */ + SQLITE_FLOAT, /* 0x24 (not possible) */ + SQLITE_NULL, /* 0x25 (not possible) */ + SQLITE_FLOAT, /* 0x26 (not possible) */ + SQLITE_NULL, /* 0x27 (not possible) */ + SQLITE_FLOAT, /* 0x28 (not possible) */ + SQLITE_NULL, /* 0x29 (not possible) */ + SQLITE_FLOAT, /* 0x2a (not possible) */ + SQLITE_NULL, /* 0x2b (not possible) */ + SQLITE_FLOAT, /* 0x2c (not possible) */ + SQLITE_NULL, /* 0x2d (not possible) */ + SQLITE_FLOAT, /* 0x2e (not possible) */ + SQLITE_NULL, /* 0x2f (not possible) */ + SQLITE_BLOB, /* 0x30 (not possible) */ + SQLITE_NULL, /* 0x31 (not possible) */ + SQLITE_TEXT, /* 0x32 (not possible) */ + SQLITE_NULL, /* 0x33 (not possible) */ + SQLITE_FLOAT, /* 0x34 (not possible) */ + SQLITE_NULL, /* 0x35 (not possible) */ + SQLITE_FLOAT, /* 0x36 (not possible) */ + SQLITE_NULL, /* 0x37 (not possible) */ + SQLITE_FLOAT, /* 0x38 (not possible) */ + SQLITE_NULL, /* 0x39 (not possible) */ + SQLITE_FLOAT, /* 0x3a (not possible) */ + SQLITE_NULL, /* 0x3b (not possible) */ + SQLITE_FLOAT, /* 0x3c (not possible) */ + SQLITE_NULL, /* 0x3d (not possible) */ + SQLITE_FLOAT, /* 0x3e (not possible) */ + SQLITE_NULL, /* 0x3f (not possible) */ + }; +#ifdef SQLITE_DEBUG + { + int eType = SQLITE_BLOB; + if( pVal->flags & MEM_Null ){ + eType = SQLITE_NULL; + }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){ + eType = SQLITE_FLOAT; + }else if( pVal->flags & MEM_Int ){ + eType = SQLITE_INTEGER; + }else if( pVal->flags & MEM_Str ){ + eType = SQLITE_TEXT; + } + assert( eType == aType[pVal->flags&MEM_AffMask] ); + } +#endif + return aType[pVal->flags&MEM_AffMask]; +} +SQLITE_API int sqlite3_value_encoding(sqlite3_value *pVal){ + return pVal->enc; +} + +/* Return true if a parameter to xUpdate represents an unchanged column */ +SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ + return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); +} + +/* Return true if a parameter value originated from an sqlite3_bind() */ +SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){ + return (pVal->flags&MEM_FromBind)!=0; +} + +/* Make a copy of an sqlite3_value object +*/ +SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ + sqlite3_value *pNew; + if( pOrig==0 ) return 0; + pNew = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return 0; + memset(pNew, 0, sizeof(*pNew)); + memcpy(pNew, pOrig, MEMCELLSIZE); + pNew->flags &= ~MEM_Dyn; + pNew->db = 0; + if( pNew->flags&(MEM_Str|MEM_Blob) ){ + pNew->flags &= ~(MEM_Static|MEM_Dyn); + pNew->flags |= MEM_Ephem; + if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){ + sqlite3ValueFree(pNew); + pNew = 0; + } + }else if( pNew->flags & MEM_Null ){ + /* Do not duplicate pointer values */ + pNew->flags &= ~(MEM_Term|MEM_Subtype); + } + return pNew; +} + +/* Destroy an sqlite3_value object previously obtained from +** sqlite3_value_dup(). +*/ +SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ + sqlite3ValueFree(pOld); +} + + +/**************************** sqlite3_result_ ******************************* +** The following routines are used by user-defined functions to specify +** the function result. +** +** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the +** result as a string or blob. Appropriate errors are set if the string/blob +** is too big or if an OOM occurs. +** +** The invokeValueDestructor(P,X) routine invokes destructor function X() +** on value P if P is not going to be used and need to be destroyed. +*/ +static void setResultStrOrError( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* String pointer */ + int n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + Mem *pOut = pCtx->pOut; + int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); + if( rc ){ + if( rc==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); + }else{ + /* The only errors possible from sqlite3VdbeMemSetStr are + ** SQLITE_TOOBIG and SQLITE_NOMEM */ + assert( rc==SQLITE_NOMEM ); + sqlite3_result_error_nomem(pCtx); + } + return; + } + sqlite3VdbeChangeEncoding(pOut, pCtx->enc); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } +} +static int invokeValueDestructor( + const void *p, /* Value to destroy */ + void (*xDel)(void*), /* The destructor */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */ +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( xDel==0 ){ + /* noop */ + }else if( xDel==SQLITE_TRANSIENT ){ + /* noop */ + }else{ + xDel((void*)p); + } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx!=0 ){ + sqlite3_result_error_toobig(pCtx); + } +#else + assert( pCtx!=0 ); + sqlite3_result_error_toobig(pCtx); +#endif + return SQLITE_TOOBIG; +} +SQLITE_API void sqlite3_result_blob( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 || n<0 ){ + invokeValueDestructor(z, xDel, pCtx); + return; + } +#endif + assert( n>=0 ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, 0, xDel); +} +SQLITE_API void sqlite3_result_blob64( + sqlite3_context *pCtx, + const void *z, + sqlite3_uint64 n, + void (*xDel)(void *) +){ + assert( xDel!=SQLITE_DYNAMIC ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, 0, xDel); + } +} +SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); +} +SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_ERROR; + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_ERROR; + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); +} +#endif +SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); +} +SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); +} +SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); +} +SQLITE_API void sqlite3_result_pointer( + sqlite3_context *pCtx, + void *pPtr, + const char *zPType, + void (*xDestructor)(void*) +){ + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(pPtr, xDestructor, 0); + return; + } +#endif + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + sqlite3VdbeMemRelease(pOut); + pOut->flags = MEM_Null; + sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); +} +SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif +#if defined(SQLITE_STRICT_SUBTYPE) && SQLITE_STRICT_SUBTYPE+0!=0 + if( pCtx->pFunc!=0 + && (pCtx->pFunc->funcFlags & SQLITE_RESULT_SUBTYPE)==0 + ){ + char zErr[200]; + sqlite3_snprintf(sizeof(zErr), zErr, + "misuse of sqlite3_result_subtype() by %s()", + pCtx->pFunc->zName); + sqlite3_result_error(pCtx, zErr, -1); + return; + } +#endif /* SQLITE_STRICT_SUBTYPE */ + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + pOut->eSubtype = eSubtype & 0xff; + pOut->flags |= MEM_Subtype; +} +SQLITE_API void sqlite3_result_text( + sqlite3_context *pCtx, + const char *z, + int n, + void (*xDel)(void *) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); +} +SQLITE_API void sqlite3_result_text64( + sqlite3_context *pCtx, + const char *z, + sqlite3_uint64 n, + void (*xDel)(void *), + unsigned char enc +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); + if( enc!=SQLITE_UTF8 ){ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + n &= ~(u64)1; + } + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, enc, xDel); + sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut); + } +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API void sqlite3_result_text16( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel); +} +SQLITE_API void sqlite3_result_text16be( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel); +} +SQLITE_API void sqlite3_result_text16le( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16LE, xDel); +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; + if( pValue==0 ){ + sqlite3_result_null(pCtx); + return; + } +#endif + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemCopy(pOut, pValue); + sqlite3VdbeChangeEncoding(pOut, pCtx->enc); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } +} +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ + sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); +} +SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return SQLITE_MISUSE_BKPT; +#endif + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(pCtx); + return SQLITE_TOOBIG; + } +#ifndef SQLITE_OMIT_INCRBLOB + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); + return SQLITE_OK; +#else + return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); +#endif +} +SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pCtx->isError = errCode ? errCode : -1; +#ifdef SQLITE_DEBUG + if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; +#endif + if( pCtx->pOut->flags & MEM_Null ){ + setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, + SQLITE_STATIC); + } +} + +/* Force an SQLITE_TOOBIG error. */ +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_TOOBIG; + sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, + SQLITE_UTF8, SQLITE_STATIC); +} + +/* An SQLITE_NOMEM error. */ +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); + pCtx->isError = SQLITE_NOMEM_BKPT; + sqlite3OomFault(pCtx->pOut->db); +} + +#ifndef SQLITE_UNTESTABLE +/* Force the INT64 value currently stored as the result to be +** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL +** test-control. +*/ +SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( pCtx->pOut->flags & MEM_Int ){ + pCtx->pOut->flags &= ~MEM_Int; + pCtx->pOut->flags |= MEM_IntReal; + } +} +#endif + + +/* +** This function is called after a transaction has been committed. It +** invokes callbacks registered with sqlite3_wal_hook() as required. +*/ +static int doWalCallbacks(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_WAL + int i; + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + int nEntry; + sqlite3BtreeEnter(pBt); + nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); + sqlite3BtreeLeave(pBt); + if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){ + rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry); + } + } + } +#endif + return rc; +} + + +/* +** Execute the statement pStmt, either until a row of data is ready, the +** statement is completely executed or an error occurs. +** +** This routine implements the bulk of the logic behind the sqlite_step() +** API. The only thing omitted is the automatic recompile if a +** schema change has occurred. That detail is handled by the +** outer sqlite3_step() wrapper procedure. +*/ +static int sqlite3Step(Vdbe *p){ + sqlite3 *db; + int rc; + + assert(p); + db = p->db; + if( p->eVdbeState!=VDBE_RUN_STATE ){ + restart_step: + if( p->eVdbeState==VDBE_READY_STATE ){ + if( p->expired ){ + p->rc = SQLITE_SCHEMA; + rc = SQLITE_ERROR; + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ + /* If this statement was prepared using saved SQL and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same + ** value. + */ + rc = sqlite3VdbeTransferError(p); + } + goto end_of_step; + } + + /* If there are no other statements currently running, then + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + + assert( db->nVdbeWrite>0 || db->autoCommit==0 + || (db->nDeferredCons==0 && db->nDeferredImmCons==0) + ); + +#ifndef SQLITE_OMIT_TRACE + if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 + && !db->init.busy && p->zSql ){ + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); + }else{ + assert( p->startTime==0 ); + } +#endif + + db->nVdbeActive++; + if( p->readOnly==0 ) db->nVdbeWrite++; + if( p->bIsReader ) db->nVdbeRead++; + p->pc = 0; + p->eVdbeState = VDBE_RUN_STATE; + }else + + if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){ + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_reset() would + ** be called automatically instead of throwing the SQLITE_MISUSE error. + ** This "automatic-reset" change is not technically an incompatibility, + ** since any application that receives an SQLITE_MISUSE is broken by + ** definition. + ** + ** Nevertheless, some published applications that were originally written + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE + ** returns, and those were broken by the automatic-reset change. As a + ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the + ** legacy behavior of returning SQLITE_MISUSE for cases where the + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED + ** or SQLITE_BUSY error. + */ +#ifdef SQLITE_OMIT_AUTORESET + if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } +#else + sqlite3_reset((sqlite3_stmt*)p); +#endif + assert( p->eVdbeState==VDBE_READY_STATE ); + goto restart_step; + } + } + +#ifdef SQLITE_DEBUG + p->rcApp = SQLITE_OK; +#endif +#ifndef SQLITE_OMIT_EXPLAIN + if( p->explain ){ + rc = sqlite3VdbeList(p); + }else +#endif /* SQLITE_OMIT_EXPLAIN */ + { + db->nVdbeExec++; + rc = sqlite3VdbeExec(p); + db->nVdbeExec--; + } + + if( rc==SQLITE_ROW ){ + assert( p->rc==SQLITE_OK ); + assert( db->mallocFailed==0 ); + db->errCode = SQLITE_ROW; + return SQLITE_ROW; + }else{ +#ifndef SQLITE_OMIT_TRACE + /* If the statement completed successfully, invoke the profile callback */ + checkProfileCallback(db, p); +#endif + p->pResultRow = 0; + if( rc==SQLITE_DONE && db->autoCommit ){ + assert( p->rc==SQLITE_OK ); + p->rc = doWalCallbacks(db); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + } + }else if( rc!=SQLITE_DONE && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ + /* If this statement was prepared using saved SQL and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same value. + */ + rc = sqlite3VdbeTransferError(p); + } + } + + db->errCode = rc; + if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){ + p->rc = SQLITE_NOMEM_BKPT; + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ) rc = p->rc; + } +end_of_step: + /* There are only a limited number of result codes allowed from the + ** statements prepared using the legacy sqlite3_prepare() interface */ + assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 + || rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR + || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE + ); + return (rc&db->errMask); +} + +/* +** This is the top-level implementation of sqlite3_step(). Call +** sqlite3Step() to do most of the work. If a schema error occurs, +** call sqlite3Reprepare() and try again. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ + int rc = SQLITE_OK; /* Result from sqlite3Step() */ + Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ + int cnt = 0; /* Counter to prevent infinite loop of reprepares */ + sqlite3 *db; /* The database connection */ + + if( vdbeSafetyNotNull(v) ){ + return SQLITE_MISUSE_BKPT; + } + db = v->db; + sqlite3_mutex_enter(db->mutex); + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA + && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ + int savedPc = v->pc; + rc = sqlite3Reprepare(v); + if( rc!=SQLITE_OK ){ + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message + ** from the database handle into the statement and sets the statement + ** program counter to 0 to ensure that when the statement is + ** finalized or reset the parser error message is available via + ** sqlite3_errmsg() and sqlite3_errcode(). + */ + const char *zErr = (const char *)sqlite3_value_text(db->pErr); + sqlite3DbFree(db, v->zErrMsg); + if( !db->mallocFailed ){ + v->zErrMsg = sqlite3DbStrDup(db, zErr); + v->rc = rc = sqlite3ApiExit(db, rc); + } else { + v->zErrMsg = 0; + v->rc = rc = SQLITE_NOMEM_BKPT; + } + break; + } + sqlite3_reset(pStmt); + if( savedPc>=0 ){ + /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and + ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because it has + ** already been done once on a prior invocation that failed due to + ** SQLITE_SCHEMA. tag-20220401a */ + v->minWriteFileFormat = 254; + } + assert( v->expired==0 ); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#endif + assert( p && p->pFunc ); + return p->pFunc->pUserData; +} + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +** +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface +** returns a copy of the pointer to the database connection (the 1st +** parameter) of the sqlite3_create_function() and +** sqlite3_create_function16() routines that originally registered the +** application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else + assert( p && p->pOut ); +#endif + return p->pOut->db; +} + +/* +** If this routine is invoked from within an xColumn method of a virtual +** table, then it returns true if and only if the the call is during an +** UPDATE operation and the value of the column will not be modified +** by the UPDATE. +** +** If this routine is called from any context other than within the +** xColumn method of a virtual table, then the return value is meaningless +** and arbitrary. +** +** Virtual table implements might use this routine to optimize their +** performance by substituting a NULL result, or some other light-weight +** value, as a signal to the xUpdate routine that the column is unchanged. +*/ +SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else + assert( p ); +#endif + return sqlite3_value_nochange(p->pOut); +} + +/* +** The destructor function for a ValueList object. This needs to be +** a separate function, unknowable to the application, to ensure that +** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not +** preceded by activation of IN processing via sqlite3_vtab_int() do not +** try to access a fake ValueList object inserted by a hostile extension. +*/ +SQLITE_PRIVATE void sqlite3VdbeValueListFree(void *pToDelete){ + sqlite3_free(pToDelete); +} + +/* +** Implementation of sqlite3_vtab_in_first() (if bNext==0) and +** sqlite3_vtab_in_next() (if bNext!=0). +*/ +static int valueFromValueList( + sqlite3_value *pVal, /* Pointer to the ValueList object */ + sqlite3_value **ppOut, /* Store the next value from the list here */ + int bNext /* 1 for _next(). 0 for _first() */ +){ + int rc; + ValueList *pRhs; + + *ppOut = 0; + if( pVal==0 ) return SQLITE_MISUSE_BKPT; + if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ + return SQLITE_ERROR; + }else{ + assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == + (MEM_Null|MEM_Term|MEM_Subtype) ); + assert( pVal->eSubtype=='p' ); + assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 ); + pRhs = (ValueList*)pVal->z; + } + if( bNext ){ + rc = sqlite3BtreeNext(pRhs->pCsr, 0); + }else{ + int dummy = 0; + rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy); + assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) ); + if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE; + } + if( rc==SQLITE_OK ){ + u32 sz; /* Size of current row in bytes */ + Mem sMem; /* Raw content of current row */ + memset(&sMem, 0, sizeof(sMem)); + sz = sqlite3BtreePayloadSize(pRhs->pCsr); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem); + if( rc==SQLITE_OK ){ + u8 *zBuf = (u8*)sMem.z; + u32 iSerial; + sqlite3_value *pOut = pRhs->pOut; + int iOff = 1 + getVarint32(&zBuf[1], iSerial); + sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut); + pOut->enc = ENC(pOut->db); + if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){ + rc = SQLITE_NOMEM; + }else{ + *ppOut = pOut; + } + } + sqlite3VdbeMemRelease(&sMem); + } + return rc; +} + +/* +** Set the iterator value pVal to point to the first value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 0); +} + +/* +** Set the iterator value pVal to point to the next value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 1); +} + +/* +** Return the current time for a statement. If the current time +** is requested more than once within the same run of a single prepared +** statement, the exact same time is returned for each invocation regardless +** of the amount of time that elapses between invocations. In other words, +** the time returned is always the time of the first call. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ + int rc; +#ifndef SQLITE_ENABLE_STAT4 + sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; + assert( p->pVdbe!=0 ); +#else + sqlite3_int64 iTime = 0; + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; +#endif + if( *piTime==0 ){ + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + if( rc ) *piTime = 0; + } + return *piTime; +} + +/* +** Create a new aggregate context for p and return a pointer to +** its pMem->z element. +*/ +static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ + Mem *pMem = p->pMem; + assert( (pMem->flags & MEM_Agg)==0 ); + if( nByte<=0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + }else{ + sqlite3VdbeMemClearAndResize(pMem, nByte); + pMem->flags = MEM_Agg; + pMem->u.pDef = p->pFunc; + if( pMem->z ){ + memset(pMem->z, 0, nByte); + } + } + return (void*)pMem->z; +} + +/* +** Allocate or return the aggregate context for a user function. A new +** context is allocated on the first call. Subsequent calls return the +** same context that was returned on prior calls. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ + assert( p && p->pFunc && p->pFunc->xFinalize ); + assert( sqlite3_mutex_held(p->pOut->db->mutex) ); + testcase( nByte<0 ); + if( (p->pMem->flags & MEM_Agg)==0 ){ + return createAggContext(p, nByte); + }else{ + return (void*)p->pMem->z; + } +} + +/* +** Return the auxiliary data pointer, if any, for the iArg'th argument to +** the user-function defined by pCtx. +** +** The left-most argument is 0. +** +** Undocumented behavior: If iArg is negative then access a cache of +** auxiliary data pointers that is available to all functions within a +** single prepared statement. The iArg values must match. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ + AuxData *pAuxData; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return 0; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#if SQLITE_ENABLE_STAT4 + if( pCtx->pVdbe==0 ) return 0; +#else + assert( pCtx->pVdbe!=0 ); +#endif + for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ + if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ + return pAuxData->pAux; + } + } + return 0; +} + +/* +** Set the auxiliary data pointer and delete function, for the iArg'th +** argument to the user-function defined by pCtx. Any previous value is +** deleted by calling the delete function specified when it was set. +** +** The left-most argument is 0. +** +** Undocumented behavior: If iArg is negative then make the data available +** to all functions within the current prepared statement using iArg as an +** access code. +*/ +SQLITE_API void sqlite3_set_auxdata( + sqlite3_context *pCtx, + int iArg, + void *pAux, + void (*xDelete)(void*) +){ + AuxData *pAuxData; + Vdbe *pVdbe; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pVdbe= pCtx->pVdbe; + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#ifdef SQLITE_ENABLE_STAT4 + if( pVdbe==0 ) goto failed; +#else + assert( pVdbe!=0 ); +#endif + + for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ + if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ + break; + } + } + if( pAuxData==0 ){ + pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); + if( !pAuxData ) goto failed; + pAuxData->iAuxOp = pCtx->iOp; + pAuxData->iAuxArg = iArg; + pAuxData->pNextAux = pVdbe->pAuxData; + pVdbe->pAuxData = pAuxData; + if( pCtx->isError==0 ) pCtx->isError = -1; + }else if( pAuxData->xDeleteAux ){ + pAuxData->xDeleteAux(pAuxData->pAux); + } + + pAuxData->pAux = pAux; + pAuxData->xDeleteAux = xDelete; + return; + +failed: + if( xDelete ){ + xDelete(pAux); + } +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Return the number of times the Step function of an aggregate has been +** called. +** +** This function is deprecated. Do not use it for new code. It is +** provide only to avoid breaking legacy code. New aggregate function +** implementations should keep their own counts within their aggregate +** context. +*/ +SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ + assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize ); + return p->pMem->n; +} +#endif + +/* +** Return the number of columns in the result set for the statement pStmt. +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( pVm==0 ) return 0; + return pVm->nResColumn; +} + +/* +** Return the number of values available from the current row of the +** currently executing statement pStmt. +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( pVm==0 || pVm->pResultRow==0 ) return 0; + return pVm->nResColumn; +} + +/* +** Return a pointer to static memory containing an SQL NULL value. +*/ +static const Mem *columnNullValue(void){ + /* Even though the Mem structure contains an element + ** of type i64, on certain architectures (x86) with certain compiler + ** switches (-Os), gcc may align this Mem object on a 4-byte boundary + ** instead of an 8-byte one. This all works fine, except that when + ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s + ** that a Mem structure is located on an 8-byte boundary. To prevent + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical + ** __attribute__((aligned(8))) macro. */ + static const Mem nullMem +#if defined(SQLITE_DEBUG) && defined(__GNUC__) + __attribute__((aligned(8))) +#endif + = { + /* .u = */ {0}, + /* .z = */ (char*)0, + /* .n = */ (int)0, + /* .flags = */ (u16)MEM_Null, + /* .enc = */ (u8)0, + /* .eSubtype = */ (u8)0, + /* .db = */ (sqlite3*)0, + /* .szMalloc = */ (int)0, + /* .uTemp = */ (u32)0, + /* .zMalloc = */ (char*)0, + /* .xDel = */ (void(*)(void*))0, +#ifdef SQLITE_DEBUG + /* .pScopyFrom = */ (Mem*)0, + /* .mScopyFlags= */ 0, +#endif + }; + return &nullMem; +} + +/* +** Check to see if column iCol of the given statement is valid. If +** it is, return a pointer to the Mem for the value of that column. +** If iCol is not valid, return a pointer to a Mem which has a value +** of NULL. +*/ +static Mem *columnMem(sqlite3_stmt *pStmt, int i){ + Vdbe *pVm; + Mem *pOut; + + pVm = (Vdbe *)pStmt; + if( pVm==0 ) return (Mem*)columnNullValue(); + assert( pVm->db ); + sqlite3_mutex_enter(pVm->db->mutex); + if( pVm->pResultRow!=0 && inResColumn && i>=0 ){ + pOut = &pVm->pResultRow[i]; + }else{ + sqlite3Error(pVm->db, SQLITE_RANGE); + pOut = (Mem*)columnNullValue(); + } + return pOut; +} + +/* +** This function is called after invoking an sqlite3_value_XXX function on a +** column value (i.e. a value returned by evaluating an SQL expression in the +** select list of a SELECT statement) that may cause a malloc() failure. If +** malloc() has failed, the threads mallocFailed flag is cleared and the result +** code of statement pStmt set to SQLITE_NOMEM. +** +** Specifically, this is called from within: +** +** sqlite3_column_int() +** sqlite3_column_int64() +** sqlite3_column_text() +** sqlite3_column_text16() +** sqlite3_column_real() +** sqlite3_column_bytes() +** sqlite3_column_bytes16() +** sqlite3_column_blob() +*/ +static void columnMallocFailure(sqlite3_stmt *pStmt) +{ + /* If malloc() failed during an encoding conversion within an + ** sqlite3_column_XXX API, then set the return code of the statement to + ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR + ** and _finalize() will return NOMEM. + */ + Vdbe *p = (Vdbe *)pStmt; + if( p ){ + assert( p->db!=0 ); + assert( sqlite3_mutex_held(p->db->mutex) ); + p->rc = sqlite3ApiExit(p->db, p->rc); + sqlite3_mutex_leave(p->db->mutex); + } +} + +/**************************** sqlite3_column_ ******************************* +** The following routines are used to access elements of the current row +** in the result set. +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ + const void *val; + val = sqlite3_value_blob( columnMem(pStmt,i) ); + /* Even though there is no encoding conversion, value_blob() might + ** need to call malloc() to expand the result of a zeroblob() + ** expression. + */ + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){ + double val = sqlite3_value_double( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_int( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ + sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ + const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ + Mem *pOut = columnMem(pStmt, i); + if( pOut->flags&MEM_Static ){ + pOut->flags &= ~MEM_Static; + pOut->flags |= MEM_Ephem; + } + columnMallocFailure(pStmt); + return (sqlite3_value *)pOut; +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ + const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ + int iType = sqlite3_value_type( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return iType; +} + +/* +** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN. +*/ +static const char * const azExplainColNames8[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */ + "id", "parent", "notused", "detail" /* EQP */ +}; +static const u16 azExplainColNames16data[] = { + /* 0 */ 'a', 'd', 'd', 'r', 0, + /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0, + /* 12 */ 'p', '1', 0, + /* 15 */ 'p', '2', 0, + /* 18 */ 'p', '3', 0, + /* 21 */ 'p', '4', 0, + /* 24 */ 'p', '5', 0, + /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0, + /* 35 */ 'i', 'd', 0, + /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0, + /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0, + /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0 +}; +static const u8 iExplainColNames16[] = { + 0, 5, 12, 15, 18, 21, 24, 27, + 35, 38, 45, 53 +}; + +/* +** Convert the N-th element of pStmt->pColName[] into a string using +** xFunc() then return that string. If N is out of range, return 0. +** +** There are up to 5 names for each column. useType determines which +** name is returned. Here are the names: +** +** 0 The column name as it should be displayed for output +** 1 The datatype name for the column +** 2 The name of the database that the column derives from +** 3 The name of the table that the column derives from +** 4 The name of the table column that the result column derives from +** +** If the result is not a simple column reference (if it is an expression +** or a constant) then useTypes 2, 3, and 4 return NULL. +*/ +static const void *columnName( + sqlite3_stmt *pStmt, /* The statement */ + int N, /* Which column to get the name for */ + int useUtf16, /* True to return the name as UTF16 */ + int useType /* What type of name */ +){ + const void *ret; + Vdbe *p; + int n; + sqlite3 *db; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + if( N<0 ) return 0; + ret = 0; + p = (Vdbe *)pStmt; + db = p->db; + assert( db!=0 ); + sqlite3_mutex_enter(db->mutex); + + if( p->explain ){ + if( useType>0 ) goto columnName_end; + n = p->explain==1 ? 8 : 4; + if( N>=n ) goto columnName_end; + if( useUtf16 ){ + int i = iExplainColNames16[N + 8*p->explain - 8]; + ret = (void*)&azExplainColNames16data[i]; + }else{ + ret = (void*)azExplainColNames8[N + 8*p->explain - 8]; + } + goto columnName_end; + } + n = p->nResColumn; + if( NmallocFailed; + N += useType*n; +#ifndef SQLITE_OMIT_UTF16 + if( useUtf16 ){ + ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); + }else +#endif + { + ret = sqlite3_value_text((sqlite3_value*)&p->aColName[N]); + } + /* A malloc may have failed inside of the _text() call. If this + ** is the case, clear the mallocFailed flag and return NULL. + */ + assert( db->mallocFailed==0 || db->mallocFailed==1 ); + if( db->mallocFailed > prior_mallocFailed ){ + sqlite3OomClear(db); + ret = 0; + } + } +columnName_end: + sqlite3_mutex_leave(db->mutex); + return ret; +} + +/* +** Return the name of the Nth column of the result set returned by SQL +** statement pStmt. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_NAME); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_NAME); +} +#endif + +/* +** Constraint: If you have ENABLE_COLUMN_METADATA then you must +** not define OMIT_DECLTYPE. +*/ +#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA) +# error "Must not define both SQLITE_OMIT_DECLTYPE \ + and SQLITE_ENABLE_COLUMN_METADATA" +#endif + +#ifndef SQLITE_OMIT_DECLTYPE +/* +** Return the column declaration type (if applicable) of the 'i'th column +** of the result set of SQL statement pStmt. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_DECLTYPE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_DECLTYPE); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_DECLTYPE */ + +#ifdef SQLITE_ENABLE_COLUMN_METADATA +/* +** Return the name of the database from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unambiguous reference to a database column. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_DATABASE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_DATABASE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the name of the table from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unambiguous reference to a database column. +*/ +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_TABLE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_TABLE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the name of the table column from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unambiguous reference to a database column. +*/ +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_COLUMN); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_COLUMN); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_ENABLE_COLUMN_METADATA */ + + +/******************************* sqlite3_bind_ *************************** +** +** Routines used to attach values to wildcards in a compiled SQL statement. +*/ +/* +** Unbind the value bound to variable i in virtual machine p. This is the +** the same as binding a NULL value to the column. If the "i" parameter is +** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. +** +** A successful evaluation of this routine acquires the mutex on p. +** the mutex is released if any kind of error occurs. +** +** The error code stored in database p->db is overwritten with the return +** value in any case. +*/ +static int vdbeUnbind(Vdbe *p, unsigned int i){ + Mem *pVar; + if( vdbeSafetyNotNull(p) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(p->db->mutex); + if( p->eVdbeState!=VDBE_READY_STATE ){ + sqlite3Error(p->db, SQLITE_MISUSE_BKPT); + sqlite3_mutex_leave(p->db->mutex); + sqlite3_log(SQLITE_MISUSE, + "bind on a busy prepared statement: [%s]", p->zSql); + return SQLITE_MISUSE_BKPT; + } + if( i>=(unsigned int)p->nVar ){ + sqlite3Error(p->db, SQLITE_RANGE); + sqlite3_mutex_leave(p->db->mutex); + return SQLITE_RANGE; + } + pVar = &p->aVar[i]; + sqlite3VdbeMemRelease(pVar); + pVar->flags = MEM_Null; + p->db->errCode = SQLITE_OK; + + /* If the bit corresponding to this variable in Vdbe.expmask is set, then + ** binding a new value to this variable invalidates the current query plan. + ** + ** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host + ** parameter in the WHERE clause might influence the choice of query plan + ** for a statement, then the statement will be automatically recompiled, + ** as if there had been a schema change, on the first sqlite3_step() call + ** following any change to the bindings of that parameter. + */ + assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); + if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<expired = 1; + } + return SQLITE_OK; +} + +/* +** Bind a text or BLOB value. +*/ +static int bindText( + sqlite3_stmt *pStmt, /* The statement to bind against */ + int i, /* Index of the parameter to bind */ + const void *zData, /* Pointer to the data to be bound */ + i64 nData, /* Number of bytes of data to be bound */ + void (*xDel)(void*), /* Destructor for the data */ + u8 encoding /* Encoding for the data */ +){ + Vdbe *p = (Vdbe *)pStmt; + Mem *pVar; + int rc; + + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + if( zData!=0 ){ + pVar = &p->aVar[i-1]; + rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); + if( rc==SQLITE_OK && encoding!=0 ){ + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + } + if( rc ){ + sqlite3Error(p->db, rc); + rc = sqlite3ApiExit(p->db, rc); + } + } + sqlite3_mutex_leave(p->db->mutex); + }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ + xDel((void*)zData); + } + return rc; +} + + +/* +** Bind a blob value to an SQL statement variable. +*/ +SQLITE_API int sqlite3_bind_blob( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( nData<0 ) return SQLITE_MISUSE_BKPT; +#endif + return bindText(pStmt, i, zData, nData, xDel, 0); +} +SQLITE_API int sqlite3_bind_blob64( + sqlite3_stmt *pStmt, + int i, + const void *zData, + sqlite3_uint64 nData, + void (*xDel)(void*) +){ + assert( xDel!=SQLITE_DYNAMIC ); + return bindText(pStmt, i, zData, nData, xDel, 0); +} +SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ + return sqlite3_bind_int64(p, i, (i64)iValue); +} +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_pointer( + sqlite3_stmt *pStmt, + int i, + void *pPtr, + const char *zPTtype, + void (*xDestructor)(void*) +){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); + sqlite3_mutex_leave(p->db->mutex); + }else if( xDestructor ){ + xDestructor(pPtr); + } + return rc; +} +SQLITE_API int sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); +} +SQLITE_API int sqlite3_bind_text64( + sqlite3_stmt *pStmt, + int i, + const char *zData, + sqlite3_uint64 nData, + void (*xDel)(void*), + unsigned char enc +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( enc!=SQLITE_UTF8 ){ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + nData &= ~(u16)1; + } + return bindText(pStmt, i, zData, nData, xDel, enc); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API int sqlite3_bind_text16( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int n, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE); +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ + int rc; + switch( sqlite3_value_type((sqlite3_value*)pValue) ){ + case SQLITE_INTEGER: { + rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); + break; + } + case SQLITE_FLOAT: { + assert( pValue->flags & (MEM_Real|MEM_IntReal) ); + rc = sqlite3_bind_double(pStmt, i, + (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i + ); + break; + } + case SQLITE_BLOB: { + if( pValue->flags & MEM_Zero ){ + rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero); + }else{ + rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT); + } + break; + } + case SQLITE_TEXT: { + rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT, + pValue->enc); + break; + } + default: { + rc = sqlite3_bind_null(pStmt, i); + break; + } + } + return rc; +} +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_INCRBLOB + sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); +#else + rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); +#endif + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ + int rc; + Vdbe *p = (Vdbe *)pStmt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(p->db->mutex); + if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + rc = SQLITE_TOOBIG; + }else{ + assert( (n & 0x7FFFFFFF)==n ); + rc = sqlite3_bind_zeroblob(pStmt, i, n); + } + rc = sqlite3ApiExit(p->db, rc); + sqlite3_mutex_leave(p->db->mutex); + return rc; +} + +/* +** Return the number of wildcards that can be potentially bound to. +** This routine is added to support DBD::SQLite. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p ? p->nVar : 0; +} + +/* +** Return the name of a wildcard parameter. Return NULL if the index +** is out of range or if the wildcard is unnamed. +** +** The result is always UTF-8. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ + Vdbe *p = (Vdbe*)pStmt; + if( p==0 ) return 0; + return sqlite3VListNumToName(p->pVList, i); +} + +/* +** Given a wildcard parameter name, return the index of the variable +** with that name. If there is no variable with the given name, +** return 0. +*/ +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ + if( p==0 || zName==0 ) return 0; + return sqlite3VListNameToNum(p->pVList, zName, nName); +} +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ + return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); +} + +/* +** Transfer all bindings from the first statement over to the second. +*/ +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + int i; + assert( pTo->db==pFrom->db ); + assert( pTo->nVar==pFrom->nVar ); + sqlite3_mutex_enter(pTo->db->mutex); + for(i=0; inVar; i++){ + sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); + } + sqlite3_mutex_leave(pTo->db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. Internal/core SQLite code +** should call sqlite3TransferBindings. +** +** It is misuse to call this routine with statements from different +** database connections. But as this is a deprecated interface, we +** will not bother to check for that condition. +** +** If the two statements contain a different number of bindings, then +** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise +** SQLITE_OK is returned. +*/ +SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + if( pFrom->nVar!=pTo->nVar ){ + return SQLITE_ERROR; + } + assert( (pTo->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pTo->expmask==0 ); + if( pTo->expmask ){ + pTo->expired = 1; + } + assert( (pFrom->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pFrom->expmask==0 ); + if( pFrom->expmask ){ + pFrom->expired = 1; + } + return sqlite3TransferBindings(pFromStmt, pToStmt); +} +#endif + +/* +** Return the sqlite3* database handle to which the prepared statement given +** in the argument belongs. This is the same database handle that was +** the first argument to the sqlite3_prepare() that was used to create +** the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->db : 0; +} + +/* +** Return true if the prepared statement is guaranteed to not modify the +** database. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; +} + +/* +** Return 1 if the statement is an EXPLAIN and return 2 if the +** statement is an EXPLAIN QUERY PLAN +*/ +SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->explain : 0; +} + +/* +** Set the explain mode for a statement. +*/ +SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ + Vdbe *v = (Vdbe*)pStmt; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(v->db->mutex); + if( ((int)v->explain)==eMode ){ + rc = SQLITE_OK; + }else if( eMode<0 || eMode>2 ){ + rc = SQLITE_ERROR; + }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ + rc = SQLITE_ERROR; + }else if( v->eVdbeState!=VDBE_READY_STATE ){ + rc = SQLITE_BUSY; + }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ + /* No reprepare necessary */ + v->explain = eMode; + rc = SQLITE_OK; + }else{ + v->explain = eMode; + rc = sqlite3Reprepare(v); + v->haveEqpOps = eMode==2; + } + if( v->explain ){ + v->nResColumn = 12 - 4*v->explain; + }else{ + v->nResColumn = v->nResAlloc; + } + sqlite3_mutex_leave(v->db->mutex); + return rc; +} + +/* +** Return true if the prepared statement is in need of being reset. +*/ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ + Vdbe *v = (Vdbe*)pStmt; + return v!=0 && v->eVdbeState==VDBE_RUN_STATE; +} + +/* +** Return a pointer to the next prepared statement after pStmt associated +** with database connection pDb. If pStmt is NULL, return the first +** prepared statement for the database connection. Return NULL if there +** are no more. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ + sqlite3_stmt *pNext; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(pDb) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(pDb->mutex); + if( pStmt==0 ){ + pNext = (sqlite3_stmt*)pDb->pVdbe; + }else{ + pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pVNext; + } + sqlite3_mutex_leave(pDb->mutex); + return pNext; +} + +/* +** Return the value of a status counter for a prepared statement +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ + Vdbe *pVdbe = (Vdbe*)pStmt; + u32 v; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !pStmt + || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter))) + ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + if( op==SQLITE_STMTSTATUS_MEMUSED ){ + sqlite3 *db = pVdbe->db; + sqlite3_mutex_enter(db->mutex); + v = 0; + db->pnBytesFreed = (int*)&v; + assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); + db->lookaside.pEnd = db->lookaside.pStart; + sqlite3VdbeDelete(pVdbe); + db->pnBytesFreed = 0; + db->lookaside.pEnd = db->lookaside.pTrueEnd; + sqlite3_mutex_leave(db->mutex); + }else{ + v = pVdbe->aCounter[op]; + if( resetFlag ) pVdbe->aCounter[op] = 0; + } + return (int)v; +} + +/* +** Return the SQL associated with a prepared statement +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + return p ? p->zSql : 0; +} + +/* +** Return the SQL associated with a prepared statement with +** bound parameters expanded. Space to hold the returned string is +** obtained from sqlite3_malloc(). The caller is responsible for +** freeing the returned string by passing it to sqlite3_free(). +** +** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of +** expanded bound parameters. +*/ +SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ +#ifdef SQLITE_OMIT_TRACE + return 0; +#else + char *z = 0; + const char *zSql = sqlite3_sql(pStmt); + if( zSql ){ + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + z = sqlite3VdbeExpandSql(p, zSql); + sqlite3_mutex_leave(p->db->mutex); + } + return z; +#endif +} + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Return the normalized SQL associated with a prepared statement. +*/ +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + if( p==0 ) return 0; + if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){ + sqlite3_mutex_enter(p->db->mutex); + p->zNormSql = sqlite3Normalize(p, p->zSql); + sqlite3_mutex_leave(p->db->mutex); + } + return p->zNormSql; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** Allocate and populate an UnpackedRecord structure based on the serialized +** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure +** if successful, or a NULL pointer if an OOM error is encountered. +*/ +static UnpackedRecord *vdbeUnpackRecord( + KeyInfo *pKeyInfo, + int nKey, + const void *pKey +){ + UnpackedRecord *pRet; /* Return value */ + + pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( pRet ){ + memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); + sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); + } + return pRet; +} + +/* +** This function is called from within a pre-update callback to retrieve +** a field of the row currently being updated or deleted. +*/ +SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ + PreUpdate *p; + Mem *pMem; + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; + /* Test that this call is being made from within an SQLITE_DELETE or + ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ + if( !p || p->op==SQLITE_INSERT ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_old_out; + } + if( p->pPk ){ + iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); + } + if( iIdx>=p->pCsr->nField || iIdx<0 ){ + rc = SQLITE_RANGE; + goto preupdate_old_out; + } + + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; + + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; + } + p->aRecord = aRec; + } + + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else if( iIdx>=p->pUnpacked->nField ){ + *ppValue = (sqlite3_value *)columnNullValue(); + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); + } + } + + preupdate_old_out: + sqlite3Error(db, rc); + return sqlite3ApiExit(db, rc); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is called from within a pre-update callback to retrieve +** the number of columns in the row being updated, deleted or inserted. +*/ +SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif + return (p ? p->keyinfo.nKeyField : 0); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is designed to be called from within a pre-update callback +** only. It returns zero if the change that caused the callback was made +** immediately by a user SQL statement. Or, if the change was made by a +** trigger program, it returns the number of trigger programs currently +** on the stack (1 for a top-level trigger, 2 for a trigger fired by a +** top-level trigger etc.). +** +** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL +** or SET DEFAULT action is considered a trigger. +*/ +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif + return (p ? p->v->nFrame : 0); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is designed to be called from within a pre-update callback +** only. +*/ +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif + return (p ? p->iBlobWrite : -1); +} +#endif + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is called from within a pre-update callback to retrieve +** a field of the row currently being updated or inserted. +*/ +SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ + PreUpdate *p; + int rc = SQLITE_OK; + Mem *pMem; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; + if( !p || p->op==SQLITE_DELETE ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_new_out; + } + if( p->pPk && p->op!=SQLITE_UPDATE ){ + iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); + } + if( iIdx>=p->pCsr->nField || iIdx<0 ){ + rc = SQLITE_RANGE; + goto preupdate_new_out; + } + + if( p->op==SQLITE_INSERT ){ + /* For an INSERT, memory cell p->iNewReg contains the serialized record + ** that is being inserted. Deserialize it. */ + UnpackedRecord *pUnpack = p->pNewUnpacked; + if( !pUnpack ){ + Mem *pData = &p->v->aMem[p->iNewReg]; + rc = ExpandBlob(pData); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z); + if( !pUnpack ){ + rc = SQLITE_NOMEM; + goto preupdate_new_out; + } + p->pNewUnpacked = pUnpack; + } + pMem = &pUnpack->aMem[iIdx]; + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + }else if( iIdx>=pUnpack->nField ){ + pMem = (sqlite3_value *)columnNullValue(); + } + }else{ + /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required + ** value. Make a copy of the cell contents and return a pointer to it. + ** It is not safe to return a pointer to the memory cell itself as the + ** caller may modify the value text encoding. + */ + assert( p->op==SQLITE_UPDATE ); + if( !p->aNew ){ + p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); + if( !p->aNew ){ + rc = SQLITE_NOMEM; + goto preupdate_new_out; + } + } + assert( iIdx>=0 && iIdxpCsr->nField ); + pMem = &p->aNew[iIdx]; + if( pMem->flags==0 ){ + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + }else{ + rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + } + } + } + *ppValue = pMem; + + preupdate_new_out: + sqlite3Error(db, rc); + return sqlite3ApiExit(db, rc); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Return status data for a single loop within query pStmt. +*/ +SQLITE_API int sqlite3_stmt_scanstatus_v2( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ + int iScan, /* Index of loop to report on */ + int iScanStatusOp, /* Which metric to return */ + int flags, + void *pOut /* OUT: Write the answer here */ +){ + Vdbe *p = (Vdbe*)pStmt; + VdbeOp *aOp; + int nOp; + ScanStatus *pScan = 0; + int idx; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 || pOut==0 + || iScanStatusOpSQLITE_SCANSTAT_NCYCLE ){ + return 1; + } +#endif + aOp = p->aOp; + nOp = p->nOp; + if( p->pFrame ){ + VdbeFrame *pFrame; + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + aOp = pFrame->aOp; + nOp = pFrame->nOp; + } + + if( iScan<0 ){ + int ii; + if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){ + i64 res = 0; + for(ii=0; iiaScan[idx]; + }else{ + /* If the COMPLEX flag is clear, then this function must ignore any + ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ + for(idx=0; idxnScan; idx++){ + pScan = &p->aScan[idx]; + if( pScan->zName ){ + iScan--; + if( iScan<0 ) break; + } + } + } + if( idx>=p->nScan ) return 1; + + switch( iScanStatusOp ){ + case SQLITE_SCANSTAT_NLOOP: { + if( pScan->addrLoop>0 ){ + *(sqlite3_int64*)pOut = aOp[pScan->addrLoop].nExec; + }else{ + *(sqlite3_int64*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_NVISIT: { + if( pScan->addrVisit>0 ){ + *(sqlite3_int64*)pOut = aOp[pScan->addrVisit].nExec; + }else{ + *(sqlite3_int64*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_EST: { + double r = 1.0; + LogEst x = pScan->nEst; + while( x<100 ){ + x += 10; + r *= 0.5; + } + *(double*)pOut = r*sqlite3LogEstToInt(x); + break; + } + case SQLITE_SCANSTAT_NAME: { + *(const char**)pOut = pScan->zName; + break; + } + case SQLITE_SCANSTAT_EXPLAIN: { + if( pScan->addrExplain ){ + *(const char**)pOut = aOp[ pScan->addrExplain ].p4.z; + }else{ + *(const char**)pOut = 0; + } + break; + } + case SQLITE_SCANSTAT_SELECTID: { + if( pScan->addrExplain ){ + *(int*)pOut = aOp[ pScan->addrExplain ].p1; + }else{ + *(int*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_PARENTID: { + if( pScan->addrExplain ){ + *(int*)pOut = aOp[ pScan->addrExplain ].p2; + }else{ + *(int*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_NCYCLE: { + i64 res = 0; + if( pScan->aAddrRange[0]==0 ){ + res = -1; + }else{ + int ii; + for(ii=0; iiaAddrRange); ii+=2){ + int iIns = pScan->aAddrRange[ii]; + int iEnd = pScan->aAddrRange[ii+1]; + if( iIns==0 ) break; + if( iIns>0 ){ + while( iIns<=iEnd ){ + res += aOp[iIns].nCycle; + iIns++; + } + }else{ + int iOp; + for(iOp=0; iOpp1!=iEnd ) continue; + if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){ + continue; + } + res += aOp[iOp].nCycle; + } + } + } + } + *(i64*)pOut = res; + break; + } + default: { + return 1; + } + } + return 0; +} + +/* +** Return status data for a single loop within query pStmt. +*/ +SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ + int iScan, /* Index of loop to report on */ + int iScanStatusOp, /* Which metric to return */ + void *pOut /* OUT: Write the answer here */ +){ + return sqlite3_stmt_scanstatus_v2(pStmt, iScan, iScanStatusOp, 0, pOut); +} + +/* +** Zero all counters associated with the sqlite3_stmt_scanstatus() data. +*/ +SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + int ii; + for(ii=0; p!=0 && iinOp; ii++){ + Op *pOp = &p->aOp[ii]; + pOp->nExec = 0; + pOp->nCycle = 0; + } +} +#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ + +/************** End of vdbeapi.c *********************************************/ +/************** Begin file vdbetrace.c ***************************************/ +/* +** 2009 November 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to insert the values of host parameters +** (aka "wildcards") into the SQL text output by sqlite3_trace(). +** +** The Vdbe parse-tree explainer is also found here. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +#ifndef SQLITE_OMIT_TRACE + +/* +** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of +** bytes in this text up to but excluding the first character in +** a host parameter. If the text contains no host parameters, return +** the total number of bytes in the text. +*/ +static int findNextHostParameter(const char *zSql, int *pnToken){ + int tokenType; + int nTotal = 0; + int n; + + *pnToken = 0; + while( zSql[0] ){ + n = sqlite3GetToken((u8*)zSql, &tokenType); + assert( n>0 && tokenType!=TK_ILLEGAL ); + if( tokenType==TK_VARIABLE ){ + *pnToken = n; + break; + } + nTotal += n; + zSql += n; + } + return nTotal; +} + +/* +** This function returns a pointer to a nul-terminated string in memory +** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the +** string contains a copy of zRawSql but with host parameters expanded to +** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, +** then the returned string holds a copy of zRawSql with "-- " prepended +** to each line of text. +** +** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then +** then long strings and blobs are truncated to that many bytes. This +** can be used to prevent unreasonably large trace strings when dealing +** with large (multi-megabyte) strings and blobs. +** +** The calling function is responsible for making sure the memory returned +** is eventually freed. +** +** ALGORITHM: Scan the input string looking for host parameters in any of +** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within +** string literals, quoted identifier names, and comments. For text forms, +** the host parameter index is found by scanning the prepared +** statement for the corresponding OP_Variable opcode. Once the host +** parameter index is known, locate the value in p->aVar[]. Then render +** the value as a literal in place of the host parameter name. +*/ +SQLITE_PRIVATE char *sqlite3VdbeExpandSql( + Vdbe *p, /* The prepared statement being evaluated */ + const char *zRawSql /* Raw text of the SQL statement */ +){ + sqlite3 *db; /* The database connection */ + int idx = 0; /* Index of a host parameter */ + int nextIndex = 1; /* Index of next ? host parameter */ + int n; /* Length of a token prefix */ + int nToken; /* Length of the parameter token */ + int i; /* Loop counter */ + Mem *pVar; /* Value of a host parameter */ + StrAccum out; /* Accumulate the output here */ +#ifndef SQLITE_OMIT_UTF16 + Mem utf8; /* Used to convert UTF16 into UTF8 for display */ +#endif + + db = p->db; + sqlite3StrAccumInit(&out, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + if( db->nVdbeExec>1 ){ + while( *zRawSql ){ + const char *zStart = zRawSql; + while( *(zRawSql++)!='\n' && *zRawSql ); + sqlite3_str_append(&out, "-- ", 3); + assert( (zRawSql - zStart) > 0 ); + sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart)); + } + }else if( p->nVar==0 ){ + sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql)); + }else{ + while( zRawSql[0] ){ + n = findNextHostParameter(zRawSql, &nToken); + assert( n>0 ); + sqlite3_str_append(&out, zRawSql, n); + zRawSql += n; + assert( zRawSql[0] || nToken==0 ); + if( nToken==0 ) break; + if( zRawSql[0]=='?' ){ + if( nToken>1 ){ + assert( sqlite3Isdigit(zRawSql[1]) ); + sqlite3GetInt32(&zRawSql[1], &idx); + }else{ + idx = nextIndex; + } + }else{ + assert( zRawSql[0]==':' || zRawSql[0]=='$' || + zRawSql[0]=='@' || zRawSql[0]=='#' ); + testcase( zRawSql[0]==':' ); + testcase( zRawSql[0]=='$' ); + testcase( zRawSql[0]=='@' ); + testcase( zRawSql[0]=='#' ); + idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); + assert( idx>0 ); + } + zRawSql += nToken; + nextIndex = MAX(idx + 1, nextIndex); + assert( idx>0 && idx<=p->nVar ); + pVar = &p->aVar[idx-1]; + if( pVar->flags & MEM_Null ){ + sqlite3_str_append(&out, "NULL", 4); + }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){ + sqlite3_str_appendf(&out, "%lld", pVar->u.i); + }else if( pVar->flags & MEM_Real ){ + sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); + }else if( pVar->flags & MEM_Str ){ + int nOut; /* Number of bytes of the string text to include in output */ +#ifndef SQLITE_OMIT_UTF16 + u8 enc = ENC(db); + if( enc!=SQLITE_UTF8 ){ + memset(&utf8, 0, sizeof(utf8)); + utf8.db = db; + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); + if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ + out.accError = SQLITE_NOMEM; + out.nAlloc = 0; + } + pVar = &utf8; + } +#endif + nOut = pVar->n; +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ + nOut = SQLITE_TRACE_SIZE_LIMIT; + while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } + } +#endif + sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z); +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOutn ){ + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); + } +#endif +#ifndef SQLITE_OMIT_UTF16 + if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); +#endif + }else if( pVar->flags & MEM_Zero ){ + sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero); + }else{ + int nOut; /* Number of bytes of the blob to include in output */ + assert( pVar->flags & MEM_Blob ); + sqlite3_str_append(&out, "x'", 2); + nOut = pVar->n; +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; +#endif + for(i=0; iz[i]&0xff); + } + sqlite3_str_append(&out, "'", 1); +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOutn ){ + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); + } +#endif + } + } + } + if( out.accError ) sqlite3_str_reset(&out); + return sqlite3StrAccumFinish(&out); +} + +#endif /* #ifndef SQLITE_OMIT_TRACE */ + +/************** End of vdbetrace.c *******************************************/ +/************** Begin file vdbe.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** The code in this file implements the function that runs the +** bytecode of a prepared statement. +** +** Various scripts scan this source file in order to generate HTML +** documentation, headers files, or other derived files. The formatting +** of the code in this file is, therefore, important. See other comments +** in this file for details. If in doubt, do not deviate from existing +** commenting and indentation practices when changing or adding code. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* +** Invoke this macro on memory cells just prior to changing the +** value of the cell. This macro verifies that shallow copies are +** not misused. A shallow copy of a string or blob just copies a +** pointer to the string or blob, not the content. If the original +** is changed while the copy is still in use, the string or blob might +** be changed out from under the copy. This macro verifies that nothing +** like that ever happens. +*/ +#ifdef SQLITE_DEBUG +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) +#else +# define memAboutToChange(P,M) +#endif + +/* +** The following global variable is incremented every time a cursor +** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test +** procedures use this information to make sure that indices are +** working correctly. This variable has no function other than to +** help verify the correct operation of the library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_search_count = 0; +#endif + +/* +** When this global variable is positive, it gets decremented once before +** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted +** field of the sqlite3 structure is set in order to simulate an interrupt. +** +** This facility is used for testing purposes only. It does not function +** in an ordinary build. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_interrupt_count = 0; +#endif + +/* +** The next global variable is incremented each type the OP_Sort opcode +** is executed. The test procedures use this information to make sure that +** sorting is occurring or not occurring at appropriate times. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_sort_count = 0; +#endif + +/* +** The next global variable records the size of the largest MEM_Blob +** or MEM_Str that has been used by a VDBE opcode. The test procedures +** use this information to make sure that the zero-blob functionality +** is working correctly. This variable has no function other than to +** help verify the correct operation of the library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_max_blobsize = 0; +static void updateMaxBlobsize(Mem *p){ + if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ + sqlite3_max_blobsize = p->n; + } +} +#endif + +/* +** This macro evaluates to true if either the update hook or the preupdate +** hook are enabled for database connect DB. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback) +#else +# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback) +#endif + +/* +** The next global variable is incremented each time the OP_Found opcode +** is executed. This is used to test whether or not the foreign key +** operation implemented using OP_FkIsZero is working. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_found_count = 0; +#endif + +/* +** Test a register to see if it exceeds the current maximum blob size. +** If it does, record the new maximum blob size. +*/ +#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE) +# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) +#else +# define UPDATE_MAX_BLOBSIZE(P) +#endif + +#ifdef SQLITE_DEBUG +/* This routine provides a convenient place to set a breakpoint during +** tracing with PRAGMA vdbe_trace=on. The breakpoint fires right after +** each opcode is printed. Variables "pc" (program counter) and pOp are +** available to add conditionals to the breakpoint. GDB example: +** +** break test_trace_breakpoint if pc=22 +** +** Other useful labels for breakpoints include: +** test_addop_breakpoint(pc,pOp) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) +*/ +static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ + static u64 n = 0; + (void)pc; + (void)pOp; + (void)v; + n++; + if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ +} +#endif + +/* +** Invoke the VDBE coverage callback, if that callback is defined. This +** feature is used for test suite validation only and does not appear an +** production builds. +** +** M is the type of branch. I is the direction taken for this instance of +** the branch. +** +** M: 2 - two-way branch (I=0: fall-thru 1: jump ) +** 3 - two-way + NULL (I=0: fall-thru 1: jump 2: NULL ) +** 4 - OP_Jump (I=0: jump p1 1: jump p2 2: jump p3) +** +** In other words, if M is 2, then I is either 0 (for fall-through) or +** 1 (for when the branch is taken). If M is 3, the I is 0 for an +** ordinary fall-through, I is 1 if the branch was taken, and I is 2 +** if the result of comparison is NULL. For M=3, I=2 the jump may or +** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5. +** When M is 4, that means that an OP_Jump is being run. I is 0, 1, or 2 +** depending on if the operands are less than, equal, or greater than. +** +** iSrcLine is the source code line (from the __LINE__ macro) that +** generated the VDBE instruction combined with flag bits. The source +** code line number is in the lower 24 bits of iSrcLine and the upper +** 8 bytes are flags. The lower three bits of the flags indicate +** values for I that should never occur. For example, if the branch is +** always taken, the flags should be 0x05 since the fall-through and +** alternate branch are never taken. If a branch is never taken then +** flags should be 0x06 since only the fall-through approach is allowed. +** +** Bit 0x08 of the flags indicates an OP_Jump opcode that is only +** interested in equal or not-equal. In other words, I==0 and I==2 +** should be treated as equivalent +** +** Since only a line number is retained, not the filename, this macro +** only works for amalgamation builds. But that is ok, since these macros +** should be no-ops except for special builds used to measure test coverage. +*/ +#if !defined(SQLITE_VDBE_COVERAGE) +# define VdbeBranchTaken(I,M) +#else +# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) + static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){ + u8 mNever; + assert( I<=2 ); /* 0: fall through, 1: taken, 2: alternate taken */ + assert( M<=4 ); /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */ + assert( I> 24; + assert( (I & mNever)==0 ); + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + /* Invoke the branch coverage callback with three arguments: + ** iSrcLine - the line number of the VdbeCoverage() macro, with + ** flags removed. + ** I - Mask of bits 0x07 indicating which cases are are + ** fulfilled by this instance of the jump. 0x01 means + ** fall-thru, 0x02 means taken, 0x04 means NULL. Any + ** impossible cases (ex: if the comparison is never NULL) + ** are filled in automatically so that the coverage + ** measurement logic does not flag those impossible cases + ** as missed coverage. + ** M - Type of jump. Same as M argument above + */ + I |= mNever; + if( M==2 ) I |= 0x04; + if( M==4 ){ + I |= 0x08; + if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/ + } + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, + iSrcLine&0xffffff, I, M); + } +#endif + +/* +** An ephemeral string value (signified by the MEM_Ephem flag) contains +** a pointer to a dynamically allocated string where some other entity +** is responsible for deallocating that string. Because the register +** does not control the string, it might be deleted without the register +** knowing it. +** +** This routine converts an ephemeral string into a dynamically allocated +** string that the register itself controls. In other words, it +** converts an MEM_Ephem string into a string with P.z==P.zMalloc. +*/ +#define Deephemeralize(P) \ + if( ((P)->flags&MEM_Ephem)!=0 \ + && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} + +/* Return true if the cursor was opened using the OP_OpenSorter opcode. */ +#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER) + +/* +** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL +** if we run out of memory. +*/ +static VdbeCursor *allocateCursor( + Vdbe *p, /* The virtual machine */ + int iCur, /* Index of the new VdbeCursor */ + int nField, /* Number of fields in the table or index */ + u8 eCurType /* Type of the new cursor */ +){ + /* Find the memory cell that will be used to store the blob of memory + ** required for this VdbeCursor structure. It is convenient to use a + ** vdbe memory cell to manage the memory allocation required for a + ** VdbeCursor structure for the following reasons: + ** + ** * Sometimes cursor numbers are used for a couple of different + ** purposes in a vdbe program. The different uses might require + ** different sized allocations. Memory cells provide growable + ** allocations. + ** + ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can + ** be freed lazily via the sqlite3_release_memory() API. This + ** minimizes the number of malloc calls made by the system. + ** + ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from + ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. + ** Cursor 2 is at Mem[p->nMem-2]. And so forth. + */ + Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; + + int nByte; + VdbeCursor *pCx = 0; + nByte = + ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); + + assert( iCur>=0 && iCurnCursor ); + if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ + sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]); + p->apCsr[iCur] = 0; + } + + /* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure + ** the pMem used to hold space for the cursor has enough storage available + ** in pMem->zMalloc. But for the special case of the aMem[] entries used + ** to hold cursors, it is faster to in-line the logic. */ + assert( pMem->flags==MEM_Undefined ); + assert( (pMem->flags & MEM_Dyn)==0 ); + assert( pMem->szMalloc==0 || pMem->z==pMem->zMalloc ); + if( pMem->szMallocszMalloc>0 ){ + sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + } + pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte); + if( pMem->zMalloc==0 ){ + pMem->szMalloc = 0; + return 0; + } + pMem->szMalloc = nByte; + } + + p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; + memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); + pCx->eCurType = eCurType; + pCx->nField = nField; + pCx->aOffset = &pCx->aType[nField]; + if( eCurType==CURTYPE_BTREE ){ + pCx->uc.pCursor = (BtCursor*) + &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; + sqlite3BtreeCursorZero(pCx->uc.pCursor); + } + return pCx; +} + +/* +** The string in pRec is known to look like an integer and to have a +** floating point value of rValue. Return true and set *piValue to the +** integer value if the string is in range to be an integer. Otherwise, +** return false. +*/ +static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ + i64 iValue; + iValue = sqlite3RealToI64(rValue); + if( sqlite3RealSameAsInt(rValue,iValue) ){ + *piValue = iValue; + return 1; + } + return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc); +} + +/* +** Try to convert a value into a numeric representation if we can +** do so without loss of information. In other words, if the string +** looks like a number, convert it into a number. If it does not +** look like a number, leave it alone. +** +** If the bTryForInt flag is true, then extra effort is made to give +** an integer representation. Strings that look like floating point +** values but which have no fractional component (example: '48.00') +** will have a MEM_Int representation when bTryForInt is true. +** +** If bTryForInt is false, then if the input string contains a decimal +** point or exponential notation, the result is only MEM_Real, even +** if there is an exact integer representation of the quantity. +*/ +static void applyNumericAffinity(Mem *pRec, int bTryForInt){ + double rValue; + u8 enc = pRec->enc; + int rc; + assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); + rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc); + if( rc<=0 ) return; + if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ + pRec->flags |= MEM_Int; + }else{ + pRec->u.r = rValue; + pRec->flags |= MEM_Real; + if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); + } + /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the + ** string representation after computing a numeric equivalent, because the + ** string representation might not be the canonical representation for the + ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */ + pRec->flags &= ~MEM_Str; +} + +/* +** Processing is determine by the affinity parameter: +** +** SQLITE_AFF_INTEGER: +** SQLITE_AFF_REAL: +** SQLITE_AFF_NUMERIC: +** Try to convert pRec to an integer representation or a +** floating-point representation if an integer representation +** is not possible. Note that the integer representation is +** always preferred, even if the affinity is REAL, because +** an integer representation is more space efficient on disk. +** +** SQLITE_AFF_FLEXNUM: +** If the value is text, then try to convert it into a number of +** some kind (integer or real) but do not make any other changes. +** +** SQLITE_AFF_TEXT: +** Convert pRec to a text representation. +** +** SQLITE_AFF_BLOB: +** SQLITE_AFF_NONE: +** No-op. pRec is unchanged. +*/ +static void applyAffinity( + Mem *pRec, /* The value to apply affinity to */ + char affinity, /* The affinity to be applied */ + u8 enc /* Use this text encoding */ +){ + if( affinity>=SQLITE_AFF_NUMERIC ){ + assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL + || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM ); + if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + if( (pRec->flags & (MEM_Real|MEM_IntReal))==0 ){ + if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); + }else if( affinity<=SQLITE_AFF_REAL ){ + sqlite3VdbeIntegerAffinity(pRec); + } + } + }else if( affinity==SQLITE_AFF_TEXT ){ + /* Only attempt the conversion to TEXT if there is an integer or real + ** representation (blob and NULL do not get converted) but no string + ** representation. It would be harmless to repeat the conversion if + ** there is already a string rep, but it is pointless to waste those + ** CPU cycles. */ + if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ + if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){ + testcase( pRec->flags & MEM_Int ); + testcase( pRec->flags & MEM_Real ); + testcase( pRec->flags & MEM_IntReal ); + sqlite3VdbeMemStringify(pRec, enc, 1); + } + } + pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal); + } +} + +/* +** Try to convert the type of a function argument or a result column +** into a numeric representation. Use either INTEGER or REAL whichever +** is appropriate. But only do the conversion if it is possible without +** loss of information and return the revised type of the argument. +*/ +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ + int eType = sqlite3_value_type(pVal); + if( eType==SQLITE_TEXT ){ + Mem *pMem = (Mem*)pVal; + applyNumericAffinity(pMem, 0); + eType = sqlite3_value_type(pVal); + } + return eType; +} + +/* +** Exported version of applyAffinity(). This one works on sqlite3_value*, +** not the internal Mem* type. +*/ +SQLITE_PRIVATE void sqlite3ValueApplyAffinity( + sqlite3_value *pVal, + u8 affinity, + u8 enc +){ + applyAffinity((Mem *)pVal, affinity, enc); +} + +/* +** pMem currently only holds a string type (or maybe a BLOB that we can +** interpret as a string if we want to). Compute its corresponding +** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields +** accordingly. +*/ +static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ + int rc; + sqlite3_int64 ix; + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); + assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); + if( ExpandBlob(pMem) ){ + pMem->u.i = 0; + return MEM_Int; + } + rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); + if( rc<=0 ){ + if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ + pMem->u.i = ix; + return MEM_Int; + }else{ + return MEM_Real; + } + }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ + pMem->u.i = ix; + return MEM_Int; + } + return MEM_Real; +} + +/* +** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or +** none. +** +** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. +** But it does set pMem->u.r and pMem->u.i appropriately. +*/ +static u16 numericType(Mem *pMem){ + assert( (pMem->flags & MEM_Null)==0 + || pMem->db==0 || pMem->db->mallocFailed ); + if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_Real ); + testcase( pMem->flags & MEM_IntReal ); + return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null); + } + assert( pMem->flags & (MEM_Str|MEM_Blob) ); + testcase( pMem->flags & MEM_Str ); + testcase( pMem->flags & MEM_Blob ); + return computeNumericType(pMem); + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** Write a nice string representation of the contents of cell pMem +** into buffer zBuf, length nBuf. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ + int f = pMem->flags; + static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"}; + if( f&MEM_Blob ){ + int i; + char c; + if( f & MEM_Dyn ){ + c = 'z'; + assert( (f & (MEM_Static|MEM_Ephem))==0 ); + }else if( f & MEM_Static ){ + c = 't'; + assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); + }else if( f & MEM_Ephem ){ + c = 'e'; + assert( (f & (MEM_Static|MEM_Dyn))==0 ); + }else{ + c = 's'; + } + sqlite3_str_appendf(pStr, "%cx[", c); + for(i=0; i<25 && in; i++){ + sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF)); + } + sqlite3_str_appendf(pStr, "|"); + for(i=0; i<25 && in; i++){ + char z = pMem->z[i]; + sqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z); + } + sqlite3_str_appendf(pStr,"]"); + if( f & MEM_Zero ){ + sqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero); + } + }else if( f & MEM_Str ){ + int j; + u8 c; + if( f & MEM_Dyn ){ + c = 'z'; + assert( (f & (MEM_Static|MEM_Ephem))==0 ); + }else if( f & MEM_Static ){ + c = 't'; + assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); + }else if( f & MEM_Ephem ){ + c = 'e'; + assert( (f & (MEM_Static|MEM_Dyn))==0 ); + }else{ + c = 's'; + } + sqlite3_str_appendf(pStr, " %c%d[", c, pMem->n); + for(j=0; j<25 && jn; j++){ + c = pMem->z[j]; + sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); + } + sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); + if( f & MEM_Term ){ + sqlite3_str_appendf(pStr, "(0-term)"); + } + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Print the value of a register for tracing purposes: +*/ +static void memTracePrint(Mem *p){ + if( p->flags & MEM_Undefined ){ + printf(" undefined"); + }else if( p->flags & MEM_Null ){ + printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); + }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ + printf(" si:%lld", p->u.i); + }else if( (p->flags & (MEM_IntReal))!=0 ){ + printf(" ir:%lld", p->u.i); + }else if( p->flags & MEM_Int ){ + printf(" i:%lld", p->u.i); +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( p->flags & MEM_Real ){ + printf(" r:%.17g", p->u.r); +#endif + }else if( sqlite3VdbeMemIsRowSet(p) ){ + printf(" (rowset)"); + }else{ + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(p, &acc); + printf(" %s", sqlite3StrAccumFinish(&acc)); + } + if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); +} +static void registerTrace(int iReg, Mem *p){ + printf("R[%d] = ", iReg); + memTracePrint(p); + if( p->pScopyFrom ){ + printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg])); + } + printf("\n"); + sqlite3VdbeCheckMemInvariants(p); +} +/**/ void sqlite3PrintMem(Mem *pMem){ + memTracePrint(pMem); + printf("\n"); + fflush(stdout); +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Show the values of all registers in the virtual machine. Used for +** interactive debugging. +*/ +SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){ + int i; + for(i=1; inMem; i++) registerTrace(i, v->aMem+i); +} +#endif /* SQLITE_DEBUG */ + + +#ifdef SQLITE_DEBUG +# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) +#else +# define REGISTER_TRACE(R,M) +#endif + +#ifndef NDEBUG +/* +** This function is only called from within an assert() expression. It +** checks that the sqlite3.nTransaction variable is correctly set to +** the number of non-transaction savepoints currently in the +** linked list starting at sqlite3.pSavepoint. +** +** Usage: +** +** assert( checkSavepointCount(db) ); +*/ +static int checkSavepointCount(sqlite3 *db){ + int n = 0; + Savepoint *p; + for(p=db->pSavepoint; p; p=p->pNext) n++; + assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); + return 1; +} +#endif + +/* +** Return the register of pOp->p2 after first preparing it to be +** overwritten with an integer value. +*/ +static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ + sqlite3VdbeMemSetNull(pOut); + pOut->flags = MEM_Int; + return pOut; +} +static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ + Mem *pOut; + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + pOut = &p->aMem[pOp->p2]; + memAboutToChange(p, pOut); + if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ + return out2PrereleaseWithClear(pOut); + }else{ + pOut->flags = MEM_Int; + return pOut; + } +} + +/* +** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning +** with pOp->p3. Return the hash. +*/ +static u64 filterHash(const Mem *aMem, const Op *pOp){ + int i, mx; + u64 h = 0; + + assert( pOp->p4type==P4_INT32 ); + for(i=pOp->p3, mx=i+pOp->p4.i; iflags & (MEM_Int|MEM_IntReal) ){ + h += p->u.i; + }else if( p->flags & MEM_Real ){ + h += sqlite3VdbeIntValue(p); + }else if( p->flags & (MEM_Str|MEM_Blob) ){ + /* All strings have the same hash and all blobs have the same hash, + ** though, at least, those hashes are different from each other and + ** from NULL. */ + h += 4093 + (p->flags & (MEM_Str|MEM_Blob)); + } + } + return h; +} + + +/* +** For OP_Column, factor out the case where content is loaded from +** overflow pages, so that the code to implement this case is separate +** the common case where all content fits on the page. Factoring out +** the code reduces register pressure and helps the common case +** to run faster. +*/ +static SQLITE_NOINLINE int vdbeColumnFromOverflow( + VdbeCursor *pC, /* The BTree cursor from which we are reading */ + int iCol, /* The column to read */ + int t, /* The serial-type code for the column value */ + i64 iOffset, /* Offset to the start of the content value */ + u32 cacheStatus, /* Current Vdbe.cacheCtr value */ + u32 colCacheCtr, /* Current value of the column cache counter */ + Mem *pDest /* Store the value into this register. */ +){ + int rc; + sqlite3 *db = pDest->db; + int encoding = pDest->enc; + int len = sqlite3VdbeSerialTypeLen(t); + assert( pC->eCurType==CURTYPE_BTREE ); + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG; + if( len > 4000 && pC->pKeyInfo==0 ){ + /* Cache large column values that are on overflow pages using + ** an RCStr (reference counted string) so that if they are reloaded, + ** that do not have to be copied a second time. The overhead of + ** creating and managing the cache is such that this is only + ** profitable for larger TEXT and BLOB values. + ** + ** Only do this on table-btrees so that writes to index-btrees do not + ** need to clear the cache. This buys performance in the common case + ** in exchange for generality. + */ + VdbeTxtBlbCache *pCache; + char *pBuf; + if( pC->colCache==0 ){ + pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) ); + if( pC->pCache==0 ) return SQLITE_NOMEM; + pC->colCache = 1; + } + pCache = pC->pCache; + if( pCache->pCValue==0 + || pCache->iCol!=iCol + || pCache->cacheStatus!=cacheStatus + || pCache->colCacheCtr!=colCacheCtr + || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor) + ){ + if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue); + pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 ); + if( pBuf==0 ) return SQLITE_NOMEM; + rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf); + if( rc ) return rc; + pBuf[len] = 0; + pBuf[len+1] = 0; + pBuf[len+2] = 0; + pCache->iCol = iCol; + pCache->cacheStatus = cacheStatus; + pCache->colCacheCtr = colCacheCtr; + pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); + }else{ + pBuf = pCache->pCValue; + } + assert( t>=12 ); + sqlite3RCStrRef(pBuf); + if( t&1 ){ + rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, + sqlite3RCStrUnref); + pDest->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, + sqlite3RCStrUnref); + } + }else{ + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); + if( rc ) return rc; + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + if( (t&1)!=0 && encoding==SQLITE_UTF8 ){ + pDest->z[len] = 0; + pDest->flags |= MEM_Term; + } + } + pDest->flags &= ~MEM_Ephem; + return rc; +} + + +/* +** Return the symbolic name for the data type of a pMem +*/ +static const char *vdbeMemTypeName(Mem *pMem){ + static const char *azTypes[] = { + /* SQLITE_INTEGER */ "INT", + /* SQLITE_FLOAT */ "REAL", + /* SQLITE_TEXT */ "TEXT", + /* SQLITE_BLOB */ "BLOB", + /* SQLITE_NULL */ "NULL" + }; + return azTypes[sqlite3_value_type(pMem)-1]; +} + +/* +** Execute as much of a VDBE program as we can. +** This is the core of sqlite3_step(). +*/ +SQLITE_PRIVATE int sqlite3VdbeExec( + Vdbe *p /* The VDBE */ +){ + Op *aOp = p->aOp; /* Copy of p->aOp */ + Op *pOp = aOp; /* Current operation */ +#ifdef SQLITE_DEBUG + Op *pOrigOp; /* Value of pOp at the top of the loop */ + int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ + u8 iCompareIsInit = 0; /* iCompare is initialized */ +#endif + int rc = SQLITE_OK; /* Value to return */ + sqlite3 *db = p->db; /* The database */ + u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ + u8 encoding = ENC(db); /* The database encoding */ + int iCompare = 0; /* Result of last comparison */ + u64 nVmStep = 0; /* Number of virtual machine steps */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + u64 nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */ +#endif + Mem *aMem = p->aMem; /* Copy of p->aMem */ + Mem *pIn1 = 0; /* 1st input operand */ + Mem *pIn2 = 0; /* 2nd input operand */ + Mem *pIn3 = 0; /* 3rd input operand */ + Mem *pOut = 0; /* Output operand */ + u32 colCacheCtr = 0; /* Column cache counter */ +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + u64 *pnCycle = 0; + int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; +#endif + /*** INSERT STACK UNION HERE ***/ + + assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ + if( DbMaskNonZero(p->lockMask) ){ + sqlite3VdbeEnter(p); + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; + assert( 0 < db->nProgressOps ); + nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps); + }else{ + nProgressLimit = LARGEST_UINT64; + } +#endif + if( p->rc==SQLITE_NOMEM ){ + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ + goto no_mem; + } + assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); + testcase( p->rc!=SQLITE_OK ); + p->rc = SQLITE_OK; + assert( p->bIsReader || p->readOnly!=0 ); + p->iCurrentTime = 0; + assert( p->explain==0 ); + db->busyHandler.nBusy = 0; + if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; + sqlite3VdbeIOTraceSql(p); +#ifdef SQLITE_DEBUG + sqlite3BeginBenignMalloc(); + if( p->pc==0 + && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 + ){ + int i; + int once = 1; + sqlite3VdbePrintSql(p); + if( p->db->flags & SQLITE_VdbeListing ){ + printf("VDBE Program Listing:\n"); + for(i=0; inOp; i++){ + sqlite3VdbePrintOp(stdout, i, &aOp[i]); + } + } + if( p->db->flags & SQLITE_VdbeEQP ){ + for(i=0; inOp; i++){ + if( aOp[i].opcode==OP_Explain ){ + if( once ) printf("VDBE Query Plan:\n"); + printf("%s\n", aOp[i].p4.z); + once = 0; + } + } + } + if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); + } + sqlite3EndBenignMalloc(); +#endif + for(pOp=&aOp[p->pc]; 1; pOp++){ + /* Errors are detected by individual opcodes, with an immediate + ** jumps to abort_due_to_error. */ + assert( rc==SQLITE_OK ); + + assert( pOp>=aOp && pOp<&aOp[p->nOp]); + nVmStep++; + +#if defined(VDBE_PROFILE) + pOp->nExec++; + pnCycle = &pOp->nCycle; + if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime(); +#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( bStmtScanStatus ){ + pOp->nExec++; + pnCycle = &pOp->nCycle; + *pnCycle -= sqlite3Hwtime(); + } +#endif + + /* Only allow tracing if SQLITE_DEBUG is defined. + */ +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); + test_trace_breakpoint((int)(pOp - aOp),pOp,p); + } +#endif + + + /* Check to see if we need to simulate an interrupt. This only happens + ** if we have a special test build. + */ +#ifdef SQLITE_TEST + if( sqlite3_interrupt_count>0 ){ + sqlite3_interrupt_count--; + if( sqlite3_interrupt_count==0 ){ + sqlite3_interrupt(db); + } + } +#endif + + /* Sanity checking on other operands */ +#ifdef SQLITE_DEBUG + { + u8 opProperty = sqlite3OpcodeProperty[pOp->opcode]; + if( (opProperty & OPFLG_IN1)!=0 ){ + assert( pOp->p1>0 ); + assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p1]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); + REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); + } + if( (opProperty & OPFLG_IN2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p2]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); + REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); + } + if( (opProperty & OPFLG_IN3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p3]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); + REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); + } + if( (opProperty & OPFLG_OUT2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p2]); + } + if( (opProperty & OPFLG_OUT3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p3]); + } + } +#endif +#ifdef SQLITE_DEBUG + pOrigOp = pOp; +#endif + + switch( pOp->opcode ){ + +/***************************************************************************** +** What follows is a massive switch statement where each case implements a +** separate instruction in the virtual machine. If we follow the usual +** indentation conventions, each case should be indented by 6 spaces. But +** that is a lot of wasted space on the left margin. So the code within +** the switch statement will break with convention and be flush-left. Another +** big comment (similar to this one) will mark the point in the code where +** we transition back to normal indentation. +** +** The formatting of each case is important. The makefile for SQLite +** generates two C files "opcodes.h" and "opcodes.c" by scanning this +** file looking for lines that begin with "case OP_". The opcodes.h files +** will be filled with #defines that give unique integer values to each +** opcode and the opcodes.c file is filled with an array of strings where +** each string is the symbolic name for the corresponding opcode. If the +** case statement is followed by a comment of the form "/# same as ... #/" +** that comment is used to determine the particular value of the opcode. +** +** Other keywords in the comment that follows each case are used to +** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. +** Keywords include: in1, in2, in3, out2, out3. See +** the mkopcodeh.awk script for additional information. +** +** Documentation about VDBE opcodes is generated by scanning this file +** for lines of that contain "Opcode:". That line and all subsequent +** comment lines are used in the generation of the opcode.html documentation +** file. +** +** SUMMARY: +** +** Formatting is important to scripts that scan this file. +** Do not deviate from the formatting style currently in use. +** +*****************************************************************************/ + +/* Opcode: Goto * P2 * * * +** +** An unconditional jump to address P2. +** The next instruction executed will be +** the one at index P2 from the beginning of +** the program. +** +** The P1 parameter is not actually used by this opcode. However, it +** is sometimes set to 1 instead of 0 as a hint to the command-line shell +** that this Goto is the bottom of a loop and that the lines from P2 down +** to the current line should be indented for EXPLAIN output. +*/ +case OP_Goto: { /* jump */ + +#ifdef SQLITE_DEBUG + /* In debugging mode, when the p5 flags is set on an OP_Goto, that + ** means we should really jump back to the preceding OP_ReleaseReg + ** instruction. */ + if( pOp->p5 ){ + assert( pOp->p2 < (int)(pOp - aOp) ); + assert( pOp->p2 > 1 ); + pOp = &aOp[pOp->p2 - 2]; + assert( pOp[1].opcode==OP_ReleaseReg ); + goto check_for_interrupt; + } +#endif + +jump_to_p2_and_check_for_interrupt: + pOp = &aOp[pOp->p2 - 1]; + + /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, + ** OP_VNext, or OP_SorterNext) all jump here upon + ** completion. Check to see if sqlite3_interrupt() has been called + ** or if the progress callback needs to be invoked. + ** + ** This code uses unstructured "goto" statements and does not look clean. + ** But that is not due to sloppy coding habits. The code is written this + ** way for performance, to avoid having to run the interrupt and progress + ** checks on every opcode. This helps sqlite3_step() to run about 1.5% + ** faster according to "valgrind --tool=cachegrind" */ +check_for_interrupt: + if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + /* Call the progress callback if it is configured and the required number + ** of VDBE ops have been executed (either since this invocation of + ** sqlite3VdbeExec() or since last time the progress callback was called). + ** If the progress callback returns non-zero, exit the virtual machine with + ** a return code SQLITE_ABORT. + */ + while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ + assert( db->nProgressOps!=0 ); + nProgressLimit += db->nProgressOps; + if( db->xProgress(db->pProgressArg) ){ + nProgressLimit = LARGEST_UINT64; + rc = SQLITE_INTERRUPT; + goto abort_due_to_error; + } + } +#endif + + break; +} + +/* Opcode: Gosub P1 P2 * * * +** +** Write the current address onto register P1 +** and then jump to address P2. +*/ +case OP_Gosub: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( VdbeMemDynamic(pIn1)==0 ); + memAboutToChange(p, pIn1); + pIn1->flags = MEM_Int; + pIn1->u.i = (int)(pOp-aOp); + REGISTER_TRACE(pOp->p1, pIn1); + goto jump_to_p2_and_check_for_interrupt; +} + +/* Opcode: Return P1 P2 P3 * * +** +** Jump to the address stored in register P1. If P1 is a return address +** register, then this accomplishes a return from a subroutine. +** +** If P3 is 1, then the jump is only taken if register P1 holds an integer +** values, otherwise execution falls through to the next opcode, and the +** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an +** integer or else an assert() is raised. P3 should be set to 1 when +** this opcode is used in combination with OP_BeginSubrtn, and set to 0 +** otherwise. +** +** The value in register P1 is unchanged by this opcode. +** +** P2 is not used by the byte-code engine. However, if P2 is positive +** and also less than the current address, then the "EXPLAIN" output +** formatter in the CLI will indent all opcodes from the P2 opcode up +** to be not including the current Return. P2 should be the first opcode +** in the subroutine from which this opcode is returning. Thus the P2 +** value is a byte-code indentation hint. See tag-20220407a in +** wherecode.c and shell.c. +*/ +case OP_Return: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & MEM_Int ){ + if( pOp->p3 ){ VdbeBranchTaken(1, 2); } + pOp = &aOp[pIn1->u.i]; + }else if( ALWAYS(pOp->p3) ){ + VdbeBranchTaken(0, 2); + } + break; +} + +/* Opcode: InitCoroutine P1 P2 P3 * * +** +** Set up register P1 so that it will Yield to the coroutine +** located at address P3. +** +** If P2!=0 then the coroutine implementation immediately follows +** this opcode. So jump over the coroutine implementation to +** address P2. +** +** See also: EndCoroutine +*/ +case OP_InitCoroutine: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( pOp->p2>=0 && pOp->p2nOp ); + assert( pOp->p3>=0 && pOp->p3nOp ); + pOut = &aMem[pOp->p1]; + assert( !VdbeMemDynamic(pOut) ); + pOut->u.i = pOp->p3 - 1; + pOut->flags = MEM_Int; + if( pOp->p2==0 ) break; + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ + assert( pOp->p2nOp ); /* Jumps must be in range */ + pOp = &aOp[pOp->p2 - 1]; + break; +} + +/* Opcode: EndCoroutine P1 * * * * +** +** The instruction at the address in register P1 is a Yield. +** Jump to the P2 parameter of that Yield. +** After the jump, register P1 becomes undefined. +** +** See also: InitCoroutine +*/ +case OP_EndCoroutine: { /* in1 */ + VdbeOp *pCaller; + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags==MEM_Int ); + assert( pIn1->u.i>=0 && pIn1->u.inOp ); + pCaller = &aOp[pIn1->u.i]; + assert( pCaller->opcode==OP_Yield ); + assert( pCaller->p2>=0 && pCaller->p2nOp ); + pOp = &aOp[pCaller->p2 - 1]; + pIn1->flags = MEM_Undefined; + break; +} + +/* Opcode: Yield P1 P2 * * * +** +** Swap the program counter with the value in register P1. This +** has the effect of yielding to a coroutine. +** +** If the coroutine that is launched by this instruction ends with +** Yield or Return then continue to the next instruction. But if +** the coroutine launched by this instruction ends with +** EndCoroutine, then jump to P2 rather than continuing with the +** next instruction. +** +** See also: InitCoroutine +*/ +case OP_Yield: { /* in1, jump */ + int pcDest; + pIn1 = &aMem[pOp->p1]; + assert( VdbeMemDynamic(pIn1)==0 ); + pIn1->flags = MEM_Int; + pcDest = (int)pIn1->u.i; + pIn1->u.i = (int)(pOp - aOp); + REGISTER_TRACE(pOp->p1, pIn1); + pOp = &aOp[pcDest]; + break; +} + +/* Opcode: HaltIfNull P1 P2 P3 P4 P5 +** Synopsis: if r[P3]=null halt +** +** Check the value in register P3. If it is NULL then Halt using +** parameter P1, P2, and P4 as if this were a Halt instruction. If the +** value in register P3 is not NULL, then this routine is a no-op. +** The P5 parameter should be 1. +*/ +case OP_HaltIfNull: { /* in3 */ + pIn3 = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } +#endif + if( (pIn3->flags & MEM_Null)==0 ) break; + /* Fall through into OP_Halt */ + /* no break */ deliberate_fall_through +} + +/* Opcode: Halt P1 P2 * P4 P5 +** +** Exit immediately. All open cursors, etc are closed +** automatically. +** +** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), +** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). +** For errors, it can be some other value. If P1!=0 then P2 will determine +** whether or not to rollback the current transaction. Do not rollback +** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, +** then back out all changes that have occurred during this execution of the +** VDBE, but do not rollback the transaction. +** +** If P4 is not null then it is an error message string. +** +** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. +** +** 0: (no change) +** 1: NOT NULL constraint failed: P4 +** 2: UNIQUE constraint failed: P4 +** 3: CHECK constraint failed: P4 +** 4: FOREIGN KEY constraint failed: P4 +** +** If P5 is not zero and P4 is NULL, then everything after the ":" is +** omitted. +** +** There is an implied "Halt 0 0 0" instruction inserted at the very end of +** every program. So a jump past the last instruction of the program +** is the same as executing Halt. +*/ +case OP_Halt: { + VdbeFrame *pFrame; + int pcx; + +#ifdef SQLITE_DEBUG + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } +#endif + + /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates + ** something is wrong with the code generator. Raise an assertion in order + ** to bring this to the attention of fuzzers and other testing tools. */ + assert( pOp->p1!=SQLITE_INTERNAL ); + + if( p->pFrame && pOp->p1==SQLITE_OK ){ + /* Halt the sub-program. Return control to the parent frame. */ + pFrame = p->pFrame; + p->pFrame = pFrame->pParent; + p->nFrame--; + sqlite3VdbeSetChanges(db, p->nChange); + pcx = sqlite3VdbeFrameRestore(pFrame); + if( pOp->p2==OE_Ignore ){ + /* Instruction pcx is the OP_Program that invoked the sub-program + ** currently being halted. If the p2 instruction of this OP_Halt + ** instruction is set to OE_Ignore, then the sub-program is throwing + ** an IGNORE exception. In this case jump to the address specified + ** as the p2 of the calling OP_Program. */ + pcx = p->aOp[pcx].p2-1; + } + aOp = p->aOp; + aMem = p->aMem; + pOp = &aOp[pcx]; + break; + } + p->rc = pOp->p1; + p->errorAction = (u8)pOp->p2; + assert( pOp->p5<=4 ); + if( p->rc ){ + if( pOp->p5 ){ + static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", + "FOREIGN KEY" }; + testcase( pOp->p5==1 ); + testcase( pOp->p5==2 ); + testcase( pOp->p5==3 ); + testcase( pOp->p5==4 ); + sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); + if( pOp->p4.z ){ + p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); + } + }else{ + sqlite3VdbeError(p, "%s", pOp->p4.z); + } + pcx = (int)(pOp - aOp); + sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); + } + rc = sqlite3VdbeHalt(p); + assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); + if( rc==SQLITE_BUSY ){ + p->rc = SQLITE_BUSY; + }else{ + assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); + assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); + rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; + } + goto vdbe_return; +} + +/* Opcode: Integer P1 P2 * * * +** Synopsis: r[P2]=P1 +** +** The 32-bit integer value P1 is written into register P2. +*/ +case OP_Integer: { /* out2 */ + pOut = out2Prerelease(p, pOp); + pOut->u.i = pOp->p1; + break; +} + +/* Opcode: Int64 * P2 * P4 * +** Synopsis: r[P2]=P4 +** +** P4 is a pointer to a 64-bit integer value. +** Write that value into register P2. +*/ +case OP_Int64: { /* out2 */ + pOut = out2Prerelease(p, pOp); + assert( pOp->p4.pI64!=0 ); + pOut->u.i = *pOp->p4.pI64; + break; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* Opcode: Real * P2 * P4 * +** Synopsis: r[P2]=P4 +** +** P4 is a pointer to a 64-bit floating point value. +** Write that value into register P2. +*/ +case OP_Real: { /* same as TK_FLOAT, out2 */ + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Real; + assert( !sqlite3IsNaN(*pOp->p4.pReal) ); + pOut->u.r = *pOp->p4.pReal; + break; +} +#endif + +/* Opcode: String8 * P2 * P4 * +** Synopsis: r[P2]='P4' +** +** P4 points to a nul terminated UTF-8 string. This opcode is transformed +** into a String opcode before it is executed for the first time. During +** this transformation, the length of string P4 is computed and stored +** as the P1 parameter. +*/ +case OP_String8: { /* same as TK_STRING, out2 */ + assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); + pOp->p1 = sqlite3Strlen30(pOp->p4.z); + +#ifndef SQLITE_OMIT_UTF16 + if( encoding!=SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG ); + if( rc ) goto too_big; + if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; + assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); + assert( VdbeMemDynamic(pOut)==0 ); + pOut->szMalloc = 0; + pOut->flags |= MEM_Static; + if( pOp->p4type==P4_DYNAMIC ){ + sqlite3DbFree(db, pOp->p4.z); + } + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = pOut->z; + pOp->p1 = pOut->n; + } +#endif + if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + pOp->opcode = OP_String; + assert( rc==SQLITE_OK ); + /* Fall through to the next case, OP_String */ + /* no break */ deliberate_fall_through +} + +/* Opcode: String P1 P2 P3 P4 P5 +** Synopsis: r[P2]='P4' (len=P1) +** +** The string value P4 of length P1 (bytes) is stored in register P2. +** +** If P3 is not zero and the content of register P3 is equal to P5, then +** the datatype of the register P2 is converted to BLOB. The content is +** the same sequence of bytes, it is merely interpreted as a BLOB instead +** of a string, as if it had been CAST. In other words: +** +** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB) +*/ +case OP_String: { /* out2 */ + assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = pOp->p4.z; + pOut->n = pOp->p1; + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( pOp->p3>0 ){ + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + pIn3 = &aMem[pOp->p3]; + assert( pIn3->flags & MEM_Int ); + if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; + } +#endif + break; +} + +/* Opcode: BeginSubrtn * P2 * * * +** Synopsis: r[P2]=NULL +** +** Mark the beginning of a subroutine that can be entered in-line +** or that can be called using OP_Gosub. The subroutine should +** be terminated by an OP_Return instruction that has a P1 operand that +** is the same as the P2 operand to this opcode and that has P3 set to 1. +** If the subroutine is entered in-line, then the OP_Return will simply +** fall through. But if the subroutine is entered using OP_Gosub, then +** the OP_Return will jump back to the first instruction after the OP_Gosub. +** +** This routine works by loading a NULL into the P2 register. When the +** return address register contains a NULL, the OP_Return instruction is +** a no-op that simply falls through to the next instruction (assuming that +** the OP_Return opcode has a P3 value of 1). Thus if the subroutine is +** entered in-line, then the OP_Return will cause in-line execution to +** continue. But if the subroutine is entered via OP_Gosub, then the +** OP_Return will cause a return to the address following the OP_Gosub. +** +** This opcode is identical to OP_Null. It has a different name +** only to make the byte code easier to read and verify. +*/ +/* Opcode: Null P1 P2 P3 * * +** Synopsis: r[P2..P3]=NULL +** +** Write a NULL into registers P2. If P3 greater than P2, then also write +** NULL into register P3 and every register in between P2 and P3. If P3 +** is less than P2 (typically P3 is zero) then only register P2 is +** set to NULL. +** +** If the P1 value is non-zero, then also set the MEM_Cleared flag so that +** NULL values will not compare equal even if SQLITE_NULLEQ is set on +** OP_Ne or OP_Eq. +*/ +case OP_BeginSubrtn: +case OP_Null: { /* out2 */ + int cnt; + u16 nullFlag; + pOut = out2Prerelease(p, pOp); + cnt = pOp->p3-pOp->p2; + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; + pOut->n = 0; +#ifdef SQLITE_DEBUG + pOut->uTemp = 0; +#endif + while( cnt>0 ){ + pOut++; + memAboutToChange(p, pOut); + sqlite3VdbeMemSetNull(pOut); + pOut->flags = nullFlag; + pOut->n = 0; + cnt--; + } + break; +} + +/* Opcode: SoftNull P1 * * * * +** Synopsis: r[P1]=NULL +** +** Set register P1 to have the value NULL as seen by the OP_MakeRecord +** instruction, but do not free any string or blob memory associated with +** the register, so that if the value was a string or blob that was +** previously copied using OP_SCopy, the copies will continue to be valid. +*/ +case OP_SoftNull: { + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pOut = &aMem[pOp->p1]; + pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null; + break; +} + +/* Opcode: Blob P1 P2 * P4 * +** Synopsis: r[P2]=P4 (len=P1) +** +** P4 points to a blob of data P1 bytes long. Store this +** blob in register P2. If P4 is a NULL pointer, then construct +** a zero-filled blob that is P1 bytes long in P2. +*/ +case OP_Blob: { /* out2 */ + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); + pOut = out2Prerelease(p, pOp); + if( pOp->p4.z==0 ){ + sqlite3VdbeMemSetZeroBlob(pOut, pOp->p1); + if( sqlite3VdbeMemExpandBlob(pOut) ) goto no_mem; + }else{ + sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + } + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Variable P1 P2 * P4 * +** Synopsis: r[P2]=parameter(P1,P4) +** +** Transfer the values of bound parameter P1 into register P2 +** +** If the parameter is named, then its name appears in P4. +** The P4 value is used by sqlite3_bind_parameter_name(). +*/ +case OP_Variable: { /* out2 */ + Mem *pVar; /* Value being transferred */ + + assert( pOp->p1>0 && pOp->p1<=p->nVar ); + assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); + pVar = &p->aVar[pOp->p1 - 1]; + if( sqlite3VdbeMemTooBig(pVar) ){ + goto too_big; + } + pOut = &aMem[pOp->p2]; + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); + memcpy(pOut, pVar, MEMCELLSIZE); + pOut->flags &= ~(MEM_Dyn|MEM_Ephem); + pOut->flags |= MEM_Static|MEM_FromBind; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Move P1 P2 P3 * * +** Synopsis: r[P2@P3]=r[P1@P3] +** +** Move the P3 values in register P1..P1+P3-1 over into +** registers P2..P2+P3-1. Registers P1..P1+P3-1 are +** left holding a NULL. It is an error for register ranges +** P1..P1+P3-1 and P2..P2+P3-1 to overlap. It is an error +** for P3 to be less than 1. +*/ +case OP_Move: { + int n; /* Number of registers left to copy */ + int p1; /* Register to copy from */ + int p2; /* Register to copy to */ + + n = pOp->p3; + p1 = pOp->p1; + p2 = pOp->p2; + assert( n>0 && p1>0 && p2>0 ); + assert( p1+n<=p2 || p2+n<=p1 ); + + pIn1 = &aMem[p1]; + pOut = &aMem[p2]; + do{ + assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] ); + assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); + assert( memIsValid(pIn1) ); + memAboutToChange(p, pOut); + sqlite3VdbeMemMove(pOut, pIn1); +#ifdef SQLITE_DEBUG + pIn1->pScopyFrom = 0; + { int i; + for(i=1; inMem; i++){ + if( aMem[i].pScopyFrom==pIn1 ){ + aMem[i].pScopyFrom = pOut; + } + } + } +#endif + Deephemeralize(pOut); + REGISTER_TRACE(p2++, pOut); + pIn1++; + pOut++; + }while( --n ); + break; +} + +/* Opcode: Copy P1 P2 P3 * P5 +** Synopsis: r[P2@P3+1]=r[P1@P3+1] +** +** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. +** +** If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the +** destination. The 0x0001 bit of P5 indicates that this Copy opcode cannot +** be merged. The 0x0001 bit is used by the query planner and does not +** come into play during query execution. +** +** This instruction makes a deep copy of the value. A duplicate +** is made of any string or blob constant. See also OP_SCopy. +*/ +case OP_Copy: { + int n; + + n = pOp->p3; + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + assert( pOut!=pIn1 ); + while( 1 ){ + memAboutToChange(p, pOut); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + Deephemeralize(pOut); + if( (pOut->flags & MEM_Subtype)!=0 && (pOp->p5 & 0x0002)!=0 ){ + pOut->flags &= ~MEM_Subtype; + } +#ifdef SQLITE_DEBUG + pOut->pScopyFrom = 0; +#endif + REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); + if( (n--)==0 ) break; + pOut++; + pIn1++; + } + break; +} + +/* Opcode: SCopy P1 P2 * * * +** Synopsis: r[P2]=r[P1] +** +** Make a shallow copy of register P1 into register P2. +** +** This instruction makes a shallow copy of the value. If the value +** is a string or blob, then the copy is only a pointer to the +** original and hence if the original changes so will the copy. +** Worse, if the original is deallocated, the copy becomes invalid. +** Thus the program must guarantee that the original will not change +** during the lifetime of the copy. Use OP_Copy to make a complete +** copy. +*/ +case OP_SCopy: { /* out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + assert( pOut!=pIn1 ); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); +#ifdef SQLITE_DEBUG + pOut->pScopyFrom = pIn1; + pOut->mScopyFlags = pIn1->flags; +#endif + break; +} + +/* Opcode: IntCopy P1 P2 * * * +** Synopsis: r[P2]=r[P1] +** +** Transfer the integer value held in register P1 into register P2. +** +** This is an optimized version of SCopy that works only for integer +** values. +*/ +case OP_IntCopy: { /* out2 */ + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Int)!=0 ); + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetInt64(pOut, pIn1->u.i); + break; +} + +/* Opcode: FkCheck * * * * * +** +** Halt with an SQLITE_CONSTRAINT error if there are any unresolved +** foreign key constraint violations. If there are no foreign key +** constraint violations, this is a no-op. +** +** FK constraint violations are also checked when the prepared statement +** exits. This opcode is used to raise foreign key constraint errors prior +** to returning results such as a row change count or the result of a +** RETURNING clause. +*/ +case OP_FkCheck: { + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + break; +} + +/* Opcode: ResultRow P1 P2 * * * +** Synopsis: output=r[P1@P2] +** +** The registers P1 through P1+P2-1 contain a single row of +** results. This opcode causes the sqlite3_step() call to terminate +** with an SQLITE_ROW return code and it sets up the sqlite3_stmt +** structure to provide access to the r(P1)..r(P1+P2-1) values as +** the result row. +*/ +case OP_ResultRow: { + assert( p->nResColumn==pOp->p2 ); + assert( pOp->p1>0 || CORRUPT_DB ); + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); + + p->cacheCtr = (p->cacheCtr + 2)|1; + p->pResultRow = &aMem[pOp->p1]; +#ifdef SQLITE_DEBUG + { + Mem *pMem = p->pResultRow; + int i; + for(i=0; ip2; i++){ + assert( memIsValid(&pMem[i]) ); + REGISTER_TRACE(pOp->p1+i, &pMem[i]); + /* The registers in the result will not be used again when the + ** prepared statement restarts. This is because sqlite3_column() + ** APIs might have caused type conversions of made other changes to + ** the register values. Therefore, we can go ahead and break any + ** OP_SCopy dependencies. */ + pMem[i].pScopyFrom = 0; + } + } +#endif + if( db->mallocFailed ) goto no_mem; + if( db->mTrace & SQLITE_TRACE_ROW ){ + db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); + } + p->pc = (int)(pOp - aOp) + 1; + rc = SQLITE_ROW; + goto vdbe_return; +} + +/* Opcode: Concat P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]+r[P1] +** +** Add the text in register P1 onto the end of the text in +** register P2 and store the result in register P3. +** If either the P1 or P2 text are NULL then store NULL in P3. +** +** P3 = P2 || P1 +** +** It is illegal for P1 and P3 to be the same register. Sometimes, +** if P3 is the same register as P2, the implementation is able +** to avoid a memcpy(). +*/ +case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ + i64 nByte; /* Total size of the output string or blob */ + u16 flags1; /* Initial flags for P1 */ + u16 flags2; /* Initial flags for P2 */ + + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + pOut = &aMem[pOp->p3]; + testcase( pOut==pIn2 ); + assert( pIn1!=pOut ); + flags1 = pIn1->flags; + testcase( flags1 & MEM_Null ); + testcase( pIn2->flags & MEM_Null ); + if( (flags1 | pIn2->flags) & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + break; + } + if( (flags1 & (MEM_Str|MEM_Blob))==0 ){ + if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem; + flags1 = pIn1->flags & ~MEM_Str; + }else if( (flags1 & MEM_Zero)!=0 ){ + if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem; + flags1 = pIn1->flags & ~MEM_Str; + } + flags2 = pIn2->flags; + if( (flags2 & (MEM_Str|MEM_Blob))==0 ){ + if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem; + flags2 = pIn2->flags & ~MEM_Str; + }else if( (flags2 & MEM_Zero)!=0 ){ + if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem; + flags2 = pIn2->flags & ~MEM_Str; + } + nByte = pIn1->n + pIn2->n; + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ + goto no_mem; + } + MemSetTypeFlag(pOut, MEM_Str); + if( pOut!=pIn2 ){ + memcpy(pOut->z, pIn2->z, pIn2->n); + assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) ); + pIn2->flags = flags2; + } + memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; + if( encoding>SQLITE_UTF8 ) nByte &= ~1; + pOut->z[nByte]=0; + pOut->z[nByte+1] = 0; + pOut->flags |= MEM_Term; + pOut->n = (int)nByte; + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Add P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]+r[P2] +** +** Add the value in register P1 to the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Multiply P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]*r[P2] +** +** +** Multiply the value in register P1 by the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Subtract P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]-r[P1] +** +** Subtract the value in register P1 from the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Divide P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]/r[P1] +** +** Divide the value in register P1 by the value in register P2 +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is +** NULL, the result is NULL. +*/ +/* Opcode: Remainder P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]%r[P1] +** +** Compute the remainder after integer register P2 is divided by +** register P1 and store the result in register P3. +** If the value in register P1 is zero the result is NULL. +** If either operand is NULL, the result is NULL. +*/ +case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ +case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ +case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ +case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ +case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ + u16 type1; /* Numeric type of left operand */ + u16 type2; /* Numeric type of right operand */ + i64 iA; /* Integer value of left operand */ + i64 iB; /* Integer value of right operand */ + double rA; /* Real value of left operand */ + double rB; /* Real value of right operand */ + + pIn1 = &aMem[pOp->p1]; + type1 = pIn1->flags; + pIn2 = &aMem[pOp->p2]; + type2 = pIn2->flags; + pOut = &aMem[pOp->p3]; + if( (type1 & type2 & MEM_Int)!=0 ){ +int_math: + iA = pIn1->u.i; + iB = pIn2->u.i; + switch( pOp->opcode ){ + case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; + case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; + case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; + case OP_Divide: { + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; + iB /= iA; + break; + } + default: { + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + iB %= iA; + break; + } + } + pOut->u.i = iB; + MemSetTypeFlag(pOut, MEM_Int); + }else if( ((type1 | type2) & MEM_Null)!=0 ){ + goto arithmetic_result_is_null; + }else{ + type1 = numericType(pIn1); + type2 = numericType(pIn2); + if( (type1 & type2 & MEM_Int)!=0 ) goto int_math; +fp_math: + rA = sqlite3VdbeRealValue(pIn1); + rB = sqlite3VdbeRealValue(pIn2); + switch( pOp->opcode ){ + case OP_Add: rB += rA; break; + case OP_Subtract: rB -= rA; break; + case OP_Multiply: rB *= rA; break; + case OP_Divide: { + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + if( rA==(double)0 ) goto arithmetic_result_is_null; + rB /= rA; + break; + } + default: { + iA = sqlite3VdbeIntValue(pIn1); + iB = sqlite3VdbeIntValue(pIn2); + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + rB = (double)(iB % iA); + break; + } + } +#ifdef SQLITE_OMIT_FLOATING_POINT + pOut->u.i = rB; + MemSetTypeFlag(pOut, MEM_Int); +#else + if( sqlite3IsNaN(rB) ){ + goto arithmetic_result_is_null; + } + pOut->u.r = rB; + MemSetTypeFlag(pOut, MEM_Real); +#endif + } + break; + +arithmetic_result_is_null: + sqlite3VdbeMemSetNull(pOut); + break; +} + +/* Opcode: CollSeq P1 * * P4 +** +** P4 is a pointer to a CollSeq object. If the next call to a user function +** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will +** be returned. This is used by the built-in min(), max() and nullif() +** functions. +** +** If P1 is not zero, then it is a register that a subsequent min() or +** max() aggregate will set to 1 if the current row is not the minimum or +** maximum. The P1 register is initialized to 0 by this instruction. +** +** The interface used by the implementation of the aforementioned functions +** to retrieve the collation sequence set by this opcode is not available +** publicly. Only built-in functions have access to this feature. +*/ +case OP_CollSeq: { + assert( pOp->p4type==P4_COLLSEQ ); + if( pOp->p1 ){ + sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); + } + break; +} + +/* Opcode: BitAnd P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]&r[P2] +** +** Take the bit-wise AND of the values in register P1 and P2 and +** store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: BitOr P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]|r[P2] +** +** Take the bit-wise OR of the values in register P1 and P2 and +** store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: ShiftLeft P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]<>r[P1] +** +** Shift the integer value in register P2 to the right by the +** number of bits specified by the integer in register P1. +** Store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ +case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ +case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ +case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ + i64 iA; + u64 uA; + i64 iB; + u8 op; + + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + pOut = &aMem[pOp->p3]; + if( (pIn1->flags | pIn2->flags) & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + break; + } + iA = sqlite3VdbeIntValue(pIn2); + iB = sqlite3VdbeIntValue(pIn1); + op = pOp->opcode; + if( op==OP_BitAnd ){ + iA &= iB; + }else if( op==OP_BitOr ){ + iA |= iB; + }else if( iB!=0 ){ + assert( op==OP_ShiftRight || op==OP_ShiftLeft ); + + /* If shifting by a negative amount, shift in the other direction */ + if( iB<0 ){ + assert( OP_ShiftRight==OP_ShiftLeft+1 ); + op = 2*OP_ShiftLeft + 1 - op; + iB = iB>(-64) ? -iB : 64; + } + + if( iB>=64 ){ + iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1; + }else{ + memcpy(&uA, &iA, sizeof(uA)); + if( op==OP_ShiftLeft ){ + uA <<= iB; + }else{ + uA >>= iB; + /* Sign-extend on a right shift of a negative number */ + if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB); + } + memcpy(&iA, &uA, sizeof(iA)); + } + } + pOut->u.i = iA; + MemSetTypeFlag(pOut, MEM_Int); + break; +} + +/* Opcode: AddImm P1 P2 * * * +** Synopsis: r[P1]=r[P1]+P2 +** +** Add the constant P2 to the value in register P1. +** The result is always an integer. +** +** To force any register to be an integer, just add 0. +*/ +case OP_AddImm: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); + sqlite3VdbeMemIntegerify(pIn1); + *(u64*)&pIn1->u.i += (u64)pOp->p2; + break; +} + +/* Opcode: MustBeInt P1 P2 * * * +** +** Force the value in register P1 to be an integer. If the value +** in P1 is not an integer and cannot be converted into an integer +** without data loss, then jump immediately to P2, or if P2==0 +** raise an SQLITE_MISMATCH exception. +*/ +case OP_MustBeInt: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + if( (pIn1->flags & MEM_Int)==0 ){ + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + if( (pIn1->flags & MEM_Int)==0 ){ + VdbeBranchTaken(1, 2); + if( pOp->p2==0 ){ + rc = SQLITE_MISMATCH; + goto abort_due_to_error; + }else{ + goto jump_to_p2; + } + } + } + VdbeBranchTaken(0, 2); + MemSetTypeFlag(pIn1, MEM_Int); + break; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* Opcode: RealAffinity P1 * * * * +** +** If register P1 holds an integer convert it to a real value. +** +** This opcode is used when extracting information from a column that +** has REAL affinity. Such column values may still be stored as +** integers, for space efficiency, but after extraction we want them +** to have only a real value. +*/ +case OP_RealAffinity: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pIn1); + REGISTER_TRACE(pOp->p1, pIn1); + } + break; +} +#endif + +#ifndef SQLITE_OMIT_CAST +/* Opcode: Cast P1 P2 * * * +** Synopsis: affinity(r[P1]) +** +** Force the value in register P1 to be the type defined by P2. +** +**
    +**
  • P2=='A' → BLOB +**
  • P2=='B' → TEXT +**
  • P2=='C' → NUMERIC +**
  • P2=='D' → INTEGER +**
  • P2=='E' → REAL +**
+** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_Cast: { /* in1 */ + assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL ); + testcase( pOp->p2==SQLITE_AFF_TEXT ); + testcase( pOp->p2==SQLITE_AFF_BLOB ); + testcase( pOp->p2==SQLITE_AFF_NUMERIC ); + testcase( pOp->p2==SQLITE_AFF_INTEGER ); + testcase( pOp->p2==SQLITE_AFF_REAL ); + pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); + rc = ExpandBlob(pIn1); + if( rc ) goto abort_due_to_error; + rc = sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); + if( rc ) goto abort_due_to_error; + UPDATE_MAX_BLOBSIZE(pIn1); + REGISTER_TRACE(pOp->p1, pIn1); + break; +} +#endif /* SQLITE_OMIT_CAST */ + +/* Opcode: Eq P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]==r[P1] +** +** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then +** jump to address P2. +** +** The SQLITE_AFF_MASK portion of P5 must be an affinity character - +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** to coerce both inputs according to this affinity before the +** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric +** affinity is used. Note that the affinity conversions are stored +** back into the input registers P1 and P3. So this opcode can cause +** persistent changes to registers P1 and P3. +** +** Once any conversions have taken place, and neither value is NULL, +** the values are compared. If both values are blobs then memcmp() is +** used to determine the results of the comparison. If both values +** are text, then the appropriate collating function specified in +** P4 is used to do the comparison. If P4 is not specified then +** memcmp() is used to compare text string. If both values are +** numeric, then a numeric comparison is used. If the two values +** are of different types, then numbers are considered less than +** strings and strings are considered less than blobs. +** +** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either +** true or false and is never NULL. If both operands are NULL then the result +** of comparison is true. If either operand is NULL then the result is false. +** If neither operand is NULL the result is the same as it would be if +** the SQLITE_NULLEQ flag were omitted from P5. +** +** This opcode saves the result of comparison for use by the new +** OP_Jump opcode. +*/ +/* Opcode: Ne P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]!=r[P1] +** +** This works just like the Eq opcode except that the jump is taken if +** the operands in registers P1 and P3 are not equal. See the Eq opcode for +** additional information. +*/ +/* Opcode: Lt P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]r[P1] +** +** This works just like the Lt opcode except that the jump is taken if +** the content of register P3 is greater than the content of +** register P1. See the Lt opcode for additional information. +*/ +/* Opcode: Ge P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]>=r[P1] +** +** This works just like the Lt opcode except that the jump is taken if +** the content of register P3 is greater than or equal to the content of +** register P1. See the Lt opcode for additional information. +*/ +case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ +case OP_Ne: /* same as TK_NE, jump, in1, in3 */ +case OP_Lt: /* same as TK_LT, jump, in1, in3 */ +case OP_Le: /* same as TK_LE, jump, in1, in3 */ +case OP_Gt: /* same as TK_GT, jump, in1, in3 */ +case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ + int res, res2; /* Result of the comparison of pIn1 against pIn3 */ + char affinity; /* Affinity to use for comparison */ + u16 flags1; /* Copy of initial value of pIn1->flags */ + u16 flags3; /* Copy of initial value of pIn3->flags */ + + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + flags1 = pIn1->flags; + flags3 = pIn3->flags; + if( (flags1 & flags3 & MEM_Int)!=0 ){ + /* Common case of comparison of two integers */ + if( pIn3->u.i > pIn1->u.i ){ + if( sqlite3aGTb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + iCompare = +1; + VVA_ONLY( iCompareIsInit = 1; ) + }else if( pIn3->u.i < pIn1->u.i ){ + if( sqlite3aLTb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + iCompare = -1; + VVA_ONLY( iCompareIsInit = 1; ) + }else{ + if( sqlite3aEQb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + iCompare = 0; + VVA_ONLY( iCompareIsInit = 1; ) + } + VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + break; + } + if( (flags1 | flags3)&MEM_Null ){ + /* One or both operands are NULL */ + if( pOp->p5 & SQLITE_NULLEQ ){ + /* If SQLITE_NULLEQ is set (which will only happen if the operator is + ** OP_Eq or OP_Ne) then take the jump or not depending on whether + ** or not both operands are null. + */ + assert( (flags1 & MEM_Cleared)==0 ); + assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB ); + testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 ); + if( (flags1&flags3&MEM_Null)!=0 + && (flags3&MEM_Cleared)==0 + ){ + res = 0; /* Operands are equal */ + }else{ + res = ((flags3 & MEM_Null) ? -1 : +1); /* Operands are not equal */ + } + }else{ + /* SQLITE_NULLEQ is clear and at least one operand is NULL, + ** then the result is always NULL. + ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. + */ + VdbeBranchTaken(2,3); + if( pOp->p5 & SQLITE_JUMPIFNULL ){ + goto jump_to_p2; + } + iCompare = 1; /* Operands are not equal */ + VVA_ONLY( iCompareIsInit = 1; ) + break; + } + }else{ + /* Neither operand is NULL and we couldn't do the special high-speed + ** integer comparison case. So do a general-case comparison. */ + affinity = pOp->p5 & SQLITE_AFF_MASK; + if( affinity>=SQLITE_AFF_NUMERIC ){ + if( (flags1 | flags3)&MEM_Str ){ + if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn1,0); + assert( flags3==pIn3->flags || CORRUPT_DB ); + flags3 = pIn3->flags; + } + if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3,0); + } + } + }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ + if( (flags1 & MEM_Str)!=0 ){ + pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_Real ); + testcase( pIn1->flags & MEM_IntReal ); + sqlite3VdbeMemStringify(pIn1, encoding, 1); + testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); + flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); + if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; + } + if( (flags3 & MEM_Str)!=0 ){ + pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_Real ); + testcase( pIn3->flags & MEM_IntReal ); + sqlite3VdbeMemStringify(pIn3, encoding, 1); + testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); + flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); + } + } + assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); + res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + } + + /* At this point, res is negative, zero, or positive if reg[P1] is + ** less than, equal to, or greater than reg[P3], respectively. Compute + ** the answer to this operator in res2, depending on what the comparison + ** operator actually is. The next block of code depends on the fact + ** that the 6 comparison operators are consecutive integers in this + ** order: NE, EQ, GT, LE, LT, GE */ + assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 ); + assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 ); + if( res<0 ){ + res2 = sqlite3aLTb[pOp->opcode]; + }else if( res==0 ){ + res2 = sqlite3aEQb[pOp->opcode]; + }else{ + res2 = sqlite3aGTb[pOp->opcode]; + } + iCompare = res; + VVA_ONLY( iCompareIsInit = 1; ) + + /* Undo any changes made by applyAffinity() to the input registers. */ + assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); + pIn3->flags = flags3; + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; + + VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + if( res2 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: ElseEq * P2 * * * +** +** This opcode must follow an OP_Lt or OP_Gt comparison operator. There +** can be zero or more OP_ReleaseReg opcodes intervening, but no other +** opcodes are allowed to occur between this instruction and the previous +** OP_Lt or OP_Gt. +** +** If the result of an OP_Eq comparison on the same two operands as +** the prior OP_Lt or OP_Gt would have been true, then jump to P2. If +** the result of an OP_Eq comparison on the two previous operands +** would have been false or NULL, then fall through. +*/ +case OP_ElseEq: { /* same as TK_ESCAPE, jump */ + +#ifdef SQLITE_DEBUG + /* Verify the preconditions of this opcode - that it follows an OP_Lt or + ** OP_Gt with zero or more intervening OP_ReleaseReg opcodes */ + int iAddr; + for(iAddr = (int)(pOp - aOp) - 1; ALWAYS(iAddr>=0); iAddr--){ + if( aOp[iAddr].opcode==OP_ReleaseReg ) continue; + assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt ); + break; + } +#endif /* SQLITE_DEBUG */ + assert( iCompareIsInit ); + VdbeBranchTaken(iCompare==0, 2); + if( iCompare==0 ) goto jump_to_p2; + break; +} + + +/* Opcode: Permutation * * * P4 * +** +** Set the permutation used by the OP_Compare operator in the next +** instruction. The permutation is stored in the P4 operand. +** +** The permutation is only valid for the next opcode which must be +** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5. +** +** The first integer in the P4 integer array is the length of the array +** and does not become part of the permutation. +*/ +case OP_Permutation: { + assert( pOp->p4type==P4_INTARRAY ); + assert( pOp->p4.ai ); + assert( pOp[1].opcode==OP_Compare ); + assert( pOp[1].p5 & OPFLAG_PERMUTE ); + break; +} + +/* Opcode: Compare P1 P2 P3 P4 P5 +** Synopsis: r[P1@P3] <-> r[P2@P3] +** +** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this +** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of +** the comparison for use by the next OP_Jump instruct. +** +** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is +** determined by the most recent OP_Permutation operator. If the +** OPFLAG_PERMUTE bit is clear, then register are compared in sequential +** order. +** +** P4 is a KeyInfo structure that defines collating sequences and sort +** orders for the comparison. The permutation applies to registers +** only. The KeyInfo elements are used sequentially. +** +** The comparison is a sort comparison, so NULLs compare equal, +** NULLs are less than numbers, numbers are less than strings, +** and strings are less than blobs. +** +** This opcode must be immediately followed by an OP_Jump opcode. +*/ +case OP_Compare: { + int n; + int i; + int p1; + int p2; + const KeyInfo *pKeyInfo; + u32 idx; + CollSeq *pColl; /* Collating sequence to use on this term */ + int bRev; /* True for DESCENDING sort order */ + u32 *aPermute; /* The permutation */ + + if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){ + aPermute = 0; + }else{ + assert( pOp>aOp ); + assert( pOp[-1].opcode==OP_Permutation ); + assert( pOp[-1].p4type==P4_INTARRAY ); + aPermute = pOp[-1].p4.ai + 1; + assert( aPermute!=0 ); + } + n = pOp->p3; + pKeyInfo = pOp->p4.pKeyInfo; + assert( n>0 ); + assert( pKeyInfo!=0 ); + p1 = pOp->p1; + p2 = pOp->p2; +#ifdef SQLITE_DEBUG + if( aPermute ){ + int k, mx = 0; + for(k=0; k(u32)mx ) mx = aPermute[k]; + assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 ); + assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 ); + }else{ + assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 ); + assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 ); + } +#endif /* SQLITE_DEBUG */ + for(i=0; inKeyField ); + pColl = pKeyInfo->aColl[i]; + bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); + iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); + VVA_ONLY( iCompareIsInit = 1; ) + if( iCompare ){ + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) + ){ + iCompare = -iCompare; + } + if( bRev ) iCompare = -iCompare; + break; + } + } + assert( pOp[1].opcode==OP_Jump ); + break; +} + +/* Opcode: Jump P1 P2 P3 * * +** +** Jump to the instruction at address P1, P2, or P3 depending on whether +** in the most recent OP_Compare instruction the P1 vector was less than, +** equal to, or greater than the P2 vector, respectively. +** +** This opcode must immediately follow an OP_Compare opcode. +*/ +case OP_Jump: { /* jump */ + assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); + assert( iCompareIsInit ); + if( iCompare<0 ){ + VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; + }else if( iCompare==0 ){ + VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; + }else{ + VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1]; + } + break; +} + +/* Opcode: And P1 P2 P3 * * +** Synopsis: r[P3]=(r[P1] && r[P2]) +** +** Take the logical AND of the values in registers P1 and P2 and +** write the result into register P3. +** +** If either P1 or P2 is 0 (false) then the result is 0 even if +** the other input is NULL. A NULL and true or two NULLs give +** a NULL output. +*/ +/* Opcode: Or P1 P2 P3 * * +** Synopsis: r[P3]=(r[P1] || r[P2]) +** +** Take the logical OR of the values in register P1 and P2 and +** store the answer in register P3. +** +** If either P1 or P2 is nonzero (true) then the result is 1 (true) +** even if the other input is NULL. A NULL and false or two NULLs +** give a NULL output. +*/ +case OP_And: /* same as TK_AND, in1, in2, out3 */ +case OP_Or: { /* same as TK_OR, in1, in2, out3 */ + int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + + v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2); + v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2); + if( pOp->opcode==OP_And ){ + static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; + v1 = and_logic[v1*3+v2]; + }else{ + static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; + v1 = or_logic[v1*3+v2]; + } + pOut = &aMem[pOp->p3]; + if( v1==2 ){ + MemSetTypeFlag(pOut, MEM_Null); + }else{ + pOut->u.i = v1; + MemSetTypeFlag(pOut, MEM_Int); + } + break; +} + +/* Opcode: IsTrue P1 P2 P3 P4 * +** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 +** +** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and +** IS NOT FALSE operators. +** +** Interpret the value in register P1 as a boolean value. Store that +** boolean (a 0 or 1) in register P2. Or if the value in register P1 is +** NULL, then the P3 is stored in register P2. Invert the answer if P4 +** is 1. +** +** The logic is summarized like this: +** +**
    +**
  • If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE +**
  • If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE +**
  • If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE +**
  • If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE +**
+*/ +case OP_IsTrue: { /* in1, out2 */ + assert( pOp->p4type==P4_INT32 ); + assert( pOp->p4.i==0 || pOp->p4.i==1 ); + assert( pOp->p3==0 || pOp->p3==1 ); + sqlite3VdbeMemSetInt64(&aMem[pOp->p2], + sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i); + break; +} + +/* Opcode: Not P1 P2 * * * +** Synopsis: r[P2]= !r[P1] +** +** Interpret the value in register P1 as a boolean value. Store the +** boolean complement in register P2. If the value in register P1 is +** NULL, then a NULL is stored in P2. +*/ +case OP_Not: { /* same as TK_NOT, in1, out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( (pIn1->flags & MEM_Null)==0 ){ + sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0)); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: BitNot P1 P2 * * * +** Synopsis: r[P2]= ~r[P1] +** +** Interpret the content of register P1 as an integer. Store the +** ones-complement of the P1 value into register P2. If P1 holds +** a NULL then store a NULL in P2. +*/ +case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = ~sqlite3VdbeIntValue(pIn1); + } + break; +} + +/* Opcode: Once P1 P2 * * * +** +** Fall through to the next instruction the first time this opcode is +** encountered on each invocation of the byte-code program. Jump to P2 +** on the second and all subsequent encounters during the same invocation. +** +** Top-level programs determine first invocation by comparing the P1 +** operand against the P1 operand on the OP_Init opcode at the beginning +** of the program. If the P1 values differ, then fall through and make +** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are +** the same then take the jump. +** +** For subprograms, there is a bitmask in the VdbeFrame that determines +** whether or not the jump should be taken. The bitmask is necessary +** because the self-altering code trick does not work for recursive +** triggers. +*/ +case OP_Once: { /* jump */ + u32 iAddr; /* Address of this instruction */ + assert( p->aOp[0].opcode==OP_Init ); + if( p->pFrame ){ + iAddr = (int)(pOp - p->aOp); + if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){ + VdbeBranchTaken(1, 2); + goto jump_to_p2; + } + p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7); + }else{ + if( p->aOp[0].p1==pOp->p1 ){ + VdbeBranchTaken(1, 2); + goto jump_to_p2; + } + } + VdbeBranchTaken(0, 2); + pOp->p1 = p->aOp[0].p1; + break; +} + +/* Opcode: If P1 P2 P3 * * +** +** Jump to P2 if the value in register P1 is true. The value +** is considered true if it is numeric and non-zero. If the value +** in P1 is NULL then take the jump if and only if P3 is non-zero. +*/ +case OP_If: { /* jump, in1 */ + int c; + c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3); + VdbeBranchTaken(c!=0, 2); + if( c ) goto jump_to_p2; + break; +} + +/* Opcode: IfNot P1 P2 P3 * * +** +** Jump to P2 if the value in register P1 is False. The value +** is considered false if it has a numeric value of zero. If the value +** in P1 is NULL then take the jump if and only if P3 is non-zero. +*/ +case OP_IfNot: { /* jump, in1 */ + int c; + c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3); + VdbeBranchTaken(c!=0, 2); + if( c ) goto jump_to_p2; + break; +} + +/* Opcode: IsNull P1 P2 * * * +** Synopsis: if r[P1]==NULL goto P2 +** +** Jump to P2 if the value in register P1 is NULL. +*/ +case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ + pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); + if( (pIn1->flags & MEM_Null)!=0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: IsType P1 P2 P3 P4 P5 +** Synopsis: if typeof(P1.P3) in P5 goto P2 +** +** Jump to P2 if the type of a column in a btree is one of the types specified +** by the P5 bitmask. +** +** P1 is normally a cursor on a btree for which the row decode cache is +** valid through at least column P3. In other words, there should have been +** a prior OP_Column for column P3 or greater. If the cursor is not valid, +** then this opcode might give spurious results. +** The the btree row has fewer than P3 columns, then use P4 as the +** datatype. +** +** If P1 is -1, then P3 is a register number and the datatype is taken +** from the value in that register. +** +** P5 is a bitmask of data types. SQLITE_INTEGER is the least significant +** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. +** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10. +** +** WARNING: This opcode does not reliably distinguish between NULL and REAL +** when P1>=0. If the database contains a NaN value, this opcode will think +** that the datatype is REAL when it should be NULL. When P1<0 and the value +** is already stored in register P3, then this opcode does reliably +** distinguish between NULL and REAL. The problem only arises then P1>=0. +** +** Take the jump to address P2 if and only if the datatype of the +** value determined by P1 and P3 corresponds to one of the bits in the +** P5 bitmask. +** +*/ +case OP_IsType: { /* jump */ + VdbeCursor *pC; + u16 typeMask; + u32 serialType; + + assert( pOp->p1>=(-1) && pOp->p1nCursor ); + assert( pOp->p1>=0 || (pOp->p3>=0 && pOp->p3<=(p->nMem+1 - p->nCursor)) ); + if( pOp->p1>=0 ){ + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p3>=0 ); + if( pOp->p3nHdrParsed ){ + serialType = pC->aType[pOp->p3]; + if( serialType>=12 ){ + if( serialType&1 ){ + typeMask = 0x04; /* SQLITE_TEXT */ + }else{ + typeMask = 0x08; /* SQLITE_BLOB */ + } + }else{ + static const unsigned char aMask[] = { + 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2, + 0x01, 0x01, 0x10, 0x10 + }; + testcase( serialType==0 ); + testcase( serialType==1 ); + testcase( serialType==2 ); + testcase( serialType==3 ); + testcase( serialType==4 ); + testcase( serialType==5 ); + testcase( serialType==6 ); + testcase( serialType==7 ); + testcase( serialType==8 ); + testcase( serialType==9 ); + testcase( serialType==10 ); + testcase( serialType==11 ); + typeMask = aMask[serialType]; + } + }else{ + typeMask = 1 << (pOp->p4.i - 1); + testcase( typeMask==0x01 ); + testcase( typeMask==0x02 ); + testcase( typeMask==0x04 ); + testcase( typeMask==0x08 ); + testcase( typeMask==0x10 ); + } + }else{ + assert( memIsValid(&aMem[pOp->p3]) ); + typeMask = 1 << (sqlite3_value_type((sqlite3_value*)&aMem[pOp->p3])-1); + testcase( typeMask==0x01 ); + testcase( typeMask==0x02 ); + testcase( typeMask==0x04 ); + testcase( typeMask==0x08 ); + testcase( typeMask==0x10 ); + } + VdbeBranchTaken( (typeMask & pOp->p5)!=0, 2); + if( typeMask & pOp->p5 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: ZeroOrNull P1 P2 P3 * * +** Synopsis: r[P2] = 0 OR NULL +** +** If both registers P1 and P3 are NOT NULL, then store a zero in +** register P2. If either registers P1 or P3 are NULL then put +** a NULL in register P2. +*/ +case OP_ZeroOrNull: { /* in1, in2, out2, in3 */ + if( (aMem[pOp->p1].flags & MEM_Null)!=0 + || (aMem[pOp->p3].flags & MEM_Null)!=0 + ){ + sqlite3VdbeMemSetNull(aMem + pOp->p2); + }else{ + sqlite3VdbeMemSetInt64(aMem + pOp->p2, 0); + } + break; +} + +/* Opcode: NotNull P1 P2 * * * +** Synopsis: if r[P1]!=NULL goto P2 +** +** Jump to P2 if the value in register P1 is not NULL. +*/ +case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ + pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); + if( (pIn1->flags & MEM_Null)==0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: IfNullRow P1 P2 P3 * * +** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2 +** +** Check the cursor P1 to see if it is currently pointing at a NULL row. +** If it is, then set register P3 to NULL and jump immediately to P2. +** If P1 is not on a NULL row, then fall through without making any +** changes. +** +** If P1 is not an open cursor, then this opcode is a no-op. +*/ +case OP_IfNullRow: { /* jump */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC && pC->nullRow ){ + sqlite3VdbeMemSetNull(aMem + pOp->p3); + goto jump_to_p2; + } + break; +} + +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC +/* Opcode: Offset P1 P2 P3 * * +** Synopsis: r[P3] = sqlite_offset(P1) +** +** Store in register r[P3] the byte offset into the database file that is the +** start of the payload for the record at which that cursor P1 is currently +** pointing. +** +** P2 is the column number for the argument to the sqlite_offset() function. +** This opcode does not use P2 itself, but the P2 value is used by the +** code generator. The P1, P2, and P3 operands to this opcode are the +** same as for OP_Column. +** +** This opcode is only available if SQLite is compiled with the +** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option. +*/ +case OP_Offset: { /* out3 */ + VdbeCursor *pC; /* The VDBE cursor */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + pOut = &p->aMem[pOp->p3]; + if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + if( sqlite3BtreeEof(pC->uc.pCursor) ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + } + } + break; +} +#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ + +/* Opcode: Column P1 P2 P3 P4 P5 +** Synopsis: r[P3]=PX cursor P1 column P2 +** +** Interpret the data that cursor P1 points to as a structure built using +** the MakeRecord instruction. (See the MakeRecord opcode for additional +** information about the format of the data.) Extract the P2-th column +** from this record. If there are less than (P2+1) +** values in the record, extract a NULL. +** +** The value extracted is stored in register P3. +** +** If the record contains fewer than P2 fields, then extract a NULL. Or, +** if the P4 argument is a P4_MEM use the value of the P4 argument as +** the result. +** +** If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed +** to only be used by the length() function or the equivalent. The content +** of large blobs is not loaded, thus saving CPU cycles. If the +** OPFLAG_TYPEOFARG bit is set then the result will only be used by the +** typeof() function or the IS NULL or IS NOT NULL operators or the +** equivalent. In this case, all content loading can be omitted. +*/ +case OP_Column: { /* ncycle */ + u32 p2; /* column number to retrieve */ + VdbeCursor *pC; /* The VDBE cursor */ + BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ + u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ + int len; /* The length of the serialized data for the column */ + int i; /* Loop counter */ + Mem *pDest; /* Where to write the extracted value */ + Mem sMem; /* For storing the record being decoded */ + const u8 *zData; /* Part of the record being decoded */ + const u8 *zHdr; /* Next unparsed byte of the header */ + const u8 *zEndHdr; /* Pointer to first byte after the header */ + u64 offset64; /* 64-bit offset */ + u32 t; /* A type code from the record header */ + Mem *pReg; /* PseudoTable input register */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + pC = p->apCsr[pOp->p1]; + p2 = (u32)pOp->p2; + +op_column_restart: + assert( pC!=0 ); + assert( p2<(u32)pC->nField + || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) ); + aOffset = pC->aOffset; + assert( aOffset==pC->aType+pC->nField ); + assert( pC->eCurType!=CURTYPE_VTAB ); + assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); + assert( pC->eCurType!=CURTYPE_SORTER ); + + if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ + if( pC->nullRow ){ + if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){ + /* For the special case of as pseudo-cursor, the seekResult field + ** identifies the register that holds the record */ + pReg = &aMem[pC->seekResult]; + assert( pReg->flags & MEM_Blob ); + assert( memIsValid(pReg) ); + pC->payloadSize = pC->szRow = pReg->n; + pC->aRow = (u8*)pReg->z; + }else{ + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + sqlite3VdbeMemSetNull(pDest); + goto op_column_out; + } + }else{ + pCrsr = pC->uc.pCursor; + if( pC->deferredMoveto ){ + u32 iMap; + assert( !pC->isEphemeral ); + if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){ + pC = pC->pAltCursor; + p2 = iMap - 1; + goto op_column_restart; + } + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){ + rc = sqlite3VdbeHandleMovedCursor(pC); + if( rc ) goto abort_due_to_error; + goto op_column_restart; + } + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pCrsr ); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); + pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); + assert( pC->szRow<=pC->payloadSize ); + assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ + } + pC->cacheStatus = p->cacheCtr; + if( (aOffset[0] = pC->aRow[0])<0x80 ){ + pC->iHdrOffset = 1; + }else{ + pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset); + } + pC->nHdrParsed = 0; + + if( pC->szRowaRow does not have to hold the entire row, but it does at least + ** need to cover the header of the record. If pC->aRow does not contain + ** the complete header, then set it to zero, forcing the header to be + ** dynamically allocated. */ + pC->aRow = 0; + pC->szRow = 0; + + /* Make sure a corrupt database has not given us an oversize header. + ** Do this now to avoid an oversize memory allocation. + ** + ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte + ** types use so much data space that there can only be 4096 and 32 of + ** them, respectively. So the maximum header length results from a + ** 3-byte type for each of the maximum of 32768 columns plus three + ** extra bytes for the header length itself. 32768*3 + 3 = 98307. + */ + if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){ + goto op_column_corrupt; + } + }else{ + /* This is an optimization. By skipping over the first few tests + ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a + ** measurable performance gain. + ** + ** This branch is taken even if aOffset[0]==0. Such a record is never + ** generated by SQLite, and could be considered corruption, but we + ** accept it for historical reasons. When aOffset[0]==0, the code this + ** branch jumps to reads past the end of the record, but never more + ** than a few bytes. Even if the record occurs at the end of the page + ** content area, the "page header" comes after the page content and so + ** this overread is harmless. Similar overreads can occur for a corrupt + ** database file. + */ + zData = pC->aRow; + assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ + testcase( aOffset[0]==0 ); + goto op_column_read_header; + } + }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){ + rc = sqlite3VdbeHandleMovedCursor(pC); + if( rc ) goto abort_due_to_error; + goto op_column_restart; + } + + /* Make sure at least the first p2+1 entries of the header have been + ** parsed and valid information is in aOffset[] and pC->aType[]. + */ + if( pC->nHdrParsed<=p2 ){ + /* If there is more header available for parsing in the record, try + ** to extract additional fields up through the p2+1-th field + */ + if( pC->iHdrOffsetaRow==0 ){ + memset(&sMem, 0, sizeof(sMem)); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + zData = (u8*)sMem.z; + }else{ + zData = pC->aRow; + } + + /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ + op_column_read_header: + i = pC->nHdrParsed; + offset64 = aOffset[i]; + zHdr = zData + pC->iHdrOffset; + zEndHdr = zData + aOffset[0]; + testcase( zHdr>=zEndHdr ); + do{ + if( (pC->aType[i] = t = zHdr[0])<0x80 ){ + zHdr++; + offset64 += sqlite3VdbeOneByteSerialTypeLen(t); + }else{ + zHdr += sqlite3GetVarint32(zHdr, &t); + pC->aType[i] = t; + offset64 += sqlite3VdbeSerialTypeLen(t); + } + aOffset[++i] = (u32)(offset64 & 0xffffffff); + }while( (u32)i<=p2 && zHdr=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) + || (offset64 > pC->payloadSize) + ){ + if( aOffset[0]==0 ){ + i = 0; + zHdr = zEndHdr; + }else{ + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + goto op_column_corrupt; + } + } + + pC->nHdrParsed = i; + pC->iHdrOffset = (u32)(zHdr - zData); + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + }else{ + t = 0; + } + + /* If after trying to extract new entries from the header, nHdrParsed is + ** still not up to p2, that means that the record has fewer than p2 + ** columns. So the result will be either the default value or a NULL. + */ + if( pC->nHdrParsed<=p2 ){ + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + if( pOp->p4type==P4_MEM ){ + sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); + }else{ + sqlite3VdbeMemSetNull(pDest); + } + goto op_column_out; + } + }else{ + t = pC->aType[p2]; + } + + /* Extract the content for the p2+1-th column. Control can only + ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are + ** all valid. + */ + assert( p2nHdrParsed ); + assert( rc==SQLITE_OK ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + assert( sqlite3VdbeCheckMemInvariants(pDest) ); + if( VdbeMemDynamic(pDest) ){ + sqlite3VdbeMemSetNull(pDest); + } + assert( t==pC->aType[p2] ); + if( pC->szRow>=aOffset[p2+1] ){ + /* This is the common case where the desired content fits on the original + ** page - where the content is not on an overflow page */ + zData = pC->aRow + aOffset[p2]; + if( t<12 ){ + sqlite3VdbeSerialGet(zData, t, pDest); + }else{ + /* If the column value is a string, we need a persistent value, not + ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent + ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). + */ + static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; + pDest->n = len = (t-12)/2; + pDest->enc = encoding; + if( pDest->szMalloc < len+2 ){ + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; + pDest->flags = MEM_Null; + if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; + }else{ + pDest->z = pDest->zMalloc; + } + memcpy(pDest->z, zData, len); + pDest->z[len] = 0; + pDest->z[len+1] = 0; + pDest->flags = aFlag[t&1]; + } + }else{ + u8 p5; + pDest->enc = encoding; + assert( pDest->db==db ); + /* This branch happens only when content is on overflow pages */ + if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0 + && (p5==OPFLAG_TYPEOFARG + || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG)) + ) + ) + || sqlite3VdbeSerialTypeLen(t)==0 + ){ + /* Content is irrelevant for + ** 1. the typeof() function, + ** 2. the length(X) function if X is a blob, and + ** 3. if the content length is zero. + ** So we might as well use bogus content rather than reading + ** content from disk. + ** + ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the + ** buffer passed to it, debugging function VdbeMemPrettyPrint() may + ** read more. Use the global constant sqlite3CtypeMap[] as the array, + ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) + ** and it begins with a bunch of zeros. + */ + sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); + }else{ + rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], + p->cacheCtr, colCacheCtr, pDest); + if( rc ){ + if( rc==SQLITE_NOMEM ) goto no_mem; + if( rc==SQLITE_TOOBIG ) goto too_big; + goto abort_due_to_error; + } + } + } + +op_column_out: + UPDATE_MAX_BLOBSIZE(pDest); + REGISTER_TRACE(pOp->p3, pDest); + break; + +op_column_corrupt: + if( aOp[0].p3>0 ){ + pOp = &aOp[aOp[0].p3-1]; + break; + }else{ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } +} + +/* Opcode: TypeCheck P1 P2 P3 P4 * +** Synopsis: typecheck(r[P1@P2]) +** +** Apply affinities to the range of P2 registers beginning with P1. +** Take the affinities from the Table object in P4. If any value +** cannot be coerced into the correct type, then raise an error. +** +** This opcode is similar to OP_Affinity except that this opcode +** forces the register type to the Table column type. This is used +** to implement "strict affinity". +** +** GENERATED ALWAYS AS ... STATIC columns are only checked if P3 +** is zero. When P3 is non-zero, no type checking occurs for +** static generated columns. Virtual columns are computed at query time +** and so they are never checked. +** +** Preconditions: +** +**
    +**
  • P2 should be the number of non-virtual columns in the +** table of P4. +**
  • Table P4 should be a STRICT table. +**
+** +** If any precondition is false, an assertion fault occurs. +*/ +case OP_TypeCheck: { + Table *pTab; + Column *aCol; + int i; + + assert( pOp->p4type==P4_TABLE ); + pTab = pOp->p4.pTab; + assert( pTab->tabFlags & TF_Strict ); + assert( pTab->nNVCol==pOp->p2 ); + aCol = pTab->aCol; + pIn1 = &aMem[pOp->p1]; + for(i=0; inCol; i++){ + if( aCol[i].colFlags & COLFLAG_GENERATED ){ + if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue; + if( pOp->p3 ){ pIn1++; continue; } + } + assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); + applyAffinity(pIn1, aCol[i].affinity, encoding); + if( (pIn1->flags & MEM_Null)==0 ){ + switch( aCol[i].eCType ){ + case COLTYPE_BLOB: { + if( (pIn1->flags & MEM_Blob)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_INTEGER: + case COLTYPE_INT: { + if( (pIn1->flags & MEM_Int)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_TEXT: { + if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_REAL: { + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); + assert( (pIn1->flags & MEM_IntReal)==0 ); + if( pIn1->flags & MEM_Int ){ + /* When applying REAL affinity, if the result is still an MEM_Int + ** that will fit in 6 bytes, then change the type to MEM_IntReal + ** so that we keep the high-resolution integer value but know that + ** the type really wants to be REAL. */ + testcase( pIn1->u.i==140737488355328LL ); + testcase( pIn1->u.i==140737488355327LL ); + testcase( pIn1->u.i==-140737488355328LL ); + testcase( pIn1->u.i==-140737488355329LL ); + if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL){ + pIn1->flags |= MEM_IntReal; + pIn1->flags &= ~MEM_Int; + }else{ + pIn1->u.r = (double)pIn1->u.i; + pIn1->flags |= MEM_Real; + pIn1->flags &= ~MEM_Int; + } + }else if( (pIn1->flags & (MEM_Real|MEM_IntReal))==0 ){ + goto vdbe_type_error; + } + break; + } + default: { + /* COLTYPE_ANY. Accept anything. */ + break; + } + } + } + REGISTER_TRACE((int)(pIn1-aMem), pIn1); + pIn1++; + } + assert( pIn1 == &aMem[pOp->p1+pOp->p2] ); + break; + +vdbe_type_error: + sqlite3VdbeError(p, "cannot store %s value in %s column %s.%s", + vdbeMemTypeName(pIn1), sqlite3StdType[aCol[i].eCType-1], + pTab->zName, aCol[i].zCnName); + rc = SQLITE_CONSTRAINT_DATATYPE; + goto abort_due_to_error; +} + +/* Opcode: Affinity P1 P2 * P4 * +** Synopsis: affinity(r[P1@P2]) +** +** Apply affinities to a range of P2 registers starting with P1. +** +** P4 is a string that is P2 characters long. The N-th character of the +** string indicates the column affinity that should be used for the N-th +** memory cell in the range. +*/ +case OP_Affinity: { + const char *zAffinity; /* The affinity to be applied */ + + zAffinity = pOp->p4.z; + assert( zAffinity!=0 ); + assert( pOp->p2>0 ); + assert( zAffinity[pOp->p2]==0 ); + pIn1 = &aMem[pOp->p1]; + while( 1 /*exit-by-break*/ ){ + assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); + assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) ); + applyAffinity(pIn1, zAffinity[0], encoding); + if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ + /* When applying REAL affinity, if the result is still an MEM_Int + ** that will fit in 6 bytes, then change the type to MEM_IntReal + ** so that we keep the high-resolution integer value but know that + ** the type really wants to be REAL. */ + testcase( pIn1->u.i==140737488355328LL ); + testcase( pIn1->u.i==140737488355327LL ); + testcase( pIn1->u.i==-140737488355328LL ); + testcase( pIn1->u.i==-140737488355329LL ); + if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){ + pIn1->flags |= MEM_IntReal; + pIn1->flags &= ~MEM_Int; + }else{ + pIn1->u.r = (double)pIn1->u.i; + pIn1->flags |= MEM_Real; + pIn1->flags &= ~(MEM_Int|MEM_Str); + } + } + REGISTER_TRACE((int)(pIn1-aMem), pIn1); + zAffinity++; + if( zAffinity[0]==0 ) break; + pIn1++; + } + break; +} + +/* Opcode: MakeRecord P1 P2 P3 P4 * +** Synopsis: r[P3]=mkrec(r[P1@P2]) +** +** Convert P2 registers beginning with P1 into the [record format] +** use as a data record in a database table or as a key +** in an index. The OP_Column opcode can decode the record later. +** +** P4 may be a string that is P2 characters long. The N-th character of the +** string indicates the column affinity that should be used for the N-th +** field of the index key. +** +** The mapping from character to affinity is given by the SQLITE_AFF_ +** macros defined in sqliteInt.h. +** +** If P4 is NULL then all index fields have the affinity BLOB. +** +** The meaning of P5 depends on whether or not the SQLITE_ENABLE_NULL_TRIM +** compile-time option is enabled: +** +** * If SQLITE_ENABLE_NULL_TRIM is enabled, then the P5 is the index +** of the right-most table that can be null-trimmed. +** +** * If SQLITE_ENABLE_NULL_TRIM is omitted, then P5 has the value +** OPFLAG_NOCHNG_MAGIC if the OP_MakeRecord opcode is allowed to +** accept no-change records with serial_type 10. This value is +** only used inside an assert() and does not affect the end result. +*/ +case OP_MakeRecord: { + Mem *pRec; /* The new record */ + u64 nData; /* Number of bytes of data space */ + int nHdr; /* Number of bytes of header space */ + i64 nByte; /* Data space required for this record */ + i64 nZero; /* Number of zero bytes at the end of the record */ + int nVarint; /* Number of bytes in a varint */ + u32 serial_type; /* Type field */ + Mem *pData0; /* First field to be combined into the record */ + Mem *pLast; /* Last field of the record */ + int nField; /* Number of fields in the record */ + char *zAffinity; /* The affinity string for the record */ + u32 len; /* Length of a field */ + u8 *zHdr; /* Where to write next byte of the header */ + u8 *zPayload; /* Where to write next byte of the payload */ + + /* Assuming the record contains N fields, the record format looks + ** like this: + ** + ** ------------------------------------------------------------------------ + ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | + ** ------------------------------------------------------------------------ + ** + ** Data(0) is taken from register P1. Data(1) comes from register P1+1 + ** and so forth. + ** + ** Each type field is a varint representing the serial type of the + ** corresponding data element (see sqlite3VdbeSerialType()). The + ** hdr-size field is also a varint which is the offset from the beginning + ** of the record to data0. + */ + nData = 0; /* Number of bytes of data space */ + nHdr = 0; /* Number of bytes of header space */ + nZero = 0; /* Number of zero bytes at the end of the record */ + nField = pOp->p1; + zAffinity = pOp->p4.z; + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); + pData0 = &aMem[nField]; + nField = pOp->p2; + pLast = &pData0[nField-1]; + + /* Identify the output register */ + assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); + pOut = &aMem[pOp->p3]; + memAboutToChange(p, pOut); + + /* Apply the requested affinity to all inputs + */ + assert( pData0<=pLast ); + if( zAffinity ){ + pRec = pData0; + do{ + applyAffinity(pRec, zAffinity[0], encoding); + if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){ + pRec->flags |= MEM_IntReal; + pRec->flags &= ~(MEM_Int); + } + REGISTER_TRACE((int)(pRec-aMem), pRec); + zAffinity++; + pRec++; + assert( zAffinity[0]==0 || pRec<=pLast ); + }while( zAffinity[0] ); + } + +#ifdef SQLITE_ENABLE_NULL_TRIM + /* NULLs can be safely trimmed from the end of the record, as long as + ** as the schema format is 2 or more and none of the omitted columns + ** have a non-NULL default value. Also, the record must be left with + ** at least one field. If P5>0 then it will be one more than the + ** index of the right-most column with a non-NULL default value */ + if( pOp->p5 ){ + while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){ + pLast--; + nField--; + } + } +#endif + + /* Loop through the elements that will make up the record to figure + ** out how much space is required for the new record. After this loop, + ** the Mem.uTemp field of each term should hold the serial-type that will + ** be used for that term in the generated record: + ** + ** Mem.uTemp value type + ** --------------- --------------- + ** 0 NULL + ** 1 1-byte signed integer + ** 2 2-byte signed integer + ** 3 3-byte signed integer + ** 4 4-byte signed integer + ** 5 6-byte signed integer + ** 6 8-byte signed integer + ** 7 IEEE float + ** 8 Integer constant 0 + ** 9 Integer constant 1 + ** 10,11 reserved for expansion + ** N>=12 and even BLOB + ** N>=13 and odd text + ** + ** The following additional values are computed: + ** nHdr Number of bytes needed for the record header + ** nData Number of bytes of data space needed for the record + ** nZero Zero bytes at the end of the record + */ + pRec = pLast; + do{ + assert( memIsValid(pRec) ); + if( pRec->flags & MEM_Null ){ + if( pRec->flags & MEM_Zero ){ + /* Values with MEM_Null and MEM_Zero are created by xColumn virtual + ** table methods that never invoke sqlite3_result_xxxxx() while + ** computing an unchanging column value in an UPDATE statement. + ** Give such values a special internal-use-only serial-type of 10 + ** so that they can be passed through to xUpdate and have + ** a true sqlite3_value_nochange(). */ +#ifndef SQLITE_ENABLE_NULL_TRIM + assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); +#endif + pRec->uTemp = 10; + }else{ + pRec->uTemp = 0; + } + nHdr++; + }else if( pRec->flags & (MEM_Int|MEM_IntReal) ){ + /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ + i64 i = pRec->u.i; + u64 uu; + testcase( pRec->flags & MEM_Int ); + testcase( pRec->flags & MEM_IntReal ); + if( i<0 ){ + uu = ~i; + }else{ + uu = i; + } + nHdr++; + testcase( uu==127 ); testcase( uu==128 ); + testcase( uu==32767 ); testcase( uu==32768 ); + testcase( uu==8388607 ); testcase( uu==8388608 ); + testcase( uu==2147483647 ); testcase( uu==2147483648LL ); + testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); + if( uu<=127 ){ + if( (i&1)==i && p->minWriteFileFormat>=4 ){ + pRec->uTemp = 8+(u32)uu; + }else{ + nData++; + pRec->uTemp = 1; + } + }else if( uu<=32767 ){ + nData += 2; + pRec->uTemp = 2; + }else if( uu<=8388607 ){ + nData += 3; + pRec->uTemp = 3; + }else if( uu<=2147483647 ){ + nData += 4; + pRec->uTemp = 4; + }else if( uu<=140737488355327LL ){ + nData += 6; + pRec->uTemp = 5; + }else{ + nData += 8; + if( pRec->flags & MEM_IntReal ){ + /* If the value is IntReal and is going to take up 8 bytes to store + ** as an integer, then we might as well make it an 8-byte floating + ** point value */ + pRec->u.r = (double)pRec->u.i; + pRec->flags &= ~MEM_IntReal; + pRec->flags |= MEM_Real; + pRec->uTemp = 7; + }else{ + pRec->uTemp = 6; + } + } + }else if( pRec->flags & MEM_Real ){ + nHdr++; + nData += 8; + pRec->uTemp = 7; + }else{ + assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) ); + assert( pRec->n>=0 ); + len = (u32)pRec->n; + serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0); + if( pRec->flags & MEM_Zero ){ + serial_type += pRec->u.nZero*2; + if( nData ){ + if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; + len += pRec->u.nZero; + }else{ + nZero += pRec->u.nZero; + } + } + nData += len; + nHdr += sqlite3VarintLen(serial_type); + pRec->uTemp = serial_type; + } + if( pRec==pData0 ) break; + pRec--; + }while(1); + + /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint + ** which determines the total number of bytes in the header. The varint + ** value is the size of the header in bytes including the size varint + ** itself. */ + testcase( nHdr==126 ); + testcase( nHdr==127 ); + if( nHdr<=126 ){ + /* The common case */ + nHdr += 1; + }else{ + /* Rare case of a really large header */ + nVarint = sqlite3VarintLen(nHdr); + nHdr += nVarint; + if( nVarintp3) is not allowed to + ** be one of the input registers (because the following call to + ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). + */ + if( nByte+nZero<=pOut->szMalloc ){ + /* The output register is already large enough to hold the record. + ** No error checks or buffer enlargement is required */ + pOut->z = pOut->zMalloc; + }else{ + /* Need to make sure that the output is not too big and then enlarge + ** the output register to hold the full result */ + if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + goto no_mem; + } + } + pOut->n = (int)nByte; + pOut->flags = MEM_Blob; + if( nZero ){ + pOut->u.nZero = nZero; + pOut->flags |= MEM_Zero; + } + UPDATE_MAX_BLOBSIZE(pOut); + zHdr = (u8 *)pOut->z; + zPayload = zHdr + nHdr; + + /* Write the record */ + if( nHdr<0x80 ){ + *(zHdr++) = nHdr; + }else{ + zHdr += sqlite3PutVarint(zHdr,nHdr); + } + assert( pData0<=pLast ); + pRec = pData0; + while( 1 /*exit-by-break*/ ){ + serial_type = pRec->uTemp; + /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more + ** additional varints, one per column. + ** EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** immediately follow the header. */ + if( serial_type<=7 ){ + *(zHdr++) = serial_type; + if( serial_type==0 ){ + /* NULL value. No change in zPayload */ + }else{ + u64 v; + if( serial_type==7 ){ + assert( sizeof(v)==sizeof(pRec->u.r) ); + memcpy(&v, &pRec->u.r, sizeof(v)); + swapMixedEndianFloat(v); + }else{ + v = pRec->u.i; + } + len = sqlite3SmallTypeSizes[serial_type]; + assert( len>=1 && len<=8 && len!=5 && len!=7 ); + switch( len ){ + default: zPayload[7] = (u8)(v&0xff); v >>= 8; + zPayload[6] = (u8)(v&0xff); v >>= 8; + case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; + zPayload[4] = (u8)(v&0xff); v >>= 8; + case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; + case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; + case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; + case 1: zPayload[0] = (u8)(v&0xff); + } + zPayload += len; + } + }else if( serial_type<0x80 ){ + *(zHdr++) = serial_type; + if( serial_type>=14 && pRec->n>0 ){ + assert( pRec->z!=0 ); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } + }else{ + zHdr += sqlite3PutVarint(zHdr, serial_type); + if( pRec->n ){ + assert( pRec->z!=0 ); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } + } + if( pRec==pLast ) break; + pRec++; + } + assert( nHdr==(int)(zHdr - (u8*)pOut->z) ); + assert( nByte==(int)(zPayload - (u8*)pOut->z) ); + + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + REGISTER_TRACE(pOp->p3, pOut); + break; +} + +/* Opcode: Count P1 P2 P3 * * +** Synopsis: r[P2]=count() +** +** Store the number of entries (an integer value) in the table or index +** opened by cursor P1 in register P2. +** +** If P3==0, then an exact count is obtained, which involves visiting +** every btree page of the table. But if P3 is non-zero, an estimate +** is returned based on the current cursor position. +*/ +case OP_Count: { /* out2 */ + i64 nEntry; + BtCursor *pCrsr; + + assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE ); + pCrsr = p->apCsr[pOp->p1]->uc.pCursor; + assert( pCrsr ); + if( pOp->p3 ){ + nEntry = sqlite3BtreeRowCountEst(pCrsr); + }else{ + nEntry = 0; /* Not needed. Only used to silence a warning. */ + rc = sqlite3BtreeCount(db, pCrsr, &nEntry); + if( rc ) goto abort_due_to_error; + } + pOut = out2Prerelease(p, pOp); + pOut->u.i = nEntry; + goto check_for_interrupt; +} + +/* Opcode: Savepoint P1 * * P4 * +** +** Open, release or rollback the savepoint named by parameter P4, depending +** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN). +** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE). +** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK). +*/ +case OP_Savepoint: { + int p1; /* Value of P1 operand */ + char *zName; /* Name of savepoint */ + int nName; + Savepoint *pNew; + Savepoint *pSavepoint; + Savepoint *pTmp; + int iSavepoint; + int ii; + + p1 = pOp->p1; + zName = pOp->p4.z; + + /* Assert that the p1 parameter is valid. Also that if there is no open + ** transaction, then there cannot be any savepoints. + */ + assert( db->pSavepoint==0 || db->autoCommit==0 ); + assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); + assert( db->pSavepoint || db->isTransactionSavepoint==0 ); + assert( checkSavepointCount(db) ); + assert( p->bIsReader ); + + if( p1==SAVEPOINT_BEGIN ){ + if( db->nVdbeWrite>0 ){ + /* A new savepoint cannot be created if there are active write + ** statements (i.e. open read/write incremental blob handles). + */ + sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress"); + rc = SQLITE_BUSY; + }else{ + nName = sqlite3Strlen30(zName); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* This call is Ok even if this savepoint is actually a transaction + ** savepoint (and therefore should not prompt xSavepoint()) callbacks. + ** If this is a transaction savepoint being opened, it is guaranteed + ** that the db->aVTrans[] array is empty. */ + assert( db->autoCommit==0 || db->nVTrans==0 ); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, + db->nStatement+db->nSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; +#endif + + /* Create a new savepoint structure. */ + pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); + if( pNew ){ + pNew->zName = (char *)&pNew[1]; + memcpy(pNew->zName, zName, nName+1); + + /* If there is no open transaction, then mark this as a special + ** "transaction savepoint". */ + if( db->autoCommit ){ + db->autoCommit = 0; + db->isTransactionSavepoint = 1; + }else{ + db->nSavepoint++; + } + + /* Link the new savepoint into the database handle's list. */ + pNew->pNext = db->pSavepoint; + db->pSavepoint = pNew; + pNew->nDeferredCons = db->nDeferredCons; + pNew->nDeferredImmCons = db->nDeferredImmCons; + } + } + }else{ + assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK ); + iSavepoint = 0; + + /* Find the named savepoint. If there is no such savepoint, then an + ** an error is returned to the user. */ + for( + pSavepoint = db->pSavepoint; + pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); + pSavepoint = pSavepoint->pNext + ){ + iSavepoint++; + } + if( !pSavepoint ){ + sqlite3VdbeError(p, "no such savepoint: %s", zName); + rc = SQLITE_ERROR; + }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ + /* It is not possible to release (commit) a savepoint if there are + ** active write statements. + */ + sqlite3VdbeError(p, "cannot release savepoint - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + }else{ + + /* Determine whether or not this is a transaction savepoint. If so, + ** and this is a RELEASE command, then the current transaction + ** is committed. + */ + int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; + if( isTransaction && p1==SAVEPOINT_RELEASE ){ + if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + goto vdbe_return; + } + db->autoCommit = 1; + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + db->autoCommit = 0; + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + rc = p->rc; + if( rc ){ + db->autoCommit = 0; + }else{ + db->isTransactionSavepoint = 0; + } + }else{ + int isSchemaChange; + iSavepoint = db->nSavepoint - iSavepoint - 1; + if( p1==SAVEPOINT_ROLLBACK ){ + isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0; + for(ii=0; iinDb; ii++){ + rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, + SQLITE_ABORT_ROLLBACK, + isSchemaChange==0); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + }else{ + assert( p1==SAVEPOINT_RELEASE ); + isSchemaChange = 0; + } + for(ii=0; iinDb; ii++){ + rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + } + if( isSchemaChange ){ + sqlite3ExpirePreparedStatements(db, 0); + sqlite3ResetAllSchemasOfConnection(db); + db->mDbFlags |= DBFLAG_SchemaChange; + } + } + if( rc ) goto abort_due_to_error; + + /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all + ** savepoints nested inside of the savepoint being operated on. */ + while( db->pSavepoint!=pSavepoint ){ + pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + db->nSavepoint--; + } + + /* If it is a RELEASE, then destroy the savepoint being operated on + ** too. If it is a ROLLBACK TO, then set the number of deferred + ** constraint violations present in the database to the value stored + ** when the savepoint was created. */ + if( p1==SAVEPOINT_RELEASE ){ + assert( pSavepoint==db->pSavepoint ); + db->pSavepoint = pSavepoint->pNext; + sqlite3DbFree(db, pSavepoint); + if( !isTransaction ){ + db->nSavepoint--; + } + }else{ + assert( p1==SAVEPOINT_ROLLBACK ); + db->nDeferredCons = pSavepoint->nDeferredCons; + db->nDeferredImmCons = pSavepoint->nDeferredImmCons; + } + + if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, p1, iSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + } + } + if( rc ) goto abort_due_to_error; + if( p->eVdbeState==VDBE_HALT_STATE ){ + rc = SQLITE_DONE; + goto vdbe_return; + } + break; +} + +/* Opcode: AutoCommit P1 P2 * * * +** +** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll +** back any currently active btree transactions. If there are any active +** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if +** there are active writing VMs or active VMs that use shared cache. +** +** This instruction causes the VM to halt. +*/ +case OP_AutoCommit: { + int desiredAutoCommit; + int iRollback; + + desiredAutoCommit = pOp->p1; + iRollback = pOp->p2; + assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); + assert( desiredAutoCommit==1 || iRollback==0 ); + assert( db->nVdbeActive>0 ); /* At least this one VM is active */ + assert( p->bIsReader ); + + if( desiredAutoCommit!=db->autoCommit ){ + if( iRollback ){ + assert( desiredAutoCommit==1 ); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + db->autoCommit = 1; + }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ + /* If this instruction implements a COMMIT and other VMs are writing + ** return an error indicating that the other VMs must complete first. + */ + sqlite3VdbeError(p, "cannot commit transaction - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + goto abort_due_to_error; + }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + goto vdbe_return; + }else{ + db->autoCommit = (u8)desiredAutoCommit; + } + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + db->autoCommit = (u8)(1-desiredAutoCommit); + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + sqlite3CloseSavepoints(db); + if( p->rc==SQLITE_OK ){ + rc = SQLITE_DONE; + }else{ + rc = SQLITE_ERROR; + } + goto vdbe_return; + }else{ + sqlite3VdbeError(p, + (!desiredAutoCommit)?"cannot start a transaction within a transaction":( + (iRollback)?"cannot rollback - no transaction is active": + "cannot commit - no transaction is active")); + + rc = SQLITE_ERROR; + goto abort_due_to_error; + } + /*NOTREACHED*/ assert(0); +} + +/* Opcode: Transaction P1 P2 P3 P4 P5 +** +** Begin a transaction on database P1 if a transaction is not already +** active. +** If P2 is non-zero, then a write-transaction is started, or if a +** read-transaction is already active, it is upgraded to a write-transaction. +** If P2 is zero, then a read-transaction is started. If P2 is 2 or more +** then an exclusive transaction is started. +** +** P1 is the index of the database file on which the transaction is +** started. Index 0 is the main database file and index 1 is the +** file used for temporary tables. Indices of 2 or more are used for +** attached databases. +** +** If a write-transaction is started and the Vdbe.usesStmtJournal flag is +** true (this flag is set if the Vdbe may modify more than one row and may +** throw an ABORT exception), a statement transaction may also be opened. +** More specifically, a statement transaction is opened iff the database +** connection is currently not in autocommit mode, or if there are other +** active statements. A statement transaction allows the changes made by this +** VDBE to be rolled back after an error without having to roll back the +** entire transaction. If no error is encountered, the statement transaction +** will automatically commit when the VDBE halts. +** +** If P5!=0 then this opcode also checks the schema cookie against P3 +** and the schema generation counter against P4. +** The cookie changes its value whenever the database schema changes. +** This operation is used to detect when that the cookie has changed +** and that the current process needs to reread the schema. If the schema +** cookie in P3 differs from the schema cookie in the database header or +** if the schema generation counter in P4 differs from the current +** generation counter, then an SQLITE_SCHEMA error is raised and execution +** halts. The sqlite3_step() wrapper function might then reprepare the +** statement and rerun it from the beginning. +*/ +case OP_Transaction: { + Btree *pBt; + Db *pDb; + int iMeta = 0; + + assert( p->bIsReader ); + assert( p->readOnly==0 || pOp->p2==0 ); + assert( pOp->p2>=0 && pOp->p2<=2 ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( rc==SQLITE_OK ); + if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){ + if( db->flags & SQLITE_QueryOnly ){ + /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */ + rc = SQLITE_READONLY; + }else{ + /* Writes prohibited due to a prior SQLITE_CORRUPT in the current + ** transaction */ + rc = SQLITE_CORRUPT; + } + goto abort_due_to_error; + } + pDb = &db->aDb[pOp->p1]; + pBt = pDb->pBt; + + if( pBt ){ + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); + testcase( rc==SQLITE_BUSY_SNAPSHOT ); + testcase( rc==SQLITE_BUSY_RECOVERY ); + if( rc!=SQLITE_OK ){ + if( (rc&0xff)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + p->rc = rc; + goto vdbe_return; + } + goto abort_due_to_error; + } + + if( p->usesStmtJournal + && pOp->p2 + && (db->autoCommit==0 || db->nVdbeRead>1) + ){ + assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ); + if( p->iStatement==0 ){ + assert( db->nStatement>=0 && db->nSavepoint>=0 ); + db->nStatement++; + p->iStatement = db->nSavepoint + db->nStatement; + } + + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); + } + + /* Store the current value of the database handles deferred constraint + ** counter. If the statement transaction needs to be rolled back, + ** the value of this counter needs to be restored too. */ + p->nStmtDefCons = db->nDeferredCons; + p->nStmtDefImmCons = db->nDeferredImmCons; + } + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( rc==SQLITE_OK + && pOp->p5 + && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i) + ){ + /* + ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema + ** version is checked to ensure that the schema has not changed since the + ** SQL statement was prepared. + */ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); + /* If the schema-cookie from the database file matches the cookie + ** stored with the in-memory representation of the schema, do + ** not reload the schema from the database file. + ** + ** If virtual-tables are in use, this is not just an optimization. + ** Often, v-tables store their data in other SQLite tables, which + ** are queried from within xNext() and other v-table methods using + ** prepared queries. If such a query is out-of-date, we do not want to + ** discard the database schema, as the user code implementing the + ** v-table would have to be ready for the sqlite3_vtab structure itself + ** to be invalidated whenever sqlite3_step() is called from within + ** a v-table method. + */ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ + sqlite3ResetOneSchema(db, pOp->p1); + } + p->expired = 1; + rc = SQLITE_SCHEMA; + + /* Set changeCntOn to 0 to prevent the value returned by sqlite3_changes() + ** from being modified in sqlite3VdbeHalt(). If this statement is + ** reprepared, changeCntOn will be set again. */ + p->changeCntOn = 0; + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: ReadCookie P1 P2 P3 * * +** +** Read cookie number P3 from database P1 and write it into register P2. +** P3==1 is the schema version. P3==2 is the database format. +** P3==3 is the recommended pager cache size, and so forth. P1==0 is +** the main database file and P1==1 is the database file used to store +** temporary tables. +** +** There must be a read-lock on the database (either a transaction +** must be started or there must be an open cursor) before +** executing this instruction. +*/ +case OP_ReadCookie: { /* out2 */ + int iMeta; + int iDb; + int iCookie; + + assert( p->bIsReader ); + iDb = pOp->p1; + iCookie = pOp->p3; + assert( pOp->p3=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + assert( DbMaskTest(p->btreeMask, iDb) ); + + sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); + pOut = out2Prerelease(p, pOp); + pOut->u.i = iMeta; + break; +} + +/* Opcode: SetCookie P1 P2 P3 * P5 +** +** Write the integer value P3 into cookie number P2 of database P1. +** P2==1 is the schema version. P2==2 is the database format. +** P2==3 is the recommended pager cache +** size, and so forth. P1==0 is the main database file and P1==1 is the +** database file used to store temporary tables. +** +** A transaction must be started before executing this opcode. +** +** If P2 is the SCHEMA_VERSION cookie (cookie number 1) then the internal +** schema version is set to P3-P5. The "PRAGMA schema_version=N" statement +** has P5 set to 1, so that the internal schema version will be different +** from the database schema version, resulting in a schema reset. +*/ +case OP_SetCookie: { + Db *pDb; + + sqlite3VdbeIncrWriteCounter(p, 0); + assert( pOp->p2p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pDb = &db->aDb[pOp->p1]; + assert( pDb->pBt!=0 ); + assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); + /* See note about index shifting on OP_ReadCookie */ + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); + if( pOp->p2==BTREE_SCHEMA_VERSION ){ + /* When the schema cookie changes, record the new cookie internally */ + *(u32*)&pDb->pSchema->schema_cookie = *(u32*)&pOp->p3 - pOp->p5; + db->mDbFlags |= DBFLAG_SchemaChange; + sqlite3FkClearTriggerCache(db, pOp->p1); + }else if( pOp->p2==BTREE_FILE_FORMAT ){ + /* Record changes in the file format */ + pDb->pSchema->file_format = pOp->p3; + } + if( pOp->p1==1 ){ + /* Invalidate all prepared statements whenever the TEMP database + ** schema is changed. Ticket #1644 */ + sqlite3ExpirePreparedStatements(db, 0); + p->expired = 0; + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: OpenRead P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** Open a read-only cursor for the database table whose root page is +** P2 in a database file. The database file is determined by P3. +** P3==0 means the main database, P3==1 means the database used for +** temporary tables, and P3>1 means used the corresponding attached +** database. Give the new cursor an identifier of P1. The P1 +** values need not be contiguous but all P1 values should be small integers. +** It is an error for P1 to be negative. +** +** Allowed P5 bits: +**
    +**
  • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxLT) +**
+** +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. +** +** See also: OpenWrite, ReopenIdx +*/ +/* Opcode: ReopenIdx P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** The ReopenIdx opcode works like OP_OpenRead except that it first +** checks to see if the cursor on P1 is already open on the same +** b-tree and if it is this opcode becomes a no-op. In other words, +** if the cursor is already open, do not reopen it. +** +** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ +** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must +** be the same as every other ReopenIdx or OpenRead for the same cursor +** number. +** +** Allowed P5 bits: +**
    +**
  • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxLT) +**
+** +** See also: OP_OpenRead, OP_OpenWrite +*/ +/* Opcode: OpenWrite P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** Open a read/write cursor named P1 on the table or index whose root +** page is P2 (or whose root page is held in register P2 if the +** OPFLAG_P2ISREG bit is set in P5 - see below). +** +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. +** +** Allowed P5 bits: +**
    +**
  • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxLT) +**
  • 0x08 OPFLAG_FORDELETE: This cursor is used only to seek +** and subsequently delete entries in an index btree. This is a +** hint to the storage engine that the storage engine is allowed to +** ignore. The hint is not used by the official SQLite b*tree storage +** engine, but is used by COMDB2. +**
  • 0x10 OPFLAG_P2ISREG: Use the content of register P2 +** as the root page, not the value of P2 itself. +**
+** +** This instruction works like OpenRead except that it opens the cursor +** in read/write mode. +** +** See also: OP_OpenRead, OP_ReopenIdx +*/ +case OP_ReopenIdx: { /* ncycle */ + int nField; + KeyInfo *pKeyInfo; + u32 p2; + int iDb; + int wrFlag; + Btree *pX; + VdbeCursor *pCur; + Db *pDb; + + assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); + assert( pOp->p4type==P4_KEYINFO ); + pCur = p->apCsr[pOp->p1]; + if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ + assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ + assert( pCur->eCurType==CURTYPE_BTREE ); + sqlite3BtreeClearCursor(pCur->uc.pCursor); + goto open_cursor_set_hints; + } + /* If the cursor is not currently open or is open on a different + ** index, then fall through into OP_OpenRead to force a reopen */ +case OP_OpenRead: /* ncycle */ +case OP_OpenWrite: + + assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); + assert( p->bIsReader ); + assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx + || p->readOnly==0 ); + + if( p->expired==1 ){ + rc = SQLITE_ABORT_ROLLBACK; + goto abort_due_to_error; + } + + nField = 0; + pKeyInfo = 0; + p2 = (u32)pOp->p2; + iDb = pOp->p3; + assert( iDb>=0 && iDbnDb ); + assert( DbMaskTest(p->btreeMask, iDb) ); + pDb = &db->aDb[iDb]; + pX = pDb->pBt; + assert( pX!=0 ); + if( pOp->opcode==OP_OpenWrite ){ + assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); + wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( pDb->pSchema->file_format < p->minWriteFileFormat ){ + p->minWriteFileFormat = pDb->pSchema->file_format; + } + }else{ + wrFlag = 0; + } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); + assert( pOp->opcode==OP_OpenWrite ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateBtree opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + assert( p2>=2 ); + } + if( pOp->p4type==P4_KEYINFO ){ + pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->enc==ENC(db) ); + assert( pKeyInfo->db==db ); + nField = pKeyInfo->nAllField; + }else if( pOp->p4type==P4_INT32 ){ + nField = pOp->p4.i; + } + assert( pOp->p1>=0 ); + assert( nField>=0 ); + testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ + pCur = allocateCursor(p, pOp->p1, nField, CURTYPE_BTREE); + if( pCur==0 ) goto no_mem; + pCur->iDb = iDb; + pCur->nullRow = 1; + pCur->isOrdered = 1; + pCur->pgnoRoot = p2; +#ifdef SQLITE_DEBUG + pCur->wrFlag = wrFlag; +#endif + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); + pCur->pKeyInfo = pKeyInfo; + /* Set the VdbeCursor.isTable variable. Previous versions of + ** SQLite used to check if the root-page flags were sane at this point + ** and report database corruption if they were not, but this check has + ** since moved into the btree layer. */ + pCur->isTable = pOp->p4type!=P4_KEYINFO; + +open_cursor_set_hints: + assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); + assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); + testcase( pOp->p5 & OPFLAG_BULKCSR ); + testcase( pOp->p2 & OPFLAG_SEEKEQ ); + sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: OpenDup P1 P2 * * * +** +** Open a new cursor P1 that points to the same ephemeral table as +** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral +** opcode. Only ephemeral cursors may be duplicated. +** +** Duplicate ephemeral cursors are used for self-joins of materialized views. +*/ +case OP_OpenDup: { /* ncycle */ + VdbeCursor *pOrig; /* The original cursor to be duplicated */ + VdbeCursor *pCx; /* The new cursor */ + + pOrig = p->apCsr[pOp->p2]; + assert( pOrig ); + assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */ + + pCx = allocateCursor(p, pOp->p1, pOrig->nField, CURTYPE_BTREE); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->isEphemeral = 1; + pCx->pKeyInfo = pOrig->pKeyInfo; + pCx->isTable = pOrig->isTable; + pCx->pgnoRoot = pOrig->pgnoRoot; + pCx->isOrdered = pOrig->isOrdered; + pCx->ub.pBtx = pOrig->ub.pBtx; + pCx->noReuse = 1; + pOrig->noReuse = 1; + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pCx->pKeyInfo, pCx->uc.pCursor); + /* The sqlite3BtreeCursor() routine can only fail for the first cursor + ** opened for a database. Since there is already an open cursor when this + ** opcode is run, the sqlite3BtreeCursor() cannot fail */ + assert( rc==SQLITE_OK ); + break; +} + + +/* Opcode: OpenEphemeral P1 P2 P3 P4 P5 +** Synopsis: nColumn=P2 +** +** Open a new cursor P1 to a transient table. +** The cursor is always opened read/write even if +** the main database is read-only. The ephemeral +** table is deleted automatically when the cursor is closed. +** +** If the cursor P1 is already opened on an ephemeral table, the table +** is cleared (all content is erased). +** +** P2 is the number of columns in the ephemeral table. +** The cursor points to a BTree table if P4==0 and to a BTree index +** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure +** that defines the format of keys in the index. +** +** The P5 parameter can be a mask of the BTREE_* flags defined +** in btree.h. These flags control aspects of the operation of +** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are +** added automatically. +** +** If P3 is positive, then reg[P3] is modified slightly so that it +** can be used as zero-length data for OP_Insert. This is an optimization +** that avoids an extra OP_Blob opcode to initialize that register. +*/ +/* Opcode: OpenAutoindex P1 P2 * P4 * +** Synopsis: nColumn=P2 +** +** This opcode works the same as OP_OpenEphemeral. It has a +** different name to distinguish its use. Tables created using +** by this opcode will be used for automatically created transient +** indices in joins. +*/ +case OP_OpenAutoindex: /* ncycle */ +case OP_OpenEphemeral: { /* ncycle */ + VdbeCursor *pCx; + KeyInfo *pKeyInfo; + + static const int vfsFlags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TRANSIENT_DB; + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); + if( pOp->p3>0 ){ + /* Make register reg[P3] into a value that can be used as the data + ** form sqlite3BtreeInsert() where the length of the data is zero. */ + assert( pOp->p2==0 ); /* Only used when number of columns is zero */ + assert( pOp->opcode==OP_OpenEphemeral ); + assert( aMem[pOp->p3].flags & MEM_Null ); + aMem[pOp->p3].n = 0; + aMem[pOp->p3].z = ""; + } + pCx = p->apCsr[pOp->p1]; + if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ + /* If the ephemeral table is already open and has no duplicates from + ** OP_OpenDup, then erase all existing content so that the table is + ** empty again, rather than creating a new table. */ + assert( pCx->isEphemeral ); + pCx->seqCount = 0; + pCx->cacheStatus = CACHE_STALE; + rc = sqlite3BtreeClearTable(pCx->ub.pBtx, pCx->pgnoRoot, 0); + }else{ + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); + if( pCx==0 ) goto no_mem; + pCx->isEphemeral = 1; + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, + BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, + vfsFlags); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pCx->ub.pBtx, 1, 0); + if( rc==SQLITE_OK ){ + /* If a transient index is required, create it by calling + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before + ** opening it. If a transient table is required, just use the + ** automatically created table with root-page 1 (an BLOB_INTKEY table). + */ + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + assert( pOp->p4type==P4_KEYINFO ); + rc = sqlite3BtreeCreateTable(pCx->ub.pBtx, &pCx->pgnoRoot, + BTREE_BLOBKEY | pOp->p5); + if( rc==SQLITE_OK ){ + assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); + assert( pKeyInfo->db==db ); + assert( pKeyInfo->enc==ENC(db) ); + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pKeyInfo, pCx->uc.pCursor); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->ub.pBtx, SCHEMA_ROOT, BTREE_WRCSR, + 0, pCx->uc.pCursor); + pCx->isTable = 1; + } + } + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + if( rc ){ + sqlite3BtreeClose(pCx->ub.pBtx); + } + } + } + if( rc ) goto abort_due_to_error; + pCx->nullRow = 1; + break; +} + +/* Opcode: SorterOpen P1 P2 P3 P4 * +** +** This opcode works like OP_OpenEphemeral except that it opens +** a transient index that is specifically designed to sort large +** tables using an external merge-sort algorithm. +** +** If argument P3 is non-zero, then it indicates that the sorter may +** assume that a stable sort considering the first P3 fields of each +** key is sufficient to produce the required results. +*/ +case OP_SorterOpen: { + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER); + if( pCx==0 ) goto no_mem; + pCx->pKeyInfo = pOp->p4.pKeyInfo; + assert( pCx->pKeyInfo->db==db ); + assert( pCx->pKeyInfo->enc==ENC(db) ); + rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: SequenceTest P1 P2 * * * +** Synopsis: if( cursor[P1].ctr++ ) pc = P2 +** +** P1 is a sorter cursor. If the sequence counter is currently zero, jump +** to P2. Regardless of whether or not the jump is taken, increment the +** the sequence value. +*/ +case OP_SequenceTest: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + if( (pC->seqCount++)==0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: OpenPseudo P1 P2 P3 * * +** Synopsis: P3 columns in r[P2] +** +** Open a new cursor that points to a fake table that contains a single +** row of data. The content of that one row is the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. +** +** A pseudo-table created by this opcode is used to hold a single +** row output from the sorter so that the row can be decomposed into +** individual columns using the OP_Column opcode. The OP_Column opcode +** is the only cursor opcode that works with a pseudo-table. +** +** P3 is the number of fields in the records that will be stored by +** the pseudo-table. +*/ +case OP_OpenPseudo: { + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + assert( pOp->p3>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->seekResult = pOp->p2; + pCx->isTable = 1; + /* Give this pseudo-cursor a fake BtCursor pointer so that pCx + ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test + ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() + ** which is a performance optimization */ + pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); + assert( pOp->p5==0 ); + break; +} + +/* Opcode: Close P1 * * * * +** +** Close a cursor previously opened as P1. If P1 is not +** currently open, this instruction is a no-op. +*/ +case OP_Close: { /* ncycle */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + p->apCsr[pOp->p1] = 0; + break; +} + +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK +/* Opcode: ColumnsUsed P1 * * P4 * +** +** This opcode (which only exists if SQLite was compiled with +** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the +** table or index for cursor P1 are used. P4 is a 64-bit integer +** (P4_INT64) in which the first 63 bits are one for each of the +** first 63 columns of the table or index that are actually used +** by the cursor. The high-order bit is set if any column after +** the 64th is used. +*/ +case OP_ColumnsUsed: { + VdbeCursor *pC; + pC = p->apCsr[pOp->p1]; + assert( pC->eCurType==CURTYPE_BTREE ); + pC->maskUsed = *(u64*)pOp->p4.pI64; + break; +} +#endif + +/* Opcode: SeekGE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as the key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than or equal to the key value. If there are no records +** greater than or equal to the key and P2 is not zero, then jump to P2. +** +** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this +** opcode will either land on a record that exactly matches the key, or +** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ, +** this opcode must be followed by an IdxLE opcode with the same arguments. +** The IdxGT opcode will be skipped if this opcode succeeds, but the +** IdxGT opcode will be used on subsequent loop iterations. The +** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this +** is an equality search. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +** +** See also: Found, NotFound, SeekLt, SeekGt, SeekLe +*/ +/* Opcode: SeekGT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than the key value. If there are no records greater than +** the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +** +** See also: Found, NotFound, SeekLt, SeekGe, SeekLe +*/ +/* Opcode: SeekLT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the largest entry that +** is less than the key value. If there are no records less than +** the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +** +** See also: Found, NotFound, SeekGt, SeekGe, SeekLe +*/ +/* Opcode: SeekLE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the largest entry that +** is less than or equal to the key value. If there are no records +** less than or equal to the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +** +** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this +** opcode will either land on a record that exactly matches the key, or +** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ, +** this opcode must be followed by an IdxLE opcode with the same arguments. +** The IdxGE opcode will be skipped if this opcode succeeds, but the +** IdxGE opcode will be used on subsequent loop iterations. The +** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this +** is an equality search. +** +** See also: Found, NotFound, SeekGt, SeekGe, SeekLt +*/ +case OP_SeekLT: /* jump, in3, group, ncycle */ +case OP_SeekLE: /* jump, in3, group, ncycle */ +case OP_SeekGE: /* jump, in3, group, ncycle */ +case OP_SeekGT: { /* jump, in3, group, ncycle */ + int res; /* Comparison result */ + int oc; /* Opcode */ + VdbeCursor *pC; /* The cursor to seek */ + UnpackedRecord r; /* The key to seek for */ + int nField; /* Number of columns or fields in the key */ + i64 iKey; /* The rowid we are to seek to */ + int eqOnly; /* Only interested in == results */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p2!=0 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( OP_SeekLE == OP_SeekLT+1 ); + assert( OP_SeekGE == OP_SeekLT+2 ); + assert( OP_SeekGT == OP_SeekLT+3 ); + assert( pC->isOrdered ); + assert( pC->uc.pCursor!=0 ); + oc = pOp->opcode; + eqOnly = 0; + pC->nullRow = 0; +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( pC->isTable ){ + u16 flags3, newType; + /* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */ + assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 + || CORRUPT_DB ); + + /* The input value in P3 might be of any type: integer, real, string, + ** blob, or NULL. But it needs to be an integer before we can do + ** the seek, so convert it. */ + pIn3 = &aMem[pOp->p3]; + flags3 = pIn3->flags; + if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3, 0); + } + iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */ + newType = pIn3->flags; /* Record the type after applying numeric affinity */ + pIn3->flags = flags3; /* But convert the type back to its original */ + + /* If the P3 value could not be converted into an integer without + ** loss of information, then special processing is required... */ + if( (newType & (MEM_Int|MEM_IntReal))==0 ){ + int c; + if( (newType & MEM_Real)==0 ){ + if( (newType & MEM_Null) || oc>=OP_SeekGE ){ + VdbeBranchTaken(1,2); + goto jump_to_p2; + }else{ + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + goto seek_not_found; + } + } + c = sqlite3IntFloatCompare(iKey, pIn3->u.r); + + /* If the approximation iKey is larger than the actual real search + ** term, substitute >= for > and < for <=. e.g. if the search term + ** is 4.9 and the integer approximation 5: + ** + ** (x > 4.9) -> (x >= 5) + ** (x <= 4.9) -> (x < 5) + */ + if( c>0 ){ + assert( OP_SeekGE==(OP_SeekGT-1) ); + assert( OP_SeekLT==(OP_SeekLE-1) ); + assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--; + } + + /* If the approximation iKey is smaller than the actual real search + ** term, substitute <= for < and > for >=. */ + else if( c<0 ){ + assert( OP_SeekLE==(OP_SeekLT+1) ); + assert( OP_SeekGT==(OP_SeekGE+1) ); + assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; + } + } + rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)iKey, 0, &res); + pC->movetoTarget = iKey; /* Used by OP_Delete */ + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + }else{ + /* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the + ** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be + ** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively, + ** with the same key. + */ + if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){ + eqOnly = 1; + assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); + assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); + assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT ); + assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT ); + assert( pOp[1].p1==pOp[0].p1 ); + assert( pOp[1].p2==pOp[0].p2 ); + assert( pOp[1].p3==pOp[0].p3 ); + assert( pOp[1].p4.i==pOp[0].p4.i ); + } + + nField = pOp->p4.i; + assert( pOp->p4type==P4_INT32 ); + assert( nField>0 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)nField; + + /* The next line of code computes as follows, only faster: + ** if( oc==OP_SeekGT || oc==OP_SeekLE ){ + ** r.default_rc = -1; + ** }else{ + ** r.default_rc = +1; + ** } + */ + r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1); + assert( oc!=OP_SeekGT || r.default_rc==-1 ); + assert( oc!=OP_SeekLE || r.default_rc==-1 ); + assert( oc!=OP_SeekGE || r.default_rc==+1 ); + assert( oc!=OP_SeekLT || r.default_rc==+1 ); + + r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; i0 ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]); + } + } +#endif + r.eqSeen = 0; + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( eqOnly && r.eqSeen==0 ){ + assert( res!=0 ); + goto seek_not_found; + } + } +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); + if( res<0 || (res==0 && oc==OP_SeekGT) ){ + res = 0; + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + res = 1; + }else{ + goto abort_due_to_error; + } + } + }else{ + res = 0; + } + }else{ + assert( oc==OP_SeekLT || oc==OP_SeekLE ); + if( res>0 || (res==0 && oc==OP_SeekLT) ){ + res = 0; + rc = sqlite3BtreePrevious(pC->uc.pCursor, 0); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + res = 1; + }else{ + goto abort_due_to_error; + } + } + }else{ + /* res might be negative because the table is empty. Check to + ** see if this is the case. + */ + res = sqlite3BtreeEof(pC->uc.pCursor); + } + } +seek_not_found: + assert( pOp->p2>0 ); + VdbeBranchTaken(res!=0,2); + if( res ){ + goto jump_to_p2; + }else if( eqOnly ){ + assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); + pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */ + } + break; +} + + +/* Opcode: SeekScan P1 P2 * * P5 +** Synopsis: Scan-ahead up to P1 rows +** +** This opcode is a prefix opcode to OP_SeekGE. In other words, this +** opcode must be immediately followed by OP_SeekGE. This constraint is +** checked by assert() statements. +** +** This opcode uses the P1 through P4 operands of the subsequent +** OP_SeekGE. In the text that follows, the operands of the subsequent +** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only +** the P1, P2 and P5 operands of this opcode are also used, and are called +** This.P1, This.P2 and This.P5. +** +** This opcode helps to optimize IN operators on a multi-column index +** where the IN operator is on the later terms of the index by avoiding +** unnecessary seeks on the btree, substituting steps to the next row +** of the b-tree instead. A correct answer is obtained if this opcode +** is omitted or is a no-op. +** +** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which +** is the desired entry that we want the cursor SeekGE.P1 to be pointing +** to. Call this SeekGE.P3/P4 row the "target". +** +** If the SeekGE.P1 cursor is not currently pointing to a valid row, +** then this opcode is a no-op and control passes through into the OP_SeekGE. +** +** If the SeekGE.P1 cursor is pointing to a valid row, then that row +** might be the target row, or it might be near and slightly before the +** target row, or it might be after the target row. If the cursor is +** currently before the target row, then this opcode attempts to position +** the cursor on or after the target row by invoking sqlite3BtreeStep() +** on the cursor between 1 and This.P1 times. +** +** The This.P5 parameter is a flag that indicates what to do if the +** cursor ends up pointing at a valid row that is past the target +** row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If +** This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 +** case occurs when there are no inequality constraints to the right of +** the IN constraint. The jump to SeekGE.P2 ends the loop. The P5!=0 case +** occurs when there are inequality constraints to the right of the IN +** operator. In that case, the This.P2 will point either directly to or +** to setup code prior to the OP_IdxGT or OP_IdxGE opcode that checks for +** loop terminate. +** +** Possible outcomes from this opcode:
    +** +**
  1. If the cursor is initially not pointed to any valid row, then +** fall through into the subsequent OP_SeekGE opcode. +** +**
  2. If the cursor is left pointing to a row that is before the target +** row, even after making as many as This.P1 calls to +** sqlite3BtreeNext(), then also fall through into OP_SeekGE. +** +**
  3. If the cursor is left pointing at the target row, either because it +** was at the target row to begin with or because one or more +** sqlite3BtreeNext() calls moved the cursor to the target row, +** then jump to This.P2.., +** +**
  4. If the cursor started out before the target row and a call to +** to sqlite3BtreeNext() moved the cursor off the end of the index +** (indicating that the target row definitely does not exist in the +** btree) then jump to SeekGE.P2, ending the loop. +** +**
  5. If the cursor ends up on a valid row that is past the target row +** (indicating that the target row does not exist in the btree) then +** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. +**
+*/ +case OP_SeekScan: { /* ncycle */ + VdbeCursor *pC; + int res; + int nStep; + UnpackedRecord r; + + assert( pOp[1].opcode==OP_SeekGE ); + + /* If pOp->p5 is clear, then pOp->p2 points to the first instruction past the + ** OP_IdxGT that follows the OP_SeekGE. Otherwise, it points to the first + ** opcode past the OP_SeekGE itself. */ + assert( pOp->p2>=(int)(pOp-aOp)+2 ); +#ifdef SQLITE_DEBUG + if( pOp->p5==0 ){ + /* There are no inequality constraints following the IN constraint. */ + assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); + assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); + assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); + assert( aOp[pOp->p2-1].opcode==OP_IdxGT + || aOp[pOp->p2-1].opcode==OP_IdxGE ); + testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); + }else{ + /* There are inequality constraints. */ + assert( pOp->p2==(int)(pOp-aOp)+2 ); + assert( aOp[pOp->p2-1].opcode==OP_SeekGE ); + } +#endif + + assert( pOp->p1>0 ); + pC = p->apCsr[pOp[1].p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( !pC->isTable ); + if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... cursor not valid - fall through\n"); + } +#endif + break; + } + nStep = pOp->p1; + assert( nStep>=1 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp[1].p4.i; + r.default_rc = 0; + r.aMem = &aMem[pOp[1].p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; i0 && pOp->p5==0 ){ + seekscan_search_fail: + /* Jump to SeekGE.P2, ending the loop */ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then skip\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(1,3); + pOp++; + goto jump_to_p2; + } + if( res>=0 ){ + /* Jump to This.P2, bypassing the OP_SeekGE opcode */ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then success\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(2,3); + goto jump_to_p2; + break; + } + if( nStep<=0 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... fall through after %d steps\n", pOp->p1); + } +#endif + VdbeBranchTaken(0,3); + break; + } + nStep--; + pC->cacheStatus = CACHE_STALE; + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); + if( rc ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + goto seekscan_search_fail; + }else{ + goto abort_due_to_error; + } + } + } + + break; +} + + +/* Opcode: SeekHit P1 P2 P3 * * +** Synopsis: set P2<=seekHit<=P3 +** +** Increase or decrease the seekHit value for cursor P1, if necessary, +** so that it is no less than P2 and no greater than P3. +** +** The seekHit integer represents the maximum of terms in an index for which +** there is known to be at least one match. If the seekHit value is smaller +** than the total number of equality terms in an index lookup, then the +** OP_IfNoHope opcode might run to see if the IN loop can be abandoned +** early, thus saving work. This is part of the IN-early-out optimization. +** +** P1 must be a valid b-tree cursor. +*/ +case OP_SeekHit: { /* ncycle */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p3>=pOp->p2 ); + if( pC->seekHitp2 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p2); + } +#endif + pC->seekHit = pOp->p2; + }else if( pC->seekHit>pOp->p3 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p3); + } +#endif + pC->seekHit = pOp->p3; + } + break; +} + +/* Opcode: IfNotOpen P1 P2 * * * +** Synopsis: if( !csr[P1] ) goto P2 +** +** If cursor P1 is not open or if P1 is set to a NULL row using the +** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through. +*/ +case OP_IfNotOpen: { /* jump */ + VdbeCursor *pCur; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pCur = p->apCsr[pOp->p1]; + VdbeBranchTaken(pCur==0 || pCur->nullRow, 2); + if( pCur==0 || pCur->nullRow ){ + goto jump_to_p2_and_check_for_interrupt; + } + break; +} + +/* Opcode: Found P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** is a prefix of any entry in P1 then a jump is made to P2 and +** P1 is left pointing at the matching entry. +** +** This operation leaves the cursor in a state where it can be +** advanced in the forward direction. The Next instruction will work, +** but not the Prev instruction. +** +** See also: NotFound, NoConflict, NotExists. SeekGe +*/ +/* Opcode: NotFound P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** is not the prefix of any entry in P1 then a jump is made to P2. If P1 +** does contain an entry whose prefix matches the P3/P4 record then control +** falls through to the next instruction and P1 is left pointing at the +** matching entry. +** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** +** See also: Found, NotExists, NoConflict, IfNoHope +*/ +/* Opcode: IfNoHope P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** Register P3 is the first of P4 registers that form an unpacked +** record. Cursor P1 is an index btree. P2 is a jump destination. +** In other words, the operands to this opcode are the same as the +** operands to OP_NotFound and OP_IdxGT. +** +** This opcode is an optimization attempt only. If this opcode always +** falls through, the correct answer is still obtained, but extra work +** is performed. +** +** A value of N in the seekHit flag of cursor P1 means that there exists +** a key P3:N that will match some record in the index. We want to know +** if it is possible for a record P3:P4 to match some record in the +** index. If it is not possible, we can skip some work. So if seekHit +** is less than P4, attempt to find out if a match is possible by running +** OP_NotFound. +** +** This opcode is used in IN clause processing for a multi-column key. +** If an IN clause is attached to an element of the key other than the +** left-most element, and if there are no matches on the most recent +** seek over the whole key, then it might be that one of the key element +** to the left is prohibiting a match, and hence there is "no hope" of +** any match regardless of how many IN clause elements are checked. +** In such a case, we abandon the IN clause search early, using this +** opcode. The opcode name comes from the fact that the +** jump is taken if there is "no hope" of achieving a match. +** +** See also: NotFound, SeekHit +*/ +/* Opcode: NoConflict P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** contains any NULL value, jump immediately to P2. If all terms of the +** record are not-NULL then a check is done to determine if any row in the +** P1 index btree has a matching key prefix. If there are no matches, jump +** immediately to P2. If there is a match, fall through and leave the P1 +** cursor pointing to the matching row. +** +** This opcode is similar to OP_NotFound with the exceptions that the +** branch is always taken if any part of the search key input is NULL. +** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** +** See also: NotFound, Found, NotExists +*/ +case OP_IfNoHope: { /* jump, in3, ncycle */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit is %d\n", pC->seekHit); + } +#endif + if( pC->seekHit>=pOp->p4.i ) break; + /* Fall through into OP_NotFound */ + /* no break */ deliberate_fall_through +} +case OP_NoConflict: /* jump, in3, ncycle */ +case OP_NotFound: /* jump, in3, ncycle */ +case OP_Found: { /* jump, in3, ncycle */ + int alreadyExists; + int ii; + VdbeCursor *pC; + UnpackedRecord *pIdxKey; + UnpackedRecord r; + +#ifdef SQLITE_TEST + if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; +#endif + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_INT32 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + r.aMem = &aMem[pOp->p3]; + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + assert( pC->isTable==0 ); + r.nField = (u16)pOp->p4.i; + if( r.nField>0 ){ + /* Key values in an array of registers */ + r.pKeyInfo = pC->pKeyInfo; + r.default_rc = 0; +#ifdef SQLITE_DEBUG + for(ii=0; iip3+ii, &r.aMem[ii]); + } +#endif + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult); + }else{ + /* Composite key generated by OP_MakeRecord */ + assert( r.aMem->flags & MEM_Blob ); + assert( pOp->opcode!=OP_NoConflict ); + rc = ExpandBlob(r.aMem); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc ) goto no_mem; + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); + if( pIdxKey==0 ) goto no_mem; + sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); + pIdxKey->default_rc = 0; + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); + sqlite3DbFreeNN(db, pIdxKey); + } + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + alreadyExists = (pC->seekResult==0); + pC->nullRow = 1-alreadyExists; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( pOp->opcode==OP_Found ){ + VdbeBranchTaken(alreadyExists!=0,2); + if( alreadyExists ) goto jump_to_p2; + }else{ + if( !alreadyExists ){ + VdbeBranchTaken(1,2); + goto jump_to_p2; + } + if( pOp->opcode==OP_NoConflict ){ + /* For the OP_NoConflict opcode, take the jump if any of the + ** input fields are NULL, since any key with a NULL will not + ** conflict */ + for(ii=0; iiopcode==OP_IfNoHope ){ + pC->seekHit = pOp->p4.i; + } + } + break; +} + +/* Opcode: SeekRowid P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 is the index of a cursor open on an SQL table btree (with integer +** keys). If register P3 does not contain an integer or if P1 does not +** contain a record with rowid P3 then jump immediately to P2. +** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain +** a record with rowid P3 then +** leave the cursor pointing at that record and fall through to the next +** instruction. +** +** The OP_NotExists opcode performs the same operation, but with OP_NotExists +** the P3 register must be guaranteed to contain an integer value. With this +** opcode, register P3 might not contain an integer. +** +** The OP_NotFound opcode performs the same operation on index btrees +** (with arbitrary multi-value keys). +** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** +** See also: Found, NotFound, NoConflict, SeekRowid +*/ +/* Opcode: NotExists P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 is the index of a cursor open on an SQL table btree (with integer +** keys). P3 is an integer rowid. If P1 does not contain a record with +** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an +** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then +** leave the cursor pointing at that record and fall through to the next +** instruction. +** +** The OP_SeekRowid opcode performs the same operation but also allows the +** P3 register to contain a non-integer value, in which case the jump is +** always taken. This opcode requires that P3 always contain an integer. +** +** The OP_NotFound opcode performs the same operation on index btrees +** (with arbitrary multi-value keys). +** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** +** See also: Found, NotFound, NoConflict, SeekRowid +*/ +case OP_SeekRowid: { /* jump, in3, ncycle */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + u64 iKey; + + pIn3 = &aMem[pOp->p3]; + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_IntReal ); + testcase( pIn3->flags & MEM_Real ); + testcase( (pIn3->flags & (MEM_Str|MEM_Int))==MEM_Str ); + if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ + /* If pIn3->u.i does not contain an integer, compute iKey as the + ** integer value of pIn3. Jump to P2 if pIn3 cannot be converted + ** into an integer without loss of information. Take care to avoid + ** changing the datatype of pIn3, however, as it is used by other + ** parts of the prepared statement. */ + Mem x = pIn3[0]; + applyAffinity(&x, SQLITE_AFF_NUMERIC, encoding); + if( (x.flags & MEM_Int)==0 ) goto jump_to_p2; + iKey = x.u.i; + goto notExistsWithKey; + } + /* Fall through into OP_NotExists */ + /* no break */ deliberate_fall_through +case OP_NotExists: /* jump, in3, ncycle */ + pIn3 = &aMem[pOp->p3]; + assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + iKey = pIn3->u.i; +notExistsWithKey: + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid; +#endif + assert( pC->isTable ); + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + assert( pCrsr!=0 ); + res = 0; + rc = sqlite3BtreeTableMoveto(pCrsr, iKey, 0, &res); + assert( rc==SQLITE_OK || res==0 ); + pC->movetoTarget = iKey; /* Used by OP_Delete */ + pC->nullRow = 0; + pC->cacheStatus = CACHE_STALE; + pC->deferredMoveto = 0; + VdbeBranchTaken(res!=0,2); + pC->seekResult = res; + if( res!=0 ){ + assert( rc==SQLITE_OK ); + if( pOp->p2==0 ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + goto jump_to_p2; + } + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: Sequence P1 P2 * * * +** Synopsis: r[P2]=cursor[P1].ctr++ +** +** Find the next available sequence number for cursor P1. +** Write the sequence number into register P2. +** The sequence number on the cursor is incremented after this +** instruction. +*/ +case OP_Sequence: { /* out2 */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( p->apCsr[pOp->p1]!=0 ); + assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB ); + pOut = out2Prerelease(p, pOp); + pOut->u.i = p->apCsr[pOp->p1]->seqCount++; + break; +} + + +/* Opcode: NewRowid P1 P2 P3 * * +** Synopsis: r[P2]=rowid +** +** Get a new integer record number (a.k.a "rowid") used as the key to a table. +** The record number is not previously used as a key in the database +** table that cursor P1 points to. The new record number is written +** written to register P2. +** +** If P3>0 then P3 is a register in the root frame of this VDBE that holds +** the largest previously generated record number. No new record numbers are +** allowed to be less than this value. When this value reaches its maximum, +** an SQLITE_FULL error is generated. The P3 register is updated with the ' +** generated record number. This P3 mechanism is used to help implement the +** AUTOINCREMENT feature. +*/ +case OP_NewRowid: { /* out2 */ + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ +#ifndef SQLITE_OMIT_AUTOINCREMENT + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + VdbeFrame *pFrame; /* Root frame of VDBE */ +#endif + + v = 0; + res = 0; + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->isTable ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + { + /* The next rowid or record number (different terms for the same + ** thing) is obtained in a two-step algorithm. + ** + ** First we attempt to find the largest existing rowid and add one + ** to that. But if the largest existing rowid is already the maximum + ** positive integer, we have to fall through to the second + ** probabilistic algorithm + ** + ** The second algorithm is to select a rowid at random and see if + ** it already exists in the table. If it does not exist, we have + ** succeeded. If the random rowid does exist, we select a new one + ** and try again, up to 100 times. + */ + assert( pC->isTable ); + +#ifdef SQLITE_32BIT_ROWID +# define MAX_ROWID 0x7fffffff +#else + /* Some compilers complain about constants of the form 0x7fffffffffffffff. + ** Others complain about 0x7ffffffffffffffffLL. The following macro seems + ** to provide the constant while making all compilers happy. + */ +# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) +#endif + + if( !pC->useRandomRowid ){ + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( res ){ + v = 1; /* IMP: R-61914-48074 */ + }else{ + assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) ); + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); + if( v>=MAX_ROWID ){ + pC->useRandomRowid = 1; + }else{ + v++; /* IMP: R-29538-34987 */ + } + } + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( pOp->p3 ){ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3>0 ); + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=pFrame->nMem ); + pMem = &pFrame->aMem[pOp->p3]; + }else{ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + pMem = &aMem[pOp->p3]; + memAboutToChange(p, pMem); + } + assert( memIsValid(pMem) ); + + REGISTER_TRACE(pOp->p3, pMem); + sqlite3VdbeMemIntegerify(pMem); + assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ + rc = SQLITE_FULL; /* IMP: R-17817-00630 */ + goto abort_due_to_error; + } + if( vu.i+1 ){ + v = pMem->u.i + 1; + } + pMem->u.i = v; + } +#endif + if( pC->useRandomRowid ){ + /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the + ** largest possible integer (9223372036854775807) then the database + ** engine starts picking positive candidate ROWIDs at random until + ** it finds one that is not previously used. */ + assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is + ** an AUTOINCREMENT table. */ + cnt = 0; + do{ + sqlite3_randomness(sizeof(v), &v); + v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ + }while( ((rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)v, + 0, &res))==SQLITE_OK) + && (res==0) + && (++cnt<100)); + if( rc ) goto abort_due_to_error; + if( res==0 ){ + rc = SQLITE_FULL; /* IMP: R-38219-53002 */ + goto abort_due_to_error; + } + assert( v>0 ); /* EV: R-40812-03570 */ + } + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + } + pOut->u.i = v; + break; +} + +/* Opcode: Insert P1 P2 P3 P4 P5 +** Synopsis: intkey=r[P3] data=r[P2] +** +** Write an entry into the table of cursor P1. A new entry is +** created if it doesn't already exist or the data for an existing +** entry is overwritten. The data is the value MEM_Blob stored in register +** number P2. The key is stored in register P3. The key must +** be a MEM_Int. +** +** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is +** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, +** then rowid is stored for subsequent return by the +** sqlite3_last_insert_rowid() function (otherwise it is unmodified). +** +** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might +** run faster by avoiding an unnecessary seek on cursor P1. However, +** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior +** seeks on the cursor or if the most recent seek used a key equal to P3. +** +** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an +** UPDATE operation. Otherwise (if the flag is clear) then this opcode +** is part of an INSERT operation. The difference is only important to +** the update hook. +** +** Parameter P4 may point to a Table structure, or may be NULL. If it is +** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked +** following a successful insert. +** +** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically +** allocated, then ownership of P2 is transferred to the pseudo-cursor +** and register P2 becomes ephemeral. If the cursor is changed, the +** value of register P2 will then change. Make sure this does not +** cause any problems.) +** +** This instruction only works on tables. The equivalent instruction +** for indices is OP_IdxInsert. +*/ +case OP_Insert: { + Mem *pData; /* MEM cell holding data for the record to be inserted */ + Mem *pKey; /* MEM cell holding key for the record */ + VdbeCursor *pC; /* Cursor to table into which insert is written */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + const char *zDb; /* database name - used by the update hook */ + Table *pTab; /* Table structure - used by update and pre-update hooks */ + BtreePayload x; /* Payload to be inserted */ + + pData = &aMem[pOp->p2]; + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( memIsValid(pData) ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->deferredMoveto==0 ); + assert( pC->uc.pCursor!=0 ); + assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); + assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); + REGISTER_TRACE(pOp->p2, pData); + sqlite3VdbeIncrWriteCounter(p, pC); + + pKey = &aMem[pOp->p3]; + assert( pKey->flags & MEM_Int ); + assert( memIsValid(pKey) ); + REGISTER_TRACE(pOp->p3, pKey); + x.nKey = pKey->u.i; + + if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ + assert( pC->iDb>=0 ); + zDb = db->aDb[pC->iDb].zDbSName; + pTab = pOp->p4.pTab; + assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); + }else{ + pTab = 0; + zDb = 0; + } + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + /* Invoke the pre-update hook, if any */ + if( pTab ){ + if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ + sqlite3VdbePreUpdateHook(p,pC,SQLITE_INSERT,zDb,pTab,x.nKey,pOp->p2,-1); + } + if( db->xUpdateCallback==0 || pTab->aCol==0 ){ + /* Prevent post-update hook from running in cases when it should not */ + pTab = 0; + } + } + if( pOp->p5 & OPFLAG_ISNOOP ) break; +#endif + + assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); + if( pOp->p5 & OPFLAG_NCHANGE ){ + p->nChange++; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; + } + assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); + x.pData = pData->z; + x.nData = pData->n; + seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); + if( pData->flags & MEM_Zero ){ + x.nZero = pData->u.nZero; + }else{ + x.nZero = 0; + } + x.pKey = 0; + assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + seekResult + ); + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + colCacheCtr++; + + /* Invoke the update-hook if required. */ + if( rc ) goto abort_due_to_error; + if( pTab ){ + assert( db->xUpdateCallback!=0 ); + assert( pTab->aCol!=0 ); + db->xUpdateCallback(db->pUpdateArg, + (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT, + zDb, pTab->zName, x.nKey); + } + break; +} + +/* Opcode: RowCell P1 P2 P3 * * +** +** P1 and P2 are both open cursors. Both must be opened on the same type +** of table - intkey or index. This opcode is used as part of copying +** the current row from P2 into P1. If the cursors are opened on intkey +** tables, register P3 contains the rowid to use with the new record in +** P1. If they are opened on index tables, P3 is not used. +** +** This opcode must be followed by either an Insert or InsertIdx opcode +** with the OPFLAG_PREFORMAT flag set to complete the insert operation. +*/ +case OP_RowCell: { + VdbeCursor *pDest; /* Cursor to write to */ + VdbeCursor *pSrc; /* Cursor to read from */ + i64 iKey; /* Rowid value to insert with */ + assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); + assert( pOp[1].opcode==OP_Insert || pOp->p3==0 ); + assert( pOp[1].opcode==OP_IdxInsert || pOp->p3>0 ); + assert( pOp[1].p5 & OPFLAG_PREFORMAT ); + pDest = p->apCsr[pOp->p1]; + pSrc = p->apCsr[pOp->p2]; + iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; + rc = sqlite3BtreeTransferRow(pDest->uc.pCursor, pSrc->uc.pCursor, iKey); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + break; +}; + +/* Opcode: Delete P1 P2 P3 P4 P5 +** +** Delete the record at which the P1 cursor is currently pointing. +** +** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then +** the cursor will be left pointing at either the next or the previous +** record in the table. If it is left pointing at the next record, then +** the next Next instruction will be a no-op. As a result, in this case +** it is ok to delete a record from within a Next loop. If +** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be +** left in an undefined state. +** +** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this +** delete is one of several associated with deleting a table row and +** all its associated index entries. Exactly one of those deletes is +** the "primary" delete. The others are all on OPFLAG_FORDELETE +** cursors or else are marked with the AUXDELETE flag. +** +** If the OPFLAG_NCHANGE (0x01) flag of P2 (NB: P2 not P5) is set, then +** the row change count is incremented (otherwise not). +** +** If the OPFLAG_ISNOOP (0x40) flag of P2 (not P5!) is set, then the +** pre-update-hook for deletes is run, but the btree is otherwise unchanged. +** This happens when the OP_Delete is to be shortly followed by an OP_Insert +** with the same key, causing the btree entry to be overwritten. +** +** P1 must not be pseudo-table. It has to be a real table with +** multiple rows. +** +** If P4 is not NULL then it points to a Table object. In this case either +** the update or pre-update hook, or both, may be invoked. The P1 cursor must +** have been positioned using OP_NotFound prior to invoking this opcode in +** this case. Specifically, if one is configured, the pre-update hook is +** invoked if P4 is not NULL. The update-hook is invoked if one is configured, +** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2. +** +** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address +** of the memory cell that contains the value that the rowid of the row will +** be set to by the update. +*/ +case OP_Delete: { + VdbeCursor *pC; + const char *zDb; + Table *pTab; + int opflags; + + opflags = pOp->p2; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + assert( pC->deferredMoveto==0 ); + sqlite3VdbeIncrWriteCounter(p, pC); + +#ifdef SQLITE_DEBUG + if( pOp->p4type==P4_TABLE + && HasRowid(pOp->p4.pTab) + && pOp->p5==0 + && sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) + ){ + /* If p5 is zero, the seek operation that positioned the cursor prior to + ** OP_Delete will have also set the pC->movetoTarget field to the rowid of + ** the row that is being deleted */ + i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor); + assert( CORRUPT_DB || pC->movetoTarget==iKey ); + } +#endif + + /* If the update-hook or pre-update-hook will be invoked, set zDb to + ** the name of the db to pass as to it. Also set local pTab to a copy + ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was + ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set + ** VdbeCursor.movetoTarget to the current rowid. */ + if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ + assert( pC->iDb>=0 ); + assert( pOp->p4.pTab!=0 ); + zDb = db->aDb[pC->iDb].zDbSName; + pTab = pOp->p4.pTab; + if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ + pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); + } + }else{ + zDb = 0; + pTab = 0; + } + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + /* Invoke the pre-update-hook if required. */ + assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab ); + if( db->xPreUpdateCallback && pTab ){ + assert( !(opflags & OPFLAG_ISUPDATE) + || HasRowid(pTab)==0 + || (aMem[pOp->p3].flags & MEM_Int) + ); + sqlite3VdbePreUpdateHook(p, pC, + (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, + zDb, pTab, pC->movetoTarget, + pOp->p3, -1 + ); + } + if( opflags & OPFLAG_ISNOOP ) break; +#endif + + /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ + assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); + assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); + assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); + +#ifdef SQLITE_DEBUG + if( p->pFrame==0 ){ + if( pC->isEphemeral==0 + && (pOp->p5 & OPFLAG_AUXDELETE)==0 + && (pC->wrFlag & OPFLAG_FORDELETE)==0 + ){ + nExtraDelete++; + } + if( pOp->p2 & OPFLAG_NCHANGE ){ + nExtraDelete--; + } + } +#endif + + rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); + pC->cacheStatus = CACHE_STALE; + colCacheCtr++; + pC->seekResult = 0; + if( rc ) goto abort_due_to_error; + + /* Invoke the update-hook if required. */ + if( opflags & OPFLAG_NCHANGE ){ + p->nChange++; + if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){ + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, + pC->movetoTarget); + assert( pC->iDb>=0 ); + } + } + + break; +} +/* Opcode: ResetCount * * * * * +** +** The value of the change counter is copied to the database handle +** change counter (returned by subsequent calls to sqlite3_changes()). +** Then the VMs internal change counter resets to 0. +** This is used by trigger programs. +*/ +case OP_ResetCount: { + sqlite3VdbeSetChanges(db, p->nChange); + p->nChange = 0; + break; +} + +/* Opcode: SorterCompare P1 P2 P3 P4 +** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 +** +** P1 is a sorter cursor. This instruction compares a prefix of the +** record blob in register P3 against a prefix of the entry that +** the sorter cursor currently points to. Only the first P4 fields +** of r[P3] and the sorter record are compared. +** +** If either P3 or the sorter contains a NULL in one of their significant +** fields (not counting the P4 fields at the end which are ignored) then +** the comparison is assumed to be equal. +** +** Fall through to next instruction if the two records compare equal to +** each other. Jump to P2 if they are different. +*/ +case OP_SorterCompare: { + VdbeCursor *pC; + int res; + int nKeyCol; + + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + assert( pOp->p4type==P4_INT32 ); + pIn3 = &aMem[pOp->p3]; + nKeyCol = pOp->p4.i; + res = 0; + rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); + VdbeBranchTaken(res!=0,2); + if( rc ) goto abort_due_to_error; + if( res ) goto jump_to_p2; + break; +}; + +/* Opcode: SorterData P1 P2 P3 * * +** Synopsis: r[P2]=data +** +** Write into register P2 the current sorter data for sorter cursor P1. +** Then clear the column header cache on cursor P3. +** +** This opcode is normally used to move a record out of the sorter and into +** a register that is the source for a pseudo-table cursor created using +** OpenPseudo. That pseudo-table cursor is the one that is identified by +** parameter P3. Clearing the P3 column cache as part of this opcode saves +** us from having to issue a separate NullRow instruction to clear that cache. +*/ +case OP_SorterData: { /* ncycle */ + VdbeCursor *pC; + + pOut = &aMem[pOp->p2]; + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + rc = sqlite3VdbeSorterRowkey(pC, pOut); + assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + if( rc ) goto abort_due_to_error; + p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; + break; +} + +/* Opcode: RowData P1 P2 P3 * * +** Synopsis: r[P2]=data +** +** Write into register P2 the complete row content for the row at +** which cursor P1 is currently pointing. +** There is no interpretation of the data. +** It is just copied onto the P2 register exactly as +** it is found in the database file. +** +** If cursor P1 is an index, then the content is the key of the row. +** If cursor P2 is a table, then the content extracted is the data. +** +** If the P1 cursor must be pointing to a valid row (not a NULL row) +** of a real table, not a pseudo-table. +** +** If P3!=0 then this opcode is allowed to make an ephemeral pointer +** into the database page. That means that the content of the output +** register will be invalidated as soon as the cursor moves - including +** moves caused by other cursors that "save" the current cursors +** position in order that they can write to the same table. If P3==0 +** then a copy of the data is made into memory. P3!=0 is faster, but +** P3==0 is safer. +** +** If P3!=0 then the content of the P2 register is unsuitable for use +** in OP_Result and any OP_Result will invalidate the P2 register content. +** The P2 register content is invalidated by opcodes like OP_Function or +** by any use of another cursor pointing to the same table. +*/ +case OP_RowData: { + VdbeCursor *pC; + BtCursor *pCrsr; + u32 n; + + pOut = out2Prerelease(p, pOp); + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( isSorter(pC)==0 ); + assert( pC->nullRow==0 ); + assert( pC->uc.pCursor!=0 ); + pCrsr = pC->uc.pCursor; + + /* The OP_RowData opcodes always follow OP_NotExists or + ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions + ** that might invalidate the cursor. + ** If this where not the case, on of the following assert()s + ** would fail. Should this ever change (because of changes in the code + ** generator) then the fix would be to insert a call to + ** sqlite3VdbeCursorMoveto(). + */ + assert( pC->deferredMoveto==0 ); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + + n = sqlite3BtreePayloadSize(pCrsr); + if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + testcase( n==0 ); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut); + if( rc ) goto abort_due_to_error; + if( !pOp->p3 ) Deephemeralize(pOut); + UPDATE_MAX_BLOBSIZE(pOut); + REGISTER_TRACE(pOp->p2, pOut); + break; +} + +/* Opcode: Rowid P1 P2 * * * +** Synopsis: r[P2]=PX rowid of P1 +** +** Store in register P2 an integer which is the key of the table entry that +** P1 is currently point to. +** +** P1 can be either an ordinary table or a virtual table. There used to +** be a separate OP_VRowid opcode for use with virtual tables, but this +** one opcode now works for both table types. +*/ +case OP_Rowid: { /* out2, ncycle */ + VdbeCursor *pC; + i64 v; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); + if( pC->nullRow ){ + pOut->flags = MEM_Null; + break; + }else if( pC->deferredMoveto ){ + v = pC->movetoTarget; +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( pC->eCurType==CURTYPE_VTAB ){ + assert( pC->uc.pVCur!=0 ); + pVtab = pC->uc.pVCur->pVtab; + pModule = pVtab->pModule; + assert( pModule->xRowid ); + rc = pModule->xRowid(pC->uc.pVCur, &v); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + }else{ + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + rc = sqlite3VdbeCursorRestore(pC); + if( rc ) goto abort_due_to_error; + if( pC->nullRow ){ + pOut->flags = MEM_Null; + break; + } + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); + } + pOut->u.i = v; + break; +} + +/* Opcode: NullRow P1 * * * * +** +** Move the cursor P1 to a null row. Any OP_Column operations +** that occur while the cursor is on the null row will always +** write a NULL. +** +** If cursor P1 is not previously opened, open it now to a special +** pseudo-cursor that always returns NULL for every column. +*/ +case OP_NullRow: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC==0 ){ + /* If the cursor is not already open, create a special kind of + ** pseudo-cursor that always gives null rows. */ + pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO); + if( pC==0 ) goto no_mem; + pC->seekResult = 0; + pC->isTable = 1; + pC->noReuse = 1; + pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); + } + pC->nullRow = 1; + pC->cacheStatus = CACHE_STALE; + if( pC->eCurType==CURTYPE_BTREE ){ + assert( pC->uc.pCursor!=0 ); + sqlite3BtreeClearCursor(pC->uc.pCursor); + } +#ifdef SQLITE_DEBUG + if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; +#endif + break; +} + +/* Opcode: SeekEnd P1 * * * * +** +** Position cursor P1 at the end of the btree for the purpose of +** appending a new entry onto the btree. +** +** It is assumed that the cursor is used only for appending and so +** if the cursor is valid, then the cursor must already be pointing +** at the end of the btree and so no changes are made to +** the cursor. +*/ +/* Opcode: Last P1 P2 * * * +** +** The next use of the Rowid or Column or Prev instruction for P1 +** will refer to the last entry in the database table or index. +** If the table or index is empty and P2>0, then jump immediately to P2. +** If P2 is 0 or if the table or index is not empty, fall through +** to the following instruction. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +*/ +case OP_SeekEnd: /* ncycle */ +case OP_Last: { /* jump, ncycle */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + res = 0; + assert( pCrsr!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + if( pOp->opcode==OP_SeekEnd ){ + assert( pOp->p2==0 ); + pC->seekResult = -1; + if( sqlite3BtreeCursorIsValidNN(pCrsr) ){ + break; + } + } + rc = sqlite3BtreeLast(pCrsr, &res); + pC->nullRow = (u8)res; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( rc ) goto abort_due_to_error; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + break; +} + +/* Opcode: IfSmaller P1 P2 P3 * * +** +** Estimate the number of rows in the table P1. Jump to P2 if that +** estimate is less than approximately 2**(0.1*P3). +*/ +case OP_IfSmaller: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + i64 sz; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + rc = sqlite3BtreeFirst(pCrsr, &res); + if( rc ) goto abort_due_to_error; + if( res==0 ){ + sz = sqlite3BtreeRowCountEst(pCrsr); + if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)p3 ) res = 1; + } + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} + + +/* Opcode: SorterSort P1 P2 * * * +** +** After all records have been inserted into the Sorter object +** identified by P1, invoke this opcode to actually do the sorting. +** Jump to P2 if there are no records to be sorted. +** +** This opcode is an alias for OP_Sort and OP_Rewind that is used +** for Sorter objects. +*/ +/* Opcode: Sort P1 P2 * * * +** +** This opcode does exactly the same thing as OP_Rewind except that +** it increments an undocumented global variable used for testing. +** +** Sorting is accomplished by writing records into a sorting index, +** then rewinding that index and playing it back from beginning to +** end. We use the OP_Sort opcode instead of OP_Rewind to do the +** rewinding so that the global variable will be incremented and +** regression tests can determine whether or not the optimizer is +** correctly optimizing out sorts. +*/ +case OP_SorterSort: /* jump ncycle */ +case OP_Sort: { /* jump ncycle */ +#ifdef SQLITE_TEST + sqlite3_sort_count++; + sqlite3_search_count--; +#endif + p->aCounter[SQLITE_STMTSTATUS_SORT]++; + /* Fall through into OP_Rewind */ + /* no break */ deliberate_fall_through +} +/* Opcode: Rewind P1 P2 * * * +** +** The next use of the Rowid or Column or Next instruction for P1 +** will refer to the first entry in the database table or index. +** If the table or index is empty, jump immediately to P2. +** If the table or index is not empty, fall through to the following +** instruction. +** +** If P2 is zero, that is an assertion that the P1 table is never +** empty and hence the jump will never be taken. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +*/ +case OP_Rewind: { /* jump, ncycle */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5==0 ); + assert( pOp->p2>=0 && pOp->p2nOp ); + + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); + res = 1; +#ifdef SQLITE_DEBUG + pC->seekOp = OP_Rewind; +#endif + if( isSorter(pC) ){ + rc = sqlite3VdbeSorterRewind(pC, &res); + }else{ + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + rc = sqlite3BtreeFirst(pCrsr, &res); + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + } + if( rc ) goto abort_due_to_error; + pC->nullRow = (u8)res; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + break; +} + +/* Opcode: Next P1 P2 P3 * P5 +** +** Advance cursor P1 so that it points to the next key/data pair in its +** table or index. If there are no more key/value pairs then fall through +** to the following instruction. But if the cursor advance was successful, +** jump immediately to P2. +** +** The Next opcode is only valid following an SeekGT, SeekGE, or +** OP_Rewind opcode used to position the cursor. Next is not allowed +** to follow SeekLT, SeekLE, or OP_Last. +** +** The P1 cursor must be for a real table, not a pseudo-table. P1 must have +** been opened prior to this opcode or the program will segfault. +** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +** +** See also: Prev +*/ +/* Opcode: Prev P1 P2 P3 * P5 +** +** Back up cursor P1 so that it points to the previous key/data pair in its +** table or index. If there is no previous key/value pairs then fall through +** to the following instruction. But if the cursor backup was successful, +** jump immediately to P2. +** +** +** The Prev opcode is only valid following an SeekLT, SeekLE, or +** OP_Last opcode used to position the cursor. Prev is not allowed +** to follow SeekGT, SeekGE, or OP_Rewind. +** +** The P1 cursor must be for a real table, not a pseudo-table. If P1 is +** not open then the behavior is undefined. +** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +*/ +/* Opcode: SorterNext P1 P2 * * P5 +** +** This opcode works just like OP_Next except that P1 must be a +** sorter object for which the OP_SorterSort opcode has been +** invoked. This opcode advances the cursor to the next sorted +** record, or jumps to P2 if there are no more sorted records. +*/ +case OP_SorterNext: { /* jump */ + VdbeCursor *pC; + + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + rc = sqlite3VdbeSorterNext(db, pC); + goto next_tail; + +case OP_Prev: /* jump, ncycle */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5==0 + || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP + || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE + || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope + || pC->seekOp==OP_NullRow); + rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); + goto next_tail; + +case OP_Next: /* jump, ncycle */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5==0 + || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP + || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid + || pC->seekOp==OP_IfNoHope); + rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3); + +next_tail: + pC->cacheStatus = CACHE_STALE; + VdbeBranchTaken(rc==SQLITE_OK,2); + if( rc==SQLITE_OK ){ + pC->nullRow = 0; + p->aCounter[pOp->p5]++; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + goto jump_to_p2_and_check_for_interrupt; + } + if( rc!=SQLITE_DONE ) goto abort_due_to_error; + rc = SQLITE_OK; + pC->nullRow = 1; + goto check_for_interrupt; +} + +/* Opcode: IdxInsert P1 P2 P3 P4 P5 +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the index P1. Data for the entry is nil. +** +** If P4 is not zero, then it is the number of values in the unpacked +** key of reg(P2). In that case, P3 is the index of the first register +** for the unpacked key. The availability of the unpacked key can sometimes +** be an optimization. +** +** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer +** that this insert is likely to be an append. +** +** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is +** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, +** then the change counter is unchanged. +** +** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might +** run faster by avoiding an unnecessary seek on cursor P1. However, +** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior +** seeks on the cursor or if the most recent seek used a key equivalent +** to P2. +** +** This instruction only works for indices. The equivalent instruction +** for tables is OP_Insert. +*/ +case OP_IdxInsert: { /* in2 */ + VdbeCursor *pC; + BtreePayload x; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + sqlite3VdbeIncrWriteCounter(p, pC); + assert( pC!=0 ); + assert( !isSorter(pC) ); + pIn2 = &aMem[pOp->p2]; + assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) ); + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->isTable==0 ); + rc = ExpandBlob(pIn2); + if( rc ) goto abort_due_to_error; + x.nKey = pIn2->n; + x.pKey = pIn2->z; + x.aMem = aMem + pOp->p3; + x.nMem = (u16)pOp->p4.i; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) + ); + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + if( rc) goto abort_due_to_error; + break; +} + +/* Opcode: SorterInsert P1 P2 * * * +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the sorter P1. Data for the entry is nil. +*/ +case OP_SorterInsert: { /* in2 */ + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + sqlite3VdbeIncrWriteCounter(p, pC); + assert( pC!=0 ); + assert( isSorter(pC) ); + pIn2 = &aMem[pOp->p2]; + assert( pIn2->flags & MEM_Blob ); + assert( pC->isTable==0 ); + rc = ExpandBlob(pIn2); + if( rc ) goto abort_due_to_error; + rc = sqlite3VdbeSorterWrite(pC, pIn2); + if( rc) goto abort_due_to_error; + break; +} + +/* Opcode: IdxDelete P1 P2 P3 * P5 +** Synopsis: key=r[P2@P3] +** +** The content of P3 registers starting at register P2 form +** an unpacked index key. This opcode removes that entry from the +** index opened by cursor P1. +** +** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error +** if no matching index entry is found. This happens when running +** an UPDATE or DELETE statement and the index entry to be updated +** or deleted is not found. For some uses of IdxDelete +** (example: the EXCEPT operator) it does not matter that no matching +** entry is found. For those cases, P5 is zero. Also, do not raise +** this (self-correcting and non-critical) error if in writable_schema mode. +*/ +case OP_IdxDelete: { + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + UnpackedRecord r; + + assert( pOp->p3>0 ); + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3VdbeIncrWriteCounter(p, pC); + pCrsr = pC->uc.pCursor; + assert( pCrsr!=0 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p3; + r.default_rc = 0; + r.aMem = &aMem[pOp->p2]; + rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res); + if( rc ) goto abort_due_to_error; + if( res==0 ){ + rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); + if( rc ) goto abort_due_to_error; + }else if( pOp->p5 && !sqlite3WritableSchema(db) ){ + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); + goto abort_due_to_error; + } + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; + break; +} + +/* Opcode: DeferredSeek P1 * P3 P4 * +** Synopsis: Move P3 to P1.rowid if needed +** +** P1 is an open index cursor and P3 is a cursor on the corresponding +** table. This opcode does a deferred seek of the P3 table cursor +** to the row that corresponds to the current row of P1. +** +** This is a deferred seek. Nothing actually happens until +** the cursor is used to read a record. That way, if no reads +** occur, no unnecessary I/O happens. +** +** P4 may be an array of integers (type P4_INTARRAY) containing +** one entry for each column in the P3 table. If array entry a(i) +** is non-zero, then reading column a(i)-1 from cursor P3 is +** equivalent to performing the deferred seek and then reading column i +** from P1. This information is stored in P3 and used to redirect +** reads against P3 over to P1, thus possibly avoiding the need to +** seek and read cursor P3. +*/ +/* Opcode: IdxRowid P1 P2 * * * +** Synopsis: r[P2]=rowid +** +** Write into register P2 an integer which is the last entry in the record at +** the end of the index key pointed to by cursor P1. This integer should be +** the rowid of the table entry to which this index entry points. +** +** See also: Rowid, MakeRecord. +*/ +case OP_DeferredSeek: /* ncycle */ +case OP_IdxRowid: { /* out2, ncycle */ + VdbeCursor *pC; /* The P1 index cursor */ + VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */ + i64 rowid; /* Rowid that P1 current points to */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) ); + assert( pC->uc.pCursor!=0 ); + assert( pC->isTable==0 || IsNullCursor(pC) ); + assert( pC->deferredMoveto==0 ); + assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); + + /* The IdxRowid and Seek opcodes are combined because of the commonality + ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ + rc = sqlite3VdbeCursorRestore(pC); + + /* sqlite3VdbeCursorRestore() may fail if the cursor has been disturbed + ** since it was last positioned and an error (e.g. OOM or an IO error) + ** occurs while trying to reposition it. */ + if( rc!=SQLITE_OK ) goto abort_due_to_error; + + if( !pC->nullRow ){ + rowid = 0; /* Not needed. Only used to silence a warning. */ + rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( pOp->opcode==OP_DeferredSeek ){ + assert( pOp->p3>=0 && pOp->p3nCursor ); + pTabCur = p->apCsr[pOp->p3]; + assert( pTabCur!=0 ); + assert( pTabCur->eCurType==CURTYPE_BTREE ); + assert( pTabCur->uc.pCursor!=0 ); + assert( pTabCur->isTable ); + pTabCur->nullRow = 0; + pTabCur->movetoTarget = rowid; + pTabCur->deferredMoveto = 1; + pTabCur->cacheStatus = CACHE_STALE; + assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); + assert( !pTabCur->isEphemeral ); + pTabCur->ub.aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); + pTabCur->pAltCursor = pC; + }else{ + pOut = out2Prerelease(p, pOp); + pOut->u.i = rowid; + } + }else{ + assert( pOp->opcode==OP_IdxRowid ); + sqlite3VdbeMemSetNull(&aMem[pOp->p2]); + } + break; +} + +/* Opcode: FinishSeek P1 * * * * +** +** If cursor P1 was previously moved via OP_DeferredSeek, complete that +** seek operation now, without further delay. If the cursor seek has +** already occurred, this instruction is a no-op. +*/ +case OP_FinishSeek: { /* ncycle */ + VdbeCursor *pC; /* The P1 index cursor */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + break; +} + +/* Opcode: IdxGE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than or equal to the key value +** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxGT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than the key value +** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxLT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than the key value then jump to P2. +** Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxLE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than or equal to the key value then jump +** to P2. Otherwise fall through to the next instruction. +*/ +case OP_IdxLE: /* jump, ncycle */ +case OP_IdxGT: /* jump, ncycle */ +case OP_IdxLT: /* jump, ncycle */ +case OP_IdxGE: { /* jump, ncycle */ + VdbeCursor *pC; + int res; + UnpackedRecord r; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->isOrdered ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0); + assert( pC->deferredMoveto==0 ); + assert( pOp->p4type==P4_INT32 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p4.i; + if( pOp->opcodeopcode==OP_IdxLE || pOp->opcode==OP_IdxGT ); + r.default_rc = -1; + }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT ); + r.default_rc = 0; + } + r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; ip3+i, &aMem[pOp->p3+i]); + } + } +#endif + + /* Inlined version of sqlite3VdbeIdxKeyCompare() */ + { + i64 nCellKey = 0; + BtCursor *pCur; + Mem m; + + assert( pC->eCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ) goto abort_due_to_error; + res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); + sqlite3VdbeMemReleaseMalloc(&m); + } + /* End of inlined sqlite3VdbeIdxKeyCompare() */ + + assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); + if( (pOp->opcode&1)==(OP_IdxLT&1) ){ + assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); + res = -res; + }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); + res++; + } + VdbeBranchTaken(res>0,2); + assert( rc==SQLITE_OK ); + if( res>0 ) goto jump_to_p2; + break; +} + +/* Opcode: Destroy P1 P2 P3 * * +** +** Delete an entire database table or index whose root page in the database +** file is given by P1. +** +** The table being destroyed is in the main database file if P3==0. If +** P3==1 then the table to be destroyed is in the auxiliary database file +** that is used to store tables create using CREATE TEMPORARY TABLE. +** +** If AUTOVACUUM is enabled then it is possible that another root page +** might be moved into the newly deleted root page in order to keep all +** root pages contiguous at the beginning of the database. The former +** value of the root page that moved - its value before the move occurred - +** is stored in register P2. If no page movement was required (because the +** table being dropped was already the last one in the database) then a +** zero is stored in register P2. If AUTOVACUUM is disabled then a zero +** is stored in register P2. +** +** This opcode throws an error if there are any active reader VMs when +** it is invoked. This is done to avoid the difficulty associated with +** updating existing cursors when a root page is moved in an AUTOVACUUM +** database. This error is thrown even if the database is not an AUTOVACUUM +** db in order to avoid introducing an incompatibility between autovacuum +** and non-autovacuum modes. +** +** See also: Clear +*/ +case OP_Destroy: { /* out2 */ + int iMoved; + int iDb; + + sqlite3VdbeIncrWriteCounter(p, 0); + assert( p->readOnly==0 ); + assert( pOp->p1>1 ); + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + if( db->nVdbeRead > db->nVDestroy+1 ){ + rc = SQLITE_LOCKED; + p->errorAction = OE_Abort; + goto abort_due_to_error; + }else{ + iDb = pOp->p3; + assert( DbMaskTest(p->btreeMask, iDb) ); + iMoved = 0; /* Not needed. Only to silence a warning. */ + rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); + pOut->flags = MEM_Int; + pOut->u.i = iMoved; + if( rc ) goto abort_due_to_error; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( iMoved!=0 ){ + sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); + /* All OP_Destroy operations occur on the same btree */ + assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 ); + resetSchemaOnFault = iDb+1; + } +#endif + } + break; +} + +/* Opcode: Clear P1 P2 P3 +** +** Delete all contents of the database table or index whose root page +** in the database file is given by P1. But, unlike Destroy, do not +** remove the table or index from the database file. +** +** The table being cleared is in the main database file if P2==0. If +** P2==1 then the table to be cleared is in the auxiliary database file +** that is used to store tables create using CREATE TEMPORARY TABLE. +** +** If the P3 value is non-zero, then the row change count is incremented +** by the number of rows in the table being cleared. If P3 is greater +** than zero, then the value stored in register P3 is also incremented +** by the number of rows in the table being cleared. +** +** See also: Destroy +*/ +case OP_Clear: { + i64 nChange; + + sqlite3VdbeIncrWriteCounter(p, 0); + nChange = 0; + assert( p->readOnly==0 ); + assert( DbMaskTest(p->btreeMask, pOp->p2) ); + rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, (u32)pOp->p1, &nChange); + if( pOp->p3 ){ + p->nChange += nChange; + if( pOp->p3>0 ){ + assert( memIsValid(&aMem[pOp->p3]) ); + memAboutToChange(p, &aMem[pOp->p3]); + aMem[pOp->p3].u.i += nChange; + } + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: ResetSorter P1 * * * * +** +** Delete all contents from the ephemeral table or sorter +** that is open on cursor P1. +** +** This opcode only works for cursors used for sorting and +** opened with OP_OpenEphemeral or OP_SorterOpen. +*/ +case OP_ResetSorter: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( isSorter(pC) ){ + sqlite3VdbeSorterReset(db, pC->uc.pSorter); + }else{ + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->isEphemeral ); + rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor); + if( rc ) goto abort_due_to_error; + } + break; +} + +/* Opcode: CreateBtree P1 P2 P3 * * +** Synopsis: r[P2]=root iDb=P1 flags=P3 +** +** Allocate a new b-tree in the main database file if P1==0 or in the +** TEMP database file if P1==1 or in an attached database if +** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table +** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table. +** The root page number of the new b-tree is stored in register P2. +*/ +case OP_CreateBtree: { /* out2 */ + Pgno pgno; + Db *pDb; + + sqlite3VdbeIncrWriteCounter(p, 0); + pOut = out2Prerelease(p, pOp); + pgno = 0; + assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pDb = &db->aDb[pOp->p1]; + assert( pDb->pBt!=0 ); + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); + if( rc ) goto abort_due_to_error; + pOut->u.i = pgno; + break; +} + +/* Opcode: SqlExec * * * P4 * +** +** Run the SQL statement or statements specified in the P4 string. +** Disable Auth and Trace callbacks while those statements are running if +** P1 is true. +*/ +case OP_SqlExec: { + char *zErr; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; +#endif + u8 mTrace; + + sqlite3VdbeIncrWriteCounter(p, 0); + db->nSqlExec++; + zErr = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; +#endif + mTrace = db->mTrace; + if( pOp->p1 ){ +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + db->mTrace = 0; + } + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); + db->nSqlExec--; +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + db->mTrace = mTrace; + if( zErr || rc ){ + sqlite3VdbeError(p, "%s", zErr); + sqlite3_free(zErr); + if( rc==SQLITE_NOMEM ) goto no_mem; + goto abort_due_to_error; + } + break; +} + +/* Opcode: ParseSchema P1 * * P4 * +** +** Read and parse all entries from the schema table of database P1 +** that match the WHERE clause P4. If P4 is a NULL pointer, then the +** entire schema for P1 is reparsed. +** +** This opcode invokes the parser to create a new virtual machine, +** then runs the new virtual machine. It is thus a re-entrant opcode. +*/ +case OP_ParseSchema: { + int iDb; + const char *zSchema; + char *zSql; + InitData initData; + + /* Any prepared statement that invokes this opcode will hold mutexes + ** on every btree. This is a prerequisite for invoking + ** sqlite3InitCallback(). + */ +#ifdef SQLITE_DEBUG + for(iDb=0; iDbnDb; iDb++){ + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + } +#endif + + iDb = pOp->p1; + assert( iDb>=0 && iDbnDb ); + assert( DbHasProperty(db, iDb, DB_SchemaLoaded) + || db->mallocFailed + || (CORRUPT_DB && (db->flags & SQLITE_NoSchemaError)!=0) ); + +#ifndef SQLITE_OMIT_ALTERTABLE + if( pOp->p4.z==0 ){ + sqlite3SchemaClear(db->aDb[iDb].pSchema); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); + db->mDbFlags |= DBFLAG_SchemaChange; + p->expired = 0; + }else +#endif + { + zSchema = LEGACY_SCHEMA_TABLE; + initData.db = db; + initData.iDb = iDb; + initData.pzErrMsg = &p->zErrMsg; + initData.mInitFlags = 0; + initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt); + zSql = sqlite3MPrintf(db, + "SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid", + db->aDb[iDb].zDbSName, zSchema, pOp->p4.z); + if( zSql==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + assert( db->init.busy==0 ); + db->init.busy = 1; + initData.rc = SQLITE_OK; + initData.nInitRow = 0; + assert( !db->mallocFailed ); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + if( rc==SQLITE_OK ) rc = initData.rc; + if( rc==SQLITE_OK && initData.nInitRow==0 ){ + /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse + ** at least one SQL statement. Any less than that indicates that + ** the sqlite_schema table is corrupt. */ + rc = SQLITE_CORRUPT_BKPT; + } + sqlite3DbFreeNN(db, zSql); + db->init.busy = 0; + } + } + if( rc ){ + sqlite3ResetAllSchemasOfConnection(db); + if( rc==SQLITE_NOMEM ){ + goto no_mem; + } + goto abort_due_to_error; + } + break; +} + +#if !defined(SQLITE_OMIT_ANALYZE) +/* Opcode: LoadAnalysis P1 * * * * +** +** Read the sqlite_stat1 table for database P1 and load the content +** of that table into the internal index hash table. This will cause +** the analysis to be used when preparing all subsequent queries. +*/ +case OP_LoadAnalysis: { + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = sqlite3AnalysisLoad(db, pOp->p1); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* !defined(SQLITE_OMIT_ANALYZE) */ + +/* Opcode: DropTable P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the table named P4 in database P1. This is called after a table +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropTable: { + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); + break; +} + +/* Opcode: DropIndex P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the index named P4 in database P1. This is called after an index +** is dropped from disk (using the Destroy opcode) +** in order to keep the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropIndex: { + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); + break; +} + +/* Opcode: DropTrigger P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the trigger named P4 in database P1. This is called after a trigger +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropTrigger: { + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); + break; +} + + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* Opcode: IntegrityCk P1 P2 P3 P4 P5 +** +** Do an analysis of the currently open database. Store in +** register P1 the text of an error message describing any problems. +** If no problems are found, store a NULL in register P1. +** +** The register P3 contains one less than the maximum number of allowed errors. +** At most reg(P3) errors will be reported. +** In other words, the analysis stops as soon as reg(P1) errors are +** seen. Reg(P1) is updated with the number of errors remaining. +** +** The root page numbers of all tables in the database are integers +** stored in P4_INTARRAY argument. +** +** If P5 is not zero, the check is done on the auxiliary database +** file, not the main database file. +** +** This opcode is used to implement the integrity_check pragma. +*/ +case OP_IntegrityCk: { + int nRoot; /* Number of tables to check. (Number of root pages.) */ + Pgno *aRoot; /* Array of rootpage numbers for tables to be checked */ + int nErr; /* Number of errors reported */ + char *z; /* Text of the error report */ + Mem *pnErr; /* Register keeping track of errors remaining */ + + assert( p->bIsReader ); + nRoot = pOp->p2; + aRoot = pOp->p4.ai; + assert( nRoot>0 ); + assert( aRoot[0]==(Pgno)nRoot ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + pnErr = &aMem[pOp->p3]; + assert( (pnErr->flags & MEM_Int)!=0 ); + assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); + pIn1 = &aMem[pOp->p1]; + assert( pOp->p5nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p5) ); + rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, + (int)pnErr->u.i+1, &nErr, &z); + sqlite3VdbeMemSetNull(pIn1); + if( nErr==0 ){ + assert( z==0 ); + }else if( rc ){ + sqlite3_free(z); + goto abort_due_to_error; + }else{ + pnErr->u.i -= nErr-1; + sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); + } + UPDATE_MAX_BLOBSIZE(pIn1); + sqlite3VdbeChangeEncoding(pIn1, encoding); + goto check_for_interrupt; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* Opcode: RowSetAdd P1 P2 * * * +** Synopsis: rowset(P1)=r[P2] +** +** Insert the integer value held by register P2 into a RowSet object +** held in register P1. +** +** An assertion fails if P2 is not an integer. +*/ +case OP_RowSetAdd: { /* in1, in2 */ + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + assert( (pIn2->flags & MEM_Int)!=0 ); + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; + } + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); + break; +} + +/* Opcode: RowSetRead P1 P2 P3 * * +** Synopsis: r[P3]=rowset(P1) +** +** Extract the smallest value from the RowSet object in P1 +** and put that value into register P3. +** Or, if RowSet object P1 is initially empty, leave P3 +** unchanged and jump to instruction P2. +*/ +case OP_RowSetRead: { /* jump, in1, out3 */ + i64 val; + + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); + if( (pIn1->flags & MEM_Blob)==0 + || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 + ){ + /* The boolean index is empty */ + sqlite3VdbeMemSetNull(pIn1); + VdbeBranchTaken(1,2); + goto jump_to_p2_and_check_for_interrupt; + }else{ + /* A value was pulled from the index */ + VdbeBranchTaken(0,2); + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); + } + goto check_for_interrupt; +} + +/* Opcode: RowSetTest P1 P2 P3 P4 +** Synopsis: if r[P3] in rowset(P1) goto P2 +** +** Register P3 is assumed to hold a 64-bit integer value. If register P1 +** contains a RowSet object and that RowSet object contains +** the value held in P3, jump to register P2. Otherwise, insert the +** integer in P3 into the RowSet and continue on to the +** next opcode. +** +** The RowSet object is optimized for the case where sets of integers +** are inserted in distinct phases, which each set contains no duplicates. +** Each set is identified by a unique P4 value. The first set +** must have P4==0, the final set must have P4==-1, and for all other sets +** must have P4>0. +** +** This allows optimizations: (a) when P4==0 there is no need to test +** the RowSet object for P3, as it is guaranteed not to contain it, +** (b) when P4==-1 there is no need to insert the value, as it will +** never be tested for, and (c) when a value that is part of set X is +** inserted, there is no need to search to see if the same value was +** previously inserted as part of set X (only if it was previously +** inserted as part of some other set). +*/ +case OP_RowSetTest: { /* jump, in1, in3 */ + int iSet; + int exists; + + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + iSet = pOp->p4.i; + assert( pIn3->flags&MEM_Int ); + + /* If there is anything other than a rowset object in memory cell P1, + ** delete it now and initialize P1 with an empty rowset + */ + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; + } + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + assert( pOp->p4type==P4_INT32 ); + assert( iSet==-1 || iSet>=0 ); + if( iSet ){ + exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); + VdbeBranchTaken(exists!=0,2); + if( exists ) goto jump_to_p2; + } + if( iSet>=0 ){ + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); + } + break; +} + + +#ifndef SQLITE_OMIT_TRIGGER + +/* Opcode: Program P1 P2 P3 P4 P5 +** +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the +** memory required by the sub-vdbe at runtime. +** +** P4 is a pointer to the VM containing the trigger program. +** +** If P5 is non-zero, then recursive program invocation is enabled. +*/ +case OP_Program: { /* jump */ + int nMem; /* Number of memory registers for sub-program */ + int nByte; /* Bytes of runtime space required for sub-program */ + Mem *pRt; /* Register to allocate runtime space */ + Mem *pMem; /* Used to iterate through memory cells */ + Mem *pEnd; /* Last memory cell in new array */ + VdbeFrame *pFrame; /* New vdbe frame to execute in */ + SubProgram *pProgram; /* Sub-program to execute */ + void *t; /* Token identifying trigger */ + + pProgram = pOp->p4.pProgram; + pRt = &aMem[pOp->p3]; + assert( pProgram->nOp>0 ); + + /* If the p5 flag is clear, then recursive invocation of triggers is + ** disabled for backwards compatibility (p5 is set if this sub-program + ** is really a trigger, not a foreign key action, and the flag set + ** and cleared by the "PRAGMA recursive_triggers" command is clear). + ** + ** It is recursive invocation of triggers, at the SQL level, that is + ** disabled. In some cases a single trigger may generate more than one + ** SubProgram (if the trigger may be executed with more than one different + ** ON CONFLICT algorithm). SubProgram structures associated with a + ** single trigger all have the same value for the SubProgram.token + ** variable. */ + if( pOp->p5 ){ + t = pProgram->token; + for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent); + if( pFrame ) break; + } + + if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + rc = SQLITE_ERROR; + sqlite3VdbeError(p, "too many levels of trigger recursion"); + goto abort_due_to_error; + } + + /* Register pRt is used to store the memory required to save the state + ** of the current program, and the memory required at runtime to execute + ** the trigger program. If this trigger has been fired before, then pRt + ** is already allocated. Otherwise, it must be initialized. */ + if( (pRt->flags&MEM_Blob)==0 ){ + /* SubProgram.nMem is set to the number of memory cells used by the + ** program stored in SubProgram.aOp. As well as these, one memory + ** cell is required for each cursor used by the program. Set local + ** variable nMem (and later, VdbeFrame.nChildMem) to this value. + */ + nMem = pProgram->nMem + pProgram->nCsr; + assert( nMem>0 ); + if( pProgram->nCsr==0 ) nMem++; + nByte = ROUND8(sizeof(VdbeFrame)) + + nMem * sizeof(Mem) + + pProgram->nCsr * sizeof(VdbeCursor*) + + (pProgram->nOp + 7)/8; + pFrame = sqlite3DbMallocZero(db, nByte); + if( !pFrame ){ + goto no_mem; + } + sqlite3VdbeMemRelease(pRt); + pRt->flags = MEM_Blob|MEM_Dyn; + pRt->z = (char*)pFrame; + pRt->n = nByte; + pRt->xDel = sqlite3VdbeFrameMemDel; + + pFrame->v = p; + pFrame->nChildMem = nMem; + pFrame->nChildCsr = pProgram->nCsr; + pFrame->pc = (int)(pOp - aOp); + pFrame->aMem = p->aMem; + pFrame->nMem = p->nMem; + pFrame->apCsr = p->apCsr; + pFrame->nCursor = p->nCursor; + pFrame->aOp = p->aOp; + pFrame->nOp = p->nOp; + pFrame->token = pProgram->token; +#ifdef SQLITE_DEBUG + pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; +#endif + + pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; + for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ + pMem->flags = MEM_Undefined; + pMem->db = db; + } + }else{ + pFrame = (VdbeFrame*)pRt->z; + assert( pRt->xDel==sqlite3VdbeFrameMemDel ); + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem + || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); + assert( pProgram->nCsr==pFrame->nChildCsr ); + assert( (int)(pOp - aOp)==pFrame->pc ); + } + + p->nFrame++; + pFrame->pParent = p->pFrame; + pFrame->lastRowid = db->lastRowid; + pFrame->nChange = p->nChange; + pFrame->nDbChange = p->db->nChange; + assert( pFrame->pAuxData==0 ); + pFrame->pAuxData = p->pAuxData; + p->pAuxData = 0; + p->nChange = 0; + p->pFrame = pFrame; + p->aMem = aMem = VdbeFrameMem(pFrame); + p->nMem = pFrame->nChildMem; + p->nCursor = (u16)pFrame->nChildCsr; + p->apCsr = (VdbeCursor **)&aMem[p->nMem]; + pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr]; + memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); + p->aOp = aOp = pProgram->aOp; + p->nOp = pProgram->nOp; +#ifdef SQLITE_DEBUG + /* Verify that second and subsequent executions of the same trigger do not + ** try to reuse register values from the first use. */ + { + int i; + for(i=0; inMem; i++){ + aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */ + MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */ + } + } +#endif + pOp = &aOp[-1]; + goto check_for_interrupt; +} + +/* Opcode: Param P1 P2 * * * +** +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* +** and old.* values. +** +** The address of the cell in the parent frame is determined by adding +** the value of the P1 argument to the value of the P1 argument to the +** calling OP_Program instruction. +*/ +case OP_Param: { /* out2 */ + VdbeFrame *pFrame; + Mem *pIn; + pOut = out2Prerelease(p, pOp); + pFrame = p->pFrame; + pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; + sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); + break; +} + +#endif /* #ifndef SQLITE_OMIT_TRIGGER */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +/* Opcode: FkCounter P1 P2 * * * +** Synopsis: fkctr[P1]+=P2 +** +** Increment a "constraint counter" by P2 (P2 may be negative or positive). +** If P1 is non-zero, the database constraint counter is incremented +** (deferred foreign key constraints). Otherwise, if P1 is zero, the +** statement counter is incremented (immediate foreign key constraints). +*/ +case OP_FkCounter: { + if( db->flags & SQLITE_DeferFKs ){ + db->nDeferredImmCons += pOp->p2; + }else if( pOp->p1 ){ + db->nDeferredCons += pOp->p2; + }else{ + p->nFkConstraint += pOp->p2; + } + break; +} + +/* Opcode: FkIfZero P1 P2 * * * +** Synopsis: if fkctr[P1]==0 goto P2 +** +** This opcode tests if a foreign key constraint-counter is currently zero. +** If so, jump to instruction P2. Otherwise, fall through to the next +** instruction. +** +** If P1 is non-zero, then the jump is taken if the database constraint-counter +** is zero (the one that counts deferred constraint violations). If P1 is +** zero, the jump is taken if the statement constraint-counter is zero +** (immediate foreign key constraint violations). +*/ +case OP_FkIfZero: { /* jump */ + if( pOp->p1 ){ + VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); + if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; + }else{ + VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); + if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; + } + break; +} +#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */ + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* Opcode: MemMax P1 P2 * * * +** Synopsis: r[P1]=max(r[P1],r[P2]) +** +** P1 is a register in the root frame of this VM (the root frame is +** different from the current frame if this instruction is being executed +** within a sub-program). Set the value of register P1 to the maximum of +** its current value and the value in register P2. +** +** This instruction throws an error if the memory cell is not initially +** an integer. +*/ +case OP_MemMax: { /* in2 */ + VdbeFrame *pFrame; + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + pIn1 = &pFrame->aMem[pOp->p1]; + }else{ + pIn1 = &aMem[pOp->p1]; + } + assert( memIsValid(pIn1) ); + sqlite3VdbeMemIntegerify(pIn1); + pIn2 = &aMem[pOp->p2]; + sqlite3VdbeMemIntegerify(pIn2); + if( pIn1->u.iu.i){ + pIn1->u.i = pIn2->u.i; + } + break; +} +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + +/* Opcode: IfPos P1 P2 P3 * * +** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 +** +** Register P1 must contain an integer. +** If the value of register P1 is 1 or greater, subtract P3 from the +** value in P1 and jump to P2. +** +** If the initial value of register P1 is less than 1, then the +** value is unchanged and control passes through to the next instruction. +*/ +case OP_IfPos: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken( pIn1->u.i>0, 2); + if( pIn1->u.i>0 ){ + pIn1->u.i -= pOp->p3; + goto jump_to_p2; + } + break; +} + +/* Opcode: OffsetLimit P1 P2 P3 * * +** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) +** +** This opcode performs a commonly used computation associated with +** LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3] +** holds the offset counter. The opcode computes the combined value +** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] +** value computed is the total number of rows that will need to be +** visited in order to complete the query. +** +** If r[P3] is zero or negative, that means there is no OFFSET +** and r[P2] is set to be the value of the LIMIT, r[P1]. +** +** if r[P1] is zero or negative, that means there is no LIMIT +** and r[P2] is set to -1. +** +** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. +*/ +case OP_OffsetLimit: { /* in1, out2, in3 */ + i64 x; + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + assert( pIn1->flags & MEM_Int ); + assert( pIn3->flags & MEM_Int ); + x = pIn1->u.i; + if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){ + /* If the LIMIT is less than or equal to zero, loop forever. This + ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then + ** also loop forever. This is undocumented. In fact, one could argue + ** that the loop should terminate. But assuming 1 billion iterations + ** per second (far exceeding the capabilities of any current hardware) + ** it would take nearly 300 years to actually reach the limit. So + ** looping forever is a reasonable approximation. */ + pOut->u.i = -1; + }else{ + pOut->u.i = x; + } + break; +} + +/* Opcode: IfNotZero P1 P2 * * * +** Synopsis: if r[P1]!=0 then r[P1]--, goto P2 +** +** Register P1 must contain an integer. If the content of register P1 is +** initially greater than zero, then decrement the value in register P1. +** If it is non-zero (negative or positive) and then also jump to P2. +** If register P1 is initially zero, leave it unchanged and fall through. +*/ +case OP_IfNotZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i<0, 2); + if( pIn1->u.i ){ + if( pIn1->u.i>0 ) pIn1->u.i--; + goto jump_to_p2; + } + break; +} + +/* Opcode: DecrJumpZero P1 P2 * * * +** Synopsis: if (--r[P1])==0 goto P2 +** +** Register P1 must hold an integer. Decrement the value in P1 +** and jump to P2 if the new value is exactly zero. +*/ +case OP_DecrJumpZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--; + VdbeBranchTaken(pIn1->u.i==0, 2); + if( pIn1->u.i==0 ) goto jump_to_p2; + break; +} + + +/* Opcode: AggStep * P2 P3 P4 P5 +** Synopsis: accum=r[P3] step(r[P2@P5]) +** +** Execute the xStep function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +/* Opcode: AggInverse * P2 P3 P4 P5 +** Synopsis: accum=r[P3] inverse(r[P2@P5]) +** +** Execute the xInverse function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +/* Opcode: AggStep1 P1 P2 P3 P4 P5 +** Synopsis: accum=r[P3] step(r[P2@P5]) +** +** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an +** aggregate. The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +** +** This opcode is initially coded as OP_AggStep0. On first evaluation, +** the FuncDef stored in P4 is converted into an sqlite3_context and +** the opcode is changed. In this way, the initialization of the +** sqlite3_context only happens once, instead of on each call to the +** step function. +*/ +case OP_AggInverse: +case OP_AggStep: { + int n; + sqlite3_context *pCtx; + + assert( pOp->p4type==P4_FUNCDEF ); + n = pOp->p5; + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); + assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); + pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + + (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); + if( pCtx==0 ) goto no_mem; + pCtx->pMem = 0; + pCtx->pOut = (Mem*)&(pCtx->argv[n]); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + pCtx->pFunc = pOp->p4.pFunc; + pCtx->iOp = (int)(pOp - aOp); + pCtx->pVdbe = p; + pCtx->skipFlag = 0; + pCtx->isError = 0; + pCtx->enc = encoding; + pCtx->argc = n; + pOp->p4type = P4_FUNCCTX; + pOp->p4.pCtx = pCtx; + + /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */ + assert( pOp->p1==(pOp->opcode==OP_AggInverse) ); + + pOp->opcode = OP_AggStep1; + /* Fall through into OP_AggStep */ + /* no break */ deliberate_fall_through +} +case OP_AggStep1: { + int i; + sqlite3_context *pCtx; + Mem *pMem; + + assert( pOp->p4type==P4_FUNCCTX ); + pCtx = pOp->p4.pCtx; + pMem = &aMem[pOp->p3]; + +#ifdef SQLITE_DEBUG + if( pOp->p1 ){ + /* This is an OP_AggInverse call. Verify that xStep has always + ** been called at least once prior to any xInverse call. */ + assert( pMem->uTemp==0x1122e0e3 ); + }else{ + /* This is an OP_AggStep call. Mark it as such. */ + pMem->uTemp = 0x1122e0e3; + } +#endif + + /* If this function is inside of a trigger, the register array in aMem[] + ** might change from one evaluation to the next. The next block of code + ** checks to see if the register array has changed, and if so it + ** reinitializes the relevant parts of the sqlite3_context object */ + if( pCtx->pMem != pMem ){ + pCtx->pMem = pMem; + for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; + } + +#ifdef SQLITE_DEBUG + for(i=0; iargc; i++){ + assert( memIsValid(pCtx->argv[i]) ); + REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); + } +#endif + + pMem->n++; + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->isError==0 ); + assert( pCtx->skipFlag==0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p1 ){ + (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv); + }else +#endif + (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ + + if( pCtx->isError ){ + if( pCtx->isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); + rc = pCtx->isError; + } + if( pCtx->skipFlag ){ + assert( pOp[-1].opcode==OP_CollSeq ); + i = pOp[-1].p1; + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); + pCtx->skipFlag = 0; + } + sqlite3VdbeMemRelease(pCtx->pOut); + pCtx->pOut->flags = MEM_Null; + pCtx->isError = 0; + if( rc ) goto abort_due_to_error; + } + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->skipFlag==0 ); + break; +} + +/* Opcode: AggFinal P1 P2 * P4 * +** Synopsis: accum=r[P1] N=P2 +** +** P1 is the memory location that is the accumulator for an aggregate +** or window function. Execute the finalizer function +** for an aggregate and store the result in P1. +** +** P2 is the number of arguments that the step function takes and +** P4 is a pointer to the FuncDef for this function. The P2 +** argument is not used by this opcode. It is only there to disambiguate +** functions that can take varying numbers of arguments. The +** P4 argument is only needed for the case where +** the step function was not previously called. +*/ +/* Opcode: AggValue * P2 P3 P4 * +** Synopsis: r[P3]=value N=P2 +** +** Invoke the xValue() function and store the result in register P3. +** +** P2 is the number of arguments that the step function takes and +** P4 is a pointer to the FuncDef for this function. The P2 +** argument is not used by this opcode. It is only there to disambiguate +** functions that can take varying numbers of arguments. The +** P4 argument is only needed for the case where +** the step function was not previously called. +*/ +case OP_AggValue: +case OP_AggFinal: { + Mem *pMem; + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( pOp->p3==0 || pOp->opcode==OP_AggValue ); + pMem = &aMem[pOp->p1]; + assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p3 ){ + memAboutToChange(p, &aMem[pOp->p3]); + rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); + pMem = &aMem[pOp->p3]; + }else +#endif + { + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); + } + + if( rc ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); + goto abort_due_to_error; + } + sqlite3VdbeChangeEncoding(pMem, encoding); + UPDATE_MAX_BLOBSIZE(pMem); + REGISTER_TRACE((int)(pMem-aMem), pMem); + break; +} + +#ifndef SQLITE_OMIT_WAL +/* Opcode: Checkpoint P1 P2 P3 * * +** +** Checkpoint database P1. This is a no-op if P1 is not currently in +** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL, +** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns +** SQLITE_BUSY or not, respectively. Write the number of pages in the +** WAL after the checkpoint into mem[P3+1] and the number of pages +** in the WAL that have been checkpointed after the checkpoint +** completes into mem[P3+2]. However on an error, mem[P3+1] and +** mem[P3+2] are initialized to -1. +*/ +case OP_Checkpoint: { + int i; /* Loop counter */ + int aRes[3]; /* Results */ + Mem *pMem; /* Write results here */ + + assert( p->readOnly==0 ); + aRes[0] = 0; + aRes[1] = aRes[2] = -1; + assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE + || pOp->p2==SQLITE_CHECKPOINT_FULL + || pOp->p2==SQLITE_CHECKPOINT_RESTART + || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE + ); + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); + if( rc ){ + if( rc!=SQLITE_BUSY ) goto abort_due_to_error; + rc = SQLITE_OK; + aRes[0] = 1; + } + for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ + sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); + } + break; +}; +#endif + +#ifndef SQLITE_OMIT_PRAGMA +/* Opcode: JournalMode P1 P2 P3 * * +** +** Change the journal mode of database P1 to P3. P3 must be one of the +** PAGER_JOURNALMODE_XXX values. If changing between the various rollback +** modes (delete, truncate, persist, off and memory), this is a simple +** operation. No IO is required. +** +** If changing into or out of WAL mode the procedure is more complicated. +** +** Write a string containing the final journal-mode to register P2. +*/ +case OP_JournalMode: { /* out2 */ + Btree *pBt; /* Btree to change journal mode of */ + Pager *pPager; /* Pager associated with pBt */ + int eNew; /* New journal mode */ + int eOld; /* The old journal mode */ +#ifndef SQLITE_OMIT_WAL + const char *zFilename; /* Name of database file for pPager */ +#endif + + pOut = out2Prerelease(p, pOp); + eNew = pOp->p3; + assert( eNew==PAGER_JOURNALMODE_DELETE + || eNew==PAGER_JOURNALMODE_TRUNCATE + || eNew==PAGER_JOURNALMODE_PERSIST + || eNew==PAGER_JOURNALMODE_OFF + || eNew==PAGER_JOURNALMODE_MEMORY + || eNew==PAGER_JOURNALMODE_WAL + || eNew==PAGER_JOURNALMODE_QUERY + ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( p->readOnly==0 ); + + pBt = db->aDb[pOp->p1].pBt; + pPager = sqlite3BtreePager(pBt); + eOld = sqlite3PagerGetJournalMode(pPager); + if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; + assert( sqlite3BtreeHoldsMutex(pBt) ); + if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; + +#ifndef SQLITE_OMIT_WAL + zFilename = sqlite3PagerFilename(pPager, 1); + + /* Do not allow a transition to journal_mode=WAL for a database + ** in temporary storage or if the VFS does not support shared memory + */ + if( eNew==PAGER_JOURNALMODE_WAL + && (sqlite3Strlen30(zFilename)==0 /* Temp file */ + || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ + ){ + eNew = eOld; + } + + if( (eNew!=eOld) + && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) + ){ + if( !db->autoCommit || db->nVdbeRead>1 ){ + rc = SQLITE_ERROR; + sqlite3VdbeError(p, + "cannot change %s wal mode from within a transaction", + (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") + ); + goto abort_due_to_error; + }else{ + + if( eOld==PAGER_JOURNALMODE_WAL ){ + /* If leaving WAL mode, close the log file. If successful, the call + ** to PagerCloseWal() checkpoints and deletes the write-ahead-log + ** file. An EXCLUSIVE lock may still be held on the database file + ** after a successful return. + */ + rc = sqlite3PagerCloseWal(pPager, db); + if( rc==SQLITE_OK ){ + sqlite3PagerSetJournalMode(pPager, eNew); + } + }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ + /* Cannot transition directly from MEMORY to WAL. Use mode OFF + ** as an intermediate */ + sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); + } + + /* Open a transaction on the database file. Regardless of the journal + ** mode, this transaction always uses a rollback journal. + */ + assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); + } + } + } +#endif /* ifndef SQLITE_OMIT_WAL */ + + if( rc ) eNew = eOld; + eNew = sqlite3PagerSetJournalMode(pPager, eNew); + + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = (char *)sqlite3JournalModename(eNew); + pOut->n = sqlite3Strlen30(pOut->z); + pOut->enc = SQLITE_UTF8; + sqlite3VdbeChangeEncoding(pOut, encoding); + if( rc ) goto abort_due_to_error; + break; +}; +#endif /* SQLITE_OMIT_PRAGMA */ + +#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) +/* Opcode: Vacuum P1 P2 * * * +** +** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more +** for an attached database. The "temp" database may not be vacuumed. +** +** If P2 is not zero, then it is a register holding a string which is +** the file into which the result of vacuum should be written. When +** P2 is zero, the vacuum overwrites the original database. +*/ +case OP_Vacuum: { + assert( p->readOnly==0 ); + rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1, + pOp->p2 ? &aMem[pOp->p2] : 0); + if( rc ) goto abort_due_to_error; + break; +} +#endif + +#if !defined(SQLITE_OMIT_AUTOVACUUM) +/* Opcode: IncrVacuum P1 P2 * * * +** +** Perform a single step of the incremental vacuum procedure on +** the P1 database. If the vacuum has finished, jump to instruction +** P2. Otherwise, fall through to the next instruction. +*/ +case OP_IncrVacuum: { /* jump */ + Btree *pBt; + + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pBt = db->aDb[pOp->p1].pBt; + rc = sqlite3BtreeIncrVacuum(pBt); + VdbeBranchTaken(rc==SQLITE_DONE,2); + if( rc ){ + if( rc!=SQLITE_DONE ) goto abort_due_to_error; + rc = SQLITE_OK; + goto jump_to_p2; + } + break; +} +#endif + +/* Opcode: Expire P1 P2 * * * +** +** Cause precompiled statements to expire. When an expired statement +** is executed using sqlite3_step() it will either automatically +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) +** or it will fail with SQLITE_SCHEMA. +** +** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, +** then only the currently executing statement is expired. +** +** If P2 is 0, then SQL statements are expired immediately. If P2 is 1, +** then running SQL statements are allowed to continue to run to completion. +** The P2==1 case occurs when a CREATE INDEX or similar schema change happens +** that might help the statement run faster but which does not affect the +** correctness of operation. +*/ +case OP_Expire: { + assert( pOp->p2==0 || pOp->p2==1 ); + if( !pOp->p1 ){ + sqlite3ExpirePreparedStatements(db, pOp->p2); + }else{ + p->expired = pOp->p2+1; + } + break; +} + +/* Opcode: CursorLock P1 * * * * +** +** Lock the btree to which cursor P1 is pointing so that the btree cannot be +** written by an other cursor. +*/ +case OP_CursorLock: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorPin(pC->uc.pCursor); + break; +} + +/* Opcode: CursorUnlock P1 * * * * +** +** Unlock the btree to which cursor P1 is pointing so that it can be +** written by other cursors. +*/ +case OP_CursorUnlock: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorUnpin(pC->uc.pCursor); + break; +} + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* Opcode: TableLock P1 P2 P3 P4 * +** Synopsis: iDb=P1 root=P2 write=P3 +** +** Obtain a lock on a particular table. This instruction is only used when +** the shared-cache feature is enabled. +** +** P1 is the index of the database in sqlite3.aDb[] of the database +** on which the lock is acquired. A readlock is obtained if P3==0 or +** a write lock if P3==1. +** +** P2 contains the root-page of the table to lock. +** +** P4 contains a pointer to the name of the table being locked. This is only +** used to generate an error message if the lock cannot be obtained. +*/ +case OP_TableLock: { + u8 isWriteLock = (u8)pOp->p3; + if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){ + int p1 = pOp->p1; + assert( p1>=0 && p1nDb ); + assert( DbMaskTest(p->btreeMask, p1) ); + assert( isWriteLock==0 || isWriteLock==1 ); + rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); + if( rc ){ + if( (rc&0xFF)==SQLITE_LOCKED ){ + const char *z = pOp->p4.z; + sqlite3VdbeError(p, "database table is locked: %s", z); + } + goto abort_due_to_error; + } + } + break; +} +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VBegin * * * P4 * +** +** P4 may be a pointer to an sqlite3_vtab structure. If so, call the +** xBegin method for that table. +** +** Also, whether or not P4 is set, check that this is not being called from +** within a callback to a virtual table xSync() method. If it is, the error +** code will be set to SQLITE_LOCKED. +*/ +case OP_VBegin: { + VTable *pVTab; + pVTab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, pVTab); + if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCreate P1 P2 * * * +** +** P2 is a register that holds the name of a virtual table in database +** P1. Call the xCreate method for that table. +*/ +case OP_VCreate: { + Mem sMem; /* For storing the record being decoded */ + const char *zTab; /* Name of the virtual table */ + + memset(&sMem, 0, sizeof(sMem)); + sMem.db = db; + /* Because P2 is always a static string, it is impossible for the + ** sqlite3VdbeMemCopy() to fail */ + assert( (aMem[pOp->p2].flags & MEM_Str)!=0 ); + assert( (aMem[pOp->p2].flags & MEM_Static)!=0 ); + rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); + assert( rc==SQLITE_OK ); + zTab = (const char*)sqlite3_value_text(&sMem); + assert( zTab || db->mallocFailed ); + if( zTab ){ + rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); + } + sqlite3VdbeMemRelease(&sMem); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VDestroy P1 * * P4 * +** +** P4 is the name of a virtual table in database P1. Call the xDestroy method +** of that table. +*/ +case OP_VDestroy: { + db->nVDestroy++; + rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); + db->nVDestroy--; + assert( p->errorAction==OE_Abort && p->usesStmtJournal ); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VOpen P1 * * P4 * +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** P1 is a cursor number. This opcode opens a cursor to the virtual +** table and stores that cursor in P1. +*/ +case OP_VOpen: { /* ncycle */ + VdbeCursor *pCur; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + + assert( p->bIsReader ); + pCur = 0; + pVCur = 0; + pVtab = pOp->p4.pVtab->pVtab; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + goto abort_due_to_error; + } + pModule = pVtab->pModule; + rc = pModule->xOpen(pVtab, &pVCur); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; + + /* Initialize sqlite3_vtab_cursor base class */ + pVCur->pVtab = pVtab; + + /* Initialize vdbe cursor object */ + pCur = allocateCursor(p, pOp->p1, 0, CURTYPE_VTAB); + if( pCur ){ + pCur->uc.pVCur = pVCur; + pVtab->nRef++; + }else{ + assert( db->mallocFailed ); + pModule->xClose(pVCur); + goto no_mem; + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCheck P1 P2 P3 P4 * +** +** P4 is a pointer to a Table object that is a virtual table in schema P1 +** that supports the xIntegrity() method. This opcode runs the xIntegrity() +** method for that virtual table, using P3 as the integer argument. If +** an error is reported back, the table name is prepended to the error +** message and that message is stored in P2. If no errors are seen, +** register P2 is set to NULL. +*/ +case OP_VCheck: { /* out2 */ + Table *pTab; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + char *zErr = 0; + + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ + assert( pOp->p4type==P4_TABLEREF ); + pTab = pOp->p4.pTab; + assert( pTab!=0 ); + assert( pTab->nTabRef>0 ); + assert( IsVirtual(pTab) ); + if( pTab->u.vtab.p==0 ) break; + pVtab = pTab->u.vtab.p->pVtab; + assert( pVtab!=0 ); + pModule = pVtab->pModule; + assert( pModule!=0 ); + assert( pModule->iVersion>=4 ); + assert( pModule->xIntegrity!=0 ); + sqlite3VtabLock(pTab->u.vtab.p); + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, + pOp->p3, &zErr); + sqlite3VtabUnlock(pTab->u.vtab.p); + if( rc ){ + sqlite3_free(zErr); + goto abort_due_to_error; + } + if( zErr ){ + sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free); + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VInitIn P1 P2 P3 * * +** Synopsis: r[P2]=ValueList(P1,P3) +** +** Set register P2 to be a pointer to a ValueList object for cursor P1 +** with cache register P3 and output register P3+1. This ValueList object +** can be used as the first argument to sqlite3_vtab_in_first() and +** sqlite3_vtab_in_next() to extract all of the values stored in the P1 +** cursor. Register P3 is used to hold the values returned by +** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). +*/ +case OP_VInitIn: { /* out2, ncycle */ + VdbeCursor *pC; /* The cursor containing the RHS values */ + ValueList *pRhs; /* New ValueList object to put in reg[P2] */ + + pC = p->apCsr[pOp->p1]; + pRhs = sqlite3_malloc64( sizeof(*pRhs) ); + if( pRhs==0 ) goto no_mem; + pRhs->pCsr = pC->uc.pCursor; + pRhs->pOut = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VFilter P1 P2 P3 P4 * +** Synopsis: iplan=r[P3] zplan='P4' +** +** P1 is a cursor opened using VOpen. P2 is an address to jump to if +** the filtered result set is empty. +** +** P4 is either NULL or a string that was generated by the xBestIndex +** method of the module. The interpretation of the P4 string is left +** to the module implementation. +** +** This opcode invokes the xFilter method on the virtual table specified +** by P1. The integer query plan parameter to xFilter is stored in register +** P3. Register P3+1 stores the argc parameter to be passed to the +** xFilter method. Registers P3+2..P3+1+argc are the argc +** additional parameters which are passed to +** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. +** +** A jump is made to P2 if the result set after filtering would be empty. +*/ +case OP_VFilter: { /* jump, ncycle */ + int nArg; + int iQuery; + const sqlite3_module *pModule; + Mem *pQuery; + Mem *pArgc; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; + VdbeCursor *pCur; + int res; + int i; + Mem **apArg; + + pQuery = &aMem[pOp->p3]; + pArgc = &pQuery[1]; + pCur = p->apCsr[pOp->p1]; + assert( memIsValid(pQuery) ); + REGISTER_TRACE(pOp->p3, pQuery); + assert( pCur!=0 ); + assert( pCur->eCurType==CURTYPE_VTAB ); + pVCur = pCur->uc.pVCur; + pVtab = pVCur->pVtab; + pModule = pVtab->pModule; + + /* Grab the index number and argc parameters */ + assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); + nArg = (int)pArgc->u.i; + iQuery = (int)pQuery->u.i; + + /* Invoke the xFilter method */ + apArg = p->apArg; + for(i = 0; ixFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; + res = pModule->xEof(pVCur); + pCur->nullRow = 0; + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VColumn P1 P2 P3 * P5 +** Synopsis: r[P3]=vcolumn(P2) +** +** Store in register P3 the value of the P2-th column of +** the current row of the virtual-table of cursor P1. +** +** If the VColumn opcode is being used to fetch the value of +** an unchanging column during an UPDATE operation, then the P5 +** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange() +** function to return true inside the xColumn method of the virtual +** table implementation. The P5 column might also contain other +** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are +** unused by OP_VColumn. +*/ +case OP_VColumn: { /* ncycle */ + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + Mem *pDest; + sqlite3_context sContext; + FuncDef nullFunc; + + VdbeCursor *pCur = p->apCsr[pOp->p1]; + assert( pCur!=0 ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + if( pCur->nullRow ){ + sqlite3VdbeMemSetNull(pDest); + break; + } + assert( pCur->eCurType==CURTYPE_VTAB ); + pVtab = pCur->uc.pVCur->pVtab; + pModule = pVtab->pModule; + assert( pModule->xColumn ); + memset(&sContext, 0, sizeof(sContext)); + sContext.pOut = pDest; + sContext.enc = encoding; + nullFunc.pUserData = 0; + nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE; + sContext.pFunc = &nullFunc; + assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); + if( pOp->p5 & OPFLAG_NOCHNG ){ + sqlite3VdbeMemSetNull(pDest); + pDest->flags = MEM_Null|MEM_Zero; + pDest->u.nZero = 0; + }else{ + MemSetTypeFlag(pDest, MEM_Null); + } + rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); + sqlite3VtabImportErrmsg(p, pVtab); + if( sContext.isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest)); + rc = sContext.isError; + } + sqlite3VdbeChangeEncoding(pDest, encoding); + REGISTER_TRACE(pOp->p3, pDest); + UPDATE_MAX_BLOBSIZE(pDest); + + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VNext P1 P2 * * * +** +** Advance virtual table P1 to the next row in its result set and +** jump to instruction P2. Or, if the virtual table has reached +** the end of its result set, then fall through to the next instruction. +*/ +case OP_VNext: { /* jump, ncycle */ + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + int res; + VdbeCursor *pCur; + + pCur = p->apCsr[pOp->p1]; + assert( pCur!=0 ); + assert( pCur->eCurType==CURTYPE_VTAB ); + if( pCur->nullRow ){ + break; + } + pVtab = pCur->uc.pVCur->pVtab; + pModule = pVtab->pModule; + assert( pModule->xNext ); + + /* Invoke the xNext() method of the module. There is no way for the + ** underlying implementation to return an error if one occurs during + ** xNext(). Instead, if an error occurs, true is returned (indicating that + ** data is available) and the error code returned when xColumn or + ** some other method is next invoked on the save virtual table cursor. + */ + rc = pModule->xNext(pCur->uc.pVCur); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; + res = pModule->xEof(pCur->uc.pVCur); + VdbeBranchTaken(!res,2); + if( !res ){ + /* If there is data, jump to P2 */ + goto jump_to_p2_and_check_for_interrupt; + } + goto check_for_interrupt; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VRename P1 * * P4 * +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xRename method. The value +** in register P1 is passed as the zName argument to the xRename method. +*/ +case OP_VRename: { + sqlite3_vtab *pVtab; + Mem *pName; + int isLegacy; + + isLegacy = (db->flags & SQLITE_LegacyAlter); + db->flags |= SQLITE_LegacyAlter; + pVtab = pOp->p4.pVtab->pVtab; + pName = &aMem[pOp->p1]; + assert( pVtab->pModule->xRename ); + assert( memIsValid(pName) ); + assert( p->readOnly==0 ); + REGISTER_TRACE(pOp->p1, pName); + assert( pName->flags & MEM_Str ); + testcase( pName->enc==SQLITE_UTF8 ); + testcase( pName->enc==SQLITE_UTF16BE ); + testcase( pName->enc==SQLITE_UTF16LE ); + rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); + if( rc ) goto abort_due_to_error; + rc = pVtab->pModule->xRename(pVtab, pName->z); + if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter; + sqlite3VtabImportErrmsg(p, pVtab); + p->expired = 0; + if( rc ) goto abort_due_to_error; + break; +} +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VUpdate P1 P2 P3 P4 P5 +** Synopsis: data=r[P3@P2] +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xUpdate method. P2 values +** are contiguous memory cells starting at P3 to pass to the xUpdate +** invocation. The value in register (P3+P2-1) corresponds to the +** p2th element of the argv array passed to xUpdate. +** +** The xUpdate method will do a DELETE or an INSERT or both. +** The argv[0] element (which corresponds to memory cell P3) +** is the rowid of a row to delete. If argv[0] is NULL then no +** deletion occurs. The argv[1] element is the rowid of the new +** row. This can be NULL to have the virtual table select the new +** rowid for itself. The subsequent elements in the array are +** the values of columns in the new row. +** +** If P2==1 then no insert is performed. argv[0] is the rowid of +** a row to delete. +** +** P1 is a boolean flag. If it is set to true and the xUpdate call +** is successful, then the value returned by sqlite3_last_insert_rowid() +** is set to the value of the rowid for the row just inserted. +** +** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to +** apply in the case of a constraint failure on an insert or update. +*/ +case OP_VUpdate: { + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + int nArg; + int i; + sqlite_int64 rowid = 0; + Mem **apArg; + Mem *pX; + + assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback + || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace + ); + assert( p->readOnly==0 ); + if( db->mallocFailed ) goto no_mem; + sqlite3VdbeIncrWriteCounter(p, 0); + pVtab = pOp->p4.pVtab->pVtab; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + goto abort_due_to_error; + } + pModule = pVtab->pModule; + nArg = pOp->p2; + assert( pOp->p4type==P4_VTAB ); + if( ALWAYS(pModule->xUpdate) ){ + u8 vtabOnConflict = db->vtabOnConflict; + apArg = p->apArg; + pX = &aMem[pOp->p3]; + for(i=0; ivtabOnConflict = pOp->p5; + rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); + db->vtabOnConflict = vtabOnConflict; + sqlite3VtabImportErrmsg(p, pVtab); + if( rc==SQLITE_OK && pOp->p1 ){ + assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); + db->lastRowid = rowid; + } + if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ + if( pOp->p5==OE_Ignore ){ + rc = SQLITE_OK; + }else{ + p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); + } + }else{ + p->nChange++; + } + if( rc ) goto abort_due_to_error; + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: Pagecount P1 P2 * * * +** +** Write the current number of pages in database P1 to memory cell P2. +*/ +case OP_Pagecount: { /* out2 */ + pOut = out2Prerelease(p, pOp); + pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); + break; +} +#endif + + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: MaxPgcnt P1 P2 P3 * * +** +** Try to set the maximum page count for database P1 to the value in P3. +** Do not let the maximum page count fall below the current page count and +** do not change the maximum page count value if P3==0. +** +** Store the maximum page count after the change in register P2. +*/ +case OP_MaxPgcnt: { /* out2 */ + unsigned int newMax; + Btree *pBt; + + pOut = out2Prerelease(p, pOp); + pBt = db->aDb[pOp->p1].pBt; + newMax = 0; + if( pOp->p3 ){ + newMax = sqlite3BtreeLastPage(pBt); + if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3; + } + pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax); + break; +} +#endif + +/* Opcode: Function P1 P2 P3 P4 * +** Synopsis: r[P3]=func(r[P2@NP]) +** +** Invoke a user function (P4 is a pointer to an sqlite3_context object that +** contains a pointer to the function to be run) with arguments taken +** from register P2 and successors. The number of arguments is in +** the sqlite3_context object that P4 points to. +** The result of the function is stored +** in register P3. Register P3 must not be one of the function inputs. +** +** P1 is a 32-bit bitmask indicating whether or not each argument to the +** function was determined to be constant at compile time. If the first +** argument was constant then bit 0 of P1 is set. This is used to determine +** whether meta data associated with a user function argument using the +** sqlite3_set_auxdata() API may be safely retained until the next +** invocation of this opcode. +** +** See also: AggStep, AggFinal, PureFunc +*/ +/* Opcode: PureFunc P1 P2 P3 P4 * +** Synopsis: r[P3]=func(r[P2@NP]) +** +** Invoke a user function (P4 is a pointer to an sqlite3_context object that +** contains a pointer to the function to be run) with arguments taken +** from register P2 and successors. The number of arguments is in +** the sqlite3_context object that P4 points to. +** The result of the function is stored +** in register P3. Register P3 must not be one of the function inputs. +** +** P1 is a 32-bit bitmask indicating whether or not each argument to the +** function was determined to be constant at compile time. If the first +** argument was constant then bit 0 of P1 is set. This is used to determine +** whether meta data associated with a user function argument using the +** sqlite3_set_auxdata() API may be safely retained until the next +** invocation of this opcode. +** +** This opcode works exactly like OP_Function. The only difference is in +** its name. This opcode is used in places where the function must be +** purely non-deterministic. Some built-in date/time functions can be +** either deterministic of non-deterministic, depending on their arguments. +** When those function are used in a non-deterministic way, they will check +** to see if they were called using OP_PureFunc instead of OP_Function, and +** if they were, they throw an error. +** +** See also: AggStep, AggFinal, Function +*/ +case OP_PureFunc: /* group */ +case OP_Function: { /* group */ + int i; + sqlite3_context *pCtx; + + assert( pOp->p4type==P4_FUNCCTX ); + pCtx = pOp->p4.pCtx; + + /* If this function is inside of a trigger, the register array in aMem[] + ** might change from one evaluation to the next. The next block of code + ** checks to see if the register array has changed, and if so it + ** reinitializes the relevant parts of the sqlite3_context object */ + pOut = &aMem[pOp->p3]; + if( pCtx->pOut != pOut ){ + pCtx->pVdbe = p; + pCtx->pOut = pOut; + pCtx->enc = encoding; + for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; + } + assert( pCtx->pVdbe==p ); + + memAboutToChange(p, pOut); +#ifdef SQLITE_DEBUG + for(i=0; iargc; i++){ + assert( memIsValid(pCtx->argv[i]) ); + REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); + } +#endif + MemSetTypeFlag(pOut, MEM_Null); + assert( pCtx->isError==0 ); + (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ + + /* If the function returned an error, throw an exception */ + if( pCtx->isError ){ + if( pCtx->isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); + rc = pCtx->isError; + } + sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); + pCtx->isError = 0; + if( rc ) goto abort_due_to_error; + } + + assert( (pOut->flags&MEM_Str)==0 + || pOut->enc==encoding + || db->mallocFailed ); + assert( !sqlite3VdbeMemTooBig(pOut) ); + + REGISTER_TRACE(pOp->p3, pOut); + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: ClrSubtype P1 * * * * +** Synopsis: r[P1].subtype = 0 +** +** Clear the subtype from register P1. +*/ +case OP_ClrSubtype: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + pIn1->flags &= ~MEM_Subtype; + break; +} + +/* Opcode: GetSubtype P1 P2 * * * +** Synopsis: r[P2] = r[P1].subtype +** +** Extract the subtype value from register P1 and write that subtype +** into register P2. If P1 has no subtype, then P1 gets a NULL. +*/ +case OP_GetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Subtype ){ + sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: SetSubtype P1 P2 * * * +** Synopsis: r[P2].subtype = r[P1] +** +** Set the subtype value of register P2 to the integer from register P1. +** If P1 is NULL, clear the subtype from p2. +*/ +case OP_SetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + pOut->flags &= ~MEM_Subtype; + }else{ + assert( pIn1->flags & MEM_Int ); + pOut->flags |= MEM_Subtype; + pOut->eSubtype = (u8)(pIn1->u.i & 0xff); + } + break; +} + +/* Opcode: FilterAdd P1 * P3 P4 * +** Synopsis: filter(P1) += key(P3@P4) +** +** Compute a hash on the P4 registers starting with r[P3] and +** add that hash to the bloom filter contained in r[P1]. +*/ +case OP_FilterAdd: { + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags & MEM_Blob ); + assert( pIn1->n>0 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= (pIn1->n*8); + pIn1->z[h/8] |= 1<<(h&7); + break; +} + +/* Opcode: Filter P1 P2 P3 P4 * +** Synopsis: if key(P3@P4) not in filter(P1) goto P2 +** +** Compute a hash on the key contained in the P4 registers starting +** with r[P3]. Check to see if that hash is found in the +** bloom filter hosted by register P1. If it is not present then +** maybe jump to P2. Otherwise fall through. +** +** False negatives are harmless. It is always safe to fall through, +** even if the value is in the bloom filter. A false negative causes +** more CPU cycles to be used, but it should still yield the correct +** answer. However, an incorrect answer may well arise from a +** false positive - if the jump is taken when it should fall through. +*/ +case OP_Filter: { /* jump */ + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Blob)!=0 ); + assert( pIn1->n >= 1 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= (pIn1->n*8); + if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ + VdbeBranchTaken(1, 2); + p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; + goto jump_to_p2; + }else{ + p->aCounter[SQLITE_STMTSTATUS_FILTER_MISS]++; + VdbeBranchTaken(0, 2); + } + break; +} + +/* Opcode: Trace P1 P2 * P4 * +** +** Write P4 on the statement trace output if statement tracing is +** enabled. +** +** Operand P1 must be 0x7fffffff and P2 must positive. +*/ +/* Opcode: Init P1 P2 P3 P4 * +** Synopsis: Start at P2 +** +** Programs contain a single instance of this opcode as the very first +** opcode. +** +** If tracing is enabled (by the sqlite3_trace()) interface, then +** the UTF-8 string contained in P4 is emitted on the trace callback. +** Or if P4 is blank, use the string returned by sqlite3_sql(). +** +** If P2 is not zero, jump to instruction P2. +** +** Increment the value of P1 so that OP_Once opcodes will jump the +** first time they are evaluated for this run. +** +** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT +** error is encountered. +*/ +case OP_Trace: +case OP_Init: { /* jump */ + int i; +#ifndef SQLITE_OMIT_TRACE + char *zTrace; +#endif + + /* If the P4 argument is not NULL, then it must be an SQL comment string. + ** The "--" string is broken up to prevent false-positives with srcck1.c. + ** + ** This assert() provides evidence for: + ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that + ** would have been returned by the legacy sqlite3_trace() interface by + ** using the X argument when X begins with "--" and invoking + ** sqlite3_expanded_sql(P) otherwise. + */ + assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); + + /* OP_Init is always instruction 0 */ + assert( pOp==p->aOp || pOp->opcode==OP_Trace ); + +#ifndef SQLITE_OMIT_TRACE + if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 + && p->minWriteFileFormat!=254 /* tag-20220401a */ + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ +#ifndef SQLITE_OMIT_DEPRECATED + if( db->mTrace & SQLITE_TRACE_LEGACY ){ + char *z = sqlite3VdbeExpandSql(p, zTrace); + db->trace.xLegacy(db->pTraceArg, z); + sqlite3_free(z); + }else +#endif + if( db->nVdbeExec>1 ){ + char *z = sqlite3MPrintf(db, "-- %s", zTrace); + (void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, z); + sqlite3DbFree(db, z); + }else{ + (void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace); + } + } +#ifdef SQLITE_USE_FCNTL_TRACE + zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); + if( zTrace ){ + int j; + for(j=0; jnDb; j++){ + if( DbMaskTest(p->btreeMask, j)==0 ) continue; + sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace); + } + } +#endif /* SQLITE_USE_FCNTL_TRACE */ +#ifdef SQLITE_DEBUG + if( (db->flags & SQLITE_SqlTrace)!=0 + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); + } +#endif /* SQLITE_DEBUG */ +#endif /* SQLITE_OMIT_TRACE */ + assert( pOp->p2>0 ); + if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ + if( pOp->opcode==OP_Trace ) break; + for(i=1; inOp; i++){ + if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; + } + pOp->p1 = 0; + } + pOp->p1++; + p->aCounter[SQLITE_STMTSTATUS_RUN]++; + goto jump_to_p2; +} + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* Opcode: CursorHint P1 * * P4 * +** +** Provide a hint to cursor P1 that it only needs to return rows that +** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer +** to values currently held in registers. TK_COLUMN terms in the P4 +** expression refer to columns in the b-tree to which cursor P1 is pointing. +*/ +case OP_CursorHint: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_EXPR ); + pC = p->apCsr[pOp->p1]; + if( pC ){ + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, + pOp->p4.pExpr, aMem); + } + break; +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + +#ifdef SQLITE_DEBUG +/* Opcode: Abortable * * * * * +** +** Verify that an Abort can happen. Assert if an Abort at this point +** might cause database corruption. This opcode only appears in debugging +** builds. +** +** An Abort is safe if either there have been no writes, or if there is +** an active statement journal. +*/ +case OP_Abortable: { + sqlite3VdbeAssertAbortable(p); + break; +} +#endif + +#ifdef SQLITE_DEBUG +/* Opcode: ReleaseReg P1 P2 P3 * P5 +** Synopsis: release r[P1@P2] mask P3 +** +** Release registers from service. Any content that was in the +** the registers is unreliable after this opcode completes. +** +** The registers released will be the P2 registers starting at P1, +** except if bit ii of P3 set, then do not release register P1+ii. +** In other words, P3 is a mask of registers to preserve. +** +** Releasing a register clears the Mem.pScopyFrom pointer. That means +** that if the content of the released register was set using OP_SCopy, +** a change to the value of the source register for the OP_SCopy will no longer +** generate an assertion fault in sqlite3VdbeMemAboutToChange(). +** +** If P5 is set, then all released registers have their type set +** to MEM_Undefined so that any subsequent attempt to read the released +** register (before it is reinitialized) will generate an assertion fault. +** +** P5 ought to be set on every call to this opcode. +** However, there are places in the code generator will release registers +** before their are used, under the (valid) assumption that the registers +** will not be reallocated for some other purpose before they are used and +** hence are safe to release. +** +** This opcode is only available in testing and debugging builds. It is +** not generated for release builds. The purpose of this opcode is to help +** validate the generated bytecode. This opcode does not actually contribute +** to computing an answer. +*/ +case OP_ReleaseReg: { + Mem *pMem; + int i; + u32 constMask; + assert( pOp->p1>0 ); + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); + pMem = &aMem[pOp->p1]; + constMask = pOp->p3; + for(i=0; ip2; i++, pMem++){ + if( i>=32 || (constMask & MASKBIT32(i))==0 ){ + pMem->pScopyFrom = 0; + if( i<32 && pOp->p5 ) MemSetTypeFlag(pMem, MEM_Undefined); + } + } + break; +} +#endif + +/* Opcode: Noop * * * * * +** +** Do nothing. This instruction is often useful as a jump +** destination. +*/ +/* +** The magic Explain opcode are only inserted when explain==2 (which +** is to say when the EXPLAIN QUERY PLAN syntax is used.) +** This opcode records information from the optimizer. It is the +** the same as a no-op. This opcodesnever appears in a real VM program. +*/ +default: { /* This is really OP_Noop, OP_Explain */ + assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); + + break; +} + +/***************************************************************************** +** The cases of the switch statement above this line should all be indented +** by 6 spaces. But the left-most 6 spaces have been removed to improve the +** readability. From this point on down, the normal indentation rules are +** restored. +*****************************************************************************/ + } + +#if defined(VDBE_PROFILE) + *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); + pnCycle = 0; +#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( pnCycle ){ + *pnCycle += sqlite3Hwtime(); + pnCycle = 0; + } +#endif + + /* The following code adds nothing to the actual functionality + ** of the program. It is only here for testing and debugging. + ** On the other hand, it does burn CPU cycles every time through + ** the evaluator loop. So we can leave it out when NDEBUG is defined. + */ +#ifndef NDEBUG + assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] ); + +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode]; + if( rc!=0 ) printf("rc=%d\n",rc); + if( opProperty & (OPFLG_OUT2) ){ + registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); + } + if( opProperty & OPFLG_OUT3 ){ + registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); + } + if( opProperty==0xff ){ + /* Never happens. This code exists to avoid a harmless linkage + ** warning about sqlite3VdbeRegisterDump() being defined but not + ** used. */ + sqlite3VdbeRegisterDump(p); + } + } +#endif /* SQLITE_DEBUG */ +#endif /* NDEBUG */ + } /* The end of the for(;;) loop the loops through opcodes */ + + /* If we reach this point, it means that execution is finished with + ** an error of some kind. + */ +abort_due_to_error: + if( db->mallocFailed ){ + rc = SQLITE_NOMEM_BKPT; + }else if( rc==SQLITE_IOERR_CORRUPTFS ){ + rc = SQLITE_CORRUPT_BKPT; + } + assert( rc ); +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + const char *zTrace = p->zSql; + if( zTrace==0 ){ + if( aOp[0].opcode==OP_Trace ){ + zTrace = aOp[0].p4.z; + } + if( zTrace==0 ) zTrace = "???"; + } + printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace); + } +#endif + if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ + sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); + } + p->rc = rc; + sqlite3SystemError(db, rc); + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(rc, "statement aborts at %d: [%s] %s", + (int)(pOp - aOp), p->zSql, p->zErrMsg); + if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); + if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); + if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ + db->flags |= SQLITE_CorruptRdOnly; + } + rc = SQLITE_ERROR; + if( resetSchemaOnFault>0 ){ + sqlite3ResetOneSchema(db, resetSchemaOnFault-1); + } + + /* This is the only way out of this procedure. We have to + ** release the mutexes on btrees that were acquired at the + ** top. */ +vdbe_return: +#if defined(VDBE_PROFILE) + if( pnCycle ){ + *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); + pnCycle = 0; + } +#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( pnCycle ){ + *pnCycle += sqlite3Hwtime(); + pnCycle = 0; + } +#endif + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ + nProgressLimit += db->nProgressOps; + if( db->xProgress(db->pProgressArg) ){ + nProgressLimit = LARGEST_UINT64; + rc = SQLITE_INTERRUPT; + goto abort_due_to_error; + } + } +#endif + p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; + if( DbMaskNonZero(p->lockMask) ){ + sqlite3VdbeLeave(p); + } + assert( rc!=SQLITE_OK || nExtraDelete==0 + || sqlite3_strlike("DELETE%",p->zSql,0)!=0 + ); + return rc; + + /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH + ** is encountered. + */ +too_big: + sqlite3VdbeError(p, "string or blob too big"); + rc = SQLITE_TOOBIG; + goto abort_due_to_error; + + /* Jump to here if a malloc() fails. + */ +no_mem: + sqlite3OomFault(db); + sqlite3VdbeError(p, "out of memory"); + rc = SQLITE_NOMEM_BKPT; + goto abort_due_to_error; + + /* Jump to here if the sqlite3_interrupt() API sets the interrupt + ** flag. + */ +abort_due_to_interrupt: + assert( AtomicLoad(&db->u1.isInterrupted) ); + rc = SQLITE_INTERRUPT; + goto abort_due_to_error; +} + + +/************** End of vdbe.c ************************************************/ +/************** Begin file vdbeblob.c ****************************************/ +/* +** 2007 May 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to implement incremental BLOB I/O. +*/ + +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +#ifndef SQLITE_OMIT_INCRBLOB + +/* +** Valid sqlite3_blob* handles point to Incrblob structures. +*/ +typedef struct Incrblob Incrblob; +struct Incrblob { + int nByte; /* Size of open blob, in bytes */ + int iOffset; /* Byte offset of blob in cursor data */ + u16 iCol; /* Table column this handle is open on */ + BtCursor *pCsr; /* Cursor pointing at blob row */ + sqlite3_stmt *pStmt; /* Statement holding cursor open */ + sqlite3 *db; /* The associated database */ + char *zDb; /* Database name */ + Table *pTab; /* Table object */ +}; + + +/* +** This function is used by both blob_open() and blob_reopen(). It seeks +** the b-tree cursor associated with blob handle p to point to row iRow. +** If successful, SQLITE_OK is returned and subsequent calls to +** sqlite3_blob_read() or sqlite3_blob_write() access the specified row. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a value of type TEXT or BLOB in the column nominated when the +** blob handle was opened, then an error code is returned and *pzErr may +** be set to point to a buffer containing an error message. It is the +** responsibility of the caller to free the error message buffer using +** sqlite3DbFree(). +** +** If an error does occur, then the b-tree cursor is closed. All subsequent +** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will +** immediately return SQLITE_ABORT. +*/ +static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ + int rc; /* Error code */ + char *zErr = 0; /* Error message */ + Vdbe *v = (Vdbe *)p->pStmt; + + /* Set the value of register r[1] in the SQL statement to integer iRow. + ** This is done directly as a performance optimization + */ + sqlite3VdbeMemSetInt64(&v->aMem[1], iRow); + + /* If the statement has been run before (and is paused at the OP_ResultRow) + ** then back it up to the point where it does the OP_NotExists. This could + ** have been down with an extra OP_Goto, but simply setting the program + ** counter is faster. */ + if( v->pc>4 ){ + v->pc = 4; + assert( v->aOp[v->pc].opcode==OP_NotExists ); + rc = sqlite3VdbeExec(v); + }else{ + rc = sqlite3_step(p->pStmt); + } + if( rc==SQLITE_ROW ){ + VdbeCursor *pC = v->apCsr[0]; + u32 type; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0; + testcase( pC->nHdrParsed==p->iCol ); + testcase( pC->nHdrParsed==p->iCol+1 ); + if( type<12 ){ + zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", + type==0?"null": type==7?"real": "integer" + ); + rc = SQLITE_ERROR; + sqlite3_finalize(p->pStmt); + p->pStmt = 0; + }else{ + p->iOffset = pC->aType[p->iCol + pC->nField]; + p->nByte = sqlite3VdbeSerialTypeLen(type); + p->pCsr = pC->uc.pCursor; + sqlite3BtreeIncrblobCursor(p->pCsr); + } + } + + if( rc==SQLITE_ROW ){ + rc = SQLITE_OK; + }else if( p->pStmt ){ + rc = sqlite3_finalize(p->pStmt); + p->pStmt = 0; + if( rc==SQLITE_OK ){ + zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow); + rc = SQLITE_ERROR; + }else{ + zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db)); + } + } + + assert( rc!=SQLITE_OK || zErr==0 ); + assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE ); + + *pzErr = zErr; + return rc; +} + +/* +** Open a blob handle. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3* db, /* The database connection */ + const char *zDb, /* The attached database containing the blob */ + const char *zTable, /* The table containing the blob */ + const char *zColumn, /* The column containing the blob */ + sqlite_int64 iRow, /* The row containing the glob */ + int wrFlag, /* True -> read/write access, false -> read-only */ + sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ +){ + int nAttempt = 0; + int iCol; /* Index of zColumn in row-record */ + int rc = SQLITE_OK; + char *zErr = 0; + Table *pTab; + Incrblob *pBlob = 0; + Parse sParse; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppBlob==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + *ppBlob = 0; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ + + sqlite3_mutex_enter(db->mutex); + + pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); + while(1){ + sqlite3ParseObjectInit(&sParse,db); + if( !pBlob ) goto blob_open_out; + sqlite3DbFree(db, zErr); + zErr = 0; + + sqlite3BtreeEnterAll(db); + pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb); + if( pTab && IsVirtual(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); + } + if( pTab && !HasRowid(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); + } +#ifndef SQLITE_OMIT_VIEW + if( pTab && IsView(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); + } +#endif + if( !pTab ){ + if( sParse.zErrMsg ){ + sqlite3DbFree(db, zErr); + zErr = sParse.zErrMsg; + sParse.zErrMsg = 0; + } + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + pBlob->pTab = pTab; + pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; + + /* Now search pTab for the exact column. */ + for(iCol=0; iColnCol; iCol++) { + if( sqlite3StrICmp(pTab->aCol[iCol].zCnName, zColumn)==0 ){ + break; + } + } + if( iCol==pTab->nCol ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + + /* If the value is being opened for writing, check that the + ** column is not indexed, and that it is not part of a foreign key. + */ + if( wrFlag ){ + const char *zFault = 0; + Index *pIdx; +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( db->flags&SQLITE_ForeignKeys ){ + /* Check that the column is not part of an FK child key definition. It + ** is not necessary to check if it is part of a parent key, as parent + ** key columns must be indexed. The check below will pick up this + ** case. */ + FKey *pFKey; + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + int j; + for(j=0; jnCol; j++){ + if( pFKey->aCol[j].iFrom==iCol ){ + zFault = "foreign key"; + } + } + } + } +#endif + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int j; + for(j=0; jnKeyCol; j++){ + /* FIXME: Be smarter about indexes that use expressions */ + if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){ + zFault = "indexed"; + } + } + } + if( zFault ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + } + + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse); + assert( pBlob->pStmt || db->mallocFailed ); + if( pBlob->pStmt ){ + + /* This VDBE program seeks a btree cursor to the identified + ** db/table/row entry. The reason for using a vdbe program instead + ** of writing code to use the b-tree layer directly is that the + ** vdbe program will take advantage of the various transaction, + ** locking and error handling infrastructure built into the vdbe. + ** + ** After seeking the cursor, the vdbe executes an OP_ResultRow. + ** Code external to the Vdbe then "borrows" the b-tree cursor and + ** uses it to implement the blob_read(), blob_write() and + ** blob_bytes() functions. + ** + ** The sqlite3_blob_close() function finalizes the vdbe program, + ** which closes the b-tree cursor and (possibly) commits the + ** transaction. + */ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList openBlob[] = { + {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ + {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */ + /* blobSeekToRow() will initialize r[1] to the desired rowid */ + {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */ + {OP_Column, 0, 0, 1}, /* 3 */ + {OP_ResultRow, 1, 0, 0}, /* 4 */ + {OP_Halt, 0, 0, 0}, /* 5 */ + }; + Vdbe *v = (Vdbe *)pBlob->pStmt; + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + VdbeOp *aOp; + + sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, + pTab->pSchema->schema_cookie, + pTab->pSchema->iGeneration); + sqlite3VdbeChangeP5(v, 1); + assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); + aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); + + /* Make sure a mutex is held on the table to be accessed */ + sqlite3VdbeUsesBtree(v, iDb); + + if( db->mallocFailed==0 ){ + assert( aOp!=0 ); + /* Configure the OP_TableLock instruction */ +#ifdef SQLITE_OMIT_SHARED_CACHE + aOp[0].opcode = OP_Noop; +#else + aOp[0].p1 = iDb; + aOp[0].p2 = pTab->tnum; + aOp[0].p3 = wrFlag; + sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); + } + if( db->mallocFailed==0 ){ +#endif + + /* Remove either the OP_OpenWrite or OpenRead. Set the P2 + ** parameter of the other to pTab->tnum. */ + if( wrFlag ) aOp[1].opcode = OP_OpenWrite; + aOp[1].p2 = pTab->tnum; + aOp[1].p3 = iDb; + + /* Configure the number of columns. Configure the cursor to + ** think that the table has one more column than it really + ** does. An OP_Column to retrieve this imaginary column will + ** always return an SQL NULL. This is useful because it means + ** we can invoke OP_Column to fill in the vdbe cursors type + ** and offset cache without causing any IO. + */ + aOp[1].p4type = P4_INT32; + aOp[1].p4.i = pTab->nCol+1; + aOp[3].p2 = pTab->nCol; + + sParse.nVar = 0; + sParse.nMem = 1; + sParse.nTab = 1; + sqlite3VdbeMakeReady(v, &sParse); + } + } + + pBlob->iCol = iCol; + pBlob->db = db; + sqlite3BtreeLeaveAll(db); + if( db->mallocFailed ){ + goto blob_open_out; + } + rc = blobSeekToRow(pBlob, iRow, &zErr); + if( (++nAttempt)>=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break; + sqlite3ParseObjectReset(&sParse); + } + +blob_open_out: + if( rc==SQLITE_OK && db->mallocFailed==0 ){ + *ppBlob = (sqlite3_blob *)pBlob; + }else{ + if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); + sqlite3DbFree(db, pBlob); + } + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); + sqlite3DbFree(db, zErr); + sqlite3ParseObjectReset(&sParse); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Close a blob handle that was previously created using +** sqlite3_blob_open(). +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){ + Incrblob *p = (Incrblob *)pBlob; + int rc; + sqlite3 *db; + + if( p ){ + sqlite3_stmt *pStmt = p->pStmt; + db = p->db; + sqlite3_mutex_enter(db->mutex); + sqlite3DbFree(db, p); + sqlite3_mutex_leave(db->mutex); + rc = sqlite3_finalize(pStmt); + }else{ + rc = SQLITE_OK; + } + return rc; +} + +/* +** Perform a read or write operation on a blob +*/ +static int blobReadWrite( + sqlite3_blob *pBlob, + void *z, + int n, + int iOffset, + int (*xCall)(BtCursor*, u32, u32, void*) +){ + int rc; + Incrblob *p = (Incrblob *)pBlob; + Vdbe *v; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + v = (Vdbe*)p->pStmt; + + if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ + /* Request is out of range. Return a transient error. */ + rc = SQLITE_ERROR; + }else if( v==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is + ** returned, clean-up the statement handle. + */ + assert( db == v->db ); + sqlite3BtreeEnterCursor(p->pCsr); + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){ + /* If a pre-update hook is registered and this is a write cursor, + ** invoke it here. + ** + ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this + ** operation should really be an SQLITE_UPDATE. This is probably + ** incorrect, but is convenient because at this point the new.* values + ** are not easily obtainable. And for the sessions module, an + ** SQLITE_UPDATE where the PK columns do not change is handled in the + ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually + ** slightly more efficient). Since you cannot write to a PK column + ** using the incremental-blob API, this works. For the sessions module + ** anyhow. + */ + sqlite3_int64 iKey; + iKey = sqlite3BtreeIntegerKey(p->pCsr); + assert( v->apCsr[0]!=0 ); + assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); + sqlite3VdbePreUpdateHook( + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol + ); + } +#endif + + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); + sqlite3BtreeLeaveCursor(p->pCsr); + if( rc==SQLITE_ABORT ){ + sqlite3VdbeFinalize(v); + p->pStmt = 0; + }else{ + v->rc = rc; + } + } + sqlite3Error(db, rc); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Read data from a blob handle. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ + return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked); +} + +/* +** Write data to a blob handle. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ + return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData); +} + +/* +** Query a blob handle for the size of the data. +** +** The Incrblob.nByte field is fixed for the lifetime of the Incrblob +** so no mutex is required for access. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ + Incrblob *p = (Incrblob *)pBlob; + return (p && p->pStmt) ? p->nByte : 0; +} + +/* +** Move an existing blob handle to point to a different row of the same +** database table. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a blob or text value, then an error code is returned and the +** database handle error code and message set. If this happens, then all +** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) +** immediately return SQLITE_ABORT. +*/ +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ + int rc; + Incrblob *p = (Incrblob *)pBlob; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + + if( p->pStmt==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + char *zErr; + ((Vdbe*)p->pStmt)->rc = SQLITE_OK; + rc = blobSeekToRow(p, iRow, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); + sqlite3DbFree(db, zErr); + } + assert( rc!=SQLITE_SCHEMA ); + } + + rc = sqlite3ApiExit(db, rc); + assert( rc==SQLITE_OK || p->pStmt==0 ); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#endif /* #ifndef SQLITE_OMIT_INCRBLOB */ + +/************** End of vdbeblob.c ********************************************/ +/************** Begin file vdbesort.c ****************************************/ +/* +** 2011-07-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code for the VdbeSorter object, used in concert with +** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements +** or by SELECT statements with ORDER BY clauses that cannot be satisfied +** using indexes and without LIMIT clauses. +** +** The VdbeSorter object implements a multi-threaded external merge sort +** algorithm that is efficient even if the number of elements being sorted +** exceeds the available memory. +** +** Here is the (internal, non-API) interface between this module and the +** rest of the SQLite system: +** +** sqlite3VdbeSorterInit() Create a new VdbeSorter object. +** +** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter +** object. The row is a binary blob in the +** OP_MakeRecord format that contains both +** the ORDER BY key columns and result columns +** in the case of a SELECT w/ ORDER BY, or +** the complete record for an index entry +** in the case of a CREATE INDEX. +** +** sqlite3VdbeSorterRewind() Sort all content previously added. +** Position the read cursor on the +** first sorted element. +** +** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted +** element. +** +** sqlite3VdbeSorterRowkey() Return the complete binary blob for the +** row currently under the read cursor. +** +** sqlite3VdbeSorterCompare() Compare the binary blob for the row +** currently under the read cursor against +** another binary blob X and report if +** X is strictly less than the read cursor. +** Used to enforce uniqueness in a +** CREATE UNIQUE INDEX statement. +** +** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim +** all resources. +** +** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This +** is like Close() followed by Init() only +** much faster. +** +** The interfaces above must be called in a particular order. Write() can +** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and +** Compare() can only occur in between Rewind() and Close()/Reset(). i.e. +** +** Init() +** for each record: Write() +** Rewind() +** Rowkey()/Compare() +** Next() +** Close() +** +** Algorithm: +** +** Records passed to the sorter via calls to Write() are initially held +** unsorted in main memory. Assuming the amount of memory used never exceeds +** a threshold, when Rewind() is called the set of records is sorted using +** an in-memory merge sort. In this case, no temporary files are required +** and subsequent calls to Rowkey(), Next() and Compare() read records +** directly from main memory. +** +** If the amount of space used to store records in main memory exceeds the +** threshold, then the set of records currently in memory are sorted and +** written to a temporary file in "Packed Memory Array" (PMA) format. +** A PMA created at this point is known as a "level-0 PMA". Higher levels +** of PMAs may be created by merging existing PMAs together - for example +** merging two or more level-0 PMAs together creates a level-1 PMA. +** +** The threshold for the amount of main memory to use before flushing +** records to a PMA is roughly the same as the limit configured for the +** page-cache of the main database. Specifically, the threshold is set to +** the value returned by "PRAGMA main.page_size" multiplied by +** that returned by "PRAGMA main.cache_size", in bytes. +** +** If the sorter is running in single-threaded mode, then all PMAs generated +** are appended to a single temporary file. Or, if the sorter is running in +** multi-threaded mode then up to (N+1) temporary files may be opened, where +** N is the configured number of worker threads. In this case, instead of +** sorting the records and writing the PMA to a temporary file itself, the +** calling thread usually launches a worker thread to do so. Except, if +** there are already N worker threads running, the main thread does the work +** itself. +** +** The sorter is running in multi-threaded mode if (a) the library was built +** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater +** than zero, and (b) worker threads have been enabled at runtime by calling +** "PRAGMA threads=N" with some value of N greater than 0. +** +** When Rewind() is called, any data remaining in memory is flushed to a +** final PMA. So at this point the data is stored in some number of sorted +** PMAs within temporary files on disk. +** +** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the +** sorter is running in single-threaded mode, then these PMAs are merged +** incrementally as keys are retrieved from the sorter by the VDBE. The +** MergeEngine object, described in further detail below, performs this +** merge. +** +** Or, if running in multi-threaded mode, then a background thread is +** launched to merge the existing PMAs. Once the background thread has +** merged T bytes of data into a single sorted PMA, the main thread +** begins reading keys from that PMA while the background thread proceeds +** with merging the next T bytes of data. And so on. +** +** Parameter T is set to half the value of the memory threshold used +** by Write() above to determine when to create a new PMA. +** +** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when +** Rewind() is called, then a hierarchy of incremental-merges is used. +** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on +** disk are merged together. Then T bytes of data from the second set, and +** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT +** PMAs at a time. This done is to improve locality. +** +** If running in multi-threaded mode and there are more than +** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more +** than one background thread may be created. Specifically, there may be +** one background thread for each temporary file on disk, and one background +** thread to merge the output of each of the others to a single PMA for +** the main thread to read from. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* +** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various +** messages to stderr that may be helpful in understanding the performance +** characteristics of the sorter in multi-threaded mode. +*/ +#if 0 +# define SQLITE_DEBUG_SORTER_THREADS 1 +#endif + +/* +** Hard-coded maximum amount of data to accumulate in memory before flushing +** to a level 0 PMA. The purpose of this limit is to prevent various integer +** overflows. 512MiB. +*/ +#define SQLITE_MAX_PMASZ (1<<29) + +/* +** Private objects used by the sorter +*/ +typedef struct MergeEngine MergeEngine; /* Merge PMAs together */ +typedef struct PmaReader PmaReader; /* Incrementally read one PMA */ +typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ +typedef struct SorterRecord SorterRecord; /* A record being sorted */ +typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ +typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ +typedef struct SorterList SorterList; /* In-memory list of records */ +typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ + +/* +** A container for a temp file handle and the current amount of data +** stored in the file. +*/ +struct SorterFile { + sqlite3_file *pFd; /* File handle */ + i64 iEof; /* Bytes of data stored in pFd */ +}; + +/* +** An in-memory list of objects to be sorted. +** +** If aMemory==0 then each object is allocated separately and the objects +** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects +** are stored in the aMemory[] bulk memory, one right after the other, and +** are connected using SorterRecord.u.iNext. +*/ +struct SorterList { + SorterRecord *pList; /* Linked list of records */ + u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ + i64 szPMA; /* Size of pList as PMA in bytes */ +}; + +/* +** The MergeEngine object is used to combine two or more smaller PMAs into +** one big PMA using a merge operation. Separate PMAs all need to be +** combined into one big PMA in order to be able to step through the sorted +** records in order. +** +** The aReadr[] array contains a PmaReader object for each of the PMAs being +** merged. An aReadr[] object either points to a valid key or else is at EOF. +** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.) +** For the purposes of the paragraphs below, we assume that the array is +** actually N elements in size, where N is the smallest power of 2 greater +** to or equal to the number of PMAs being merged. The extra aReadr[] elements +** are treated as if they are empty (always at EOF). +** +** The aTree[] array is also N elements in size. The value of N is stored in +** the MergeEngine.nTree variable. +** +** The final (N/2) elements of aTree[] contain the results of comparing +** pairs of PMA keys together. Element i contains the result of +** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the +** aTree element is set to the index of it. +** +** For the purposes of this comparison, EOF is considered greater than any +** other key value. If the keys are equal (only possible with two EOF +** values), it doesn't matter which index is stored. +** +** The (N/4) elements of aTree[] that precede the final (N/2) described +** above contains the index of the smallest of each block of 4 PmaReaders +** And so on. So that aTree[1] contains the index of the PmaReader that +** currently points to the smallest key value. aTree[0] is unused. +** +** Example: +** +** aReadr[0] -> Banana +** aReadr[1] -> Feijoa +** aReadr[2] -> Elderberry +** aReadr[3] -> Currant +** aReadr[4] -> Grapefruit +** aReadr[5] -> Apple +** aReadr[6] -> Durian +** aReadr[7] -> EOF +** +** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } +** +** The current element is "Apple" (the value of the key indicated by +** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will +** be advanced to the next key in its segment. Say the next key is +** "Eggplant": +** +** aReadr[5] -> Eggplant +** +** The contents of aTree[] are updated first by comparing the new PmaReader +** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader +** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree. +** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader +** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Bananafile2. And instead of using a +** background thread to prepare data for the PmaReader, with a single +** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with +** keys from pMerger by the calling thread whenever the PmaReader runs out +** of data. +*/ +struct IncrMerger { + SortSubtask *pTask; /* Task that owns this merger */ + MergeEngine *pMerger; /* Merge engine thread reads data from */ + i64 iStartOff; /* Offset to start writing file at */ + int mxSz; /* Maximum bytes of data to store */ + int bEof; /* Set to true when merge is finished */ + int bUseThread; /* True to use a bg thread for this object */ + SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */ +}; + +/* +** An instance of this object is used for writing a PMA. +** +** The PMA is written one record at a time. Each record is of an arbitrary +** size. But I/O is more efficient if it occurs in page-sized blocks where +** each block is aligned on a page boundary. This object caches writes to +** the PMA so that aligned, page-size blocks are written. +*/ +struct PmaWriter { + int eFWErr; /* Non-zero if in an error state */ + u8 *aBuffer; /* Pointer to write buffer */ + int nBuffer; /* Size of write buffer in bytes */ + int iBufStart; /* First byte of buffer to write */ + int iBufEnd; /* Last byte of buffer to write */ + i64 iWriteOff; /* Offset of start of buffer in file */ + sqlite3_file *pFd; /* File handle to write to */ +}; + +/* +** This object is the header on a single record while that record is being +** held in memory and prior to being written out as part of a PMA. +** +** How the linked list is connected depends on how memory is being managed +** by this module. If using a separate allocation for each in-memory record +** (VdbeSorter.list.aMemory==0), then the list is always connected using the +** SorterRecord.u.pNext pointers. +** +** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0), +** then while records are being accumulated the list is linked using the +** SorterRecord.u.iNext offset. This is because the aMemory[] array may +** be sqlite3Realloc()ed while records are being accumulated. Once the VM +** has finished passing records to the sorter, or when the in-memory buffer +** is full, the list is sorted. As part of the sorting process, it is +** converted to use the SorterRecord.u.pNext pointers. See function +** vdbeSorterSort() for details. +*/ +struct SorterRecord { + int nVal; /* Size of the record in bytes */ + union { + SorterRecord *pNext; /* Pointer to next record in list */ + int iNext; /* Offset within aMemory of next record */ + } u; + /* The data for the record immediately follows this header */ +}; + +/* Return a pointer to the buffer containing the record data for SorterRecord +** object p. Should be used as if: +** +** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; } +*/ +#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1)) + + +/* Maximum number of PMAs that a single MergeEngine can merge */ +#define SORTER_MAX_MERGE_COUNT 16 + +static int vdbeIncrSwap(IncrMerger*); +static void vdbeIncrFree(IncrMerger *); + +/* +** Free all memory belonging to the PmaReader object passed as the +** argument. All structure fields are set to zero before returning. +*/ +static void vdbePmaReaderClear(PmaReader *pReadr){ + sqlite3_free(pReadr->aAlloc); + sqlite3_free(pReadr->aBuffer); + if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + vdbeIncrFree(pReadr->pIncr); + memset(pReadr, 0, sizeof(PmaReader)); +} + +/* +** Read the next nByte bytes of data from the PMA p. +** If successful, set *ppOut to point to a buffer containing the data +** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite +** error code. +** +** The buffer returned in *ppOut is only valid until the +** next call to this function. +*/ +static int vdbePmaReadBlob( + PmaReader *p, /* PmaReader from which to take the blob */ + int nByte, /* Bytes of data to read */ + u8 **ppOut /* OUT: Pointer to buffer containing data */ +){ + int iBuf; /* Offset within buffer to read from */ + int nAvail; /* Bytes of data available in buffer */ + + if( p->aMap ){ + *ppOut = &p->aMap[p->iReadOff]; + p->iReadOff += nByte; + return SQLITE_OK; + } + + assert( p->aBuffer ); + + /* If there is no more data to be read from the buffer, read the next + ** p->nBuffer bytes of data from the file into it. Or, if there are less + ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf==0 ){ + int nRead; /* Bytes to read from disk */ + int rc; /* sqlite3OsRead() return code */ + + /* Determine how many bytes of data to read. */ + if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ + nRead = p->nBuffer; + }else{ + nRead = (int)(p->iEof - p->iReadOff); + } + assert( nRead>0 ); + + /* Readr data from the file. Return early if an error occurs. */ + rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); + assert( rc!=SQLITE_IOERR_SHORT_READ ); + if( rc!=SQLITE_OK ) return rc; + } + nAvail = p->nBuffer - iBuf; + + if( nByte<=nAvail ){ + /* The requested data is available in the in-memory buffer. In this + ** case there is no need to make a copy of the data, just return a + ** pointer into the buffer to the caller. */ + *ppOut = &p->aBuffer[iBuf]; + p->iReadOff += nByte; + }else{ + /* The requested data is not all available in the in-memory buffer. + ** In this case, allocate space at p->aAlloc[] to copy the requested + ** range into. Then return a copy of pointer p->aAlloc to the caller. */ + int nRem; /* Bytes remaining to copy */ + + /* Extend the p->aAlloc[] allocation if required. */ + if( p->nAllocnAlloc); + while( nByte>nNew ) nNew = nNew*2; + aNew = sqlite3Realloc(p->aAlloc, nNew); + if( !aNew ) return SQLITE_NOMEM_BKPT; + p->nAlloc = nNew; + p->aAlloc = aNew; + } + + /* Copy as much data as is available in the buffer into the start of + ** p->aAlloc[]. */ + memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); + p->iReadOff += nAvail; + nRem = nByte - nAvail; + + /* The following loop copies up to p->nBuffer bytes per iteration into + ** the p->aAlloc[] buffer. */ + while( nRem>0 ){ + int rc; /* vdbePmaReadBlob() return code */ + int nCopy; /* Number of bytes to copy */ + u8 *aNext; /* Pointer to buffer to copy data from */ + + nCopy = nRem; + if( nRem>p->nBuffer ) nCopy = p->nBuffer; + rc = vdbePmaReadBlob(p, nCopy, &aNext); + if( rc!=SQLITE_OK ) return rc; + assert( aNext!=p->aAlloc ); + memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); + nRem -= nCopy; + } + + *ppOut = p->aAlloc; + } + + return SQLITE_OK; +} + +/* +** Read a varint from the stream of data accessed by p. Set *pnOut to +** the value read. +*/ +static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ + int iBuf; + + if( p->aMap ){ + p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); + }else{ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf && (p->nBuffer-iBuf)>=9 ){ + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); + }else{ + u8 aVarint[16], *a; + int i = 0, rc; + do{ + rc = vdbePmaReadBlob(p, 1, &a); + if( rc ) return rc; + aVarint[(i++)&0xf] = a[0]; + }while( (a[0]&0x80)!=0 ); + sqlite3GetVarint(aVarint, pnOut); + } + } + + return SQLITE_OK; +} + +/* +** Attempt to memory map file pFile. If successful, set *pp to point to the +** new mapping and return SQLITE_OK. If the mapping is not attempted +** (because the file is too large or the VFS layer is configured not to use +** mmap), return SQLITE_OK and set *pp to NULL. +** +** Or, if an error occurs, return an SQLite error code. The final value of +** *pp is undefined in this case. +*/ +static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ + int rc = SQLITE_OK; + if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ + sqlite3_file *pFd = pFile->pFd; + if( pFd->pMethods->iVersion>=3 ){ + rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); + testcase( rc!=SQLITE_OK ); + } + } + return rc; +} + +/* +** Attach PmaReader pReadr to file pFile (if it is not already attached to +** that file) and seek it to offset iOff within the file. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static int vdbePmaReaderSeek( + SortSubtask *pTask, /* Task context */ + PmaReader *pReadr, /* Reader whose cursor is to be moved */ + SorterFile *pFile, /* Sorter file to read from */ + i64 iOff /* Offset in pFile */ +){ + int rc = SQLITE_OK; + + assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 ); + + if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ; + if( pReadr->aMap ){ + sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + pReadr->aMap = 0; + } + pReadr->iReadOff = iOff; + pReadr->iEof = pFile->iEof; + pReadr->pFd = pFile->pFd; + + rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap); + if( rc==SQLITE_OK && pReadr->aMap==0 ){ + int pgsz = pTask->pSorter->pgsz; + int iBuf = pReadr->iReadOff % pgsz; + if( pReadr->aBuffer==0 ){ + pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz); + if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT; + pReadr->nBuffer = pgsz; + } + if( rc==SQLITE_OK && iBuf ){ + int nRead = pgsz - iBuf; + if( (pReadr->iReadOff + nRead) > pReadr->iEof ){ + nRead = (int)(pReadr->iEof - pReadr->iReadOff); + } + rc = sqlite3OsRead( + pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff + ); + testcase( rc!=SQLITE_OK ); + } + } + + return rc; +} + +/* +** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if +** no error occurs, or an SQLite error code if one does. +*/ +static int vdbePmaReaderNext(PmaReader *pReadr){ + int rc = SQLITE_OK; /* Return Code */ + u64 nRec = 0; /* Size of record in bytes */ + + + if( pReadr->iReadOff>=pReadr->iEof ){ + IncrMerger *pIncr = pReadr->pIncr; + int bEof = 1; + if( pIncr ){ + rc = vdbeIncrSwap(pIncr); + if( rc==SQLITE_OK && pIncr->bEof==0 ){ + rc = vdbePmaReaderSeek( + pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff + ); + bEof = 0; + } + } + + if( bEof ){ + /* This is an EOF condition */ + vdbePmaReaderClear(pReadr); + testcase( rc!=SQLITE_OK ); + return rc; + } + } + + if( rc==SQLITE_OK ){ + rc = vdbePmaReadVarint(pReadr, &nRec); + } + if( rc==SQLITE_OK ){ + pReadr->nKey = (int)nRec; + rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey); + testcase( rc!=SQLITE_OK ); + } + + return rc; +} + +/* +** Initialize PmaReader pReadr to scan through the PMA stored in file pFile +** starting at offset iStart and ending at offset iEof-1. This function +** leaves the PmaReader pointing to the first key in the PMA (or EOF if the +** PMA is empty). +** +** If the pnByte parameter is NULL, then it is assumed that the file +** contains a single PMA, and that that PMA omits the initial length varint. +*/ +static int vdbePmaReaderInit( + SortSubtask *pTask, /* Task context */ + SorterFile *pFile, /* Sorter file to read from */ + i64 iStart, /* Start offset in pFile */ + PmaReader *pReadr, /* PmaReader to populate */ + i64 *pnByte /* IN/OUT: Increment this value by PMA size */ +){ + int rc; + + assert( pFile->iEof>iStart ); + assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 ); + assert( pReadr->aBuffer==0 ); + assert( pReadr->aMap==0 ); + + rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart); + if( rc==SQLITE_OK ){ + u64 nByte = 0; /* Size of PMA in bytes */ + rc = vdbePmaReadVarint(pReadr, &nByte); + pReadr->iEof = pReadr->iReadOff + nByte; + *pnByte += nByte; + } + + if( rc==SQLITE_OK ){ + rc = vdbePmaReaderNext(pReadr); + } + return rc; +} + +/* +** A version of vdbeSorterCompare() that assumes that it has already been +** determined that the first field of key1 is equal to the first field of +** key2. +*/ +static int vdbeSorterCompareTail( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( *pbKey2Cached==0 ){ + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); +} + +/* +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, +** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences +** used by the comparison. Return the result of the comparison. +** +** If IN/OUT parameter *pbKey2Cached is true when this function is called, +** it is assumed that (pTask->pUnpacked) contains the unpacked version +** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked +** version of key2 and *pbKey2Cached set to true before returning. +** +** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set +** to SQLITE_NOMEM. +*/ +static int vdbeSorterCompare( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( !*pbKey2Cached ){ + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is a TEXT value and that the collation +** sequence to compare them with is BINARY. +*/ +static int vdbeSorterCompareText( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + + int n1; + int n2; + int res; + + getVarint32NR(&p1[1], n1); + getVarint32NR(&p2[1], n2); + res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2); + if( res==0 ){ + res = n1 - n2; + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else{ + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); + if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ + res = res * -1; + } + } + + return res; +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is an INTEGER value. +*/ +static int vdbeSorterCompareInt( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const int s1 = p1[1]; /* Left hand serial type */ + const int s2 = p2[1]; /* Right hand serial type */ + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + int res; /* Return value */ + + assert( (s1>0 && s1<7) || s1==8 || s1==9 ); + assert( (s2>0 && s2<7) || s2==8 || s2==9 ); + + if( s1==s2 ){ + /* The two values have the same sign. Compare using memcmp(). */ + static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 }; + const u8 n = aLen[s1]; + int i; + res = 0; + for(i=0; i7 && s2>7 ){ + res = s1 - s2; + }else{ + if( s2>7 ){ + res = +1; + }else if( s1>7 ){ + res = -1; + }else{ + res = s1 - s2; + } + assert( res!=0 ); + + if( res>0 ){ + if( *v1 & 0x80 ) res = -1; + }else{ + if( *v2 & 0x80 ) res = +1; + } + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); + res = res * -1; + } + + return res; +} + +/* +** Initialize the temporary index cursor just opened as a sorter cursor. +** +** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField) +** to determine the number of fields that should be compared from the +** records being sorted. However, if the value passed as argument nField +** is non-zero and the sorter is able to guarantee a stable sort, nField +** is used instead. This is used when sorting records for a CREATE INDEX +** statement. In this case, keys are always delivered to the sorter in +** order of the primary key, which happens to be make up the final part +** of the records being sorted. So if the sort is stable, there is never +** any reason to compare PK fields and they can be ignored for a small +** performance boost. +** +** The sorter can guarantee a stable sort when running in single-threaded +** mode, but not in multi-threaded mode. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterInit( + sqlite3 *db, /* Database connection (for malloc()) */ + int nField, /* Number of key fields in each record */ + VdbeCursor *pCsr /* Cursor that holds the new sorter */ +){ + int pgsz; /* Page size of main database */ + int i; /* Used to iterate through aTask[] */ + VdbeSorter *pSorter; /* The new sorter */ + KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ + int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ + int sz; /* Size of pSorter in bytes */ + int rc = SQLITE_OK; +#if SQLITE_MAX_WORKER_THREADS==0 +# define nWorker 0 +#else + int nWorker; +#endif + + /* Initialize the upper limit on the number of worker threads */ +#if SQLITE_MAX_WORKER_THREADS>0 + if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){ + nWorker = 0; + }else{ + nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS]; + } +#endif + + /* Do not allow the total number of threads (main thread + all workers) + ** to exceed the maximum merge count */ +#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT + if( nWorker>=SORTER_MAX_MERGE_COUNT ){ + nWorker = SORTER_MAX_MERGE_COUNT-1; + } +#endif + + assert( pCsr->pKeyInfo ); + assert( !pCsr->isEphemeral ); + assert( pCsr->eCurType==CURTYPE_SORTER ); + szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); + sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); + + pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); + pCsr->uc.pSorter = pSorter; + if( pSorter==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + Btree *pBt = db->aDb[0].pBt; + pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); + memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); + pKeyInfo->db = 0; + if( nField && nWorker==0 ){ + pKeyInfo->nKeyField = nField; + } + sqlite3BtreeEnter(pBt); + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); + sqlite3BtreeLeave(pBt); + pSorter->nTask = nWorker + 1; + pSorter->iPrev = (u8)(nWorker - 1); + pSorter->bUseThreads = (pSorter->nTask>1); + pSorter->db = db; + for(i=0; inTask; i++){ + SortSubtask *pTask = &pSorter->aTask[i]; + pTask->pSorter = pSorter; + } + + if( !sqlite3TempInMemory(db) ){ + i64 mxCache; /* Cache size in bytes*/ + u32 szPma = sqlite3GlobalConfig.szPma; + pSorter->mnPmaSize = szPma * pgsz; + + mxCache = db->aDb[0].pSchema->cache_size; + if( mxCache<0 ){ + /* A negative cache-size value C indicates that the cache is abs(C) + ** KiB in size. */ + mxCache = mxCache * -1024; + }else{ + mxCache = mxCache * pgsz; + } + mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); + pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); + + /* Avoid large memory allocations if the application has requested + ** SQLITE_CONFIG_SMALL_MALLOC. */ + if( sqlite3GlobalConfig.bSmallMalloc==0 ){ + assert( pSorter->iMemory==0 ); + pSorter->nMemory = pgsz; + pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); + if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT; + } + } + + if( pKeyInfo->nAllField<13 + && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) + && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0 + ){ + pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; + } + } + + return rc; +} +#undef nWorker /* Defined at the top of this function */ + +/* +** Free the list of sorted records starting at pRecord. +*/ +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ + SorterRecord *p; + SorterRecord *pNext; + for(p=pRecord; p; p=pNext){ + pNext = p->u.pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Free all resources owned by the object indicated by argument pTask. All +** fields of *pTask are zeroed before returning. +*/ +static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ + sqlite3DbFree(db, pTask->pUnpacked); +#if SQLITE_MAX_WORKER_THREADS>0 + /* pTask->list.aMemory can only be non-zero if it was handed memory + ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ + if( pTask->list.aMemory ){ + sqlite3_free(pTask->list.aMemory); + }else +#endif + { + assert( pTask->list.aMemory==0 ); + vdbeSorterRecordFree(0, pTask->list.pList); + } + if( pTask->file.pFd ){ + sqlite3OsCloseFree(pTask->file.pFd); + } + if( pTask->file2.pFd ){ + sqlite3OsCloseFree(pTask->file2.pFd); + } + memset(pTask, 0, sizeof(SortSubtask)); +} + +#ifdef SQLITE_DEBUG_SORTER_THREADS +static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ + i64 t; + int iTask = (pTask - pTask->pSorter->aTask); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); +} +static void vdbeSorterRewindDebug(const char *zEvent){ + i64 t = 0; + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); + if( ALWAYS(pVfs) ) sqlite3OsCurrentTimeInt64(pVfs, &t); + fprintf(stderr, "%lld:X %s\n", t, zEvent); +} +static void vdbeSorterPopulateDebug( + SortSubtask *pTask, + const char *zEvent +){ + i64 t; + int iTask = (pTask - pTask->pSorter->aTask); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); +} +static void vdbeSorterBlockDebug( + SortSubtask *pTask, + int bBlocked, + const char *zEvent +){ + if( bBlocked ){ + i64 t; + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:main %s\n", t, zEvent); + } +} +#else +# define vdbeSorterWorkDebug(x,y) +# define vdbeSorterRewindDebug(y) +# define vdbeSorterPopulateDebug(x,y) +# define vdbeSorterBlockDebug(x,y,z) +#endif + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** Join thread pTask->thread. +*/ +static int vdbeSorterJoinThread(SortSubtask *pTask){ + int rc = SQLITE_OK; + if( pTask->pThread ){ +#ifdef SQLITE_DEBUG_SORTER_THREADS + int bDone = pTask->bDone; +#endif + void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR); + vdbeSorterBlockDebug(pTask, !bDone, "enter"); + (void)sqlite3ThreadJoin(pTask->pThread, &pRet); + vdbeSorterBlockDebug(pTask, !bDone, "exit"); + rc = SQLITE_PTR_TO_INT(pRet); + assert( pTask->bDone==1 ); + pTask->bDone = 0; + pTask->pThread = 0; + } + return rc; +} + +/* +** Launch a background thread to run xTask(pIn). +*/ +static int vdbeSorterCreateThread( + SortSubtask *pTask, /* Thread will use this task object */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + assert( pTask->pThread==0 && pTask->bDone==0 ); + return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn); +} + +/* +** Join all outstanding threads launched by SorterWrite() to create +** level-0 PMAs. +*/ +static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ + int rc = rcin; + int i; + + /* This function is always called by the main user thread. + ** + ** If this function is being called after SorterRewind() has been called, + ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread + ** is currently attempt to join one of the other threads. To avoid a race + ** condition where this thread also attempts to join the same object, join + ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */ + for(i=pSorter->nTask-1; i>=0; i--){ + SortSubtask *pTask = &pSorter->aTask[i]; + int rc2 = vdbeSorterJoinThread(pTask); + if( rc==SQLITE_OK ) rc = rc2; + } + return rc; +} +#else +# define vdbeSorterJoinAll(x,rcin) (rcin) +# define vdbeSorterJoinThread(pTask) SQLITE_OK +#endif + +/* +** Allocate a new MergeEngine object capable of handling up to +** nReader PmaReader inputs. +** +** nReader is automatically rounded up to the next power of two. +** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up. +*/ +static MergeEngine *vdbeMergeEngineNew(int nReader){ + int N = 2; /* Smallest power of two >= nReader */ + int nByte; /* Total bytes of space to allocate */ + MergeEngine *pNew; /* Pointer to allocated object to return */ + + assert( nReader<=SORTER_MAX_MERGE_COUNT ); + + while( NnTree = N; + pNew->pTask = 0; + pNew->aReadr = (PmaReader*)&pNew[1]; + pNew->aTree = (int*)&pNew->aReadr[N]; + } + return pNew; +} + +/* +** Free the MergeEngine object passed as the only argument. +*/ +static void vdbeMergeEngineFree(MergeEngine *pMerger){ + int i; + if( pMerger ){ + for(i=0; inTree; i++){ + vdbePmaReaderClear(&pMerger->aReadr[i]); + } + } + sqlite3_free(pMerger); +} + +/* +** Free all resources associated with the IncrMerger object indicated by +** the first argument. +*/ +static void vdbeIncrFree(IncrMerger *pIncr){ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + vdbeSorterJoinThread(pIncr->pTask); + if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd); + if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd); + } +#endif + vdbeMergeEngineFree(pIncr->pMerger); + sqlite3_free(pIncr); + } +} + +/* +** Reset a sorting cursor back to its original empty state. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ + int i; + (void)vdbeSorterJoinAll(pSorter, SQLITE_OK); + assert( pSorter->bUseThreads || pSorter->pReader==0 ); +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->pReader ){ + vdbePmaReaderClear(pSorter->pReader); + sqlite3DbFree(db, pSorter->pReader); + pSorter->pReader = 0; + } +#endif + vdbeMergeEngineFree(pSorter->pMerger); + pSorter->pMerger = 0; + for(i=0; inTask; i++){ + SortSubtask *pTask = &pSorter->aTask[i]; + vdbeSortSubtaskCleanup(db, pTask); + pTask->pSorter = pSorter; + } + if( pSorter->list.aMemory==0 ){ + vdbeSorterRecordFree(0, pSorter->list.pList); + } + pSorter->list.pList = 0; + pSorter->list.szPMA = 0; + pSorter->bUsePMA = 0; + pSorter->iMemory = 0; + pSorter->mxKeysize = 0; + sqlite3DbFree(db, pSorter->pUnpacked); + pSorter->pUnpacked = 0; +} + +/* +** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ + VdbeSorter *pSorter; + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + if( pSorter ){ + sqlite3VdbeSorterReset(db, pSorter); + sqlite3_free(pSorter->list.aMemory); + sqlite3DbFree(db, pSorter); + pCsr->uc.pSorter = 0; + } +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** The first argument is a file-handle open on a temporary file. The file +** is guaranteed to be nByte bytes or smaller in size. This function +** attempts to extend the file to nByte bytes in size and to ensure that +** the VFS has memory mapped it. +** +** Whether or not the file does end up memory mapped of course depends on +** the specific VFS implementation. +*/ +static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ + if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ + void *p = 0; + int chunksize = 4*1024; + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); + sqlite3OsFetch(pFd, 0, (int)nByte, &p); + if( p ) sqlite3OsUnfetch(pFd, 0, p); + } +} +#else +# define vdbeSorterExtendFile(x,y,z) +#endif + +/* +** Allocate space for a file-handle and open a temporary file. If successful, +** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK. +** Otherwise, set *ppFd to 0 and return an SQLite error code. +*/ +static int vdbeSorterOpenTempFile( + sqlite3 *db, /* Database handle doing sort */ + i64 nExtend, /* Attempt to extend file to this size */ + sqlite3_file **ppFd +){ + int rc; + if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; + rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc + ); + if( rc==SQLITE_OK ){ + i64 max = SQLITE_MAX_MMAP_SIZE; + sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); + if( nExtend>0 ){ + vdbeSorterExtendFile(db, *ppFd, nExtend); + } + } + return rc; +} + +/* +** If it has not already been allocated, allocate the UnpackedRecord +** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or +** if no allocation was required), or SQLITE_NOMEM otherwise. +*/ +static int vdbeSortAllocUnpacked(SortSubtask *pTask){ + if( pTask->pUnpacked==0 ){ + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); + if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT; + pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField; + pTask->pUnpacked->errCode = 0; + } + return SQLITE_OK; +} + + +/* +** Merge the two sorted lists p1 and p2 into a single list. +*/ +static SorterRecord *vdbeSorterMerge( + SortSubtask *pTask, /* Calling thread context */ + SorterRecord *p1, /* First list to merge */ + SorterRecord *p2 /* Second list to merge */ +){ + SorterRecord *pFinal = 0; + SorterRecord **pp = &pFinal; + int bCached = 0; + + assert( p1!=0 && p2!=0 ); + for(;;){ + int res; + res = pTask->xCompare( + pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal + ); + + if( res<=0 ){ + *pp = p1; + pp = &p1->u.pNext; + p1 = p1->u.pNext; + if( p1==0 ){ + *pp = p2; + break; + } + }else{ + *pp = p2; + pp = &p2->u.pNext; + p2 = p2->u.pNext; + bCached = 0; + if( p2==0 ){ + *pp = p1; + break; + } + } + } + return pFinal; +} + +/* +** Return the SorterCompare function to compare values collected by the +** sorter object passed as the only argument. +*/ +static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ + if( p->typeMask==SORTER_TYPE_INTEGER ){ + return vdbeSorterCompareInt; + }else if( p->typeMask==SORTER_TYPE_TEXT ){ + return vdbeSorterCompareText; + } + return vdbeSorterCompare; +} + +/* +** Sort the linked list of records headed at pTask->pList. Return +** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if +** an error occurs. +*/ +static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ + int i; + SorterRecord *p; + int rc; + SorterRecord *aSlot[64]; + + rc = vdbeSortAllocUnpacked(pTask); + if( rc!=SQLITE_OK ) return rc; + + p = pList->pList; + pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter); + memset(aSlot, 0, sizeof(aSlot)); + + while( p ){ + SorterRecord *pNext; + if( pList->aMemory ){ + if( (u8*)p==pList->aMemory ){ + pNext = 0; + }else{ + assert( p->u.iNextaMemory) ); + pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; + } + }else{ + pNext = p->u.pNext; + } + + p->u.pNext = 0; + for(i=0; aSlot[i]; i++){ + p = vdbeSorterMerge(pTask, p, aSlot[i]); + aSlot[i] = 0; + } + aSlot[i] = p; + p = pNext; + } + + p = 0; + for(i=0; ipList = p; + + assert( pTask->pUnpacked->errCode==SQLITE_OK + || pTask->pUnpacked->errCode==SQLITE_NOMEM + ); + return pTask->pUnpacked->errCode; +} + +/* +** Initialize a PMA-writer object. +*/ +static void vdbePmaWriterInit( + sqlite3_file *pFd, /* File handle to write to */ + PmaWriter *p, /* Object to populate */ + int nBuf, /* Buffer size */ + i64 iStart /* Offset of pFd to begin writing at */ +){ + memset(p, 0, sizeof(PmaWriter)); + p->aBuffer = (u8*)sqlite3Malloc(nBuf); + if( !p->aBuffer ){ + p->eFWErr = SQLITE_NOMEM_BKPT; + }else{ + p->iBufEnd = p->iBufStart = (iStart % nBuf); + p->iWriteOff = iStart - p->iBufStart; + p->nBuffer = nBuf; + p->pFd = pFd; + } +} + +/* +** Write nData bytes of data to the PMA. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ + int nRem = nData; + while( nRem>0 && p->eFWErr==0 ){ + int nCopy = nRem; + if( nCopy>(p->nBuffer - p->iBufEnd) ){ + nCopy = p->nBuffer - p->iBufEnd; + } + + memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); + p->iBufEnd += nCopy; + if( p->iBufEnd==p->nBuffer ){ + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + p->iBufStart = p->iBufEnd = 0; + p->iWriteOff += p->nBuffer; + } + assert( p->iBufEndnBuffer ); + + nRem -= nCopy; + } +} + +/* +** Flush any buffered data to disk and clean up the PMA-writer object. +** The results of using the PMA-writer after this call are undefined. +** Return SQLITE_OK if flushing the buffered data succeeds or is not +** required. Otherwise, return an SQLite error code. +** +** Before returning, set *piEof to the offset immediately following the +** last byte written to the file. +*/ +static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ + int rc; + if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + } + *piEof = (p->iWriteOff + p->iBufEnd); + sqlite3_free(p->aBuffer); + rc = p->eFWErr; + memset(p, 0, sizeof(PmaWriter)); + return rc; +} + +/* +** Write value iVal encoded as a varint to the PMA. Return +** SQLITE_OK if successful, or an SQLite error code if an error occurs. +*/ +static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ + int nByte; + u8 aByte[10]; + nByte = sqlite3PutVarint(aByte, iVal); + vdbePmaWriteBlob(p, aByte, nByte); +} + +/* +** Write the current contents of in-memory linked-list pList to a level-0 +** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if +** successful, or an SQLite error code otherwise. +** +** The format of a PMA is: +** +** * A varint. This varint contains the total number of bytes of content +** in the PMA (not including the varint itself). +** +** * One or more records packed end-to-end in order of ascending keys. +** Each record consists of a varint followed by a blob of data (the +** key). The varint is the number of bytes in the blob of data. +*/ +static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ + sqlite3 *db = pTask->pSorter->db; + int rc = SQLITE_OK; /* Return code */ + PmaWriter writer; /* Object used to write to the file */ + +#ifdef SQLITE_DEBUG + /* Set iSz to the expected size of file pTask->file after writing the PMA. + ** This is used by an assert() statement at the end of this function. */ + i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; +#endif + + vdbeSorterWorkDebug(pTask, "enter"); + memset(&writer, 0, sizeof(PmaWriter)); + assert( pList->szPMA>0 ); + + /* If the first temporary PMA file has not been opened, open it now. */ + if( pTask->file.pFd==0 ){ + rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd); + assert( rc!=SQLITE_OK || pTask->file.pFd ); + assert( pTask->file.iEof==0 ); + assert( pTask->nPMA==0 ); + } + + /* Try to get the file to memory map */ + if( rc==SQLITE_OK ){ + vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9); + } + + /* Sort the list */ + if( rc==SQLITE_OK ){ + rc = vdbeSorterSort(pTask, pList); + } + + if( rc==SQLITE_OK ){ + SorterRecord *p; + SorterRecord *pNext = 0; + + vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz, + pTask->file.iEof); + pTask->nPMA++; + vdbePmaWriteVarint(&writer, pList->szPMA); + for(p=pList->pList; p; p=pNext){ + pNext = p->u.pNext; + vdbePmaWriteVarint(&writer, p->nVal); + vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal); + if( pList->aMemory==0 ) sqlite3_free(p); + } + pList->pList = p; + rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof); + } + + vdbeSorterWorkDebug(pTask, "exit"); + assert( rc!=SQLITE_OK || pList->pList==0 ); + assert( rc!=SQLITE_OK || pTask->file.iEof==iSz ); + return rc; +} + +/* +** Advance the MergeEngine to its next entry. +** Set *pbEof to true there is no next entry because +** the MergeEngine has reached the end of all its inputs. +** +** Return SQLITE_OK if successful or an error code if an error occurs. +*/ +static int vdbeMergeEngineStep( + MergeEngine *pMerger, /* The merge engine to advance to the next row */ + int *pbEof /* Set TRUE at EOF. Set false for more content */ +){ + int rc; + int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */ + SortSubtask *pTask = pMerger->pTask; + + /* Advance the current PmaReader */ + rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]); + + /* Update contents of aTree[] */ + if( rc==SQLITE_OK ){ + int i; /* Index of aTree[] to recalculate */ + PmaReader *pReadr1; /* First PmaReader to compare */ + PmaReader *pReadr2; /* Second PmaReader to compare */ + int bCached = 0; + + /* Find the first two PmaReaders to compare. The one that was just + ** advanced (iPrev) and the one next to it in the array. */ + pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; + pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; + + for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ + /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ + int iRes; + if( pReadr1->pFd==0 ){ + iRes = +1; + }else if( pReadr2->pFd==0 ){ + iRes = -1; + }else{ + iRes = pTask->xCompare(pTask, &bCached, + pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey + ); + } + + /* If pReadr1 contained the smaller value, set aTree[i] to its index. + ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this + ** case there is no cache of pReadr2 in pTask->pUnpacked, so set + ** pKey2 to point to the record belonging to pReadr2. + ** + ** Alternatively, if pReadr2 contains the smaller of the two values, + ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare() + ** was actually called above, then pTask->pUnpacked now contains + ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent + ** vdbeSorterCompare() from decoding pReadr2 again. + ** + ** If the two values were equal, then the value from the oldest + ** PMA should be considered smaller. The VdbeSorter.aReadr[] array + ** is sorted from oldest to newest, so pReadr1 contains older values + ** than pReadr2 iff (pReadr1aTree[i] = (int)(pReadr1 - pMerger->aReadr); + pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; + bCached = 0; + }else{ + if( pReadr1->pFd ) bCached = 0; + pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); + pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; + } + } + *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0); + } + + return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc); +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for background threads that write level-0 PMAs. +*/ +static void *vdbeSorterFlushThread(void *pCtx){ + SortSubtask *pTask = (SortSubtask*)pCtx; + int rc; /* Return code */ + assert( pTask->bDone==0 ); + rc = vdbeSorterListToPMA(pTask, &pTask->list); + pTask->bDone = 1; + return SQLITE_INT_TO_PTR(rc); +} +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + +/* +** Flush the current contents of VdbeSorter.list to a new PMA, possibly +** using a background thread. +*/ +static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ +#if SQLITE_MAX_WORKER_THREADS==0 + pSorter->bUsePMA = 1; + return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list); +#else + int rc = SQLITE_OK; + int i; + SortSubtask *pTask = 0; /* Thread context used to create new PMA */ + int nWorker = (pSorter->nTask-1); + + /* Set the flag to indicate that at least one PMA has been written. + ** Or will be, anyhow. */ + pSorter->bUsePMA = 1; + + /* Select a sub-task to sort and flush the current list of in-memory + ** records to disk. If the sorter is running in multi-threaded mode, + ** round-robin between the first (pSorter->nTask-1) tasks. Except, if + ** the background thread from a sub-tasks previous turn is still running, + ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, + ** fall back to using the final sub-task. The first (pSorter->nTask-1) + ** sub-tasks are preferred as they use background threads - the final + ** sub-task uses the main thread. */ + for(i=0; iiPrev + i + 1) % nWorker; + pTask = &pSorter->aTask[iTest]; + if( pTask->bDone ){ + rc = vdbeSorterJoinThread(pTask); + } + if( rc!=SQLITE_OK || pTask->pThread==0 ) break; + } + + if( rc==SQLITE_OK ){ + if( i==nWorker ){ + /* Use the foreground thread for this operation */ + rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); + }else{ + /* Launch a background thread for this operation */ + u8 *aMem; + void *pCtx; + + assert( pTask!=0 ); + assert( pTask->pThread==0 && pTask->bDone==0 ); + assert( pTask->list.pList==0 ); + assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 ); + + aMem = pTask->list.aMemory; + pCtx = (void*)pTask; + pSorter->iPrev = (u8)(pTask - pSorter->aTask); + pTask->list = pSorter->list; + pSorter->list.pList = 0; + pSorter->list.szPMA = 0; + if( aMem ){ + pSorter->list.aMemory = aMem; + pSorter->nMemory = sqlite3MallocSize(aMem); + }else if( pSorter->list.aMemory ){ + pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory); + if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT; + } + + rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx); + } + } + + return rc; +#endif /* SQLITE_MAX_WORKER_THREADS!=0 */ +} + +/* +** Add a record to the sorter. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( + const VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal /* Memory cell containing record */ +){ + VdbeSorter *pSorter; + int rc = SQLITE_OK; /* Return Code */ + SorterRecord *pNew; /* New list element */ + int bFlush; /* True to flush contents of memory to PMA */ + i64 nReq; /* Bytes of memory required */ + i64 nPMA; /* Bytes of PMA space required */ + int t; /* serial type of first record field */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + getVarint32NR((const u8*)&pVal->z[1], t); + if( t>0 && t<10 && t!=7 ){ + pSorter->typeMask &= SORTER_TYPE_INTEGER; + }else if( t>10 && (t & 0x01) ){ + pSorter->typeMask &= SORTER_TYPE_TEXT; + }else{ + pSorter->typeMask = 0; + } + + assert( pSorter ); + + /* Figure out whether or not the current contents of memory should be + ** flushed to a PMA before continuing. If so, do so. + ** + ** If using the single large allocation mode (pSorter->aMemory!=0), then + ** flush the contents of memory to a new PMA if (a) at least one value is + ** already in memory and (b) the new value will not fit in memory. + ** + ** Or, if using separate allocations for each record, flush the contents + ** of memory to a PMA if either of the following are true: + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * cache-size), or + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. + */ + nReq = pVal->n + sizeof(SorterRecord); + nPMA = pVal->n + sqlite3VarintLen(pVal->n); + if( pSorter->mxPmaSize ){ + if( pSorter->list.aMemory ){ + bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize; + }else{ + bFlush = ( + (pSorter->list.szPMA > pSorter->mxPmaSize) + || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull()) + ); + } + if( bFlush ){ + rc = vdbeSorterFlushPMA(pSorter); + pSorter->list.szPMA = 0; + pSorter->iMemory = 0; + assert( rc!=SQLITE_OK || pSorter->list.pList==0 ); + } + } + + pSorter->list.szPMA += nPMA; + if( nPMA>pSorter->mxKeysize ){ + pSorter->mxKeysize = nPMA; + } + + if( pSorter->list.aMemory ){ + int nMin = pSorter->iMemory + nReq; + + if( nMin>pSorter->nMemory ){ + u8 *aNew; + sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory; + int iListOff = -1; + if( pSorter->list.pList ){ + iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; + } + while( nNew < nMin ) nNew = nNew*2; + if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; + if( nNew < nMin ) nNew = nMin; + aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); + if( !aNew ) return SQLITE_NOMEM_BKPT; + if( iListOff>=0 ){ + pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; + } + pSorter->list.aMemory = aNew; + pSorter->nMemory = nNew; + } + + pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; + pSorter->iMemory += ROUND8(nReq); + if( pSorter->list.pList ){ + pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); + } + }else{ + pNew = (SorterRecord *)sqlite3Malloc(nReq); + if( pNew==0 ){ + return SQLITE_NOMEM_BKPT; + } + pNew->u.pNext = pSorter->list.pList; + } + + memcpy(SRVAL(pNew), pVal->z, pVal->n); + pNew->nVal = pVal->n; + pSorter->list.pList = pNew; + + return rc; +} + +/* +** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format +** of the data stored in aFile[1] is the same as that used by regular PMAs, +** except that the number-of-bytes varint is omitted from the start. +*/ +static int vdbeIncrPopulate(IncrMerger *pIncr){ + int rc = SQLITE_OK; + int rc2; + i64 iStart = pIncr->iStartOff; + SorterFile *pOut = &pIncr->aFile[1]; + SortSubtask *pTask = pIncr->pTask; + MergeEngine *pMerger = pIncr->pMerger; + PmaWriter writer; + assert( pIncr->bEof==0 ); + + vdbeSorterPopulateDebug(pTask, "enter"); + + vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart); + while( rc==SQLITE_OK ){ + int dummy; + PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ]; + int nKey = pReader->nKey; + i64 iEof = writer.iWriteOff + writer.iBufEnd; + + /* Check if the output file is full or if the input has been exhausted. + ** In either case exit the loop. */ + if( pReader->pFd==0 ) break; + if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; + + /* Write the next key to the output. */ + vdbePmaWriteVarint(&writer, nKey); + vdbePmaWriteBlob(&writer, pReader->aKey, nKey); + assert( pIncr->pMerger->pTask==pTask ); + rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy); + } + + rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof); + if( rc==SQLITE_OK ) rc = rc2; + vdbeSorterPopulateDebug(pTask, "exit"); + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for background threads that populate aFile[1] of +** multi-threaded IncrMerger objects. +*/ +static void *vdbeIncrPopulateThread(void *pCtx){ + IncrMerger *pIncr = (IncrMerger*)pCtx; + void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) ); + pIncr->pTask->bDone = 1; + return pRet; +} + +/* +** Launch a background thread to populate aFile[1] of pIncr. +*/ +static int vdbeIncrBgPopulate(IncrMerger *pIncr){ + void *p = (void*)pIncr; + assert( pIncr->bUseThread ); + return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p); +} +#endif + +/* +** This function is called when the PmaReader corresponding to pIncr has +** finished reading the contents of aFile[0]. Its purpose is to "refill" +** aFile[0] such that the PmaReader should start rereading it from the +** beginning. +** +** For single-threaded objects, this is accomplished by literally reading +** keys from pIncr->pMerger and repopulating aFile[0]. +** +** For multi-threaded objects, all that is required is to wait until the +** background thread is finished (if it is not already) and then swap +** aFile[0] and aFile[1] in place. If the contents of pMerger have not +** been exhausted, this function also launches a new background thread +** to populate the new aFile[1]. +** +** SQLITE_OK is returned on success, or an SQLite error code otherwise. +*/ +static int vdbeIncrSwap(IncrMerger *pIncr){ + int rc = SQLITE_OK; + +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + rc = vdbeSorterJoinThread(pIncr->pTask); + + if( rc==SQLITE_OK ){ + SorterFile f0 = pIncr->aFile[0]; + pIncr->aFile[0] = pIncr->aFile[1]; + pIncr->aFile[1] = f0; + } + + if( rc==SQLITE_OK ){ + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ + pIncr->bEof = 1; + }else{ + rc = vdbeIncrBgPopulate(pIncr); + } + } + }else +#endif + { + rc = vdbeIncrPopulate(pIncr); + pIncr->aFile[0] = pIncr->aFile[1]; + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ + pIncr->bEof = 1; + } + } + + return rc; +} + +/* +** Allocate and return a new IncrMerger object to read data from pMerger. +** +** If an OOM condition is encountered, return NULL. In this case free the +** pMerger argument before returning. +*/ +static int vdbeIncrMergerNew( + SortSubtask *pTask, /* The thread that will be using the new IncrMerger */ + MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */ + IncrMerger **ppOut /* Write the new IncrMerger here */ +){ + int rc = SQLITE_OK; + IncrMerger *pIncr = *ppOut = (IncrMerger*) + (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr))); + if( pIncr ){ + pIncr->pMerger = pMerger; + pIncr->pTask = pTask; + pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2); + pTask->file2.iEof += pIncr->mxSz; + }else{ + vdbeMergeEngineFree(pMerger); + rc = SQLITE_NOMEM_BKPT; + } + assert( *ppOut!=0 || rc!=SQLITE_OK ); + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** Set the "use-threads" flag on object pIncr. +*/ +static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){ + pIncr->bUseThread = 1; + pIncr->pTask->file2.iEof -= pIncr->mxSz; +} +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + + + +/* +** Recompute pMerger->aTree[iOut] by comparing the next keys on the +** two PmaReaders that feed that entry. Neither of the PmaReaders +** are advanced. This routine merely does the comparison. +*/ +static void vdbeMergeEngineCompare( + MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */ + int iOut /* Store the result in pMerger->aTree[iOut] */ +){ + int i1; + int i2; + int iRes; + PmaReader *p1; + PmaReader *p2; + + assert( iOutnTree && iOut>0 ); + + if( iOut>=(pMerger->nTree/2) ){ + i1 = (iOut - pMerger->nTree/2) * 2; + i2 = i1 + 1; + }else{ + i1 = pMerger->aTree[iOut*2]; + i2 = pMerger->aTree[iOut*2+1]; + } + + p1 = &pMerger->aReadr[i1]; + p2 = &pMerger->aReadr[i2]; + + if( p1->pFd==0 ){ + iRes = i2; + }else if( p2->pFd==0 ){ + iRes = i1; + }else{ + SortSubtask *pTask = pMerger->pTask; + int bCached = 0; + int res; + assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ + res = pTask->xCompare( + pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey + ); + if( res<=0 ){ + iRes = i1; + }else{ + iRes = i2; + } + } + + pMerger->aTree[iOut] = iRes; +} + +/* +** Allowed values for the eMode parameter to vdbeMergeEngineInit() +** and vdbePmaReaderIncrMergeInit(). +** +** Only INCRINIT_NORMAL is valid in single-threaded builds (when +** SQLITE_MAX_WORKER_THREADS==0). The other values are only used +** when there exists one or more separate worker threads. +*/ +#define INCRINIT_NORMAL 0 +#define INCRINIT_TASK 1 +#define INCRINIT_ROOT 2 + +/* +** Forward reference required as the vdbeIncrMergeInit() and +** vdbePmaReaderIncrInit() routines are called mutually recursively when +** building a merge tree. +*/ +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode); + +/* +** Initialize the MergeEngine object passed as the second argument. Once this +** function returns, the first key of merged data may be read from the +** MergeEngine object in the usual fashion. +** +** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge +** objects attached to the PmaReader objects that the merger reads from have +** already been populated, but that they have not yet populated aFile[0] and +** set the PmaReader objects up to read from it. In this case all that is +** required is to call vdbePmaReaderNext() on each PmaReader to point it at +** its first key. +** +** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use +** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data +** to pMerger. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbeMergeEngineInit( + SortSubtask *pTask, /* Thread that will run pMerger */ + MergeEngine *pMerger, /* MergeEngine to initialize */ + int eMode /* One of the INCRINIT_XXX constants */ +){ + int rc = SQLITE_OK; /* Return code */ + int i; /* For looping over PmaReader objects */ + int nTree; /* Number of subtrees to merge */ + + /* Failure to allocate the merge would have been detected prior to + ** invoking this routine */ + assert( pMerger!=0 ); + + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); + + /* Verify that the MergeEngine is assigned to a single thread */ + assert( pMerger->pTask==0 ); + pMerger->pTask = pTask; + + nTree = pMerger->nTree; + for(i=0; i0 && eMode==INCRINIT_ROOT ){ + /* PmaReaders should be normally initialized in order, as if they are + ** reading from the same temp file this makes for more linear file IO. + ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is + ** in use it will block the vdbePmaReaderNext() call while it uses + ** the main thread to fill its buffer. So calling PmaReaderNext() + ** on this PmaReader before any of the multi-threaded PmaReaders takes + ** better advantage of multi-processor hardware. */ + rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); + }else{ + rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL); + } + if( rc!=SQLITE_OK ) return rc; + } + + for(i=pMerger->nTree-1; i>0; i--){ + vdbeMergeEngineCompare(pMerger, i); + } + return pTask->pUnpacked->errCode; +} + +/* +** The PmaReader passed as the first argument is guaranteed to be an +** incremental-reader (pReadr->pIncr!=0). This function serves to open +** and/or initialize the temp file related fields of the IncrMerge +** object at (pReadr->pIncr). +** +** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders +** in the sub-tree headed by pReadr are also initialized. Data is then +** loaded into the buffers belonging to pReadr and it is set to point to +** the first key in its range. +** +** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed +** to be a multi-threaded PmaReader and this function is being called in a +** background thread. In this case all PmaReaders in the sub-tree are +** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to +** pReadr is populated. However, pReadr itself is not set up to point +** to its first key. A call to vdbePmaReaderNext() is still required to do +** that. +** +** The reason this function does not call vdbePmaReaderNext() immediately +** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has +** to block on thread (pTask->thread) before accessing aFile[1]. But, since +** this entire function is being run by thread (pTask->thread), that will +** lead to the current background thread attempting to join itself. +** +** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed +** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all +** child-trees have already been initialized using IncrInit(INCRINIT_TASK). +** In this case vdbePmaReaderNext() is called on all child PmaReaders and +** the current PmaReader set to point to the first key in its range. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ + int rc = SQLITE_OK; + IncrMerger *pIncr = pReadr->pIncr; + SortSubtask *pTask = pIncr->pTask; + sqlite3 *db = pTask->pSorter->db; + + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); + + rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); + + /* Set up the required files for pIncr. A multi-threaded IncrMerge object + ** requires two temp files to itself, whereas a single-threaded object + ** only requires a region of pTask->file2. */ + if( rc==SQLITE_OK ){ + int mxSz = pIncr->mxSz; +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); + if( rc==SQLITE_OK ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); + } + }else +#endif + /*if( !pIncr->bUseThread )*/{ + if( pTask->file2.pFd==0 ){ + assert( pTask->file2.iEof>0 ); + rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); + pTask->file2.iEof = 0; + } + if( rc==SQLITE_OK ){ + pIncr->aFile[1].pFd = pTask->file2.pFd; + pIncr->iStartOff = pTask->file2.iEof; + pTask->file2.iEof += mxSz; + } + } + } + +#if SQLITE_MAX_WORKER_THREADS>0 + if( rc==SQLITE_OK && pIncr->bUseThread ){ + /* Use the current thread to populate aFile[1], even though this + ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object, + ** then this function is already running in background thread + ** pIncr->pTask->thread. + ** + ** If this is the INCRINIT_ROOT object, then it is running in the + ** main VDBE thread. But that is Ok, as that thread cannot return + ** control to the VDBE or proceed with anything useful until the + ** first results are ready from this merger object anyway. + */ + assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); + rc = vdbeIncrPopulate(pIncr); + } +#endif + + if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){ + rc = vdbePmaReaderNext(pReadr); + } + + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for vdbePmaReaderIncrMergeInit() operations run in +** background threads. +*/ +static void *vdbePmaReaderBgIncrInit(void *pCtx){ + PmaReader *pReader = (PmaReader*)pCtx; + void *pRet = SQLITE_INT_TO_PTR( + vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) + ); + pReader->pIncr->pTask->bDone = 1; + return pRet; +} +#endif + +/* +** If the PmaReader passed as the first argument is not an incremental-reader +** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes +** the vdbePmaReaderIncrMergeInit() function with the parameters passed to +** this routine to initialize the incremental merge. +** +** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), +** then a background thread is launched to call vdbePmaReaderIncrMergeInit(). +** Or, if the IncrMerger is single threaded, the same function is called +** using the current thread. +*/ +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){ + IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */ + int rc = SQLITE_OK; /* Return code */ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK ); + if( pIncr->bUseThread ){ + void *pCtx = (void*)pReadr; + rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx); + }else +#endif + { + rc = vdbePmaReaderIncrMergeInit(pReadr, eMode); + } + } + return rc; +} + +/* +** Allocate a new MergeEngine object to merge the contents of nPMA level-0 +** PMAs from pTask->file. If no error occurs, set *ppOut to point to +** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut +** to NULL and return an SQLite error code. +** +** When this function is called, *piOffset is set to the offset of the +** first PMA to read from pTask->file. Assuming no error occurs, it is +** set to the offset immediately following the last byte of the last +** PMA before returning. If an error does occur, then the final value of +** *piOffset is undefined. +*/ +static int vdbeMergeEngineLevel0( + SortSubtask *pTask, /* Sorter task to read from */ + int nPMA, /* Number of PMAs to read */ + i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */ + MergeEngine **ppOut /* OUT: New merge-engine */ +){ + MergeEngine *pNew; /* Merge engine to return */ + i64 iOff = *piOffset; + int i; + int rc = SQLITE_OK; + + *ppOut = pNew = vdbeMergeEngineNew(nPMA); + if( pNew==0 ) rc = SQLITE_NOMEM_BKPT; + + for(i=0; iaReadr[i]; + rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy); + iOff = pReadr->iEof; + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pNew); + *ppOut = 0; + } + *piOffset = iOff; + return rc; +} + +/* +** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of +** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes. +** +** i.e. +** +** nPMA<=16 -> TreeDepth() == 0 +** nPMA<=256 -> TreeDepth() == 1 +** nPMA<=65536 -> TreeDepth() == 2 +*/ +static int vdbeSorterTreeDepth(int nPMA){ + int nDepth = 0; + i64 nDiv = SORTER_MAX_MERGE_COUNT; + while( nDiv < (i64)nPMA ){ + nDiv = nDiv * SORTER_MAX_MERGE_COUNT; + nDepth++; + } + return nDepth; +} + +/* +** pRoot is the root of an incremental merge-tree with depth nDepth (according +** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the +** tree, counting from zero. This function adds pLeaf to the tree. +** +** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error +** code is returned and pLeaf is freed. +*/ +static int vdbeSorterAddToTree( + SortSubtask *pTask, /* Task context */ + int nDepth, /* Depth of tree according to TreeDepth() */ + int iSeq, /* Sequence number of leaf within tree */ + MergeEngine *pRoot, /* Root of tree */ + MergeEngine *pLeaf /* Leaf to add to tree */ +){ + int rc = SQLITE_OK; + int nDiv = 1; + int i; + MergeEngine *p = pRoot; + IncrMerger *pIncr; + + rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr); + + for(i=1; iaReadr[iIter]; + + if( pReadr->pIncr==0 ){ + MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if( pNew==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr); + } + } + if( rc==SQLITE_OK ){ + p = pReadr->pIncr->pMerger; + nDiv = nDiv / SORTER_MAX_MERGE_COUNT; + } + } + + if( rc==SQLITE_OK ){ + p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr; + }else{ + vdbeIncrFree(pIncr); + } + return rc; +} + +/* +** This function is called as part of a SorterRewind() operation on a sorter +** that has already written two or more level-0 PMAs to one or more temp +** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that +** can be used to incrementally merge all PMAs on disk. +** +** If successful, SQLITE_OK is returned and *ppOut set to point to the +** MergeEngine object at the root of the tree before returning. Or, if an +** error occurs, an SQLite error code is returned and the final value +** of *ppOut is undefined. +*/ +static int vdbeSorterMergeTreeBuild( + VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */ + MergeEngine **ppOut /* Write the MergeEngine here */ +){ + MergeEngine *pMain = 0; + int rc = SQLITE_OK; + int iTask; + +#if SQLITE_MAX_WORKER_THREADS>0 + /* If the sorter uses more than one task, then create the top-level + ** MergeEngine here. This MergeEngine will read data from exactly + ** one PmaReader per sub-task. */ + assert( pSorter->bUseThreads || pSorter->nTask==1 ); + if( pSorter->nTask>1 ){ + pMain = vdbeMergeEngineNew(pSorter->nTask); + if( pMain==0 ) rc = SQLITE_NOMEM_BKPT; + } +#endif + + for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ + SortSubtask *pTask = &pSorter->aTask[iTask]; + assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 ); + if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){ + MergeEngine *pRoot = 0; /* Root node of tree for this task */ + int nDepth = vdbeSorterTreeDepth(pTask->nPMA); + i64 iReadOff = 0; + + if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){ + rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot); + }else{ + int i; + int iSeq = 0; + pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT; + for(i=0; inPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){ + MergeEngine *pMerger = 0; /* New level-0 PMA merger */ + int nReader; /* Number of level-0 PMAs to merge */ + + nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT); + rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger); + if( rc==SQLITE_OK ){ + rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger); + } + } + } + + if( rc==SQLITE_OK ){ +#if SQLITE_MAX_WORKER_THREADS>0 + if( pMain!=0 ){ + rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr); + }else +#endif + { + assert( pMain==0 ); + pMain = pRoot; + } + }else{ + vdbeMergeEngineFree(pRoot); + } + } + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pMain); + pMain = 0; + } + *ppOut = pMain; + return rc; +} + +/* +** This function is called as part of an sqlite3VdbeSorterRewind() operation +** on a sorter that has written two or more PMAs to temporary files. It sets +** up either VdbeSorter.pMerger (for single threaded sorters) or pReader +** (for multi-threaded sorters) so that it can be used to iterate through +** all records stored in the sorter. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ + int rc; /* Return code */ + SortSubtask *pTask0 = &pSorter->aTask[0]; + MergeEngine *pMain = 0; +#if SQLITE_MAX_WORKER_THREADS + sqlite3 *db = pTask0->pSorter->db; + int i; + SorterCompare xCompare = vdbeSorterGetCompare(pSorter); + for(i=0; inTask; i++){ + pSorter->aTask[i].xCompare = xCompare; + } +#endif + + rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); + if( rc==SQLITE_OK ){ +#if SQLITE_MAX_WORKER_THREADS + assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); + if( pSorter->bUseThreads ){ + int iTask; + PmaReader *pReadr = 0; + SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; + rc = vdbeSortAllocUnpacked(pLast); + if( rc==SQLITE_OK ){ + pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); + pSorter->pReader = pReadr; + if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT; + } + if( rc==SQLITE_OK ){ + rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr); + if( rc==SQLITE_OK ){ + vdbeIncrMergerSetThreads(pReadr->pIncr); + for(iTask=0; iTask<(pSorter->nTask-1); iTask++){ + IncrMerger *pIncr; + if( (pIncr = pMain->aReadr[iTask].pIncr) ){ + vdbeIncrMergerSetThreads(pIncr); + assert( pIncr->pTask!=pLast ); + } + } + for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ + /* Check that: + ** + ** a) The incremental merge object is configured to use the + ** right task, and + ** b) If it is using task (nTask-1), it is configured to run + ** in single-threaded mode. This is important, as the + ** root merge (INCRINIT_ROOT) will be using the same task + ** object. + */ + PmaReader *p = &pMain->aReadr[iTask]; + assert( p->pIncr==0 || ( + (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */ + && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */ + )); + rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK); + } + } + pMain = 0; + } + if( rc==SQLITE_OK ){ + rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT); + } + }else +#endif + { + rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL); + pSorter->pMerger = pMain; + pMain = 0; + } + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pMain); + } + return rc; +} + + +/* +** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, +** this function is called to prepare for iterating through the records +** in sorted order. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ + VdbeSorter *pSorter; + int rc = SQLITE_OK; /* Return code */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + assert( pSorter ); + + /* If no data has been written to disk, then do not do so now. Instead, + ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly + ** from the in-memory list. */ + if( pSorter->bUsePMA==0 ){ + if( pSorter->list.pList ){ + *pbEof = 0; + rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); + }else{ + *pbEof = 1; + } + return rc; + } + + /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() + ** function flushes the contents of memory to disk, it immediately always + ** creates a new list consisting of a single key immediately afterwards. + ** So the list is never empty at this point. */ + assert( pSorter->list.pList ); + rc = vdbeSorterFlushPMA(pSorter); + + /* Join all threads */ + rc = vdbeSorterJoinAll(pSorter, rc); + + vdbeSorterRewindDebug("rewind"); + + /* Assuming no errors have occurred, set up a merger structure to + ** incrementally read and merge all remaining PMAs. */ + assert( pSorter->pReader==0 ); + if( rc==SQLITE_OK ){ + rc = vdbeSorterSetupMerge(pSorter); + *pbEof = 0; + } + + vdbeSorterRewindDebug("rewinddone"); + return rc; +} + +/* +** Advance to the next element in the sorter. Return value: +** +** SQLITE_OK success +** SQLITE_DONE end of data +** otherwise some kind of error. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){ + VdbeSorter *pSorter; + int rc; /* Return code */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); + if( pSorter->bUsePMA ){ + assert( pSorter->pReader==0 || pSorter->pMerger==0 ); + assert( pSorter->bUseThreads==0 || pSorter->pReader ); + assert( pSorter->bUseThreads==1 || pSorter->pMerger ); +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->bUseThreads ){ + rc = vdbePmaReaderNext(pSorter->pReader); + if( rc==SQLITE_OK && pSorter->pReader->pFd==0 ) rc = SQLITE_DONE; + }else +#endif + /*if( !pSorter->bUseThreads )*/ { + int res = 0; + assert( pSorter->pMerger!=0 ); + assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); + rc = vdbeMergeEngineStep(pSorter->pMerger, &res); + if( rc==SQLITE_OK && res ) rc = SQLITE_DONE; + } + }else{ + SorterRecord *pFree = pSorter->list.pList; + pSorter->list.pList = pFree->u.pNext; + pFree->u.pNext = 0; + if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree); + rc = pSorter->list.pList ? SQLITE_OK : SQLITE_DONE; + } + return rc; +} + +/* +** Return a pointer to a buffer owned by the sorter that contains the +** current key. +*/ +static void *vdbeSorterRowkey( + const VdbeSorter *pSorter, /* Sorter object */ + int *pnKey /* OUT: Size of current key in bytes */ +){ + void *pKey; + if( pSorter->bUsePMA ){ + PmaReader *pReader; +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->bUseThreads ){ + pReader = pSorter->pReader; + }else +#endif + /*if( !pSorter->bUseThreads )*/{ + pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]]; + } + *pnKey = pReader->nKey; + pKey = pReader->aKey; + }else{ + *pnKey = pSorter->list.pList->nVal; + pKey = SRVAL(pSorter->list.pList); + } + return pKey; +} + +/* +** Copy the current sorter key into the memory cell pOut. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ + VdbeSorter *pSorter; + void *pKey; int nKey; /* Sorter key to copy into pOut */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + pKey = vdbeSorterRowkey(pSorter, &nKey); + if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ + return SQLITE_NOMEM_BKPT; + } + pOut->n = nKey; + MemSetTypeFlag(pOut, MEM_Blob); + memcpy(pOut->z, pKey, nKey); + + return SQLITE_OK; +} + +/* +** Compare the key in memory cell pVal with the key that the sorter cursor +** passed as the first argument currently points to. For the purposes of +** the comparison, ignore the rowid field at the end of each record. +** +** If the sorter cursor key contains any NULL values, consider it to be +** less than pVal. Even if pVal also contains NULL values. +** +** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). +** Otherwise, set *pRes to a negative, zero or positive value if the +** key in pVal is smaller than, equal to or larger than the current sorter +** key. +** +** This routine forms the core of the OP_SorterCompare opcode, which in +** turn is used to verify uniqueness when constructing a UNIQUE INDEX. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( + const VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal, /* Value to compare to current sorter key */ + int nKeyCol, /* Compare this many columns */ + int *pRes /* OUT: Result of comparison */ +){ + VdbeSorter *pSorter; + UnpackedRecord *r2; + KeyInfo *pKeyInfo; + int i; + void *pKey; int nKey; /* Sorter key to compare pVal with */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + r2 = pSorter->pUnpacked; + pKeyInfo = pCsr->pKeyInfo; + if( r2==0 ){ + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( r2==0 ) return SQLITE_NOMEM_BKPT; + r2->nField = nKeyCol; + } + assert( r2->nField==nKeyCol ); + + pKey = vdbeSorterRowkey(pSorter, &nKey); + sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); + for(i=0; iaMem[i].flags & MEM_Null ){ + *pRes = -1; + return SQLITE_OK; + } + } + + *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); + return SQLITE_OK; +} + +/************** End of vdbesort.c ********************************************/ +/************** Begin file vdbevtab.c ****************************************/ +/* +** 2020-03-23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements virtual-tables for examining the bytecode content +** of a prepared statement. +*/ +/* #include "sqliteInt.h" */ +#if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE) +/* #include "vdbeInt.h" */ + +/* An instance of the bytecode() table-valued function. +*/ +typedef struct bytecodevtab bytecodevtab; +struct bytecodevtab { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ + int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */ +}; + +/* A cursor for scanning through the bytecode +*/ +typedef struct bytecodevtab_cursor bytecodevtab_cursor; +struct bytecodevtab_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */ + int iRowid; /* The rowid of the output table */ + int iAddr; /* Address */ + int needFinalize; /* Cursors owns pStmt and must finalize it */ + int showSubprograms; /* Provide a listing of subprograms */ + Op *aOp; /* Operand array */ + char *zP4; /* Rendered P4 value */ + const char *zType; /* tables_used.type */ + const char *zSchema; /* tables_used.schema */ + const char *zName; /* tables_used.name */ + Mem sub; /* Subprograms */ +}; + +/* +** Create a new bytecode() table-valued function. +*/ +static int bytecodevtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + bytecodevtab *pNew; + int rc; + int isTabUsed = pAux!=0; + const char *azSchema[2] = { + /* bytecode() schema */ + "CREATE TABLE x(" + "addr INT," + "opcode TEXT," + "p1 INT," + "p2 INT," + "p3 INT," + "p4 TEXT," + "p5 INT," + "comment TEXT," + "subprog TEXT," + "nexec INT," + "ncycle INT," + "stmt HIDDEN" + ");", + + /* Tables_used() schema */ + "CREATE TABLE x(" + "type TEXT," + "schema TEXT," + "name TEXT," + "wr INT," + "subprog TEXT," + "stmt HIDDEN" + ");" + }; + + (void)argc; + (void)argv; + (void)pzErr; + rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + pNew->bTablesUsed = isTabUsed*2; + } + return rc; +} + +/* +** This method is the destructor for bytecodevtab objects. +*/ +static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){ + bytecodevtab *p = (bytecodevtab*)pVtab; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Constructor for a new bytecodevtab_cursor object. +*/ +static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + bytecodevtab *pVTab = (bytecodevtab*)p; + bytecodevtab_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Clear all internal content from a bytecodevtab cursor. +*/ +static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){ + sqlite3_free(pCur->zP4); + pCur->zP4 = 0; + sqlite3VdbeMemRelease(&pCur->sub); + sqlite3VdbeMemSetNull(&pCur->sub); + if( pCur->needFinalize ){ + sqlite3_finalize(pCur->pStmt); + } + pCur->pStmt = 0; + pCur->needFinalize = 0; + pCur->zType = 0; + pCur->zSchema = 0; + pCur->zName = 0; +} + +/* +** Destructor for a bytecodevtab_cursor. +*/ +static int bytecodevtabClose(sqlite3_vtab_cursor *cur){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + bytecodevtabCursorClear(pCur); + sqlite3_free(pCur); + return SQLITE_OK; +} + + +/* +** Advance a bytecodevtab_cursor to its next row of output. +*/ +static int bytecodevtabNext(sqlite3_vtab_cursor *cur){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + bytecodevtab *pTab = (bytecodevtab*)cur->pVtab; + int rc; + if( pCur->zP4 ){ + sqlite3_free(pCur->zP4); + pCur->zP4 = 0; + } + if( pCur->zName ){ + pCur->zName = 0; + pCur->zType = 0; + pCur->zSchema = 0; + } + rc = sqlite3VdbeNextOpcode( + (Vdbe*)pCur->pStmt, + pCur->showSubprograms ? &pCur->sub : 0, + pTab->bTablesUsed, + &pCur->iRowid, + &pCur->iAddr, + &pCur->aOp); + if( rc!=SQLITE_OK ){ + sqlite3VdbeMemSetNull(&pCur->sub); + pCur->aOp = 0; + } + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int bytecodevtabEof(sqlite3_vtab_cursor *cur){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + return pCur->aOp==0; +} + +/* +** Return values of columns for the row at which the bytecodevtab_cursor +** is currently pointing. +*/ +static int bytecodevtabColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab; + Op *pOp = pCur->aOp + pCur->iAddr; + if( pVTab->bTablesUsed ){ + if( i==4 ){ + i = 8; + }else{ + if( i<=2 && pCur->zType==0 ){ + Schema *pSchema; + HashElem *k; + int iDb = pOp->p3; + Pgno iRoot = (Pgno)pOp->p2; + sqlite3 *db = pVTab->db; + pSchema = db->aDb[iDb].pSchema; + pCur->zSchema = db->aDb[iDb].zDbSName; + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + if( !IsVirtual(pTab) && pTab->tnum==iRoot ){ + pCur->zName = pTab->zName; + pCur->zType = "table"; + break; + } + } + if( pCur->zName==0 ){ + for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){ + Index *pIdx = (Index*)sqliteHashData(k); + if( pIdx->tnum==iRoot ){ + pCur->zName = pIdx->zName; + pCur->zType = "index"; + } + } + } + } + i += 20; + } + } + switch( i ){ + case 0: /* addr */ + sqlite3_result_int(ctx, pCur->iAddr); + break; + case 1: /* opcode */ + sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode), + -1, SQLITE_STATIC); + break; + case 2: /* p1 */ + sqlite3_result_int(ctx, pOp->p1); + break; + case 3: /* p2 */ + sqlite3_result_int(ctx, pOp->p2); + break; + case 4: /* p3 */ + sqlite3_result_int(ctx, pOp->p3); + break; + case 5: /* p4 */ + case 7: /* comment */ + if( pCur->zP4==0 ){ + pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp); + } + if( i==5 ){ + sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC); + }else{ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4); + sqlite3_result_text(ctx, zCom, -1, sqlite3_free); +#endif + } + break; + case 6: /* p5 */ + sqlite3_result_int(ctx, pOp->p5); + break; + case 8: { /* subprog */ + Op *aOp = pCur->aOp; + assert( aOp[0].opcode==OP_Init ); + assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 ); + if( pCur->iRowid==pCur->iAddr+1 ){ + break; /* Result is NULL for the main program */ + }else if( aOp[0].p4.z!=0 ){ + sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC); + } + break; + } + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + case 9: /* nexec */ + sqlite3_result_int(ctx, pOp->nExec); + break; + case 10: /* ncycle */ + sqlite3_result_int(ctx, pOp->nCycle); + break; +#else + case 9: /* nexec */ + case 10: /* ncycle */ + sqlite3_result_int(ctx, 0); + break; +#endif + + case 20: /* tables_used.type */ + sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC); + break; + case 21: /* tables_used.schema */ + sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC); + break; + case 22: /* tables_used.name */ + sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC); + break; + case 23: /* tables_used.wr */ + sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite); + break; + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Initialize a cursor. +** +** idxNum==0 means show all subprograms +** idxNum==1 means show only the main bytecode and omit subprograms. +*/ +static int bytecodevtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; + bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; + int rc = SQLITE_OK; + (void)idxStr; + + bytecodevtabCursorClear(pCur); + pCur->iRowid = 0; + pCur->iAddr = 0; + pCur->showSubprograms = idxNum==0; + assert( argc==1 ); + if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){ + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0); + pCur->needFinalize = 1; + } + }else{ + pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer"); + } + if( pCur->pStmt==0 ){ + pVTab->base.zErrMsg = sqlite3_mprintf( + "argument to %s() is not a valid SQL statement", + pVTab->bTablesUsed ? "tables_used" : "bytecode" + ); + rc = SQLITE_ERROR; + }else{ + bytecodevtabNext(pVtabCursor); + } + return rc; +} + +/* +** We must have a single stmt=? constraint that will be passed through +** into the xFilter method. If there is no valid stmt=? constraint, +** then return an SQLITE_CONSTRAINT error. +*/ +static int bytecodevtabBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; + int rc = SQLITE_CONSTRAINT; + struct sqlite3_index_constraint *p; + bytecodevtab *pVTab = (bytecodevtab*)tab; + int iBaseCol = pVTab->bTablesUsed ? 4 : 10; + pIdxInfo->estimatedCost = (double)100; + pIdxInfo->estimatedRows = 100; + pIdxInfo->idxNum = 0; + for(i=0, p=pIdxInfo->aConstraint; inConstraint; i++, p++){ + if( p->usable==0 ) continue; + if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){ + rc = SQLITE_OK; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + } + if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){ + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 1; + } + } + return rc; +} + +/* +** This following structure defines all the methods for the +** virtual table. +*/ +static sqlite3_module bytecodevtabModule = { + /* iVersion */ 0, + /* xCreate */ 0, + /* xConnect */ bytecodevtabConnect, + /* xBestIndex */ bytecodevtabBestIndex, + /* xDisconnect */ bytecodevtabDisconnect, + /* xDestroy */ 0, + /* xOpen */ bytecodevtabOpen, + /* xClose */ bytecodevtabClose, + /* xFilter */ bytecodevtabFilter, + /* xNext */ bytecodevtabNext, + /* xEof */ bytecodevtabEof, + /* xColumn */ bytecodevtabColumn, + /* xRowid */ bytecodevtabRowid, + /* xUpdate */ 0, + /* xBegin */ 0, + /* xSync */ 0, + /* xCommit */ 0, + /* xRollback */ 0, + /* xFindMethod */ 0, + /* xRename */ 0, + /* xSavepoint */ 0, + /* xRelease */ 0, + /* xRollbackTo */ 0, + /* xShadowName */ 0, + /* xIntegrity */ 0 +}; + + +SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ + int rc; + rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db); + } + return rc; +} +#elif defined(SQLITE_ENABLE_BYTECODE_VTAB) +SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; } +#endif /* SQLITE_ENABLE_BYTECODE_VTAB */ + +/************** End of vdbevtab.c ********************************************/ +/************** Begin file memjournal.c **************************************/ +/* +** 2008 October 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to implement an in-memory rollback journal. +** The in-memory rollback journal is used to journal transactions for +** ":memory:" databases and when the journal_mode=MEMORY pragma is used. +** +** Update: The in-memory journal is also used to temporarily cache +** smaller journals that are not critical for power-loss recovery. +** For example, statement journals that are not too big will be held +** entirely in memory, thus reducing the number of file I/O calls, and +** more importantly, reducing temporary file creation events. If these +** journals become too large for memory, they are spilled to disk. But +** in the common case, they are usually small and no file I/O needs to +** occur. +*/ +/* #include "sqliteInt.h" */ + +/* Forward references to internal structures */ +typedef struct MemJournal MemJournal; +typedef struct FilePoint FilePoint; +typedef struct FileChunk FileChunk; + +/* +** The rollback journal is composed of a linked list of these structures. +** +** The zChunk array is always at least 8 bytes in size - usually much more. +** Its actual size is stored in the MemJournal.nChunkSize variable. +*/ +struct FileChunk { + FileChunk *pNext; /* Next chunk in the journal */ + u8 zChunk[8]; /* Content of this chunk */ +}; + +/* +** By default, allocate this many bytes of memory for each FileChunk object. +*/ +#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024 + +/* +** For chunk size nChunkSize, return the number of bytes that should +** be allocated for each FileChunk structure. +*/ +#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8)) + +/* +** An instance of this object serves as a cursor into the rollback journal. +** The cursor can be either for reading or writing. +*/ +struct FilePoint { + sqlite3_int64 iOffset; /* Offset from the beginning of the file */ + FileChunk *pChunk; /* Specific chunk into which cursor points */ +}; + +/* +** This structure is a subclass of sqlite3_file. Each open memory-journal +** is an instance of this class. +*/ +struct MemJournal { + const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ + int nChunkSize; /* In-memory chunk-size */ + + int nSpill; /* Bytes of data before flushing */ + FileChunk *pFirst; /* Head of in-memory chunk-list */ + FilePoint endpoint; /* Pointer to the end of the file */ + FilePoint readpoint; /* Pointer to the end of the last xRead() */ + + int flags; /* xOpen flags */ + sqlite3_vfs *pVfs; /* The "real" underlying VFS */ + const char *zJournal; /* Name of the journal file */ +}; + +/* +** Read data from the in-memory journal file. This is the implementation +** of the sqlite3_vfs.xRead method. +*/ +static int memjrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + MemJournal *p = (MemJournal *)pJfd; + u8 *zOut = zBuf; + int nRead = iAmt; + int iChunkOffset; + FileChunk *pChunk; + + if( (iAmt+iOfst)>p->endpoint.iOffset ){ + return SQLITE_IOERR_SHORT_READ; + } + assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); + if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ + sqlite3_int64 iOff = 0; + for(pChunk=p->pFirst; + ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst; + pChunk=pChunk->pNext + ){ + iOff += p->nChunkSize; + } + }else{ + pChunk = p->readpoint.pChunk; + assert( pChunk!=0 ); + } + + iChunkOffset = (int)(iOfst%p->nChunkSize); + do { + int iSpace = p->nChunkSize - iChunkOffset; + int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset)); + memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy); + zOut += nCopy; + nRead -= iSpace; + iChunkOffset = 0; + } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); + p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0; + p->readpoint.pChunk = pChunk; + + return SQLITE_OK; +} + +/* +** Free the list of FileChunk structures headed at MemJournal.pFirst. +*/ +static void memjrnlFreeChunks(FileChunk *pFirst){ + FileChunk *pIter; + FileChunk *pNext; + for(pIter=pFirst; pIter; pIter=pNext){ + pNext = pIter->pNext; + sqlite3_free(pIter); + } +} + +/* +** Flush the contents of memory to a real file on disk. +*/ +static int memjrnlCreateFile(MemJournal *p){ + int rc; + sqlite3_file *pReal = (sqlite3_file*)p; + MemJournal copy = *p; + + memset(p, 0, sizeof(MemJournal)); + rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0); + if( rc==SQLITE_OK ){ + int nChunk = copy.nChunkSize; + i64 iOff = 0; + FileChunk *pIter; + for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){ + if( iOff + nChunk > copy.endpoint.iOffset ){ + nChunk = copy.endpoint.iOffset - iOff; + } + rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff); + if( rc ) break; + iOff += nChunk; + } + if( rc==SQLITE_OK ){ + /* No error has occurred. Free the in-memory buffers. */ + memjrnlFreeChunks(copy.pFirst); + } + } + if( rc!=SQLITE_OK ){ + /* If an error occurred while creating or writing to the file, restore + ** the original before returning. This way, SQLite uses the in-memory + ** journal data to roll back changes made to the internal page-cache + ** before this function was called. */ + sqlite3OsClose(pReal); + *p = copy; + } + return rc; +} + + +/* Forward reference */ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size); + +/* +** Write data to the file. +*/ +static int memjrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + MemJournal *p = (MemJournal *)pJfd; + int nWrite = iAmt; + u8 *zWrite = (u8 *)zBuf; + + /* If the file should be created now, create it and write the new data + ** into the file on disk. */ + if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){ + int rc = memjrnlCreateFile(p); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst); + } + return rc; + } + + /* If the contents of this write should be stored in memory */ + else{ + /* An in-memory journal file should only ever be appended to. Random + ** access writes are not required. The only exception to this is when + ** the in-memory journal is being used by a connection using the + ** atomic-write optimization. In this case the first 28 bytes of the + ** journal file may be written as part of committing the transaction. */ + assert( iOfst<=p->endpoint.iOffset ); + if( iOfst>0 && iOfst!=p->endpoint.iOffset ){ + memjrnlTruncate(pJfd, iOfst); + } + if( iOfst==0 && p->pFirst ){ + assert( p->nChunkSize>iAmt ); + memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt); + }else{ + while( nWrite>0 ){ + FileChunk *pChunk = p->endpoint.pChunk; + int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize); + int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset); + + assert( pChunk!=0 || iChunkOffset==0 ); + if( iChunkOffset==0 ){ + /* New chunk is required to extend the file. */ + FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize)); + if( !pNew ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + pNew->pNext = 0; + if( pChunk ){ + assert( p->pFirst ); + pChunk->pNext = pNew; + }else{ + assert( !p->pFirst ); + p->pFirst = pNew; + } + pChunk = p->endpoint.pChunk = pNew; + } + + assert( pChunk!=0 ); + memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace); + zWrite += iSpace; + nWrite -= iSpace; + p->endpoint.iOffset += iSpace; + } + } + } + + return SQLITE_OK; +} + +/* +** Truncate the in-memory file. +*/ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + MemJournal *p = (MemJournal *)pJfd; + assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 ); + if( sizeendpoint.iOffset ){ + FileChunk *pIter = 0; + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOffpNext){ + iOff += p->nChunkSize; + } + if( ALWAYS(pIter) ){ + memjrnlFreeChunks(pIter->pNext); + pIter->pNext = 0; + } + } + + p->endpoint.pChunk = pIter; + p->endpoint.iOffset = size; + p->readpoint.pChunk = 0; + p->readpoint.iOffset = 0; + } + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int memjrnlClose(sqlite3_file *pJfd){ + MemJournal *p = (MemJournal *)pJfd; + memjrnlFreeChunks(p->pFirst); + return SQLITE_OK; +} + +/* +** Sync the file. +** +** If the real file has been created, call its xSync method. Otherwise, +** syncing an in-memory journal is a no-op. +*/ +static int memjrnlSync(sqlite3_file *pJfd, int flags){ + UNUSED_PARAMETER2(pJfd, flags); + return SQLITE_OK; +} + +/* +** Query the size of the file in bytes. +*/ +static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + MemJournal *p = (MemJournal *)pJfd; + *pSize = (sqlite_int64) p->endpoint.iOffset; + return SQLITE_OK; +} + +/* +** Table of methods for MemJournal sqlite3_file object. +*/ +static const struct sqlite3_io_methods MemJournalMethods = { + 1, /* iVersion */ + memjrnlClose, /* xClose */ + memjrnlRead, /* xRead */ + memjrnlWrite, /* xWrite */ + memjrnlTruncate, /* xTruncate */ + memjrnlSync, /* xSync */ + memjrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/* +** Open a journal file. +** +** The behaviour of the journal file depends on the value of parameter +** nSpill. If nSpill is 0, then the journal file is always create and +** accessed using the underlying VFS. If nSpill is less than zero, then +** all content is always stored in main-memory. Finally, if nSpill is a +** positive value, then the journal file is initially created in-memory +** but may be flushed to disk later on. In this case the journal file is +** flushed to disk either when it grows larger than nSpill bytes in size, +** or when sqlite3JournalCreate() is called. +*/ +SQLITE_PRIVATE int sqlite3JournalOpen( + sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ + const char *zName, /* Name of the journal file */ + sqlite3_file *pJfd, /* Preallocated, blank file handle */ + int flags, /* Opening flags */ + int nSpill /* Bytes buffered before opening the file */ +){ + MemJournal *p = (MemJournal*)pJfd; + + assert( zName || nSpill<0 || (flags & SQLITE_OPEN_EXCLUSIVE) ); + + /* Zero the file-handle object. If nSpill was passed zero, initialize + ** it using the sqlite3OsOpen() function of the underlying VFS. In this + ** case none of the code in this module is executed as a result of calls + ** made on the journal file-handle. */ + memset(p, 0, sizeof(MemJournal)); + if( nSpill==0 ){ + return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); + } + + if( nSpill>0 ){ + p->nChunkSize = nSpill; + }else{ + p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk); + assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) ); + } + + pJfd->pMethods = (const sqlite3_io_methods*)&MemJournalMethods; + p->nSpill = nSpill; + p->flags = flags; + p->zJournal = zName; + p->pVfs = pVfs; + return SQLITE_OK; +} + +/* +** Open an in-memory journal file. +*/ +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){ + sqlite3JournalOpen(0, 0, pJfd, 0, -1); +} + +#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ + || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +/* +** If the argument p points to a MemJournal structure that is not an +** in-memory-only journal file (i.e. is one that was opened with a +ve +** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying +** file has not yet been created, create it now. +*/ +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){ + int rc = SQLITE_OK; + MemJournal *p = (MemJournal*)pJfd; + if( pJfd->pMethods==&MemJournalMethods && ( +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + p->nSpill>0 +#else + /* While this appears to not be possible without ATOMIC_WRITE, the + ** paths are complex, so it seems prudent to leave the test in as + ** a NEVER(), in case our analysis is subtly flawed. */ + NEVER(p->nSpill>0) +#endif +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + || (p->flags & SQLITE_OPEN_MAIN_JOURNAL) +#endif + )){ + rc = memjrnlCreateFile(p); + } + return rc; +} +#endif + +/* +** The file-handle passed as the only argument is open on a journal file. +** Return true if this "journal file" is currently stored in heap memory, +** or false otherwise. +*/ +SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){ + return p->pMethods==&MemJournalMethods; +} + +/* +** Return the number of bytes required to store a JournalFile that uses vfs +** pVfs to create the underlying on-disk files. +*/ +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ + return MAX(pVfs->szOsFile, (int)sizeof(MemJournal)); +} + +/************** End of memjournal.c ******************************************/ +/************** Begin file walker.c ******************************************/ +/* +** 2008 August 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used for walking the parser tree for +** an SQL statement. +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include */ + + +#if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** Walk all expressions linked into the list of Window objects passed +** as the second argument. +*/ +static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ + Window *pWin; + for(pWin=pList; pWin; pWin=pWin->pNextWin){ + int rc; + rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExprList(pWalker, pWin->pPartition); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExpr(pWalker, pWin->pFilter); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExpr(pWalker, pWin->pStart); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExpr(pWalker, pWin->pEnd); + if( rc ) return WRC_Abort; + if( bOneOnly ) break; + } + return WRC_Continue; +} +#endif + +/* +** Walk an expression tree. Invoke the callback once for each node +** of the expression, while descending. (In other words, the callback +** is invoked before visiting children.) +** +** The return value from the callback should be one of the WRC_* +** constants to specify how to proceed with the walk. +** +** WRC_Continue Continue descending down the tree. +** +** WRC_Prune Do not descend into child nodes, but allow +** the walk to continue with sibling nodes. +** +** WRC_Abort Do no more callbacks. Unwind the stack and +** return from the top-level walk call. +** +** The return value from this routine is WRC_Abort to abandon the tree walk +** and WRC_Continue to continue. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExpr){ + int rc; + testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); + testcase( ExprHasProperty(pExpr, EP_Reduced) ); + while(1){ + rc = pWalker->xExprCallback(pWalker, pExpr); + if( rc ) return rc & WRC_Abort; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + assert( pExpr->x.pList==0 || pExpr->pRight==0 ); + if( pExpr->pLeft && sqlite3WalkExprNN(pWalker, pExpr->pLeft) ){ + return WRC_Abort; + } + if( pExpr->pRight ){ + assert( !ExprHasProperty(pExpr, EP_WinFunc) ); + pExpr = pExpr->pRight; + continue; + }else if( ExprUseXSelect(pExpr) ){ + assert( !ExprHasProperty(pExpr, EP_WinFunc) ); + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + }else{ + if( pExpr->x.pList ){ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + if( walkWindowList(pWalker, pExpr->y.pWin, 1) ) return WRC_Abort; + } +#endif + } + } + break; + } + return WRC_Continue; +} +SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ + return pExpr ? sqlite3WalkExprNN(pWalker,pExpr) : WRC_Continue; +} + +/* +** Call sqlite3WalkExpr() for every expression in list p or until +** an abort request is seen. +*/ +SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ + int i; + struct ExprList_item *pItem; + if( p ){ + for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ + if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** This is a no-op callback for Walker->xSelectCallback2. If this +** callback is set, then the Select->pWinDefn list is traversed. +*/ +SQLITE_PRIVATE void sqlite3WalkWinDefnDummyCallback(Walker *pWalker, Select *p){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(p); + /* No-op */ +} + +/* +** Walk all expressions associated with SELECT statement p. Do +** not invoke the SELECT callback on p, but do (of course) invoke +** any expr callbacks and SELECT callbacks that come from subqueries. +** Return WRC_Abort or WRC_Continue. +*/ +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ + if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; +#if !defined(SQLITE_OMIT_WINDOWFUNC) + if( p->pWinDefn ){ + Parse *pParse; + if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback + || ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT) +#ifndef SQLITE_OMIT_CTE + || pWalker->xSelectCallback2==sqlite3SelectPopWith +#endif + ){ + /* The following may return WRC_Abort if there are unresolvable + ** symbols (e.g. a table that does not exist) in a window definition. */ + int rc = walkWindowList(pWalker, p->pWinDefn, 0); + return rc; + } + } +#endif + return WRC_Continue; +} + +/* +** Walk the parse trees associated with all subqueries in the +** FROM clause of SELECT statement p. Do not invoke the select +** callback on p, but do invoke it on each FROM clause subquery +** and on any subqueries further down in the tree. Return +** WRC_Abort or WRC_Continue; +*/ +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ + SrcList *pSrc; + int i; + SrcItem *pItem; + + pSrc = p->pSrc; + if( ALWAYS(pSrc) ){ + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + return WRC_Abort; + } + if( pItem->fg.isTabFunc + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + +/* +** Call sqlite3WalkExpr() for every expression in Select statement p. +** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and +** on the compound select chain, p->pPrior. +** +** If it is not NULL, the xSelectCallback() callback is invoked before +** the walk of the expressions and FROM clause. The xSelectCallback2() +** method is invoked following the walk of the expressions and FROM clause, +** but only if both xSelectCallback and xSelectCallback2 are both non-NULL +** and if the expressions and FROM clause both return WRC_Continue; +** +** Return WRC_Continue under normal conditions. Return WRC_Abort if +** there is an abort request. +** +** If the Walker does not have an xSelectCallback() then this routine +** is a no-op returning WRC_Continue. +*/ +SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ + int rc; + if( p==0 ) return WRC_Continue; + if( pWalker->xSelectCallback==0 ) return WRC_Continue; + do{ + rc = pWalker->xSelectCallback(pWalker, p); + if( rc ) return rc & WRC_Abort; + if( sqlite3WalkSelectExpr(pWalker, p) + || sqlite3WalkSelectFrom(pWalker, p) + ){ + return WRC_Abort; + } + if( pWalker->xSelectCallback2 ){ + pWalker->xSelectCallback2(pWalker, p); + } + p = p->pPrior; + }while( p!=0 ); + return WRC_Continue; +} + +/* Increase the walkerDepth when entering a subquery, and +** decrease when leaving the subquery. +*/ +SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ + UNUSED_PARAMETER(pSelect); + pWalker->walkerDepth++; + return WRC_Continue; +} +SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){ + UNUSED_PARAMETER(pSelect); + pWalker->walkerDepth--; +} + + +/* +** No-op routine for the parse-tree walker. +** +** When this routine is the Walker.xExprCallback then expression trees +** are walked without any actions being taken at each node. Presumably, +** when this routine is used for Walker.xExprCallback then +** Walker.xSelectCallback is set to do something useful for every +** subquery in the parser tree. +*/ +SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +/* +** No-op routine for the parse-tree walker for SELECT statements. +** subquery in the parser tree. +*/ +SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +/************** End of walker.c **********************************************/ +/************** Begin file resolve.c *****************************************/ +/* +** 2008 August 18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains routines used for walking the parser tree and +** resolve all identifiers by associating them with a particular +** table and column. +*/ +/* #include "sqliteInt.h" */ + +/* +** Magic table number to mean the EXCLUDED table in an UPSERT statement. +*/ +#define EXCLUDED_TABLE_NUMBER 2 + +/* +** Walk the expression tree pExpr and increase the aggregate function +** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. +** This needs to occur when copying a TK_AGG_FUNCTION node from an +** outer query into an inner subquery. +** +** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..) +** is a helper function - a callback for the tree walker. +** +** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c +*/ +static int incrAggDepth(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n; + return WRC_Continue; +} +static void incrAggFunctionDepth(Expr *pExpr, int N){ + if( N>0 ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = incrAggDepth; + w.u.n = N; + sqlite3WalkExpr(&w, pExpr); + } +} + +/* +** Turn the pExpr expression into an alias for the iCol-th column of the +** result set in pEList. +** +** If the reference is followed by a COLLATE operator, then make sure +** the COLLATE operator is preserved. For example: +** +** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase; +** +** Should be transformed into: +** +** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; +** +** The nSubquery parameter specifies how many levels of subquery the +** alias is removed from the original expression. The usual value is +** zero but it might be more if the alias is contained within a subquery +** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION +** structures must be increased by the nSubquery amount. +*/ +static void resolveAlias( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* A result set */ + int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ + Expr *pExpr, /* Transform this into an alias to the result set */ + int nSubquery /* Number of subqueries that the label is moving */ +){ + Expr *pOrig; /* The iCol-th column of the result set */ + Expr *pDup; /* Copy of pOrig */ + sqlite3 *db; /* The database connection */ + + assert( iCol>=0 && iColnExpr ); + pOrig = pEList->a[iCol].pExpr; + assert( pOrig!=0 ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); + if( pExpr->pAggInfo ) return; + db = pParse->db; + pDup = sqlite3ExprDup(db, pOrig, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + pDup = 0; + }else{ + Expr temp; + incrAggFunctionDepth(pDup, nSubquery); + if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); + } + memcpy(&temp, pDup, sizeof(Expr)); + memcpy(pDup, pExpr, sizeof(Expr)); + memcpy(pExpr, &temp, sizeof(Expr)); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + if( ALWAYS(pExpr->y.pWin!=0) ){ + pExpr->y.pWin->pOwner = pExpr; + } + } + sqlite3ExprDeferredDelete(pParse, pDup); + } +} + +/* +** Subqueries store the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN", +** and mark the expression-list item by setting ExprList.a[].fg.eEName +** to ENAME_TAB. +** +** Check to see if the zSpan/eEName of the expression-list item passed to this +** routine matches the zDb, zTab, and zCol. If any of zDb, zTab, and zCol are +** NULL then those fields will match anything. Return true if there is a match, +** or false otherwise. +** +** SF_NestedFrom subqueries also store an entry for the implicit rowid (or +** _rowid_, or oid) column by setting ExprList.a[].fg.eEName to ENAME_ROWID, +** and setting zSpan to "DATABASE.TABLE.". This type of pItem +** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid) +** is set to 1 if there is this kind of match. +*/ +SQLITE_PRIVATE int sqlite3MatchEName( + const struct ExprList_item *pItem, + const char *zCol, + const char *zTab, + const char *zDb, + int *pbRowid +){ + int n; + const char *zSpan; + int eEName = pItem->fg.eEName; + if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || NEVER(pbRowid==0)) ){ + return 0; + } + assert( pbRowid==0 || *pbRowid==0 ); + zSpan = pItem->zEName; + for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} + if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ + return 0; + } + zSpan += n+1; + for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} + if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ + return 0; + } + zSpan += n+1; + if( zCol ){ + if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0; + if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; + } + if( eEName==ENAME_ROWID ) *pbRowid = 1; + return 1; +} + +/* +** Return TRUE if the double-quoted string mis-feature should be supported. +*/ +static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){ + if( db->init.busy ) return 1; /* Always support for legacy schemas */ + if( pTopNC->ncFlags & NC_IsDDL ){ + /* Currently parsing a DDL statement */ + if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){ + return 1; + } + return (db->flags & SQLITE_DqsDDL)!=0; + }else{ + /* Currently parsing a DML statement */ + return (db->flags & SQLITE_DqsDML)!=0; + } +} + +/* +** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN. +** return the appropriate colUsed mask. +*/ +SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ + int n; + Table *pExTab; + + n = pExpr->iColumn; + assert( ExprUseYTab(pExpr) ); + pExTab = pExpr->y.pTab; + assert( pExTab!=0 ); + assert( n < pExTab->nCol ); + if( (pExTab->tabFlags & TF_HasGenerated)!=0 + && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pExTab->nCol==BMS-1 ); + testcase( pExTab->nCol==BMS ); + return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1; + }else{ + testcase( n==BMS-1 ); + testcase( n==BMS ); + if( n>=BMS ) n = BMS-1; + return ((Bitmask)1)<db, TK_COLUMN, 0, 0); + if( pNew ){ + pNew->iTable = pMatch->iCursor; + pNew->iColumn = iColumn; + pNew->y.pTab = pMatch->pTab; + assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); + ExprSetProperty(pNew, EP_CanBeNull); + *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); + } +} + +/* +** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab. +*/ +static SQLITE_NOINLINE int isValidSchemaTableName( + const char *zTab, /* Name as it appears in the SQL */ + Table *pTab, /* The schema table we are trying to match */ + Schema *pSchema /* non-NULL if a database qualifier is present */ +){ + const char *zLegacy; + assert( pTab!=0 ); + assert( pTab->tnum==1 ); + if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0; + zLegacy = pTab->zName; + if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ + if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ + return 1; + } + if( pSchema==0 ) return 0; + if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; + if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; + }else{ + if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; + } + return 0; +} + +/* +** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up +** that name in the set of source tables in pSrcList and make the pExpr +** expression node refer back to that source column. The following changes +** are made to pExpr: +** +** pExpr->iDb Set the index in db->aDb[] of the database X +** (even if X is implied). +** pExpr->iTable Set to the cursor number for the table obtained +** from pSrcList. +** pExpr->y.pTab Points to the Table structure of X.Y (even if +** X and/or Y are implied.) +** pExpr->iColumn Set to the column number within the table. +** pExpr->op Set to TK_COLUMN. +** pExpr->pLeft Any expression this points to is deleted +** pExpr->pRight Any expression this points to is deleted. +** +** The zDb variable is the name of the database (the "X"). This value may be +** NULL meaning that name is of the form Y.Z or Z. Any available database +** can be used. The zTable variable is the name of the table (the "Y"). This +** value can be NULL if zDb is also NULL. If zTable is NULL it +** means that the form of the name is Z and that columns from any table +** can be used. +** +** If the name cannot be resolved unambiguously, leave an error message +** in pParse and return WRC_Abort. Return WRC_Prune on success. +*/ +static int lookupName( + Parse *pParse, /* The parsing context */ + const char *zDb, /* Name of the database containing table, or NULL */ + const char *zTab, /* Name of table containing column, or NULL */ + const char *zCol, /* Name of the column. */ + NameContext *pNC, /* The name context used to resolve the name */ + Expr *pExpr /* Make this EXPR node point to the selected column */ +){ + int i, j; /* Loop counters */ + int cnt = 0; /* Number of matching column names */ + int cntTab = 0; /* Number of potential "rowid" matches */ + int nSubquery = 0; /* How many levels of subquery */ + sqlite3 *db = pParse->db; /* The database connection */ + SrcItem *pItem; /* Use for looping over pSrcList items */ + SrcItem *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ + Schema *pSchema = 0; /* Schema of the expression */ + int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ + Table *pTab = 0; /* Table holding the row */ + Column *pCol; /* A column of pTab */ + ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ + + assert( pNC ); /* the name context cannot be NULL. */ + assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ + assert( zDb==0 || zTab!=0 ); + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + + /* Initialize the node to no-match */ + pExpr->iTable = -1; + ExprSetVVAProperty(pExpr, EP_NoReduce); + + /* Translate the schema name in zDb into a pointer to the corresponding + ** schema. If not found, pSchema will remain NULL and nothing will match + ** resulting in an appropriate error message toward the end of this routine + */ + if( zDb ){ + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IsCheck ); + if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ + /* Silently ignore database qualifiers inside CHECK constraints and + ** partial indices. Do not raise errors because that might break + ** legacy and because it does not hurt anything to just ignore the + ** database name. */ + zDb = 0; + }else{ + for(i=0; inDb; i++){ + assert( db->aDb[i].zDbSName ); + if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){ + pSchema = db->aDb[i].pSchema; + break; + } + } + if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){ + /* This branch is taken when the main database has been renamed + ** using SQLITE_DBCONFIG_MAINDBNAME. */ + pSchema = db->aDb[0].pSchema; + zDb = db->aDb[0].zDbSName; + } + } + } + + /* Start at the inner-most context and move outward until a match is found */ + assert( pNC && cnt==0 ); + do{ + ExprList *pEList; + SrcList *pSrcList = pNC->pSrcList; + + if( pSrcList ){ + for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + u8 hCol; + pTab = pItem->pTab; + assert( pTab!=0 && pTab->zName!=0 ); + assert( pTab->nCol>0 || pParse->nErr ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + if( pItem->fg.isNestedFrom ){ + /* In this case, pItem is a subquery that has been formed from a + ** parenthesized subset of the FROM clause terms. Example: + ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... + ** \_________________________/ + ** This pItem -------------^ + */ + int hit = 0; + assert( pItem->pSelect!=0 ); + pEList = pItem->pSelect->pEList; + assert( pEList!=0 ); + assert( pEList->nExpr==pTab->nCol ); + for(j=0; jnExpr; j++){ + int bRowid = 0; /* True if possible rowid match */ + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){ + continue; + } + if( bRowid==0 ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } + } + cnt++; + hit = 1; + }else if( cnt>0 ){ + /* This is a potential rowid match, but there has already been + ** a real match found. So this can be ignored. */ + continue; + } + cntTab++; + pMatch = pItem; + pExpr->iColumn = j; + pEList->a[j].fg.bUsed = 1; + + /* rowid cannot be part of a USING clause - assert() this. */ + assert( bRowid==0 || pEList->a[j].fg.bUsingTerm==0 ); + if( pEList->a[j].fg.bUsingTerm ) break; + } + if( hit || zTab==0 ) continue; + } + assert( zDb==0 || zTab!=0 ); + if( zTab ){ + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; + } + if( pItem->zAlias!=0 ){ + if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ + continue; + } + }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ + if( pTab->tnum!=1 ) continue; + if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; + } + assert( ExprUseYTab(pExpr) ); + if( IN_RENAME_OBJECT && pItem->zAlias ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); + } + } + hCol = sqlite3StrIHash(zCol); + for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } + } + cnt++; + pMatch = pItem; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + if( pItem->fg.isNestedFrom ){ + sqlite3SrcItemColumnUsed(pItem, j); + } + break; + } + } + if( 0==cnt && VisibleRowid(pTab) ){ + /* pTab is a potential ROWID match. Keep track of it and match + ** the ROWID later if that seems appropriate. (Search for "cntTab" + ** to find related code.) Only allow a ROWID match if there is + ** a single ROWID match candidate. + */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match + ** if there is a single VIEW candidate or if there is a single + ** non-VIEW candidate plus multiple VIEW candidates. In other + ** words non-VIEW candidate terms take precedence over VIEWs. + */ + if( cntTab==0 + || (cntTab==1 + && ALWAYS(pMatch!=0) + && ALWAYS(pMatch->pTab!=0) + && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0 + && (pTab->tabFlags & TF_Ephemeral)==0) + ){ + cntTab = 1; + pMatch = pItem; + }else{ + cntTab++; + } +#else + /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is + ** simpler since we require exactly one candidate, which will + ** always be a non-VIEW + */ + cntTab++; + pMatch = pItem; +#endif + } + } + if( pMatch ){ + pExpr->iTable = pMatch->iCursor; + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pMatch->pTab; + if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ + ExprSetProperty(pExpr, EP_CanBeNull); + } + pSchema = pExpr->y.pTab->pSchema; + } + } /* if( pSrcList ) */ + +#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) + /* If we have not already resolved the name, then maybe + ** it is a new.* or old.* trigger argument reference. Or + ** maybe it is an excluded.* from an upsert. Or maybe it is + ** a reference in the RETURNING clause to a table being modified. + */ + if( cnt==0 && zDb==0 ){ + pTab = 0; +#ifndef SQLITE_OMIT_TRIGGER + if( pParse->pTriggerTab!=0 ){ + int op = pParse->eTriggerOp; + assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); + if( pParse->bReturning ){ + if( (pNC->ncFlags & NC_UBaseReg)!=0 + && ALWAYS(zTab==0 + || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + ){ + pExpr->iTable = op!=TK_DELETE; + pTab = pParse->pTriggerTab; + } + }else if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ + pExpr->iTable = 1; + pTab = pParse->pTriggerTab; + }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ + pExpr->iTable = 0; + pTab = pParse->pTriggerTab; + } + } +#endif /* SQLITE_OMIT_TRIGGER */ +#ifndef SQLITE_OMIT_UPSERT + if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ + Upsert *pUpsert = pNC->uNC.pUpsert; + if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ + pTab = pUpsert->pUpsertSrc->a[0].pTab; + pExpr->iTable = EXCLUDED_TABLE_NUMBER; + } + } +#endif /* SQLITE_OMIT_UPSERT */ + + if( pTab ){ + int iCol; + u8 hCol = sqlite3StrIHash(zCol); + pSchema = pTab->pSchema; + cntTab++; + for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ + if( iCol==pTab->iPKey ){ + iCol = -1; + } + break; + } + } + if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ + /* IMP: R-51414-32910 */ + iCol = -1; + } + if( iColnCol ){ + cnt++; + pMatch = 0; +#ifndef SQLITE_OMIT_UPSERT + if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ + testcase( iCol==(-1) ); + assert( ExprUseYTab(pExpr) ); + if( IN_RENAME_OBJECT ){ + pExpr->iColumn = iCol; + pExpr->y.pTab = pTab; + eNewExprOp = TK_COLUMN; + }else{ + pExpr->iTable = pNC->uNC.pUpsert->regData + + sqlite3TableColumnToStorage(pTab, iCol); + eNewExprOp = TK_REGISTER; + } + }else +#endif /* SQLITE_OMIT_UPSERT */ + { + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pTab; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + pExpr->op2 = TK_COLUMN; + pExpr->iColumn = iCol; + pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + + sqlite3TableColumnToStorage(pTab, iCol) + 1; + }else{ + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#ifndef SQLITE_OMIT_TRIGGER + if( iCol<0 ){ + pExpr->affExpr = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<=1 + && pMatch + && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 + && sqlite3IsRowid(zCol) + && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) + ){ + cnt = cntTab; + if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; + pExpr->affExpr = SQLITE_AFF_INTEGER; + } + + /* + ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z + ** might refer to an result-set alias. This happens, for example, when + ** we are resolving names in the WHERE clause of the following command: + ** + ** SELECT a+b AS x FROM table WHERE x<10; + ** + ** In cases like this, replace pExpr with a copy of the expression that + ** forms the result set entry ("a+b" in the example) and return immediately. + ** Note that the expression in the result set should have already been + ** resolved by the time the WHERE clause is resolved. + ** + ** The ability to use an output result-set column in the WHERE, GROUP BY, + ** or HAVING clauses, or as part of a larger expression in the ORDER BY + ** clause is not standard SQL. This is a (goofy) SQLite extension, that + ** is supported for backwards compatibility only. Hence, we issue a warning + ** on sqlite3_log() whenever the capability is used. + */ + if( cnt==0 + && (pNC->ncFlags & NC_UEList)!=0 + && zTab==0 + ){ + pEList = pNC->uNC.pEList; + assert( pEList!=0 ); + for(j=0; jnExpr; j++){ + char *zAs = pEList->a[j].zEName; + if( pEList->a[j].fg.eEName==ENAME_NAME + && sqlite3_stricmp(zAs, zCol)==0 + ){ + Expr *pOrig; + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 ); + assert( ExprUseXSelect(pExpr)==0 || pExpr->x.pSelect==0 ); + pOrig = pEList->a[j].pExpr; + if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); + return WRC_Abort; + } + if( ExprHasProperty(pOrig, EP_Win) + && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC ) + ){ + sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); + return WRC_Abort; + } + if( sqlite3ExprVectorSize(pOrig)!=1 ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return WRC_Abort; + } + resolveAlias(pParse, pEList, j, pExpr, nSubquery); + cnt = 1; + pMatch = 0; + assert( zTab==0 && zDb==0 ); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + } + goto lookupname_end; + } + } + } + + /* Advance to the next name context. The loop will exit when either + ** we have a match (cnt>0) or when we run out of name contexts. + */ + if( cnt ) break; + pNC = pNC->pNext; + nSubquery++; + }while( pNC ); + + + /* + ** If X and Y are NULL (in other words if only the column name Z is + ** supplied) and the value of Z is enclosed in double-quotes, then + ** Z is a string literal if it doesn't match any column names. In that + ** case, we need to return right away and not make any changes to + ** pExpr. + ** + ** Because no reference was made to outer contexts, the pNC->nRef + ** fields are not changed in any context. + */ + if( cnt==0 && zTab==0 ){ + assert( pExpr->op==TK_ID ); + if( ExprHasProperty(pExpr,EP_DblQuoted) + && areDoubleQuotedStringsEnabled(db, pTopNC) + ){ + /* If a double-quoted identifier does not match any known column name, + ** then treat it as a string. + ** + ** This hack was added in the early days of SQLite in a misguided attempt + ** to be compatible with MySQL 3.x, which used double-quotes for strings. + ** I now sorely regret putting in this hack. The effect of this hack is + ** that misspelled identifier names are silently converted into strings + ** rather than causing an error, to the frustration of countless + ** programmers. To all those frustrated programmers, my apologies. + ** + ** Someday, I hope to get rid of this hack. Unfortunately there is + ** a huge amount of legacy SQL that uses it. So for now, we just + ** issue a warning. + */ + sqlite3_log(SQLITE_WARNING, + "double-quoted string literal: \"%w\"", zCol); +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); +#endif + pExpr->op = TK_STRING; + memset(&pExpr->y, 0, sizeof(pExpr->y)); + return WRC_Prune; + } + if( sqlite3ExprIdToTrueFalse(pExpr) ){ + return WRC_Prune; + } + } + + /* + ** cnt==0 means there was not match. + ** cnt>1 means there were two or more matches. + ** + ** cnt==0 is always an error. cnt>1 is often an error, but might + ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING. + */ + assert( pFJMatch==0 || cnt>0 ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + if( cnt!=1 ){ + const char *zErr; + if( pFJMatch ){ + if( pFJMatch->nExpr==cnt-1 ){ + if( ExprHasProperty(pExpr,EP_Leaf) ){ + ExprClearProperty(pExpr,EP_Leaf); + }else{ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + pExpr->op = TK_FUNCTION; + pExpr->u.zToken = "coalesce"; + pExpr->x.pList = pFJMatch; + cnt = 1; + goto lookupname_end; + }else{ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + } + } + zErr = cnt==0 ? "no such column" : "ambiguous column name"; + if( zDb ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); + }else if( zTab ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); + } + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + pParse->checkSchema = 1; + pTopNC->nNcErr++; + eNewExprOp = TK_NULL; + } + assert( pFJMatch==0 ); + + /* Remove all substructure from pExpr */ + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + ExprSetProperty(pExpr, EP_Leaf); + } + + /* If a column from a table in pSrcList is referenced, then record + ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes + ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is + ** set if the 63rd or any subsequent column is used. + ** + ** The colUsed mask is an optimization used to help determine if an + ** index is a covering index. The correct answer is still obtained + ** if the mask contains extra set bits. However, it is important to + ** avoid setting bits beyond the maximum column number of the table. + ** (See ticket [b92e5e8ec2cdbaa1]). + ** + ** If a generated column is referenced, set bits for every column + ** of the table. + */ + if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){ + pMatch->colUsed |= sqlite3ExprColUsed(pExpr); + } + + pExpr->op = eNewExprOp; +lookupname_end: + if( cnt==1 ){ + assert( pNC!=0 ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pParse->db->xAuth + && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) + ){ + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + } +#endif + /* Increment the nRef value on all name contexts from TopNC up to + ** the point where the name matched. */ + for(;;){ + assert( pTopNC!=0 ); + pTopNC->nRef++; + if( pTopNC==pNC ) break; + pTopNC = pTopNC->pNext; + } + return WRC_Prune; + } else { + return WRC_Abort; + } +} + +/* +** Allocate and return a pointer to an expression to load the column iCol +** from datasource iSrc in SrcList pSrc. +*/ +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ + Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); + if( p ){ + SrcItem *pItem = &pSrc->a[iSrc]; + Table *pTab; + assert( ExprUseYTab(p) ); + pTab = p->y.pTab = pItem->pTab; + p->iTable = pItem->iCursor; + if( p->y.pTab->iPKey==iCol ){ + p->iColumn = -1; + }else{ + p->iColumn = (ynVar)iCol; + if( (pTab->tabFlags & TF_HasGenerated)!=0 + && (pTab->aCol[iCol].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pTab->nCol==63 ); + testcase( pTab->nCol==64 ); + pItem->colUsed = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1; + }else{ + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + } + } + return p; +} + +/* +** Report an error that an expression is not valid for some set of +** pNC->ncFlags values determined by validMask. +** +** static void notValid( +** Parse *pParse, // Leave error message here +** NameContext *pNC, // The name context +** const char *zMsg, // Type of error +** int validMask, // Set of contexts for which prohibited +** Expr *pExpr // Invalidate this expression on error +** ){...} +** +** As an optimization, since the conditional is almost always false +** (because errors are rare), the conditional is moved outside of the +** function call using a macro. +*/ +static void notValidImpl( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg, /* Type of error */ + Expr *pExpr, /* Invalidate this expression on error */ + Expr *pError /* Associate error with this expression */ +){ + const char *zIn = "partial index WHERE clauses"; + if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; +#ifndef SQLITE_OMIT_CHECK + else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; +#endif +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns"; +#endif + sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); + if( pExpr ) pExpr->op = TK_NULL; + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); +} +#define sqlite3ResolveNotValid(P,N,M,X,E,R) \ + assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ + if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R); + +/* +** Expression p should encode a floating point value between 1.0 and 0.0. +** Return 1024 times this value. Or return -1 if p is not a floating point +** value between 1.0 and 0.0. +*/ +static int exprProbability(Expr *p){ + double r = -1.0; + if( p->op!=TK_FLOAT ) return -1; + assert( !ExprHasProperty(p, EP_IntValue) ); + sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); + assert( r>=0.0 ); + if( r>1.0 ) return -1; + return (int)(r*134217728.0); +} + +/* +** This routine is callback for sqlite3WalkExpr(). +** +** Resolve symbolic names into TK_COLUMN operators for the current +** node in the expression tree. Return 0 to continue the search down +** the tree or 2 to abort the tree walk. +** +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. +*/ +static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + NameContext *pNC; + Parse *pParse; + + pNC = pWalker->u.pNC; + assert( pNC!=0 ); + pParse = pNC->pParse; + assert( pParse==pWalker->pParse ); + +#ifndef NDEBUG + if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ + SrcList *pSrcList = pNC->pSrcList; + int i; + for(i=0; ipSrcList->nSrc; i++){ + assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); + } + } +#endif + switch( pExpr->op ){ + + /* The special operator TK_ROW means use the rowid for the first + ** column in the FROM clause. This is used by the LIMIT and ORDER BY + ** clause processing on UPDATE and DELETE statements, and by + ** UPDATE ... FROM statement processing. + */ + case TK_ROW: { + SrcList *pSrcList = pNC->pSrcList; + SrcItem *pItem; + assert( pSrcList && pSrcList->nSrc>=1 ); + pItem = pSrcList->a; + pExpr->op = TK_COLUMN; + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pItem->pTab; + pExpr->iTable = pItem->iCursor; + pExpr->iColumn--; + pExpr->affExpr = SQLITE_AFF_INTEGER; + break; + } + + /* An optimization: Attempt to convert + ** + ** "expr IS NOT NULL" --> "TRUE" + ** "expr IS NULL" --> "FALSE" + ** + ** if we can prove that "expr" is never NULL. Call this the + ** "NOT NULL strength reduction optimization". + ** + ** If this optimization occurs, also restore the NameContext ref-counts + ** to the state they where in before the "column" LHS expression was + ** resolved. This prevents "column" from being counted as having been + ** referenced, which might prevent a SELECT from being erroneously + ** marked as correlated. + ** + ** 2024-03-28: Beware of aggregates. A bare column of aggregated table + ** can still evaluate to NULL even though it is marked as NOT NULL. + ** Example: + ** + ** CREATE TABLE t1(a INT NOT NULL); + ** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1; + ** + ** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized + ** here because at the time this case is hit, we do not yet know whether + ** or not t1 is being aggregated. We have to assume the worst and omit + ** the optimization. The only time it is safe to apply this optimization + ** is within the WHERE clause. + */ + case TK_NOTNULL: + case TK_ISNULL: { + int anRef[8]; + NameContext *p; + int i; + for(i=0, p=pNC; p && ipNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( IN_RENAME_OBJECT ) return WRC_Prune; + if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ + /* The expression can be NULL. So the optimization does not apply */ + return WRC_Prune; + } + + for(i=0, p=pNC; p; p=p->pNext, i++){ + if( (p->ncFlags & NC_Where)==0 ){ + return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */ + } + } + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x80000 ){ + sqlite3DebugPrintf( + "NOT NULL strength reduction converts the following to %d:\n", + pExpr->op==TK_NOTNULL + ); + sqlite3ShowExpr(pExpr); + } +#endif /* TREETRACE_ENABLED */ + pExpr->u.iValue = (pExpr->op==TK_NOTNULL); + pExpr->flags |= EP_IntValue; + pExpr->op = TK_INTEGER; + for(i=0, p=pNC; p && ipNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; + return WRC_Prune; + } + + /* A column name: ID + ** Or table name and column name: ID.ID + ** Or a database, table and column: ID.ID.ID + ** + ** The TK_ID and TK_OUT cases are combined so that there will only + ** be one call to lookupName(). Then the compiler will in-line + ** lookupName() for a size reduction and performance increase. + */ + case TK_ID: + case TK_DOT: { + const char *zColumn; + const char *zTable; + const char *zDb; + Expr *pRight; + + if( pExpr->op==TK_ID ){ + zDb = 0; + zTable = 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + zColumn = pExpr->u.zToken; + }else{ + Expr *pLeft = pExpr->pLeft; + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", + NC_IdxExpr|NC_GenCol, 0, pExpr); + pRight = pExpr->pRight; + if( pRight->op==TK_ID ){ + zDb = 0; + }else{ + assert( pRight->op==TK_DOT ); + assert( !ExprHasProperty(pRight, EP_IntValue) ); + zDb = pLeft->u.zToken; + pLeft = pRight->pLeft; + pRight = pRight->pRight; + } + assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); + zTable = pLeft->u.zToken; + zColumn = pRight->u.zToken; + assert( ExprUseYTab(pExpr) ); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); + sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); + } + } + return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); + } + + /* Resolve function names + */ + case TK_FUNCTION: { + ExprList *pList = pExpr->x.pList; /* The argument list */ + int n = pList ? pList->nExpr : 0; /* Number of arguments */ + int no_such_func = 0; /* True if no such function exists */ + int wrong_num_args = 0; /* True if wrong number of arguments */ + int is_agg = 0; /* True if is an aggregate function */ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + u8 enc = ENC(pParse->db); /* The database encoding */ + int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); +#endif + assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); + zId = pExpr->u.zToken; + pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); + if( pDef==0 ){ + pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); + if( pDef==0 ){ + no_such_func = 1; + }else{ + wrong_num_args = 1; + } + }else{ + is_agg = pDef->xFinalize!=0; + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ + ExprSetProperty(pExpr, EP_Unlikely); + if( n==2 ){ + pExpr->iTable = exprProbability(pList->a[1].pExpr); + if( pExpr->iTable<0 ){ + sqlite3ErrorMsg(pParse, + "second argument to %#T() must be a " + "constant between 0.0 and 1.0", pExpr); + pNC->nNcErr++; + } + }else{ + /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is + ** equivalent to likelihood(X, 0.0625). + ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is + ** short-hand for likelihood(X,0.0625). + ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand + ** for likelihood(X,0.9375). + ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent + ** to likelihood(X,0.9375). */ + /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ + pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); + if( auth!=SQLITE_OK ){ + if( auth==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %#T", + pExpr); + pNC->nNcErr++; + } + pExpr->op = TK_NULL; + return WRC_Prune; + } + } +#endif + if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ + /* For the purposes of the EP_ConstFunc flag, date and time + ** functions and other functions that change slowly are considered + ** constant because they are constant for the duration of one query. + ** This allows them to be factored out of inner loops. */ + ExprSetProperty(pExpr,EP_ConstFunc); + } + if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ + /* Clearly non-deterministic functions like random(), but also + ** date/time functions that use 'now', and other functions like + ** sqlite_version() that might change over time cannot be used + ** in an index or generated column. Curiously, they can be used + ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all + ** all this. */ + sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", + NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr); + }else{ + assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ + pExpr->op2 = pNC->ncFlags & NC_SelfRef; + if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); + } + if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && pParse->nested==0 + && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 + ){ + /* Internal-use-only functions are disallowed unless the + ** SQL is being compiled using sqlite3NestedParse() or + ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be + ** used to activate internal functions for testing purposes */ + no_such_func = 1; + pDef = 0; + }else + if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 + && !IN_RENAME_OBJECT + ){ + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); + } + } + + if( 0==IN_RENAME_OBJECT ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) + || (pDef->xValue==0 && pDef->xInverse==0) + || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) + ); + if( pDef && pDef->xValue==0 && pWin ){ + sqlite3ErrorMsg(pParse, + "%#T() may not be used as a window function", pExpr + ); + pNC->nNcErr++; + }else if( + (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) + || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin) + || (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0) + ){ + const char *zType; + if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){ + zType = "window"; + }else{ + zType = "aggregate"; + } + sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr); + pNC->nNcErr++; + is_agg = 0; + } +#else + if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ + sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr); + pNC->nNcErr++; + is_agg = 0; + } +#endif + else if( no_such_func && pParse->db->init.busy==0 +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + && pParse->explain==0 +#endif + ){ + sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr); + pNC->nNcErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()", + pExpr); + pNC->nNcErr++; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ErrorMsg(pParse, + "FILTER may not be used with non-aggregate %#T()", + pExpr + ); + pNC->nNcErr++; + } +#endif + else if( is_agg==0 && pExpr->pLeft ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + pNC->nNcErr++; + } + if( is_agg ){ + /* Window functions may not be arguments of aggregate functions. + ** Or arguments of other window functions. But aggregate functions + ** may be arguments for window functions. */ +#ifndef SQLITE_OMIT_WINDOWFUNC + pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0)); +#else + pNC->ncFlags &= ~NC_AllowAgg; +#endif + } + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else if( ExprHasProperty(pExpr, EP_WinFunc) ){ + is_agg = 1; + } +#endif + sqlite3WalkExprList(pWalker, pList); + if( is_agg ){ + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + Select *pSel = pNC->pWinSelect; + assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) ); + if( IN_RENAME_OBJECT==0 ){ + sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); + if( pParse->db->mallocFailed ) break; + } + sqlite3WalkExprList(pWalker, pWin->pPartition); + sqlite3WalkExprList(pWalker, pWin->pOrderBy); + sqlite3WalkExpr(pWalker, pWin->pFilter); + sqlite3WindowLink(pSel, pWin); + pNC->ncFlags |= NC_HasWin; + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + NameContext *pNC2; /* For looping up thru outer contexts */ + pExpr->op = TK_AGG_FUNCTION; + pExpr->op2 = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); + } +#endif + pNC2 = pNC; + while( pNC2 + && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 + ){ + pExpr->op2 += (1 + pNC2->nNestedSelect); + pNC2 = pNC2->pNext; + } + assert( pDef!=0 || IN_RENAME_OBJECT ); + if( pNC2 && pDef ){ + pExpr->op2 += pNC2->nNestedSelect; + assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); + testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); + testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 ); + pNC2->ncFlags |= NC_HasAgg + | ((pDef->funcFlags^SQLITE_FUNC_ANYORDER) + & (SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER)); + } + } + pNC->ncFlags |= savedAllowFlags; + } + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function + */ + return WRC_Prune; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); +#endif + case TK_IN: { + testcase( pExpr->op==TK_IN ); + if( ExprUseXSelect(pExpr) ){ + int nRef = pNC->nRef; + testcase( pNC->ncFlags & NC_IsCheck ); + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + if( pNC->ncFlags & NC_SelfRef ){ + notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); + }else{ + sqlite3WalkSelect(pWalker, pExpr->x.pSelect); + } + assert( pNC->nRef>=nRef ); + if( nRef!=pNC->nRef ){ + ExprSetProperty(pExpr, EP_VarSelect); + } + pNC->ncFlags |= NC_Subquery; + } + break; + } + case TK_VARIABLE: { + testcase( pNC->ncFlags & NC_IsCheck ); + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "parameters", + NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr); + break; + } + case TK_IS: + case TK_ISNOT: { + Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight); + assert( !ExprHasProperty(pExpr, EP_Reduced) ); + /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", + ** and "x IS NOT FALSE". */ + if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){ + int rc = resolveExprStep(pWalker, pRight); + if( rc==WRC_Abort ) return WRC_Abort; + if( pRight->op==TK_TRUEFALSE ){ + pExpr->op2 = pExpr->op; + pExpr->op = TK_TRUTH; + return WRC_Continue; + } + } + /* no break */ deliberate_fall_through + } + case TK_BETWEEN: + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: { + int nLeft, nRight; + if( pParse->db->mallocFailed ) break; + assert( pExpr->pLeft!=0 ); + nLeft = sqlite3ExprVectorSize(pExpr->pLeft); + if( pExpr->op==TK_BETWEEN ){ + assert( ExprUseXList(pExpr) ); + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr); + if( nRight==nLeft ){ + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr); + } + }else{ + assert( pExpr->pRight!=0 ); + nRight = sqlite3ExprVectorSize(pExpr->pRight); + } + if( nLeft!=nRight ){ + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + testcase( pExpr->op==TK_BETWEEN ); + sqlite3ErrorMsg(pParse, "row value misused"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + } + break; + } + } + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + return pParse->nErr ? WRC_Abort : WRC_Continue; +} + +/* +** pEList is a list of expressions which are really the result set of the +** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause. +** This routine checks to see if pE is a simple identifier which corresponds +** to the AS-name of one of the terms of the expression list. If it is, +** this routine return an integer between 1 and N where N is the number of +** elements in pEList, corresponding to the matching entry. If there is +** no match, or if pE is not a simple identifier, then this routine +** return 0. +** +** pEList has been resolved. pE has not. +*/ +static int resolveAsName( + Parse *pParse, /* Parsing context for error messages */ + ExprList *pEList, /* List of expressions to scan */ + Expr *pE /* Expression we are trying to match */ +){ + int i; /* Loop counter */ + + UNUSED_PARAMETER(pParse); + + if( pE->op==TK_ID ){ + const char *zCol; + assert( !ExprHasProperty(pE, EP_IntValue) ); + zCol = pE->u.zToken; + for(i=0; inExpr; i++){ + if( pEList->a[i].fg.eEName==ENAME_NAME + && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 + ){ + return i+1; + } + } + } + return 0; +} + +/* +** pE is a pointer to an expression which is a single term in the +** ORDER BY of a compound SELECT. The expression has not been +** name resolved. +** +** At the point this routine is called, we already know that the +** ORDER BY term is not an integer index into the result set. That +** case is handled by the calling routine. +** +** Attempt to match pE against result set columns in the left-most +** SELECT statement. Return the index i of the matching column, +** as an indication to the caller that it should sort by the i-th column. +** The left-most column is 1. In other words, the value returned is the +** same integer value that would be used in the SQL statement to indicate +** the column. +** +** If there is no match, return 0. Return -1 if an error occurs. +*/ +static int resolveOrderByTermToExprList( + Parse *pParse, /* Parsing context for error messages */ + Select *pSelect, /* The SELECT statement with the ORDER BY clause */ + Expr *pE /* The specific ORDER BY term */ +){ + int i; /* Loop counter */ + ExprList *pEList; /* The columns of the result set */ + NameContext nc; /* Name context for resolving pE */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code from subprocedures */ + u8 savedSuppErr; /* Saved value of db->suppressErr */ + + assert( sqlite3ExprIsInteger(pE, &i)==0 ); + pEList = pSelect->pEList; + + /* Resolve all names in the ORDER BY term expression + */ + memset(&nc, 0, sizeof(nc)); + nc.pParse = pParse; + nc.pSrcList = pSelect->pSrc; + nc.uNC.pEList = pEList; + nc.ncFlags = NC_AllowAgg|NC_UEList|NC_NoSelect; + nc.nNcErr = 0; + db = pParse->db; + savedSuppErr = db->suppressErr; + db->suppressErr = 1; + rc = sqlite3ResolveExprNames(&nc, pE); + db->suppressErr = savedSuppErr; + if( rc ) return 0; + + /* Try to match the ORDER BY expression against an expression + ** in the result set. Return an 1-based index of the matching + ** result-set entry. + */ + for(i=0; inExpr; i++){ + if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){ + return i+1; + } + } + + /* If no match, return 0. */ + return 0; +} + +/* +** Generate an ORDER BY or GROUP BY term out-of-range error. +*/ +static void resolveOutOfRangeError( + Parse *pParse, /* The error context into which to write the error */ + const char *zType, /* "ORDER" or "GROUP" */ + int i, /* The index (1-based) of the term out of range */ + int mx, /* Largest permissible value of i */ + Expr *pError /* Associate the error with the expression */ +){ + sqlite3ErrorMsg(pParse, + "%r %s BY term out of range - should be " + "between 1 and %d", i, zType, mx); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); +} + +/* +** Analyze the ORDER BY clause in a compound SELECT statement. Modify +** each term of the ORDER BY clause is a constant integer between 1 +** and N where N is the number of columns in the compound SELECT. +** +** ORDER BY terms that are already an integer between 1 and N are +** unmodified. ORDER BY terms that are integers outside the range of +** 1 through N generate an error. ORDER BY terms that are expressions +** are matched against result set expressions of compound SELECT +** beginning with the left-most SELECT and working toward the right. +** At the first match, the ORDER BY expression is transformed into +** the integer column number. +** +** Return the number of errors seen. +*/ +static int resolveCompoundOrderBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect /* The SELECT statement containing the ORDER BY */ +){ + int i; + ExprList *pOrderBy; + ExprList *pEList; + sqlite3 *db; + int moreToDo = 1; + + pOrderBy = pSelect->pOrderBy; + if( pOrderBy==0 ) return 0; + db = pParse->db; + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); + return 1; + } + for(i=0; inExpr; i++){ + pOrderBy->a[i].fg.done = 0; + } + pSelect->pNext = 0; + while( pSelect->pPrior ){ + pSelect->pPrior->pNext = pSelect; + pSelect = pSelect->pPrior; + } + while( pSelect && moreToDo ){ + struct ExprList_item *pItem; + moreToDo = 0; + pEList = pSelect->pEList; + assert( pEList!=0 ); + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + int iCol = -1; + Expr *pE, *pDup; + if( pItem->fg.done ) continue; + pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); + if( NEVER(pE==0) ) continue; + if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( iCol<=0 || iCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); + return 1; + } + }else{ + iCol = resolveAsName(pParse, pEList, pE); + if( iCol==0 ){ + /* Now test if expression pE matches one of the values returned + ** by pSelect. In the usual case this is done by duplicating the + ** expression, resolving any symbols in it, and then comparing + ** it against each expression returned by the SELECT statement. + ** Once the comparisons are finished, the duplicate expression + ** is deleted. + ** + ** If this is running as part of an ALTER TABLE operation and + ** the symbols resolve successfully, also resolve the symbols in the + ** actual expression. This allows the code in alter.c to modify + ** column references within the ORDER BY expression as required. */ + pDup = sqlite3ExprDup(db, pE, 0); + if( !db->mallocFailed ){ + assert(pDup); + iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); + if( IN_RENAME_OBJECT && iCol>0 ){ + resolveOrderByTermToExprList(pParse, pSelect, pE); + } + } + sqlite3ExprDelete(db, pDup); + } + } + if( iCol>0 ){ + /* Convert the ORDER BY term into an integer column number iCol, + ** taking care to preserve the COLLATE clause if it exists. */ + if( !IN_RENAME_OBJECT ){ + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + if( pNew==0 ) return 1; + pNew->flags |= EP_IntValue; + pNew->u.iValue = iCol; + if( pItem->pExpr==pE ){ + pItem->pExpr = pNew; + }else{ + Expr *pParent = pItem->pExpr; + assert( pParent->op==TK_COLLATE ); + while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; + assert( pParent->pLeft==pE ); + pParent->pLeft = pNew; + } + sqlite3ExprDelete(db, pE); + pItem->u.x.iOrderByCol = (u16)iCol; + } + pItem->fg.done = 1; + }else{ + moreToDo = 1; + } + } + pSelect = pSelect->pNext; + } + for(i=0; inExpr; i++){ + if( pOrderBy->a[i].fg.done==0 ){ + sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " + "column in the result set", i+1); + return 1; + } + } + return 0; +} + +/* +** Check every term in the ORDER BY or GROUP BY clause pOrderBy of +** the SELECT statement pSelect. If any term is reference to a +** result set expression (as determined by the ExprList.a.u.x.iOrderByCol +** field) then convert that term into a copy of the corresponding result set +** column. +** +** If any errors are detected, add an error message to pParse and +** return non-zero. Return zero if no errors are seen. +*/ +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect, /* The SELECT statement containing the clause */ + ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ + const char *zType /* "ORDER" or "GROUP" */ +){ + int i; + sqlite3 *db = pParse->db; + ExprList *pEList; + struct ExprList_item *pItem; + + if( pOrderBy==0 || pParse->db->mallocFailed || IN_RENAME_OBJECT ) return 0; + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); + return 1; + } + pEList = pSelect->pEList; + assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + if( pItem->u.x.iOrderByCol ){ + if( pItem->u.x.iOrderByCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0); + return 1; + } + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); + } + } + return 0; +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Walker callback for windowRemoveExprFromSelect(). +*/ +static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){ + UNUSED_PARAMETER(pWalker); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + Window *pWin = pExpr->y.pWin; + sqlite3WindowUnlinkFromSelect(pWin); + } + return WRC_Continue; +} + +/* +** Remove any Window objects owned by the expression pExpr from the +** Select.pWin list of Select object pSelect. +*/ +static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ + if( pSelect->pWin ){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.xExprCallback = resolveRemoveWindowsCb; + sWalker.u.pSelect = pSelect; + sqlite3WalkExpr(&sWalker, pExpr); + } +} +#else +# define windowRemoveExprFromSelect(a, b) +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. +** The Name context of the SELECT statement is pNC. zType is either +** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. +** +** This routine resolves each term of the clause into an expression. +** If the order-by term is an integer I between 1 and N (where N is the +** number of columns in the result set of the SELECT) then the expression +** in the resolution is a copy of the I-th result-set expression. If +** the order-by term is an identifier that corresponds to the AS-name of +** a result-set expression, then the term resolves to a copy of the +** result-set expression. Otherwise, the expression is resolved in +** the usual way - using sqlite3ResolveExprNames(). +** +** This routine returns the number of errors. If errors occur, then +** an appropriate error message might be left in pParse. (OOM errors +** excepted.) +*/ +static int resolveOrderGroupBy( + NameContext *pNC, /* The name context of the SELECT statement */ + Select *pSelect, /* The SELECT statement holding pOrderBy */ + ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ + const char *zType /* Either "ORDER" or "GROUP", as appropriate */ +){ + int i, j; /* Loop counters */ + int iCol; /* Column number */ + struct ExprList_item *pItem; /* A term of the ORDER BY clause */ + Parse *pParse; /* Parsing context */ + int nResult; /* Number of terms in the result set */ + + assert( pOrderBy!=0 ); + nResult = pSelect->pEList->nExpr; + pParse = pNC->pParse; + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + Expr *pE = pItem->pExpr; + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); + if( NEVER(pE2==0) ) continue; + if( zType[0]!='G' ){ + iCol = resolveAsName(pParse, pSelect->pEList, pE2); + if( iCol>0 ){ + /* If an AS-name match is found, mark this ORDER BY column as being + ** a copy of the iCol-th result-set column. The subsequent call to + ** sqlite3ResolveOrderGroupBy() will convert the expression to a + ** copy of the iCol-th result-set expression. */ + pItem->u.x.iOrderByCol = (u16)iCol; + continue; + } + } + if( sqlite3ExprIsInteger(pE2, &iCol) ){ + /* The ORDER BY term is an integer constant. Again, set the column + ** number so that sqlite3ResolveOrderGroupBy() will convert the + ** order-by term to a copy of the result-set expression */ + if( iCol<1 || iCol>0xffff ){ + resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2); + return 1; + } + pItem->u.x.iOrderByCol = (u16)iCol; + continue; + } + + /* Otherwise, treat the ORDER BY term as an ordinary expression */ + pItem->u.x.iOrderByCol = 0; + if( sqlite3ResolveExprNames(pNC, pE) ){ + return 1; + } + for(j=0; jpEList->nExpr; j++){ + if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ + /* Since this expression is being changed into a reference + ** to an identical expression in the result set, remove all Window + ** objects belonging to the expression from the Select.pWin list. */ + windowRemoveExprFromSelect(pSelect, pE); + pItem->u.x.iOrderByCol = j+1; + } + } + } + return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); +} + +/* +** Resolve names in the SELECT statement p and all of its descendants. +*/ +static int resolveSelectStep(Walker *pWalker, Select *p){ + NameContext *pOuterNC; /* Context that contains this SELECT */ + NameContext sNC; /* Name context of this SELECT */ + int isCompound; /* True if p is a compound select */ + int nCompound; /* Number of compound terms processed so far */ + Parse *pParse; /* Parsing context */ + int i; /* Loop counter */ + ExprList *pGroupBy; /* The GROUP BY clause */ + Select *pLeftmost; /* Left-most of SELECT of a compound */ + sqlite3 *db; /* Database connection */ + + + assert( p!=0 ); + if( p->selFlags & SF_Resolved ){ + return WRC_Prune; + } + pOuterNC = pWalker->u.pNC; + pParse = pWalker->pParse; + db = pParse->db; + + /* Normally sqlite3SelectExpand() will be called first and will have + ** already expanded this SELECT. However, if this is a subquery within + ** an expression, sqlite3ResolveExprNames() will be called without a + ** prior call to sqlite3SelectExpand(). When that happens, let + ** sqlite3SelectPrep() do all of the processing for this SELECT. + ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and + ** this routine in the correct order. + */ + if( (p->selFlags & SF_Expanded)==0 ){ + sqlite3SelectPrep(pParse, p, pOuterNC); + return pParse->nErr ? WRC_Abort : WRC_Prune; + } + + isCompound = p->pPrior!=0; + nCompound = 0; + pLeftmost = p; + while( p ){ + assert( (p->selFlags & SF_Expanded)!=0 ); + assert( (p->selFlags & SF_Resolved)==0 ); + p->selFlags |= SF_Resolved; + + /* Resolve the expressions in the LIMIT and OFFSET clauses. These + ** are not allowed to refer to any names, so pass an empty NameContext. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pWinSelect = p; + if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ + return WRC_Abort; + } + + /* If the SF_Converted flags is set, then this Select object was + ** was created by the convertCompoundSelectToSubquery() function. + ** In this case the ORDER BY clause (p->pOrderBy) should be resolved + ** as if it were part of the sub-query, not the parent. This block + ** moves the pOrderBy down to the sub-query. It will be moved back + ** after the names have been resolved. */ + if( p->selFlags & SF_Converted ){ + Select *pSub = p->pSrc->a[0].pSelect; + assert( p->pSrc->nSrc==1 && p->pOrderBy ); + assert( pSub->pPrior && pSub->pOrderBy==0 ); + pSub->pOrderBy = p->pOrderBy; + p->pOrderBy = 0; + } + + /* Recursively resolve names in all subqueries in the FROM clause + */ + if( pOuterNC ) pOuterNC->nNestedSelect++; + for(i=0; ipSrc->nSrc; i++){ + SrcItem *pItem = &p->pSrc->a[i]; + if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ + int nRef = pOuterNC ? pOuterNC->nRef : 0; + const char *zSavedContext = pParse->zAuthContext; + + if( pItem->zName ) pParse->zAuthContext = pItem->zName; + sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + pParse->zAuthContext = zSavedContext; + if( pParse->nErr ) return WRC_Abort; + assert( db->mallocFailed==0 ); + + /* If the number of references to the outer context changed when + ** expressions in the sub-select were resolved, the sub-select + ** is correlated. It is not required to check the refcount on any + ** but the innermost outer context object, as lookupName() increments + ** the refcount on all contexts between the current one and the + ** context containing the column when it resolves a name. */ + if( pOuterNC ){ + assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef ); + pItem->fg.isCorrelated = (pOuterNC->nRef>nRef); + } + } + } + if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){ + pOuterNC->nNestedSelect--; + } + + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to + ** resolve the result-set expression list. + */ + sNC.ncFlags = NC_AllowAgg|NC_AllowWin; + sNC.pSrcList = p->pSrc; + sNC.pNext = pOuterNC; + + /* Resolve names in the result set. */ + if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; + sNC.ncFlags &= ~NC_AllowWin; + + /* If there are no aggregate functions in the result-set, and no GROUP BY + ** expression, do not allow aggregates in any of the other expressions. + */ + assert( (p->selFlags & SF_Aggregate)==0 ); + pGroupBy = p->pGroupBy; + if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ + assert( NC_MinMaxAgg==SF_MinMaxAgg ); + assert( NC_OrderAgg==SF_OrderByReqd ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&(NC_MinMaxAgg|NC_OrderAgg)); + }else{ + sNC.ncFlags &= ~NC_AllowAgg; + } + + /* Add the output column list to the name-context before parsing the + ** other expressions in the SELECT statement. This is so that + ** expressions in the WHERE clause (etc.) can refer to expressions by + ** aliases in the result set. + ** + ** Minor point: If this is the case, then the expression will be + ** re-evaluated for each reference to it. + */ + assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 ); + sNC.uNC.pEList = p->pEList; + sNC.ncFlags |= NC_UEList; + if( p->pHaving ){ + if( (p->selFlags & SF_Aggregate)==0 ){ + sqlite3ErrorMsg(pParse, "HAVING clause on a non-aggregate query"); + return WRC_Abort; + } + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + } + sNC.ncFlags |= NC_Where; + if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + sNC.ncFlags &= ~NC_Where; + + /* Resolve names in table-valued-function arguments */ + for(i=0; ipSrc->nSrc; i++){ + SrcItem *pItem = &p->pSrc->a[i]; + if( pItem->fg.isTabFunc + && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } + } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( IN_RENAME_OBJECT ){ + Window *pWin; + for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ + if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) + || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) + ){ + return WRC_Abort; + } + } + } +#endif + + /* The ORDER BY and GROUP BY clauses may not refer to terms in + ** outer queries + */ + sNC.pNext = 0; + sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; + + /* If this is a converted compound query, move the ORDER BY clause from + ** the sub-query back to the parent query. At this point each term + ** within the ORDER BY clause has been transformed to an integer value. + ** These integers will be replaced by copies of the corresponding result + ** set expressions by the call to resolveOrderGroupBy() below. */ + if( p->selFlags & SF_Converted ){ + Select *pSub = p->pSrc->a[0].pSelect; + p->pOrderBy = pSub->pOrderBy; + pSub->pOrderBy = 0; + } + + /* Process the ORDER BY clause for singleton SELECT statements. + ** The ORDER BY clause for compounds SELECT statements is handled + ** below, after all of the result-sets for all of the elements of + ** the compound have been resolved. + ** + ** If there is an ORDER BY clause on a term of a compound-select other + ** than the right-most term, then that is a syntax error. But the error + ** is not detected until much later, and so we need to go ahead and + ** resolve those symbols on the incorrect ORDER BY for consistency. + */ + if( p->pOrderBy!=0 + && isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ + && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") + ){ + return WRC_Abort; + } + if( db->mallocFailed ){ + return WRC_Abort; + } + sNC.ncFlags &= ~NC_AllowWin; + + /* Resolve the GROUP BY clause. At the same time, make sure + ** the GROUP BY clause does not contain aggregate functions. + */ + if( pGroupBy ){ + struct ExprList_item *pItem; + + if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ + return WRC_Abort; + } + for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ + if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " + "the GROUP BY clause"); + return WRC_Abort; + } + } + } + + /* If this is part of a compound SELECT, check that it has the right + ** number of expressions in the select list. */ + if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, p->pNext); + return WRC_Abort; + } + + /* Advance to the next term of the compound + */ + p = p->pPrior; + nCompound++; + } + + /* Resolve the ORDER BY on a compound SELECT after all terms of + ** the compound have been resolved. + */ + if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){ + return WRC_Abort; + } + + return WRC_Prune; +} + +/* +** This routine walks an expression tree and resolves references to +** table columns and result-set columns. At the same time, do error +** checking on function usage and set a flag if any aggregate functions +** are seen. +** +** To resolve table columns references we look for nodes (or subtrees) of the +** form X.Y.Z or Y.Z or just Z where +** +** X: The name of a database. Ex: "main" or "temp" or +** the symbolic name assigned to an ATTACH-ed database. +** +** Y: The name of a table in a FROM clause. Or in a trigger +** one of the special names "old" or "new". +** +** Z: The name of a column in table Y. +** +** The node at the root of the subtree is modified as follows: +** +** Expr.op Changed to TK_COLUMN +** Expr.pTab Points to the Table object for X.Y +** Expr.iColumn The column index in X.Y. -1 for the rowid. +** Expr.iTable The VDBE cursor number for X.Y +** +** +** To resolve result-set references, look for expression nodes of the +** form Z (with no X and Y prefix) where the Z matches the right-hand +** size of an AS clause in the result-set of a SELECT. The Z expression +** is replaced by a copy of the left-hand side of the result-set expression. +** Table-name and function resolution occurs on the substituted expression +** tree. For example, in: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x; +** +** The "x" term of the order by is replaced by "a+b" to render: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; +** +** Function calls are checked to make sure that the function is +** defined and that the correct number of arguments are specified. +** If the function is an aggregate function, then the NC_HasAgg flag is +** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. +** If an expression contains aggregate functions then the EP_Agg +** property on the expression is set. +** +** An error message is left in pParse if anything is amiss. The number +** if errors is returned. +*/ +SQLITE_PRIVATE int sqlite3ResolveExprNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + Expr *pExpr /* The expression to be analyzed. */ +){ + int savedHasAgg; + Walker w; + + if( pExpr==0 ) return SQLITE_OK; + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + w.pParse = pNC->pParse; + w.xExprCallback = resolveExprStep; + w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep; + w.xSelectCallback2 = 0; + w.u.pNC = pNC; +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight += pExpr->nHeight; + if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ + return SQLITE_ERROR; + } +#endif + assert( pExpr!=0 ); + sqlite3WalkExprNN(&w, pExpr); +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight -= pExpr->nHeight; +#endif + assert( EP_Agg==NC_HasAgg ); + assert( EP_Win==NC_HasWin ); + testcase( pNC->ncFlags & NC_HasAgg ); + testcase( pNC->ncFlags & NC_HasWin ); + ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); + pNC->ncFlags |= savedHasAgg; + return pNC->nNcErr>0 || w.pParse->nErr>0; +} + +/* +** Resolve all names for all expression in an expression list. This is +** just like sqlite3ResolveExprNames() except that it works for an expression +** list rather than a single expression. +*/ +SQLITE_PRIVATE int sqlite3ResolveExprListNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + ExprList *pList /* The expression list to be analyzed. */ +){ + int i; + int savedHasAgg = 0; + Walker w; + if( pList==0 ) return WRC_Continue; + w.pParse = pNC->pParse; + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.xSelectCallback2 = 0; + w.u.pNC = pNC; + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + if( pExpr==0 ) continue; +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight += pExpr->nHeight; + if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ + return WRC_Abort; + } +#endif + sqlite3WalkExprNN(&w, pExpr); +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight -= pExpr->nHeight; +#endif + assert( EP_Agg==NC_HasAgg ); + assert( EP_Win==NC_HasWin ); + testcase( pNC->ncFlags & NC_HasAgg ); + testcase( pNC->ncFlags & NC_HasWin ); + if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg) ){ + ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); + savedHasAgg |= pNC->ncFlags & + (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + } + if( w.pParse->nErr>0 ) return WRC_Abort; + } + pNC->ncFlags |= savedHasAgg; + return WRC_Continue; +} + +/* +** Resolve all names in all expressions of a SELECT and in all +** descendants of the SELECT, including compounds off of p->pPrior, +** subqueries in expressions, and subqueries used as FROM clause +** terms. +** +** See sqlite3ResolveExprNames() for a description of the kinds of +** transformations that occur. +** +** All SELECT statements should have been expanded using +** sqlite3SelectExpand() prior to invoking this routine. +*/ +SQLITE_PRIVATE void sqlite3ResolveSelectNames( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for parent SELECT statement */ +){ + Walker w; + + assert( p!=0 ); + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.xSelectCallback2 = 0; + w.pParse = pParse; + w.u.pNC = pOuterNC; + sqlite3WalkSelect(&w, p); +} + +/* +** Resolve names in expressions that can only reference a single table +** or which cannot reference any tables at all. Examples: +** +** "type" flag +** ------------ +** (1) CHECK constraints NC_IsCheck +** (2) WHERE clauses on partial indices NC_PartIdx +** (3) Expressions in indexes on expressions NC_IdxExpr +** (4) Expression arguments to VACUUM INTO. 0 +** (5) GENERATED ALWAYS as expressions NC_GenCol +** +** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN +** nodes of the expression is set to -1 and the Expr.iColumn value is +** set to the column number. In case (4), TK_COLUMN nodes cause an error. +** +** Any errors cause an error message to be set in pParse. +*/ +SQLITE_PRIVATE int sqlite3ResolveSelfReference( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table being referenced, or NULL */ + int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ + Expr *pExpr, /* Expression to resolve. May be NULL. */ + ExprList *pList /* Expression list to resolve. May be NULL. */ +){ + SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ + NameContext sNC; /* Name context for pParse->pNewTable */ + int rc; + + assert( type==0 || pTab!=0 ); + assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr + || type==NC_GenCol || pTab==0 ); + memset(&sNC, 0, sizeof(sNC)); + memset(&sSrc, 0, sizeof(sSrc)); + if( pTab ){ + sSrc.nSrc = 1; + sSrc.a[0].zName = pTab->zName; + sSrc.a[0].pTab = pTab; + sSrc.a[0].iCursor = -1; + if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ + /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP + ** schema elements */ + type |= NC_FromDDL; + } + } + sNC.pParse = pParse; + sNC.pSrcList = &sSrc; + sNC.ncFlags = type | NC_IsDDL; + if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; + if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); + return rc; +} + +/************** End of resolve.c *********************************************/ +/************** Begin file expr.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used for analyzing expressions and +** for generating VDBE code that evaluates expressions in SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* Forward declarations */ +static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); +static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); + +/* +** Return the affinity character for a single column of a table. +*/ +SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){ + if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER; + return pTab->aCol[iCol].affinity; +} + +/* +** Return the 'affinity' of the expression pExpr if any. +** +** If pExpr is a column, a reference to a column via an 'AS' alias, +** or a sub-select with a column as the return value, then the +** affinity of that column is returned. Otherwise, 0x00 is returned, +** indicating no affinity for the expression. +** +** i.e. the WHERE clause expressions in the following statements all +** have an affinity: +** +** CREATE TABLE t1(a); +** SELECT * FROM t1 WHERE a; +** SELECT a AS b FROM t1 WHERE b; +** SELECT * FROM t1 WHERE (select a from t1); +*/ +SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ + int op; + op = pExpr->op; + while( 1 /* exit-by-break */ ){ + if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){ + assert( ExprUseYTab(pExpr) ); + assert( pExpr->y.pTab!=0 ); + return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + } + if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( pExpr->x.pSelect->pEList!=0 ); + assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + } +#ifndef SQLITE_OMIT_CAST + if( op==TK_CAST ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + return sqlite3AffinityType(pExpr->u.zToken, 0); + } +#endif + if( op==TK_SELECT_COLUMN ){ + assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); + assert( pExpr->iColumn < pExpr->iTable ); + assert( pExpr->iColumn >= 0 ); + assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); + return sqlite3ExprAffinity( + pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr + ); + } + if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); + } + if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ + assert( pExpr->op==TK_COLLATE + || pExpr->op==TK_IF_NULL_ROW + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); + pExpr = pExpr->pLeft; + op = pExpr->op; + continue; + } + if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + } + return pExpr->affExpr; +} + +/* +** Make a guess at all the possible datatypes of the result that could +** be returned by an expression. Return a bitmask indicating the answer: +** +** 0x01 Numeric +** 0x02 Text +** 0x04 Blob +** +** If the expression must return NULL, then 0x00 is returned. +*/ +SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){ + while( pExpr ){ + switch( pExpr->op ){ + case TK_COLLATE: + case TK_IF_NULL_ROW: + case TK_UPLUS: { + pExpr = pExpr->pLeft; + break; + } + case TK_NULL: { + pExpr = 0; + break; + } + case TK_STRING: { + return 0x02; + } + case TK_BLOB: { + return 0x04; + } + case TK_CONCAT: { + return 0x06; + } + case TK_VARIABLE: + case TK_AGG_FUNCTION: + case TK_FUNCTION: { + return 0x07; + } + case TK_COLUMN: + case TK_AGG_COLUMN: + case TK_SELECT: + case TK_CAST: + case TK_SELECT_COLUMN: + case TK_VECTOR: { + int aff = sqlite3ExprAffinity(pExpr); + if( aff>=SQLITE_AFF_NUMERIC ) return 0x05; + if( aff==SQLITE_AFF_TEXT ) return 0x06; + return 0x07; + } + case TK_CASE: { + int res = 0; + int ii; + ExprList *pList = pExpr->x.pList; + assert( ExprUseXList(pExpr) && pList!=0 ); + assert( pList->nExpr > 0); + for(ii=1; iinExpr; ii+=2){ + res |= sqlite3ExprDataType(pList->a[ii].pExpr); + } + if( pList->nExpr % 2 ){ + res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr); + } + return res; + } + default: { + return 0x01; + } + } /* End of switch(op) */ + } /* End of while(pExpr) */ + return 0x00; +} + +/* +** Set the collating sequence for expression pExpr to be the collating +** sequence named by pToken. Return a pointer to a new Expr node that +** implements the COLLATE operator. +** +** If a memory allocation error occurs, that fact is recorded in pParse->db +** and the pExpr parameter is returned unchanged. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( + const Parse *pParse, /* Parsing context */ + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ + const Token *pCollName, /* Name of collating sequence */ + int dequote /* True to dequote pCollName */ +){ + if( pCollName->n>0 ){ + Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); + if( pNew ){ + pNew->pLeft = pExpr; + pNew->flags |= EP_Collate|EP_Skip; + pExpr = pNew; + } + } + return pExpr; +} +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString( + const Parse *pParse, /* Parsing context */ + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ + const char *zC /* The collating sequence name */ +){ + Token s; + assert( zC!=0 ); + sqlite3TokenInit(&s, (char*)zC); + return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); +} + +/* +** Skip over any TK_COLLATE operators. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ + while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ + assert( pExpr->op==TK_COLLATE ); + pExpr = pExpr->pLeft; + } + return pExpr; +} + +/* +** Skip over any TK_COLLATE operators and/or any unlikely() +** or likelihood() or likely() functions at the root of an +** expression. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ + while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){ + if( ExprHasProperty(pExpr, EP_Unlikely) ){ + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr>0 ); + assert( pExpr->op==TK_FUNCTION ); + pExpr = pExpr->x.pList->a[0].pExpr; + }else if( pExpr->op==TK_COLLATE ){ + pExpr = pExpr->pLeft; + }else{ + break; + } + } + return pExpr; +} + +/* +** Return the collation sequence for the expression pExpr. If +** there is no defined collating sequence, return NULL. +** +** See also: sqlite3ExprNNCollSeq() +** +** The sqlite3ExprNNCollSeq() works the same exact that it returns the +** default collation if pExpr has no defined collation. +** +** The collating sequence might be determined by a COLLATE operator +** or by the presence of a column with a defined collating sequence. +** COLLATE operators take first precedence. Left operands take +** precedence over right operands. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ + sqlite3 *db = pParse->db; + CollSeq *pColl = 0; + const Expr *p = pExpr; + while( p ){ + int op = p->op; + if( op==TK_REGISTER ) op = p->op2; + if( (op==TK_AGG_COLUMN && p->y.pTab!=0) + || op==TK_COLUMN || op==TK_TRIGGER + ){ + int j; + assert( ExprUseYTab(p) ); + assert( p->y.pTab!=0 ); + if( (j = p->iColumn)>=0 ){ + const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; + } + if( op==TK_CAST || op==TK_UPLUS ){ + p = p->pLeft; + continue; + } + if( op==TK_VECTOR ){ + assert( ExprUseXList(p) ); + p = p->x.pList->a[0].pExpr; + continue; + } + if( op==TK_COLLATE ){ + assert( !ExprHasProperty(p, EP_IntValue) ); + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); + break; + } + if( p->flags & EP_Collate ){ + if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ + p = p->pLeft; + }else{ + Expr *pNext = p->pRight; + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 ); + if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ + pNext = p->x.pList->a[i].pExpr; + break; + } + } + } + p = pNext; + } + }else{ + break; + } + } + if( sqlite3CheckCollSeq(pParse, pColl) ){ + pColl = 0; + } + return pColl; +} + +/* +** Return the collation sequence for the expression pExpr. If +** there is no defined collating sequence, return a pointer to the +** default collation sequence. +** +** See also: sqlite3ExprCollSeq() +** +** The sqlite3ExprCollSeq() routine works the same except that it +** returns NULL if there is no defined collation. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){ + CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr); + if( p==0 ) p = pParse->db->pDfltColl; + assert( p!=0 ); + return p; +} + +/* +** Return TRUE if the two expressions have equivalent collating sequences. +*/ +SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){ + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); + CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); + return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; +} + +/* +** pExpr is an operand of a comparison operator. aff2 is the +** type affinity of the other operand. This routine returns the +** type affinity that should be used for the comparison operator. +*/ +SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2){ + char aff1 = sqlite3ExprAffinity(pExpr); + if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){ + /* Both sides of the comparison are columns. If one has numeric + ** affinity, use that. Otherwise use no affinity. + */ + if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ + return SQLITE_AFF_NUMERIC; + }else{ + return SQLITE_AFF_BLOB; + } + }else{ + /* One side is a column, the other is not. Use the columns affinity. */ + assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE ); + return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE; + } +} + +/* +** pExpr is a comparison operator. Return the type affinity that should +** be applied to both operands prior to doing the comparison. +*/ +static char comparisonAffinity(const Expr *pExpr){ + char aff; + assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || + pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || + pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); + assert( pExpr->pLeft ); + aff = sqlite3ExprAffinity(pExpr->pLeft); + if( pExpr->pRight ){ + aff = sqlite3CompareAffinity(pExpr->pRight, aff); + }else if( ExprUseXSelect(pExpr) ){ + aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); + }else if( aff==0 ){ + aff = SQLITE_AFF_BLOB; + } + return aff; +} + +/* +** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. +** idx_affinity is the affinity of an indexed column. Return true +** if the index with affinity idx_affinity may be used to implement +** the comparison in pExpr. +*/ +SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){ + char aff = comparisonAffinity(pExpr); + if( affflags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + }else if( pRight && (pRight->flags & EP_Collate)!=0 ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + }else{ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + if( !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + } + } + return pColl; +} + +/* Expression p is a comparison operator. Return a collation sequence +** appropriate for the comparison operator. +** +** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). +** However, if the OP_Commuted flag is set, then the order of the operands +** is reversed in the sqlite3BinaryCompareCollSeq() call so that the +** correct collating sequence is found. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){ + if( ExprHasProperty(p, EP_Commuted) ){ + return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft); + }else{ + return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight); + } +} + +/* +** Generate code for a comparison operator. +*/ +static int codeCompare( + Parse *pParse, /* The parsing (and code generating) context */ + Expr *pLeft, /* The left operand */ + Expr *pRight, /* The right operand */ + int opcode, /* The comparison opcode */ + int in1, int in2, /* Register holding operands */ + int dest, /* Jump here if true. */ + int jumpIfNull, /* If true, jump if either operand is NULL */ + int isCommuted /* The comparison has been commuted */ +){ + int p5; + int addr; + CollSeq *p4; + + if( pParse->nErr ) return 0; + if( isCommuted ){ + p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); + }else{ + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + } + p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); + addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, + (void*)p4, P4_COLLSEQ); + sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + return addr; +} + +/* +** Return true if expression pExpr is a vector, or false otherwise. +** +** A vector is defined as any expression that results in two or more +** columns of result. Every TK_VECTOR node is an vector because the +** parser will not generate a TK_VECTOR with fewer than two entries. +** But a TK_SELECT might be either a vector or a scalar. It is only +** considered a vector if it has two or more result columns. +*/ +SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr){ + return sqlite3ExprVectorSize(pExpr)>1; +} + +/* +** If the expression passed as the only argument is of type TK_VECTOR +** return the number of expressions in the vector. Or, if the expression +** is a sub-select, return the number of columns in the sub-select. For +** any other type of expression, return 1. +*/ +SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){ + u8 op = pExpr->op; + if( op==TK_REGISTER ) op = pExpr->op2; + if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + return pExpr->x.pList->nExpr; + }else if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + return pExpr->x.pSelect->pEList->nExpr; + }else{ + return 1; + } +} + +/* +** Return a pointer to a subexpression of pVector that is the i-th +** column of the vector (numbered starting with 0). The caller must +** ensure that i is within range. +** +** If pVector is really a scalar (and "scalar" here includes subqueries +** that return a single column!) then return pVector unmodified. +** +** pVector retains ownership of the returned subexpression. +** +** If the vector is a (SELECT ...) then the expression returned is +** just the expression for the i-th term of the result set, and may +** not be ready for evaluation because the table cursor has not yet +** been positioned. +*/ +SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ + assert( iop==TK_ERROR ); + if( sqlite3ExprIsVector(pVector) ){ + assert( pVector->op2==0 || pVector->op==TK_REGISTER ); + if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); + return pVector->x.pSelect->pEList->a[i].pExpr; + }else{ + assert( ExprUseXList(pVector) ); + return pVector->x.pList->a[i].pExpr; + } + } + return pVector; +} + +/* +** Compute and return a new Expr object which when passed to +** sqlite3ExprCode() will generate all necessary code to compute +** the iField-th column of the vector expression pVector. +** +** It is ok for pVector to be a scalar (as long as iField==0). +** In that case, this routine works like sqlite3ExprDup(). +** +** The caller owns the returned Expr object and is responsible for +** ensuring that the returned value eventually gets freed. +** +** The caller retains ownership of pVector. If pVector is a TK_SELECT, +** then the returned object will reference pVector and so pVector must remain +** valid for the life of the returned object. If pVector is a TK_VECTOR +** or a scalar expression, then it can be deleted as soon as this routine +** returns. +** +** A trick to cause a TK_SELECT pVector to be deleted together with +** the returned Expr object is to attach the pVector to the pRight field +** of the returned TK_SELECT_COLUMN Expr object. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( + Parse *pParse, /* Parsing context */ + Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ + int iField, /* Which column of the vector to return */ + int nField /* Total number of columns in the vector */ +){ + Expr *pRet; + if( pVector->op==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); + /* The TK_SELECT_COLUMN Expr node: + ** + ** pLeft: pVector containing TK_SELECT. Not deleted. + ** pRight: not used. But recursively deleted. + ** iColumn: Index of a column in pVector + ** iTable: 0 or the number of columns on the LHS of an assignment + ** pLeft->iTable: First in an array of register holding result, or 0 + ** if the result is not yet computed. + ** + ** sqlite3ExprDelete() specifically skips the recursive delete of + ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector + ** can be attached to pRight to cause this node to take ownership of + ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes + ** with the same pLeft pointer to the pVector, but only one of them + ** will own the pVector. + */ + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); + if( pRet ){ + ExprSetProperty(pRet, EP_FullSize); + pRet->iTable = nField; + pRet->iColumn = iField; + pRet->pLeft = pVector; + } + }else{ + if( pVector->op==TK_VECTOR ){ + Expr **ppVector; + assert( ExprUseXList(pVector) ); + ppVector = &pVector->x.pList->a[iField].pExpr; + pVector = *ppVector; + if( IN_RENAME_OBJECT ){ + /* This must be a vector UPDATE inside a trigger */ + *ppVector = 0; + return pVector; + } + } + pRet = sqlite3ExprDup(pParse->db, pVector, 0); + } + return pRet; +} + +/* +** If expression pExpr is of type TK_SELECT, generate code to evaluate +** it. Return the register in which the result is stored (or, if the +** sub-select returns more than one column, the first in an array +** of registers in which the result is stored). +** +** If pExpr is not a TK_SELECT expression, return 0. +*/ +static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ + int reg = 0; +#ifndef SQLITE_OMIT_SUBQUERY + if( pExpr->op==TK_SELECT ){ + reg = sqlite3CodeSubselect(pParse, pExpr); + } +#endif + return reg; +} + +/* +** Argument pVector points to a vector expression - either a TK_VECTOR +** or TK_SELECT that returns more than one column. This function returns +** the register number of a register that contains the value of +** element iField of the vector. +** +** If pVector is a TK_SELECT expression, then code for it must have +** already been generated using the exprCodeSubselect() routine. In this +** case parameter regSelect should be the first in an array of registers +** containing the results of the sub-select. +** +** If pVector is of type TK_VECTOR, then code for the requested field +** is generated. In this case (*pRegFree) may be set to the number of +** a temporary register to be freed by the caller before returning. +** +** Before returning, output parameter (*ppExpr) is set to point to the +** Expr object corresponding to element iElem of the vector. +*/ +static int exprVectorRegister( + Parse *pParse, /* Parse context */ + Expr *pVector, /* Vector to extract element from */ + int iField, /* Field to extract from pVector */ + int regSelect, /* First in array of registers */ + Expr **ppExpr, /* OUT: Expression element */ + int *pRegFree /* OUT: Temp register to free */ +){ + u8 op = pVector->op; + assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR ); + if( op==TK_REGISTER ){ + *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); + return pVector->iTable+iField; + } + if( op==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); + *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; + return regSelect+iField; + } + if( op==TK_VECTOR ){ + assert( ExprUseXList(pVector) ); + *ppExpr = pVector->x.pList->a[iField].pExpr; + return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); + } + return 0; +} + +/* +** Expression pExpr is a comparison between two vector values. Compute +** the result of the comparison (1, 0, or NULL) and write that +** result into register dest. +** +** The caller must satisfy the following preconditions: +** +** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ +** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ +** otherwise: op==pExpr->op and p5==0 +*/ +static void codeVectorCompare( + Parse *pParse, /* Code generator context */ + Expr *pExpr, /* The comparison operation */ + int dest, /* Write results into this register */ + u8 op, /* Comparison operator */ + u8 p5 /* SQLITE_NULLEQ or zero */ +){ + Vdbe *v = pParse->pVdbe; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + int nLeft = sqlite3ExprVectorSize(pLeft); + int i; + int regLeft = 0; + int regRight = 0; + u8 opx = op; + int addrCmp = 0; + int addrDone = sqlite3VdbeMakeLabel(pParse); + int isCommuted = ExprHasProperty(pExpr,EP_Commuted); + + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + if( pParse->nErr ) return; + if( nLeft!=sqlite3ExprVectorSize(pRight) ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return; + } + assert( pExpr->op==TK_EQ || pExpr->op==TK_NE + || pExpr->op==TK_IS || pExpr->op==TK_ISNOT + || pExpr->op==TK_LT || pExpr->op==TK_GT + || pExpr->op==TK_LE || pExpr->op==TK_GE + ); + assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) + || (pExpr->op==TK_ISNOT && op==TK_NE) ); + assert( p5==0 || pExpr->op!=op ); + assert( p5==SQLITE_NULLEQ || pExpr->op==op ); + + if( op==TK_LE ) opx = TK_LT; + if( op==TK_GE ) opx = TK_GT; + if( op==TK_NE ) opx = TK_EQ; + + regLeft = exprCodeSubselect(pParse, pLeft); + regRight = exprCodeSubselect(pParse, pRight); + + sqlite3VdbeAddOp2(v, OP_Integer, 1, dest); + for(i=0; 1 /*Loop exits by "break"*/; i++){ + int regFree1 = 0, regFree2 = 0; + Expr *pL = 0, *pR = 0; + int r1, r2; + assert( i>=0 && i0 +/* +** Check that argument nHeight is less than or equal to the maximum +** expression depth allowed. If it is not, leave an error message in +** pParse. +*/ +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ + int rc = SQLITE_OK; + int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; + if( nHeight>mxHeight ){ + sqlite3ErrorMsg(pParse, + "Expression tree is too large (maximum depth %d)", mxHeight + ); + rc = SQLITE_ERROR; + } + return rc; +} + +/* The following three functions, heightOfExpr(), heightOfExprList() +** and heightOfSelect(), are used to determine the maximum height +** of any expression tree referenced by the structure passed as the +** first argument. +** +** If this maximum height is greater than the current value pointed +** to by pnHeight, the second parameter, then set *pnHeight to that +** value. +*/ +static void heightOfExpr(const Expr *p, int *pnHeight){ + if( p ){ + if( p->nHeight>*pnHeight ){ + *pnHeight = p->nHeight; + } + } +} +static void heightOfExprList(const ExprList *p, int *pnHeight){ + if( p ){ + int i; + for(i=0; inExpr; i++){ + heightOfExpr(p->a[i].pExpr, pnHeight); + } + } +} +static void heightOfSelect(const Select *pSelect, int *pnHeight){ + const Select *p; + for(p=pSelect; p; p=p->pPrior){ + heightOfExpr(p->pWhere, pnHeight); + heightOfExpr(p->pHaving, pnHeight); + heightOfExpr(p->pLimit, pnHeight); + heightOfExprList(p->pEList, pnHeight); + heightOfExprList(p->pGroupBy, pnHeight); + heightOfExprList(p->pOrderBy, pnHeight); + } +} + +/* +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or +** Expr.pSelect member has a height of 1. Any other expression +** has a height equal to the maximum height of any other +** referenced Expr plus one. +** +** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, +** if appropriate. +*/ +static void exprSetHeight(Expr *p){ + int nHeight = p->pLeft ? p->pLeft->nHeight : 0; + if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){ + nHeight = p->pRight->nHeight; + } + if( ExprUseXSelect(p) ){ + heightOfSelect(p->x.pSelect, &nHeight); + }else if( p->x.pList ){ + heightOfExprList(p->x.pList, &nHeight); + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } + p->nHeight = nHeight + 1; +} + +/* +** Set the Expr.nHeight variable using the exprSetHeight() function. If +** the height is greater than the maximum allowed expression depth, +** leave an error in pParse. +** +** Also propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; + exprSetHeight(p); + sqlite3ExprCheckHeight(pParse, p->nHeight); +} + +/* +** Return the maximum height of any expression tree referenced +** by the select statement passed as an argument. +*/ +SQLITE_PRIVATE int sqlite3SelectExprHeight(const Select *p){ + int nHeight = 0; + heightOfSelect(p, &nHeight); + return nHeight; +} +#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */ +/* +** Propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; + if( p && ExprUseXList(p) && p->x.pList ){ + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } +} +#define exprSetHeight(y) +#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ + +/* +** Set the error offset for an Expr node, if possible. +*/ +SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ + if( pExpr==0 ) return; + if( NEVER(ExprUseWJoin(pExpr)) ) return; + pExpr->w.iOfst = iOfst; +} + +/* +** This routine is the core allocator for Expr nodes. +** +** Construct a new expression node and return a pointer to it. Memory +** for this node and for the pToken argument is a single allocation +** obtained from sqlite3DbMalloc(). The calling function +** is responsible for making sure the node eventually gets freed. +** +** If dequote is true, then the token (if it exists) is dequoted. +** If dequote is false, no dequoting is performed. The deQuote +** parameter is ignored if pToken is NULL or if the token does not +** appear to be quoted. If the quotes were of the form "..." (double-quotes) +** then the EP_DblQuoted flag is set on the expression node. +** +** Special case: If op==TK_INTEGER and pToken points to a string that +** can be translated into a 32-bit integer, then the token is not +** stored in u.zToken. Instead, the integer values is written +** into u.iValue and the EP_IntValue flag is set. No extra storage +** is allocated to hold the integer text and the dequote flag is ignored. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAlloc( + sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ + int op, /* Expression opcode */ + const Token *pToken, /* Token argument. Might be NULL */ + int dequote /* True to dequote */ +){ + Expr *pNew; + int nExtra = 0; + int iValue = 0; + + assert( db!=0 ); + if( pToken ){ + if( op!=TK_INTEGER || pToken->z==0 + || sqlite3GetInt32(pToken->z, &iValue)==0 ){ + nExtra = pToken->n+1; + assert( iValue>=0 ); + } + } + pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); + if( pNew ){ + memset(pNew, 0, sizeof(Expr)); + pNew->op = (u8)op; + pNew->iAgg = -1; + if( pToken ){ + if( nExtra==0 ){ + pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse); + pNew->u.iValue = iValue; + }else{ + pNew->u.zToken = (char*)&pNew[1]; + assert( pToken->z!=0 || pToken->n==0 ); + if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); + pNew->u.zToken[pToken->n] = 0; + if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ + sqlite3DequoteExpr(pNew); + } + } + } +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = 1; +#endif + } + return pNew; +} + +/* +** Allocate a new expression node from a zero-terminated token that has +** already been dequoted. +*/ +SQLITE_PRIVATE Expr *sqlite3Expr( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + int op, /* Expression opcode */ + const char *zToken /* Token argument. Might be NULL */ +){ + Token x; + x.z = zToken; + x.n = sqlite3Strlen30(zToken); + return sqlite3ExprAlloc(db, op, &x, 0); +} + +/* +** Attach subtrees pLeft and pRight to the Expr node pRoot. +** +** If pRoot==NULL that means that a memory allocation error has occurred. +** In that case, delete the subtrees pLeft and pRight. +*/ +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( + sqlite3 *db, + Expr *pRoot, + Expr *pLeft, + Expr *pRight +){ + if( pRoot==0 ){ + assert( db->mallocFailed ); + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + }else{ + assert( ExprUseXList(pRoot) ); + assert( pRoot->x.pSelect==0 ); + if( pRight ){ + pRoot->pRight = pRight; + pRoot->flags |= EP_Propagate & pRight->flags; +#if SQLITE_MAX_EXPR_DEPTH>0 + pRoot->nHeight = pRight->nHeight+1; + }else{ + pRoot->nHeight = 1; +#endif + } + if( pLeft ){ + pRoot->pLeft = pLeft; + pRoot->flags |= EP_Propagate & pLeft->flags; +#if SQLITE_MAX_EXPR_DEPTH>0 + if( pLeft->nHeight>=pRoot->nHeight ){ + pRoot->nHeight = pLeft->nHeight+1; + } +#endif + } + } +} + +/* +** Allocate an Expr node which joins as many as two subtrees. +** +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. +*/ +SQLITE_PRIVATE Expr *sqlite3PExpr( + Parse *pParse, /* Parsing context */ + int op, /* Expression opcode */ + Expr *pLeft, /* Left operand */ + Expr *pRight /* Right operand */ +){ + Expr *p; + p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); + if( p ){ + memset(p, 0, sizeof(Expr)); + p->op = op & 0xff; + p->iAgg = -1; + sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + sqlite3ExprCheckHeight(pParse, p->nHeight); + }else{ + sqlite3ExprDelete(pParse->db, pLeft); + sqlite3ExprDelete(pParse->db, pRight); + } + return p; +} + +/* +** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due +** do a memory allocation failure) then delete the pSelect object. +*/ +SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ + if( pExpr ){ + pExpr->x.pSelect = pSelect; + ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, pExpr); + }else{ + assert( pParse->db->mallocFailed ); + sqlite3SelectDelete(pParse->db, pSelect); + } +} + +/* +** Expression list pEList is a list of vector values. This function +** converts the contents of pEList to a VALUES(...) Select statement +** returning 1 row for each element of the list. For example, the +** expression list: +** +** ( (1,2), (3,4) (5,6) ) +** +** is translated to the equivalent of: +** +** VALUES(1,2), (3,4), (5,6) +** +** Each of the vector values in pEList must contain exactly nElem terms. +** If a list element that is not a vector or does not contain nElem terms, +** an error message is left in pParse. +** +** This is used as part of processing IN(...) expressions with a list +** of vectors on the RHS. e.g. "... IN ((1,2), (3,4), (5,6))". +*/ +SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){ + int ii; + Select *pRet = 0; + assert( nElem>1 ); + for(ii=0; iinExpr; ii++){ + Select *pSel; + Expr *pExpr = pEList->a[ii].pExpr; + int nExprElem; + if( pExpr->op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + nExprElem = pExpr->x.pList->nExpr; + }else{ + nExprElem = 1; + } + if( nExprElem!=nElem ){ + sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d", + nExprElem, nExprElem>1?"s":"", nElem + ); + break; + } + assert( ExprUseXList(pExpr) ); + pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0); + pExpr->x.pList = 0; + if( pSel ){ + if( pRet ){ + pSel->op = TK_ALL; + pSel->pPrior = pRet; + } + pRet = pSel; + } + } + + if( pRet && pRet->pPrior ){ + pRet->selFlags |= SF_MultiValue; + } + sqlite3ExprListDelete(pParse->db, pEList); + return pRet; +} + +/* +** Join two expressions using an AND operator. If either expression is +** NULL, then just return the other expression. +** +** If one side or the other of the AND is known to be false, and neither side +** is part of an ON clause, then instead of returning an AND expression, +** just return a constant expression with a value of false. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ + sqlite3 *db = pParse->db; + if( pLeft==0 ){ + return pRight; + }else if( pRight==0 ){ + return pLeft; + }else{ + u32 f = pLeft->flags | pRight->flags; + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse + && !IN_RENAME_OBJECT + ){ + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); + return sqlite3Expr(db, TK_INTEGER, "0"); + }else{ + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); + } + } +} + +/* +** Construct a new expression node for a function with multiple +** arguments. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprFunction( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Argument list */ + const Token *pToken, /* Name of the function */ + int eDistinct /* SF_Distinct or SF_ALL or 0 */ +){ + Expr *pNew; + sqlite3 *db = pParse->db; + assert( pToken ); + pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ + return 0; + } + assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) ); + pNew->w.iOfst = (int)(pToken->z - pParse->zTail); + if( pList + && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] + && !pParse->nested + ){ + sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); + } + pNew->x.pList = pList; + ExprSetProperty(pNew, EP_HasFunc); + assert( ExprUseXList(pNew) ); + sqlite3ExprSetHeightAndFlags(pParse, pNew); + if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); + return pNew; +} + +/* +** Report an error when attempting to use an ORDER BY clause within +** the arguments of a non-aggregate function. +*/ +SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ + sqlite3ErrorMsg(pParse, + "ORDER BY may not be used with non-aggregate %#T()", p + ); +} + +/* +** Attach an ORDER BY clause to a function call. +** +** functionname( arguments ORDER BY sortlist ) +** \_____________________/ \______/ +** pExpr pOrderBy +** +** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER +** and added to the Expr.pLeft field of the parent TK_FUNCTION node. +*/ +SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The function call to which ORDER BY is to be added */ + ExprList *pOrderBy /* The ORDER BY clause to add */ +){ + Expr *pOB; + sqlite3 *db = pParse->db; + if( NEVER(pOrderBy==0) ){ + assert( db->mallocFailed ); + return; + } + if( pExpr==0 ){ + assert( db->mallocFailed ); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + assert( pExpr->op==TK_FUNCTION ); + assert( pExpr->pLeft==0 ); + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ + /* Ignore ORDER BY on zero-argument aggregates */ + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy); + return; + } + if( IsWindowFunc(pExpr) ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); + if( pOB==0 ){ + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB->x.pList = pOrderBy; + assert( ExprUseXList(pOB) ); + pExpr->pLeft = pOB; + ExprSetProperty(pOB, EP_FullSize); +} + +/* +** Check to see if a function is usable according to current access +** rules: +** +** SQLITE_FUNC_DIRECT - Only usable from top-level SQL +** +** SQLITE_FUNC_UNSAFE - Usable if TRUSTED_SCHEMA or from +** top-level SQL +** +** If the function is not usable, create an error. +*/ +SQLITE_PRIVATE void sqlite3ExprFunctionUsable( + Parse *pParse, /* Parsing and code generating context */ + const Expr *pExpr, /* The function invocation */ + const FuncDef *pDef /* The function being invoked */ +){ + assert( !IN_RENAME_OBJECT ); + assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); + if( ExprHasProperty(pExpr, EP_FromDDL) ){ + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + || (pParse->db->flags & SQLITE_TrustedSchema)==0 + ){ + /* Functions prohibited in triggers and views if: + ** (1) tagged with SQLITE_DIRECTONLY + ** (2) not tagged with SQLITE_INNOCUOUS (which means it + ** is tagged with SQLITE_FUNC_UNSAFE) and + ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning + ** that the schema is possibly tainted). + */ + sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr); + } + } +} + +/* +** Assign a variable number to an expression that encodes a wildcard +** in the original SQL statement. +** +** Wildcards consisting of a single "?" are assigned the next sequential +** variable number. +** +** Wildcards of the form "?nnn" are assigned the number "nnn". We make +** sure "nnn" is not too big to avoid a denial of service attack when +** the SQL statement comes from an external source. +** +** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number +** as the previous instance of the same wildcard. Or if this is the first +** instance of the wildcard, the next sequential variable number is +** assigned. +*/ +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ + sqlite3 *db = pParse->db; + const char *z; + ynVar x; + + if( pExpr==0 ) return; + assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); + z = pExpr->u.zToken; + assert( z!=0 ); + assert( z[0]!=0 ); + assert( n==(u32)sqlite3Strlen30(z) ); + if( z[1]==0 ){ + /* Wildcard of the form "?". Assign the next variable number */ + assert( z[0]=='?' ); + x = (ynVar)(++pParse->nVar); + }else{ + int doAdd = 0; + if( z[0]=='?' ){ + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and + ** use it as the variable number */ + i64 i; + int bOk; + if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/ + i = z[1]-'0'; /* The common case of ?N for a single digit N */ + bOk = 1; + }else{ + bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + } + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + return; + } + x = (ynVar)i; + if( x>pParse->nVar ){ + pParse->nVar = (int)x; + doAdd = 1; + }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ + doAdd = 1; + } + }else{ + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable + ** number as the prior appearance of the same name, or if the name + ** has never appeared before, reuse the same variable number + */ + x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n); + if( x==0 ){ + x = (ynVar)(++pParse->nVar); + doAdd = 1; + } + } + if( doAdd ){ + pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); + } + } + pExpr->iColumn = x; + if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "too many SQL variables"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + } +} + +/* +** Recursively delete an expression tree. +*/ +static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ + assert( p!=0 ); + assert( db!=0 ); + assert( !ExprUseUValue(p) || p->u.iValue>=0 ); + assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); + assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); + assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) ); +#ifdef SQLITE_DEBUG + if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ + assert( p->pLeft==0 ); + assert( p->pRight==0 ); + assert( !ExprUseXSelect(p) || p->x.pSelect==0 ); + assert( !ExprUseXList(p) || p->x.pList==0 ); + } +#endif + if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); + if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); + if( p->pRight ){ + assert( !ExprHasProperty(p, EP_WinFunc) ); + sqlite3ExprDeleteNN(db, p->pRight); + }else if( ExprUseXSelect(p) ){ + assert( !ExprHasProperty(p, EP_WinFunc) ); + sqlite3SelectDelete(db, p->x.pSelect); + }else{ + sqlite3ExprListDelete(db, p->x.pList); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(p, EP_WinFunc) ){ + sqlite3WindowDelete(db, p->y.pWin); + } +#endif + } + } + if( !ExprHasProperty(p, EP_Static) ){ + sqlite3DbNNFreeNN(db, p); + } +} +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ + if( p ) sqlite3ExprDeleteNN(db, p); +} +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p); +} + +/* +** Clear both elements of an OnOrUsing object +*/ +SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ + if( p==0 ){ + /* Nothing to clear */ + }else if( p->pOn ){ + sqlite3ExprDeleteNN(db, p->pOn); + }else if( p->pUsing ){ + sqlite3IdListDelete(db, p->pUsing); + } +} + +/* +** Arrange to cause pExpr to be deleted when the pParse is deleted. +** This is similar to sqlite3ExprDelete() except that the delete is +** deferred until the pParse is deleted. +** +** The pExpr might be deleted immediately on an OOM error. +** +** The deferred delete is (currently) implemented by adding the +** pExpr to the pParse->pConstExpr list with a register number of 0. +*/ +SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); +} + +/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the +** expression. +*/ +SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){ + if( p ){ + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, p); + } + sqlite3ExprDeleteNN(pParse->db, p); + } +} + +/* +** Return the number of bytes allocated for the expression structure +** passed as the first argument. This is always one of EXPR_FULLSIZE, +** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. +*/ +static int exprStructSize(const Expr *p){ + if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; + if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; + return EXPR_FULLSIZE; +} + +/* +** The dupedExpr*Size() routines each return the number of bytes required +** to store a copy of an expression or expression tree. They differ in +** how much of the tree is measured. +** +** dupedExprStructSize() Size of only the Expr structure +** dupedExprNodeSize() Size of Expr + space for token +** dupedExprSize() Expr + token + subtree components +** +*************************************************************************** +** +** The dupedExprStructSize() function returns two values OR-ed together: +** (1) the space required for a copy of the Expr structure only and +** (2) the EP_xxx flags that indicate what the structure size should be. +** The return values is always one of: +** +** EXPR_FULLSIZE +** EXPR_REDUCEDSIZE | EP_Reduced +** EXPR_TOKENONLYSIZE | EP_TokenOnly +** +** The size of the structure can be found by masking the return value +** of this routine with 0xfff. The flags can be found by masking the +** return value with EP_Reduced|EP_TokenOnly. +** +** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size +** (unreduced) Expr objects as they or originally constructed by the parser. +** During expression analysis, extra information is computed and moved into +** later parts of the Expr object and that extra information might get chopped +** off if the expression is reduced. Note also that it does not work to +** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal +** to reduce a pristine expression tree from the parser. The implementation +** of dupedExprStructSize() contain multiple assert() statements that attempt +** to enforce this constraint. +*/ +static int dupedExprStructSize(const Expr *p, int flags){ + int nSize; + assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ + assert( EXPR_FULLSIZE<=0xfff ); + assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); + if( 0==flags || ExprHasProperty(p, EP_FullSize) ){ + nSize = EXPR_FULLSIZE; + }else{ + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); + assert( !ExprHasProperty(p, EP_OuterON) ); + assert( !ExprHasVVAProperty(p, EP_NoReduce) ); + if( p->pLeft || p->x.pList ){ + nSize = EXPR_REDUCEDSIZE | EP_Reduced; + }else{ + assert( p->pRight==0 ); + nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; + } + } + return nSize; +} + +/* +** This function returns the space in bytes required to store the copy +** of the Expr structure and a copy of the Expr.u.zToken string (if that +** string is defined.) +*/ +static int dupedExprNodeSize(const Expr *p, int flags){ + int nByte = dupedExprStructSize(p, flags) & 0xfff; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nByte += sqlite3Strlen30NN(p->u.zToken)+1; + } + return ROUND8(nByte); +} + +/* +** Return the number of bytes required to create a duplicate of the +** expression passed as the first argument. +** +** The value returned includes space to create a copy of the Expr struct +** itself and the buffer referred to by Expr.u.zToken, if any. +** +** The return value includes space to duplicate all Expr nodes in the +** tree formed by Expr.pLeft and Expr.pRight, but not any other +** substructure such as Expr.x.pList, Expr.x.pSelect, and Expr.y.pWin. +*/ +static int dupedExprSize(const Expr *p){ + int nByte; + assert( p!=0 ); + nByte = dupedExprNodeSize(p, EXPRDUP_REDUCE); + if( p->pLeft ) nByte += dupedExprSize(p->pLeft); + if( p->pRight ) nByte += dupedExprSize(p->pRight); + assert( nByte==ROUND8(nByte) ); + return nByte; +} + +/* +** An EdupBuf is a memory allocation used to stored multiple Expr objects +** together with their Expr.zToken content. This is used to help implement +** compression while doing sqlite3ExprDup(). The top-level Expr does the +** allocation for itself and many of its decendents, then passes an instance +** of the structure down into exprDup() so that they decendents can have +** access to that memory. +*/ +typedef struct EdupBuf EdupBuf; +struct EdupBuf { + u8 *zAlloc; /* Memory space available for storage */ +#ifdef SQLITE_DEBUG + u8 *zEnd; /* First byte past the end of memory */ +#endif +}; + +/* +** This function is similar to sqlite3ExprDup(), except that if pEdupBuf +** is not NULL then it points to memory that can be used to store a copy +** of the input Expr p together with its p->u.zToken (if any). pEdupBuf +** is updated with the new buffer tail prior to returning. +*/ +static Expr *exprDup( + sqlite3 *db, /* Database connection (for memory allocation) */ + const Expr *p, /* Expr tree to be duplicated */ + int dupFlags, /* EXPRDUP_REDUCE for compression. 0 if not */ + EdupBuf *pEdupBuf /* Preallocated storage space, or NULL */ +){ + Expr *pNew; /* Value to return */ + EdupBuf sEdupBuf; /* Memory space from which to build Expr object */ + u32 staticFlag; /* EP_Static if space not obtained from malloc */ + int nToken = -1; /* Space needed for p->u.zToken. -1 means unknown */ + + assert( db!=0 ); + assert( p ); + assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pEdupBuf==0 || dupFlags==EXPRDUP_REDUCE ); + + /* Figure out where to write the new Expr structure. */ + if( pEdupBuf ){ + sEdupBuf.zAlloc = pEdupBuf->zAlloc; +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = pEdupBuf->zEnd; +#endif + staticFlag = EP_Static; + assert( sEdupBuf.zAlloc!=0 ); + assert( dupFlags==EXPRDUP_REDUCE ); + }else{ + int nAlloc; + if( dupFlags ){ + nAlloc = dupedExprSize(p); + }else if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30NN(p->u.zToken)+1; + nAlloc = ROUND8(EXPR_FULLSIZE + nToken); + }else{ + nToken = 0; + nAlloc = ROUND8(EXPR_FULLSIZE); + } + assert( nAlloc==ROUND8(nAlloc) ); + sEdupBuf.zAlloc = sqlite3DbMallocRawNN(db, nAlloc); +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = sEdupBuf.zAlloc ? sEdupBuf.zAlloc+nAlloc : 0; +#endif + + staticFlag = 0; + } + pNew = (Expr *)sEdupBuf.zAlloc; + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); + + if( pNew ){ + /* Set nNewSize to the size allocated for the structure pointed to + ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or + ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed + ** by the copy of the p->u.zToken string (if any). + */ + const unsigned nStructSize = dupedExprStructSize(p, dupFlags); + int nNewSize = nStructSize & 0xfff; + if( nToken<0 ){ + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } + } + if( dupFlags ){ + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= nNewSize+nToken ); + assert( ExprHasProperty(p, EP_Reduced)==0 ); + memcpy(sEdupBuf.zAlloc, p, nNewSize); + }else{ + u32 nSize = (u32)exprStructSize(p); + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= + (int)EXPR_FULLSIZE+nToken ); + memcpy(sEdupBuf.zAlloc, p, nSize); + if( nSizeflags &= ~(EP_Reduced|EP_TokenOnly|EP_Static); + pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); + pNew->flags |= staticFlag; + ExprClearVVAProperties(pNew); + if( dupFlags ){ + ExprSetVVAProperty(pNew, EP_Immutable); + } + + /* Copy the p->u.zToken string, if any. */ + assert( nToken>=0 ); + if( nToken>0 ){ + char *zToken = pNew->u.zToken = (char*)&sEdupBuf.zAlloc[nNewSize]; + memcpy(zToken, p->u.zToken, nToken); + nNewSize += nToken; + } + sEdupBuf.zAlloc += ROUND8(nNewSize); + + if( ((p->flags|pNew->flags)&(EP_TokenOnly|EP_Leaf))==0 ){ + + /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ + if( ExprUseXSelect(p) ){ + pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); + }else{ + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, + p->op!=TK_ORDER ? dupFlags : 0); + } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(p, EP_WinFunc) ){ + pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); + assert( ExprHasProperty(pNew, EP_WinFunc) ); + } +#endif /* SQLITE_OMIT_WINDOWFUNC */ + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( dupFlags ){ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &sEdupBuf) : 0; + } + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &sEdupBuf) : 0; + }else{ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + } + pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); + } + } + } + if( pEdupBuf ) memcpy(pEdupBuf, &sEdupBuf, sizeof(sEdupBuf)); + assert( sEdupBuf.zAlloc <= sEdupBuf.zEnd ); + return pNew; +} + +/* +** Create and return a deep copy of the object passed as the second +** argument. If an OOM condition is encountered, NULL is returned +** and the db->mallocFailed flag set. +*/ +#ifndef SQLITE_OMIT_CTE +SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ + With *pRet = 0; + if( p ){ + sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); + pRet = sqlite3DbMallocZero(db, nByte); + if( pRet ){ + int i; + pRet->nCte = p->nCte; + for(i=0; inCte; i++){ + pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); + pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); + pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); + pRet->a[i].eM10d = p->a[i].eM10d; + } + } + } + return pRet; +} +#else +# define sqlite3WithDup(x,y) 0 +#endif + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** The gatherSelectWindows() procedure and its helper routine +** gatherSelectWindowsCallback() are used to scan all the expressions +** an a newly duplicated SELECT statement and gather all of the Window +** objects found there, assembling them onto the linked list at Select->pWin. +*/ +static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){ + Select *pSelect = pWalker->u.pSelect; + Window *pWin = pExpr->y.pWin; + assert( pWin ); + assert( IsWindowFunc(pExpr) ); + assert( pWin->ppThis==0 ); + sqlite3WindowLink(pSelect, pWin); + } + return WRC_Continue; +} +static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){ + return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune; +} +static void gatherSelectWindows(Select *p){ + Walker w; + w.xExprCallback = gatherSelectWindowsCallback; + w.xSelectCallback = gatherSelectWindowsSelectCallback; + w.xSelectCallback2 = 0; + w.pParse = 0; + w.u.pSelect = p; + sqlite3WalkSelect(&w, p); +} +#endif + + +/* +** The following group of routines make deep copies of expressions, +** expression lists, ID lists, and select statements. The copies can +** be deleted (by being passed to their respective ...Delete() routines) +** without effecting the originals. +** +** The expression list, ID, and source lists return by sqlite3ExprListDup(), +** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded +** by subsequent calls to sqlite*ListAppend() routines. +** +** Any tables that the SrcList might point to are not duplicated. +** +** The flags parameter contains a combination of the EXPRDUP_XXX flags. +** If the EXPRDUP_REDUCE flag is set, then the structure returned is a +** truncated version of the usual Expr structure that will be stored as +** part of the in-memory representation of the database schema. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, const Expr *p, int flags){ + assert( flags==0 || flags==EXPRDUP_REDUCE ); + return p ? exprDup(db, p, flags, 0) : 0; +} +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ + ExprList *pNew; + struct ExprList_item *pItem; + const struct ExprList_item *pOldItem; + int i; + Expr *pPriorSelectColOld = 0; + Expr *pPriorSelectColNew = 0; + assert( db!=0 ); + if( p==0 ) return 0; + pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); + if( pNew==0 ) return 0; + pNew->nExpr = p->nExpr; + pNew->nAlloc = p->nAlloc; + pItem = pNew->a; + pOldItem = p->a; + for(i=0; inExpr; i++, pItem++, pOldItem++){ + Expr *pOldExpr = pOldItem->pExpr; + Expr *pNewExpr; + pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + if( pOldExpr + && pOldExpr->op==TK_SELECT_COLUMN + && (pNewExpr = pItem->pExpr)!=0 + ){ + if( pNewExpr->pRight ){ + pPriorSelectColOld = pOldExpr->pRight; + pPriorSelectColNew = pNewExpr->pRight; + pNewExpr->pLeft = pNewExpr->pRight; + }else{ + if( pOldExpr->pLeft!=pPriorSelectColOld ){ + pPriorSelectColOld = pOldExpr->pLeft; + pPriorSelectColNew = sqlite3ExprDup(db, pPriorSelectColOld, flags); + pNewExpr->pRight = pPriorSelectColNew; + } + pNewExpr->pLeft = pPriorSelectColNew; + } + } + pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); + pItem->fg = pOldItem->fg; + pItem->fg.done = 0; + pItem->u = pOldItem->u; + } + return pNew; +} + +/* +** If cursors, triggers, views and subqueries are all omitted from +** the build, then none of the following routines, except for +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes +** called with a NULL argument. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ + || !defined(SQLITE_OMIT_SUBQUERY) +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ + SrcList *pNew; + int i; + int nByte; + assert( db!=0 ); + if( p==0 ) return 0; + nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); + pNew = sqlite3DbMallocRawNN(db, nByte ); + if( pNew==0 ) return 0; + pNew->nSrc = pNew->nAlloc = p->nSrc; + for(i=0; inSrc; i++){ + SrcItem *pNewItem = &pNew->a[i]; + const SrcItem *pOldItem = &p->a[i]; + Table *pTab; + pNewItem->pSchema = pOldItem->pSchema; + pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); + pNewItem->fg = pOldItem->fg; + pNewItem->iCursor = pOldItem->iCursor; + pNewItem->addrFillSub = pOldItem->addrFillSub; + pNewItem->regReturn = pOldItem->regReturn; + if( pNewItem->fg.isIndexedBy ){ + pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); + } + pNewItem->u2 = pOldItem->u2; + if( pNewItem->fg.isCte ){ + pNewItem->u2.pCteUse->nUse++; + } + if( pNewItem->fg.isTabFunc ){ + pNewItem->u1.pFuncArg = + sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); + } + pTab = pNewItem->pTab = pOldItem->pTab; + if( pTab ){ + pTab->nTabRef++; + } + pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); + if( pOldItem->fg.isUsing ){ + assert( pNewItem->fg.isUsing ); + pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); + }else{ + pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags); + } + pNewItem->colUsed = pOldItem->colUsed; + } + return pNew; +} +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ + IdList *pNew; + int i; + assert( db!=0 ); + if( p==0 ) return 0; + assert( p->eU4!=EU4_EXPR ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); + if( pNew==0 ) return 0; + pNew->nId = p->nId; + pNew->eU4 = p->eU4; + for(i=0; inId; i++){ + struct IdList_item *pNewItem = &pNew->a[i]; + const struct IdList_item *pOldItem = &p->a[i]; + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->u4 = pOldItem->u4; + } + return pNew; +} +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){ + Select *pRet = 0; + Select *pNext = 0; + Select **pp = &pRet; + const Select *p; + + assert( db!=0 ); + for(p=pDup; p; p=p->pPrior){ + Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); + if( pNew==0 ) break; + pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); + pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); + pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); + pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); + pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); + pNew->op = p->op; + pNew->pNext = pNext; + pNew->pPrior = 0; + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->nSelectRow = p->nSelectRow; + pNew->pWith = sqlite3WithDup(db, p->pWith); +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); + if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); +#endif + pNew->selId = p->selId; + if( db->mallocFailed ){ + /* Any prior OOM might have left the Select object incomplete. + ** Delete the whole thing rather than allow an incomplete Select + ** to be used by the code generator. */ + pNew->pNext = 0; + sqlite3SelectDelete(db, pNew); + break; + } + *pp = pNew; + pp = &pNew->pPrior; + pNext = pNew; + } + + return pRet; +} +#else +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){ + assert( p==0 ); + return 0; +} +#endif + + +/* +** Add a new element to the end of an expression list. If pList is +** initially NULL, then create a new expression list. +** +** The pList argument must be either NULL or a pointer to an ExprList +** obtained from a prior call to sqlite3ExprListAppend(). +** +** If a memory allocation error occurs, the entire list is freed and +** NULL is returned. If non-NULL is returned, then it is guaranteed +** that the new entry was successfully appended. +*/ +static const struct ExprList_item zeroItem = {0}; +SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( + sqlite3 *db, /* Database handle. Used for memory allocation */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pList; + + pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 ); + if( pList==0 ){ + sqlite3ExprDelete(db, pExpr); + return 0; + } + pList->nAlloc = 4; + pList->nExpr = 1; + pItem = &pList->a[0]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} +SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( + sqlite3 *db, /* Database handle. Used for memory allocation */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pNew; + pList->nAlloc *= 2; + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); + sqlite3ExprDelete(db, pExpr); + return 0; + }else{ + pList = pNew; + } + pItem = &pList->a[pList->nExpr++]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + if( pList==0 ){ + return sqlite3ExprListAppendNew(pParse->db,pExpr); + } + if( pList->nAllocnExpr+1 ){ + return sqlite3ExprListAppendGrow(pParse->db,pList,pExpr); + } + pItem = &pList->a[pList->nExpr++]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} + +/* +** pColumns and pExpr form a vector assignment which is part of the SET +** clause of an UPDATE statement. Like this: +** +** (a,b,c) = (expr1,expr2,expr3) +** Or: (a,b,c) = (SELECT x,y,z FROM ....) +** +** For each term of the vector assignment, append new entries to the +** expression list pList. In the case of a subquery on the RHS, append +** TK_SELECT_COLUMN expressions. +*/ +SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + IdList *pColumns, /* List of names of LHS of the assignment */ + Expr *pExpr /* Vector expression to be appended. Might be NULL */ +){ + sqlite3 *db = pParse->db; + int n; + int i; + int iFirst = pList ? pList->nExpr : 0; + /* pColumns can only be NULL due to an OOM but an OOM will cause an + ** exit prior to this routine being invoked */ + if( NEVER(pColumns==0) ) goto vector_append_error; + if( pExpr==0 ) goto vector_append_error; + + /* If the RHS is a vector, then we can immediately check to see that + ** the size of the RHS and LHS match. But if the RHS is a SELECT, + ** wildcards ("*") in the result set of the SELECT must be expanded before + ** we can do the size check, so defer the size check until code generation. + */ + if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", + pColumns->nId, n); + goto vector_append_error; + } + + for(i=0; inId; i++){ + Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i, pColumns->nId); + assert( pSubExpr!=0 || db->mallocFailed ); + if( pSubExpr==0 ) continue; + pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); + if( pList ){ + assert( pList->nExpr==iFirst+i+1 ); + pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName; + pColumns->a[i].zName = 0; + } + } + + if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){ + Expr *pFirst = pList->a[iFirst].pExpr; + assert( pFirst!=0 ); + assert( pFirst->op==TK_SELECT_COLUMN ); + + /* Store the SELECT statement in pRight so it will be deleted when + ** sqlite3ExprListDelete() is called */ + pFirst->pRight = pExpr; + pExpr = 0; + + /* Remember the size of the LHS in iTable so that we can check that + ** the RHS and LHS sizes match during code generation. */ + pFirst->iTable = pColumns->nId; + } + +vector_append_error: + sqlite3ExprUnmapAndDelete(pParse, pExpr); + sqlite3IdListDelete(db, pColumns); + return pList; +} + +/* +** Set the sort order for the last element on the given ExprList. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ + struct ExprList_item *pItem; + if( p==0 ) return; + assert( p->nExpr>0 ); + + assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 ); + assert( iSortOrder==SQLITE_SO_UNDEFINED + || iSortOrder==SQLITE_SO_ASC + || iSortOrder==SQLITE_SO_DESC + ); + assert( eNulls==SQLITE_SO_UNDEFINED + || eNulls==SQLITE_SO_ASC + || eNulls==SQLITE_SO_DESC + ); + + pItem = &p->a[p->nExpr-1]; + assert( pItem->fg.bNulls==0 ); + if( iSortOrder==SQLITE_SO_UNDEFINED ){ + iSortOrder = SQLITE_SO_ASC; + } + pItem->fg.sortFlags = (u8)iSortOrder; + + if( eNulls!=SQLITE_SO_UNDEFINED ){ + pItem->fg.bNulls = 1; + if( iSortOrder!=eNulls ){ + pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL; + } + } +} + +/* +** Set the ExprList.a[].zEName element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pName should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetName( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + const Token *pName, /* Name to be added */ + int dequote /* True to cause the name to be dequoted */ +){ + assert( pList!=0 || pParse->db->mallocFailed!=0 ); + assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 ); + if( pList ){ + struct ExprList_item *pItem; + assert( pList->nExpr>0 ); + pItem = &pList->a[pList->nExpr-1]; + assert( pItem->zEName==0 ); + assert( pItem->fg.eEName==ENAME_NAME ); + pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + if( dequote ){ + /* If dequote==0, then pName->z does not point to part of a DDL + ** statement handled by the parser. And so no token need be added + ** to the token-map. */ + sqlite3Dequote(pItem->zEName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (const void*)pItem->zEName, pName); + } + } + } +} + +/* +** Set the ExprList.a[].zSpan element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pSpan should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetSpan( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + const char *zStart, /* Start of the span */ + const char *zEnd /* End of the span */ +){ + sqlite3 *db = pParse->db; + assert( pList!=0 || db->mallocFailed!=0 ); + if( pList ){ + struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; + assert( pList->nExpr>0 ); + if( pItem->zEName==0 ){ + pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd); + pItem->fg.eEName = ENAME_SPAN; + } + } +} + +/* +** If the expression list pEList contains more than iLimit elements, +** leave an error message in pParse. +*/ +SQLITE_PRIVATE void sqlite3ExprListCheckLength( + Parse *pParse, + ExprList *pEList, + const char *zObject +){ + int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + testcase( pEList && pEList->nExpr==mx ); + testcase( pEList && pEList->nExpr==mx+1 ); + if( pEList && pEList->nExpr>mx ){ + sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); + } +} + +/* +** Delete an entire expression list. +*/ +static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ + int i = pList->nExpr; + struct ExprList_item *pItem = pList->a; + assert( pList->nExpr>0 ); + assert( db!=0 ); + do{ + sqlite3ExprDelete(db, pItem->pExpr); + if( pItem->zEName ) sqlite3DbNNFreeNN(db, pItem->zEName); + pItem++; + }while( --i>0 ); + sqlite3DbNNFreeNN(db, pList); +} +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ + if( pList ) exprListDeleteNN(db, pList); +} +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){ + if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList); +} + +/* +** Return the bitwise-OR of all Expr.flags fields in the given +** ExprList. +*/ +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ + int i; + u32 m = 0; + assert( pList!=0 ); + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + assert( pExpr!=0 ); + m |= pExpr->flags; + } + return m; +} + +/* +** This is a SELECT-node callback for the expression walker that +** always "fails". By "fail" in this case, we mean set +** pWalker->eCode to zero and abort. +** +** This callback is used by multiple expression walkers. +*/ +SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ + UNUSED_PARAMETER(NotUsed); + pWalker->eCode = 0; + return WRC_Abort; +} + +/* +** Check the input string to see if it is "true" or "false" (in any case). +** +** If the string is.... Return +** "true" EP_IsTrue +** "false" EP_IsFalse +** anything else 0 +*/ +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char *zIn){ + if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; + if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; + return 0; +} + + +/* +** If the input expression is an ID with the name "true" or "false" +** then convert it into an TK_TRUEFALSE term. Return non-zero if +** the conversion happened, and zero if the expression is unaltered. +*/ +SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ + u32 v; + assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); + if( !ExprHasProperty(pExpr, EP_Quoted|EP_IntValue) + && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 + ){ + pExpr->op = TK_TRUEFALSE; + ExprSetProperty(pExpr, v); + return 1; + } + return 0; +} + +/* +** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE +** and 0 if it is FALSE. +*/ +SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ + pExpr = sqlite3ExprSkipCollateAndLikely((Expr*)pExpr); + assert( pExpr->op==TK_TRUEFALSE ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 + || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); + return pExpr->u.zToken[4]==0; +} + +/* +** If pExpr is an AND or OR expression, try to simplify it by eliminating +** terms that are always true or false. Return the simplified expression. +** Or return the original expression if no simplification is possible. +** +** Examples: +** +** (x<10) AND true => (x<10) +** (x<10) AND false => false +** (x<10) AND (y=22 OR false) => (x<10) AND (y=22) +** (x<10) AND (y=22 OR true) => (x<10) +** (y=22) OR true => true +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ + assert( pExpr!=0 ); + if( pExpr->op==TK_AND || pExpr->op==TK_OR ){ + Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight); + Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft); + if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){ + pExpr = pExpr->op==TK_AND ? pRight : pLeft; + }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){ + pExpr = pExpr->op==TK_AND ? pLeft : pRight; + } + } + return pExpr; +} + + +/* +** These routines are Walker callbacks used to check expressions to +** see if they are "constant" for some definition of constant. The +** Walker.eCode value determines the type of "constant" we are looking +** for. +** +** These callback routines are used to implement the following: +** +** sqlite3ExprIsConstant() pWalker->eCode==1 +** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 +** sqlite3ExprIsTableConstant() pWalker->eCode==3 +** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 +** +** In all cases, the callbacks set Walker.eCode=0 and abort if the expression +** is found to not be a constant. +** +** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT +** expressions in a CREATE TABLE statement. The Walker.eCode value is 5 +** when parsing an existing schema out of the sqlite_schema table and 4 +** when processing a new CREATE TABLE statement. A bound parameter raises +** an error for new statements, but is silently converted +** to NULL for existing schemas. This allows sqlite_schema tables that +** contain a bound parameter because they were generated by older versions +** of SQLite to be parsed by newer versions of SQLite without raising a +** malformed schema error. +*/ +static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ + + /* If pWalker->eCode is 2 then any term of the expression that comes from + ** the ON or USING clauses of an outer join disqualifies the expression + ** from being considered constant. */ + if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){ + pWalker->eCode = 0; + return WRC_Abort; + } + + switch( pExpr->op ){ + /* Consider functions to be constant if all their arguments are constant + ** and either pWalker->eCode==4 or 5 or the function has the + ** SQLITE_FUNC_CONST flag. */ + case TK_FUNCTION: + if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc)) + && !ExprHasProperty(pExpr, EP_WinFunc) + ){ + if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); + return WRC_Continue; + }else{ + pWalker->eCode = 0; + return WRC_Abort; + } + case TK_ID: + /* Convert "true" or "false" in a DEFAULT clause into the + ** appropriate TK_TRUEFALSE operator */ + if( sqlite3ExprIdToTrueFalse(pExpr) ){ + return WRC_Prune; + } + /* no break */ deliberate_fall_through + case TK_COLUMN: + case TK_AGG_FUNCTION: + case TK_AGG_COLUMN: + testcase( pExpr->op==TK_ID ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + testcase( pExpr->op==TK_AGG_COLUMN ); + if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){ + return WRC_Continue; + } + if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ + return WRC_Continue; + } + /* no break */ deliberate_fall_through + case TK_IF_NULL_ROW: + case TK_REGISTER: + case TK_DOT: + testcase( pExpr->op==TK_REGISTER ); + testcase( pExpr->op==TK_IF_NULL_ROW ); + testcase( pExpr->op==TK_DOT ); + pWalker->eCode = 0; + return WRC_Abort; + case TK_VARIABLE: + if( pWalker->eCode==5 ){ + /* Silently convert bound parameters that appear inside of CREATE + ** statements into a NULL when parsing the CREATE statement text out + ** of the sqlite_schema table */ + pExpr->op = TK_NULL; + }else if( pWalker->eCode==4 ){ + /* A bound parameter in a CREATE statement that originates from + ** sqlite3_prepare() causes an error */ + pWalker->eCode = 0; + return WRC_Abort; + } + /* no break */ deliberate_fall_through + default: + testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */ + testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */ + return WRC_Continue; + } +} +static int exprIsConst(Expr *p, int initFlag, int iCur){ + Walker w; + w.eCode = initFlag; + w.xExprCallback = exprNodeIsConstant; + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + w.u.iCur = iCur; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** Walk an expression tree. Return non-zero if the expression is constant +** and 0 if it involves variables or function calls. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ + return exprIsConst(p, 1, 0); +} + +/* +** Walk an expression tree. Return non-zero if +** +** (1) the expression is constant, and +** (2) the expression does originate in the ON or USING clause +** of a LEFT JOIN, and +** (3) the expression does not contain any EP_FixedCol TK_COLUMN +** operands created by the constant propagation optimization. +** +** When this routine returns true, it indicates that the expression +** can be added to the pParse->pConstExpr list and evaluated once when +** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ + return exprIsConst(p, 2, 0); +} + +/* +** Walk an expression tree. Return non-zero if the expression is constant +** for any single row of the table with cursor iCur. In other words, the +** expression must not refer to any non-deterministic function nor any +** table other than iCur. +*/ +SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ + return exprIsConst(p, 3, iCur); +} + +/* +** Check pExpr to see if it is an constraint on the single data source +** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr +** constrains pSrc but does not depend on any other tables or data +** sources anywhere else in the query. Return true (non-zero) if pExpr +** is a constraint on pSrc only. +** +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** doubt, return 0. +** +** To be an single-source constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2) pExpr cannot use subqueries or non-deterministic functions. +** +** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. +** (Is there some way to relax this constraint?) +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. +** (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +** +** (6) Either: +** +** (6a) pExpr does not originate in an ON or USING clause, or +** +** (6b) The ON or USING clause from which pExpr is derived is +** not to the left of a RIGHT JOIN (or FULL JOIN). +** +** Without this restriction, accepting pExpr as a single-table +** constraint might move the the ON/USING filter expression +** from the left side of a RIGHT JOIN over to the right side, +** which leads to incorrect answers. See also restriction (9) +** on push-down. +*/ +SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( + Expr *pExpr, /* The constraint */ + const SrcList *pSrcList, /* Complete FROM clause */ + int iSrc /* Which element of pSrcList to use */ +){ + const SrcItem *pSrc = &pSrcList->a[iSrc]; + if( pSrc->fg.jointype & JT_LTORJ ){ + return 0; /* rule (3) */ + } + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */ + if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ + } + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) /* (6a) */ + && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (6b) */ + ){ + int jj; + for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ + if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){ + return 0; /* restriction (6) */ + } + break; + } + } + } + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ +} + + +/* +** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). +*/ +static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ + ExprList *pGroupBy = pWalker->u.pGroupBy; + int i; + + /* Check if pExpr is identical to any GROUP BY term. If so, consider + ** it constant. */ + for(i=0; inExpr; i++){ + Expr *p = pGroupBy->a[i].pExpr; + if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p); + if( sqlite3IsBinary(pColl) ){ + return WRC_Prune; + } + } + } + + /* Check if pExpr is a sub-select. If so, consider it variable. */ + if( ExprUseXSelect(pExpr) ){ + pWalker->eCode = 0; + return WRC_Abort; + } + + return exprNodeIsConstant(pWalker, pExpr); +} + +/* +** Walk the expression tree passed as the first argument. Return non-zero +** if the expression consists entirely of constants or copies of terms +** in pGroupBy that sort with the BINARY collation sequence. +** +** This routine is used to determine if a term of the HAVING clause can +** be promoted into the WHERE clause. In order for such a promotion to work, +** the value of the HAVING clause term must be the same for all members of +** a "group". The requirement that the GROUP BY term must be BINARY +** assumes that no other collating sequence will have a finer-grained +** grouping than binary. In other words (A=B COLLATE binary) implies +** A=B in every other collating sequence. The requirement that the +** GROUP BY be BINARY is stricter than necessary. It would also work +** to promote HAVING clauses that use the same alternative collating +** sequence as the GROUP BY term, but that is much harder to check, +** alternative collating sequences are uncommon, and this is only an +** optimization, so we take the easy way out and simply require the +** GROUP BY to use the BINARY collating sequence. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ + Walker w; + w.eCode = 1; + w.xExprCallback = exprNodeIsConstantOrGroupBy; + w.xSelectCallback = 0; + w.u.pGroupBy = pGroupBy; + w.pParse = pParse; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** Walk an expression tree for the DEFAULT field of a column definition +** in a CREATE TABLE statement. Return non-zero if the expression is +** acceptable for use as a DEFAULT. That is to say, return non-zero if +** the expression is constant or a function call with constant arguments. +** Return and 0 if there are any variables. +** +** isInit is true when parsing from sqlite_schema. isInit is false when +** processing a new CREATE TABLE statement. When isInit is true, parameters +** (such as ? or $abc) in the expression are converted into NULL. When +** isInit is false, parameters raise an error. Parameters should not be +** allowed in a CREATE TABLE statement, but some legacy versions of SQLite +** allowed it, so we need to support it when reading sqlite_schema for +** backwards compatibility. +** +** If isInit is true, set EP_FromDDL on every TK_FUNCTION node. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ + assert( isInit==0 || isInit==1 ); + return exprIsConst(p, 4+isInit, 0); +} + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Walk an expression tree. Return 1 if the expression contains a +** subquery of some kind. Return 0 if there are no subqueries. +*/ +SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ + Walker w; + w.eCode = 1; + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + sqlite3WalkExpr(&w, p); + return w.eCode==0; +} +#endif + +/* +** If the expression p codes a constant integer that is small enough +** to fit in a 32-bit integer, return 1 and put the value of the integer +** in *pValue. If the expression is not an integer or if it is too big +** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +*/ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ + int rc = 0; + if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ + + /* If an expression is an integer literal that fits in a signed 32-bit + ** integer, then the EP_IntValue flag will have already been set */ + assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 + || sqlite3GetInt32(p->u.zToken, &rc)==0 ); + + if( p->flags & EP_IntValue ){ + *pValue = p->u.iValue; + return 1; + } + switch( p->op ){ + case TK_UPLUS: { + rc = sqlite3ExprIsInteger(p->pLeft, pValue); + break; + } + case TK_UMINUS: { + int v = 0; + if( sqlite3ExprIsInteger(p->pLeft, &v) ){ + assert( ((unsigned int)v)!=0x80000000 ); + *pValue = -v; + rc = 1; + } + break; + } + default: break; + } + return rc; +} + +/* +** Return FALSE if there is no chance that the expression can be NULL. +** +** If the expression might be NULL or if the expression is too complex +** to tell return TRUE. +** +** This routine is used as an optimization, to skip OP_IsNull opcodes +** when we know that a value cannot be NULL. Hence, a false positive +** (returning TRUE when in fact the expression can never be NULL) might +** be a small performance hit but is otherwise harmless. On the other +** hand, a false negative (returning FALSE when the result could be NULL) +** will likely result in an incorrect answer. So when in doubt, return +** TRUE. +*/ +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ + u8 op; + assert( p!=0 ); + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + p = p->pLeft; + assert( p!=0 ); + } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: + case TK_STRING: + case TK_FLOAT: + case TK_BLOB: + return 0; + case TK_COLUMN: + assert( ExprUseYTab(p) ); + return ExprHasProperty(p, EP_CanBeNull) + || NEVER(p->y.pTab==0) /* Reference to column of index on expr */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + || (p->iColumn==XN_ROWID && IsView(p->y.pTab)) +#endif + || (p->iColumn>=0 + && p->y.pTab->aCol!=0 /* Possible due to prior error */ + && ALWAYS(p->iColumny.pTab->nCol) + && p->y.pTab->aCol[p->iColumn].notNull==0); + default: + return 1; + } +} + +/* +** Return TRUE if the given expression is a constant which would be +** unchanged by OP_Affinity with the affinity given in the second +** argument. +** +** This routine is used to determine if the OP_Affinity operation +** can be omitted. When in doubt return FALSE. A false negative +** is harmless. A false positive, however, can result in the wrong +** answer. +*/ +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ + u8 op; + int unaryMinus = 0; + if( aff==SQLITE_AFF_BLOB ) return 1; + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + if( p->op==TK_UMINUS ) unaryMinus = 1; + p = p->pLeft; + } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: { + return aff>=SQLITE_AFF_NUMERIC; + } + case TK_FLOAT: { + return aff>=SQLITE_AFF_NUMERIC; + } + case TK_STRING: { + return !unaryMinus && aff==SQLITE_AFF_TEXT; + } + case TK_BLOB: { + return !unaryMinus; + } + case TK_COLUMN: { + assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ + return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0; + } + default: { + return 0; + } + } +} + +/* +** Return TRUE if the given string is a row-id column name. +*/ +SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ + if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; + if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; + if( sqlite3StrICmp(z, "OID")==0 ) return 1; + return 0; +} + +/* +** Return a pointer to a buffer containing a usable rowid alias for table +** pTab. An alias is usable if there is not an explicit user-defined column +** of the same name. +*/ +SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){ + const char *azOpt[] = {"_ROWID_", "ROWID", "OID"}; + int ii; + assert( VisibleRowid(pTab) ); + for(ii=0; iinCol; iCol++){ + if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; + } + if( iCol==pTab->nCol ){ + return azOpt[ii]; + } + } + return 0; +} + +/* +** pX is the RHS of an IN operator. If pX is a SELECT statement +** that can be simplified to a direct table access, then return +** a pointer to the SELECT statement. If pX is not a SELECT statement, +** or if the SELECT statement needs to be materialized into a transient +** table, then return NULL. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +static Select *isCandidateForInOpt(const Expr *pX){ + Select *p; + SrcList *pSrc; + ExprList *pEList; + Table *pTab; + int i; + if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */ + if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */ + p = pX->x.pSelect; + if( p->pPrior ) return 0; /* Not a compound SELECT */ + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + return 0; /* No DISTINCT keyword and no aggregate functions */ + } + assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ + if( p->pLimit ) return 0; /* Has no LIMIT clause */ + if( p->pWhere ) return 0; /* Has no WHERE clause */ + pSrc = p->pSrc; + assert( pSrc!=0 ); + if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ + if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ + pTab = pSrc->a[0].pTab; + assert( pTab!=0 ); + assert( !IsView(pTab) ); /* FROM clause is not a view */ + if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ + pEList = p->pEList; + assert( pEList!=0 ); + /* All SELECT results must be columns. */ + for(i=0; inExpr; i++){ + Expr *pRes = pEList->a[i].pExpr; + if( pRes->op!=TK_COLUMN ) return 0; + assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */ + } + return p; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code that checks the left-most column of index table iCur to see if +** it contains any NULL entries. Cause the register at regHasNull to be set +** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull +** to be set to NULL if iCur contains one or more NULL values. +*/ +static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ + int addr1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); + addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + VdbeComment((v, "first_entry_in(%d)", iCur)); + sqlite3VdbeJumpHere(v, addr1); +} +#endif + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** The argument is an IN operator with a list (not a subquery) on the +** right-hand side. Return TRUE if that list is constant. +*/ +static int sqlite3InRhsIsConstant(Expr *pIn){ + Expr *pLHS; + int res; + assert( !ExprHasProperty(pIn, EP_xIsSelect) ); + pLHS = pIn->pLeft; + pIn->pLeft = 0; + res = sqlite3ExprIsConstant(pIn); + pIn->pLeft = pLHS; + return res; +} +#endif + +/* +** This function is used by the implementation of the IN (...) operator. +** The pX parameter is the expression on the RHS of the IN operator, which +** might be either a list of expressions or a subquery. +** +** The job of this routine is to find or create a b-tree object that can +** be used either to test for membership in the RHS set or to iterate through +** all members of the RHS set, skipping duplicates. +** +** A cursor is opened on the b-tree object that is the RHS of the IN operator +** and the *piTab parameter is set to the index of that cursor. +** +** The returned value of this function indicates the b-tree type, as follows: +** +** IN_INDEX_ROWID - The cursor was opened on a database table. +** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. +** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. +** IN_INDEX_EPH - The cursor was opened on a specially created and +** populated ephemeral table. +** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be +** implemented as a sequence of comparisons. +** +** An existing b-tree might be used if the RHS expression pX is a simple +** subquery such as: +** +** SELECT , ... FROM +** +** If the RHS of the IN operator is a list or a more complex subquery, then +** an ephemeral table might need to be generated from the RHS and then +** pX->iTable made to point to the ephemeral table instead of an +** existing table. In this case, the creation and initialization of the +** ephemeral table might be put inside of a subroutine, the EP_Subrtn flag +** will be set on pX and the pX->y.sub fields will be set to show where +** the subroutine is coded. +** +** The inFlags parameter must contain, at a minimum, one of the bits +** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains +** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast +** membership test. When the IN_INDEX_LOOP bit is set, the IN index will +** be used to loop over all values of the RHS of the IN operator. +** +** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate +** through the set members) then the b-tree must not contain duplicates. +** An ephemeral table will be created unless the selected columns are guaranteed +** to be unique - either because it is an INTEGER PRIMARY KEY or due to +** a UNIQUE constraint or index. +** +** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used +** for fast set membership tests) then an ephemeral table must +** be used unless is a single INTEGER PRIMARY KEY column or an +** index can be found with the specified as its left-most. +** +** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and +** if the RHS of the IN operator is a list (not a subquery) then this +** routine might decide that creating an ephemeral b-tree for membership +** testing is too expensive and return IN_INDEX_NOOP. In that case, the +** calling routine should implement the IN operator using a sequence +** of Eq or Ne comparison operations. +** +** When the b-tree is being used for membership tests, the calling function +** might need to know whether or not the RHS side of the IN operator +** contains a NULL. If prRhsHasNull is not a NULL pointer and +** if there is any chance that the (...) might contain a NULL value at +** runtime, then a register is allocated and the register number written +** to *prRhsHasNull. If there is no chance that the (...) contains a +** NULL value, then *prRhsHasNull is left unchanged. +** +** If a register is allocated and its location stored in *prRhsHasNull, then +** the value in that register will be NULL if the b-tree contains one or more +** NULL values, and it will be some non-NULL value if the b-tree contains no +** NULL values. +** +** If the aiMap parameter is not NULL, it must point to an array containing +** one element for each column returned by the SELECT statement on the RHS +** of the IN(...) operator. The i'th entry of the array is populated with the +** offset of the index column that matches the i'th column returned by the +** SELECT. For example, if the expression and selected index are: +** +** (?,?,?) IN (SELECT a, b, c FROM t1) +** CREATE INDEX i1 ON t1(b, c, a); +** +** then aiMap[] is populated with {2, 0, 1}. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3FindInIndex( + Parse *pParse, /* Parsing context */ + Expr *pX, /* The IN expression */ + u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ + int *prRhsHasNull, /* Register holding NULL status. See notes */ + int *aiMap, /* Mapping from Index fields to RHS fields */ + int *piTab /* OUT: index to use */ +){ + Select *p; /* SELECT to the right of IN operator */ + int eType = 0; /* Type of RHS table. IN_INDEX_* */ + int iTab; /* Cursor of the RHS table */ + int mustBeUnique; /* True if RHS must be unique */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + + assert( pX->op==TK_IN ); + mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; + iTab = pParse->nTab++; + + /* If the RHS of this IN(...) operator is a SELECT, and if it matters + ** whether or not the SELECT result contains NULL values, check whether + ** or not NULL is actually possible (it may not be, for example, due + ** to NOT NULL constraints in the schema). If no NULL values are possible, + ** set prRhsHasNull to 0 before continuing. */ + if( prRhsHasNull && ExprUseXSelect(pX) ){ + int i; + ExprList *pEList = pX->x.pSelect->pEList; + for(i=0; inExpr; i++){ + if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break; + } + if( i==pEList->nExpr ){ + prRhsHasNull = 0; + } + } + + /* Check to see if an existing table or index can be used to + ** satisfy the query. This is preferable to generating a new + ** ephemeral table. */ + if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table
. */ + int iDb; /* Database idx for pTab */ + ExprList *pEList = p->pEList; + int nExpr = pEList->nExpr; + + assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ + pTab = p->pSrc->a[0].pTab; + + /* Code an OP_Transaction and OP_TableLock for
. */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 && iDbtnum, 0, pTab->zName); + + assert(v); /* sqlite3GetVdbe() has always been previously called */ + if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ + /* The "x IN (SELECT rowid FROM table)" case */ + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); + VdbeCoverage(v); + + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + eType = IN_INDEX_ROWID; + ExplainQueryPlan((pParse, 0, + "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName)); + sqlite3VdbeJumpHere(v, iAddr); + }else{ + Index *pIdx; /* Iterator variable */ + int affinity_ok = 1; + int i; + + /* Check that the affinity that will be used to perform each + ** comparison is the same as the affinity of each column in table + ** on the RHS of the IN operator. If it not, it is not possible to + ** use any index of the RHS table. */ + for(i=0; ipLeft, i); + int iCol = pEList->a[i].pExpr->iColumn; + char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */ + char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); + testcase( cmpaff==SQLITE_AFF_BLOB ); + testcase( cmpaff==SQLITE_AFF_TEXT ); + switch( cmpaff ){ + case SQLITE_AFF_BLOB: + break; + case SQLITE_AFF_TEXT: + /* sqlite3CompareAffinity() only returns TEXT if one side or the + ** other has no affinity and the other side is TEXT. Hence, + ** the only way for cmpaff to be TEXT is for idxaff to be TEXT + ** and for the term on the LHS of the IN to have no affinity. */ + assert( idxaff==SQLITE_AFF_TEXT ); + break; + default: + affinity_ok = sqlite3IsNumericAffinity(idxaff); + } + } + + if( affinity_ok ){ + /* Search for an existing index that will work for this IN operator */ + for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){ + Bitmask colUsed; /* Columns of the index used */ + Bitmask mCol; /* Mask for the current column */ + if( pIdx->nColumnpPartIdxWhere!=0 ) continue; + /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute + ** BITMASK(nExpr) without overflowing */ + testcase( pIdx->nColumn==BMS-2 ); + testcase( pIdx->nColumn==BMS-1 ); + if( pIdx->nColumn>=BMS-1 ) continue; + if( mustBeUnique ){ + if( pIdx->nKeyCol>nExpr + ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx)) + ){ + continue; /* This index is not unique over the IN RHS columns */ + } + } + + colUsed = 0; /* Columns of index used so far */ + for(i=0; ipLeft, i); + Expr *pRhs = pEList->a[i].pExpr; + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + int j; + + for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; + assert( pIdx->azColl[j] ); + if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ + continue; + } + break; + } + if( j==nExpr ) break; + mCol = MASKBIT(j); + if( mCol & colUsed ) break; /* Each column used only once */ + colUsed |= mCol; + if( aiMap ) aiMap[i] = j; + } + + assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); + if( colUsed==(MASKBIT(nExpr)-1) ){ + /* If we reach this point, that means the index pIdx is usable */ + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + ExplainQueryPlan((pParse, 0, + "USING INDEX %s FOR IN-OPERATOR",pIdx->zName)); + sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); + eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; + + if( prRhsHasNull ){ +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + i64 mask = (1<nMem; + if( nExpr==1 ){ + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + } + } + sqlite3VdbeJumpHere(v, iAddr); + } + } /* End loop over indexes */ + } /* End if( affinity_ok ) */ + } /* End if not an rowid index */ + } /* End attempt to optimize using an index */ + + /* If no preexisting index is available for the IN clause + ** and IN_INDEX_NOOP is an allowed reply + ** and the RHS of the IN operator is a list, not a subquery + ** and the RHS is not constant or has two or fewer terms, + ** then it is not worth creating an ephemeral table to evaluate + ** the IN operator so return IN_INDEX_NOOP. + */ + if( eType==0 + && (inFlags & IN_INDEX_NOOP_OK) + && ExprUseXList(pX) + && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) + ){ + pParse->nTab--; /* Back out the allocation of the unused cursor */ + iTab = -1; /* Cursor is not allocated */ + eType = IN_INDEX_NOOP; + } + + if( eType==0 ){ + /* Could not find an existing table or index to use as the RHS b-tree. + ** We will have to generate an ephemeral table to do the job. + */ + u32 savedNQueryLoop = pParse->nQueryLoop; + int rMayHaveNull = 0; + eType = IN_INDEX_EPH; + if( inFlags & IN_INDEX_LOOP ){ + pParse->nQueryLoop = 0; + }else if( prRhsHasNull ){ + *prRhsHasNull = rMayHaveNull = ++pParse->nMem; + } + assert( pX->op==TK_IN ); + sqlite3CodeRhsOfIN(pParse, pX, iTab); + if( rMayHaveNull ){ + sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); + } + pParse->nQueryLoop = savedNQueryLoop; + } + + if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){ + int i, n; + n = sqlite3ExprVectorSize(pX->pLeft); + for(i=0; ipLeft; + int nVal = sqlite3ExprVectorSize(pLeft); + Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0; + char *zRet; + + assert( pExpr->op==TK_IN ); + zRet = sqlite3DbMallocRaw(pParse->db, nVal+1); + if( zRet ){ + int i; + for(i=0; ipEList->a[i].pExpr, a); + }else{ + zRet[i] = a; + } + } + zRet[nVal] = '\0'; + } + return zRet; +} +#endif + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Load the Parse object passed as the first argument with an error +** message of the form: +** +** "sub-select returns N columns - expected M" +*/ +SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ + if( pParse->nErr==0 ){ + const char *zFmt = "sub-select returns %d columns - expected %d"; + sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); + } +} +#endif + +/* +** Expression pExpr is a vector that has been used in a context where +** it is not permitted. If pExpr is a sub-select vector, this routine +** loads the Parse object with a message of the form: +** +** "sub-select returns N columns - expected 1" +** +** Or, if it is a regular scalar vector: +** +** "row value misused" +*/ +SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ +#ifndef SQLITE_OMIT_SUBQUERY + if( ExprUseXSelect(pExpr) ){ + sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1); + }else +#endif + { + sqlite3ErrorMsg(pParse, "row value misused"); + } +} + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code that will construct an ephemeral table containing all terms +** in the RHS of an IN operator. The IN operator can be in either of two +** forms: +** +** x IN (4,5,11) -- IN operator with list on right-hand side +** x IN (SELECT a FROM b) -- IN operator with subquery on the right +** +** The pExpr parameter is the IN operator. The cursor number for the +** constructed ephemeral table is returned. The first time the ephemeral +** table is computed, the cursor number is also stored in pExpr->iTable, +** however the cursor number returned might not be the same, as it might +** have been duplicated using OP_OpenDup. +** +** If the LHS expression ("x" in the examples) is a column value, or +** the SELECT statement returns a column value, then the affinity of that +** column is used to build the index keys. If both 'x' and the +** SELECT... statement are columns, then numeric affinity is used +** if either column has NUMERIC or INTEGER affinity. If neither +** 'x' nor the SELECT... statement are columns, then numeric affinity +** is used. +*/ +SQLITE_PRIVATE void sqlite3CodeRhsOfIN( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The IN operator */ + int iTab /* Use this cursor number */ +){ + int addrOnce = 0; /* Address of the OP_Once instruction at top */ + int addr; /* Address of OP_OpenEphemeral instruction */ + Expr *pLeft; /* the LHS of the IN operator */ + KeyInfo *pKeyInfo = 0; /* Key information */ + int nVal; /* Size of vector pLeft */ + Vdbe *v; /* The prepared statement under construction */ + + v = pParse->pVdbe; + assert( v!=0 ); + + /* The evaluation of the IN must be repeated every time it + ** is encountered if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can compute the RHS just once + ** and reuse it many names. + */ + if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ + /* Reuse of the RHS is allowed */ + /* If this routine has already been coded, but the previous code + ** might not have been invoked yet, so invoke it now as a subroutine. + */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + if( ExprUseXSelect(pExpr) ){ + ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", + pExpr->x.pSelect->selId)); + } + assert( ExprUseYSub(pExpr) ); + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + assert( iTab!=pExpr->iTable ); + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + sqlite3VdbeJumpHere(v, addrOnce); + return; + } + + /* Begin coding the subroutine */ + assert( !ExprUseYWin(pExpr) ); + ExprSetProperty(pExpr, EP_Subrtn); + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + pExpr->y.sub.regReturn = ++pParse->nMem; + pExpr->y.sub.iAddr = + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; + + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + + /* Check to see if this is a vector IN operator */ + pLeft = pExpr->pLeft; + nVal = sqlite3ExprVectorSize(pLeft); + + /* Construct the ephemeral table that will contain the content of + ** RHS of the IN operator. + */ + pExpr->iTable = iTab; + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + if( ExprUseXSelect(pExpr) ){ + VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId)); + }else{ + VdbeComment((v, "RHS of IN operator")); + } +#endif + pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1); + + if( ExprUseXSelect(pExpr) ){ + /* Case 1: expr IN (SELECT ...) + ** + ** Generate code to write the results of the select into the temporary + ** table allocated and opened above. + */ + Select *pSelect = pExpr->x.pSelect; + ExprList *pEList = pSelect->pEList; + + ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d", + addrOnce?"":"CORRELATED ", pSelect->selId + )); + /* If the LHS and RHS of the IN operator do not match, that + ** error will have been caught long before we reach this point. */ + if( ALWAYS(pEList->nExpr==nVal) ){ + Select *pCopy; + SelectDest dest; + int i; + int rc; + sqlite3SelectDestInit(&dest, SRT_Set, iTab); + dest.zAffSdst = exprINAffinity(pParse, pExpr); + pSelect->iLimit = 0; + testcase( pSelect->selFlags & SF_Distinct ); + testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ + pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); + rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); + sqlite3SelectDelete(pParse->db, pCopy); + sqlite3DbFree(pParse->db, dest.zAffSdst); + if( rc ){ + sqlite3KeyInfoUnref(pKeyInfo); + return; + } + assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ + assert( pEList!=0 ); + assert( pEList->nExpr>0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + for(i=0; iaColl[i] = sqlite3BinaryCompareCollSeq( + pParse, p, pEList->a[i].pExpr + ); + } + } + }else if( ALWAYS(pExpr->x.pList!=0) ){ + /* Case 2: expr IN (exprlist) + ** + ** For each expression, build an index key from the evaluation and + ** store it in the temporary table. If is a column, then use + ** that columns affinity when building index keys. If is not + ** a column, use numeric affinity. + */ + char affinity; /* Affinity of the LHS of the IN */ + int i; + ExprList *pList = pExpr->x.pList; + struct ExprList_item *pItem; + int r1, r2; + affinity = sqlite3ExprAffinity(pLeft); + if( affinity<=SQLITE_AFF_NONE ){ + affinity = SQLITE_AFF_BLOB; + }else if( affinity==SQLITE_AFF_REAL ){ + affinity = SQLITE_AFF_NUMERIC; + } + if( pKeyInfo ){ + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + } + + /* Loop through each expression in . */ + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempReg(pParse); + for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ + Expr *pE2 = pItem->pExpr; + + /* If the expression is not constant then we will need to + ** disable the test that was generated above that makes sure + ** this code only executes once. Because for a non-constant + ** expression we need to rerun this code each time. + */ + if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, addrOnce-1); + sqlite3VdbeChangeToNoop(v, addrOnce); + ExprClearProperty(pExpr, EP_Subrtn); + addrOnce = 0; + } + + /* Evaluate the expression and insert it into the temp table */ + sqlite3ExprCode(pParse, pE2, r1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); + } + if( addrOnce ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iTab); + sqlite3VdbeJumpHere(v, addrOnce); + /* Subroutine return */ + assert( ExprUseYSub(pExpr) ); + assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn + || pParse->nErr ); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); + sqlite3ClearTempRegCache(pParse); + } +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Generate code for scalar subqueries used as a subquery expression +** or EXISTS operator: +** +** (SELECT a FROM b) -- subquery +** EXISTS (SELECT a FROM b) -- EXISTS subquery +** +** The pExpr parameter is the SELECT or EXISTS operator to be coded. +** +** Return the register that holds the result. For a multi-column SELECT, +** the result is stored in a contiguous array of registers and the +** return value is the register of the left-most result column. +** Return 0 if an error occurs. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + int addrOnce = 0; /* Address of OP_Once at top of subroutine */ + int rReg = 0; /* Register storing resulting */ + Select *pSel; /* SELECT statement to encode */ + SelectDest dest; /* How to deal with SELECT result */ + int nReg; /* Registers to allocate */ + Expr *pLimit; /* New limit expression */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExplain; /* Address of OP_Explain instruction */ +#endif + + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + if( pParse->nErr ) return 0; + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); + assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); + assert( ExprUseXSelect(pExpr) ); + pSel = pExpr->x.pSelect; + + /* If this routine has already been coded, then invoke it as a + ** subroutine. */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId)); + assert( ExprUseYSub(pExpr) ); + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + return pExpr->iTable; + } + + /* Begin coding the subroutine */ + assert( !ExprUseYWin(pExpr) ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); + ExprSetProperty(pExpr, EP_Subrtn); + pExpr->y.sub.regReturn = ++pParse->nMem; + pExpr->y.sub.iAddr = + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; + + /* The evaluation of the EXISTS/SELECT must be repeated every time it + ** is encountered if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can run this code just once + ** save the results, and reuse the same result on subsequent invocations. + */ + if( !ExprHasProperty(pExpr, EP_VarSelect) ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + + /* For a SELECT, generate code to put the values for all columns of + ** the first row into an array of registers and return the index of + ** the first register. + ** + ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) + ** into a register and return that register number. + ** + ** In both cases, the query is augmented with "LIMIT 1". Any + ** preexisting limit is discarded in place of the new LIMIT 1. + */ + ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d", + addrOnce?"":"CORRELATED ", pSel->selId)); + sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1); + nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; + sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); + pParse->nMem += nReg; + if( pExpr->op==TK_SELECT ){ + dest.eDest = SRT_Mem; + dest.iSdst = dest.iSDParm; + dest.nSdst = nReg; + sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); + VdbeComment((v, "Init subquery result")); + }else{ + dest.eDest = SRT_Exists; + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); + VdbeComment((v, "Init EXISTS result")); + } + if( pSel->pLimit ){ + /* The subquery already has a limit. If the pre-existing limit is X + ** then make the new limit X<>0 so that the new limit is either 1 or 0 */ + sqlite3 *db = pParse->db; + pLimit = sqlite3Expr(db, TK_INTEGER, "0"); + if( pLimit ){ + pLimit->affExpr = SQLITE_AFF_NUMERIC; + pLimit = sqlite3PExpr(pParse, TK_NE, + sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); + } + sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft); + pSel->pLimit->pLeft = pLimit; + }else{ + /* If there is no pre-existing limit add a limit of 1 */ + pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + } + pSel->iLimit = 0; + if( sqlite3Select(pParse, pSel, &dest) ){ + pExpr->op2 = pExpr->op; + pExpr->op = TK_ERROR; + return 0; + } + pExpr->iTable = rReg = dest.iSDParm; + ExprSetVVAProperty(pExpr, EP_NoReduce); + if( addrOnce ){ + sqlite3VdbeJumpHere(v, addrOnce); + } + sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + + /* Subroutine return */ + assert( ExprUseYSub(pExpr) ); + assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn + || pParse->nErr ); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); + sqlite3ClearTempRegCache(pParse); + return rReg; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Expr pIn is an IN(...) expression. This function checks that the +** sub-select on the RHS of the IN() operator has the same number of +** columns as the vector on the LHS. Or, if the RHS of the IN() is not +** a sub-query, that the LHS is a vector of size 1. +*/ +SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ + int nVector = sqlite3ExprVectorSize(pIn->pLeft); + if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){ + if( nVector!=pIn->x.pSelect->pEList->nExpr ){ + sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); + return 1; + } + }else if( nVector!=1 ){ + sqlite3VectorErrorMsg(pParse, pIn->pLeft); + return 1; + } + return 0; +} +#endif + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for an IN expression. +** +** x IN (SELECT ...) +** x IN (value, value, ...) +** +** The left-hand side (LHS) is a scalar or vector expression. The +** right-hand side (RHS) is an array of zero or more scalar values, or a +** subquery. If the RHS is a subquery, the number of result columns must +** match the number of columns in the vector on the LHS. If the RHS is +** a list of values, the LHS must be a scalar. +** +** The IN operator is true if the LHS value is contained within the RHS. +** The result is false if the LHS is definitely not in the RHS. The +** result is NULL if the presence of the LHS in the RHS cannot be +** determined due to NULLs. +** +** This routine generates code that jumps to destIfFalse if the LHS is not +** contained within the RHS. If due to NULLs we cannot determine if the LHS +** is contained in the RHS then jump to destIfNull. If the LHS is contained +** within the RHS then fall through. +** +** See the separate in-operator.md documentation file in the canonical +** SQLite source tree for additional information. +*/ +static void sqlite3ExprCodeIN( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The IN expression */ + int destIfFalse, /* Jump here if LHS is not contained in the RHS */ + int destIfNull /* Jump here if the results are unknown due to NULLs */ +){ + int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ + int eType; /* Type of the RHS */ + int rLhs; /* Register(s) holding the LHS values */ + int rLhsOrig; /* LHS values prior to reordering by aiMap[] */ + Vdbe *v; /* Statement under construction */ + int *aiMap = 0; /* Map from vector field to index column */ + char *zAff = 0; /* Affinity string for comparisons */ + int nVector; /* Size of vectors for this IN operator */ + int iDummy; /* Dummy parameter to exprCodeVector() */ + Expr *pLeft; /* The LHS of the IN operator */ + int i; /* loop counter */ + int destStep2; /* Where to jump when NULLs seen in step 2 */ + int destStep6 = 0; /* Start of code for Step 6 */ + int addrTruthOp; /* Address of opcode that determines the IN is true */ + int destNotNull; /* Jump here if a comparison is not true in step 6 */ + int addrTop; /* Top of the step-6 loop */ + int iTab = 0; /* Index to use */ + u8 okConstFactor = pParse->okConstFactor; + + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + pLeft = pExpr->pLeft; + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; + zAff = exprINAffinity(pParse, pExpr); + nVector = sqlite3ExprVectorSize(pExpr->pLeft); + aiMap = (int*)sqlite3DbMallocZero( + pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 + ); + if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; + + /* Attempt to compute the RHS. After this step, if anything other than + ** IN_INDEX_NOOP is returned, the table opened with cursor iTab + ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, + ** the RHS has not yet been coded. */ + v = pParse->pVdbe; + assert( v!=0 ); /* OOM detected prior to this routine */ + VdbeNoopComment((v, "begin IN expr")); + eType = sqlite3FindInIndex(pParse, pExpr, + IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, + destIfFalse==destIfNull ? 0 : &rRhsHasNull, + aiMap, &iTab); + + assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH + || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC + ); +#ifdef SQLITE_DEBUG + /* Confirm that aiMap[] contains nVector integer values between 0 and + ** nVector-1. */ + for(i=0; i from " IN (...)". If the LHS is a + ** vector, then it is stored in an array of nVector registers starting + ** at r1. + ** + ** sqlite3FindInIndex() might have reordered the fields of the LHS vector + ** so that the fields are in the same order as an existing index. The + ** aiMap[] array contains a mapping from the original LHS field order to + ** the field order that matches the RHS index. + ** + ** Avoid factoring the LHS of the IN(...) expression out of the loop, + ** even if it is constant, as OP_Affinity may be used on the register + ** by code generated below. */ + assert( pParse->okConstFactor==okConstFactor ); + pParse->okConstFactor = 0; + rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy); + pParse->okConstFactor = okConstFactor; + for(i=0; ix.pList; + pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + if( destIfNull!=destIfFalse ){ + regCkNull = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); + } + for(ii=0; iinExpr; ii++){ + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); + if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ + sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); + } + sqlite3ReleaseTempReg(pParse, regToFree); + if( iinExpr-1 || destIfNull!=destIfFalse ){ + int op = rLhs!=r2 ? OP_Eq : OP_NotNull; + sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2, + (void*)pColl, P4_COLLSEQ); + VdbeCoverageIf(v, iinExpr-1 && op==OP_Eq); + VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq); + VdbeCoverageIf(v, iinExpr-1 && op==OP_NotNull); + VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull); + sqlite3VdbeChangeP5(v, zAff[0]); + }else{ + int op = rLhs!=r2 ? OP_Ne : OP_IsNull; + assert( destIfNull==destIfFalse ); + sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2, + (void*)pColl, P4_COLLSEQ); + VdbeCoverageIf(v, op==OP_Ne); + VdbeCoverageIf(v, op==OP_IsNull); + sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); + } + } + if( regCkNull ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); + sqlite3VdbeGoto(v, destIfFalse); + } + sqlite3VdbeResolveLabel(v, labelOk); + sqlite3ReleaseTempReg(pParse, regCkNull); + goto sqlite3ExprCodeIN_finished; + } + + /* Step 2: Check to see if the LHS contains any NULL columns. If the + ** LHS does contain NULLs then the result must be either FALSE or NULL. + ** We will then skip the binary search of the RHS. + */ + if( destIfNull==destIfFalse ){ + destStep2 = destIfFalse; + }else{ + destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); + } + for(i=0; ipLeft, i); + if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; + if( sqlite3ExprCanBeNull(p) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); + VdbeCoverage(v); + } + } + + /* Step 3. The LHS is now known to be non-NULL. Do the binary search + ** of the RHS using the LHS as a probe. If found, the result is + ** true. + */ + if( eType==IN_INDEX_ROWID ){ + /* In this case, the RHS is the ROWID of table b-tree and so we also + ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4 + ** into a single opcode. */ + sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); + VdbeCoverage(v); + addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ + }else{ + sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); + if( destIfFalse==destIfNull ){ + /* Combine Step 3 and Step 5 into a single opcode */ + sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + goto sqlite3ExprCodeIN_finished; + } + /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ + addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, + rLhs, nVector); VdbeCoverage(v); + } + + /* Step 4. If the RHS is known to be non-NULL and we did not find + ** an match on the search above, then the result must be FALSE. + */ + if( rRhsHasNull && nVector==1 ){ + sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse); + VdbeCoverage(v); + } + + /* Step 5. If we do not care about the difference between NULL and + ** FALSE, then just return false. + */ + if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse); + + /* Step 6: Loop through rows of the RHS. Compare each row to the LHS. + ** If any comparison is NULL, then the result is NULL. If all + ** comparisons are FALSE then the final result is FALSE. + ** + ** For a scalar LHS, it is sufficient to check just the first row + ** of the RHS. + */ + if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); + VdbeCoverage(v); + if( nVector>1 ){ + destNotNull = sqlite3VdbeMakeLabel(pParse); + }else{ + /* For nVector==1, combine steps 6 and 7 by immediately returning + ** FALSE if the first comparison is not NULL */ + destNotNull = destIfFalse; + } + for(i=0; i1 ){ + sqlite3VdbeResolveLabel(v, destNotNull); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1); + VdbeCoverage(v); + + /* Step 7: If we reach this point, we know that the result must + ** be false. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + } + + /* Jumps here in order to return true. */ + sqlite3VdbeJumpHere(v, addrTruthOp); + +sqlite3ExprCodeIN_finished: + if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs); + VdbeComment((v, "end IN expr")); +sqlite3ExprCodeIN_oom_error: + sqlite3DbFree(pParse->db, aiMap); + sqlite3DbFree(pParse->db, zAff); +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Generate an instruction that will put the floating point +** value described by z[0..n-1] into register iMem. +** +** The z[] string will probably not be zero-terminated. But the +** z[n] character is guaranteed to be something that does not look +** like the continuation of the number. +*/ +static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ + if( ALWAYS(z!=0) ){ + double value; + sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + if( negateFlag ) value = -value; + sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); + } +} +#endif + + +/* +** Generate an instruction that will put the integer describe by +** text z[0..n-1] into register iMem. +** +** Expr.u.zToken is always UTF8 and zero-terminated. +*/ +static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ + Vdbe *v = pParse->pVdbe; + if( pExpr->flags & EP_IntValue ){ + int i = pExpr->u.iValue; + assert( i>=0 ); + if( negFlag ) i = -i; + sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); + }else{ + int c; + i64 value; + const char *z = pExpr->u.zToken; + assert( z!=0 ); + c = sqlite3DecOrHexToI64(z, &value); + if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ +#ifdef SQLITE_OMIT_FLOATING_POINT + sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr); +#else +#ifndef SQLITE_OMIT_HEX_INTEGER + if( sqlite3_strnicmp(z,"0x",2)==0 ){ + sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T", + negFlag?"-":"",pExpr); + }else +#endif + { + codeReal(v, z, negFlag, iMem); + } +#endif + }else{ + if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } + sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); + } + } +} + + +/* Generate code that will load into register regOut a value that is +** appropriate for the iIdxCol-th column of index pIdx. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn( + Parse *pParse, /* The parsing context */ + Index *pIdx, /* The index whose column is to be loaded */ + int iTabCur, /* Cursor pointing to a table row */ + int iIdxCol, /* The column of the index to be loaded */ + int regOut /* Store the index column value in this register */ +){ + i16 iTabCol = pIdx->aiColumn[iIdxCol]; + if( iTabCol==XN_EXPR ){ + assert( pIdx->aColExpr ); + assert( pIdx->aColExpr->nExpr>iIdxCol ); + pParse->iSelfTab = iTabCur + 1; + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); + pParse->iSelfTab = 0; + }else{ + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur, + iTabCol, regOut); + } +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* +** Generate code that will compute the value of generated column pCol +** and store the result in register regOut +*/ +SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the generated column */ + Column *pCol, /* The generated column */ + int regOut /* Put the result in this register */ +){ + int iAddr; + Vdbe *v = pParse->pVdbe; + int nErr = pParse->nErr; + assert( v!=0 ); + assert( pParse->iSelfTab!=0 ); + if( pParse->iSelfTab>0 ){ + iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); + }else{ + iAddr = 0; + } + sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); + if( pCol->affinity>=SQLITE_AFF_TEXT ){ + sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); + } + if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); + if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + +/* +** Generate code to extract the value of the iCol-th column of a table. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( + Vdbe *v, /* Parsing context */ + Table *pTab, /* The table containing the value */ + int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ + int iCol, /* Index of the column to extract */ + int regOut /* Extract the value into this register */ +){ + Column *pCol; + assert( v!=0 ); + assert( pTab!=0 ); + assert( iCol!=XN_EXPR ); + if( iCol<0 || iCol==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + VdbeComment((v, "%s.rowid", pTab->zName)); + }else{ + int op; + int x; + if( IsVirtual(pTab) ){ + op = OP_VColumn; + x = iCol; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ + Parse *pParse = sqlite3VdbeParser(v); + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zCnName); + }else{ + int savedSelfTab = pParse->iSelfTab; + pCol->colFlags |= COLFLAG_BUSY; + pParse->iSelfTab = iTabCur+1; + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, regOut); + pParse->iSelfTab = savedSelfTab; + pCol->colFlags &= ~COLFLAG_BUSY; + } + return; +#endif + }else if( !HasRowid(pTab) ){ + testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) ); + x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol); + op = OP_Column; + }else{ + x = sqlite3TableColumnToStorage(pTab,iCol); + testcase( x!=iCol ); + op = OP_Column; + } + sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); + sqlite3ColumnDefault(v, pTab, iCol, regOut); + } +} + +/* +** Generate code that will extract the iColumn-th column from +** table pTab and store the column value in register iReg. +** +** There must be an open cursor to pTab in iTable when this routine +** is called. If iColumn<0 then code is generated that extracts the rowid. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Description of the table we are reading from */ + int iColumn, /* Index of the table column */ + int iTable, /* The cursor pointing to the table */ + int iReg, /* Store results here */ + u8 p5 /* P5 value for OP_Column + FLAGS */ +){ + assert( pParse->pVdbe!=0 ); + assert( (p5 & (OPFLAG_NOCHNG|OPFLAG_TYPEOFARG|OPFLAG_LENGTHARG))==p5 ); + assert( IsVirtual(pTab) || (p5 & OPFLAG_NOCHNG)==0 ); + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); + if( p5 ){ + VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + if( pOp->opcode==OP_Column ) pOp->p5 = p5; + if( pOp->opcode==OP_VColumn ) pOp->p5 = (p5 & OPFLAG_NOCHNG); + } + return iReg; +} + +/* +** Generate code to move content from registers iFrom...iFrom+nReg-1 +** over to iTo..iTo+nReg-1. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); +} + +/* +** Convert a scalar expression node to a TK_REGISTER referencing +** register iReg. The caller must ensure that iReg already contains +** the correct value for the expression. +*/ +static void exprToRegister(Expr *pExpr, int iReg){ + Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); + if( NEVER(p==0) ) return; + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); +} + +/* +** Evaluate an expression (either a vector or a scalar expression) and store +** the result in contiguous temporary registers. Return the index of +** the first register used to store the result. +** +** If the returned result register is a temporary scalar, then also write +** that register number into *piFreeable. If the returned result register +** is not a temporary or if the expression is a vector set *piFreeable +** to 0. +*/ +static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ + int iResult; + int nResult = sqlite3ExprVectorSize(p); + if( nResult==1 ){ + iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable); + }else{ + *piFreeable = 0; + if( p->op==TK_SELECT ){ +#if SQLITE_OMIT_SUBQUERY + iResult = 0; +#else + iResult = sqlite3CodeSubselect(pParse, p); +#endif + }else{ + int i; + iResult = pParse->nMem+1; + pParse->nMem += nResult; + assert( ExprUseXList(p) ); + for(i=0; ix.pList->a[i].pExpr, i+iResult); + } + } + } + return iResult; +} + +/* +** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5) +** so that a subsequent copy will not be merged into this one. +*/ +static void setDoNotMergeFlagOnCopy(Vdbe *v){ + if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ + sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergeable */ + } +} + +/* +** Generate code to implement special SQL functions that are implemented +** in-line rather than by using the usual callbacks. +*/ +static int exprCodeInlineFunction( + Parse *pParse, /* Parsing context */ + ExprList *pFarg, /* List of function arguments */ + int iFuncId, /* Function ID. One of the INTFUNC_... values */ + int target /* Store function result in this register */ +){ + int nFarg; + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + assert( pFarg!=0 ); + nFarg = pFarg->nExpr; + assert( nFarg>0 ); /* All in-line functions have at least one argument */ + switch( iFuncId ){ + case INLINEFUNC_coalesce: { + /* Attempt a direct implementation of the built-in COALESCE() and + ** IFNULL() functions. This avoids unnecessary evaluation of + ** arguments past the first non-NULL argument. + */ + int endCoalesce = sqlite3VdbeMakeLabel(pParse); + int i; + assert( nFarg>=2 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + for(i=1; ia[i].pExpr, target); + } + setDoNotMergeFlagOnCopy(v); + sqlite3VdbeResolveLabel(v, endCoalesce); + break; + } + case INLINEFUNC_iif: { + Expr caseExpr; + memset(&caseExpr, 0, sizeof(caseExpr)); + caseExpr.op = TK_CASE; + caseExpr.x.pList = pFarg; + return sqlite3ExprCodeTarget(pParse, &caseExpr, target); + } +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + case INLINEFUNC_sqlite_offset: { + Expr *pArg = pFarg->a[0].pExpr; + if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){ + sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + break; + } +#endif + default: { + /* The UNLIKELY() function is a no-op. The result is the value + ** of the first argument. + */ + assert( nFarg==1 || nFarg==2 ); + target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); + break; + } + + /*********************************************************************** + ** Test-only SQL functions that are only usable if enabled + ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS + */ +#if !defined(SQLITE_UNTESTABLE) + case INLINEFUNC_expr_compare: { + /* Compare two expressions using sqlite3ExprCompare() */ + assert( nFarg==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + target); + break; + } + + case INLINEFUNC_expr_implies_expr: { + /* Compare two expressions using sqlite3ExprImpliesExpr() */ + assert( nFarg==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + target); + break; + } + + case INLINEFUNC_implies_nonnull_row: { + /* Result of sqlite3ExprImpliesNonNullRow() */ + Expr *pA1; + assert( nFarg==2 ); + pA1 = pFarg->a[1].pExpr; + if( pA1->op==TK_COLUMN ){ + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1), + target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + break; + } + + case INLINEFUNC_affinity: { + /* The AFFINITY() function evaluates to a string that describes + ** the type affinity of the argument. This is used for testing of + ** the SQLite type logic. + */ + const char *azAff[] = { "blob", "text", "numeric", "integer", + "real", "flexnum" }; + char aff; + assert( nFarg==1 ); + aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); + assert( aff<=SQLITE_AFF_NONE + || (aff>=SQLITE_AFF_BLOB && aff<=SQLITE_AFF_FLEXNUM) ); + sqlite3VdbeLoadString(v, target, + (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); + break; + } +#endif /* !defined(SQLITE_UNTESTABLE) */ + } + return target; +} + +/* +** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. +** If it is, then resolve the expression by reading from the index and +** return the register into which the value has been read. If pExpr is +** not an indexed expression, then return negative. +*/ +static SQLITE_NOINLINE int sqlite3IndexedExprLookup( + Parse *pParse, /* The parsing context */ + Expr *pExpr, /* The expression to potentially bypass */ + int target /* Where to store the result of the expression */ +){ + IndexedExpr *p; + Vdbe *v; + for(p=pParse->pIdxEpr; p; p=p->pIENext){ + u8 exprAff; + int iDataCur = p->iDataCur; + if( iDataCur<0 ) continue; + if( pParse->iSelfTab ){ + if( p->iDataCur!=pParse->iSelfTab-1 ) continue; + iDataCur = -1; + } + if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue; + assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC ); + exprAff = sqlite3ExprAffinity(pExpr); + if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB) + || (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT) + || (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC) + ){ + /* Affinity mismatch on a generated column */ + continue; + } + + v = pParse->pVdbe; + assert( v!=0 ); + if( p->bMaybeNullRow ){ + /* If the index is on a NULL row due to an outer join, then we + ** cannot extract the value from the index. The value must be + ** computed using the original expression. */ + int addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); + VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); + sqlite3VdbeGoto(v, 0); + p = pParse->pIdxEpr; + pParse->pIdxEpr = 0; + sqlite3ExprCode(pParse, pExpr, target); + pParse->pIdxEpr = p; + sqlite3VdbeJumpHere(v, addr+2); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); + VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); + } + return target; + } + return -1; /* Not found */ +} + + +/* +** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This +** function checks the Parse.pIdxPartExpr list to see if this column +** can be replaced with a constant value. If so, it generates code to +** put the constant value in a register (ideally, but not necessarily, +** register iTarget) and returns the register number. +** +** Or, if the TK_COLUMN cannot be replaced by a constant, zero is +** returned. +*/ +static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ + IndexedExpr *p; + for(p=pParse->pIdxPartExpr; p; p=p->pIENext){ + if( pExpr->iColumn==p->iIdxCol && pExpr->iTable==p->iDataCur ){ + Vdbe *v = pParse->pVdbe; + int addr = 0; + int ret; + + if( p->bMaybeNullRow ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNullRow, p->iIdxCur); + } + ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, + (const char*)&p->aff, 1); + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeChangeP3(v, addr, ret); + } + return ret; + } + } + return 0; +} + + +/* +** Generate code into the current Vdbe to evaluate the given +** expression. Attempt to store the results in register "target". +** Return the register where results are stored. +** +** With this routine, there is no guarantee that results will +** be stored in target. The result might be stored in some other +** register if it is convenient to do so. The calling function +** must check the return code and move the results to the desired +** register. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ + Vdbe *v = pParse->pVdbe; /* The VM under construction */ + int op; /* The opcode being coded */ + int inReg = target; /* Results stored in register inReg */ + int regFree1 = 0; /* If non-zero free this temporary register */ + int regFree2 = 0; /* If non-zero free this temporary register */ + int r1, r2; /* Various register numbers */ + Expr tempX; /* Temporary expression node */ + int p5 = 0; + + assert( target>0 && target<=pParse->nMem ); + assert( v!=0 ); + +expr_code_doover: + if( pExpr==0 ){ + op = TK_NULL; + }else if( pParse->pIdxEpr!=0 + && !ExprHasProperty(pExpr, EP_Leaf) + && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0 + ){ + return r1; + }else{ + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + op = pExpr->op; + } + assert( op!=TK_ORDER ); + switch( op ){ + case TK_AGG_COLUMN: { + AggInfo *pAggInfo = pExpr->pAggInfo; + struct AggInfo_col *pCol; + assert( pAggInfo!=0 ); + assert( pExpr->iAgg>=0 ); + if( pExpr->iAgg>=pAggInfo->nColumn ){ + /* Happens when the left table of a RIGHT JOIN is null and + ** is using an expression index */ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); +#ifdef SQLITE_VDBE_COVERAGE + /* Verify that the OP_Null above is exercised by tests + ** tag-20230325-2 */ + sqlite3VdbeAddOp3(v, OP_NotNull, target, 1, 20230325); + VdbeCoverageNeverTaken(v); +#endif + break; + } + pCol = &pAggInfo->aCol[pExpr->iAgg]; + if( !pAggInfo->directMode ){ + return AggInfoColumnReg(pAggInfo, pExpr->iAgg); + }else if( pAggInfo->useSortingIdx ){ + Table *pTab = pCol->pTab; + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + pCol->iSorterColumn, target); + if( pTab==0 ){ + /* No comment added */ + }else if( pCol->iColumn<0 ){ + VdbeComment((v,"%s.rowid",pTab->zName)); + }else{ + VdbeComment((v,"%s.%s", + pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); + if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } + } + return target; + }else if( pExpr->y.pTab==0 ){ + /* This case happens when the argument to an aggregate function + ** is rewritten by aggregateConvertIndexedExprRefToColumn() */ + sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target); + return target; + } + /* Otherwise, fall thru into the TK_COLUMN case */ + /* no break */ deliberate_fall_through + } + case TK_COLUMN: { + int iTab = pExpr->iTable; + int iReg; + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + /* This COLUMN expression is really a constant due to WHERE clause + ** constraints, and that constant is coded by the pExpr->pLeft + ** expression. However, make sure the constant has the correct + ** datatype by applying the Affinity of the table column to the + ** constant. + */ + int aff; + iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + assert( ExprUseYTab(pExpr) ); + assert( pExpr->y.pTab!=0 ); + aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + if( aff>SQLITE_AFF_BLOB ){ + static const char zAff[] = "B\000C\000D\000E\000F"; + assert( SQLITE_AFF_BLOB=='A' ); + assert( SQLITE_AFF_TEXT=='B' ); + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, + &zAff[(aff-'B')*2], P4_STATIC); + } + return iReg; + } + if( iTab<0 ){ + if( pParse->iSelfTab<0 ){ + /* Other columns in the same row for CHECK constraints or + ** generated columns or for inserting into partial index. + ** The row is unpacked into registers beginning at + ** 0-(pParse->iSelfTab). The rowid (if any) is in a register + ** immediately prior to the first column. + */ + Column *pCol; + Table *pTab; + int iSrc; + int iCol = pExpr->iColumn; + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + assert( pTab!=0 ); + assert( iCol>=XN_ROWID ); + assert( iColnCol ); + if( iCol<0 ){ + return -1-pParse->iSelfTab; + } + pCol = pTab->aCol + iCol; + testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) ); + iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zCnName); + return 0; + } + pCol->colFlags |= COLFLAG_BUSY; + if( pCol->colFlags & COLFLAG_NOTAVAIL ){ + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, iSrc); + } + pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); + return iSrc; + }else +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + if( pCol->affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target); + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + return target; + }else{ + return iSrc; + } + }else{ + /* Coding an expression that is part of an index where column names + ** in the index refer to the table to which the index belongs */ + iTab = pParse->iSelfTab - 1; + } + } + else if( pParse->pIdxPartExpr + && 0!=(r1 = exprPartidxExprLookup(pParse, pExpr, target)) + ){ + return r1; + } + assert( ExprUseYTab(pExpr) ); + assert( pExpr->y.pTab!=0 ); + iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, + pExpr->iColumn, iTab, target, + pExpr->op2); + return iReg; + } + case TK_INTEGER: { + codeInteger(pParse, pExpr, 0, target); + return target; + } + case TK_TRUEFALSE: { + sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target); + return target; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pExpr->u.zToken, 0, target); + return target; + } +#endif + case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3VdbeLoadString(v, target, pExpr->u.zToken); + return target; + } + default: { + /* Make NULL the default case so that if a bug causes an illegal + ** Expr node to be passed into this function, it will be handled + ** sanely and not crash. But keep the assert() to bring the problem + ** to the attention of the developers. */ + assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed ); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + return target; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + int n; + const char *z; + char *zBlob; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + z = &pExpr->u.zToken[2]; + n = sqlite3Strlen30(z) - 1; + assert( z[n]=='\'' ); + zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); + sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); + return target; + } +#endif + case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pExpr->u.zToken[0]!=0 ); + sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); + if( pExpr->u.zToken[1]!=0 ){ + const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); + assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) ); + pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ + sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); + } + return target; + } + case TK_REGISTER: { + return pExpr->iTable; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + sqlite3ExprCode(pParse, pExpr->pLeft, target); + assert( inReg==target ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3VdbeAddOp2(v, OP_Cast, target, + sqlite3AffinityType(pExpr->u.zToken, 0)); + return inReg; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_IS: + case TK_ISNOT: + op = (op==TK_IS) ? TK_EQ : TK_NE; + p5 = SQLITE_NULLEQ; + /* fall-through */ + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + Expr *pLeft = pExpr->pLeft; + if( sqlite3ExprIsVector(pLeft) ){ + codeVectorCompare(pParse, pExpr, target, op, p5); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg); + codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2, + sqlite3VdbeCurrentAddr(v)+2, p5, + ExprHasProperty(pExpr,EP_Commuted)); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + if( p5==SQLITE_NULLEQ ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg); + }else{ + sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2); + } + testcase( regFree1==0 ); + testcase( regFree2==0 ); + } + break; + } + case TK_AND: + case TK_OR: + case TK_PLUS: + case TK_STAR: + case TK_MINUS: + case TK_REM: + case TK_BITAND: + case TK_BITOR: + case TK_SLASH: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: { + assert( TK_AND==OP_And ); testcase( op==TK_AND ); + assert( TK_OR==OP_Or ); testcase( op==TK_OR ); + assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS ); + assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS ); + assert( TK_REM==OP_Remainder ); testcase( op==TK_REM ); + assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND ); + assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR ); + assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH ); + assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); + assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); + assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + sqlite3VdbeAddOp3(v, op, r2, r1, target); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_UMINUS: { + Expr *pLeft = pExpr->pLeft; + assert( pLeft ); + if( pLeft->op==TK_INTEGER ){ + codeInteger(pParse, pLeft, 1, target); + return target; +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( pLeft->op==TK_FLOAT ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pLeft->u.zToken, 1, target); + return target; +#endif + }else{ + tempX.op = TK_INTEGER; + tempX.flags = EP_IntValue|EP_TokenOnly; + tempX.u.iValue = 0; + ExprClearVVAProperties(&tempX); + r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); + sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); + testcase( regFree2==0 ); + } + break; + } + case TK_BITNOT: + case TK_NOT: { + assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT ); + assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + sqlite3VdbeAddOp2(v, op, r1, inReg); + break; + } + case TK_TRUTH: { + int isTrue; /* IS TRUE or IS NOT TRUE */ + int bNormal; /* IS TRUE or IS FALSE */ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + bNormal = pExpr->op2==TK_IS; + testcase( isTrue && bNormal); + testcase( !isTrue && bNormal); + sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + int addr; + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + addr = sqlite3VdbeAddOp1(v, op, r1); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); + sqlite3VdbeAddOp2(v, OP_Integer, 0, target); + sqlite3VdbeJumpHere(v, addr); + break; + } + case TK_AGG_FUNCTION: { + AggInfo *pInfo = pExpr->pAggInfo; + if( pInfo==0 + || NEVER(pExpr->iAgg<0) + || NEVER(pExpr->iAgg>=pInfo->nFunc) + ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); + }else{ + return AggInfoFuncReg(pInfo, pExpr->iAgg); + } + break; + } + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + int nFarg; /* Number of function arguments */ + FuncDef *pDef; /* The function definition object */ + const char *zId; /* The function name */ + u32 constMask = 0; /* Mask of function arguments that are constant */ + int i; /* Loop counter */ + sqlite3 *db = pParse->db; /* The database connection */ + u8 enc = ENC(db); /* The text encoding used by this database */ + CollSeq *pColl = 0; /* A collating sequence */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + return pExpr->y.pWin->regResult; + } +#endif + + if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ + /* SQL functions can be expensive. So try to avoid running them + ** multiple times if we know they always give the same result */ + return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); + } + assert( !ExprHasProperty(pExpr, EP_TokenOnly) ); + assert( ExprUseXList(pExpr) ); + pFarg = pExpr->x.pList; + nFarg = pFarg ? pFarg->nExpr : 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + zId = pExpr->u.zToken; + pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 && pParse->explain ){ + pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); + } +#endif + if( pDef==0 || pDef->xFinalize!=0 ){ + sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); + break; + } + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ + assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); + assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); + return exprCodeInlineFunction(pParse, pFarg, + SQLITE_PTR_TO_INT(pDef->pUserData), target); + }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){ + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); + } + + for(i=0; ia[i].pExpr) ){ + testcase( i==31 ); + constMask |= MASKBIT32(i); + } + if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); + } + } + if( pFarg ){ + if( constMask ){ + r1 = pParse->nMem+1; + pParse->nMem += nFarg; + }else{ + r1 = sqlite3GetTempRange(pParse, nFarg); + } + + /* For length() and typeof() and octet_length() functions, + ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG + ** or OPFLAG_TYPEOFARG or OPFLAG_BYTELENARG respectively, to avoid + ** unnecessary data loading. + */ + if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ + u8 exprOp; + assert( nFarg==1 ); + assert( pFarg->a[0].pExpr!=0 ); + exprOp = pFarg->a[0].pExpr->op; + if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ + assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); + assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); + assert( SQLITE_FUNC_BYTELEN==OPFLAG_BYTELENARG ); + assert( (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG)==OPFLAG_BYTELENARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_LENGTHARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_TYPEOFARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG); + pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG; + } + } + + sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR); + }else{ + r1 = 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Possibly overload the function if the first argument is + ** a virtual table column. + ** + ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the + ** second argument, not the first, as the argument to test to + ** see if it is a column in a virtual table. This is done because + ** the left operand of infix functions (the operand we want to + ** control overloading) ends up as the second argument to the + ** function. The expression "A glob B" is equivalent to + ** "glob(B,A). We want to use the A in "A glob B" to test + ** for function overloading. But we use the B term in "glob(B,A)". + */ + if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); + }else if( nFarg>0 ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); + } +#endif + if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + if( !pColl ) pColl = db->pDfltColl; + sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, + pDef, pExpr->op2); + if( nFarg ){ + if( constMask==0 ){ + sqlite3ReleaseTempRange(pParse, r1, nFarg); + }else{ + sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1); + } + } + return target; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: + case TK_SELECT: { + int nCol; + testcase( op==TK_EXISTS ); + testcase( op==TK_SELECT ); + if( pParse->db->mallocFailed ){ + return 0; + }else if( op==TK_SELECT + && ALWAYS( ExprUseXSelect(pExpr) ) + && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 + ){ + sqlite3SubselectError(pParse, nCol, 1); + }else{ + return sqlite3CodeSubselect(pParse, pExpr); + } + break; + } + case TK_SELECT_COLUMN: { + int n; + Expr *pLeft = pExpr->pLeft; + if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){ + pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft); + pLeft->op2 = pParse->withinRJSubrtn; + } + assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR ); + n = sqlite3ExprVectorSize(pLeft); + if( pExpr->iTable!=n ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", + pExpr->iTable, n); + } + return pLeft->iTable + pExpr->iColumn; + } + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(pParse); + int destIfNull = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + sqlite3VdbeResolveLabel(v, destIfFalse); + sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); + sqlite3VdbeResolveLabel(v, destIfNull); + return target; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + exprCodeBetween(pParse, pExpr, target, 0, 0); + return target; + } + case TK_COLLATE: { + if( !ExprHasProperty(pExpr, EP_Collate) ){ + /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called + ** "SOFT-COLLATE" that is added to constraints that are pushed down + ** from outer queries into sub-queries by the push-down optimization. + ** Clear subtypes as subtypes may not cross a subquery boundary. + */ + assert( pExpr->pLeft ); + sqlite3ExprCode(pParse, pExpr->pLeft, target); + sqlite3VdbeAddOp1(v, OP_ClrSubtype, target); + return target; + }else{ + pExpr = pExpr->pLeft; + goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */ + } + } + case TK_SPAN: + case TK_UPLUS: { + pExpr = pExpr->pLeft; + goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */ + } + + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + ** + ** The expression is implemented using an OP_Param opcode. The p1 + ** parameter is set to 0 for an old.rowid reference, or to (i+1) + ** to reference another column of the old.* pseudo-table, where + ** i is the index of the column. For a new.rowid reference, p1 is + ** set to (n+1), where n is the number of columns in each pseudo-table. + ** For a reference to any other column in the new.* pseudo-table, p1 + ** is set to (n+2+i), where n and i are as defined previously. For + ** example, if the table on which triggers are being fired is + ** declared as: + ** + ** CREATE TABLE t1(a, b); + ** + ** Then p1 is interpreted as follows: + ** + ** p1==0 -> old.rowid p1==3 -> new.rowid + ** p1==1 -> old.a p1==4 -> new.a + ** p1==2 -> old.b p1==5 -> new.b + */ + Table *pTab; + int iCol; + int p1; + + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + iCol = pExpr->iColumn; + p1 = pExpr->iTable * (pTab->nCol+1) + 1 + + sqlite3TableColumnToStorage(pTab, iCol); + + assert( pExpr->iTable==0 || pExpr->iTable==1 ); + assert( iCol>=-1 && iColnCol ); + assert( pTab->iPKey<0 || iCol!=pTab->iPKey ); + assert( p1>=0 && p1<(pTab->nCol*2+2) ); + + sqlite3VdbeAddOp2(v, OP_Param, p1, target); + VdbeComment((v, "r[%d]=%s.%s", target, + (pExpr->iTable ? "new" : "old"), + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zCnName) + )); + +#ifndef SQLITE_OMIT_FLOATING_POINT + /* If the column has REAL affinity, it may currently be stored as an + ** integer. Use OP_RealAffinity to make sure it is really real. + ** + ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to + ** floating point when extracting it from the record. */ + if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } +#endif + break; + } + + case TK_VECTOR: { + sqlite3ErrorMsg(pParse, "row value misused"); + break; + } + + /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions + ** that derive from the right-hand table of a LEFT JOIN. The + ** Expr.iTable value is the table number for the right-hand table. + ** The expression is only evaluated if that table is not currently + ** on a LEFT JOIN NULL row. + */ + case TK_IF_NULL_ROW: { + int addrINR; + u8 okConstFactor = pParse->okConstFactor; + AggInfo *pAggInfo = pExpr->pAggInfo; + if( pAggInfo ){ + assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); + if( !pAggInfo->directMode ){ + inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg); + break; + } + if( pExpr->pAggInfo->useSortingIdx ){ + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + pAggInfo->aCol[pExpr->iAgg].iSorterColumn, + target); + inReg = target; + break; + } + } + addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target); + /* The OP_IfNullRow opcode above can overwrite the result register with + ** NULL. So we have to ensure that the result register is not a value + ** that is suppose to be a constant. Two defenses are needed: + ** (1) Temporarily disable factoring of constant expressions + ** (2) Make sure the computed value really is stored in register + ** "target" and not someplace else. + */ + pParse->okConstFactor = 0; /* note (1) above */ + sqlite3ExprCode(pParse, pExpr->pLeft, target); + assert( target==inReg ); + pParse->okConstFactor = okConstFactor; + sqlite3VdbeJumpHere(v, addrINR); + break; + } + + /* + ** Form A: + ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form B: + ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form A is can be transformed into the equivalent form B as follows: + ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ... + ** WHEN x=eN THEN rN ELSE y END + ** + ** X (if it exists) is in pExpr->pLeft. + ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is + ** odd. The Y is also optional. If the number of elements in x.pList + ** is even, then Y is omitted and the "otherwise" result is NULL. + ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1]. + ** + ** The result of the expression is the Ri for the first matching Ei, + ** or if there is no matching Ei, the ELSE term Y, or if there is + ** no ELSE term, NULL. + */ + case TK_CASE: { + int endLabel; /* GOTO label for end of CASE stmt */ + int nextCase; /* GOTO label for next WHEN clause */ + int nExpr; /* 2x number of WHEN terms */ + int i; /* Loop counter */ + ExprList *pEList; /* List of WHEN terms */ + struct ExprList_item *aListelem; /* Array of WHEN terms */ + Expr opCompare; /* The X==Ei expression */ + Expr *pX; /* The X expression */ + Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ + Expr *pDel = 0; + sqlite3 *db = pParse->db; + + assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 ); + assert(pExpr->x.pList->nExpr > 0); + pEList = pExpr->x.pList; + aListelem = pEList->a; + nExpr = pEList->nExpr; + endLabel = sqlite3VdbeMakeLabel(pParse); + if( (pX = pExpr->pLeft)!=0 ){ + pDel = sqlite3ExprDup(db, pX, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDel); + break; + } + testcase( pX->op==TK_COLUMN ); + exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + testcase( regFree1==0 ); + memset(&opCompare, 0, sizeof(opCompare)); + opCompare.op = TK_EQ; + opCompare.pLeft = pDel; + pTest = &opCompare; + /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: + ** The value in regFree1 might get SCopy-ed into the file result. + ** So make sure that the regFree1 register is not reused for other + ** purposes and possibly overwritten. */ + regFree1 = 0; + } + for(i=0; iop==TK_COLUMN ); + sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); + testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); + sqlite3VdbeGoto(v, endLabel); + sqlite3VdbeResolveLabel(v, nextCase); + } + if( (nExpr&1)!=0 ){ + sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + sqlite3ExprDelete(db, pDel); + setDoNotMergeFlagOnCopy(v); + sqlite3VdbeResolveLabel(v, endLabel); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + assert( pExpr->affExpr==OE_Rollback + || pExpr->affExpr==OE_Abort + || pExpr->affExpr==OE_Fail + || pExpr->affExpr==OE_Ignore + ); + if( !pParse->pTriggerTab && !pParse->nested ){ + sqlite3ErrorMsg(pParse, + "RAISE() may only be used within a trigger-program"); + return 0; + } + if( pExpr->affExpr==OE_Abort ){ + sqlite3MayAbort(pParse); + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->affExpr==OE_Ignore ){ + sqlite3VdbeAddOp4( + v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + VdbeCoverage(v); + }else{ + sqlite3HaltConstraint(pParse, + pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, + pExpr->affExpr, pExpr->u.zToken, 0, 0); + } + + break; + } +#endif + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); + return inReg; +} + +/* +** Generate code that will evaluate expression pExpr just one time +** per prepared statement execution. +** +** If the expression uses functions (that might throw an exception) then +** guard them with an OP_Once opcode to ensure that the code is only executed +** once. If no functions are involved, then factor the code out and put it at +** the end of the prepared statement in the initialization section. +** +** If regDest>0 then the result is always stored in that register and the +** result is not reusable. If regDest<0 then this routine is free to +** store the value wherever it wants. The register where the expression +** is stored is returned. When regDest<0, two identical expressions might +** code to the same register, if they do not contain function calls and hence +** are factored out into the initialization section at the end of the +** prepared statement. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The expression to code when the VDBE initializes */ + int regDest /* Store the value in this register */ +){ + ExprList *p; + assert( ConstFactorOk(pParse) ); + assert( regDest!=0 ); + p = pParse->pConstExpr; + if( regDest<0 && p ){ + struct ExprList_item *pItem; + int i; + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ + if( pItem->fg.reusable + && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 + ){ + return pItem->u.iConstExprReg; + } + } + } + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){ + Vdbe *v = pParse->pVdbe; + int addr; + assert( v ); + addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + pParse->okConstFactor = 0; + if( !pParse->db->mallocFailed ){ + if( regDest<0 ) regDest = ++pParse->nMem; + sqlite3ExprCode(pParse, pExpr, regDest); + } + pParse->okConstFactor = 1; + sqlite3ExprDelete(pParse->db, pExpr); + sqlite3VdbeJumpHere(v, addr); + }else{ + p = sqlite3ExprListAppend(pParse, p, pExpr); + if( p ){ + struct ExprList_item *pItem = &p->a[p->nExpr-1]; + pItem->fg.reusable = regDest<0; + if( regDest<0 ) regDest = ++pParse->nMem; + pItem->u.iConstExprReg = regDest; + } + pParse->pConstExpr = p; + } + return regDest; +} + +/* +** Generate code to evaluate an expression and store the results +** into a register. Return the register number where the results +** are stored. +** +** If the register is a temporary register that can be deallocated, +** then write its number into *pReg. If the result register is not +** a temporary, then set *pReg to zero. +** +** If pExpr is a constant, then this routine might generate this +** code to fill the register in the initialization section of the +** VDBE program, in order to factor it out of the evaluation loop. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ + int r2; + pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); + if( ConstFactorOk(pParse) + && ALWAYS(pExpr!=0) + && pExpr->op!=TK_REGISTER + && sqlite3ExprIsConstantNotJoin(pExpr) + ){ + *pReg = 0; + r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); + }else{ + int r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( r2==r1 ){ + *pReg = r1; + }else{ + sqlite3ReleaseTempReg(pParse, r1); + *pReg = 0; + } + } + return r2; +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. +*/ +SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ + int inReg; + + assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) ); + assert( target>0 && target<=pParse->nMem ); + assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); + if( pParse->pVdbe==0 ) return; + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); + if( inReg!=target ){ + u8 op; + Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr); + testcase( pX!=pExpr ); + if( ALWAYS(pX) + && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER) + ){ + op = OP_Copy; + }else{ + op = OP_SCopy; + } + sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target); + } +} + +/* +** Make a transient copy of expression pExpr and then code it using +** sqlite3ExprCode(). This routine works just like sqlite3ExprCode() +** except that the input expression is guaranteed to be unchanged. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ + sqlite3 *db = pParse->db; + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target); + sqlite3ExprDelete(db, pExpr); +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. If the expression is constant, then this routine +** might choose to code the expression at initialization time. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ + sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); + }else{ + sqlite3ExprCodeCopy(pParse, pExpr, target); + } +} + +/* +** Generate code that pushes the value of every element of the given +** expression list into a sequence of registers beginning at target. +** +** Return the number of elements evaluated. The number returned will +** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF +** is defined. +** +** The SQLITE_ECEL_DUP flag prevents the arguments from being +** filled using OP_SCopy. OP_Copy must be used instead. +** +** The SQLITE_ECEL_FACTOR argument allows constant arguments to be +** factored out into initialization code. +** +** The SQLITE_ECEL_REF flag means that expressions in the list with +** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored +** in registers at srcReg, and so the value can be copied from there. +** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0 +** are simply omitted rather than being copied from srcReg. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The expression list to be coded */ + int target, /* Where to write results */ + int srcReg, /* Source registers if SQLITE_ECEL_REF */ + u8 flags /* SQLITE_ECEL_* flags */ +){ + struct ExprList_item *pItem; + int i, j, n; + u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; + Vdbe *v = pParse->pVdbe; + assert( pList!=0 ); + assert( target>0 ); + assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ + n = pList->nExpr; + if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; + for(pItem=pList->a, i=0; ipExpr; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( pItem->fg.bSorterRef ){ + i--; + n--; + }else +#endif + if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ + if( flags & SQLITE_ECEL_OMITREF ){ + i--; + n--; + }else{ + sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); + } + }else if( (flags & SQLITE_ECEL_FACTOR)!=0 + && sqlite3ExprIsConstantNotJoin(pExpr) + ){ + sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); + }else{ + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); + if( inReg!=target+i ){ + VdbeOp *pOp; + if( copyOp==OP_Copy + && (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy + && pOp->p1+pOp->p3+1==inReg + && pOp->p2+pOp->p3+1==target+i + && pOp->p5==0 /* The do-not-merge flag must be clear */ + ){ + pOp->p3++; + }else{ + sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); + } + } + } + } + return n; +} + +/* +** Generate code for a BETWEEN operator. +** +** x BETWEEN y AND z +** +** The above is equivalent to +** +** x>=y AND x<=z +** +** Code it as such, taking care to do the common subexpression +** elimination of x. +** +** The xJumpIf parameter determines details: +** +** NULL: Store the boolean result in reg[dest] +** sqlite3ExprIfTrue: Jump to dest if true +** sqlite3ExprIfFalse: Jump to dest if false +** +** The jumpIfNull parameter is ignored if xJumpIf is NULL. +*/ +static void exprCodeBetween( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The BETWEEN expression */ + int dest, /* Jump destination or storage location */ + void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ + int jumpIfNull /* Take the jump if the BETWEEN is NULL */ +){ + Expr exprAnd; /* The AND operator in x>=y AND x<=z */ + Expr compLeft; /* The x>=y term */ + Expr compRight; /* The x<=z term */ + int regFree1 = 0; /* Temporary use register */ + Expr *pDel = 0; + sqlite3 *db = pParse->db; + + memset(&compLeft, 0, sizeof(Expr)); + memset(&compRight, 0, sizeof(Expr)); + memset(&exprAnd, 0, sizeof(Expr)); + + assert( ExprUseXList(pExpr) ); + pDel = sqlite3ExprDup(db, pExpr->pLeft, 0); + if( db->mallocFailed==0 ){ + exprAnd.op = TK_AND; + exprAnd.pLeft = &compLeft; + exprAnd.pRight = &compRight; + compLeft.op = TK_GE; + compLeft.pLeft = pDel; + compLeft.pRight = pExpr->x.pList->a[0].pExpr; + compRight.op = TK_LE; + compRight.pLeft = pDel; + compRight.pRight = pExpr->x.pList->a[1].pExpr; + exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + if( xJump ){ + xJump(pParse, &exprAnd, dest, jumpIfNull); + }else{ + /* Mark the expression is being from the ON or USING clause of a join + ** so that the sqlite3ExprCodeTarget() routine will not attempt to move + ** it into the Parse.pConstExpr list. We should use a new bit for this, + ** for clarity, but we are out of bits in the Expr.flags field so we + ** have to reuse the EP_OuterON bit. Bummer. */ + pDel->flags |= EP_OuterON; + sqlite3ExprCodeTarget(pParse, &exprAnd, dest); + } + sqlite3ReleaseTempReg(pParse, regFree1); + } + sqlite3ExprDelete(db, pDel); + + /* Ensure adequate test coverage */ + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==0 ); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is true but execution +** continues straight thru if the expression is false. +** +** If the expression evaluates to NULL (neither true nor false), then +** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL. +** +** This code depends on the fact that certain token values (ex: TK_EQ) +** are the same as opcode values (ex: OP_Eq) that implement the corresponding +** operation. Special comments in vdbe.c and the mkopcodeh.awk script in +** the make process cause these values to align. Assert()s in the code +** below verify that the numbers are aligned correctly. +*/ +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ + if( NEVER(pExpr==0) ) return; /* No way this can happen */ + assert( !ExprHasVVAProperty(pExpr, EP_Immutable) ); + op = pExpr->op; + switch( op ){ + case TK_AND: + case TK_OR: { + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull); + }else if( op==TK_AND ){ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + }else{ + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + } + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_TRUTH: { + int isNot; /* IS NOT TRUE or IS NOT FALSE */ + int isTrue; /* IS TRUE or IS NOT TRUE */ + testcase( jumpIfNull==0 ); + isNot = pExpr->op2==TK_ISNOT; + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + testcase( isTrue && isNot ); + testcase( !isTrue && isNot ); + if( isTrue ^ isNot ){ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + }else{ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + } + break; + } + case TK_IS: + case TK_ISNOT: + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + op = (op==TK_IS) ? TK_EQ : TK_NE; + jumpIfNull = SQLITE_NULLEQ; + /* no break */ deliberate_fall_through + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; + testcase( jumpIfNull==0 ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted)); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeTypeofColumn(v, r1); + sqlite3VdbeAddOp2(v, op, r1, dest); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); + testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(pParse); + int destIfNull = jumpIfNull ? dest : destIfFalse; + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeGoto(v, dest); + sqlite3VdbeResolveLabel(v, destIfFalse); + break; + } +#endif + default: { + default_expr: + if( ExprAlwaysTrue(pExpr) ){ + sqlite3VdbeGoto(v, dest); + }else if( ExprAlwaysFalse(pExpr) ){ + /* No-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is false but execution +** continues straight thru if the expression is true. +** +** If the expression evaluates to NULL (neither true nor false) then +** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull +** is 0. +*/ +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ + if( pExpr==0 ) return; + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + + /* The value of pExpr->op and op are related as follows: + ** + ** pExpr->op op + ** --------- ---------- + ** TK_ISNULL OP_NotNull + ** TK_NOTNULL OP_IsNull + ** TK_NE OP_Eq + ** TK_EQ OP_Ne + ** TK_GT OP_Le + ** TK_LE OP_Gt + ** TK_GE OP_Lt + ** TK_LT OP_Ge + ** + ** For other values of pExpr->op, op is undefined and unused. + ** The value of TK_ and OP_ constants are arranged such that we + ** can compute the mapping above using the following expression. + ** Assert()s verify that the computation is correct. + */ + op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1); + + /* Verify correct alignment of TK_ and OP_ constants + */ + assert( pExpr->op!=TK_ISNULL || op==OP_NotNull ); + assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull ); + assert( pExpr->op!=TK_NE || op==OP_Eq ); + assert( pExpr->op!=TK_EQ || op==OP_Ne ); + assert( pExpr->op!=TK_LT || op==OP_Ge ); + assert( pExpr->op!=TK_LE || op==OP_Gt ); + assert( pExpr->op!=TK_GT || op==OP_Le ); + assert( pExpr->op!=TK_GE || op==OP_Lt ); + + switch( pExpr->op ){ + case TK_AND: + case TK_OR: { + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull); + }else if( pExpr->op==TK_AND ){ + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + }else{ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + } + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_TRUTH: { + int isNot; /* IS NOT TRUE or IS NOT FALSE */ + int isTrue; /* IS TRUE or IS NOT TRUE */ + testcase( jumpIfNull==0 ); + isNot = pExpr->op2==TK_ISNOT; + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + testcase( isTrue && isNot ); + testcase( !isTrue && isNot ); + if( isTrue ^ isNot ){ + /* IS TRUE and IS NOT FALSE */ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? 0 : SQLITE_JUMPIFNULL); + + }else{ + /* IS FALSE and IS NOT TRUE */ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? 0 : SQLITE_JUMPIFNULL); + } + break; + } + case TK_IS: + case TK_ISNOT: + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + jumpIfNull = SQLITE_NULLEQ; + /* no break */ deliberate_fall_through + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; + testcase( jumpIfNull==0 ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeTypeofColumn(v, r1); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); + testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); + testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + if( jumpIfNull ){ + sqlite3ExprCodeIN(pParse, pExpr, dest, dest); + }else{ + int destIfNull = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); + sqlite3VdbeResolveLabel(v, destIfNull); + } + break; + } +#endif + default: { + default_expr: + if( ExprAlwaysFalse(pExpr) ){ + sqlite3VdbeGoto(v, dest); + }else if( ExprAlwaysTrue(pExpr) ){ + /* no-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before +** code generation, and that copy is deleted after code generation. This +** ensures that the original pExpr is unchanged. +*/ +SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){ + sqlite3 *db = pParse->db; + Expr *pCopy = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed==0 ){ + sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull); + } + sqlite3ExprDelete(db, pCopy); +} + +/* +** Expression pVar is guaranteed to be an SQL variable. pExpr may be any +** type of expression. +** +** If pExpr is a simple SQL value - an integer, real, string, blob +** or NULL value - then the VDBE currently being prepared is configured +** to re-prepare each time a new value is bound to variable pVar. +** +** Additionally, if pExpr is a simple SQL value and the value is the +** same as that currently bound to variable pVar, non-zero is returned. +** Otherwise, if the values are not the same or if pExpr is not a simple +** SQL value, zero is returned. +*/ +static int exprCompareVariable( + const Parse *pParse, + const Expr *pVar, + const Expr *pExpr +){ + int res = 0; + int iVar; + sqlite3_value *pL, *pR = 0; + + sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); + if( pR ){ + iVar = pVar->iColumn; + sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); + pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB); + if( pL ){ + if( sqlite3_value_type(pL)==SQLITE_TEXT ){ + sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ + } + res = 0==sqlite3MemCompare(pL, pR, 0); + } + sqlite3ValueFree(pR); + sqlite3ValueFree(pL); + } + + return res; +} + +/* +** Do a deep comparison of two expression trees. Return 0 if the two +** expressions are completely identical. Return 1 if they differ only +** by a COLLATE operator at the top level. Return 2 if there are differences +** other than the top-level COLLATE operator. +** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** +** The pA side might be using TK_REGISTER. If that is the case and pB is +** not using TK_REGISTER but is otherwise equivalent, then still return 0. +** +** Sometimes this routine will return 2 even if the two expressions +** really are equivalent. If we cannot prove that the expressions are +** identical, we return 2 just to be safe. So if this routine +** returns 2, then you do not really know for certain if the two +** expressions are the same. But if you get a 0 or 1 return, then you +** can be sure the expressions are the same. In the places where +** this routine is used, it does not hurt to get an extra 2 - that +** just might result in some slightly slower code. But returning +** an incorrect 0 or 1 could lead to a malfunction. +** +** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in +** pParse->pReprepare can be matched against literals in pB. The +** pParse->pVdbe->expmask bitmask is updated for each variable referenced. +** If pParse is NULL (the normal case) then any TK_VARIABLE term in +** Argument pParse should normally be NULL. If it is not NULL and pA or +** pB causes a return value of 2. +*/ +SQLITE_PRIVATE int sqlite3ExprCompare( + const Parse *pParse, + const Expr *pA, + const Expr *pB, + int iTab +){ + u32 combinedFlags; + if( pA==0 || pB==0 ){ + return pB==pA ? 0 : 2; + } + if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){ + return 0; + } + combinedFlags = pA->flags | pB->flags; + if( combinedFlags & EP_IntValue ){ + if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){ + return 0; + } + return 2; + } + if( pA->op!=pB->op || pA->op==TK_RAISE ){ + if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){ + return 1; + } + if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ + return 1; + } + if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN + && pB->iTable<0 && pA->iTable==iTab + ){ + /* fall through */ + }else{ + return 2; + } + } + assert( !ExprHasProperty(pA, EP_IntValue) ); + assert( !ExprHasProperty(pB, EP_IntValue) ); + if( pA->u.zToken ){ + if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ + if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( pA->op==pB->op ); + if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){ + return 2; + } + if( ExprHasProperty(pA,EP_WinFunc) ){ + if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){ + return 2; + } + } +#endif + }else if( pA->op==TK_NULL ){ + return 0; + }else if( pA->op==TK_COLLATE ){ + if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; + }else + if( pB->u.zToken!=0 + && pA->op!=TK_COLUMN + && pA->op!=TK_AGG_COLUMN + && strcmp(pA->u.zToken,pB->u.zToken)!=0 + ){ + return 2; + } + } + if( (pA->flags & (EP_Distinct|EP_Commuted)) + != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2; + if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ + if( combinedFlags & EP_xIsSelect ) return 2; + if( (combinedFlags & EP_FixedCol)==0 + && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + if( pA->op!=TK_STRING + && pA->op!=TK_TRUEFALSE + && ALWAYS((combinedFlags & EP_Reduced)==0) + ){ + if( pA->iColumn!=pB->iColumn ) return 2; + if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2; + if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){ + return 2; + } + } + } + return 0; +} + +/* +** Compare two ExprList objects. Return 0 if they are identical, 1 +** if they are certainly different, or 2 if it is not possible to +** determine if they are identical or not. +** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** +** This routine might return non-zero for equivalent ExprLists. The +** only consequence will be disabled optimizations. But this routine +** must never return 0 if the two ExprList objects are different, or +** a malfunction will result. +** +** Two NULL pointers are considered to be the same. But a NULL pointer +** always differs from a non-NULL pointer. +*/ +SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){ + int i; + if( pA==0 && pB==0 ) return 0; + if( pA==0 || pB==0 ) return 1; + if( pA->nExpr!=pB->nExpr ) return 1; + for(i=0; inExpr; i++){ + int res; + Expr *pExprA = pA->a[i].pExpr; + Expr *pExprB = pB->a[i].pExpr; + if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1; + if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; + } + return 0; +} + +/* +** Like sqlite3ExprCompare() except COLLATE operators at the top-level +** are ignored. +*/ +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ + return sqlite3ExprCompare(0, + sqlite3ExprSkipCollate(pA), + sqlite3ExprSkipCollate(pB), + iTab); +} + +/* +** Return non-zero if Expr p can only be true if pNN is not NULL. +** +** Or if seenNot is true, return non-zero if Expr p can only be +** non-NULL if pNN is not NULL +*/ +static int exprImpliesNotNull( + const Parse *pParse,/* Parsing context */ + const Expr *p, /* The expression to be checked */ + const Expr *pNN, /* The expression that is NOT NULL */ + int iTab, /* Table being evaluated */ + int seenNot /* Return true only if p can be any non-NULL value */ +){ + assert( p ); + assert( pNN ); + if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){ + return pNN->op!=TK_NULL; + } + switch( p->op ){ + case TK_IN: { + if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0; + assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) ); + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + case TK_BETWEEN: { + ExprList *pList; + assert( ExprUseXList(p) ); + pList = p->x.pList; + assert( pList!=0 ); + assert( pList->nExpr==2 ); + if( seenNot ) return 0; + if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1) + || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1) + ){ + return 1; + } + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_PLUS: + case TK_MINUS: + case TK_BITOR: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: + seenNot = 1; + /* no break */ deliberate_fall_through + case TK_STAR: + case TK_REM: + case TK_BITAND: + case TK_SLASH: { + if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1; + /* no break */ deliberate_fall_through + } + case TK_SPAN: + case TK_COLLATE: + case TK_UPLUS: + case TK_UMINUS: { + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + } + case TK_TRUTH: { + if( seenNot ) return 0; + if( p->op2!=TK_IS ) return 0; + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + case TK_BITNOT: + case TK_NOT: { + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + } + return 0; +} + +/* +** Return true if we can prove the pE2 will always be true if pE1 is +** true. Return false if we cannot complete the proof or if pE2 might +** be false. Examples: +** +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** +** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has +** Expr.iTable<0 then assume a table number given by iTab. +** +** If pParse is not NULL, then the values of bound variables in pE1 are +** compared against literal values in pE2 and pParse->pVdbe->expmask is +** modified to record which bound variables are referenced. If pParse +** is NULL, then false will be returned if pE1 contains any bound variables. +** +** When in doubt, return false. Returning true might give a performance +** improvement. Returning false might cause a performance reduction, but +** it will always give the correct answer and is hence always safe. +*/ +SQLITE_PRIVATE int sqlite3ExprImpliesExpr( + const Parse *pParse, + const Expr *pE1, + const Expr *pE2, + int iTab +){ + if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){ + return 1; + } + if( pE2->op==TK_OR + && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab) + || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) ) + ){ + return 1; + } + if( pE2->op==TK_NOTNULL + && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0) + ){ + return 1; + } + return 0; +} + +/* This is a helper function to impliesNotNullRow(). In this routine, +** set pWalker->eCode to one only if *both* of the input expressions +** separately have the implies-not-null-row property. +*/ +static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){ + if( pWalker->eCode==0 ){ + sqlite3WalkExpr(pWalker, pE1); + if( pWalker->eCode ){ + pWalker->eCode = 0; + sqlite3WalkExpr(pWalker, pE2); + } + } +} + +/* +** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). +** If the expression node requires that the table at pWalker->iCur +** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. +** +** pWalker->mWFlags is non-zero if this inquiry is being undertaking on +** behalf of a RIGHT JOIN (or FULL JOIN). That makes a difference when +** evaluating terms in the ON clause of an inner join. +** +** This routine controls an optimization. False positives (setting +** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives +** (never setting pWalker->eCode) is a harmless missed optimization. +*/ +static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; + if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){ + /* If iCur is used in an inner-join ON clause to the left of a + ** RIGHT JOIN, that does *not* mean that the table must be non-null. + ** But it is difficult to check for that condition precisely. + ** To keep things simple, any use of iCur from any inner-join is + ** ignored while attempting to simplify a RIGHT JOIN. */ + return WRC_Prune; + } + switch( pExpr->op ){ + case TK_ISNOT: + case TK_ISNULL: + case TK_NOTNULL: + case TK_IS: + case TK_VECTOR: + case TK_FUNCTION: + case TK_TRUTH: + case TK_CASE: + testcase( pExpr->op==TK_ISNOT ); + testcase( pExpr->op==TK_ISNULL ); + testcase( pExpr->op==TK_NOTNULL ); + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_VECTOR ); + testcase( pExpr->op==TK_FUNCTION ); + testcase( pExpr->op==TK_TRUTH ); + testcase( pExpr->op==TK_CASE ); + return WRC_Prune; + + case TK_COLUMN: + if( pWalker->u.iCur==pExpr->iTable ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Prune; + + case TK_OR: + case TK_AND: + /* Both sides of an AND or OR must separately imply non-null-row. + ** Consider these cases: + ** 1. NOT (x AND y) + ** 2. x OR y + ** If only one of x or y is non-null-row, then the overall expression + ** can be true if the other arm is false (case 1) or true (case 2). + */ + testcase( pExpr->op==TK_OR ); + testcase( pExpr->op==TK_AND ); + bothImplyNotNullRow(pWalker, pExpr->pLeft, pExpr->pRight); + return WRC_Prune; + + case TK_IN: + /* Beware of "x NOT IN ()" and "x NOT IN (SELECT 1 WHERE false)", + ** both of which can be true. But apart from these cases, if + ** the left-hand side of the IN is NULL then the IN itself will be + ** NULL. */ + if( ExprUseXList(pExpr) && ALWAYS(pExpr->x.pList->nExpr>0) ){ + sqlite3WalkExpr(pWalker, pExpr->pLeft); + } + return WRC_Prune; + + case TK_BETWEEN: + /* In "x NOT BETWEEN y AND z" either x must be non-null-row or else + ** both y and z must be non-null row */ + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr==2 ); + sqlite3WalkExpr(pWalker, pExpr->pLeft); + bothImplyNotNullRow(pWalker, pExpr->x.pList->a[0].pExpr, + pExpr->x.pList->a[1].pExpr); + return WRC_Prune; + + /* Virtual tables are allowed to use constraints like x=NULL. So + ** a term of the form x=y does not prove that y is not null if x + ** is the column of a virtual table */ + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: { + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); + /* The y.pTab=0 assignment in wherecode.c always happens after the + ** impliesNotNullRow() test */ + assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); + assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); + if( (pLeft->op==TK_COLUMN + && ALWAYS(pLeft->y.pTab!=0) + && IsVirtual(pLeft->y.pTab)) + || (pRight->op==TK_COLUMN + && ALWAYS(pRight->y.pTab!=0) + && IsVirtual(pRight->y.pTab)) + ){ + return WRC_Prune; + } + /* no break */ deliberate_fall_through + } + default: + return WRC_Continue; + } +} + +/* +** Return true (non-zero) if expression p can only be true if at least +** one column of table iTab is non-null. In other words, return true +** if expression p will always be NULL or false if every column of iTab +** is NULL. +** +** False negatives are acceptable. In other words, it is ok to return +** zero even if expression p will never be true of every column of iTab +** is NULL. A false negative is merely a missed optimization opportunity. +** +** False positives are not allowed, however. A false positive may result +** in an incorrect answer. +** +** Terms of p that are marked with EP_OuterON (and hence that come from +** the ON or USING clauses of OUTER JOINS) are excluded from the analysis. +** +** This routine is used to check if a LEFT JOIN can be converted into +** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE +** clause requires that some column of the right table of the LEFT JOIN +** be non-NULL, then the LEFT JOIN can be safely converted into an +** ordinary join. +*/ +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ + Walker w; + p = sqlite3ExprSkipCollateAndLikely(p); + if( p==0 ) return 0; + if( p->op==TK_NOTNULL ){ + p = p->pLeft; + }else{ + while( p->op==TK_AND ){ + if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1; + p = p->pRight; + } + } + w.xExprCallback = impliesNotNullRow; + w.xSelectCallback = 0; + w.xSelectCallback2 = 0; + w.eCode = 0; + w.mWFlags = isRJ!=0; + w.u.iCur = iTab; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** An instance of the following structure is used by the tree walker +** to determine if an expression can be evaluated by reference to the +** index only, without having to do a search for the corresponding +** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur +** is the cursor for the table. +*/ +struct IdxCover { + Index *pIdx; /* The index to be tested for coverage */ + int iCur; /* Cursor number for the table corresponding to the index */ +}; + +/* +** Check to see if there are references to columns in table +** pWalker->u.pIdxCover->iCur can be satisfied using the index +** pWalker->u.pIdxCover->pIdx. +*/ +static int exprIdxCover(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pWalker->u.pIdxCover->iCur + && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 + ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Continue; +} + +/* +** Determine if an index pIdx on table with cursor iCur contains will +** the expression pExpr. Return true if the index does cover the +** expression and false if the pExpr expression references table columns +** that are not found in the index pIdx. +** +** An index covering an expression means that the expression can be +** evaluated using only the index and without having to lookup the +** corresponding table entry. +*/ +SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( + Expr *pExpr, /* The index to be tested */ + int iCur, /* The cursor number for the corresponding table */ + Index *pIdx /* The index that might be used for coverage */ +){ + Walker w; + struct IdxCover xcov; + memset(&w, 0, sizeof(w)); + xcov.iCur = iCur; + xcov.pIdx = pIdx; + w.xExprCallback = exprIdxCover; + w.u.pIdxCover = &xcov; + sqlite3WalkExpr(&w, pExpr); + return !w.eCode; +} + + +/* Structure used to pass information throughout the Walker in order to +** implement sqlite3ReferencesSrcList(). +*/ +struct RefSrcList { + sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */ + SrcList *pRef; /* Looking for references to these tables */ + i64 nExclude; /* Number of tables to exclude from the search */ + int *aiExclude; /* Cursor IDs for tables to exclude from the search */ +}; + +/* +** Walker SELECT callbacks for sqlite3ReferencesSrcList(). +** +** When entering a new subquery on the pExpr argument, add all FROM clause +** entries for that subquery to the exclude list. +** +** When leaving the subquery, remove those entries from the exclude list. +*/ +static int selectRefEnter(Walker *pWalker, Select *pSelect){ + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = pSelect->pSrc; + i64 i, j; + int *piNew; + if( pSrc->nSrc==0 ) return WRC_Continue; + j = p->nExclude; + p->nExclude += pSrc->nSrc; + piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int)); + if( piNew==0 ){ + p->nExclude = 0; + return WRC_Abort; + }else{ + p->aiExclude = piNew; + } + for(i=0; inSrc; i++, j++){ + p->aiExclude[j] = pSrc->a[i].iCursor; + } + return WRC_Continue; +} +static void selectRefLeave(Walker *pWalker, Select *pSelect){ + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = pSelect->pSrc; + if( p->nExclude ){ + assert( p->nExclude>=pSrc->nSrc ); + p->nExclude -= pSrc->nSrc; + } +} + +/* This is the Walker EXPR callback for sqlite3ReferencesSrcList(). +** +** Set the 0x01 bit of pWalker->eCode if there is a reference to any +** of the tables shown in RefSrcList.pRef. +** +** Set the 0x02 bit of pWalker->eCode if there is a reference to a +** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude. +*/ +static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + || pExpr->op==TK_AGG_COLUMN + ){ + int i; + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = p->pRef; + int nSrc = pSrc ? pSrc->nSrc : 0; + for(i=0; iiTable==pSrc->a[i].iCursor ){ + pWalker->eCode |= 1; + return WRC_Continue; + } + } + for(i=0; inExclude && p->aiExclude[i]!=pExpr->iTable; i++){} + if( i>=p->nExclude ){ + pWalker->eCode |= 2; + } + } + return WRC_Continue; +} + +/* +** Check to see if pExpr references any tables in pSrcList. +** Possible return values: +** +** 1 pExpr does references a table in pSrcList. +** +** 0 pExpr references some table that is not defined in either +** pSrcList or in subqueries of pExpr itself. +** +** -1 pExpr only references no tables at all, or it only +** references tables defined in subqueries of pExpr itself. +** +** As currently used, pExpr is always an aggregate function call. That +** fact is exploited for efficiency. +*/ +SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ + Walker w; + struct RefSrcList x; + assert( pParse->db!=0 ); + memset(&w, 0, sizeof(w)); + memset(&x, 0, sizeof(x)); + w.xExprCallback = exprRefToSrcList; + w.xSelectCallback = selectRefEnter; + w.xSelectCallback2 = selectRefLeave; + w.u.pRefSrcList = &x; + x.db = pParse->db; + x.pRef = pSrcList; + assert( pExpr->op==TK_AGG_FUNCTION ); + assert( ExprUseXList(pExpr) ); + sqlite3WalkExprList(&w, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + assert( pExpr->pLeft->x.pList!=0 ); + sqlite3WalkExprList(&w, pExpr->pLeft->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); + } +#endif + if( x.aiExclude ) sqlite3DbNNFreeNN(pParse->db, x.aiExclude); + if( w.eCode & 0x01 ){ + return 1; + }else if( w.eCode ){ + return 0; + }else{ + return -1; + } +} + +/* +** This is a Walker expression node callback. +** +** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo +** object that is referenced does not refer directly to the Expr. If +** it does, make a copy. This is done because the pExpr argument is +** subject to change. +** +** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete() +** which builds on the sqlite3ParserAddCleanup() mechanism. +*/ +static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ + if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced)) + && pExpr->pAggInfo!=0 + ){ + AggInfo *pAggInfo = pExpr->pAggInfo; + int iAgg = pExpr->iAgg; + Parse *pParse = pWalker->pParse; + sqlite3 *db = pParse->db; + assert( iAgg>=0 ); + if( pExpr->op!=TK_AGG_FUNCTION ){ + if( iAggnColumn + && pAggInfo->aCol[iAgg].pCExpr==pExpr + ){ + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( pExpr ){ + pAggInfo->aCol[iAgg].pCExpr = pExpr; + sqlite3ExprDeferredDelete(pParse, pExpr); + } + } + }else{ + assert( pExpr->op==TK_AGG_FUNCTION ); + if( ALWAYS(iAggnFunc) + && pAggInfo->aFunc[iAgg].pFExpr==pExpr + ){ + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( pExpr ){ + pAggInfo->aFunc[iAgg].pFExpr = pExpr; + sqlite3ExprDeferredDelete(pParse, pExpr); + } + } + } + } + return WRC_Continue; +} + +/* +** Initialize a Walker object so that will persist AggInfo entries referenced +** by the tree that is walked. +*/ +SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker *pWalker, Parse *pParse){ + memset(pWalker, 0, sizeof(*pWalker)); + pWalker->pParse = pParse; + pWalker->xExprCallback = agginfoPersistExprCb; + pWalker->xSelectCallback = sqlite3SelectWalkNoop; +} + +/* +** Add a new element to the pAggInfo->aCol[] array. Return the index of +** the new element. Return a negative number if malloc fails. +*/ +static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aCol = sqlite3ArrayAllocate( + db, + pInfo->aCol, + sizeof(pInfo->aCol[0]), + &pInfo->nColumn, + &i + ); + return i; +} + +/* +** Add a new element to the pAggInfo->aFunc[] array. Return the index of +** the new element. Return a negative number if malloc fails. +*/ +static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aFunc = sqlite3ArrayAllocate( + db, + pInfo->aFunc, + sizeof(pInfo->aFunc[0]), + &pInfo->nFunc, + &i + ); + return i; +} + +/* +** Search the AggInfo object for an aCol[] entry that has iTable and iColumn. +** Return the index in aCol[] of the entry that describes that column. +** +** If no prior entry is found, create a new one and return -1. The +** new column will have an index of pAggInfo->nColumn-1. +*/ +static void findOrCreateAggInfoColumn( + Parse *pParse, /* Parsing context */ + AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */ + Expr *pExpr /* Expr describing the column to find or insert */ +){ + struct AggInfo_col *pCol; + int k; + + assert( pAggInfo->iFirstReg==0 ); + pCol = pAggInfo->aCol; + for(k=0; knColumn; k++, pCol++){ + if( pCol->pCExpr==pExpr ) return; + if( pCol->iTable==pExpr->iTable + && pCol->iColumn==pExpr->iColumn + && pExpr->op!=TK_IF_NULL_ROW + ){ + goto fix_up_expr; + } + } + k = addAggInfoColumn(pParse->db, pAggInfo); + if( k<0 ){ + /* OOM on resize */ + assert( pParse->db->mallocFailed ); + return; + } + pCol = &pAggInfo->aCol[k]; + assert( ExprUseYTab(pExpr) ); + pCol->pTab = pExpr->y.pTab; + pCol->iTable = pExpr->iTable; + pCol->iColumn = pExpr->iColumn; + pCol->iSorterColumn = -1; + pCol->pCExpr = pExpr; + if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){ + int j, n; + ExprList *pGB = pAggInfo->pGroupBy; + struct ExprList_item *pTerm = pGB->a; + n = pGB->nExpr; + for(j=0; jpExpr; + if( pE->op==TK_COLUMN + && pE->iTable==pExpr->iTable + && pE->iColumn==pExpr->iColumn + ){ + pCol->iSorterColumn = j; + break; + } + } + } + if( pCol->iSorterColumn<0 ){ + pCol->iSorterColumn = pAggInfo->nSortingColumn++; + } +fix_up_expr: + ExprSetVVAProperty(pExpr, EP_NoReduce); + assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo ); + pExpr->pAggInfo = pAggInfo; + if( pExpr->op==TK_COLUMN ){ + pExpr->op = TK_AGG_COLUMN; + } + pExpr->iAgg = (i16)k; +} + +/* +** This is the xExprCallback for a tree walker. It is used to +** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates +** for additional information. +*/ +static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + int i; + NameContext *pNC = pWalker->u.pNC; + Parse *pParse = pNC->pParse; + SrcList *pSrcList = pNC->pSrcList; + AggInfo *pAggInfo = pNC->uNC.pAggInfo; + + assert( pNC->ncFlags & NC_UAggInfo ); + assert( pAggInfo->iFirstReg==0 ); + switch( pExpr->op ){ + default: { + IndexedExpr *pIEpr; + Expr tmp; + assert( pParse->iSelfTab==0 ); + if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; + if( pParse->pIdxEpr==0 ) break; + for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ + int iDataCur = pIEpr->iDataCur; + if( iDataCur<0 ) continue; + if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; + } + if( pIEpr==0 ) break; + if( NEVER(!ExprUseYTab(pExpr)) ) break; + for(i=0; inSrc; i++){ + if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; + } + if( i>=pSrcList->nSrc ) break; + if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ + if( pParse->nErr ){ return WRC_Abort; } + + /* If we reach this point, it means that expression pExpr can be + ** translated into a reference to an index column as described by + ** pIEpr. + */ + memset(&tmp, 0, sizeof(tmp)); + tmp.op = TK_AGG_COLUMN; + tmp.iTable = pIEpr->iIdxCur; + tmp.iColumn = pIEpr->iIdxCol; + findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp); + if( pParse->nErr ){ return WRC_Abort; } + assert( pAggInfo->aCol!=0 ); + assert( tmp.iAggnColumn ); + pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr; + pExpr->pAggInfo = pAggInfo; + pExpr->iAgg = tmp.iAgg; + return WRC_Prune; + } + case TK_IF_NULL_ROW: + case TK_AGG_COLUMN: + case TK_COLUMN: { + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_IF_NULL_ROW ); + /* Check to see if the column is in one of the tables in the FROM + ** clause of the aggregate query */ + if( ALWAYS(pSrcList!=0) ){ + SrcItem *pItem = pSrcList->a; + for(i=0; inSrc; i++, pItem++){ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + if( pExpr->iTable==pItem->iCursor ){ + findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr); + break; + } /* endif pExpr->iTable==pItem->iCursor */ + } /* end loop over pSrcList */ + } + return WRC_Continue; + } + case TK_AGG_FUNCTION: { + if( (pNC->ncFlags & NC_InAggFunc)==0 + && pWalker->walkerDepth==pExpr->op2 + && pExpr->pAggInfo==0 + ){ + /* Check to see if pExpr is a duplicate of another aggregate + ** function that is already in the pAggInfo structure + */ + struct AggInfo_func *pItem = pAggInfo->aFunc; + for(i=0; inFunc; i++, pItem++){ + if( NEVER(pItem->pFExpr==pExpr) ) break; + if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ + break; + } + } + if( i>=pAggInfo->nFunc ){ + /* pExpr is original. Make a new entry in pAggInfo->aFunc[] + */ + u8 enc = ENC(pParse->db); + i = addAggInfoFunc(pParse->db, pAggInfo); + if( i>=0 ){ + int nArg; + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + pItem = &pAggInfo->aFunc[i]; + pItem->pFExpr = pExpr; + assert( ExprUseUToken(pExpr) ); + nArg = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; + pItem->pFunc = sqlite3FindFunction(pParse->db, + pExpr->u.zToken, nArg, enc, 0); + assert( pItem->bOBUnique==0 ); + if( pExpr->pLeft + && (pItem->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)==0 + ){ + /* The NEEDCOLL test above causes any ORDER BY clause on + ** aggregate min() or max() to be ignored. */ + ExprList *pOBList; + assert( nArg>0 ); + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + pItem->iOBTab = pParse->nTab++; + pOBList = pExpr->pLeft->x.pList; + assert( pOBList->nExpr>0 ); + assert( pItem->bOBUnique==0 ); + if( pOBList->nExpr==1 + && nArg==1 + && sqlite3ExprCompare(0,pOBList->a[0].pExpr, + pExpr->x.pList->a[0].pExpr,0)==0 + ){ + pItem->bOBPayload = 0; + pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); + }else{ + pItem->bOBPayload = 1; + } + pItem->bUseSubtype = + (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0; + }else{ + pItem->iOBTab = -1; + } + if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){ + pItem->iDistinct = pParse->nTab++; + }else{ + pItem->iDistinct = -1; + } + } + } + /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry + */ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pExpr, EP_NoReduce); + pExpr->iAgg = (i16)i; + pExpr->pAggInfo = pAggInfo; + return WRC_Prune; + }else{ + return WRC_Continue; + } + } + } + return WRC_Continue; +} + +/* +** Analyze the pExpr expression looking for aggregate functions and +** for variables that need to be added to AggInfo object that pNC->pAggInfo +** points to. Additional entries are made on the AggInfo object as +** necessary. +** +** This routine should only be called after the expression has been +** analyzed by sqlite3ResolveExprNames(). +*/ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ + Walker w; + w.xExprCallback = analyzeAggregate; + w.xSelectCallback = sqlite3WalkerDepthIncrease; + w.xSelectCallback2 = sqlite3WalkerDepthDecrease; + w.walkerDepth = 0; + w.u.pNC = pNC; + w.pParse = 0; + assert( pNC->pSrcList!=0 ); + sqlite3WalkExpr(&w, pExpr); +} + +/* +** Call sqlite3ExprAnalyzeAggregates() for every expression in an +** expression list. Return the number of errors. +** +** If an error is found, the analysis is cut short. +*/ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ + struct ExprList_item *pItem; + int i; + if( pList ){ + for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); + } + } +} + +/* +** Allocate a single new register for use to hold some intermediate result. +*/ +SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ + if( pParse->nTempReg==0 ){ + return ++pParse->nMem; + } + return pParse->aTempReg[--pParse->nTempReg]; +} + +/* +** Deallocate a register, making available for reuse for some other +** purpose. +*/ +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ + if( iReg ){ + sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0); + if( pParse->nTempRegaTempReg) ){ + pParse->aTempReg[pParse->nTempReg++] = iReg; + } + } +} + +/* +** Allocate or deallocate a block of nReg consecutive registers. +*/ +SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ + int i, n; + if( nReg==1 ) return sqlite3GetTempReg(pParse); + i = pParse->iRangeReg; + n = pParse->nRangeReg; + if( nReg<=n ){ + pParse->iRangeReg += nReg; + pParse->nRangeReg -= nReg; + }else{ + i = pParse->nMem+1; + pParse->nMem += nReg; + } + return i; +} +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ + if( nReg==1 ){ + sqlite3ReleaseTempReg(pParse, iReg); + return; + } + sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0); + if( nReg>pParse->nRangeReg ){ + pParse->nRangeReg = nReg; + pParse->iRangeReg = iReg; + } +} + +/* +** Mark all temporary registers as being unavailable for reuse. +** +** Always invoke this procedure after coding a subroutine or co-routine +** that might be invoked from other parts of the code, to ensure that +** the sub/co-routine does not use registers in common with the code that +** invokes the sub/co-routine. +*/ +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ + pParse->nTempReg = 0; + pParse->nRangeReg = 0; +} + +/* +** Make sure sufficient registers have been allocated so that +** iReg is a valid register number. +*/ +SQLITE_PRIVATE void sqlite3TouchRegister(Parse *pParse, int iReg){ + if( pParse->nMemnMem = iReg; +} + +#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) +/* +** Return the latest reusable register in the set of all registers. +** The value returned is no less than iMin. If any register iMin or +** greater is in permanent use, then return one more than that last +** permanent register. +*/ +SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){ + const ExprList *pList = pParse->pConstExpr; + if( pList ){ + int i; + for(i=0; inExpr; i++){ + if( pList->a[i].u.iConstExprReg>=iMin ){ + iMin = pList->a[i].u.iConstExprReg + 1; + } + } + } + pParse->nTempReg = 0; + pParse->nRangeReg = 0; + return iMin; +} +#endif /* SQLITE_ENABLE_STAT4 || SQLITE_DEBUG */ + +/* +** Validate that no temporary register falls within the range of +** iFirst..iLast, inclusive. This routine is only call from within assert() +** statements. +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ + int i; + if( pParse->nRangeReg>0 + && pParse->iRangeReg+pParse->nRangeReg > iFirst + && pParse->iRangeReg <= iLast + ){ + return 0; + } + for(i=0; inTempReg; i++){ + if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){ + return 0; + } + } + if( pParse->pConstExpr ){ + ExprList *pList = pParse->pConstExpr; + for(i=0; inExpr; i++){ + int iReg = pList->a[i].u.iConstExprReg; + if( iReg==0 ) continue; + if( iReg>=iFirst && iReg<=iLast ) return 0; + } + } + return 1; +} +#endif /* SQLITE_DEBUG */ + +/************** End of expr.c ************************************************/ +/************** Begin file alter.c *******************************************/ +/* +** 2005 February 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that used to generate VDBE code +** that implements the ALTER TABLE command. +*/ +/* #include "sqliteInt.h" */ + +/* +** The code in this file only exists if we are not omitting the +** ALTER TABLE logic from the build. +*/ +#ifndef SQLITE_OMIT_ALTERTABLE + +/* +** Parameter zName is the name of a table that is about to be altered +** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). +** If the table is a system table, this function leaves an error message +** in pParse->zErr (system tables may not be altered) and returns non-zero. +** +** Or, if zName is not a system table, zero is returned. +*/ +static int isAlterableTable(Parse *pParse, Table *pTab){ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) +#ifndef SQLITE_OMIT_VIRTUALTABLE + || (pTab->tabFlags & TF_Eponymous)!=0 + || ( (pTab->tabFlags & TF_Shadow)!=0 + && sqlite3ReadOnlyShadowTables(pParse->db) + ) +#endif + ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); + return 1; + } + return 0; +} + +/* +** Generate code to verify that the schemas of database zDb and, if +** bTemp is not true, database "temp", can still be parsed. This is +** called at the end of the generation of an ALTER TABLE ... RENAME ... +** statement to ensure that the operation has not rendered any schema +** objects unusable. +*/ +static void renameTestSchema( + Parse *pParse, /* Parse context */ + const char *zDb, /* Name of db to verify schema of */ + int bTemp, /* True if this is the temp db */ + const char *zWhen, /* "when" part of error message */ + int bNoDQS /* Do not allow DQS in the schema */ +){ + pParse->colNamesSet = 1; + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ", + zDb, + zDb, bTemp, zWhen, bNoDQS + ); + + if( bTemp==0 ){ + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM temp." LEGACY_SCHEMA_TABLE " " + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ", + zDb, zWhen, bNoDQS + ); + } +} + +/* +** Generate VM code to replace any double-quoted strings (but not double-quoted +** identifiers) within the "sql" column of the sqlite_schema table in +** database zDb with their single-quoted equivalents. If argument bTemp is +** not true, similarly update all SQL statements in the sqlite_schema table +** of the temp db. +*/ +static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE + " SET sql = sqlite_rename_quotefix(%Q, sql)" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb + ); + if( bTemp==0 ){ + sqlite3NestedParse(pParse, + "UPDATE temp." LEGACY_SCHEMA_TABLE + " SET sql = sqlite_rename_quotefix('temp', sql)" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" + ); + } +} + +/* +** Generate code to reload the schema for database iDb. And, if iDb!=1, for +** the temp database as well. +*/ +static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){ + Vdbe *v = pParse->pVdbe; + if( v ){ + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5); + } +} + +/* +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. +*/ +SQLITE_PRIVATE void sqlite3AlterRenameTable( + Parse *pParse, /* Parser context. */ + SrcList *pSrc, /* The table to rename. */ + Token *pName /* The new table name. */ +){ + int iDb; /* Database that contains the table */ + char *zDb; /* Name of database iDb */ + Table *pTab; /* Table being renamed */ + char *zName = 0; /* NULL-terminated version of pName */ + sqlite3 *db = pParse->db; /* Database connection */ + int nTabName; /* Number of UTF-8 characters in zTabName */ + const char *zTabName; /* Original name of the table */ + Vdbe *v; + VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ + + if( NEVER(db->mallocFailed) ) goto exit_rename_table; + assert( pSrc->nSrc==1 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_table; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + zDb = db->aDb[iDb].zDbSName; + + /* Get a NULL terminated version of the new table name. */ + zName = sqlite3NameFromToken(db, pName); + if( !zName ) goto exit_rename_table; + + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ + if( sqlite3FindTable(db, zName, zDb) + || sqlite3FindIndex(db, zName, zDb) + || sqlite3IsShadowTableOf(db, pTab, zName) + ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; + } + + /* Make sure it is not a system table being altered, or a reserved name + ** that the table is being renamed to. + */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ + goto exit_rename_table; + } + if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){ + goto exit_rename_table; + } + +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_rename_table; + } + if( IsVirtual(pTab) ){ + pVTab = sqlite3GetVTable(db, pTab); + if( pVTab->pVtab->pModule->xRename==0 ){ + pVTab = 0; + } + } +#endif + + /* Begin a transaction for database iDb. Then modify the schema cookie + ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(), + ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the + ** nested SQL may raise an exception. */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto exit_rename_table; + } + sqlite3MayAbort(pParse); + + /* figure out how many UTF-8 characters are in zName */ + zTabName = pTab->zName; + nTabName = sqlite3Utf8CharLen(zTabName, -1); + + /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in + ** the schema to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " + "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" + "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + , zDb, zDb, zTabName, zName, (iDb==1), zTabName + ); + + /* Update the tbl_name and name columns of the sqlite_schema table + ** as required. */ + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET " + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' " + " AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q COLLATE nocase AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, + zName, zName, zName, + nTabName, zTabName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + + /* If the table being renamed is not itself part of the temp database, + ** edit view and trigger definitions within the temp database + ** as required. */ + if( iDb!=1 ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_schema SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " + "tbl_name = " + "CASE WHEN tbl_name=%Q COLLATE nocase AND " + " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename', 0) " + "THEN %Q ELSE tbl_name END " + "WHERE type IN ('view', 'trigger')" + , zDb, zTabName, zName, zTabName, zDb, zName); + } + + /* If this is a virtual table, invoke the xRename() function if + ** one is defined. The xRename() callback will modify the names + ** of any resources used by the v-table implementation (including other + ** SQLite tables) that are identified by the name of the virtual table. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pVTab ){ + int i = ++pParse->nMem; + sqlite3VdbeLoadString(v, i, zName); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); + } +#endif + + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iDb==1, "after rename", 0); + +exit_rename_table: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zName); +} + +/* +** Write code that will raise an error if the table described by +** zDb and zTab is not empty. +*/ +static void sqlite3ErrorIfNotEmpty( + Parse *pParse, /* Parsing context */ + const char *zDb, /* Schema holding the table */ + const char *zTab, /* Table to check for empty */ + const char *zErr /* Error message text */ +){ + sqlite3NestedParse(pParse, + "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"", + zErr, zDb, zTab + ); +} + +/* +** This function is called after an "ALTER TABLE ... ADD" statement +** has been parsed. Argument pColDef contains the text of the new +** column definition. +** +** The Table structure pParse->pNewTable was extended to include +** the new column during parsing. +*/ +SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ + Table *pNew; /* Copy of pParse->pNewTable */ + Table *pTab; /* Table being altered */ + int iDb; /* Database number */ + const char *zDb; /* Database name */ + const char *zTab; /* Table name */ + char *zCol; /* Null-terminated column definition */ + Column *pCol; /* The new column */ + Expr *pDflt; /* Default value for the new column */ + sqlite3 *db; /* The database connection; */ + Vdbe *v; /* The prepared statement under construction */ + int r1; /* Temporary registers */ + + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ) return; + assert( db->mallocFailed==0 ); + pNew = pParse->pNewTable; + assert( pNew ); + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pNew->pSchema); + zDb = db->aDb[iDb].zDbSName; + zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ + pCol = &pNew->aCol[pNew->nCol-1]; + pDflt = sqlite3ColumnExpr(pNew, pCol); + pTab = sqlite3FindTable(db, zTab, zDb); + assert( pTab ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + return; + } +#endif + + + /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. + ** If there is a NOT NULL constraint, then the default value for the + ** column must not be NULL. + */ + if( pCol->colFlags & COLFLAG_PRIMKEY ){ + sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); + return; + } + if( pNew->pIndex ){ + sqlite3ErrorMsg(pParse, + "Cannot add a UNIQUE column"); + return; + } + if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){ + /* If the default value for the new column was specified with a + ** literal NULL, then set pDflt to 0. This simplifies checking + ** for an SQL NULL default below. + */ + assert( pDflt==0 || pDflt->op==TK_SPAN ); + if( pDflt && pDflt->pLeft->op==TK_NULL ){ + pDflt = 0; + } + assert( IsOrdinaryTable(pNew) ); + if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, + "Cannot add a REFERENCES column with non-NULL default value"); + } + if( pCol->notNull && !pDflt ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, + "Cannot add a NOT NULL column with default value NULL"); + } + + + /* Ensure the default expression is something that sqlite3ValueFromExpr() + ** can handle (i.e. not CURRENT_TIME etc.) + */ + if( pDflt ){ + sqlite3_value *pVal = 0; + int rc; + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc!=SQLITE_OK ){ + assert( db->mallocFailed == 1 ); + return; + } + if( !pVal ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, + "Cannot add a column with non-constant default"); + } + sqlite3ValueFree(pVal); + } + }else if( pCol->colFlags & COLFLAG_STORED ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column"); + } + + + /* Modify the CREATE TABLE statement. */ + zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); + if( zCol ){ + char *zEnd = &zCol[pColDef->n-1]; + while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ + *zEnd-- = '\0'; + } + /* substr() operations on characters, but addColOffset is in bytes. So we + ** have to use printf() to translate between these units: */ + assert( IsOrdinaryTable(pTab) ); + assert( IsOrdinaryTable(pNew) ); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = printf('%%.%ds, ',sql) || %Q" + " || substr(sql,1+length(printf('%%.%ds',sql))) " + "WHERE type = 'table' AND name = %Q", + zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset, + zTab + ); + sqlite3DbFree(db, zCol); + } + + v = sqlite3GetVdbe(pParse); + if( v ){ + /* Make sure the schema version is at least 3. But do not upgrade + ** from less than 3 to 4, as that will corrupt any preexisting DESC + ** index. + */ + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); + sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); + sqlite3ReleaseTempReg(pParse, r1); + + /* Reload the table definition */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd); + + /* Verify that constraints are still satisfied */ + if( pNew->pCheck!=0 + || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + || (pTab->tabFlags & TF_Strict)!=0 + ){ + sqlite3NestedParse(pParse, + "SELECT CASE WHEN quick_check GLOB 'CHECK*'" + " THEN raise(ABORT,'CHECK constraint failed')" + " WHEN quick_check GLOB 'non-* value in*'" + " THEN raise(ABORT,'type mismatch on DEFAULT')" + " ELSE raise(ABORT,'NOT NULL constraint failed')" + " END" + " FROM pragma_quick_check(%Q,%Q)" + " WHERE quick_check GLOB 'CHECK*'" + " OR quick_check GLOB 'NULL*'" + " OR quick_check GLOB 'non-* value in*'", + zTab, zDb + ); + } + } +} + +/* +** This function is called by the parser after the table-name in +** an "ALTER TABLE ADD" statement is parsed. Argument +** pSrc is the full-name of the table being altered. +** +** This routine makes a (partial) copy of the Table structure +** for the table being altered and sets Parse.pNewTable to point +** to it. Routines called by the parser as the column definition +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to +** the copy. The copy of the Table structure is deleted by tokenize.c +** after parsing is finished. +** +** Routine sqlite3AlterFinishAddColumn() will be called to complete +** coding the "ALTER TABLE ... ADD" statement. +*/ +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ + Table *pNew; + Table *pTab; + int iDb; + int i; + int nAlloc; + sqlite3 *db = pParse->db; + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( db->mallocFailed ) goto exit_begin_add_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_begin_add_column; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_begin_add_column; + } +#endif + + /* Make sure this is not an attempt to ALTER a view. */ + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); + goto exit_begin_add_column; + } + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ + goto exit_begin_add_column; + } + + sqlite3MayAbort(pParse); + assert( IsOrdinaryTable(pTab) ); + assert( pTab->u.tab.addColOffset>0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + /* Put a copy of the Table struct in Parse.pNewTable for the + ** sqlite3AddColumn() function and friends to modify. But modify + ** the name by adding an "sqlite_altertab_" prefix. By adding this + ** prefix, we insure that the name will not collide with an existing + ** table because user table are not allowed to have the "sqlite_" + ** prefix on their name. + */ + pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); + if( !pNew ) goto exit_begin_add_column; + pParse->pNewTable = pNew; + pNew->nTabRef = 1; + pNew->nCol = pTab->nCol; + assert( pNew->nCol>0 ); + nAlloc = (((pNew->nCol-1)/8)*8)+8; + assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); + pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); + pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); + if( !pNew->aCol || !pNew->zName ){ + assert( db->mallocFailed ); + goto exit_begin_add_column; + } + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); + for(i=0; inCol; i++){ + Column *pCol = &pNew->aCol[i]; + pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); + pCol->hName = sqlite3StrIHash(pCol->zCnName); + } + assert( IsOrdinaryTable(pNew) ); + pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); + pNew->pSchema = db->aDb[iDb].pSchema; + pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; + assert( pNew->nTabRef==1 ); + +exit_begin_add_column: + sqlite3SrcListDelete(db, pSrc); + return; +} + +/* +** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN +** command. This function checks if the table is a view or virtual +** table (columns of views or virtual tables may not be renamed). If so, +** it loads an error message into pParse and returns non-zero. +** +** Or, if pTab is not a view or virtual table, zero is returned. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ + const char *zType = 0; +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ + zType = "view"; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + zType = "virtual table"; + } +#endif + if( zType ){ + sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", + (bDrop ? "drop column from" : "rename columns of"), + zType, pTab->zName + ); + return 1; + } + return 0; +} +#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ +# define isRealTable(x,y,z) (0) +#endif + +/* +** Handles the following parser reduction: +** +** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew +*/ +SQLITE_PRIVATE void sqlite3AlterRenameColumn( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ + Token *pOld, /* Name of column being changed */ + Token *pNew /* New column name */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table being updated */ + int iCol; /* Index of column being renamed */ + char *zOld = 0; /* Old column name */ + char *zNew = 0; /* New column name */ + const char *zDb; /* Name of schema containing the table */ + int iSchema; /* Index of the schema */ + int bQuote; /* True to quote the new name */ + + /* Locate the table to be altered */ + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_column; + + /* Cannot alter a system table */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column; + + /* Which schema holds the table to be altered */ + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iSchema>=0 ); + zDb = db->aDb[iSchema].zDbSName; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_column; + } +#endif + + /* Make sure the old name really is a column name in the table to be + ** altered. Set iCol to be the index of the column being renamed */ + zOld = sqlite3NameFromToken(db, pOld); + if( !zOld ) goto exit_rename_column; + for(iCol=0; iColnCol; iCol++){ + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; + } + if( iCol==pTab->nCol ){ + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); + goto exit_rename_column; + } + + /* Ensure the schema contains no double-quoted strings */ + renameTestSchema(pParse, zDb, iSchema==1, "", 0); + renameFixQuotes(pParse, zDb, iSchema==1); + + /* Do the rename operation using a recursive UPDATE statement that + ** uses the sqlite_rename_column() SQL function to compute the new + ** CREATE statement text for the sqlite_schema table. + */ + sqlite3MayAbort(pParse); + zNew = sqlite3NameFromToken(db, pNew); + if( !zNew ) goto exit_rename_column; + assert( pNew->n>0 ); + bQuote = sqlite3Isquote(pNew->z[0]); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " + " AND (type != 'index' OR tbl_name = %Q)", + zDb, + zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, + pTab->zName + ); + + sqlite3NestedParse(pParse, + "UPDATE temp." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " + "WHERE type IN ('trigger', 'view')", + zDb, pTab->zName, iCol, zNew, bQuote + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iSchema==1, "after rename", 1); + + exit_rename_column: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zOld); + sqlite3DbFree(db, zNew); + return; +} + +/* +** Each RenameToken object maps an element of the parse tree into +** the token that generated that element. The parse tree element +** might be one of: +** +** * A pointer to an Expr that represents an ID +** * The name of a table column in Column.zName +** +** A list of RenameToken objects can be constructed during parsing. +** Each new object is created by sqlite3RenameTokenMap(). +** As the parse tree is transformed, the sqlite3RenameTokenRemap() +** routine is used to keep the mapping current. +** +** After the parse finishes, renameTokenFind() routine can be used +** to look up the actual token value that created some element in +** the parse tree. +*/ +struct RenameToken { + const void *p; /* Parse tree element created by token t */ + Token t; /* The token that created parse tree element p */ + RenameToken *pNext; /* Next is a list of all RenameToken objects */ +}; + +/* +** The context of an ALTER TABLE RENAME COLUMN operation that gets passed +** down into the Walker. +*/ +typedef struct RenameCtx RenameCtx; +struct RenameCtx { + RenameToken *pList; /* List of tokens to overwrite */ + int nList; /* Number of tokens in pList */ + int iCol; /* Index of column being renamed */ + Table *pTab; /* Table being ALTERed */ + const char *zOld; /* Old column name */ +}; + +#ifdef SQLITE_DEBUG +/* +** This function is only for debugging. It performs two tasks: +** +** 1. Checks that pointer pPtr does not already appear in the +** rename-token list. +** +** 2. Dereferences each pointer in the rename-token list. +** +** The second is most effective when debugging under valgrind or +** address-sanitizer or similar. If any of these pointers no longer +** point to valid objects, an exception is raised by the memory-checking +** tool. +** +** The point of this is to prevent comparisons of invalid pointer values. +** Even though this always seems to work, it is undefined according to the +** C standard. Example of undefined comparison: +** +** sqlite3_free(x); +** if( x==y ) ... +** +** Technically, as x no longer points into a valid object or to the byte +** following a valid object, it may not be used in comparison operations. +*/ +static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ + assert( pParse==pParse->db->pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr==0 ){ + const RenameToken *p; + u32 i = 1; + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p ){ + assert( p->p!=pPtr ); + i += *(u8*)(p->p) | 1; + } + } + assert( i>0 ); + } +} +#else +# define renameTokenCheckAll(x,y) +#endif + +/* +** Remember that the parser tree element pPtr was created using +** the token pToken. +** +** In other words, construct a new RenameToken object and add it +** to the list of RenameToken objects currently being built up +** in pParse->pRename. +** +** The pPtr argument is returned so that this routine can be used +** with tail recursion in tokenExpr() routine, for a small performance +** improvement. +*/ +SQLITE_PRIVATE const void *sqlite3RenameTokenMap( + Parse *pParse, + const void *pPtr, + const Token *pToken +){ + RenameToken *pNew; + assert( pPtr || pParse->db->mallocFailed ); + renameTokenCheckAll(pParse, pPtr); + if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){ + pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); + if( pNew ){ + pNew->p = pPtr; + pNew->t = *pToken; + pNew->pNext = pParse->pRename; + pParse->pRename = pNew; + } + } + + return pPtr; +} + +/* +** It is assumed that there is already a RenameToken object associated +** with parse tree element pFrom. This function remaps the associated token +** to parse tree element pTo. +*/ +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom){ + RenameToken *p; + renameTokenCheckAll(pParse, pTo); + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p==pFrom ){ + p->p = pTo; + break; + } + } +} + +/* +** Walker callback used by sqlite3RenameExprUnmap(). +*/ +static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ + Parse *pParse = pWalker->pParse; + sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr); + if( ExprUseYTab(pExpr) ){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab); + } + return WRC_Continue; +} + +/* +** Iterate through the Select objects that are part of WITH clauses attached +** to select statement pSelect. +*/ +static void renameWalkWith(Walker *pWalker, Select *pSelect){ + With *pWith = pSelect->pWith; + if( pWith ){ + Parse *pParse = pWalker->pParse; + int i; + With *pCopy = 0; + assert( pWith->nCte>0 ); + if( (pWith->a[0].pSelect->selFlags & SF_Expanded)==0 ){ + /* Push a copy of the With object onto the with-stack. We use a copy + ** here as the original will be expanded and resolved (flags SF_Expanded + ** and SF_Resolved) below. And the parser code that uses the with-stack + ** fails if the Select objects on it have already been expanded and + ** resolved. */ + pCopy = sqlite3WithDup(pParse->db, pWith); + pCopy = sqlite3WithPush(pParse, pCopy, 1); + } + for(i=0; inCte; i++){ + Select *p = pWith->a[i].pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC); + if( sNC.pParse->db->mallocFailed ) return; + sqlite3WalkSelect(pWalker, p); + sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols); + } + if( pCopy && pParse->pWith==pCopy ){ + pParse->pWith = pCopy->pOuter; + } + } +} + +/* +** Unmap all tokens in the IdList object passed as the second argument. +*/ +static void unmapColumnIdlistNames( + Parse *pParse, + const IdList *pIdList +){ + int ii; + assert( pIdList!=0 ); + for(ii=0; iinId; ii++){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); + } +} + +/* +** Walker callback used by sqlite3RenameExprUnmap(). +*/ +static int renameUnmapSelectCb(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i; + if( pParse->nErr ) return WRC_Abort; + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); + if( p->selFlags & (SF_View|SF_CopyCte) ){ + return WRC_Prune; + } + if( ALWAYS(p->pEList) ){ + ExprList *pList = p->pEList; + for(i=0; inExpr; i++){ + if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); + } + } + } + if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */ + SrcList *pSrc = p->pSrc; + for(i=0; inSrc; i++){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); + if( pSrc->a[i].fg.isUsing==0 ){ + sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn); + }else{ + unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing); + } + } + } + + renameWalkWith(pWalker, p); + return WRC_Continue; +} + +/* +** Remove all nodes that are part of expression pExpr from the rename list. +*/ +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ + u8 eMode = pParse->eParseMode; + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sWalker.xSelectCallback = renameUnmapSelectCb; + pParse->eParseMode = PARSE_MODE_UNMAP; + sqlite3WalkExpr(&sWalker, pExpr); + pParse->eParseMode = eMode; +} + +/* +** Remove all nodes that are part of expression-list pEList from the +** rename list. +*/ +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ + if( pEList ){ + int i; + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sqlite3WalkExprList(&sWalker, pEList); + for(i=0; inExpr; i++){ + if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); + } + } + } +} + +/* +** Free the list of RenameToken objects given in the second argument +*/ +static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ + RenameToken *pNext; + RenameToken *p; + for(p=pToken; p; p=pNext){ + pNext = p->pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Search the Parse object passed as the first argument for a RenameToken +** object associated with parse tree element pPtr. If found, return a pointer +** to it. Otherwise, return NULL. +** +** If the second argument passed to this function is not NULL and a matching +** RenameToken object is found, remove it from the Parse object and add it to +** the list maintained by the RenameCtx object. +*/ +static RenameToken *renameTokenFind( + Parse *pParse, + struct RenameCtx *pCtx, + const void *pPtr +){ + RenameToken **pp; + if( NEVER(pPtr==0) ){ + return 0; + } + for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ + if( (*pp)->p==pPtr ){ + RenameToken *pToken = *pp; + if( pCtx ){ + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + } + return pToken; + } + } + return 0; +} + +/* +** This is a Walker select callback. It does nothing. It is only required +** because without a dummy callback, sqlite3WalkExpr() and similar do not +** descend into sub-select statements. +*/ +static int renameColumnSelectCb(Walker *pWalker, Select *p){ + if( p->selFlags & (SF_View|SF_CopyCte) ){ + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); + return WRC_Prune; + } + renameWalkWith(pWalker, p); + return WRC_Continue; +} + +/* +** This is a Walker expression callback. +** +** For every TK_COLUMN node in the expression tree, search to see +** if the column being references is the column being renamed by an +** ALTER TABLE statement. If it is, then attach its associated +** RenameToken object to the list of RenameToken objects being +** constructed in RenameCtx object at pWalker->u.pRename. +*/ +static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_TRIGGER + && pExpr->iColumn==p->iCol + && pWalker->pParse->pTriggerTab==p->pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + }else if( pExpr->op==TK_COLUMN + && pExpr->iColumn==p->iCol + && ALWAYS(ExprUseYTab(pExpr)) + && p->pTab==pExpr->y.pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + } + return WRC_Continue; +} + +/* +** The RenameCtx contains a list of tokens that reference a column that +** is being renamed by an ALTER TABLE statement. Return the "last" +** RenameToken in the RenameCtx and remove that RenameToken from the +** RenameContext. "Last" means the last RenameToken encountered when +** the input SQL is parsed from left to right. Repeated calls to this routine +** return all column name tokens in the order that they are encountered +** in the SQL statement. +*/ +static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ + RenameToken *pBest = pCtx->pList; + RenameToken *pToken; + RenameToken **pp; + + for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){ + if( pToken->t.z>pBest->t.z ) pBest = pToken; + } + for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); + *pp = pBest->pNext; + + return pBest; +} + +/* +** An error occurred while parsing or otherwise processing a database +** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an +** ALTER TABLE RENAME COLUMN program. The error message emitted by the +** sub-routine is currently stored in pParse->zErrMsg. This function +** adds context to the error message and then stores it in pCtx. +*/ +static void renameColumnParseError( + sqlite3_context *pCtx, + const char *zWhen, + sqlite3_value *pType, + sqlite3_value *pObject, + Parse *pParse +){ + const char *zT = (const char*)sqlite3_value_text(pType); + const char *zN = (const char*)sqlite3_value_text(pObject); + char *zErr; + + zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, + pParse->zErrMsg + ); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3DbFree(pParse->db, zErr); +} + +/* +** For each name in the the expression-list pEList (i.e. each +** pEList->a[i].zName) that matches the string in zOld, extract the +** corresponding rename-token from Parse object pParse and add it +** to the RenameCtx pCtx. +*/ +static void renameColumnElistNames( + Parse *pParse, + RenameCtx *pCtx, + const ExprList *pEList, + const char *zOld +){ + if( pEList ){ + int i; + for(i=0; inExpr; i++){ + const char *zName = pEList->a[i].zEName; + if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) + && ALWAYS(zName!=0) + && 0==sqlite3_stricmp(zName, zOld) + ){ + renameTokenFind(pParse, pCtx, (const void*)zName); + } + } + } +} + +/* +** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) +** that matches the string in zOld, extract the corresponding rename-token +** from Parse object pParse and add it to the RenameCtx pCtx. +*/ +static void renameColumnIdlistNames( + Parse *pParse, + RenameCtx *pCtx, + const IdList *pIdList, + const char *zOld +){ + if( pIdList ){ + int i; + for(i=0; inId; i++){ + const char *zName = pIdList->a[i].zName; + if( 0==sqlite3_stricmp(zName, zOld) ){ + renameTokenFind(pParse, pCtx, (const void*)zName); + } + } + } +} + + +/* +** Parse the SQL statement zSql using Parse object (*p). The Parse object +** is initialized by this function before it is used. +*/ +static int renameParseSql( + Parse *p, /* Memory to use for Parse object */ + const char *zDb, /* Name of schema SQL belongs to */ + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL to parse */ + int bTemp /* True if SQL is from temp schema */ +){ + int rc; + + sqlite3ParseObjectInit(p, db); + if( zSql==0 ){ + return SQLITE_NOMEM; + } + if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ + return SQLITE_CORRUPT_BKPT; + } + db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + p->eParseMode = PARSE_MODE_RENAME; + p->db = db; + p->nQueryLoop = 1; + rc = sqlite3RunParser(p, zSql); + if( db->mallocFailed ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK + && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) + ){ + rc = SQLITE_CORRUPT_BKPT; + } + +#ifdef SQLITE_DEBUG + /* Ensure that all mappings in the Parse.pRename list really do map to + ** a part of the input string. */ + if( rc==SQLITE_OK ){ + int nSql = sqlite3Strlen30(zSql); + RenameToken *pToken; + for(pToken=p->pRename; pToken; pToken=pToken->pNext){ + assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] ); + } + } +#endif + + db->init.iDb = 0; + return rc; +} + +/* +** This function edits SQL statement zSql, replacing each token identified +** by the linked list pRename with the text of zNew. If argument bQuote is +** true, then zNew is always quoted first. If no error occurs, the result +** is loaded into context object pCtx as the result. +** +** Or, if an error occurs (i.e. an OOM condition), an error is left in +** pCtx and an SQLite error code returned. +*/ +static int renameEditSql( + sqlite3_context *pCtx, /* Return result here */ + RenameCtx *pRename, /* Rename context */ + const char *zSql, /* SQL statement to edit */ + const char *zNew, /* New token text */ + int bQuote /* True to always quote token */ +){ + i64 nNew = sqlite3Strlen30(zNew); + i64 nSql = sqlite3Strlen30(zSql); + sqlite3 *db = sqlite3_context_db_handle(pCtx); + int rc = SQLITE_OK; + char *zQuot = 0; + char *zOut; + i64 nQuot = 0; + char *zBuf1 = 0; + char *zBuf2 = 0; + + if( zNew ){ + /* Set zQuot to point to a buffer containing a quoted copy of the + ** identifier zNew. If the corresponding identifier in the original + ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to + ** point to zQuot so that all substitutions are made using the + ** quoted version of the new column name. */ + zQuot = sqlite3MPrintf(db, "\"%w\" ", zNew); + if( zQuot==0 ){ + return SQLITE_NOMEM; + }else{ + nQuot = sqlite3Strlen30(zQuot)-1; + } + + assert( nQuot>=nNew ); + zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); + }else{ + zOut = (char*)sqlite3DbMallocZero(db, (nSql*2+1) * 3); + if( zOut ){ + zBuf1 = &zOut[nSql*2+1]; + zBuf2 = &zOut[nSql*4+2]; + } + } + + /* At this point pRename->pList contains a list of RenameToken objects + ** corresponding to all tokens in the input SQL that must be replaced + ** with the new column name, or with single-quoted versions of themselves. + ** All that remains is to construct and return the edited SQL string. */ + if( zOut ){ + int nOut = nSql; + memcpy(zOut, zSql, nSql); + while( pRename->pList ){ + int iOff; /* Offset of token to replace in zOut */ + u32 nReplace; + const char *zReplace; + RenameToken *pBest = renameColumnTokenNext(pRename); + + if( zNew ){ + if( bQuote==0 && sqlite3IsIdChar(*pBest->t.z) ){ + nReplace = nNew; + zReplace = zNew; + }else{ + nReplace = nQuot; + zReplace = zQuot; + if( pBest->t.z[pBest->t.n]=='"' ) nReplace++; + } + }else{ + /* Dequote the double-quoted token. Then requote it again, this time + ** using single quotes. If the character immediately following the + ** original token within the input SQL was a single quote ('), then + ** add another space after the new, single-quoted version of the + ** token. This is so that (SELECT "string"'alias') maps to + ** (SELECT 'string' 'alias'), and not (SELECT 'string''alias'). */ + memcpy(zBuf1, pBest->t.z, pBest->t.n); + zBuf1[pBest->t.n] = 0; + sqlite3Dequote(zBuf1); + sqlite3_snprintf(nSql*2, zBuf2, "%Q%s", zBuf1, + pBest->t.z[pBest->t.n]=='\'' ? " " : "" + ); + zReplace = zBuf2; + nReplace = sqlite3Strlen30(zReplace); + } + + iOff = pBest->t.z - zSql; + if( pBest->t.n!=nReplace ){ + memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], + nOut - (iOff + pBest->t.n) + ); + nOut += nReplace - pBest->t.n; + zOut[nOut] = '\0'; + } + memcpy(&zOut[iOff], zReplace, nReplace); + sqlite3DbFree(db, pBest); + } + + sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); + sqlite3DbFree(db, zOut); + }else{ + rc = SQLITE_NOMEM; + } + + sqlite3_free(zQuot); + return rc; +} + +/* +** Set all pEList->a[].fg.eEName fields in the expression-list to val. +*/ +static void renameSetENames(ExprList *pEList, int val){ + if( pEList ){ + int i; + for(i=0; inExpr; i++){ + assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); + pEList->a[i].fg.eEName = val; + } + } +} + +/* +** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming +** it was read from the schema of database zDb. Return SQLITE_OK if +** successful. Otherwise, return an SQLite error code and leave an error +** message in the Parse object. +*/ +static int renameResolveTrigger(Parse *pParse){ + sqlite3 *db = pParse->db; + Trigger *pNew = pParse->pNewTrigger; + TriggerStep *pStep; + NameContext sNC; + int rc = SQLITE_OK; + + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + assert( pNew->pTabSchema ); + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName + ); + pParse->eTriggerOp = pNew->op; + /* ALWAYS() because if the table of the trigger does not exist, the + ** error would have been hit before this point */ + if( ALWAYS(pParse->pTriggerTab) ){ + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + } + + /* Resolve symbols in WHEN clause */ + if( rc==SQLITE_OK && pNew->pWhen ){ + rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); + } + + for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){ + if( pStep->pSelect ){ + sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); + if( pParse->nErr ) rc = pParse->rc; + } + if( rc==SQLITE_OK && pStep->zTarget ){ + SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep); + if( pSrc ){ + Select *pSel = sqlite3SelectNew( + pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0 + ); + if( pSel==0 ){ + pStep->pExprList = 0; + pSrc = 0; + rc = SQLITE_NOMEM; + }else{ + /* pStep->pExprList contains an expression-list used for an UPDATE + ** statement. So the a[].zEName values are the RHS of the + ** "= " clauses of the UPDATE statement. So, before + ** running SelectPrep(), change all the eEName values in + ** pStep->pExprList to ENAME_SPAN (from their current value of + ** ENAME_NAME). This is to prevent any ids in ON() clauses that are + ** part of pSrc from being incorrectly resolved against the + ** a[].zEName values as if they were column aliases. */ + renameSetENames(pStep->pExprList, ENAME_SPAN); + sqlite3SelectPrep(pParse, pSel, 0); + renameSetENames(pStep->pExprList, ENAME_NAME); + rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK; + assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList ); + assert( pSrc==pSel->pSrc ); + if( pStep->pExprList ) pSel->pEList = 0; + pSel->pSrc = 0; + sqlite3SelectDelete(db, pSel); + } + if( pStep->pFrom ){ + int i; + for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){ + SrcItem *p = &pStep->pFrom->a[i]; + if( p->pSelect ){ + sqlite3SelectPrep(pParse, p->pSelect, 0); + } + } + } + + if( db->mallocFailed ){ + rc = SQLITE_NOMEM; + } + sNC.pSrcList = pSrc; + if( rc==SQLITE_OK && pStep->pWhere ){ + rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); + } + assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); + if( pStep->pUpsert && rc==SQLITE_OK ){ + Upsert *pUpsert = pStep->pUpsert; + pUpsert->pUpsertSrc = pSrc; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc==SQLITE_OK ){ + ExprList *pUpsertSet = pUpsert->pUpsertSet; + rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + } + sNC.ncFlags = 0; + } + sNC.pSrcList = 0; + sqlite3SrcListDelete(db, pSrc); + }else{ + rc = SQLITE_NOMEM; + } + } + } + return rc; +} + +/* +** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr +** objects that are part of the trigger passed as the second argument. +*/ +static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ + TriggerStep *pStep; + + /* Find tokens to edit in WHEN clause */ + sqlite3WalkExpr(pWalker, pTrigger->pWhen); + + /* Find tokens to edit in trigger steps */ + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + sqlite3WalkSelect(pWalker, pStep->pSelect); + sqlite3WalkExpr(pWalker, pStep->pWhere); + sqlite3WalkExprList(pWalker, pStep->pExprList); + if( pStep->pUpsert ){ + Upsert *pUpsert = pStep->pUpsert; + sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); + sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); + } + if( pStep->pFrom ){ + int i; + for(i=0; ipFrom->nSrc; i++){ + sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); + } + } + } +} + +/* +** Free the contents of Parse object (*pParse). Do not free the memory +** occupied by the Parse object itself. +*/ +static void renameParseCleanup(Parse *pParse){ + sqlite3 *db = pParse->db; + Index *pIdx; + if( pParse->pVdbe ){ + sqlite3VdbeFinalize(pParse->pVdbe); + } + sqlite3DeleteTable(db, pParse->pNewTable); + while( (pIdx = pParse->pNewIndex)!=0 ){ + pParse->pNewIndex = pIdx->pNext; + sqlite3FreeIndex(db, pIdx); + } + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + sqlite3DbFree(db, pParse->zErrMsg); + renameTokenFree(db, pParse->pRename); + sqlite3ParseObjectReset(pParse); +} + +/* +** SQL function: +** +** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP) +** +** 0. zSql: SQL statement to rewrite +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3. Database: Database name (e.g. "main") +** 4. Table: Table name +** 5. iCol: Index of column to rename +** 6. zNew: New column name +** 7. bQuote: Non-zero if the new column name should be quoted. +** 8. bTemp: True if zSql comes from temp schema +** +** Do a column rename operation on the CREATE statement given in zSql. +** The iCol-th column (left-most is 0) of table zTable is renamed from zCol +** into zNew. The name should be quoted if bQuote is true. +** +** This function is used internally by the ALTER TABLE RENAME COLUMN command. +** It is only accessible to SQL created using sqlite3NestedParse(). It is +** not reachable from ordinary SQL passed into sqlite3_prepare() unless the +** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled. +*/ +static void renameColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + RenameCtx sCtx; + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + const char *zDb = (const char*)sqlite3_value_text(argv[3]); + const char *zTable = (const char*)sqlite3_value_text(argv[4]); + int iCol = sqlite3_value_int(argv[5]); + const char *zNew = (const char*)sqlite3_value_text(argv[6]); + int bQuote = sqlite3_value_int(argv[7]); + int bTemp = sqlite3_value_int(argv[8]); + const char *zOld; + int rc; + Parse sParse; + Walker sWalker; + Index *pIdx; + int i; + Table *pTab; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zSql==0 ) return; + if( zTable==0 ) return; + if( zNew==0 ) return; + if( iCol<0 ) return; + sqlite3BtreeEnterAll(db); + pTab = sqlite3FindTable(db, zTable, zDb); + if( pTab==0 || iCol>=pTab->nCol ){ + sqlite3BtreeLeaveAll(db); + return; + } + zOld = pTab->aCol[iCol].zCnName; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + + /* Find tokens that need to be replaced. */ + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameColumnExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + sCtx.pTab = pTab; + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + if( sParse.pNewTable ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; + pSelect->selFlags &= ~SF_View; + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + }else if( IsOrdinaryTable(sParse.pNewTable) ){ + /* A regular table */ + int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); + FKey *pFKey; + sCtx.pTab = sParse.pNewTable; + if( bFKOnly==0 ){ + if( iColnCol ){ + renameTokenFind( + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zCnName + ); + } + if( sCtx.iCol<0 ){ + renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); + } + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); + for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } + for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + for(i=0; inCol; i++){ + Expr *pExpr = sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i]); + sqlite3WalkExpr(&sWalker, pExpr); + } +#endif + } + + assert( IsOrdinaryTable(sParse.pNewTable) ); + for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + for(i=0; inCol; i++){ + if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ + renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); + } + if( 0==sqlite3_stricmp(pFKey->zTo, zTable) + && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) + ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); + } + } + } + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ + /* A trigger */ + TriggerStep *pStep; + rc = renameResolveTrigger(&sParse); + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + + for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget ){ + Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); + if( pTarget==pTab ){ + if( pStep->pUpsert ){ + ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; + renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld); + } + renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld); + renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld); + } + } + } + + + /* Find tokens to edit in UPDATE OF clause */ + if( sParse.pTriggerTab==pTab ){ + renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); + } + + /* Find tokens to edit in various expressions and selects */ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } + + assert( rc==SQLITE_OK ); + rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); + +renameColumnFunc_done: + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[0]); + }else if( sParse.zErrMsg ){ + renameColumnParseError(context, "", argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + sqlite3BtreeLeaveAll(db); +} + +/* +** Walker expression callback used by "RENAME TABLE". +*/ +static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_COLUMN + && ALWAYS(ExprUseYTab(pExpr)) + && p->pTab==pExpr->y.pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); + } + return WRC_Continue; +} + +/* +** Walker select callback used by "RENAME TABLE". +*/ +static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ + int i; + RenameCtx *p = pWalker->u.pRename; + SrcList *pSrc = pSelect->pSrc; + if( pSelect->selFlags & (SF_View|SF_CopyCte) ){ + testcase( pSelect->selFlags & SF_View ); + testcase( pSelect->selFlags & SF_CopyCte ); + return WRC_Prune; + } + if( NEVER(pSrc==0) ){ + assert( pWalker->pParse->db->mallocFailed ); + return WRC_Abort; + } + for(i=0; inSrc; i++){ + SrcItem *pItem = &pSrc->a[i]; + if( pItem->pTab==p->pTab ){ + renameTokenFind(pWalker->pParse, p, pItem->zName); + } + } + renameWalkWith(pWalker, pSelect); + + return WRC_Continue; +} + + +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 0: The database containing the table being renamed. +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3: The complete text of the schema statement being modified, +** 4: The old name of the table being renamed, and +** 5: The new name of the table being renamed. +** 6: True if the schema statement comes from the temp db. +** +** It returns the new schema statement. For example: +** +** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0) +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDb = (const char*)sqlite3_value_text(argv[0]); + const char *zInput = (const char*)sqlite3_value_text(argv[3]); + const char *zOld = (const char*)sqlite3_value_text(argv[4]); + const char *zNew = (const char*)sqlite3_value_text(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); + UNUSED_PARAMETER(NotUsed); + + if( zInput && zOld && zNew ){ + Parse sParse; + int rc; + int bQuote = 1; + RenameCtx sCtx; + Walker sWalker; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + memset(&sCtx, 0, sizeof(RenameCtx)); + sCtx.pTab = sqlite3FindTable(db, zOld, zDb); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameTableExprCb; + sWalker.xSelectCallback = renameTableSelectCb; + sWalker.u.pRename = &sCtx; + + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + + if( rc==SQLITE_OK ){ + int isLegacy = (db->flags & SQLITE_LegacyAlter); + if( sParse.pNewTable ){ + Table *pTab = sParse.pNewTable; + + if( IsView(pTab) ){ + if( isLegacy==0 ){ + Select *pSelect = pTab->u.view.pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + + assert( pSelect->selFlags & SF_View ); + pSelect->selFlags &= ~SF_View; + sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); + if( sParse.nErr ){ + rc = sParse.rc; + }else{ + sqlite3WalkSelect(&sWalker, pTab->u.view.pSelect); + } + } + }else{ + /* Modify any FK definitions to point to the new table. */ +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys)) + && !IsVirtual(pTab) + ){ + FKey *pFKey; + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); + } + } + } +#endif + + /* If this is the table being altered, fix any table refs in CHECK + ** expressions. Also update the name that appears right after the + ** "CREATE [VIRTUAL] TABLE" bit. */ + if( sqlite3_stricmp(zOld, pTab->zName)==0 ){ + sCtx.pTab = pTab; + if( isLegacy==0 ){ + sqlite3WalkExprList(&sWalker, pTab->pCheck); + } + renameTokenFind(&sParse, &sCtx, pTab->zName); + } + } + } + + else if( sParse.pNewIndex ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName); + if( isLegacy==0 ){ + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + } + } + +#ifndef SQLITE_OMIT_TRIGGER + else{ + Trigger *pTrigger = sParse.pNewTrigger; + TriggerStep *pStep; + if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) + && sCtx.pTab->pSchema==pTrigger->pTabSchema + ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); + } + + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, pTrigger); + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ + renameTokenFind(&sParse, &sCtx, pStep->zTarget); + } + if( pStep->pFrom ){ + int i; + for(i=0; ipFrom->nSrc; i++){ + SrcItem *pItem = &pStep->pFrom->a[i]; + if( 0==sqlite3_stricmp(pItem->zName, zOld) ){ + renameTokenFind(&sParse, &sCtx, pItem->zName); + } + } + } + } + } + } + } +#endif + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); + } + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[3]); + }else if( sParse.zErrMsg ){ + renameColumnParseError(context, "", argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); + sqlite3BtreeLeaveAll(db); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + } + + return; +} + +static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_STRING && (pExpr->flags & EP_DblQuoted) ){ + renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr); + } + return WRC_Continue; +} + +/* SQL function: sqlite_rename_quotefix(DB,SQL) +** +** Rewrite the DDL statement "SQL" so that any string literals that use +** double-quotes use single quotes instead. +** +** Two arguments must be passed: +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement to edit. +** +** The returned value is the modified SQL statement. For example, given +** the database schema: +** +** CREATE TABLE t1(a, b, c); +** +** SELECT sqlite_rename_quotefix('main', +** 'CREATE VIEW v1 AS SELECT "a", "string" FROM t1' +** ); +** +** returns the string: +** +** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1 +** +** If there is a error in the input SQL, then raise an error, except +** if PRAGMA writable_schema=ON, then just return the input string +** unmodified following an error. +*/ +static void renameQuotefixFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + UNUSED_PARAMETER(NotUsed); + if( zDb && zInput ){ + int rc; + Parse sParse; + rc = renameParseSql(&sParse, zDb, db, zInput, 0); + + if( rc==SQLITE_OK ){ + RenameCtx sCtx; + Walker sWalker; + + /* Walker to find tokens that need to be replaced. */ + memset(&sCtx, 0, sizeof(RenameCtx)); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameQuotefixExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + if( sParse.pNewTable ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; + pSelect->selFlags &= ~SF_View; + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + }else{ + int i; + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + for(i=0; inCol; i++){ + sqlite3WalkExpr(&sWalker, + sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i])); + } +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ +#ifndef SQLITE_OMIT_TRIGGER + rc = renameResolveTrigger(&sParse); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } +#endif /* SQLITE_OMIT_TRIGGER */ + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, 0, 0); + } + renameTokenFree(db, sCtx.pList); + } + if( rc!=SQLITE_OK ){ + if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){ + sqlite3_result_value(context, argv[1]); + }else{ + sqlite3_result_error_code(context, rc); + } + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + + sqlite3BtreeLeaveAll(db); +} + +/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS) +** +** An SQL user function that checks that there are no parse or symbol +** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. +** After an ALTER TABLE .. RENAME operation is performed and the schema +** reloaded, this function is called on each SQL statement in the schema +** to ensure that it is still usable. +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement. +** 2: Object type ("view", "table", "trigger" or "index"). +** 3: Object name. +** 4: True if object is from temp schema. +** 5: "when" part of error message. +** 6: True to disable the DQS quirk when parsing SQL. +** +** The return value is computed as follows: +** +** A. If an error is seen and not in PRAGMA writable_schema=ON mode, +** then raise the error. +** B. Else if a trigger is created and the the table that the trigger is +** attached to is in database zDb, then return 1. +** C. Otherwise return NULL. +*/ +static void renameTableTest( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + int bTemp = sqlite3_value_int(argv[4]); + int isLegacy = (db->flags & SQLITE_LegacyAlter); + char const *zWhen = (const char*)sqlite3_value_text(argv[5]); + int bNoDQS = sqlite3_value_int(argv[6]); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + + if( zDb && zInput ){ + int rc; + Parse sParse; + int flags = db->flags; + if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL)); + if( rc==SQLITE_OK ){ + if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + sqlite3SelectPrep(&sParse, sParse.pNewTable->u.view.pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + } + + else if( sParse.pNewTrigger ){ + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse); + } + if( rc==SQLITE_OK ){ + int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); + int i2 = sqlite3FindDbName(db, zDb); + if( i1==i2 ){ + /* Handle output case B */ + sqlite3_result_int(context, 1); + } + } + } + } + + if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){ + /* Output case A */ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif +} + +/* +** The implementation of internal UDF sqlite_drop_column(). +** +** Arguments: +** +** argv[0]: An integer - the index of the schema containing the table +** argv[1]: CREATE TABLE statement to modify. +** argv[2]: An integer - the index of the column to remove. +** +** The value returned is a string containing the CREATE TABLE statement +** with column argv[2] removed. +*/ +static void dropColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + int iSchema = sqlite3_value_int(argv[0]); + const char *zSql = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + const char *zDb = db->aDb[iSchema].zDbSName; + int rc; + Parse sParse; + RenameToken *pCol; + Table *pTab; + const char *zEnd; + char *zNew = 0; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); + if( rc!=SQLITE_OK ) goto drop_column_done; + pTab = sParse.pNewTable; + if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ + /* This can happen if the sqlite_schema table is corrupt */ + rc = SQLITE_CORRUPT_BKPT; + goto drop_column_done; + } + + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); + if( iColnCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); + zEnd = (const char*)pEnd->t.z; + }else{ + assert( IsOrdinaryTable(pTab) ); + zEnd = (const char*)&zSql[pTab->u.tab.addColOffset]; + while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; + } + + zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); + sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT); + sqlite3_free(zNew); + +drop_column_done: + renameParseCleanup(&sParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(context, rc); + } +} + +/* +** This function is called by the parser upon parsing an +** +** ALTER TABLE pSrc DROP COLUMN pName +** +** statement. Argument pSrc contains the possibly qualified name of the +** table being edited, and token pName the name of the column to drop. +*/ +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const Token *pName){ + sqlite3 *db = pParse->db; /* Database handle */ + Table *pTab; /* Table to modify */ + int iDb; /* Index of db containing pTab in aDb[] */ + const char *zDb; /* Database containing pTab ("main" etc.) */ + char *zCol = 0; /* Name of column to drop */ + int iCol; /* Index of column zCol in pTab->aCol[] */ + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( NEVER(db->mallocFailed) ) goto exit_drop_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_drop_column; + + /* Make sure this is not an attempt to ALTER a view, virtual table or + ** system table. */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column; + + /* Find the index of the column being dropped. */ + zCol = sqlite3NameFromToken(db, pName); + if( zCol==0 ){ + assert( db->mallocFailed ); + goto exit_drop_column; + } + iCol = sqlite3ColumnIndex(pTab, zCol); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName); + goto exit_drop_column; + } + + /* Do not allow the user to drop a PRIMARY KEY column or a column + ** constrained by a UNIQUE constraint. */ + if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){ + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE", + zCol + ); + goto exit_drop_column; + } + + /* Do not allow the number of columns to go to zero */ + if( pTab->nCol<=1 ){ + sqlite3ErrorMsg(pParse, "cannot drop column \"%s\": no other columns exist",zCol); + goto exit_drop_column; + } + + /* Edit the sqlite_schema table */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + zDb = db->aDb[iDb].zDbSName; +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + goto exit_drop_column; + } +#endif + renameTestSchema(pParse, zDb, iDb==1, "", 0); + renameFixQuotes(pParse, zDb, iDb==1); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_drop_column(%d, sql, %d) " + "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" + , zDb, iDb, iCol, pTab->zName + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); + renameTestSchema(pParse, zDb, iDb==1, "after drop column", 1); + + /* Edit rows of table on disk */ + if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ + int i; + int addr; + int reg; + int regRec; + Index *pPk = 0; + int nField = 0; /* Number of non-virtual columns after drop */ + int iCur; + Vdbe *v = sqlite3GetVdbe(pParse); + iCur = pParse->nTab++; + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + reg = ++pParse->nMem; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); + pParse->nMem += pTab->nCol; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + pParse->nMem += pPk->nColumn; + for(i=0; inKeyCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1); + } + nField = pPk->nKeyCol; + } + regRec = ++pParse->nMem; + for(i=0; inCol; i++){ + if( i!=iCol && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + int regOut; + if( pPk ){ + int iPos = sqlite3TableColumnToIndex(pPk, i); + int iColPos = sqlite3TableColumnToIndex(pPk, iCol); + if( iPosnKeyCol ) continue; + regOut = reg+1+iPos-(iPos>iColPos); + }else{ + regOut = reg+1+nField; + } + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); + }else{ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + } + nField++; + } + } + if( nField==0 ){ + /* dbsqlfuzz 5f09e7bcc78b4954d06bf9f2400d7715f48d1fef */ + pParse->nMem++; + sqlite3VdbeAddOp2(v, OP_Null, 0, reg+1); + nField = 1; + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec); + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); + }else{ + sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); + } + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + } + +exit_drop_column: + sqlite3DbFree(db, zCol); + sqlite3SrcListDelete(db, pSrc); +} + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +SQLITE_PRIVATE void sqlite3AlterFunctions(void){ + static FuncDef aAlterTableFuncs[] = { + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), + INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc), + }; + sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); +} +#endif /* SQLITE_ALTER_TABLE */ + +/************** End of alter.c ***********************************************/ +/************** Begin file analyze.c *****************************************/ +/* +** 2005-07-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code associated with the ANALYZE command. +** +** The ANALYZE command gather statistics about the content of tables +** and indices. These statistics are made available to the query planner +** to help it make better decisions about how to perform queries. +** +** The following system tables are or have been supported: +** +** CREATE TABLE sqlite_stat1(tbl, idx, stat); +** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); +** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); +** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); +** +** Additional tables might be added in future releases of SQLite. +** The sqlite_stat2 table is not created or used unless the SQLite version +** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled +** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. +** The sqlite_stat2 table is superseded by sqlite_stat3, which is only +** created and used by SQLite versions 3.7.9 through 3.29.0 when +** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 +** is a superset of sqlite_stat2 and is also now deprecated. The +** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only +** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite +** versions 3.8.1 and later. STAT4 is the only variant that is still +** supported. +** +** For most applications, sqlite_stat1 provides all the statistics required +** for the query planner to make good choices. +** +** Format of sqlite_stat1: +** +** There is normally one row per index, with the index identified by the +** name in the idx column. The tbl column is the name of the table to +** which the index belongs. In each such row, the stat column will be +** a string consisting of a list of integers. The first integer in this +** list is the number of rows in the index. (This is the same as the +** number of rows in the table, except for partial indices.) The second +** integer is the average number of rows in the index that have the same +** value in the first column of the index. The third integer is the average +** number of rows in the index that have the same value for the first two +** columns. The N-th integer (for N>1) is the average number of rows in +** the index which have the same value for the first N-1 columns. For +** a K-column index, there will be K+1 integers in the stat column. If +** the index is unique, then the last integer will be 1. +** +** The list of integers in the stat column can optionally be followed +** by the keyword "unordered". The "unordered" keyword, if it is present, +** must be separated from the last integer by a single space. If the +** "unordered" keyword is present, then the query planner assumes that +** the index is unordered and will not use the index for a range query. +** +** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat +** column contains a single integer which is the (estimated) number of +** rows in the table identified by sqlite_stat1.tbl. +** +** Format of sqlite_stat2: +** +** The sqlite_stat2 is only created and is only used if SQLite is compiled +** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between +** 3.6.18 and 3.7.8. The "stat2" table contains additional information +** about the distribution of keys within an index. The index is identified by +** the "idx" column and the "tbl" column is the name of the table to which +** the index belongs. There are usually 10 rows in the sqlite_stat2 +** table for each index. +** +** The sqlite_stat2 entries for an index that have sampleno between 0 and 9 +** inclusive are samples of the left-most key value in the index taken at +** evenly spaced points along the index. Let the number of samples be S +** (10 in the standard build) and let C be the number of rows in the index. +** Then the sampled rows are given by: +** +** rownumber = (i*C*2 + C)/(S*2) +** +** For i between 0 and S-1. Conceptually, the index space is divided into +** S uniform buckets and the samples are the middle row from each bucket. +** +** The format for sqlite_stat2 is recorded here for legacy reference. This +** version of SQLite does not support sqlite_stat2. It neither reads nor +** writes the sqlite_stat2 table. This version of SQLite only supports +** sqlite_stat3. +** +** Format for sqlite_stat3: +** +** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the +** sqlite_stat4 format will be described first. Further information +** about sqlite_stat3 follows the sqlite_stat4 description. +** +** Format for sqlite_stat4: +** +** As with sqlite_stat2, the sqlite_stat4 table contains histogram data +** to aid the query planner in choosing good indices based on the values +** that indexed columns are compared against in the WHERE clauses of +** queries. +** +** The sqlite_stat4 table contains multiple entries for each index. +** The idx column names the index and the tbl column is the table of the +** index. If the idx and tbl columns are the same, then the sample is +** of the INTEGER PRIMARY KEY. The sample column is a blob which is the +** binary encoding of a key from the index. The nEq column is a +** list of integers. The first integer is the approximate number +** of entries in the index whose left-most column exactly matches +** the left-most column of the sample. The second integer in nEq +** is the approximate number of entries in the index where the +** first two columns match the first two columns of the sample. +** And so forth. nLt is another list of integers that show the approximate +** number of entries that are strictly less than the sample. The first +** integer in nLt contains the number of entries in the index where the +** left-most column is less than the left-most column of the sample. +** The K-th integer in the nLt entry is the number of index entries +** where the first K columns are less than the first K columns of the +** sample. The nDLt column is like nLt except that it contains the +** number of distinct entries in the index that are less than the +** sample. +** +** There can be an arbitrary number of sqlite_stat4 entries per index. +** The ANALYZE command will typically generate sqlite_stat4 tables +** that contain between 10 and 40 samples which are distributed across +** the key space, though not uniformly, and which include samples with +** large nEq values. +** +** Format for sqlite_stat3 redux: +** +** The sqlite_stat3 table is like sqlite_stat4 except that it only +** looks at the left-most column of the index. The sqlite_stat3.sample +** column contains the actual value of the left-most column instead +** of a blob encoding of the complete index key as is found in +** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 +** all contain just a single integer which is the same as the first +** integer in the equivalent columns in sqlite_stat4. +*/ +#ifndef SQLITE_OMIT_ANALYZE +/* #include "sqliteInt.h" */ + +#if defined(SQLITE_ENABLE_STAT4) +# define IsStat4 1 +#else +# define IsStat4 0 +# undef SQLITE_STAT4_SAMPLES +# define SQLITE_STAT4_SAMPLES 1 +#endif + +/* +** This routine generates code that opens the sqlite_statN tables. +** The sqlite_stat1 table is always relevant. sqlite_stat2 is now +** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when +** appropriate compile-time options are provided. +** +** If the sqlite_statN tables do not previously exist, it is created. +** +** Argument zWhere may be a pointer to a buffer containing a table name, +** or it may be a NULL pointer. If it is not NULL, then all entries in +** the sqlite_statN tables associated with the named table are deleted. +** If zWhere==0, then code is generated to delete all stat table entries. +*/ +static void openStatTable( + Parse *pParse, /* Parsing context */ + int iDb, /* The database we are looking in */ + int iStatCur, /* Open the sqlite_stat1 table on this cursor */ + const char *zWhere, /* Delete entries for this table or index */ + const char *zWhereType /* Either "tbl" or "idx" */ +){ + static const struct { + const char *zName; + const char *zCols; + } aTable[] = { + { "sqlite_stat1", "tbl,idx,stat" }, +#if defined(SQLITE_ENABLE_STAT4) + { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, +#else + { "sqlite_stat4", 0 }, +#endif + { "sqlite_stat3", 0 }, + }; + int i; + sqlite3 *db = pParse->db; + Db *pDb; + Vdbe *v = sqlite3GetVdbe(pParse); + u32 aRoot[ArraySize(aTable)]; + u8 aCreateTbl[ArraySize(aTable)]; +#ifdef SQLITE_ENABLE_STAT4 + const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1; +#else + const int nToOpen = 1; +#endif + + if( v==0 ) return; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3VdbeDb(v)==db ); + pDb = &db->aDb[iDb]; + + /* Create new statistic tables if they do not exist, or clear them + ** if they do already exist. + */ + for(i=0; izDbSName))==0 ){ + if( iregRoot. This is important + ** because the OpenWrite opcode below will be needing it. */ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols + ); + aRoot[i] = (u32)pParse->regRoot; + aCreateTbl[i] = OPFLAG_P2ISREG; + } + }else{ + /* The table already exists. If zWhere is not NULL, delete all entries + ** associated with the table zWhere. If zWhere is NULL, delete the + ** entire contents of the table. */ + aRoot[i] = pStat->tnum; + sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); + if( zWhere ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + pDb->zDbSName, zTab, zWhereType, zWhere + ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + }else if( db->xPreUpdateCallback ){ + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab); +#endif + }else{ + /* The sqlite_stat[134] table already exists. Delete all rows. */ + sqlite3VdbeAddOp2(v, OP_Clear, (int)aRoot[i], iDb); + } + } + } + + /* Open the sqlite_stat[134] tables for writing. */ + for(i=0; inRowid ){ + sqlite3DbFree(db, p->u.aRowid); + p->nRowid = 0; + } +} +#endif + +/* Initialize the BLOB value of a ROWID +*/ +#ifdef SQLITE_ENABLE_STAT4 +static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){ + assert( db!=0 ); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->u.aRowid = sqlite3DbMallocRawNN(db, n); + if( p->u.aRowid ){ + p->nRowid = n; + memcpy(p->u.aRowid, pData, n); + }else{ + p->nRowid = 0; + } +} +#endif + +/* Initialize the INTEGER value of a ROWID. +*/ +#ifdef SQLITE_ENABLE_STAT4 +static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){ + assert( db!=0 ); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->nRowid = 0; + p->u.iRowid = iRowid; +} +#endif + + +/* +** Copy the contents of object (*pFrom) into (*pTo). +*/ +#ifdef SQLITE_ENABLE_STAT4 +static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){ + pTo->isPSample = pFrom->isPSample; + pTo->iCol = pFrom->iCol; + pTo->iHash = pFrom->iHash; + memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); + memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); + memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); + if( pFrom->nRowid ){ + sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid); + }else{ + sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid); + } +} +#endif + +/* +** Reclaim all memory of a StatAccum structure. +*/ +static void statAccumDestructor(void *pOld){ + StatAccum *p = (StatAccum*)pOld; +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ){ + int i; + for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i); + for(i=0; imxSample; i++) sampleClear(p->db, p->a+i); + sampleClear(p->db, &p->current); + } +#endif + sqlite3DbFree(p->db, p); +} + +/* +** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters +** are: +** N: The number of columns in the index including the rowid/pk (note 1) +** K: The number of columns in the index excluding the rowid/pk. +** C: Estimated number of rows in the index +** L: A limit on the number of rows to scan, or 0 for no-limit +** +** Note 1: In the special case of the covering index that implements a +** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the +** total number of columns in the table. +** +** For indexes on ordinary rowid tables, N==K+1. But for indexes on +** WITHOUT ROWID tables, N=K+P where P is the number of columns in the +** PRIMARY KEY of the table. The covering index that implements the +** original WITHOUT ROWID table as N==K as a special case. +** +** This routine allocates the StatAccum object in heap memory. The return +** value is a pointer to the StatAccum object. The datatype of the +** return value is BLOB, but it is really just a pointer to the StatAccum +** object. +*/ +static void statInit( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + StatAccum *p; + int nCol; /* Number of columns in index being sampled */ + int nKeyCol; /* Number of key columns */ + int nColUp; /* nCol rounded up for alignment */ + int n; /* Bytes of space to allocate */ + sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */ +#ifdef SQLITE_ENABLE_STAT4 + /* Maximum number of samples. 0 if STAT4 data is not collected */ + int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0; +#endif + + /* Decode the three function arguments */ + UNUSED_PARAMETER(argc); + nCol = sqlite3_value_int(argv[0]); + assert( nCol>0 ); + nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; + nKeyCol = sqlite3_value_int(argv[1]); + assert( nKeyCol<=nCol ); + assert( nKeyCol>0 ); + + /* Allocate the space required for the StatAccum object */ + n = sizeof(*p) + + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ +#ifdef SQLITE_ENABLE_STAT4 + n += sizeof(tRowcnt)*nColUp; /* StatAccum.anEq */ + if( mxSample ){ + n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ + + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample); + } +#endif + p = sqlite3DbMallocZero(db, n); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + + p->db = db; + p->nEst = sqlite3_value_int64(argv[2]); + p->nRow = 0; + p->nLimit = sqlite3_value_int64(argv[3]); + p->nCol = nCol; + p->nKeyCol = nKeyCol; + p->nSkipAhead = 0; + p->current.anDLt = (tRowcnt*)&p[1]; + +#ifdef SQLITE_ENABLE_STAT4 + p->current.anEq = &p->current.anDLt[nColUp]; + p->mxSample = p->nLimit==0 ? mxSample : 0; + if( mxSample ){ + u8 *pSpace; /* Allocated space not yet assigned */ + int i; /* Used to iterate through p->aSample[] */ + + p->iGet = -1; + p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1); + p->current.anLt = &p->current.anEq[nColUp]; + p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); + + /* Set up the StatAccum.a[] and aBest[] arrays */ + p->a = (struct StatSample*)&p->current.anLt[nColUp]; + p->aBest = &p->a[mxSample]; + pSpace = (u8*)(&p->a[mxSample+nCol]); + for(i=0; i<(mxSample+nCol); i++){ + p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + } + assert( (pSpace - (u8*)p)==n ); + + for(i=0; iaBest[i].iCol = i; + } + } +#endif + + /* Return a pointer to the allocated object to the caller. Note that + ** only the pointer (the 2nd parameter) matters. The size of the object + ** (given by the 3rd parameter) is never used and can be any positive + ** value. */ + sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor); +} +static const FuncDef statInitFuncdef = { + 4, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statInit, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "stat_init", /* zName */ + {0} +}; + +#ifdef SQLITE_ENABLE_STAT4 +/* +** pNew and pOld are both candidate non-periodic samples selected for +** the same column (pNew->iCol==pOld->iCol). Ignoring this column and +** considering only any trailing columns and the sample hash value, this +** function returns true if sample pNew is to be preferred over pOld. +** In other words, if we assume that the cardinalities of the selected +** column for pNew and pOld are equal, is pNew to be preferred over pOld. +** +** This function assumes that for each argument sample, the contents of +** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. +*/ +static int sampleIsBetterPost( + StatAccum *pAccum, + StatSample *pNew, + StatSample *pOld +){ + int nCol = pAccum->nCol; + int i; + assert( pNew->iCol==pOld->iCol ); + for(i=pNew->iCol+1; ianEq[i]>pOld->anEq[i] ) return 1; + if( pNew->anEq[i]anEq[i] ) return 0; + } + if( pNew->iHash>pOld->iHash ) return 1; + return 0; +} +#endif + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Return true if pNew is to be preferred over pOld. +** +** This function assumes that for each argument sample, the contents of +** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. +*/ +static int sampleIsBetter( + StatAccum *pAccum, + StatSample *pNew, + StatSample *pOld +){ + tRowcnt nEqNew = pNew->anEq[pNew->iCol]; + tRowcnt nEqOld = pOld->anEq[pOld->iCol]; + + assert( pOld->isPSample==0 && pNew->isPSample==0 ); + assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); + + if( (nEqNew>nEqOld) ) return 1; + if( nEqNew==nEqOld ){ + if( pNew->iColiCol ) return 1; + return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); + } + return 0; +} + +/* +** Copy the contents of sample *pNew into the p->a[] array. If necessary, +** remove the least desirable sample from p->a[] to make room. +*/ +static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){ + StatSample *pSample = 0; + int i; + + assert( IsStat4 || nEqZero==0 ); + + /* StatAccum.nMaxEqZero is set to the maximum number of leading 0 + ** values in the anEq[] array of any sample in StatAccum.a[]. In + ** other words, if nMaxEqZero is n, then it is guaranteed that there + ** are no samples with StatSample.anEq[m]==0 for (m>=n). */ + if( nEqZero>p->nMaxEqZero ){ + p->nMaxEqZero = nEqZero; + } + if( pNew->isPSample==0 ){ + StatSample *pUpgrade = 0; + assert( pNew->anEq[pNew->iCol]>0 ); + + /* This sample is being added because the prefix that ends in column + ** iCol occurs many times in the table. However, if we have already + ** added a sample that shares this prefix, there is no need to add + ** this one. Instead, upgrade the priority of the highest priority + ** existing sample that shares this prefix. */ + for(i=p->nSample-1; i>=0; i--){ + StatSample *pOld = &p->a[i]; + if( pOld->anEq[pNew->iCol]==0 ){ + if( pOld->isPSample ) return; + assert( pOld->iCol>pNew->iCol ); + assert( sampleIsBetter(p, pNew, pOld) ); + if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ + pUpgrade = pOld; + } + } + } + if( pUpgrade ){ + pUpgrade->iCol = pNew->iCol; + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; + goto find_new_min; + } + } + + /* If necessary, remove sample iMin to make room for the new sample. */ + if( p->nSample>=p->mxSample ){ + StatSample *pMin = &p->a[p->iMin]; + tRowcnt *anEq = pMin->anEq; + tRowcnt *anLt = pMin->anLt; + tRowcnt *anDLt = pMin->anDLt; + sampleClear(p->db, pMin); + memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); + pSample = &p->a[p->nSample-1]; + pSample->nRowid = 0; + pSample->anEq = anEq; + pSample->anDLt = anDLt; + pSample->anLt = anLt; + p->nSample = p->mxSample-1; + } + + /* The "rows less-than" for the rowid column must be greater than that + ** for the last sample in the p->a[] array. Otherwise, the samples would + ** be out of order. */ + assert( p->nSample==0 + || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); + + /* Insert the new sample */ + pSample = &p->a[p->nSample]; + sampleCopy(p, pSample, pNew); + p->nSample++; + + /* Zero the first nEqZero entries in the anEq[] array. */ + memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); + +find_new_min: + if( p->nSample>=p->mxSample ){ + int iMin = -1; + for(i=0; imxSample; i++){ + if( p->a[i].isPSample ) continue; + if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ + iMin = i; + } + } + assert( iMin>=0 ); + p->iMin = iMin; + } +} +#endif /* SQLITE_ENABLE_STAT4 */ + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Field iChng of the index being scanned has changed. So at this point +** p->current contains a sample that reflects the previous row of the +** index. The value of anEq[iChng] and subsequent anEq[] elements are +** correct at this point. +*/ +static void samplePushPrevious(StatAccum *p, int iChng){ + int i; + + /* Check if any samples from the aBest[] array should be pushed + ** into IndexSample.a[] at this point. */ + for(i=(p->nCol-2); i>=iChng; i--){ + StatSample *pBest = &p->aBest[i]; + pBest->anEq[i] = p->current.anEq[i]; + if( p->nSamplemxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ + sampleInsert(p, pBest, i); + } + } + + /* Check that no sample contains an anEq[] entry with an index of + ** p->nMaxEqZero or greater set to zero. */ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=p->nMaxEqZero; jnCol; j++) assert( p->a[i].anEq[j]>0 ); + } + + /* Update the anEq[] fields of any samples already collected. */ + if( iChngnMaxEqZero ){ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=iChng; jnCol; j++){ + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + } + } + p->nMaxEqZero = iChng; + } +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** Implementation of the stat_push SQL function: stat_push(P,C,R) +** Arguments: +** +** P Pointer to the StatAccum object created by stat_init() +** C Index of left-most column to differ from previous row +** R Rowid for the current row. Might be a key record for +** WITHOUT ROWID tables. +** +** The purpose of this routine is to collect statistical data and/or +** samples from the index being analyzed into the StatAccum object. +** The stat_get() SQL function will be used afterwards to +** retrieve the information gathered. +** +** This SQL function usually returns NULL, but might return an integer +** if it wants the byte-code to do special processing. +** +** The R parameter is only used for STAT4 +*/ +static void statPush( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + + /* The three function arguments */ + StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]); + int iChng = sqlite3_value_int(argv[1]); + + UNUSED_PARAMETER( argc ); + UNUSED_PARAMETER( context ); + assert( p->nCol>0 ); + assert( iChngnCol ); + + if( p->nRow==0 ){ + /* This is the first call to this function. Do initialization. */ +#ifdef SQLITE_ENABLE_STAT4 + for(i=0; inCol; i++) p->current.anEq[i] = 1; +#endif + }else{ + /* Second and subsequent calls get processed here */ +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ) samplePushPrevious(p, iChng); +#endif + + /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply + ** to the current row of the index. */ +#ifdef SQLITE_ENABLE_STAT4 + for(i=0; icurrent.anEq[i]++; + } +#endif + for(i=iChng; inCol; i++){ + p->current.anDLt[i]++; +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; + p->current.anEq[i] = 1; +#endif + } + } + + p->nRow++; +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ){ + tRowcnt nLt; + if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){ + sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2])); + }else{ + sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]), + sqlite3_value_blob(argv[2])); + } + p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; + + nLt = p->current.anLt[p->nCol-1]; + /* Check if this is to be a periodic sample. If so, add it. */ + if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ + p->current.isPSample = 1; + p->current.iCol = 0; + sampleInsert(p, &p->current, p->nCol-1); + p->current.isPSample = 0; + } + + /* Update the aBest[] array. */ + for(i=0; i<(p->nCol-1); i++){ + p->current.iCol = i; + if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ + sampleCopy(p, &p->aBest[i], &p->current); + } + } + }else +#endif + if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){ + p->nSkipAhead++; + sqlite3_result_int(context, p->current.anDLt[0]>0); + } +} + +static const FuncDef statPushFuncdef = { + 2+IsStat4, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statPush, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "stat_push", /* zName */ + {0} +}; + +#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ +#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ +#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ +#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ +#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ + +/* +** Implementation of the stat_get(P,J) SQL function. This routine is +** used to query statistical information that has been gathered into +** the StatAccum object by prior calls to stat_push(). The P parameter +** has type BLOB but it is really just a pointer to the StatAccum object. +** The content to returned is determined by the parameter J +** which is one of the STAT_GET_xxxx values defined above. +** +** The stat_get(P,J) function is not available to generic SQL. It is +** inserted as part of a manually constructed bytecode program. (See +** the callStatGet() routine below.) It is guaranteed that the P +** parameter will always be a pointer to a StatAccum object, never a +** NULL. +** +** If STAT4 is not enabled, then J is always +** STAT_GET_STAT1 and is hence omitted and this routine becomes +** a one-parameter function, stat_get(P), that always returns the +** stat1 table entry information. +*/ +static void statGet( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]); +#ifdef SQLITE_ENABLE_STAT4 + /* STAT4 has a parameter on this routine. */ + int eCall = sqlite3_value_int(argv[1]); + assert( argc==2 ); + assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ + || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT + || eCall==STAT_GET_NDLT + ); + assert( eCall==STAT_GET_STAT1 || p->mxSample ); + if( eCall==STAT_GET_STAT1 ) +#else + assert( argc==1 ); +#endif + { + /* Return the value to store in the "stat" column of the sqlite_stat1 + ** table for this index. + ** + ** The value is a string composed of a list of integers describing + ** the index. The first integer in the list is the total number of + ** entries in the index. There is one additional integer in the list + ** for each indexed column. This additional integer is an estimate of + ** the number of rows matched by a equality query on the index using + ** a key with the corresponding number of fields. In other words, + ** if the index is on columns (a,b) and the sqlite_stat1 value is + ** "100 10 2", then SQLite estimates that: + ** + ** * the index contains 100 rows, + ** * "WHERE a=?" matches 10 rows, and + ** * "WHERE a=? AND b=?" matches 2 rows. + ** + ** If D is the count of distinct values and K is the total number of + ** rows, then each estimate is usually computed as: + ** + ** I = (K+D-1)/D + ** + ** In other words, I is K/D rounded up to the next whole integer. + ** However, if I is between 1.0 and 1.1 (in other words if I is + ** close to 1.0 but just a little larger) then do not round up but + ** instead keep the I value at 1.0. + */ + sqlite3_str sStat; /* Text of the constructed "stat" line */ + int i; /* Loop counter */ + + sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); + sqlite3_str_appendf(&sStat, "%llu", + p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); + for(i=0; inKeyCol; i++){ + u64 nDistinct = p->current.anDLt[i] + 1; + u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; + if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; + sqlite3_str_appendf(&sStat, " %llu", iVal); +#ifdef SQLITE_ENABLE_STAT4 + assert( p->current.anEq[i] ); +#endif + } + sqlite3ResultStrAccum(context, &sStat); + } +#ifdef SQLITE_ENABLE_STAT4 + else if( eCall==STAT_GET_ROWID ){ + if( p->iGet<0 ){ + samplePushPrevious(p, 0); + p->iGet = 0; + } + if( p->iGetnSample ){ + StatSample *pS = p->a + p->iGet; + if( pS->nRowid==0 ){ + sqlite3_result_int64(context, pS->u.iRowid); + }else{ + sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid, + SQLITE_TRANSIENT); + } + } + }else{ + tRowcnt *aCnt = 0; + sqlite3_str sStat; + int i; + + assert( p->iGetnSample ); + switch( eCall ){ + case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; + case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; + default: { + aCnt = p->a[p->iGet].anDLt; + p->iGet++; + break; + } + } + sqlite3StrAccumInit(&sStat, 0, 0, 0, p->nCol*100); + for(i=0; inCol; i++){ + sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]); + } + if( sStat.nChar ) sStat.nChar--; + sqlite3ResultStrAccum(context, &sStat); + } +#endif /* SQLITE_ENABLE_STAT4 */ +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER( argc ); +#endif +} +static const FuncDef statGetFuncdef = { + 1+IsStat4, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statGet, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "stat_get", /* zName */ + {0} +}; + +static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){ +#ifdef SQLITE_ENABLE_STAT4 + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1); +#elif SQLITE_DEBUG + assert( iParam==STAT_GET_STAT1 ); +#else + UNUSED_PARAMETER( iParam ); +#endif + assert( regOut!=regStat && regOut!=regStat+1 ); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4, + &statGetFuncdef, 0); +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* Add a comment to the most recent VDBE opcode that is the name +** of the k-th column of the pIdx index. +*/ +static void analyzeVdbeCommentIndexWithColumnName( + Vdbe *v, /* Prepared statement under construction */ + Index *pIdx, /* Index whose column is being loaded */ + int k /* Which column index */ +){ + int i; /* Index of column in the table */ + assert( k>=0 && knColumn ); + i = pIdx->aiColumn[k]; + if( NEVER(i==XN_ROWID) ){ + VdbeComment((v,"%s.rowid",pIdx->zName)); + }else if( i==XN_EXPR ){ + assert( pIdx->bHasExpr ); + VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); + }else{ + VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); + } +} +#else +# define analyzeVdbeCommentIndexWithColumnName(a,b,c) +#endif /* SQLITE_DEBUG */ + +/* +** Generate code to do an analysis of all indices associated with +** a single table. +*/ +static void analyzeOneTable( + Parse *pParse, /* Parser context */ + Table *pTab, /* Table whose indices are to be analyzed */ + Index *pOnlyIdx, /* If not NULL, only analyze this one index */ + int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ + int iMem, /* Available memory locations begin here */ + int iTab /* Next available cursor */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + Index *pIdx; /* An index to being analyzed */ + int iIdxCur; /* Cursor open on index being analyzed */ + int iTabCur; /* Table cursor */ + Vdbe *v; /* The virtual machine being built up */ + int i; /* Loop counter */ + int jZeroRows = -1; /* Jump from here if number of rows is zero */ + int iDb; /* Index of database containing pTab */ + u8 needTableCnt = 1; /* True to count the table */ + int regNewRowid = iMem++; /* Rowid for the inserted record */ + int regStat = iMem++; /* Register to hold StatAccum object */ + int regChng = iMem++; /* Index of changed index field */ + int regRowid = iMem++; /* Rowid argument passed to stat_push() */ + int regTemp = iMem++; /* Temporary use register */ + int regTemp2 = iMem++; /* Second temporary use register */ + int regTabname = iMem++; /* Register containing table name */ + int regIdxname = iMem++; /* Register containing index name */ + int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ + int regPrev = iMem; /* MUST BE LAST (see below) */ +#ifdef SQLITE_ENABLE_STAT4 + int doOnce = 1; /* Flag for a one-time computation */ +#endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + Table *pStat1 = 0; +#endif + + sqlite3TouchRegister(pParse, iMem); + assert( sqlite3NoTempsInRange(pParse, regNewRowid, iMem) ); + v = sqlite3GetVdbe(pParse); + if( v==0 || NEVER(pTab==0) ){ + return; + } + if( !IsOrdinaryTable(pTab) ){ + /* Do not gather statistics on views or virtual tables */ + return; + } + if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ + /* Do not gather statistics on system tables */ + return; + } + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, + db->aDb[iDb].zDbSName ) ){ + return; + } +#endif + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( db->xPreUpdateCallback ){ + pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); + if( pStat1==0 ) return; + pStat1->zName = (char*)&pStat1[1]; + memcpy(pStat1->zName, "sqlite_stat1", 13); + pStat1->nCol = 3; + pStat1->iPKey = -1; + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC); + } +#endif + + /* Establish a read-lock on the table at the shared-cache level. + ** Open a read-only cursor on the table. Also allocate a cursor number + ** to use for scanning indexes (iIdxCur). No index cursor is opened at + ** this time though. */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + iTabCur = iTab++; + iIdxCur = iTab++; + pParse->nTab = MAX(pParse->nTab, iTab); + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeLoadString(v, regTabname, pTab->zName); + + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int nCol; /* Number of columns in pIdx. "N" */ + int addrRewind; /* Address of "OP_Rewind iIdxCur" */ + int addrNextRow; /* Address of "next_row:" */ + const char *zIdxName; /* Name of the index */ + int nColTest; /* Number of columns to test for changes */ + + if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ + nCol = pIdx->nKeyCol; + zIdxName = pTab->zName; + nColTest = nCol - 1; + }else{ + nCol = pIdx->nColumn; + zIdxName = pIdx->zName; + nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; + } + + /* Populate the register containing the index name. */ + sqlite3VdbeLoadString(v, regIdxname, zIdxName); + VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); + + /* + ** Pseudo-code for loop that calls stat_push(): + ** + ** Rewind csr + ** if eof(csr) goto end_of_scan; + ** regChng = 0 + ** goto chng_addr_0; + ** + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto chng_addr_N + ** + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + ** + ** endDistinctTest: + ** regRowid = idx(rowid) + ** stat_push(P, regChng, regRowid) + ** Next csr + ** if !eof(csr) goto next_row; + ** + ** end_of_scan: + */ + + /* Make sure there are enough memory cells allocated to accommodate + ** the regPrev array and a trailing rowid (the rowid slot is required + ** when building a record to insert into the sample column of + ** the sqlite_stat4 table. */ + sqlite3TouchRegister(pParse, regPrev+nColTest); + + /* Open a read-only cursor on the index being analyzed. */ + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + + /* Invoke the stat_init() function. The arguments are: + ** + ** (1) the number of columns in the index including the rowid + ** (or for a WITHOUT ROWID table, the number of PK columns), + ** (2) the number of columns in the key without the rowid/pk + ** (3) estimated number of rows in the index, + */ + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); + assert( regRowid==regStat+2 ); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); +#ifdef SQLITE_ENABLE_STAT4 + if( OptimizationEnabled(db, SQLITE_Stat4) ){ + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp); + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); + }else +#endif + { + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1); + } + assert( regTemp2==regStat+4 ); + sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, + &statInitFuncdef, 0); + + /* Implementation of the following: + ** + ** Rewind csr + ** if eof(csr) goto end_of_scan; + ** regChng = 0 + ** goto next_push_0; + ** + */ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); + addrNextRow = sqlite3VdbeCurrentAddr(v); + + if( nColTest>0 ){ + int endDistinctTest = sqlite3VdbeMakeLabel(pParse); + int *aGotoChng; /* Array of jump instruction addresses */ + aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); + if( aGotoChng==0 ) continue; + + /* + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto endDistinctTest + */ + sqlite3VdbeAddOp0(v, OP_Goto); + addrNextRow = sqlite3VdbeCurrentAddr(v); + if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ + /* For a single-column UNIQUE index, once we have found a non-NULL + ** row, we know that all the rest will be distinct, so skip + ** subsequent distinctness tests. */ + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); + VdbeCoverage(v); + } + for(i=0; iazColl[i]); + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); + analyzeVdbeCommentIndexWithColumnName(v,pIdx,i); + aGotoChng[i] = + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); + sqlite3VdbeGoto(v, endDistinctTest); + + + /* + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + */ + sqlite3VdbeJumpHere(v, addrNextRow-1); + for(i=0; ipTable); + int j, k, regKey; + regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); + for(j=0; jnKeyCol; j++){ + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); + assert( k>=0 && knColumn ); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); + analyzeVdbeCommentIndexWithColumnName(v,pIdx,k); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); + sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); + } + } +#endif + assert( regChng==(regStat+1) ); + { + sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4, + &statPushFuncdef, 0); + if( db->nAnalysisLimit ){ + int j1, j2, j3; + j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v); + j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v); + j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, j2); + sqlite3VdbeJumpHere(v, j3); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + } + } + + /* Add the entry to the stat1 table. */ + callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); +#endif + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + + /* Add the entries to the stat4 table. */ +#ifdef SQLITE_ENABLE_STAT4 + if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){ + int regEq = regStat1; + int regLt = regStat1+1; + int regDLt = regStat1+2; + int regSample = regStat1+3; + int regCol = regStat1+4; + int regSampleRowid = regCol + nCol; + int addrNext; + int addrIsNull; + u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + + if( doOnce ){ + int mxCol = nCol; + Index *pX; + + /* Compute the maximum number of columns in any index */ + for(pX=pTab->pIndex; pX; pX=pX->pNext){ + int nColX; /* Number of columns in pX */ + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){ + nColX = pX->nKeyCol; + }else{ + nColX = pX->nColumn; + } + if( nColX>mxCol ) mxCol = nColX; + } + + /* Allocate space to compute results for the largest index */ + sqlite3TouchRegister(pParse, regCol+mxCol); + doOnce = 0; +#ifdef SQLITE_DEBUG + /* Verify that the call to sqlite3ClearTempRegCache() below + ** really is needed. + ** https://sqlite.org/forum/forumpost/83cb4a95a0 (2023-03-25) + */ + testcase( !sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); +#endif + sqlite3ClearTempRegCache(pParse); /* tag-20230325-1 */ + assert( sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); + } + assert( sqlite3NoTempsInRange(pParse, regEq, regCol+nCol) ); + + addrNext = sqlite3VdbeCurrentAddr(v); + callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); + VdbeCoverage(v); + callStatGet(pParse, regStat, STAT_GET_NEQ, regEq); + callStatGet(pParse, regStat, STAT_GET_NLT, regLt); + callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt); + sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); + VdbeCoverage(v); + for(i=0; izName)); + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); +#endif + sqlite3VdbeJumpHere(v, jZeroRows); + } +} + + +/* +** Generate code that will cause the most recent index analysis to +** be loaded into internal hash tables where is can be used. +*/ +static void loadAnalysis(Parse *pParse, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + } +} + +/* +** Generate code that will do an analysis of an entire database +*/ +static void analyzeDatabase(Parse *pParse, int iDb){ + sqlite3 *db = pParse->db; + Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ + HashElem *k; + int iStatCur; + int iMem; + int iTab; + + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + openStatTable(pParse, iDb, iStatCur, 0, 0); + iMem = pParse->nMem+1; + iTab = pParse->nTab; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); +#ifdef SQLITE_ENABLE_STAT4 + iMem = sqlite3FirstAvailableRegister(pParse, iMem); +#else + assert( iMem==sqlite3FirstAvailableRegister(pParse,iMem) ); +#endif + } + loadAnalysis(pParse, iDb); +} + +/* +** Generate code that will do an analysis of a single table in +** a database. If pOnlyIdx is not NULL then it is a single index +** in pTab that should be analyzed. +*/ +static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ + int iDb; + int iStatCur; + + assert( pTab!=0 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + if( pOnlyIdx ){ + openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); + }else{ + openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); + } + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); + loadAnalysis(pParse, iDb); +} + +/* +** Generate code for the ANALYZE command. The parser calls this routine +** when it recognizes an ANALYZE command. +** +** ANALYZE -- 1 +** ANALYZE -- 2 +** ANALYZE ?.? -- 3 +** +** Form 1 causes all indices in all attached databases to be analyzed. +** Form 2 analyzes all indices the single database named. +** Form 3 analyzes all indices associated with the named table. +*/ +SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ + sqlite3 *db = pParse->db; + int iDb; + int i; + char *z, *zDb; + Table *pTab; + Index *pIdx; + Token *pTableName; + Vdbe *v; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + assert( pName2!=0 || pName1==0 ); + if( pName1==0 ){ + /* Form 1: Analyze everything */ + for(i=0; inDb; i++){ + if( i==1 ) continue; /* Do not analyze the TEMP database */ + analyzeDatabase(pParse, i); + } + }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){ + /* Analyze the schema named as the argument */ + analyzeDatabase(pParse, iDb); + }else{ + /* Form 3: Analyze the table or index named as an argument */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); + if( iDb>=0 ){ + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; + z = sqlite3NameFromToken(db, pTableName); + if( z ){ + if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ + analyzeTable(pParse, pTab, 0); + } + sqlite3DbFree(db, z); + } + } + } + if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3VdbeAddOp0(v, OP_Expire); + } +} + +/* +** Used to pass information from the analyzer reader through to the +** callback routine. +*/ +typedef struct analysisInfo analysisInfo; +struct analysisInfo { + sqlite3 *db; + const char *zDatabase; +}; + +/* +** The first argument points to a nul-terminated string containing a +** list of space separated integers. Read the first nOut of these into +** the array aOut[]. +*/ +static void decodeIntArray( + char *zIntArray, /* String containing int array to decode */ + int nOut, /* Number of slots in aOut[] */ + tRowcnt *aOut, /* Store integers here */ + LogEst *aLog, /* Or, if aOut==0, here */ + Index *pIndex /* Handle extra flags for this index, if not NULL */ +){ + char *z = zIntArray; + int c; + int i; + tRowcnt v; + +#ifdef SQLITE_ENABLE_STAT4 + if( z==0 ) z = ""; +#else + assert( z!=0 ); +#endif + for(i=0; *z && i='0' && c<='9' ){ + v = v*10 + c - '0'; + z++; + } +#ifdef SQLITE_ENABLE_STAT4 + if( aOut ) aOut[i] = v; + if( aLog ) aLog[i] = sqlite3LogEst(v); +#else + assert( aOut==0 ); + UNUSED_PARAMETER(aOut); + assert( aLog!=0 ); + aLog[i] = sqlite3LogEst(v); +#endif + if( *z==' ' ) z++; + } +#ifndef SQLITE_ENABLE_STAT4 + assert( pIndex!=0 ); { +#else + if( pIndex ){ +#endif + pIndex->bUnordered = 0; + pIndex->noSkipScan = 0; + while( z[0] ){ + if( sqlite3_strglob("unordered*", z)==0 ){ + pIndex->bUnordered = 1; + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ + int sz = sqlite3Atoi(z+3); + if( sz<2 ) sz = 2; + pIndex->szIdxRow = sqlite3LogEst(sz); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->noSkipScan = 1; + } +#ifdef SQLITE_ENABLE_COSTMULT + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); + } +#endif + while( z[0]!=0 && z[0]!=' ' ) z++; + while( z[0]==' ' ) z++; + } + + /* Set the bLowQual flag if the peak number of rows obtained + ** from a full equality match is so large that a full table scan + ** seems likely to be faster than using the index. + */ + if( aLog[0] > 66 /* Index has more than 100 rows */ + && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ + ){ + pIndex->bLowQual = 1; + } + } +} + +/* +** This callback is invoked once for each index when reading the +** sqlite_stat1 table. +** +** argv[0] = name of the table +** argv[1] = name of the index (might be NULL) +** argv[2] = results of analysis - on integer for each column +** +** Entries for which argv[1]==NULL simply record the number of rows in +** the table. +*/ +static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ + analysisInfo *pInfo = (analysisInfo*)pData; + Index *pIndex; + Table *pTable; + const char *z; + + assert( argc==3 ); + UNUSED_PARAMETER2(NotUsed, argc); + + if( argv==0 || argv[0]==0 || argv[2]==0 ){ + return 0; + } + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); + if( pTable==0 ){ + return 0; + } + if( argv[1]==0 ){ + pIndex = 0; + }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ + pIndex = sqlite3PrimaryKeyIndex(pTable); + }else{ + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); + } + z = argv[2]; + + if( pIndex ){ + tRowcnt *aiRowEst = 0; + int nCol = pIndex->nKeyCol+1; +#ifdef SQLITE_ENABLE_STAT4 + /* Index.aiRowEst may already be set here if there are duplicate + ** sqlite_stat1 entries for this index. In that case just clobber + ** the old data with the new instead of allocating a new array. */ + if( pIndex->aiRowEst==0 ){ + pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); + if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); + } + aiRowEst = pIndex->aiRowEst; +#endif + pIndex->bUnordered = 0; + decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); + pIndex->hasStat1 = 1; + if( pIndex->pPartIdxWhere==0 ){ + pTable->nRowLogEst = pIndex->aiRowLogEst[0]; + pTable->tabFlags |= TF_HasStat1; + } + }else{ + Index fakeIdx; + fakeIdx.szIdxRow = pTable->szTabRow; +#ifdef SQLITE_ENABLE_COSTMULT + fakeIdx.pTable = pTable; +#endif + decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); + pTable->szTabRow = fakeIdx.szIdxRow; + pTable->tabFlags |= TF_HasStat1; + } + + return 0; +} + +/* +** If the Index.aSample variable is not NULL, delete the aSample[] array +** and its contents. +*/ +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ + assert( db!=0 ); + assert( pIdx!=0 ); +#ifdef SQLITE_ENABLE_STAT4 + if( pIdx->aSample ){ + int j; + for(j=0; jnSample; j++){ + IndexSample *p = &pIdx->aSample[j]; + sqlite3DbFree(db, p->p); + } + sqlite3DbFree(db, pIdx->aSample); + } + if( db->pnBytesFreed==0 ){ + pIdx->nSample = 0; + pIdx->aSample = 0; + } +#else + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(pIdx); +#endif /* SQLITE_ENABLE_STAT4 */ +} + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Populate the pIdx->aAvgEq[] array based on the samples currently +** stored in pIdx->aSample[]. +*/ +static void initAvgEq(Index *pIdx){ + if( pIdx ){ + IndexSample *aSample = pIdx->aSample; + IndexSample *pFinal = &aSample[pIdx->nSample-1]; + int iCol; + int nCol = 1; + if( pIdx->nSampleCol>1 ){ + /* If this is stat4 data, then calculate aAvgEq[] values for all + ** sample columns except the last. The last is always set to 1, as + ** once the trailing PK fields are considered all index keys are + ** unique. */ + nCol = pIdx->nSampleCol-1; + pIdx->aAvgEq[nCol] = 1; + } + for(iCol=0; iColnSample; + int i; /* Used to iterate through samples */ + tRowcnt sumEq = 0; /* Sum of the nEq values */ + tRowcnt avgEq = 0; + tRowcnt nRow; /* Number of rows in index */ + i64 nSum100 = 0; /* Number of terms contributing to sumEq */ + i64 nDist100; /* Number of distinct values in index */ + + if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ + nRow = pFinal->anLt[iCol]; + nDist100 = (i64)100 * pFinal->anDLt[iCol]; + nSample--; + }else{ + nRow = pIdx->aiRowEst[0]; + nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; + } + pIdx->nRowEst0 = nRow; + + /* Set nSum to the number of distinct (iCol+1) field prefixes that + ** occur in the stat4 table for this index. Set sumEq to the sum of + ** the nEq values for column iCol for the same set (adding the value + ** only once where there exist duplicate prefixes). */ + for(i=0; inSample-1) + || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] + ){ + sumEq += aSample[i].anEq[iCol]; + nSum100 += 100; + } + } + + if( nDist100>nSum100 && sumEqaAvgEq[iCol] = avgEq; + } + } +} + +/* +** Look up an index by name. Or, if the name of a WITHOUT ROWID table +** is supplied instead, find the PRIMARY KEY index for that table. +*/ +static Index *findIndexOrPrimaryKey( + sqlite3 *db, + const char *zName, + const char *zDb +){ + Index *pIdx = sqlite3FindIndex(db, zName, zDb); + if( pIdx==0 ){ + Table *pTab = sqlite3FindTable(db, zName, zDb); + if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); + } + return pIdx; +} + +/* +** Load the content from either the sqlite_stat4 +** into the relevant Index.aSample[] arrays. +** +** Arguments zSql1 and zSql2 must point to SQL statements that return +** data equivalent to the following: +** +** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx +** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 +** +** where %Q is replaced with the database name before the SQL is executed. +*/ +static int loadStatTbl( + sqlite3 *db, /* Database handle */ + const char *zSql1, /* SQL statement 1 (see above) */ + const char *zSql2, /* SQL statement 2 (see above) */ + const char *zDb /* Database name (e.g. "main") */ +){ + int rc; /* Result codes from subroutines */ + sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ + char *zSql; /* Text of the SQL statement */ + Index *pPrevIdx = 0; /* Previous index in the loop */ + IndexSample *pSample; /* A slot in pIdx->aSample[] */ + + assert( db->lookaside.bDisable ); + zSql = sqlite3MPrintf(db, zSql1, zDb); + if( !zSql ){ + return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + int nIdxCol = 1; /* Number of columns in stat4 records */ + + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + int nByte; /* Bytes of space required */ + int i; /* Bytes of space required */ + tRowcnt *pSpace; + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + nSample = sqlite3_column_int(pStmt, 1); + pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); + assert( pIdx==0 || pIdx->nSample==0 ); + if( pIdx==0 ) continue; + if( pIdx->aSample!=0 ){ + /* The same index appears in sqlite_stat4 under multiple names */ + continue; + } + assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); + if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ + nIdxCol = pIdx->nKeyCol; + }else{ + nIdxCol = pIdx->nColumn; + } + pIdx->nSampleCol = nIdxCol; + pIdx->mxSample = nSample; + nByte = sizeof(IndexSample) * nSample; + nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; + nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ + + pIdx->aSample = sqlite3DbMallocZero(db, nByte); + if( pIdx->aSample==0 ){ + sqlite3_finalize(pStmt); + return SQLITE_NOMEM_BKPT; + } + pSpace = (tRowcnt*)&pIdx->aSample[nSample]; + pIdx->aAvgEq = pSpace; pSpace += nIdxCol; + pIdx->pTable->tabFlags |= TF_HasStat4; + for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol; + pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; + pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; + } + assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); + } + rc = sqlite3_finalize(pStmt); + if( rc ) return rc; + + zSql = sqlite3MPrintf(db, zSql2, zDb); + if( !zSql ){ + return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nCol = 1; /* Number of columns in index */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); + if( pIdx==0 ) continue; + if( pIdx->nSample>=pIdx->mxSample ){ + /* Too many slots used because the same index appears in + ** sqlite_stat4 using multiple names */ + continue; + } + /* This next condition is true if data has already been loaded from + ** the sqlite_stat4 table. */ + nCol = pIdx->nSampleCol; + if( pIdx!=pPrevIdx ){ + initAvgEq(pPrevIdx); + pPrevIdx = pIdx; + } + pSample = &pIdx->aSample[pIdx->nSample]; + decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); + + /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. + ** This is in case the sample record is corrupted. In that case, the + ** sqlite3VdbeRecordCompare() may read up to two varints past the + ** end of the allocated buffer before it realizes it is dealing with + ** a corrupt record. Or it might try to read a large integer from the + ** buffer. In any case, eight 0x00 bytes prevents this from causing + ** a buffer overread. */ + pSample->n = sqlite3_column_bytes(pStmt, 4); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 8); + if( pSample->p==0 ){ + sqlite3_finalize(pStmt); + return SQLITE_NOMEM_BKPT; + } + if( pSample->n ){ + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); + } + pIdx->nSample++; + } + rc = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); + return rc; +} + +/* +** Load content from the sqlite_stat4 table into +** the Index.aSample[] arrays of all indices. +*/ +static int loadStat4(sqlite3 *db, const char *zDb){ + int rc = SQLITE_OK; /* Result codes from subroutines */ + const Table *pStat4; + + assert( db->lookaside.bDisable ); + if( OptimizationEnabled(db, SQLITE_Stat4) + && (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 + && IsOrdinaryTable(pStat4) + ){ + rc = loadStatTbl(db, + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx COLLATE nocase", + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", + zDb + ); + } + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The +** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] +** arrays. The contents of sqlite_stat4 are used to populate the +** Index.aSample[] arrays. +** +** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR +** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined +** during compilation and the sqlite_stat4 table is present, no data is +** read from it. +** +** If SQLITE_ENABLE_STAT4 was defined during compilation and the +** sqlite_stat4 table is not present in the database, SQLITE_ERROR is +** returned. However, in this case, data is read from the sqlite_stat1 +** table (if it is present) before returning. +** +** If an OOM error occurs, this function always sets db->mallocFailed. +** This means if the caller does not care about other errors, the return +** code may be ignored. +*/ +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ + analysisInfo sInfo; + HashElem *i; + char *zSql; + int rc = SQLITE_OK; + Schema *pSchema = db->aDb[iDb].pSchema; + const Table *pStat1; + + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + + /* Clear any prior statistics */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + pTab->tabFlags &= ~TF_HasStat1; + } + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + pIdx->hasStat1 = 0; +#ifdef SQLITE_ENABLE_STAT4 + sqlite3DeleteIndexSamples(db, pIdx); + pIdx->aSample = 0; +#endif + } + + /* Load new statistics out of the sqlite_stat1 table */ + sInfo.db = db; + sInfo.zDatabase = db->aDb[iDb].zDbSName; + if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)) + && IsOrdinaryTable(pStat1) + ){ + zSql = sqlite3MPrintf(db, + "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + if( zSql==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3DbFree(db, zSql); + } + } + + /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); + } + + /* Load the statistics from the sqlite_stat4 table. */ +#ifdef SQLITE_ENABLE_STAT4 + if( rc==SQLITE_OK ){ + DisableLookaside; + rc = loadStat4(db, sInfo.zDatabase); + EnableLookaside; + } + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + sqlite3_free(pIdx->aiRowEst); + pIdx->aiRowEst = 0; + } +#endif + + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } + return rc; +} + + +#endif /* SQLITE_OMIT_ANALYZE */ + +/************** End of analyze.c *********************************************/ +/************** Begin file attach.c ******************************************/ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the ATTACH and DETACH commands. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_ATTACH +/* +** Resolve an expression that was part of an ATTACH or DETACH statement. This +** is slightly different from resolving a normal SQL expression, because simple +** identifiers are treated as strings, not possible column names or aliases. +** +** i.e. if the parser sees: +** +** ATTACH DATABASE abc AS def +** +** it treats the two expressions as literal strings 'abc' and 'def' instead of +** looking for columns of the same name. +** +** This only applies to the root node of pExpr, so the statement: +** +** ATTACH DATABASE abc||def AS 'db2' +** +** will fail because neither abc or def can be resolved. +*/ +static int resolveAttachExpr(NameContext *pName, Expr *pExpr) +{ + int rc = SQLITE_OK; + if( pExpr ){ + if( pExpr->op!=TK_ID ){ + rc = sqlite3ResolveExprNames(pName, pExpr); + }else{ + pExpr->op = TK_STRING; + } + } + return rc; +} + +/* +** Return true if zName points to a name that may be used to refer to +** database iDb attached to handle db. +*/ +SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){ + return ( + sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0 + || (iDb==0 && sqlite3StrICmp("main", zName)==0) + ); +} + +/* +** An SQL user-function registered to do the work of an ATTACH statement. The +** three arguments to the function come directly from an attach statement: +** +** ATTACH DATABASE x AS y KEY z +** +** SELECT sqlite_attach(x, y, z) +** +** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the +** third argument. +** +** If the db->init.reopenMemdb flags is set, then instead of attaching a +** new database, close the database on db->init.iDb and reopen it as an +** empty MemDB. +*/ +static void attachFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + int i; + int rc = 0; + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName; + const char *zFile; + char *zPath = 0; + char *zErr = 0; + unsigned int flags; + Db *aNew; /* New array of Db pointers */ + Db *pNew = 0; /* Db object for the newly attached database */ + char *zErrDyn = 0; + sqlite3_vfs *pVfs; + + UNUSED_PARAMETER(NotUsed); + zFile = (const char *)sqlite3_value_text(argv[0]); + zName = (const char *)sqlite3_value_text(argv[1]); + if( zFile==0 ) zFile = ""; + if( zName==0 ) zName = ""; + +#ifndef SQLITE_OMIT_DESERIALIZE +# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb) +#else +# define REOPEN_AS_MEMDB(db) (0) +#endif + + if( REOPEN_AS_MEMDB(db) ){ + /* This is not a real ATTACH. Instead, this routine is being called + ** from sqlite3_deserialize() to close database db->init.iDb and + ** reopen it as a MemDB */ + Btree *pNewBt = 0; + pVfs = sqlite3_vfs_find("memdb"); + if( pVfs==0 ) return; + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); + if( rc==SQLITE_OK ){ + Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt); + if( pNewSchema ){ + /* Both the Btree and the new Schema were allocated successfully. + ** Close the old db and update the aDb[] slot with the new memdb + ** values. */ + pNew = &db->aDb[db->init.iDb]; + if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt); + pNew->pBt = pNewBt; + pNew->pSchema = pNewSchema; + }else{ + sqlite3BtreeClose(pNewBt); + rc = SQLITE_NOMEM; + } + } + if( rc ) goto attach_error; + }else{ + /* This is a real ATTACH + ** + ** Check for the following errors: + ** + ** * Too many attached databases, + ** * Transaction currently open + ** * Specified database name already being used. + */ + if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", + db->aLimit[SQLITE_LIMIT_ATTACHED] + ); + goto attach_error; + } + for(i=0; inDb; i++){ + assert( zName ); + if( sqlite3DbIsNamed(db, i, zName) ){ + zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); + goto attach_error; + } + } + + /* Allocate the new entry in the db->aDb[] array and initialize the schema + ** hash tables. + */ + if( db->aDb==db->aDbStatic ){ + aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); + }else{ + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); + if( aNew==0 ) return; + } + db->aDb = aNew; + pNew = &db->aDb[db->nDb]; + memset(pNew, 0, sizeof(*pNew)); + + /* Open the database file. If the btree is successfully opened, use + ** it to obtain the database schema. At this point the schema may + ** or may not be initialized. + */ + flags = db->openFlags; + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + assert( pVfs ); + flags |= SQLITE_OPEN_MAIN_DB; + rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); + db->nDb++; + pNew->zDbSName = sqlite3DbStrDup(db, zName); + } + db->noSharedCache = 0; + if( rc==SQLITE_CONSTRAINT ){ + rc = SQLITE_ERROR; + zErrDyn = sqlite3MPrintf(db, "database is already attached"); + }else if( rc==SQLITE_OK ){ + Pager *pPager; + pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt); + if( !pNew->pSchema ){ + rc = SQLITE_NOMEM_BKPT; + }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){ + zErrDyn = sqlite3MPrintf(db, + "attached databases must use the same text encoding as main database"); + rc = SQLITE_ERROR; + } + sqlite3BtreeEnter(pNew->pBt); + pPager = sqlite3BtreePager(pNew->pBt); + sqlite3PagerLockingMode(pPager, db->dfltLockMode); + sqlite3BtreeSecureDelete(pNew->pBt, + sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + sqlite3BtreeSetPagerFlags(pNew->pBt, + PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); +#endif + sqlite3BtreeLeave(pNew->pBt); + } + pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; + if( rc==SQLITE_OK && pNew->zDbSName==0 ){ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3_free_filename( zPath ); + + /* If the file was opened successfully, read the schema for the new database. + ** If this fails, or if opening the file failed, then close the file and + ** remove the entry from the db->aDb[] array. i.e. put everything back the + ** way we found it. + */ + if( rc==SQLITE_OK ){ + sqlite3BtreeEnterAll(db); + db->init.iDb = 0; + db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); + if( !REOPEN_AS_MEMDB(db) ){ + rc = sqlite3Init(db, &zErrDyn); + } + sqlite3BtreeLeaveAll(db); + assert( zErrDyn==0 || rc!=SQLITE_OK ); + } +#ifdef SQLITE_USER_AUTHENTICATION + if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ + u8 newAuth = 0; + rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); + if( newAuthauth.authLevel ){ + rc = SQLITE_AUTH_USER; + } + } +#endif + if( rc ){ + if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ + int iDb = db->nDb - 1; + assert( iDb>=2 ); + if( db->aDb[iDb].pBt ){ + sqlite3BtreeClose(db->aDb[iDb].pBt); + db->aDb[iDb].pBt = 0; + db->aDb[iDb].pSchema = 0; + } + sqlite3ResetAllSchemasOfConnection(db); + db->nDb = iDb; + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + sqlite3DbFree(db, zErrDyn); + zErrDyn = sqlite3MPrintf(db, "out of memory"); + }else if( zErrDyn==0 ){ + zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); + } + } + goto attach_error; + } + + return; + +attach_error: + /* Return an error if we get here */ + if( zErrDyn ){ + sqlite3_result_error(context, zErrDyn, -1); + sqlite3DbFree(db, zErrDyn); + } + if( rc ) sqlite3_result_error_code(context, rc); +} + +/* +** An SQL user-function registered to do the work of an DETACH statement. The +** three arguments to the function come directly from a detach statement: +** +** DETACH DATABASE x +** +** SELECT sqlite_detach(x) +*/ +static void detachFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + const char *zName = (const char *)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + int i; + Db *pDb = 0; + HashElem *pEntry; + char zErr[128]; + + UNUSED_PARAMETER(NotUsed); + + if( zName==0 ) zName = ""; + for(i=0; inDb; i++){ + pDb = &db->aDb[i]; + if( pDb->pBt==0 ) continue; + if( sqlite3DbIsNamed(db, i, zName) ) break; + } + + if( i>=db->nDb ){ + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); + goto detach_error; + } + if( i<2 ){ + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); + goto detach_error; + } + if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pDb->pBt) + ){ + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); + goto detach_error; + } + + /* If any TEMP triggers reference the schema being detached, move those + ** triggers to reference the TEMP schema itself. */ + assert( db->aDb[1].pSchema ); + pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash); + while( pEntry ){ + Trigger *pTrig = (Trigger*)sqliteHashData(pEntry); + if( pTrig->pTabSchema==pDb->pSchema ){ + pTrig->pTabSchema = pTrig->pSchema; + } + pEntry = sqliteHashNext(pEntry); + } + + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + sqlite3CollapseDatabaseArray(db); + return; + +detach_error: + sqlite3_result_error(context, zErr, -1); +} + +/* +** This procedure generates VDBE code for a single invocation of either the +** sqlite_detach() or sqlite_attach() SQL user functions. +*/ +static void codeAttach( + Parse *pParse, /* The parser context */ + int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ + FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ + Expr *pAuthArg, /* Expression to pass to authorization callback */ + Expr *pFilename, /* Name of database file */ + Expr *pDbname, /* Name of the database to use internally */ + Expr *pKey /* Database key for encryption extension */ +){ + int rc; + NameContext sName; + Vdbe *v; + sqlite3* db = pParse->db; + int regArgs; + + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end; + + if( pParse->nErr ) goto attach_end; + memset(&sName, 0, sizeof(NameContext)); + sName.pParse = pParse; + + if( + SQLITE_OK!=resolveAttachExpr(&sName, pFilename) || + SQLITE_OK!=resolveAttachExpr(&sName, pDbname) || + SQLITE_OK!=resolveAttachExpr(&sName, pKey) + ){ + goto attach_end; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( ALWAYS(pAuthArg) ){ + char *zAuthArg; + if( pAuthArg->op==TK_STRING ){ + assert( !ExprHasProperty(pAuthArg, EP_IntValue) ); + zAuthArg = pAuthArg->u.zToken; + }else{ + zAuthArg = 0; + } + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); + if(rc!=SQLITE_OK ){ + goto attach_end; + } + } +#endif /* SQLITE_OMIT_AUTHORIZATION */ + + + v = sqlite3GetVdbe(pParse); + regArgs = sqlite3GetTempRange(pParse, 4); + sqlite3ExprCode(pParse, pFilename, regArgs); + sqlite3ExprCode(pParse, pDbname, regArgs+1); + sqlite3ExprCode(pParse, pKey, regArgs+2); + + assert( v || db->mallocFailed ); + if( v ){ + sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3, + pFunc->nArg, pFunc, 0); + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this + ** statement only). For DETACH, set it to false (expire all existing + ** statements). + */ + sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); + } + +attach_end: + sqlite3ExprDelete(db, pFilename); + sqlite3ExprDelete(db, pDbname); + sqlite3ExprDelete(db, pKey); +} + +/* +** Called by the parser to compile a DETACH statement. +** +** DETACH pDbname +*/ +SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ + static const FuncDef detach_func = { + 1, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + detachFunc, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "sqlite_detach", /* zName */ + {0} + }; + codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); +} + +/* +** Called by the parser to compile an ATTACH statement. +** +** ATTACH p AS pDbname KEY pKey +*/ +SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ + static const FuncDef attach_func = { + 3, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + attachFunc, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "sqlite_attach", /* zName */ + {0} + }; + codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); +} +#endif /* SQLITE_OMIT_ATTACH */ + +/* +** Expression callback used by sqlite3FixAAAA() routines. +*/ +static int fixExprCb(Walker *p, Expr *pExpr){ + DbFixer *pFix = p->u.pFix; + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** Select callback used by sqlite3FixAAAA() routines. +*/ +static int fixSelectCb(Walker *p, Select *pSelect){ + DbFixer *pFix = p->u.pFix; + int i; + SrcItem *pItem; + sqlite3 *db = pFix->pParse->db; + int iDb = sqlite3FindDbName(db, pFix->zDb); + SrcList *pList = pSelect->pSrc; + + if( NEVER(pList==0) ) return WRC_Continue; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pFix->bTemp==0 ){ + if( pItem->zDatabase ){ + if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return WRC_Abort; + } + sqlite3DbFree(db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->fg.notCte = 1; + } + pItem->pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( pList->a[i].fg.isUsing==0 + && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn) + ){ + return WRC_Abort; + } +#endif + } + if( pSelect->pWith ){ + for(i=0; ipWith->nCte; i++){ + if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + +/* +** Initialize a DbFixer structure. This routine must be called prior +** to passing the structure to one of the sqliteFixAAAA() routines below. +*/ +SQLITE_PRIVATE void sqlite3FixInit( + DbFixer *pFix, /* The fixer to be initialized */ + Parse *pParse, /* Error messages will be written here */ + int iDb, /* This is the database that must be used */ + const char *zType, /* "view", "trigger", or "index" */ + const Token *pName /* Name of the view, trigger, or index */ +){ + sqlite3 *db = pParse->db; + assert( db->nDb>iDb ); + pFix->pParse = pParse; + pFix->zDb = db->aDb[iDb].zDbSName; + pFix->pSchema = db->aDb[iDb].pSchema; + pFix->zType = zType; + pFix->pName = pName; + pFix->bTemp = (iDb==1); + pFix->w.pParse = pParse; + pFix->w.xExprCallback = fixExprCb; + pFix->w.xSelectCallback = fixSelectCb; + pFix->w.xSelectCallback2 = sqlite3WalkWinDefnDummyCallback; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; +} + +/* +** The following set of routines walk through the parse tree and assign +** a specific database to all table references where the database name +** was left unspecified in the original SQL statement. The pFix structure +** must have been initialized by a prior call to sqlite3FixInit(). +** +** These routines are used to make sure that an index, trigger, or +** view in one database does not refer to objects in a different database. +** (Exception: indices, triggers, and views in the TEMP database are +** allowed to refer to anything.) If a reference is explicitly made +** to an object in a different database, an error message is added to +** pParse->zErrMsg and these routines return non-zero. If everything +** checks out, these routines return 0. +*/ +SQLITE_PRIVATE int sqlite3FixSrcList( + DbFixer *pFix, /* Context of the fixation */ + SrcList *pList /* The Source list to check and modify */ +){ + int res = 0; + if( pList ){ + Select s; + memset(&s, 0, sizeof(s)); + s.pSrc = pList; + res = sqlite3WalkSelect(&pFix->w, &s); + } + return res; +} +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE int sqlite3FixSelect( + DbFixer *pFix, /* Context of the fixation */ + Select *pSelect /* The SELECT statement to be fixed to one database */ +){ + return sqlite3WalkSelect(&pFix->w, pSelect); +} +SQLITE_PRIVATE int sqlite3FixExpr( + DbFixer *pFix, /* Context of the fixation */ + Expr *pExpr /* The expression to be fixed to one database */ +){ + return sqlite3WalkExpr(&pFix->w, pExpr); +} +#endif + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE int sqlite3FixTriggerStep( + DbFixer *pFix, /* Context of the fixation */ + TriggerStep *pStep /* The trigger step be fixed to one database */ +){ + while( pStep ){ + if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) + || sqlite3WalkExpr(&pFix->w, pStep->pWhere) + || sqlite3WalkExprList(&pFix->w, pStep->pExprList) + || sqlite3FixSrcList(pFix, pStep->pFrom) + ){ + return 1; + } +#ifndef SQLITE_OMIT_UPSERT + { + Upsert *pUp; + for(pUp=pStep->pUpsert; pUp; pUp=pUp->pNextUpsert){ + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) + ){ + return 1; + } + } + } +#endif + pStep = pStep->pNext; + } + + return 0; +} +#endif + +/************** End of attach.c **********************************************/ +/************** Begin file auth.c ********************************************/ +/* +** 2003 January 11 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the sqlite3_set_authorizer() +** API. This facility is an optional feature of the library. Embedded +** systems that do not need this facility may omit it by recompiling +** the library with -DSQLITE_OMIT_AUTHORIZATION=1 +*/ +/* #include "sqliteInt.h" */ + +/* +** All of the code in this file may be omitted by defining a single +** macro. +*/ +#ifndef SQLITE_OMIT_AUTHORIZATION + +/* +** Set or clear the access authorization function. +** +** The access authorization function is be called during the compilation +** phase to verify that the user has read and/or write access permission on +** various fields of the database. The first argument to the auth function +** is a copy of the 3rd argument to this routine. The second argument +** to the auth function is one of these constants: +** +** SQLITE_CREATE_INDEX +** SQLITE_CREATE_TABLE +** SQLITE_CREATE_TEMP_INDEX +** SQLITE_CREATE_TEMP_TABLE +** SQLITE_CREATE_TEMP_TRIGGER +** SQLITE_CREATE_TEMP_VIEW +** SQLITE_CREATE_TRIGGER +** SQLITE_CREATE_VIEW +** SQLITE_DELETE +** SQLITE_DROP_INDEX +** SQLITE_DROP_TABLE +** SQLITE_DROP_TEMP_INDEX +** SQLITE_DROP_TEMP_TABLE +** SQLITE_DROP_TEMP_TRIGGER +** SQLITE_DROP_TEMP_VIEW +** SQLITE_DROP_TRIGGER +** SQLITE_DROP_VIEW +** SQLITE_INSERT +** SQLITE_PRAGMA +** SQLITE_READ +** SQLITE_SELECT +** SQLITE_TRANSACTION +** SQLITE_UPDATE +** +** The third and fourth arguments to the auth function are the name of +** the table and the column that are being accessed. The auth function +** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If +** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY +** means that the SQL statement will never-run - the sqlite3_exec() call +** will return with an error. SQLITE_IGNORE means that the SQL statement +** should run but attempts to read the specified column will return NULL +** and attempts to write the column will be ignored. +** +** Setting the auth function to NULL disables this hook. The default +** setting of the auth function is NULL. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3 *db, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xAuth = (sqlite3_xauth)xAuth; + db->pAuthArg = pArg; + if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Write an error message into pParse->zErrMsg that explains that the +** user-supplied authorization function returned an illegal value. +*/ +static void sqliteAuthBadReturnCode(Parse *pParse){ + sqlite3ErrorMsg(pParse, "authorizer malfunction"); + pParse->rc = SQLITE_ERROR; +} + +/* +** Invoke the authorization callback for permission to read column zCol from +** table zTab in database zDb. This function assumes that an authorization +** callback has been registered (i.e. that sqlite3.xAuth is not NULL). +** +** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed +** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE +** is treated as SQLITE_DENY. In this case an error is left in pParse. +*/ +SQLITE_PRIVATE int sqlite3AuthReadCol( + Parse *pParse, /* The parser context */ + const char *zTab, /* Table name */ + const char *zCol, /* Column name */ + int iDb /* Index of containing database. */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */ + int rc; /* Auth callback return code */ + + if( db->init.busy ) return SQLITE_OK; + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext +#ifdef SQLITE_USER_AUTHENTICATION + ,db->auth.zAuthUser +#endif + ); + if( rc==SQLITE_DENY ){ + char *z = sqlite3_mprintf("%s.%s", zTab, zCol); + if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); + sqlite3ErrorMsg(pParse, "access to %z is prohibited", z); + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** The pExpr should be a TK_COLUMN expression. The table referred to +** is in pTabList or else it is the NEW or OLD table of a trigger. +** Check to see if it is OK to read this particular column. +** +** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN +** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, +** then generate an error. +*/ +SQLITE_PRIVATE void sqlite3AuthRead( + Parse *pParse, /* The parser context */ + Expr *pExpr, /* The expression to check authorization on */ + Schema *pSchema, /* The schema of the expression */ + SrcList *pTabList /* All table that pExpr might refer to */ +){ + Table *pTab = 0; /* The table being read */ + const char *zCol; /* Name of the column of the table */ + int iSrc; /* Index in pTabList->a[] of table being read */ + int iDb; /* The index of the database the expression refers to */ + int iCol; /* Index of column in table */ + + assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + assert( !IN_RENAME_OBJECT ); + assert( pParse->db->xAuth!=0 ); + iDb = sqlite3SchemaToIndex(pParse->db, pSchema); + if( iDb<0 ){ + /* An attempt to read a column out of a subquery or other + ** temporary table. */ + return; + } + + if( pExpr->op==TK_TRIGGER ){ + pTab = pParse->pTriggerTab; + }else{ + assert( pTabList ); + for(iSrc=0; iSrcnSrc; iSrc++){ + if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ + pTab = pTabList->a[iSrc].pTab; + break; + } + } + } + iCol = pExpr->iColumn; + if( pTab==0 ) return; + + if( iCol>=0 ){ + assert( iColnCol ); + zCol = pTab->aCol[iCol].zCnName; + }else if( pTab->iPKey>=0 ){ + assert( pTab->iPKeynCol ); + zCol = pTab->aCol[pTab->iPKey].zCnName; + }else{ + zCol = "ROWID"; + } + assert( iDb>=0 && iDbdb->nDb ); + if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ + pExpr->op = TK_NULL; + } +} + +/* +** Do an authorization check using the code and arguments given. Return +** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY +** is returned, then the error count and error message in pParse are +** modified appropriately. +*/ +SQLITE_PRIVATE int sqlite3AuthCheck( + Parse *pParse, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3 +){ + sqlite3 *db = pParse->db; + int rc; + + /* Don't do any authorization checks if the database is initializing + ** or if the parser is being invoked from within sqlite3_declare_vtab. + */ + assert( !IN_RENAME_OBJECT || db->xAuth==0 ); + if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){ + return SQLITE_OK; + } + + /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the + ** callback are either NULL pointers or zero-terminated strings that + ** contain additional details about the action to be authorized. + ** + ** The following testcase() macros show that any of the 3rd through 6th + ** parameters can be either NULL or a string. */ + testcase( zArg1==0 ); + testcase( zArg2==0 ); + testcase( zArg3==0 ); + testcase( pParse->zAuthContext==0 ); + + rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext +#ifdef SQLITE_USER_AUTHENTICATION + ,db->auth.zAuthUser +#endif + ); + if( rc==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized"); + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ + rc = SQLITE_DENY; + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** Push an authorization context. After this routine is called, the +** zArg3 argument to authorization callbacks will be zContext until +** popped. Or if pParse==0, this routine is a no-op. +*/ +SQLITE_PRIVATE void sqlite3AuthContextPush( + Parse *pParse, + AuthContext *pContext, + const char *zContext +){ + assert( pParse ); + pContext->pParse = pParse; + pContext->zAuthContext = pParse->zAuthContext; + pParse->zAuthContext = zContext; +} + +/* +** Pop an authorization context that was previously pushed +** by sqlite3AuthContextPush +*/ +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ + if( pContext->pParse ){ + pContext->pParse->zAuthContext = pContext->zAuthContext; + pContext->pParse = 0; + } +} + +#endif /* SQLITE_OMIT_AUTHORIZATION */ + +/************** End of auth.c ************************************************/ +/************** Begin file build.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the SQLite parser +** when syntax rules are reduced. The routines in this file handle the +** following kinds of SQL syntax: +** +** CREATE TABLE +** DROP TABLE +** CREATE INDEX +** DROP INDEX +** creating ID lists +** BEGIN TRANSACTION +** COMMIT +** ROLLBACK +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** The TableLock structure is only used by the sqlite3TableLock() and +** codeTableLocks() functions. +*/ +struct TableLock { + int iDb; /* The database containing the table to be locked */ + Pgno iTab; /* The root page of the table to be locked */ + u8 isWriteLock; /* True for write lock. False for a read lock */ + const char *zLockName; /* Name of the table */ +}; + +/* +** Record the fact that we want to lock a table at run-time. +** +** The table to be locked has root page iTab and is found in database iDb. +** A read or a write lock can be taken depending on isWritelock. +** +** This routine just records the fact that the lock is desired. The +** code to make the lock occur is generated by a later call to +** codeTableLocks() which occurs during sqlite3FinishCoding(). +*/ +static SQLITE_NOINLINE void lockTable( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + Pgno iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + Parse *pToplevel; + int i; + int nBytes; + TableLock *p; + assert( iDb>=0 ); + + pToplevel = sqlite3ParseToplevel(pParse); + for(i=0; inTableLock; i++){ + p = &pToplevel->aTableLock[i]; + if( p->iDb==iDb && p->iTab==iTab ){ + p->isWriteLock = (p->isWriteLock || isWriteLock); + return; + } + } + + nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); + pToplevel->aTableLock = + sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); + if( pToplevel->aTableLock ){ + p = &pToplevel->aTableLock[pToplevel->nTableLock++]; + p->iDb = iDb; + p->iTab = iTab; + p->isWriteLock = isWriteLock; + p->zLockName = zName; + }else{ + pToplevel->nTableLock = 0; + sqlite3OomFault(pToplevel->db); + } +} +SQLITE_PRIVATE void sqlite3TableLock( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + Pgno iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + if( iDb==1 ) return; + if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; + lockTable(pParse, iDb, iTab, isWriteLock, zName); +} + +/* +** Code an OP_TableLock instruction for each table locked by the +** statement (configured by calls to sqlite3TableLock()). +*/ +static void codeTableLocks(Parse *pParse){ + int i; + Vdbe *pVdbe = pParse->pVdbe; + assert( pVdbe!=0 ); + + for(i=0; inTableLock; i++){ + TableLock *p = &pParse->aTableLock[i]; + int p1 = p->iDb; + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, + p->zLockName, P4_STATIC); + } +} +#else + #define codeTableLocks(x) +#endif + +/* +** Return TRUE if the given yDbMask object is empty - if it contains no +** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() +** macros when SQLITE_MAX_ATTACHED is greater than 30. +*/ +#if SQLITE_MAX_ATTACHED>30 +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ + int i; + for(i=0; ipToplevel==0 ); + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nested ) return; + if( pParse->nErr ){ + if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM; + return; + } + assert( db->mallocFailed==0 ); + + /* Begin by generating some termination code at the end of the + ** vdbe program + */ + v = pParse->pVdbe; + if( v==0 ){ + if( db->init.busy ){ + pParse->rc = SQLITE_DONE; + return; + } + v = sqlite3GetVdbe(pParse); + if( v==0 ) pParse->rc = SQLITE_ERROR; + } + assert( !pParse->isMultiWrite + || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); + if( v ){ + if( pParse->bReturning ){ + Returning *pReturning = pParse->u1.pReturning; + int addrRewind; + int reg; + + if( pReturning->nRetCol ){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; inRetCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); + sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrRewind); + } + } + sqlite3VdbeAddOp0(v, OP_Halt); + +#if SQLITE_USER_AUTHENTICATION + if( pParse->nTableLock>0 && db->init.busy==0 ){ + sqlite3UserAuthInit(db); + if( db->auth.authLevelrc = SQLITE_AUTH_USER; + return; + } + } +#endif + + /* The cookie mask contains one bit for each database file open. + ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are + ** set for each database that is used. Generate code to start a + ** transaction on each used database and to verify the schema cookie + ** on each used database. + */ + assert( pParse->nErr>0 || sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); + assert( db->nDb>0 ); + iDb = 0; + do{ + Schema *pSchema; + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; + sqlite3VdbeUsesBtree(v, iDb); + pSchema = db->aDb[iDb].pSchema; + sqlite3VdbeAddOp4Int(v, + OP_Transaction, /* Opcode */ + iDb, /* P1 */ + DbMaskTest(pParse->writeMask,iDb), /* P2 */ + pSchema->schema_cookie, /* P3 */ + pSchema->iGeneration /* P4 */ + ); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); + VdbeComment((v, + "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); + }while( ++iDbnDb ); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + } + pParse->nVtabLock = 0; +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE + /* Once all the cookies have been verified and transactions opened, + ** obtain the required table-locks. This is a no-op unless the + ** shared-cache feature is enabled. + */ + if( pParse->nTableLock ) codeTableLocks(pParse); +#endif + + /* Initialize any AUTOINCREMENT data structures required. + */ + if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); + + /* Code constant expressions that were factored out of inner loops. + */ + if( pParse->pConstExpr ){ + ExprList *pEL = pParse->pConstExpr; + pParse->okConstFactor = 0; + for(i=0; inExpr; i++){ + assert( pEL->a[i].u.iConstExprReg>0 ); + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); + } + } + + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + if( pRet->nRetCol ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } + } + + /* Finally, jump back to the beginning of the executable code. */ + sqlite3VdbeGoto(v, 1); + } + + /* Get the VDBE program ready for execution + */ + assert( v!=0 || pParse->nErr ); + assert( db->mallocFailed==0 || pParse->nErr ); + if( pParse->nErr==0 ){ + /* A minimum of one cursor is required if autoincrement is used + * See ticket [a696379c1f08866] */ + assert( pParse->pAinc==0 || pParse->nTab>0 ); + sqlite3VdbeMakeReady(v, pParse); + pParse->rc = SQLITE_DONE; + }else{ + pParse->rc = SQLITE_ERROR; + } +} + +/* +** Run the parser and code generator recursively in order to generate +** code for the SQL statement given onto the end of the pParse context +** currently under construction. Notes: +** +** * The final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** * Built-in SQL functions always take precedence over application-defined +** SQL functions. In other words, it is not possible to override a +** built-in function. +*/ +SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ + va_list ap; + char *zSql; + sqlite3 *db = pParse->db; + u32 savedDbFlags = db->mDbFlags; + char saveBuf[PARSE_TAIL_SZ]; + + if( pParse->nErr ) return; + if( pParse->eParseMode ) return; + assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ + va_start(ap, zFormat); + zSql = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + if( zSql==0 ){ + /* This can result either from an OOM or because the formatted string + ** exceeds SQLITE_LIMIT_LENGTH. In the latter case, we need to set + ** an error */ + if( !db->mallocFailed ) pParse->rc = SQLITE_TOOBIG; + pParse->nErr++; + return; + } + pParse->nested++; + memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); + db->mDbFlags |= DBFLAG_PreferBuiltin; + sqlite3RunParser(pParse, zSql); + db->mDbFlags = savedDbFlags; + sqlite3DbFree(db, zSql); + memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); + pParse->nested--; +} + +#if SQLITE_USER_AUTHENTICATION +/* +** Return TRUE if zTable is the name of the system table that stores the +** list of users and their access credentials. +*/ +SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ + return sqlite3_stricmp(zTable, "sqlite_user")==0; +} +#endif + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the table and the +** first matching table is returned. (No checking for duplicate table +** names is done.) The search order is TEMP first, then MAIN, then any +** auxiliary databases added using the ATTACH command. +** +** See also sqlite3LocateTable(). +*/ +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ + Table *p = 0; + int i; + + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); +#if SQLITE_USER_AUTHENTICATION + /* Only the admin user is allowed to know that the sqlite_user table + ** exists */ + if( db->auth.authLevelnDb; i++){ + if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break; + } + if( i>=db->nDb ){ + /* No match against the official names. But always match "main" + ** to schema 0 as a legacy fallback. */ + if( sqlite3StrICmp(zDatabase,"main")==0 ){ + i = 0; + }else{ + return 0; + } + } + p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); + if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( i==1 ){ + if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 + || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 + || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 + ){ + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, + LEGACY_TEMP_SCHEMA_TABLE); + } + }else{ + if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, + LEGACY_SCHEMA_TABLE); + } + } + } + }else{ + /* Match against TEMP first */ + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName); + if( p ) return p; + /* The main database is second */ + p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName); + if( p ) return p; + /* Attached databases are in order of attachment */ + for(i=2; inDb; i++){ + assert( sqlite3SchemaMutexHeld(db, i, 0) ); + p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); + if( p ) break; + } + if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE); + }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, + LEGACY_TEMP_SCHEMA_TABLE); + } + } + } + return p; +} + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. Also leave an +** error message in pParse->zErrMsg. +** +** The difference between this routine and sqlite3FindTable() is that this +** routine leaves an error message in pParse->zErrMsg where +** sqlite3FindTable() does not. +*/ +SQLITE_PRIVATE Table *sqlite3LocateTable( + Parse *pParse, /* context in which to report errors */ + u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */ + const char *zName, /* Name of the table we are looking for */ + const char *zDbase /* Name of the database. Might be NULL */ +){ + Table *p; + sqlite3 *db = pParse->db; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 + && SQLITE_OK!=sqlite3ReadSchema(pParse) + ){ + return 0; + } + + p = sqlite3FindTable(db, zName, zDbase); + if( p==0 ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* If zName is the not the name of a table in the schema created using + ** CREATE, then check to see if it is the name of an virtual table that + ** can be an eponymous virtual table. */ + if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){ + Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(db, zName); + } + if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + testcase( pMod->pEpoTab==0 ); + return pMod->pEpoTab; + } + } +#endif + if( flags & LOCATE_NOERR ) return 0; + pParse->checkSchema = 1; + }else if( IsVirtual(p) && (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)!=0 ){ + p = 0; + } + + if( p==0 ){ + const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; + if( zDbase ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + } + }else{ + assert( HasRowid(p) || p->iPKey<0 ); + } + + return p; +} + +/* +** Locate the table identified by *p. +** +** This is a wrapper around sqlite3LocateTable(). The difference between +** sqlite3LocateTable() and this function is that this function restricts +** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be +** non-NULL if it is part of a view or trigger program definition. See +** sqlite3FixSrcList() for details. +*/ +SQLITE_PRIVATE Table *sqlite3LocateTableItem( + Parse *pParse, + u32 flags, + SrcItem *p +){ + const char *zDb; + assert( p->pSchema==0 || p->zDatabase==0 ); + if( p->pSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + zDb = pParse->db->aDb[iDb].zDbSName; + }else{ + zDb = p->zDatabase; + } + return sqlite3LocateTable(pParse, flags, p->zName, zDb); +} + +/* +** Return the preferred table name for system tables. Translate legacy +** names into the new preferred names, as appropriate. +*/ +SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){ + if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){ + return PREFERRED_SCHEMA_TABLE; + } + if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ + return PREFERRED_TEMP_SCHEMA_TABLE; + } + } + return zName; +} + +/* +** Locate the in-memory structure that describes +** a particular index given the name of that index +** and the name of the database that contains the index. +** Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the +** table and the first matching index is returned. (No checking +** for duplicate index names is done.) The search order is +** TEMP first, then MAIN, then any auxiliary databases added +** using the ATTACH command. +*/ +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ + Index *p = 0; + int i; + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + Schema *pSchema = db->aDb[j].pSchema; + assert( pSchema ); + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&pSchema->idxHash, zName); + if( p ) break; + } + return p; +} + +/* +** Reclaim the memory used by an index +*/ +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){ +#ifndef SQLITE_OMIT_ANALYZE + sqlite3DeleteIndexSamples(db, p); +#endif + sqlite3ExprDelete(db, p->pPartIdxWhere); + sqlite3ExprListDelete(db, p->aColExpr); + sqlite3DbFree(db, p->zColAff); + if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl); +#ifdef SQLITE_ENABLE_STAT4 + sqlite3_free(p->aiRowEst); +#endif + sqlite3DbFree(db, p); +} + +/* +** For the index called zIdxName which is found in the database iDb, +** unlike that index from its Table then remove the index from +** the index hash table and free all memory structures associated +** with the index. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ + Index *pIndex; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &db->aDb[iDb].pSchema->idxHash; + pIndex = sqlite3HashInsert(pHash, zIdxName, 0); + if( ALWAYS(pIndex) ){ + if( pIndex->pTable->pIndex==pIndex ){ + pIndex->pTable->pIndex = pIndex->pNext; + }else{ + Index *p; + /* Justification of ALWAYS(); The index must be on the list of + ** indices. */ + p = pIndex->pTable->pIndex; + while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; } + if( ALWAYS(p && p->pNext==pIndex) ){ + p->pNext = pIndex->pNext; + } + } + sqlite3FreeIndex(db, pIndex); + } + db->mDbFlags |= DBFLAG_SchemaChange; +} + +/* +** Look through the list of open database files in db->aDb[] and if +** any have been closed, remove them from the list. Reallocate the +** db->aDb[] structure to a smaller size, if possible. +** +** Entry 0 (the "main" database) and entry 1 (the "temp" database) +** are never candidates for being collapsed. +*/ +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){ + int i, j; + for(i=j=2; inDb; i++){ + struct Db *pDb = &db->aDb[i]; + if( pDb->pBt==0 ){ + sqlite3DbFree(db, pDb->zDbSName); + pDb->zDbSName = 0; + continue; + } + if( jaDb[j] = db->aDb[i]; + } + j++; + } + db->nDb = j; + if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ + memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); + sqlite3DbFree(db, db->aDb); + db->aDb = db->aDbStatic; + } +} + +/* +** Reset the schema for the database at index iDb. Also reset the +** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. +** Deferred resets may be run by calling with iDb<0. +*/ +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ + int i; + assert( iDbnDb ); + + if( iDb>=0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + DbSetProperty(db, iDb, DB_ResetWanted); + DbSetProperty(db, 1, DB_ResetWanted); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + } + + if( db->nSchemaLock==0 ){ + for(i=0; inDb; i++){ + if( DbHasProperty(db, i, DB_ResetWanted) ){ + sqlite3SchemaClear(db->aDb[i].pSchema); + } + } + } +} + +/* +** Erase all schema information from all attached databases (including +** "main" and "temp") for a single database connection. +*/ +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pSchema ){ + if( db->nSchemaLock==0 ){ + sqlite3SchemaClear(pDb->pSchema); + }else{ + DbSetProperty(db, i, DB_ResetWanted); + } + } + } + db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk); + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); + if( db->nSchemaLock==0 ){ + sqlite3CollapseDatabaseArray(db); + } +} + +/* +** This routine is called when a commit occurs. +*/ +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ + db->mDbFlags &= ~DBFLAG_SchemaChange; +} + +/* +** Set the expression associated with a column. This is usually +** the DEFAULT value, but might also be the expression that computes +** the value for a generated column. +*/ +SQLITE_PRIVATE void sqlite3ColumnSetExpr( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table containing the column */ + Column *pCol, /* The column to receive the new DEFAULT expression */ + Expr *pExpr /* The new default expression */ +){ + ExprList *pList; + assert( IsOrdinaryTable(pTab) ); + pList = pTab->u.tab.pDfltList; + if( pCol->iDflt==0 + || NEVER(pList==0) + || NEVER(pList->nExpriDflt) + ){ + pCol->iDflt = pList==0 ? 1 : pList->nExpr+1; + pTab->u.tab.pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr); + }else{ + sqlite3ExprDelete(pParse->db, pList->a[pCol->iDflt-1].pExpr); + pList->a[pCol->iDflt-1].pExpr = pExpr; + } +} + +/* +** Return the expression associated with a column. The expression might be +** the DEFAULT clause or the AS clause of a generated column. +** Return NULL if the column has no associated expression. +*/ +SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ + if( pCol->iDflt==0 ) return 0; + if( !IsOrdinaryTable(pTab) ) return 0; + if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; + if( NEVER(pTab->u.tab.pDfltList->nExpriDflt) ) return 0; + return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; +} + +/* +** Set the collating sequence name for a column. +*/ +SQLITE_PRIVATE void sqlite3ColumnSetColl( + sqlite3 *db, + Column *pCol, + const char *zColl +){ + i64 nColl; + i64 n; + char *zNew; + assert( zColl!=0 ); + n = sqlite3Strlen30(pCol->zCnName) + 1; + if( pCol->colFlags & COLFLAG_HASTYPE ){ + n += sqlite3Strlen30(pCol->zCnName+n) + 1; + } + nColl = sqlite3Strlen30(zColl) + 1; + zNew = sqlite3DbRealloc(db, pCol->zCnName, nColl+n); + if( zNew ){ + pCol->zCnName = zNew; + memcpy(pCol->zCnName + n, zColl, nColl); + pCol->colFlags |= COLFLAG_HASCOLL; + } +} + +/* +** Return the collating sequence name for a column +*/ +SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ + const char *z; + if( (pCol->colFlags & COLFLAG_HASCOLL)==0 ) return 0; + z = pCol->zCnName; + while( *z ){ z++; } + if( pCol->colFlags & COLFLAG_HASTYPE ){ + do{ z++; }while( *z ); + } + return z+1; +} + +/* +** Delete memory allocated for the column names of a table or view (the +** Table.aCol[] array). +*/ +SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ + int i; + Column *pCol; + assert( pTable!=0 ); + assert( db!=0 ); + if( (pCol = pTable->aCol)!=0 ){ + for(i=0; inCol; i++, pCol++){ + assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); + sqlite3DbFree(db, pCol->zCnName); + } + sqlite3DbNNFreeNN(db, pTable->aCol); + if( IsOrdinaryTable(pTable) ){ + sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); + } + if( db->pnBytesFreed==0 ){ + pTable->aCol = 0; + pTable->nCol = 0; + if( IsOrdinaryTable(pTable) ){ + pTable->u.tab.pDfltList = 0; + } + } + } +} + +/* +** Remove the memory data structures associated with the given +** Table. No changes are made to disk by this routine. +** +** This routine just deletes the data structure. It does not unlink +** the table data structure from the hash table. But it does destroy +** memory structures of the indices and foreign keys associated with +** the table. +** +** The db parameter is optional. It is needed if the Table object +** contains lookaside memory. (Table objects in the schema do not use +** lookaside memory, but some ephemeral Table objects do.) Or the +** db parameter can be used with db->pnBytesFreed to measure the memory +** used by the Table object. +*/ +static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ + Index *pIndex, *pNext; + +#ifdef SQLITE_DEBUG + /* Record the number of outstanding lookaside allocations in schema Tables + ** prior to doing any free() operations. Since schema Tables do not use + ** lookaside, this number should not change. + ** + ** If malloc has already failed, it may be that it failed while allocating + ** a Table object that was going to be marked ephemeral. So do not check + ** that no lookaside memory is used in this case either. */ + int nLookaside = 0; + assert( db!=0 ); + if( !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ + nLookaside = sqlite3LookasideUsed(db, 0); + } +#endif + + /* Delete all indices associated with this table. */ + for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ + pNext = pIndex->pNext; + assert( pIndex->pSchema==pTable->pSchema + || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); + if( db->pnBytesFreed==0 && !IsVirtual(pTable) ){ + char *zName = pIndex->zName; + TESTONLY ( Index *pOld = ) sqlite3HashInsert( + &pIndex->pSchema->idxHash, zName, 0 + ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( pOld==pIndex || pOld==0 ); + } + sqlite3FreeIndex(db, pIndex); + } + + if( IsOrdinaryTable(pTable) ){ + sqlite3FkDelete(db, pTable); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( IsVirtual(pTable) ){ + sqlite3VtabClear(db, pTable); + } +#endif + else{ + assert( IsView(pTable) ); + sqlite3SelectDelete(db, pTable->u.view.pSelect); + } + + /* Delete the Table structure itself. + */ + sqlite3DeleteColumnNames(db, pTable); + sqlite3DbFree(db, pTable->zName); + sqlite3DbFree(db, pTable->zColAff); + sqlite3ExprListDelete(db, pTable->pCheck); + sqlite3DbFree(db, pTable); + + /* Verify that no lookaside memory was used by schema tables */ + assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); +} +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ + /* Do not delete the table until the reference count reaches zero. */ + assert( db!=0 ); + if( !pTable ) return; + if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; + deleteTable(db, pTable); +} +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){ + sqlite3DeleteTable(db, (Table*)pTable); +} + + +/* +** Unlink the given table from the hash tables and the delete the +** table structure with all its indices and foreign keys. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ + Table *p; + Db *pDb; + + assert( db!=0 ); + assert( iDb>=0 && iDbnDb ); + assert( zTabName ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ + pDb = &db->aDb[iDb]; + p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); + sqlite3DeleteTable(db, p); + db->mDbFlags |= DBFLAG_SchemaChange; +} + +/* +** Given a token, return a string that consists of the text of that +** token. Space to hold the returned string +** is obtained from sqliteMalloc() and must be freed by the calling +** function. +** +** Any quotation marks (ex: "name", 'name', [name], or `name`) that +** surround the body of the token are removed. +** +** Tokens are often just pointers into the original SQL text and so +** are not \000 terminated and are not persistent. The returned string +** is \000 terminated and is persistent. +*/ +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, const Token *pName){ + char *zName; + if( pName ){ + zName = sqlite3DbStrNDup(db, (const char*)pName->z, pName->n); + sqlite3Dequote(zName); + }else{ + zName = 0; + } + return zName; +} + +/* +** Open the sqlite_schema table stored in database number iDb for +** writing. The table is opened using cursor 0. +*/ +SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){ + Vdbe *v = sqlite3GetVdbe(p); + sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE); + sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5); + if( p->nTab==0 ){ + p->nTab = 1; + } +} + +/* +** Parameter zName points to a nul-terminated buffer containing the name +** of a database ("main", "temp" or the name of an attached db). This +** function returns the index of the named database in db->aDb[], or +** -1 if the named db cannot be found. +*/ +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ + int i = -1; /* Database number */ + if( zName ){ + Db *pDb; + for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ + if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break; + /* "main" is always an acceptable alias for the primary database + ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */ + if( i==0 && 0==sqlite3_stricmp("main", zName) ) break; + } + } + return i; +} + +/* +** The token *pName contains the name of a database (either "main" or +** "temp" or the name of an attached db). This routine returns the +** index of the named database in db->aDb[], or -1 if the named db +** does not exist. +*/ +SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ + int i; /* Database number */ + char *zName; /* Name we are searching for */ + zName = sqlite3NameFromToken(db, pName); + i = sqlite3FindDbName(db, zName); + sqlite3DbFree(db, zName); + return i; +} + +/* The table or view or trigger name is passed to this routine via tokens +** pName1 and pName2. If the table name was fully qualified, for example: +** +** CREATE TABLE xxx.yyy (...); +** +** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if +** the table name is not fully qualified, i.e.: +** +** CREATE TABLE yyy(...); +** +** Then pName1 is set to "yyy" and pName2 is "". +** +** This routine sets the *ppUnqual pointer to point at the token (pName1 or +** pName2) that stores the unqualified table name. The index of the +** database "xxx" is returned. +*/ +SQLITE_PRIVATE int sqlite3TwoPartName( + Parse *pParse, /* Parsing and code generating context */ + Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ + Token *pName2, /* The "yyy" in the name "xxx.yyy" */ + Token **pUnqual /* Write the unqualified object name here */ +){ + int iDb; /* Database holding the object */ + sqlite3 *db = pParse->db; + + assert( pName2!=0 ); + if( pName2->n>0 ){ + if( db->init.busy ) { + sqlite3ErrorMsg(pParse, "corrupt database"); + return -1; + } + *pUnqual = pName2; + iDb = sqlite3FindDb(db, pName1); + if( iDb<0 ){ + sqlite3ErrorMsg(pParse, "unknown database %T", pName1); + return -1; + } + }else{ + assert( db->init.iDb==0 || db->init.busy || IN_SPECIAL_PARSE + || (db->mDbFlags & DBFLAG_Vacuum)!=0); + iDb = db->init.iDb; + *pUnqual = pName1; + } + return iDb; +} + +/* +** True if PRAGMA writable_schema is ON +*/ +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){ + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + SQLITE_WriteSchema ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + SQLITE_Defensive ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + (SQLITE_WriteSchema|SQLITE_Defensive) ); + return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema; +} + +/* +** This routine is used to check if the UTF-8 string zName is a legal +** unqualified name for a new schema object (table, index, view or +** trigger). All names are legal except those that begin with the string +** "sqlite_" (in upper, lower or mixed case). This portion of the namespace +** is reserved for internal use. +** +** When parsing the sqlite_schema table, this routine also checks to +** make sure the "type", "name", and "tbl_name" columns are consistent +** with the SQL. +*/ +SQLITE_PRIVATE int sqlite3CheckObjectName( + Parse *pParse, /* Parsing context */ + const char *zName, /* Name of the object to check */ + const char *zType, /* Type of this object */ + const char *zTblName /* Parent table name for triggers and indexes */ +){ + sqlite3 *db = pParse->db; + if( sqlite3WritableSchema(db) + || db->init.imposterTable + || !sqlite3Config.bExtraSchemaChecks + ){ + /* Skip these error checks for writable_schema=ON */ + return SQLITE_OK; + } + if( db->init.busy ){ + if( sqlite3_stricmp(zType, db->init.azInit[0]) + || sqlite3_stricmp(zName, db->init.azInit[1]) + || sqlite3_stricmp(zTblName, db->init.azInit[2]) + ){ + sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */ + return SQLITE_ERROR; + } + }else{ + if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) + || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) + ){ + sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", + zName); + return SQLITE_ERROR; + } + + } + return SQLITE_OK; +} + +/* +** Return the PRIMARY KEY index of a table +*/ +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ + Index *p; + for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} + return p; +} + +/* +** Convert an table column number into a index column number. That is, +** for the column iCol in the table (as defined by the CREATE TABLE statement) +** find the (first) offset of that column in index pIdx. Or return -1 +** if column iCol is not used in index pIdx. +*/ +SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ + int i; + for(i=0; inColumn; i++){ + if( iCol==pIdx->aiColumn[i] ) return i; + } + return -1; +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* Convert a storage column number into a table column number. +** +** The storage column number (0,1,2,....) is the index of the value +** as it appears in the record on disk. The true column number +** is the index (0,1,2,...) of the column in the CREATE TABLE statement. +** +** The storage column number is less than the table column number if +** and only there are VIRTUAL columns to the left. +** +** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro. +*/ +SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){ + if( pTab->tabFlags & TF_HasVirtual ){ + int i; + for(i=0; i<=iCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++; + } + } + return iCol; +} +#endif + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* Convert a table column number into a storage column number. +** +** The storage column number (0,1,2,....) is the index of the value +** as it appears in the record on disk. Or, if the input column is +** the N-th virtual column (zero-based) then the storage number is +** the number of non-virtual columns in the table plus N. +** +** The true column number is the index (0,1,2,...) of the column in +** the CREATE TABLE statement. +** +** If the input column is a VIRTUAL column, then it should not appear +** in storage. But the value sometimes is cached in registers that +** follow the range of registers used to construct storage. This +** avoids computing the same VIRTUAL column multiple times, and provides +** values for use by OP_Param opcodes in triggers. Hence, if the +** input column is a VIRTUAL table, put it after all the other columns. +** +** In the following, N means "normal column", S means STORED, and +** V means VIRTUAL. Suppose the CREATE TABLE has columns like this: +** +** CREATE TABLE ex(N,S,V,N,S,V,N,S,V); +** -- 0 1 2 3 4 5 6 7 8 +** +** Then the mapping from this function is as follows: +** +** INPUTS: 0 1 2 3 4 5 6 7 8 +** OUTPUTS: 0 1 6 2 3 7 4 5 8 +** +** So, in other words, this routine shifts all the virtual columns to +** the end. +** +** If SQLITE_OMIT_GENERATED_COLUMNS then there are no virtual columns and +** this routine is a no-op macro. If the pTab does not have any virtual +** columns, then this routine is no-op that always return iCol. If iCol +** is negative (indicating the ROWID column) then this routine return iCol. +*/ +SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){ + int i; + i16 n; + assert( iColnCol ); + if( (pTab->tabFlags & TF_HasVirtual)==0 || iCol<0 ) return iCol; + for(i=0, n=0; iaCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++; + } + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){ + /* iCol is a virtual column itself */ + return pTab->nNVCol + i - n; + }else{ + /* iCol is a normal or stored column */ + return n; + } +} +#endif + +/* +** Insert a single OP_JournalMode query opcode in order to force the +** prepared statement to return false for sqlite3_stmt_readonly(). This +** is used by CREATE TABLE IF NOT EXISTS and similar if the table already +** exists, so that the prepared statement for CREATE TABLE IF NOT EXISTS +** will return false for sqlite3_stmt_readonly() even if that statement +** is a read-only no-op. +*/ +static void sqlite3ForceNotReadOnly(Parse *pParse){ + int iReg = ++pParse->nMem; + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY); + sqlite3VdbeUsesBtree(v, 0); + } +} + +/* +** Begin constructing a new table representation in memory. This is +** the first of several action routines that get called in response +** to a CREATE TABLE statement. In particular, this routine is called +** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp +** flag is true if the table should be stored in the auxiliary database +** file instead of in the main database file. This is normally the case +** when the "TEMP" or "TEMPORARY" keyword occurs in between +** CREATE and TABLE. +** +** The new table record is initialized and put in pParse->pNewTable. +** As more of the CREATE TABLE statement is parsed, additional action +** routines will be called to add more information to this record. +** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine +** is called to complete the construction of the new table record. +*/ +SQLITE_PRIVATE void sqlite3StartTable( + Parse *pParse, /* Parser context */ + Token *pName1, /* First part of the name of the table or view */ + Token *pName2, /* Second part of the name of the table or view */ + int isTemp, /* True if this is a TEMP table */ + int isView, /* True if this is a VIEW */ + int isVirtual, /* True if this is a VIRTUAL table */ + int noErr /* Do nothing if table already exists */ +){ + Table *pTable; + char *zName = 0; /* The name of the new table */ + sqlite3 *db = pParse->db; + Vdbe *v; + int iDb; /* Database number to create the table in */ + Token *pName; /* Unqualified name of the table to create */ + + if( db->init.busy && db->init.newTnum==1 ){ + /* Special case: Parsing the sqlite_schema or sqlite_temp_schema schema */ + iDb = db->init.iDb; + zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb)); + pName = pName1; + }else{ + /* The common case */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) return; + if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ + /* If creating a temp table, the name may not be qualified. Unless + ** the database name is "temp" anyway. */ + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); + return; + } + if( !OMIT_TEMPDB && isTemp ) iDb = 1; + zName = sqlite3NameFromToken(db, pName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)zName, pName); + } + } + pParse->sNameToken = *pName; + if( zName==0 ) return; + if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){ + goto begin_table_error; + } + if( db->init.iDb==1 ) isTemp = 1; +#ifndef SQLITE_OMIT_AUTHORIZATION + assert( isTemp==0 || isTemp==1 ); + assert( isView==0 || isView==1 ); + { + static const u8 aCode[] = { + SQLITE_CREATE_TABLE, + SQLITE_CREATE_TEMP_TABLE, + SQLITE_CREATE_VIEW, + SQLITE_CREATE_TEMP_VIEW + }; + char *zDb = db->aDb[iDb].zDbSName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ + goto begin_table_error; + } + if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView], + zName, 0, zDb) ){ + goto begin_table_error; + } + } +#endif + + /* Make sure the new table name does not collide with an existing + ** index or table name in the same database. Issue an error message if + ** it does. The exception is if the statement being parsed was passed + ** to an sqlite3_declare_vtab() call. In that case only the column names + ** and types will be used, so there is no need to test for namespace + ** collisions. + */ + if( !IN_SPECIAL_PARSE ){ + char *zDb = db->aDb[iDb].zDbSName; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } + pTable = sqlite3FindTable(db, zName, zDb); + if( pTable ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "%s %T already exists", + (IsView(pTable)? "view" : "table"), pName); + }else{ + assert( !db->init.busy || CORRUPT_DB ); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3ForceNotReadOnly(pParse); + } + goto begin_table_error; + } + if( sqlite3FindIndex(db, zName, zDb)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); + goto begin_table_error; + } + } + + pTable = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTable==0 ){ + assert( db->mallocFailed ); + pParse->rc = SQLITE_NOMEM_BKPT; + pParse->nErr++; + goto begin_table_error; + } + pTable->zName = zName; + pTable->iPKey = -1; + pTable->pSchema = db->aDb[iDb].pSchema; + pTable->nTabRef = 1; +#ifdef SQLITE_DEFAULT_ROWEST + pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST); +#else + pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); +#endif + assert( pParse->pNewTable==0 ); + pParse->pNewTable = pTable; + + /* Begin generating the code that will insert the table record into + ** the schema table. Note in particular that we must go ahead + ** and allocate the record number for the table entry now. Before any + ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause + ** indices to be created and the table record must come before the + ** indices. Hence, the record number for the table must be allocated + ** now. + */ + if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ + int addr1; + int fileFormat; + int reg1, reg2, reg3; + /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */ + static const char nullRow[] = { 6, 0, 0, 0, 0, 0 }; + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( isVirtual ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* If the file format and encoding in the database have not been set, + ** set them now. + */ + reg1 = pParse->regRowid = ++pParse->nMem; + reg2 = pParse->regRoot = ++pParse->nMem; + reg3 = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); + fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? + 1 : SQLITE_MAX_FILE_FORMAT; + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); + sqlite3VdbeJumpHere(v, addr1); + + /* This just creates a place-holder record in the sqlite_schema table. + ** The record created does not contain anything yet. It will be replaced + ** by the real entry in code generated at sqlite3EndTable(). + ** + ** The rowid for the new entry is left in register pParse->regRowid. + ** The root page number of the new table is left in reg pParse->regRoot. + ** The rowid and root page number values are needed by the code that + ** sqlite3EndTable will generate. + */ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( isView || isVirtual ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); + }else +#endif + { + assert( !pParse->bReturning ); + pParse->u1.addrCrTab = + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); + } + sqlite3OpenSchemaTable(pParse, iDb); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); + sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); + } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + pParse->checkSchema = 1; + sqlite3DbFree(db, zName); + return; +} + +/* Set properties of a table column based on the (magical) +** name of the column. +*/ +#if SQLITE_ENABLE_HIDDEN_COLUMNS +SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ + if( sqlite3_strnicmp(pCol->zCnName, "__hidden__", 10)==0 ){ + pCol->colFlags |= COLFLAG_HIDDEN; + if( pTab ) pTab->tabFlags |= TF_HasHidden; + }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ + pTab->tabFlags |= TF_OOOHidden; + } +} +#endif + +/* +** Clean up the data structures associated with the RETURNING clause. +*/ +static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){ + Returning *pRet = (Returning*)pArg; + Hash *pHash; + pHash = &(db->aDb[1].pSchema->trigHash); + sqlite3HashInsert(pHash, pRet->zName, 0); + sqlite3ExprListDelete(db, pRet->pReturnEL); + sqlite3DbFree(db, pRet); +} + +/* +** Add the RETURNING clause to the parse currently underway. +** +** This routine creates a special TEMP trigger that will fire for each row +** of the DML statement. That TEMP trigger contains a single SELECT +** statement with a result set that is the argument of the RETURNING clause. +** The trigger has the Trigger.bReturning flag and an opcode of +** TK_RETURNING instead of TK_SELECT, so that the trigger code generator +** knows to handle it specially. The TEMP trigger is automatically +** removed at the end of the parse. +** +** When this routine is called, we do not yet know if the RETURNING clause +** is attached to a DELETE, INSERT, or UPDATE, so construct it as a +** RETURNING trigger instead. It will then be converted into the appropriate +** type on the first call to sqlite3TriggersExist(). +*/ +SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ + Returning *pRet; + Hash *pHash; + sqlite3 *db = pParse->db; + if( pParse->pNewTrigger ){ + sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); + }else{ + assert( pParse->bReturning==0 || pParse->ifNotExists ); + } + pParse->bReturning = 1; + pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); + if( pRet==0 ){ + sqlite3ExprListDelete(db, pList); + return; + } + pParse->u1.pReturning = pRet; + pRet->pParse = pParse; + pRet->pReturnEL = pList; + sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); + testcase( pParse->earlyCleanup ); + if( db->mallocFailed ) return; + sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, + "sqlite_returning_%p", pParse); + pRet->retTrig.zName = pRet->zName; + pRet->retTrig.op = TK_RETURNING; + pRet->retTrig.tr_tm = TRIGGER_AFTER; + pRet->retTrig.bReturning = 1; + pRet->retTrig.pSchema = db->aDb[1].pSchema; + pRet->retTrig.pTabSchema = db->aDb[1].pSchema; + pRet->retTrig.step_list = &pRet->retTStep; + pRet->retTStep.op = TK_RETURNING; + pRet->retTStep.pTrig = &pRet->retTrig; + pRet->retTStep.pExprList = pList; + pHash = &(db->aDb[1].pSchema->trigHash); + assert( sqlite3HashFind(pHash, pRet->zName)==0 + || pParse->nErr || pParse->ifNotExists ); + if( sqlite3HashInsert(pHash, pRet->zName, &pRet->retTrig) + ==&pRet->retTrig ){ + sqlite3OomFault(db); + } +} + +/* +** Add a new column to the table currently being constructed. +** +** The parser calls this routine once for each column declaration +** in a CREATE TABLE statement. sqlite3StartTable() gets called +** first to get things going. Then this routine is called for each +** column. +*/ +SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ + Table *p; + int i; + char *z; + char *zType; + Column *pCol; + sqlite3 *db = pParse->db; + u8 hName; + Column *aNew; + u8 eType = COLTYPE_CUSTOM; + u8 szEst = 1; + char affinity = SQLITE_AFF_BLOB; + + if( (p = pParse->pNewTable)==0 ) return; + if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); + return; + } + if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); + + /* Because keywords GENERATE ALWAYS can be converted into identifiers + ** by the parser, we can sometimes end up with a typename that ends + ** with "generated always". Check for this case and omit the surplus + ** text. */ + if( sType.n>=16 + && sqlite3_strnicmp(sType.z+(sType.n-6),"always",6)==0 + ){ + sType.n -= 6; + while( ALWAYS(sType.n>0) && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + if( sType.n>=9 + && sqlite3_strnicmp(sType.z+(sType.n-9),"generated",9)==0 + ){ + sType.n -= 9; + while( sType.n>0 && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + } + } + + /* Check for standard typenames. For standard typenames we will + ** set the Column.eType field rather than storing the typename after + ** the column name, in order to save space. */ + if( sType.n>=3 ){ + sqlite3DequoteToken(&sType); + for(i=0; i0) ); + if( z==0 ) return; + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); + memcpy(z, sName.z, sName.n); + z[sName.n] = 0; + sqlite3Dequote(z); + hName = sqlite3StrIHash(z); + for(i=0; inCol; i++){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); + sqlite3DbFree(db, z); + return; + } + } + aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0])); + if( aNew==0 ){ + sqlite3DbFree(db, z); + return; + } + p->aCol = aNew; + pCol = &p->aCol[p->nCol]; + memset(pCol, 0, sizeof(p->aCol[0])); + pCol->zCnName = z; + pCol->hName = hName; + sqlite3ColumnPropertiesFromName(p, pCol); + + if( sType.n==0 ){ + /* If there is no type specified, columns have the default affinity + ** 'BLOB' with a default size of 4 bytes. */ + pCol->affinity = affinity; + pCol->eCType = eType; + pCol->szEst = szEst; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( affinity==SQLITE_AFF_BLOB ){ + if( 4>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } + } +#endif + }else{ + zType = z + sqlite3Strlen30(z) + 1; + memcpy(zType, sType.z, sType.n); + zType[sType.n] = 0; + sqlite3Dequote(zType); + pCol->affinity = sqlite3AffinityType(zType, pCol); + pCol->colFlags |= COLFLAG_HASTYPE; + } + p->nCol++; + p->nNVCol++; + pParse->constraintName.n = 0; +} + +/* +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. A "NOT NULL" constraint has +** been seen on a column. This routine sets the notNull flag on +** the column currently under construction. +*/ +SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ + Table *p; + Column *pCol; + p = pParse->pNewTable; + if( p==0 || NEVER(p->nCol<1) ) return; + pCol = &p->aCol[p->nCol-1]; + pCol->notNull = (u8)onError; + p->tabFlags |= TF_HasNotNull; + + /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created + ** on this column. */ + if( pCol->colFlags & COLFLAG_UNIQUE ){ + Index *pIdx; + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None ); + if( pIdx->aiColumn[0]==p->nCol-1 ){ + pIdx->uniqNotNull = 1; + } + } + } +} + +/* +** Scan the column type name zType (length nType) and return the +** associated affinity type. +** +** This routine does a case-independent search of zType for the +** substrings in the following table. If one of the substrings is +** found, the corresponding affinity is returned. If zType contains +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', +** SQLITE_AFF_INTEGER is returned. +** +** Substring | Affinity +** -------------------------------- +** 'INT' | SQLITE_AFF_INTEGER +** 'CHAR' | SQLITE_AFF_TEXT +** 'CLOB' | SQLITE_AFF_TEXT +** 'TEXT' | SQLITE_AFF_TEXT +** 'BLOB' | SQLITE_AFF_BLOB +** 'REAL' | SQLITE_AFF_REAL +** 'FLOA' | SQLITE_AFF_REAL +** 'DOUB' | SQLITE_AFF_REAL +** +** If none of the substrings in the above table are found, +** SQLITE_AFF_NUMERIC is returned. +*/ +SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ + u32 h = 0; + char aff = SQLITE_AFF_NUMERIC; + const char *zChar = 0; + + assert( zIn!=0 ); + while( zIn[0] ){ + u8 x = *(u8*)zIn; + h = (h<<8) + sqlite3UpperToLower[x]; + zIn++; + if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ + aff = SQLITE_AFF_TEXT; + zChar = zIn; + }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ + && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ + aff = SQLITE_AFF_BLOB; + if( zIn[0]=='(' ) zChar = zIn; +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; +#endif + }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ + aff = SQLITE_AFF_INTEGER; + break; + } + } + + /* If pCol is not NULL, store an estimate of the field size. The + ** estimate is scaled so that the size of an integer is 1. */ + if( pCol ){ + int v = 0; /* default size is approx 4 bytes */ + if( aff r=(k/4+1) */ + sqlite3GetInt32(zChar, &v); + break; + } + zChar++; + } + }else{ + v = 16; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ + } + } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( v>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } +#endif + v = v/4 + 1; + if( v>255 ) v = 255; + pCol->szEst = v; + } + return aff; +} + +/* +** The expression is the default value for the most recently added column +** of the table currently under construction. +** +** Default value expressions must be constant. Raise an exception if this +** is not the case. +** +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3AddDefaultValue( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The parsed expression of the default value */ + const char *zStart, /* Start of the default value text */ + const char *zEnd /* First character past end of default value text */ +){ + Table *p; + Column *pCol; + sqlite3 *db = pParse->db; + p = pParse->pNewTable; + if( p!=0 ){ + int isInit = db->init.busy && db->init.iDb!=1; + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zCnName); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column"); +#endif + }else{ + /* A copy of pExpr is used instead of the original, as pExpr contains + ** tokens that point to volatile memory. + */ + Expr x, *pDfltExpr; + memset(&x, 0, sizeof(x)); + x.op = TK_SPAN; + x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); + x.pLeft = pExpr; + x.flags = EP_Skip; + pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); + sqlite3DbFree(db, x.u.zToken); + sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr); + } + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, pExpr); + } + sqlite3ExprDelete(db, pExpr); +} + +/* +** Backwards Compatibility Hack: +** +** Historical versions of SQLite accepted strings as column names in +** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example: +** +** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim) +** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC); +** +** This is goofy. But to preserve backwards compatibility we continue to +** accept it. This routine does the necessary conversion. It converts +** the expression given in its argument from a TK_STRING into a TK_ID +** if the expression is just a TK_STRING with an optional COLLATE clause. +** If the expression is anything other than TK_STRING, the expression is +** unchanged. +*/ +static void sqlite3StringToId(Expr *p){ + if( p->op==TK_STRING ){ + p->op = TK_ID; + }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){ + p->pLeft->op = TK_ID; + } +} + +/* +** Tag the given column as being part of the PRIMARY KEY +*/ +static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){ + pCol->colFlags |= COLFLAG_PRIMKEY; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "generated columns cannot be part of the PRIMARY KEY"); + } +#endif +} + +/* +** Designate the PRIMARY KEY for the table. pList is a list of names +** of columns that form the primary key. If pList is NULL, then the +** most recently added column of the table is the primary key. +** +** A table can have at most one primary key. If the table already has +** a primary key (and this is the second primary key) then create an +** error. +** +** If the PRIMARY KEY is on a single column whose datatype is INTEGER, +** then we will try to use that column as the rowid. Set the Table.iPKey +** field of the table under construction to be the index of the +** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is +** no INTEGER PRIMARY KEY. +** +** If the key is not an INTEGER PRIMARY KEY, then create a unique +** index for the key. No index is created for INTEGER PRIMARY KEYs. +*/ +SQLITE_PRIVATE void sqlite3AddPrimaryKey( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List of field names to be indexed */ + int onError, /* What to do with a uniqueness conflict */ + int autoInc, /* True if the AUTOINCREMENT keyword is present */ + int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ +){ + Table *pTab = pParse->pNewTable; + Column *pCol = 0; + int iCol = -1, i; + int nTerm; + if( pTab==0 ) goto primary_key_exit; + if( pTab->tabFlags & TF_HasPrimaryKey ){ + sqlite3ErrorMsg(pParse, + "table \"%s\" has more than one primary key", pTab->zName); + goto primary_key_exit; + } + pTab->tabFlags |= TF_HasPrimaryKey; + if( pList==0 ){ + iCol = pTab->nCol - 1; + pCol = &pTab->aCol[iCol]; + makeColumnPartOfPrimaryKey(pParse, pCol); + nTerm = 1; + }else{ + nTerm = pList->nExpr; + for(i=0; ia[i].pExpr); + assert( pCExpr!=0 ); + sqlite3StringToId(pCExpr); + if( pCExpr->op==TK_ID ){ + const char *zCName; + assert( !ExprHasProperty(pCExpr, EP_IntValue) ); + zCName = pCExpr->u.zToken; + for(iCol=0; iColnCol; iCol++){ + if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){ + pCol = &pTab->aCol[iCol]; + makeColumnPartOfPrimaryKey(pParse, pCol); + break; + } + } + } + } + } + if( nTerm==1 + && pCol + && pCol->eCType==COLTYPE_INTEGER + && sortOrder!=SQLITE_SO_DESC + ){ + if( IN_RENAME_OBJECT && pList ){ + Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr); + sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr); + } + pTab->iPKey = iCol; + pTab->keyConf = (u8)onError; + assert( autoInc==0 || autoInc==1 ); + pTab->tabFlags |= autoInc*TF_Autoincrement; + if( pList ) pParse->iPkSortOrder = pList->a[0].fg.sortFlags; + (void)sqlite3HasExplicitNulls(pParse, pList); + }else if( autoInc ){ +#ifndef SQLITE_OMIT_AUTOINCREMENT + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + "INTEGER PRIMARY KEY"); +#endif + }else{ + sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, + 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY); + pList = 0; + } + +primary_key_exit: + sqlite3ExprListDelete(pParse->db, pList); + return; +} + +/* +** Add a new CHECK constraint to the table currently under construction. +*/ +SQLITE_PRIVATE void sqlite3AddCheckConstraint( + Parse *pParse, /* Parsing context */ + Expr *pCheckExpr, /* The check expression */ + const char *zStart, /* Opening "(" */ + const char *zEnd /* Closing ")" */ +){ +#ifndef SQLITE_OMIT_CHECK + Table *pTab = pParse->pNewTable; + sqlite3 *db = pParse->db; + if( pTab && !IN_DECLARE_VTAB + && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) + ){ + pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); + if( pParse->constraintName.n ){ + sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); + }else{ + Token t; + for(zStart++; sqlite3Isspace(zStart[0]); zStart++){} + while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; } + t.z = zStart; + t.n = (int)(zEnd - t.z); + sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1); + } + }else +#endif + { + sqlite3ExprDelete(pParse->db, pCheckExpr); + } +} + +/* +** Set the collation function of the most recently parsed table column +** to the CollSeq given. +*/ +SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ + Table *p; + int i; + char *zColl; /* Dequoted name of collation sequence */ + sqlite3 *db; + + if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return; + i = p->nCol-1; + db = pParse->db; + zColl = sqlite3NameFromToken(db, pToken); + if( !zColl ) return; + + if( sqlite3LocateCollSeq(pParse, zColl) ){ + Index *pIdx; + sqlite3ColumnSetColl(db, &p->aCol[i], zColl); + + /* If the column is declared as " PRIMARY KEY COLLATE ", + ** then an index may have been created on this column before the + ** collation type was added. Correct this if it is the case. + */ + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->nKeyCol==1 ); + if( pIdx->aiColumn[0]==i ){ + pIdx->azColl[0] = sqlite3ColumnColl(&p->aCol[i]); + } + } + } + sqlite3DbFree(db, zColl); +} + +/* Change the most recently parsed column to be a GENERATED ALWAYS AS +** column. +*/ +SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + u8 eType = COLFLAG_VIRTUAL; + Table *pTab = pParse->pNewTable; + Column *pCol; + if( pTab==0 ){ + /* generated column in an CREATE TABLE IF NOT EXISTS that already exists */ + goto generated_done; + } + pCol = &(pTab->aCol[pTab->nCol-1]); + if( IN_DECLARE_VTAB ){ + sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); + goto generated_done; + } + if( pCol->iDflt>0 ) goto generated_error; + if( pType ){ + if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ + /* no-op */ + }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){ + eType = COLFLAG_STORED; + }else{ + goto generated_error; + } + } + if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--; + pCol->colFlags |= eType; + assert( TF_HasVirtual==COLFLAG_VIRTUAL ); + assert( TF_HasStored==COLFLAG_STORED ); + pTab->tabFlags |= eType; + if( pCol->colFlags & COLFLAG_PRIMKEY ){ + makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ + } + if( ALWAYS(pExpr) && pExpr->op==TK_ID ){ + /* The value of a generated column needs to be a real expression, not + ** just a reference to another column, in order for covering index + ** optimizations to work correctly. So if the value is not an expression, + ** turn it into one by adding a unary "+" operator. */ + pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0); + } + if( pExpr && pExpr->op!=TK_RAISE ) pExpr->affExpr = pCol->affinity; + sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); + pExpr = 0; + goto generated_done; + +generated_error: + sqlite3ErrorMsg(pParse, "error in generated column \"%s\"", + pCol->zCnName); +generated_done: + sqlite3ExprDelete(pParse->db, pExpr); +#else + /* Throw and error for the GENERATED ALWAYS AS clause if the + ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */ + sqlite3ErrorMsg(pParse, "generated columns not supported"); + sqlite3ExprDelete(pParse->db, pExpr); +#endif +} + +/* +** Generate code that will increment the schema cookie. +** +** The schema cookie is used to determine when the schema for the +** database changes. After each schema change, the cookie value +** changes. When a process first reads the schema it records the +** cookie. Thereafter, whenever it goes to access the database, +** it checks the cookie to make sure the schema has not changed +** since it was last read. +** +** This plan is not completely bullet-proof. It is possible for +** the schema to change multiple times and for the cookie to be +** set back to prior value. But schema changes are infrequent +** and the probability of hitting the same cookie value is only +** 1 chance in 2^32. So we're safe enough. +** +** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments +** the schema-version whenever the schema changes. +*/ +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, + (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); +} + +/* +** Measure the number of characters needed to output the given +** identifier. The number returned includes any quotes used +** but does not include the null terminator. +** +** The estimate is conservative. It might be larger that what is +** really needed. +*/ +static int identLength(const char *z){ + int n; + for(n=0; *z; n++, z++){ + if( *z=='"' ){ n++; } + } + return n + 2; +} + +/* +** The first parameter is a pointer to an output buffer. The second +** parameter is a pointer to an integer that contains the offset at +** which to write into the output buffer. This function copies the +** nul-terminated string pointed to by the third parameter, zSignedIdent, +** to the specified offset in the buffer and updates *pIdx to refer +** to the first byte after the last byte written before returning. +** +** If the string zSignedIdent consists entirely of alphanumeric +** characters, does not begin with a digit and is not an SQL keyword, +** then it is copied to the output buffer exactly as it is. Otherwise, +** it is quoted using double-quotes. +*/ +static void identPut(char *z, int *pIdx, char *zSignedIdent){ + unsigned char *zIdent = (unsigned char*)zSignedIdent; + int i, j, needQuote; + i = *pIdx; + + for(j=0; zIdent[j]; j++){ + if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; + } + needQuote = sqlite3Isdigit(zIdent[0]) + || sqlite3KeywordCode(zIdent, j)!=TK_ID + || zIdent[j]!=0 + || j==0; + + if( needQuote ) z[i++] = '"'; + for(j=0; zIdent[j]; j++){ + z[i++] = zIdent[j]; + if( zIdent[j]=='"' ) z[i++] = '"'; + } + if( needQuote ) z[i++] = '"'; + z[i] = 0; + *pIdx = i; +} + +/* +** Generate a CREATE TABLE statement appropriate for the given +** table. Memory to hold the text of the statement is obtained +** from sqliteMalloc() and must be freed by the calling function. +*/ +static char *createTableStmt(sqlite3 *db, Table *p){ + int i, k, n; + char *zStmt; + char *zSep, *zSep2, *zEnd; + Column *pCol; + n = 0; + for(pCol = p->aCol, i=0; inCol; i++, pCol++){ + n += identLength(pCol->zCnName) + 5; + } + n += identLength(p->zName); + if( n<50 ){ + zSep = ""; + zSep2 = ","; + zEnd = ")"; + }else{ + zSep = "\n "; + zSep2 = ",\n "; + zEnd = "\n)"; + } + n += 35 + 6*p->nCol; + zStmt = sqlite3DbMallocRaw(0, n); + if( zStmt==0 ){ + sqlite3OomFault(db); + return 0; + } + sqlite3_snprintf(n, zStmt, "CREATE TABLE "); + k = sqlite3Strlen30(zStmt); + identPut(zStmt, &k, p->zName); + zStmt[k++] = '('; + for(pCol=p->aCol, i=0; inCol; i++, pCol++){ + static const char * const azType[] = { + /* SQLITE_AFF_BLOB */ "", + /* SQLITE_AFF_TEXT */ " TEXT", + /* SQLITE_AFF_NUMERIC */ " NUM", + /* SQLITE_AFF_INTEGER */ " INT", + /* SQLITE_AFF_REAL */ " REAL", + /* SQLITE_AFF_FLEXNUM */ " NUM", + }; + int len; + const char *zType; + + sqlite3_snprintf(n-k, &zStmt[k], zSep); + k += sqlite3Strlen30(&zStmt[k]); + zSep = zSep2; + identPut(zStmt, &k, pCol->zCnName); + assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 ); + assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); + testcase( pCol->affinity==SQLITE_AFF_BLOB ); + testcase( pCol->affinity==SQLITE_AFF_TEXT ); + testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); + testcase( pCol->affinity==SQLITE_AFF_INTEGER ); + testcase( pCol->affinity==SQLITE_AFF_REAL ); + testcase( pCol->affinity==SQLITE_AFF_FLEXNUM ); + + zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; + len = sqlite3Strlen30(zType); + assert( pCol->affinity==SQLITE_AFF_BLOB + || pCol->affinity==SQLITE_AFF_FLEXNUM + || pCol->affinity==sqlite3AffinityType(zType, 0) ); + memcpy(&zStmt[k], zType, len); + k += len; + assert( k<=n ); + } + sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); + return zStmt; +} + +/* +** Resize an Index object to hold N columns total. Return SQLITE_OK +** on success and SQLITE_NOMEM on an OOM error. +*/ +static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ + char *zExtra; + int nByte; + if( pIdx->nColumn>=N ) return SQLITE_OK; + assert( pIdx->isResized==0 ); + nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N; + zExtra = sqlite3DbMallocZero(db, nByte); + if( zExtra==0 ) return SQLITE_NOMEM_BKPT; + memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); + pIdx->azColl = (const char**)zExtra; + zExtra += sizeof(char*)*N; + memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1)); + pIdx->aiRowLogEst = (LogEst*)zExtra; + zExtra += sizeof(LogEst)*N; + memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); + pIdx->aiColumn = (i16*)zExtra; + zExtra += sizeof(i16)*N; + memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); + pIdx->aSortOrder = (u8*)zExtra; + pIdx->nColumn = N; + pIdx->isResized = 1; + return SQLITE_OK; +} + +/* +** Estimate the total row width for a table. +*/ +static void estimateTableWidth(Table *pTab){ + unsigned wTable = 0; + const Column *pTabCol; + int i; + for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){ + wTable += pTabCol->szEst; + } + if( pTab->iPKey<0 ) wTable++; + pTab->szTabRow = sqlite3LogEst(wTable*4); +} + +/* +** Estimate the average size of a row for an index. +*/ +static void estimateIndexWidth(Index *pIdx){ + unsigned wIndex = 0; + int i; + const Column *aCol = pIdx->pTable->aCol; + for(i=0; inColumn; i++){ + i16 x = pIdx->aiColumn[i]; + assert( xpTable->nCol ); + wIndex += x<0 ? 1 : aCol[x].szEst; + } + pIdx->szIdxRow = sqlite3LogEst(wIndex*4); +} + +/* Return true if column number x is any of the first nCol entries of aiCol[]. +** This is used to determine if the column number x appears in any of the +** first nCol entries of an index. +*/ +static int hasColumn(const i16 *aiCol, int nCol, int x){ + while( nCol-- > 0 ){ + if( x==*(aiCol++) ){ + return 1; + } + } + return 0; +} + +/* +** Return true if any of the first nKey entries of index pIdx exactly +** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID +** PRIMARY KEY index. pIdx is an index on the same table. pIdx may +** or may not be the same index as pPk. +** +** The first nKey entries of pIdx are guaranteed to be ordinary columns, +** not a rowid or expression. +** +** This routine differs from hasColumn() in that both the column and the +** collating sequence must match for this routine, but for hasColumn() only +** the column name must match. +*/ +static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){ + int i, j; + assert( nKey<=pIdx->nColumn ); + assert( iColnColumn,pPk->nKeyCol) ); + assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY ); + assert( pPk->pTable->tabFlags & TF_WithoutRowid ); + assert( pPk->pTable==pIdx->pTable ); + testcase( pPk==pIdx ); + j = pPk->aiColumn[iCol]; + assert( j!=XN_ROWID && j!=XN_EXPR ); + for(i=0; iaiColumn[i]>=0 || j>=0 ); + if( pIdx->aiColumn[i]==j + && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0 + ){ + return 1; + } + } + return 0; +} + +/* Recompute the colNotIdxed field of the Index. +** +** colNotIdxed is a bitmask that has a 0 bit representing each indexed +** columns that are within the first 63 columns of the table and a 1 for +** all other bits (all columns that are not in the index). The +** high-order bit of colNotIdxed is always 1. All unindexed columns +** of the table have a 1. +** +** 2019-10-24: For the purpose of this computation, virtual columns are +** not considered to be covered by the index, even if they are in the +** index, because we do not trust the logic in whereIndexExprTrans() to be +** able to find all instances of a reference to the indexed table column +** and convert them into references to the index. Hence we always want +** the actual table at hand in order to recompute the virtual column, if +** necessary. +** +** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask +** to determine if the index is covering index. +*/ +static void recomputeColumnsNotIndexed(Index *pIdx){ + Bitmask m = 0; + int j; + Table *pTab = pIdx->pTable; + for(j=pIdx->nColumn-1; j>=0; j--){ + int x = pIdx->aiColumn[j]; + if( x>=0 && (pTab->aCol[x].colFlags & COLFLAG_VIRTUAL)==0 ){ + testcase( x==BMS-1 ); + testcase( x==BMS-2 ); + if( xcolNotIdxed = ~m; + assert( (pIdx->colNotIdxed>>63)==1 ); /* See note-20221022-a */ +} + +/* +** This routine runs at the end of parsing a CREATE TABLE statement that +** has a WITHOUT ROWID clause. The job of this routine is to convert both +** internal schema data structures and the generated VDBE code so that they +** are appropriate for a WITHOUT ROWID table instead of a rowid table. +** Changes include: +** +** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. +** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY +** into BTREE_BLOBKEY. +** (3) Bypass the creation of the sqlite_schema table entry +** for the PRIMARY KEY as the primary key index is now +** identified by the sqlite_schema table entry of the table itself. +** (4) Set the Index.tnum of the PRIMARY KEY Index object in the +** schema to the rootpage from the main table. +** (5) Add all table columns to the PRIMARY KEY Index object +** so that the PRIMARY KEY is a covering index. The surplus +** columns are part of KeyInfo.nAllField and are not used for +** sorting or lookup or uniqueness checks. +** (6) Replace the rowid tail on all automatically generated UNIQUE +** indices with the PRIMARY KEY columns. +** +** For virtual tables, only (1) is performed. +*/ +static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + Index *pIdx; + Index *pPk; + int nPk; + int nExtra; + int i, j; + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + + /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) + */ + if( !db->init.imposterTable ){ + for(i=0; inCol; i++){ + if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 + && (pTab->aCol[i].notNull==OE_None) + ){ + pTab->aCol[i].notNull = OE_Abort; + } + } + pTab->tabFlags |= TF_HasNotNull; + } + + /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY + ** into BTREE_BLOBKEY. + */ + assert( !pParse->bReturning ); + if( pParse->u1.addrCrTab ){ + assert( v ); + sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY); + } + + /* Locate the PRIMARY KEY index. Or, if this table was originally + ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. + */ + if( pTab->iPKey>=0 ){ + ExprList *pList; + Token ipkToken; + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zCnName); + pList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); + if( pList==0 ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); + } + pList->a[0].fg.sortFlags = pParse->iPkSortOrder; + assert( pParse->pNewTable==pTab ); + pTab->iPKey = -1; + sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, + SQLITE_IDXTYPE_PRIMARYKEY); + if( pParse->nErr ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } + assert( db->mallocFailed==0 ); + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk->nKeyCol==1 ); + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + + /* + ** Remove all redundant columns from the PRIMARY KEY. For example, change + ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later + ** code assumes the PRIMARY KEY contains no repeated columns. + */ + for(i=j=1; inKeyCol; i++){ + if( isDupColumn(pPk, j, pPk, i) ){ + pPk->nColumn--; + }else{ + testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ); + pPk->azColl[j] = pPk->azColl[i]; + pPk->aSortOrder[j] = pPk->aSortOrder[i]; + pPk->aiColumn[j++] = pPk->aiColumn[i]; + } + } + pPk->nKeyCol = j; + } + assert( pPk!=0 ); + pPk->isCovering = 1; + if( !db->init.imposterTable ) pPk->uniqNotNull = 1; + nPk = pPk->nColumn = pPk->nKeyCol; + + /* Bypass the creation of the PRIMARY KEY btree and the sqlite_schema + ** table entry. This is only required if currently generating VDBE + ** code for a CREATE TABLE (not when parsing one as part of reading + ** a database schema). */ + if( v && pPk->tnum>0 ){ + assert( db->init.busy==0 ); + sqlite3VdbeChangeOpcode(v, (int)pPk->tnum, OP_Goto); + } + + /* The root page of the PRIMARY KEY is the table root page */ + pPk->tnum = pTab->tnum; + + /* Update the in-memory representation of all UNIQUE indices by converting + ** the final rowid column into one or more columns of the PRIMARY KEY. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int n; + if( IsPrimaryKeyIndex(pIdx) ) continue; + for(i=n=0; inKeyCol, pPk, i) ){ + testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); + n++; + } + } + if( n==0 ){ + /* This index is a superset of the primary key */ + pIdx->nColumn = pIdx->nKeyCol; + continue; + } + if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; + for(i=0, j=pIdx->nKeyCol; inKeyCol, pPk, i) ){ + testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); + pIdx->aiColumn[j] = pPk->aiColumn[i]; + pIdx->azColl[j] = pPk->azColl[i]; + if( pPk->aSortOrder[i] ){ + /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */ + pIdx->bAscKeyBug = 1; + } + j++; + } + } + assert( pIdx->nColumn>=pIdx->nKeyCol+n ); + assert( pIdx->nColumn>=j ); + } + + /* Add all table columns to the PRIMARY KEY index + */ + nExtra = 0; + for(i=0; inCol; i++){ + if( !hasColumn(pPk->aiColumn, nPk, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; + } + if( resizeIndexObject(db, pPk, nPk+nExtra) ) return; + for(i=0, j=nPk; inCol; i++){ + if( !hasColumn(pPk->aiColumn, j, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 + ){ + assert( jnColumn ); + pPk->aiColumn[j] = i; + pPk->azColl[j] = sqlite3StrBINARY; + j++; + } + } + assert( pPk->nColumn==j ); + assert( pTab->nNVCol<=j ); + recomputeColumnsNotIndexed(pPk); +} + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if pTab is a virtual table and zName is a shadow table name +** for that virtual table. +*/ +SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){ + int nName; /* Length of zName */ + Module *pMod; /* Module for the virtual table */ + + if( !IsVirtual(pTab) ) return 0; + nName = sqlite3Strlen30(pTab->zName); + if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0; + if( zName[nName]!='_' ) return 0; + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); + if( pMod==0 ) return 0; + if( pMod->pModule->iVersion<3 ) return 0; + if( pMod->pModule->xShadowName==0 ) return 0; + return pMod->pModule->xShadowName(zName+nName+1); +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Table pTab is a virtual table. If it the virtual table implementation +** exists and has an xShadowName method, then loop over all other ordinary +** tables within the same schema looking for shadow tables of pTab, and mark +** any shadow tables seen using the TF_Shadow flag. +*/ +SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){ + int nName; /* Length of pTab->zName */ + Module *pMod; /* Module for the virtual table */ + HashElem *k; /* For looping through the symbol table */ + + assert( IsVirtual(pTab) ); + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); + if( pMod==0 ) return; + if( NEVER(pMod->pModule==0) ) return; + if( pMod->pModule->iVersion<3 ) return; + if( pMod->pModule->xShadowName==0 ) return; + assert( pTab->zName!=0 ); + nName = sqlite3Strlen30(pTab->zName); + for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pOther = sqliteHashData(k); + assert( pOther->zName!=0 ); + if( !IsOrdinaryTable(pOther) ) continue; + if( pOther->tabFlags & TF_Shadow ) continue; + if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0 + && pOther->zName[nName]=='_' + && pMod->pModule->xShadowName(pOther->zName+nName+1) + ){ + pOther->tabFlags |= TF_Shadow; + } + } +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if zName is a shadow table name in the current database +** connection. +** +** zName is temporarily modified while this routine is running, but is +** restored to its original value prior to this routine returning. +*/ +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ + char *zTail; /* Pointer to the last "_" in zName */ + Table *pTab; /* Table that zName is a shadow of */ + zTail = strrchr(zName, '_'); + if( zTail==0 ) return 0; + *zTail = 0; + pTab = sqlite3FindTable(db, zName, 0); + *zTail = '_'; + if( pTab==0 ) return 0; + if( !IsVirtual(pTab) ) return 0; + return sqlite3IsShadowTableOf(db, pTab, zName); +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + + +#ifdef SQLITE_DEBUG +/* +** Mark all nodes of an expression as EP_Immutable, indicating that +** they should not be changed. Expressions attached to a table or +** index definition are tagged this way to help ensure that we do +** not pass them into code generator routines by mistake. +*/ +static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ + (void)pWalker; + ExprSetVVAProperty(pExpr, EP_Immutable); + return WRC_Continue; +} +static void markExprListImmutable(ExprList *pList){ + if( pList ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = markImmutableExprStep; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = 0; + sqlite3WalkExprList(&w, pList); + } +} +#else +#define markExprListImmutable(X) /* no-op */ +#endif /* SQLITE_DEBUG */ + + +/* +** This routine is called to report the final ")" that terminates +** a CREATE TABLE statement. +** +** The table structure that other action routines have been building +** is added to the internal hash tables, assuming no errors have +** occurred. +** +** An entry for the table is made in the schema table on disk, unless +** this is a temporary table or db->init.busy==1. When db->init.busy==1 +** it means we are reading the sqlite_schema table because we just +** connected to the database or because the sqlite_schema table has +** recently changed, so the entry for this table already exists in +** the sqlite_schema table. We do not want to create it again. +** +** If the pSelect argument is not NULL, it means that this routine +** was called to create a table generated from a +** "CREATE TABLE ... AS SELECT ..." statement. The column names of +** the new table will match the result set of the SELECT. +*/ +SQLITE_PRIVATE void sqlite3EndTable( + Parse *pParse, /* Parse context */ + Token *pCons, /* The ',' token after the last column defn. */ + Token *pEnd, /* The ')' before options in the CREATE TABLE */ + u32 tabOpts, /* Extra table options. Usually 0. */ + Select *pSelect /* Select from a "CREATE ... AS SELECT" */ +){ + Table *p; /* The new table */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb; /* Database in which the table lives */ + Index *pIdx; /* An implied index of the table */ + + if( pEnd==0 && pSelect==0 ){ + return; + } + p = pParse->pNewTable; + if( p==0 ) return; + + if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ + p->tabFlags |= TF_Shadow; + } + + /* If the db->init.busy is 1 it means we are reading the SQL off the + ** "sqlite_schema" or "sqlite_temp_schema" table on the disk. + ** So do not write to the disk again. Extract the root page number + ** for the table from the db->init.newTnum field. (The page number + ** should have been put there by the sqliteOpenCb routine.) + ** + ** If the root page number is 1, that means this is the sqlite_schema + ** table itself. So mark it read-only. + */ + if( db->init.busy ){ + if( pSelect || (!IsOrdinaryTable(p) && db->init.newTnum) ){ + sqlite3ErrorMsg(pParse, ""); + return; + } + p->tnum = db->init.newTnum; + if( p->tnum==1 ) p->tabFlags |= TF_Readonly; + } + + /* Special processing for tables that include the STRICT keyword: + ** + ** * Do not allow custom column datatypes. Every column must have + ** a datatype that is one of INT, INTEGER, REAL, TEXT, or BLOB. + ** + ** * If a PRIMARY KEY is defined, other than the INTEGER PRIMARY KEY, + ** then all columns of the PRIMARY KEY must have a NOT NULL + ** constraint. + */ + if( tabOpts & TF_Strict ){ + int ii; + p->tabFlags |= TF_Strict; + for(ii=0; iinCol; ii++){ + Column *pCol = &p->aCol[ii]; + if( pCol->eCType==COLTYPE_CUSTOM ){ + if( pCol->colFlags & COLFLAG_HASTYPE ){ + sqlite3ErrorMsg(pParse, + "unknown datatype for %s.%s: \"%s\"", + p->zName, pCol->zCnName, sqlite3ColumnType(pCol, "") + ); + }else{ + sqlite3ErrorMsg(pParse, "missing datatype for %s.%s", + p->zName, pCol->zCnName); + } + return; + }else if( pCol->eCType==COLTYPE_ANY ){ + pCol->affinity = SQLITE_AFF_BLOB; + } + if( (pCol->colFlags & COLFLAG_PRIMKEY)!=0 + && p->iPKey!=ii + && pCol->notNull == OE_None + ){ + pCol->notNull = OE_Abort; + p->tabFlags |= TF_HasNotNull; + } + } + } + + assert( (p->tabFlags & TF_HasPrimaryKey)==0 + || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 ); + assert( (p->tabFlags & TF_HasPrimaryKey)!=0 + || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) ); + + /* Special processing for WITHOUT ROWID Tables */ + if( tabOpts & TF_WithoutRowid ){ + if( (p->tabFlags & TF_Autoincrement) ){ + sqlite3ErrorMsg(pParse, + "AUTOINCREMENT not allowed on WITHOUT ROWID tables"); + return; + } + if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ + sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); + return; + } + p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; + convertToWithoutRowidTable(pParse, p); + } + iDb = sqlite3SchemaToIndex(db, p->pSchema); + +#ifndef SQLITE_OMIT_CHECK + /* Resolve names in all CHECK constraint expressions. + */ + if( p->pCheck ){ + sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); + if( pParse->nErr ){ + /* If errors are seen, delete the CHECK constraints now, else they might + ** actually be used if PRAGMA writable_schema=ON is set. */ + sqlite3ExprListDelete(db, p->pCheck); + p->pCheck = 0; + }else{ + markExprListImmutable(p->pCheck); + } + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( p->tabFlags & TF_HasGenerated ){ + int ii, nNG = 0; + testcase( p->tabFlags & TF_HasVirtual ); + testcase( p->tabFlags & TF_HasStored ); + for(ii=0; iinCol; ii++){ + u32 colFlags = p->aCol[ii].colFlags; + if( (colFlags & COLFLAG_GENERATED)!=0 ){ + Expr *pX = sqlite3ColumnExpr(p, &p->aCol[ii]); + testcase( colFlags & COLFLAG_VIRTUAL ); + testcase( colFlags & COLFLAG_STORED ); + if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ + /* If there are errors in resolving the expression, change the + ** expression to a NULL. This prevents code generators that operate + ** on the expression from inserting extra parts into the expression + ** tree that have been allocated from lookaside memory, which is + ** illegal in a schema and will lead to errors or heap corruption + ** when the database connection closes. */ + sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + } + }else{ + nNG++; + } + } + if( nNG==0 ){ + sqlite3ErrorMsg(pParse, "must have at least one non-generated column"); + return; + } + } +#endif + + /* Estimate the average row size for the table and for all implied indices */ + estimateTableWidth(p); + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + estimateIndexWidth(pIdx); + } + + /* If not initializing, then create a record for the new table + ** in the schema table of the database. + ** + ** If this is a TEMPORARY table, write the entry into the auxiliary + ** file instead of into the main database file. + */ + if( !db->init.busy ){ + int n; + Vdbe *v; + char *zType; /* "view" or "table" */ + char *zType2; /* "VIEW" or "TABLE" */ + char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ + + v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return; + + sqlite3VdbeAddOp1(v, OP_Close, 0); + + /* + ** Initialize zType for the new view or table. + */ + if( IsOrdinaryTable(p) ){ + /* A regular table */ + zType = "table"; + zType2 = "TABLE"; +#ifndef SQLITE_OMIT_VIEW + }else{ + /* A view */ + zType = "view"; + zType2 = "VIEW"; +#endif + } + + /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT + ** statement to populate the new table. The root-page number for the + ** new table is in register pParse->regRoot. + ** + ** Once the SELECT has been coded by sqlite3Select(), it is in a + ** suitable state to query for the column names and types to be used + ** by the new table. + ** + ** A shared-cache write-lock is not required to write to the new table, + ** as a schema-lock must have already been obtained to create it. Since + ** a schema-lock excludes all other database users, the write-lock would + ** be redundant. + */ + if( pSelect ){ + SelectDest dest; /* Where the SELECT should store results */ + int regYield; /* Register holding co-routine entry-point */ + int addrTop; /* Top of the co-routine */ + int regRec; /* A record to be insert into the new table */ + int regRowid; /* Rowid of the next row to insert */ + int addrInsLoop; /* Top of the loop for inserting rows */ + Table *pSelTab; /* A table that describes the SELECT results */ + + if( IN_SPECIAL_PARSE ){ + pParse->rc = SQLITE_ERROR; + pParse->nErr++; + return; + } + regYield = ++pParse->nMem; + regRec = ++pParse->nMem; + regRowid = ++pParse->nMem; + assert(pParse->nTab==1); + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); + pParse->nTab = 2; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + if( pParse->nErr ) return; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB); + if( pSelTab==0 ) return; + assert( p->aCol==0 ); + p->nCol = p->nNVCol = pSelTab->nCol; + p->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + sqlite3Select(pParse, pSelect, &dest); + if( pParse->nErr ) return; + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); + addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); + sqlite3TableAffinity(v, p, 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); + sqlite3VdbeGoto(v, addrInsLoop); + sqlite3VdbeJumpHere(v, addrInsLoop); + sqlite3VdbeAddOp1(v, OP_Close, 1); + } + + /* Compute the complete text of the CREATE statement */ + if( pSelect ){ + zStmt = createTableStmt(db, p); + }else{ + Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; + n = (int)(pEnd2->z - pParse->sNameToken.z); + if( pEnd2->z[0]!=';' ) n += pEnd2->n; + zStmt = sqlite3MPrintf(db, + "CREATE %s %.*s", zType2, n, pParse->sNameToken.z + ); + } + + /* A slot for the record has already been allocated in the + ** schema table. We just need to update that slot with all + ** the information we've collected. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE + " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q" + " WHERE rowid=#%d", + db->aDb[iDb].zDbSName, + zType, + p->zName, + p->zName, + pParse->regRoot, + zStmt, + pParse->regRowid + ); + sqlite3DbFree(db, zStmt); + sqlite3ChangeCookie(pParse, iDb); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Check to see if we need to create an sqlite_sequence table for + ** keeping track of autoincrement keys. + */ + if( (p->tabFlags & TF_Autoincrement)!=0 && !IN_SPECIAL_PARSE ){ + Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( pDb->pSchema->pSeqTab==0 ){ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.sqlite_sequence(name,seq)", + pDb->zDbSName + ); + } + } +#endif + + /* Reparse everything to update our internal data structures */ + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); + + /* Test for cycles in generated columns and illegal expressions + ** in CHECK constraints and in DEFAULT clauses. */ + if( p->tabFlags & TF_HasGenerated ){ + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); + } + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); + } + + /* Add the table to the in-memory representation of the database. + */ + if( db->init.busy ){ + Table *pOld; + Schema *pSchema = p->pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( HasRowid(p) || p->iPKey<0 ); + pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); + if( pOld ){ + assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ + sqlite3OomFault(db); + return; + } + pParse->pNewTable = 0; + db->mDbFlags |= DBFLAG_SchemaChange; + + /* If this is the magic sqlite_sequence table used by autoincrement, + ** then record a pointer to this table in the main database structure + ** so that INSERT can find the table easily. */ + assert( !pParse->nested ); +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( strcmp(p->zName, "sqlite_sequence")==0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + p->pSchema->pSeqTab = p; + } +#endif + } + +#ifndef SQLITE_OMIT_ALTERTABLE + if( !pSelect && IsOrdinaryTable(p) ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; + } + p->u.tab.addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); + } +#endif +} + +#ifndef SQLITE_OMIT_VIEW +/* +** The parser calls this routine in order to create a new VIEW +*/ +SQLITE_PRIVATE void sqlite3CreateView( + Parse *pParse, /* The parsing context */ + Token *pBegin, /* The CREATE token that begins the statement */ + Token *pName1, /* The token that holds the name of the view */ + Token *pName2, /* The token that holds the name of the view */ + ExprList *pCNames, /* Optional list of view column names */ + Select *pSelect, /* A SELECT statement that will become the new view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ +){ + Table *p; + int n; + const char *z; + Token sEnd; + DbFixer sFix; + Token *pName = 0; + int iDb; + sqlite3 *db = pParse->db; + + if( pParse->nVar>0 ){ + sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); + goto create_view_fail; + } + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); + p = pParse->pNewTable; + if( p==0 || pParse->nErr ) goto create_view_fail; + + /* Legacy versions of SQLite allowed the use of the magic "rowid" column + ** on a view, even though views do not have rowids. The following flag + ** setting fixes this problem. But the fix can be disabled by compiling + ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that + ** depend upon the old buggy behavior. The ability can also be toggled + ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */ +#else + p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */ +#endif + + sqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3SchemaToIndex(db, p->pSchema); + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); + if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; + + /* Make a copy of the entire SELECT statement that defines the view. + ** This will force all the Expr.token.z values to be dynamically + ** allocated rather than point to the input string - which means that + ** they will persist after the current sqlite3_exec() call returns. + */ + pSelect->selFlags |= SF_View; + if( IN_RENAME_OBJECT ){ + p->u.view.pSelect = pSelect; + pSelect = 0; + }else{ + p->u.view.pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } + p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); + p->eTabType = TABTYP_VIEW; + if( db->mallocFailed ) goto create_view_fail; + + /* Locate the end of the CREATE VIEW statement. Make sEnd point to + ** the end. + */ + sEnd = pParse->sLastToken; + assert( sEnd.z[0]!=0 || sEnd.n==0 ); + if( sEnd.z[0]!=';' ){ + sEnd.z += sEnd.n; + } + sEnd.n = 0; + n = (int)(sEnd.z - pBegin->z); + assert( n>0 ); + z = pBegin->z; + while( sqlite3Isspace(z[n-1]) ){ n--; } + sEnd.z = &z[n-1]; + sEnd.n = 1; + + /* Use sqlite3EndTable() to add the view to the schema table */ + sqlite3EndTable(pParse, 0, &sEnd, 0, 0); + +create_view_fail: + sqlite3SelectDelete(db, pSelect); + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprlistUnmap(pParse, pCNames); + } + sqlite3ExprListDelete(db, pCNames); + return; +} +#endif /* SQLITE_OMIT_VIEW */ + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** The Table structure pTable is really a VIEW. Fill in the names of +** the columns of the view in the pTable structure. Return the number +** of errors. If an error is seen leave an error message in pParse->zErrMsg. +*/ +static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ + Table *pSelTab; /* A fake table from which we get the result set */ + Select *pSel; /* Copy of the SELECT that implements the view */ + int nErr = 0; /* Number of errors encountered */ + sqlite3 *db = pParse->db; /* Database connection for malloc errors */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int rc; +#endif +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; /* Saved xAuth pointer */ +#endif + + assert( pTable ); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTable) ){ + db->nSchemaLock++; + rc = sqlite3VtabCallConnect(pParse, pTable); + db->nSchemaLock--; + return rc; + } +#endif + +#ifndef SQLITE_OMIT_VIEW + /* A positive nCol means the columns names for this view are + ** already known. This routine is not called unless either the + ** table is virtual or nCol is zero. + */ + assert( pTable->nCol<=0 ); + + /* A negative nCol is a special marker meaning that we are currently + ** trying to compute the column names. If we enter this routine with + ** a negative nCol, it means two or more views form a loop, like this: + ** + ** CREATE VIEW one AS SELECT * FROM two; + ** CREATE VIEW two AS SELECT * FROM one; + ** + ** Actually, the error above is now caught prior to reaching this point. + ** But the following test is still important as it does come up + ** in the following: + ** + ** CREATE TABLE main.ex1(a); + ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; + ** SELECT * FROM temp.ex1; + */ + if( pTable->nCol<0 ){ + sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); + return 1; + } + assert( pTable->nCol>=0 ); + + /* If we get this far, it means we need to compute the table names. + ** Note that the call to sqlite3ResultSetOfSelect() will expand any + ** "*" elements in the results set of the view and will assign cursors + ** to the elements of the FROM clause. But we do not want these changes + ** to be permanent. So the computation is done on a copy of the SELECT + ** statement that defines the view. + */ + assert( IsView(pTable) ); + pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0); + if( pSel ){ + u8 eParseMode = pParse->eParseMode; + int nTab = pParse->nTab; + int nSelect = pParse->nSelect; + pParse->eParseMode = PARSE_MODE_NORMAL; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); + pTable->nCol = -1; + DisableLookaside; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; + db->xAuth = 0; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); + db->xAuth = xAuth; +#else + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); +#endif + pParse->nTab = nTab; + pParse->nSelect = nSelect; + if( pSelTab==0 ){ + pTable->nCol = 0; + nErr++; + }else if( pTable->pCheck ){ + /* CREATE VIEW name(arglist) AS ... + ** The names of the columns in the table are taken from + ** arglist which is stored in pTable->pCheck. The pCheck field + ** normally holds CHECK constraints on an ordinary table, but for + ** a VIEW it holds the list of column names. + */ + sqlite3ColumnsFromExprList(pParse, pTable->pCheck, + &pTable->nCol, &pTable->aCol); + if( pParse->nErr==0 + && pTable->nCol==pSel->pEList->nExpr + ){ + assert( db->mallocFailed==0 ); + sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE); + } + }else{ + /* CREATE VIEW name AS... without an argument list. Construct + ** the column names from the SELECT statement that defines the view. + */ + assert( pTable->aCol==0 ); + pTable->nCol = pSelTab->nCol; + pTable->aCol = pSelTab->aCol; + pTable->tabFlags |= (pSelTab->tabFlags & COLFLAG_NOINSERT); + pSelTab->nCol = 0; + pSelTab->aCol = 0; + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); + } + pTable->nNVCol = pTable->nCol; + sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDelete(db, pSel); + EnableLookaside; + pParse->eParseMode = eParseMode; + } else { + nErr++; + } + pTable->pSchema->schemaFlags |= DB_UnresetViews; + if( db->mallocFailed ){ + sqlite3DeleteColumnNames(db, pTable); + } +#endif /* SQLITE_OMIT_VIEW */ + return nErr; +} +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ + assert( pTable!=0 ); + if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0; + return viewGetColumnNames(pParse, pTable); +} +#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifndef SQLITE_OMIT_VIEW +/* +** Clear the column names from every VIEW in database idx. +*/ +static void sqliteViewResetAll(sqlite3 *db, int idx){ + HashElem *i; + assert( sqlite3SchemaMutexHeld(db, idx, 0) ); + if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; + for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + if( IsView(pTab) ){ + sqlite3DeleteColumnNames(db, pTab); + } + } + DbClearProperty(db, idx, DB_UnresetViews); +} +#else +# define sqliteViewResetAll(A,B) +#endif /* SQLITE_OMIT_VIEW */ + +/* +** This function is called by the VDBE to adjust the internal schema +** used by SQLite when the btree layer moves a table root page. The +** root-page of a table or index in database iDb has changed from iFrom +** to iTo. +** +** Ticket #1728: The symbol table might still contain information +** on tables and/or indices that are the process of being deleted. +** If you are unlucky, one of those deleted indices or tables might +** have the same rootpage number as the real table or index that is +** being moved. So we cannot stop searching after the first match +** because the first match might be for one of the deleted indices +** or tables and not the table/index that is actually being moved. +** We must continue looping until all tables and indices with +** rootpage==iFrom have been converted to have a rootpage of iTo +** in order to be certain that we got the right one. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, Pgno iFrom, Pgno iTo){ + HashElem *pElem; + Hash *pHash; + Db *pDb; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb = &db->aDb[iDb]; + pHash = &pDb->pSchema->tblHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + if( pTab->tnum==iFrom ){ + pTab->tnum = iTo; + } + } + pHash = &pDb->pSchema->idxHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Index *pIdx = sqliteHashData(pElem); + if( pIdx->tnum==iFrom ){ + pIdx->tnum = iTo; + } + } +} +#endif + +/* +** Write code to erase the table with root-page iTable from database iDb. +** Also write code to modify the sqlite_schema table and internal schema +** if a root-page of another table is moved by the btree-layer whilst +** erasing iTable (this can happen with an auto-vacuum database). +*/ +static void destroyRootPage(Parse *pParse, int iTable, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + int r1 = sqlite3GetTempReg(pParse); + if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema"); + sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); + sqlite3MayAbort(pParse); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* OP_Destroy stores an in integer r1. If this integer + ** is non-zero, then it is the root page number of a table moved to + ** location iTable. The following code modifies the sqlite_schema table to + ** reflect this. + ** + ** The "#NNN" in the SQL is a special constant that means whatever value + ** is in register NNN. See grammar rules associated with the TK_REGISTER + ** token for additional information. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE + " SET rootpage=%d WHERE #%d AND rootpage=#%d", + pParse->db->aDb[iDb].zDbSName, iTable, r1, r1); +#endif + sqlite3ReleaseTempReg(pParse, r1); +} + +/* +** Write VDBE code to erase table pTab and all associated indices on disk. +** Code to update the sqlite_schema tables and internal schema definitions +** in case a root-page belonging to another table is moved by the btree layer +** is also added (this can happen with an auto-vacuum database). +*/ +static void destroyTable(Parse *pParse, Table *pTab){ + /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM + ** is not defined), then it is important to call OP_Destroy on the + ** table and index root-pages in order, starting with the numerically + ** largest root-page number. This guarantees that none of the root-pages + ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the + ** following were coded: + ** + ** OP_Destroy 4 0 + ** ... + ** OP_Destroy 5 0 + ** + ** and root page 5 happened to be the largest root-page number in the + ** database, then root page 5 would be moved to page 4 by the + ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit + ** a free-list page. + */ + Pgno iTab = pTab->tnum; + Pgno iDestroyed = 0; + + while( 1 ){ + Index *pIdx; + Pgno iLargest = 0; + + if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ + Pgno iIdx = pIdx->tnum; + assert( pIdx->pSchema==pTab->pSchema ); + if( (iDestroyed==0 || (iIdxiLargest ){ + iLargest = iIdx; + } + } + if( iLargest==0 ){ + return; + }else{ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + assert( iDb>=0 && iDbdb->nDb ); + destroyRootPage(pParse, iLargest, iDb); + iDestroyed = iLargest; + } + } +} + +/* +** Remove entries from the sqlite_statN tables (for N in (1,2,3)) +** after a DROP INDEX or DROP TABLE command. +*/ +static void sqlite3ClearStatTables( + Parse *pParse, /* The parsing context */ + int iDb, /* The database number */ + const char *zType, /* "idx" or "tbl" */ + const char *zName /* Name of index or table */ +){ + int i; + const char *zDbName = pParse->db->aDb[iDb].zDbSName; + for(i=1; i<=4; i++){ + char zTab[24]; + sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); + if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + zDbName, zTab, zType, zName + ); + } + } +} + +/* +** Generate code to drop a table. +*/ +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ + Vdbe *v; + sqlite3 *db = pParse->db; + Trigger *pTrigger; + Db *pDb = &db->aDb[iDb]; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* Drop all triggers associated with the table being dropped. Code + ** is generated to remove entries from sqlite_schema and/or + ** sqlite_temp_schema if required. + */ + pTrigger = sqlite3TriggerList(pParse, pTab); + while( pTrigger ){ + assert( pTrigger->pSchema==pTab->pSchema || + pTrigger->pSchema==db->aDb[1].pSchema ); + sqlite3DropTriggerPtr(pParse, pTrigger); + pTrigger = pTrigger->pNext; + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Remove any entries of the sqlite_sequence table associated with + ** the table being dropped. This is done before the table is dropped + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->tabFlags & TF_Autoincrement ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", + pDb->zDbSName, pTab->zName + ); + } +#endif + + /* Drop all entries in the schema table that refer to the + ** table. The program name loops through the schema table and deletes + ** every row that refers to a table of the same name as the one being + ** dropped. Triggers are handled separately because a trigger can be + ** created in the temp database that refers to a table in another + ** database. + */ + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE + " WHERE tbl_name=%Q and type!='trigger'", + pDb->zDbSName, pTab->zName); + if( !isView && !IsVirtual(pTab) ){ + destroyTable(pParse, pTab); + } + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); + sqliteViewResetAll(db, iDb); +} + +/* +** Return TRUE if shadow tables should be read-only in the current +** context. +*/ +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (db->flags & SQLITE_Defensive)!=0 + && db->pVtabCtx==0 + && db->nVdbeExec==0 + && !sqlite3VtabInSync(db) + ){ + return 1; + } +#endif + return 0; +} + +/* +** Return true if it is not allowed to drop the given table +*/ +static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; + if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; + return 1; + } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + return 1; + } + if( pTab->tabFlags & TF_Eponymous ){ + return 1; + } + return 0; +} + +/* +** This routine is called to do the work of a DROP TABLE statement. +** pName is the name of the table to be dropped. +*/ +SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ + Table *pTab; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + if( db->mallocFailed ){ + goto exit_drop_table; + } + assert( pParse->nErr==0 ); + assert( pName->nSrc==1 ); + if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; + if( noErr ) db->suppressErr++; + assert( isView==0 || isView==LOCATE_VIEW ); + pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); + if( noErr ) db->suppressErr--; + + if( pTab==0 ){ + if( noErr ){ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3ForceNotReadOnly(pParse); + } + goto exit_drop_table; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 && iDbnDb ); + + /* If pTab is a virtual table, call ViewGetColumnNames() to ensure + ** it is initialized. + */ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code; + const char *zTab = SCHEMA_TABLE(iDb); + const char *zDb = db->aDb[iDb].zDbSName; + const char *zArg2 = 0; + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ + goto exit_drop_table; + } + if( isView ){ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_VIEW; + }else{ + code = SQLITE_DROP_VIEW; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( IsVirtual(pTab) ){ + code = SQLITE_DROP_VTABLE; + zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; +#endif + }else{ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_TABLE; + }else{ + code = SQLITE_DROP_TABLE; + } + } + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ + goto exit_drop_table; + } + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ + goto exit_drop_table; + } + } +#endif + if( tableMayNotBeDropped(db, pTab) ){ + sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); + goto exit_drop_table; + } + +#ifndef SQLITE_OMIT_VIEW + /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used + ** on a table. + */ + if( isView && !IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); + goto exit_drop_table; + } + if( !isView && IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); + goto exit_drop_table; + } +#endif + + /* Generate code to remove the table from the schema table + ** on disk. + */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + if( !isView ){ + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); + } + sqlite3CodeDropTable(pParse, pTab, iDb, isView); + } + +exit_drop_table: + sqlite3SrcListDelete(db, pName); +} + +/* +** This routine is called to create a new foreign key on the table +** currently under construction. pFromCol determines which columns +** in the current table point to the foreign key. If pFromCol==0 then +** connect the key to the last column inserted. pTo is the name of +** the table referred to (a.k.a the "parent" table). pToCol is a list +** of tables in the parent pTo table. flags contains all +** information about the conflict resolution algorithms specified +** in the ON DELETE, ON UPDATE and ON INSERT clauses. +** +** An FKey structure is created and added to the table currently +** under construction in the pParse->pNewTable field. +** +** The foreign key is set for IMMEDIATE processing. A subsequent call +** to sqlite3DeferForeignKey() might change this to DEFERRED. +*/ +SQLITE_PRIVATE void sqlite3CreateForeignKey( + Parse *pParse, /* Parsing context */ + ExprList *pFromCol, /* Columns in this table that point to other table */ + Token *pTo, /* Name of the other table */ + ExprList *pToCol, /* Columns in the other table */ + int flags /* Conflict resolution algorithms. */ +){ + sqlite3 *db = pParse->db; +#ifndef SQLITE_OMIT_FOREIGN_KEY + FKey *pFKey = 0; + FKey *pNextTo; + Table *p = pParse->pNewTable; + i64 nByte; + int i; + int nCol; + char *z; + + assert( pTo!=0 ); + if( p==0 || IN_DECLARE_VTAB ) goto fk_end; + if( pFromCol==0 ){ + int iCol = p->nCol-1; + if( NEVER(iCol<0) ) goto fk_end; + if( pToCol && pToCol->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "foreign key on %s" + " should reference only one column of table %T", + p->aCol[iCol].zCnName, pTo); + goto fk_end; + } + nCol = 1; + }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ + sqlite3ErrorMsg(pParse, + "number of columns in foreign key does not match the number of " + "columns in the referenced table"); + goto fk_end; + }else{ + nCol = pFromCol->nExpr; + } + nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; + if( pToCol ){ + for(i=0; inExpr; i++){ + nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; + } + } + pFKey = sqlite3DbMallocZero(db, nByte ); + if( pFKey==0 ){ + goto fk_end; + } + pFKey->pFrom = p; + assert( IsOrdinaryTable(p) ); + pFKey->pNextFrom = p->u.tab.pFKey; + z = (char*)&pFKey->aCol[nCol]; + pFKey->zTo = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)z, pTo); + } + memcpy(z, pTo->z, pTo->n); + z[pTo->n] = 0; + sqlite3Dequote(z); + z += pTo->n+1; + pFKey->nCol = nCol; + if( pFromCol==0 ){ + pFKey->aCol[0].iFrom = p->nCol-1; + }else{ + for(i=0; inCol; j++){ + if( sqlite3StrICmp(p->aCol[j].zCnName, pFromCol->a[i].zEName)==0 ){ + pFKey->aCol[i].iFrom = j; + break; + } + } + if( j>=p->nCol ){ + sqlite3ErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", + pFromCol->a[i].zEName); + goto fk_end; + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName); + } + } + } + if( pToCol ){ + for(i=0; ia[i].zEName); + pFKey->aCol[i].zCol = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName); + } + memcpy(z, pToCol->a[i].zEName, n); + z[n] = 0; + z += n+1; + } + } + pFKey->isDeferred = 0; + pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ + pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ + + assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + pFKey->zTo, (void *)pFKey + ); + if( pNextTo==pFKey ){ + sqlite3OomFault(db); + goto fk_end; + } + if( pNextTo ){ + assert( pNextTo->pPrevTo==0 ); + pFKey->pNextTo = pNextTo; + pNextTo->pPrevTo = pFKey; + } + + /* Link the foreign key to the table as the last step. + */ + assert( IsOrdinaryTable(p) ); + p->u.tab.pFKey = pFKey; + pFKey = 0; + +fk_end: + sqlite3DbFree(db, pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + sqlite3ExprListDelete(db, pFromCol); + sqlite3ExprListDelete(db, pToCol); +} + +/* +** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED +** clause is seen as part of a foreign key definition. The isDeferred +** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE. +** The behavior of the most recently created foreign key is adjusted +** accordingly. +*/ +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY + Table *pTab; + FKey *pFKey; + if( (pTab = pParse->pNewTable)==0 ) return; + if( NEVER(!IsOrdinaryTable(pTab)) ) return; + if( (pFKey = pTab->u.tab.pFKey)==0 ) return; + assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ + pFKey->isDeferred = (u8)isDeferred; +#endif +} + +/* +** Generate code that will erase and refill index *pIdx. This is +** used to initialize a newly created index or to recompute the +** content of an index in response to a REINDEX command. +** +** if memRootPage is not negative, it means that the index is newly +** created. The register specified by memRootPage contains the +** root page number of the index. If memRootPage is negative, then +** the index already exists and must be cleared before being refilled and +** the root page number of the index is taken from pIndex->tnum. +*/ +static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ + Table *pTab = pIndex->pTable; /* The table that is indexed */ + int iTab = pParse->nTab++; /* Btree cursor used for pTab */ + int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ + int iSorter; /* Cursor opened by OpenSorter (if in use) */ + int addr1; /* Address of top of loop */ + int addr2; /* Address to jump to for next iteration */ + Pgno tnum; /* Root page of index */ + int iPartIdxLabel; /* Jump to this label to skip a row */ + Vdbe *v; /* Generate code into this virtual machine */ + KeyInfo *pKey; /* KeyInfo for index */ + int regRecord; /* Register holding assembled index record */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + db->aDb[iDb].zDbSName ) ){ + return; + } +#endif + + /* Require a write-lock on the table to perform this operation */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + + v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + if( memRootPage>=0 ){ + tnum = (Pgno)memRootPage; + }else{ + tnum = pIndex->tnum; + } + pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); + assert( pKey!=0 || pParse->nErr ); + + /* Open the sorter cursor if we are to use one. */ + iSorter = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) + sqlite3KeyInfoRef(pKey), P4_KEYINFO); + + /* Open the table. Loop through all rows of the table, inserting index + ** records into the sorter. */ + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); + regRecord = sqlite3GetTempReg(pParse); + sqlite3MultiWrite(pParse); + + sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, (int)tnum, iDb, + (char *)pKey, P4_KEYINFO); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); + + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); + if( IsUniqueIndex(pIndex) ){ + int j2 = sqlite3VdbeGoto(v, 1); + addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyAbortable(v, OE_Abort); + sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, + pIndex->nKeyCol); VdbeCoverage(v); + sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); + sqlite3VdbeJumpHere(v, j2); + }else{ + /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not + ** abort. The exception is if one of the indexed expressions contains a + ** user function that throws an exception when it is evaluated. But the + ** overhead of adding a statement journal to a CREATE INDEX statement is + ** very small (since most of the pages written do not contain content that + ** needs to be restored if the statement aborts), so we call + ** sqlite3MayAbort() for all CREATE INDEX statements. */ + sqlite3MayAbort(pParse); + addr2 = sqlite3VdbeCurrentAddr(v); + } + sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); + if( !pIndex->bAscKeyBug ){ + /* This OP_SeekEnd opcode makes index insert for a REINDEX go much + ** faster by avoiding unnecessary seeks. But the optimization does + ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables + ** with DESC primary keys, since those indexes have there keys in + ** a different order from the main table. + ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf + */ + sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); + } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + + sqlite3VdbeAddOp1(v, OP_Close, iTab); + sqlite3VdbeAddOp1(v, OP_Close, iIdx); + sqlite3VdbeAddOp1(v, OP_Close, iSorter); +} + +/* +** Allocate heap space to hold an Index object with nCol columns. +** +** Increase the allocation size to provide an extra nExtra bytes +** of 8-byte aligned space after the Index object and return a +** pointer to this extra space in *ppExtra. +*/ +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( + sqlite3 *db, /* Database connection */ + i16 nCol, /* Total number of columns in the index */ + int nExtra, /* Number of bytes of extra space to alloc */ + char **ppExtra /* Pointer to the "extra" space */ +){ + Index *p; /* Allocated index object */ + int nByte; /* Bytes of space for Index object + arrays */ + + nByte = ROUND8(sizeof(Index)) + /* Index structure */ + ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ + ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ + sizeof(i16)*nCol + /* Index.aiColumn */ + sizeof(u8)*nCol); /* Index.aSortOrder */ + p = sqlite3DbMallocZero(db, nByte + nExtra); + if( p ){ + char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); + p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); + p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); + p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; + p->aSortOrder = (u8*)pExtra; + p->nColumn = nCol; + p->nKeyCol = nCol - 1; + *ppExtra = ((char*)p) + nByte; + } + return p; +} + +/* +** If expression list pList contains an expression that was parsed with +** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in +** pParse and return non-zero. Otherwise, return zero. +*/ +SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ + if( pList ){ + int i; + for(i=0; inExpr; i++){ + if( pList->a[i].fg.bNulls ){ + u8 sf = pList->a[i].fg.sortFlags; + sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", + (sf==0 || sf==3) ? "FIRST" : "LAST" + ); + return 1; + } + } + } + return 0; +} + +/* +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will +** be NULL for a primary key or an index that is created to satisfy a +** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable +** as the table to be indexed. pParse->pNewTable is a table that is +** currently being constructed by a CREATE TABLE statement. +** +** pList is a list of columns to be indexed. pList will be NULL if this +** is a primary key or unique-constraint on the most recent column added +** to the table currently under construction. +*/ +SQLITE_PRIVATE void sqlite3CreateIndex( + Parse *pParse, /* All information about this parse */ + Token *pName1, /* First part of index name. May be NULL */ + Token *pName2, /* Second part of index name. May be NULL */ + SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ + ExprList *pList, /* A list of columns to be indexed */ + int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + Token *pStart, /* The CREATE token that begins this statement */ + Expr *pPIWhere, /* WHERE clause for partial indices */ + int sortOrder, /* Sort order of primary key when pList==NULL */ + int ifNotExist, /* Omit error if index already exists */ + u8 idxType /* The index type */ +){ + Table *pTab = 0; /* Table to be indexed */ + Index *pIndex = 0; /* The index to be created */ + char *zName = 0; /* Name of the index */ + int nName; /* Number of characters in zName */ + int i, j; + DbFixer sFix; /* For assigning database names to pTable */ + int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ + sqlite3 *db = pParse->db; + Db *pDb; /* The specific table containing the indexed database */ + int iDb; /* Index of the database that is being written */ + Token *pName = 0; /* Unqualified name of the index to create */ + struct ExprList_item *pListItem; /* For looping over pList */ + int nExtra = 0; /* Space allocated for zExtra[] */ + int nExtraCol; /* Number of extra columns needed */ + char *zExtra = 0; /* Extra space after the Index object */ + Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ + + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto exit_create_index; + } + assert( db->mallocFailed==0 ); + if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ + goto exit_create_index; + } + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_create_index; + } + if( sqlite3HasExplicitNulls(pParse, pList) ){ + goto exit_create_index; + } + + /* + ** Find the table that is to be indexed. Return early if not found. + */ + if( pTblName!=0 ){ + + /* Use the two-part index name to determine the database + ** to search for the table. 'Fix' the table name to this db + ** before looking up the table. + */ + assert( pName1 && pName2 ); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) goto exit_create_index; + assert( pName && pName->z ); + +#ifndef SQLITE_OMIT_TEMPDB + /* If the index name was unqualified, check if the table + ** is a temp table. If so, set the database to 1. Do not do this + ** if initializing a database schema. + */ + if( !db->init.busy ){ + pTab = sqlite3SrcListLookup(pParse, pTblName); + if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } + } +#endif + + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); + if( sqlite3FixSrcList(&sFix, pTblName) ){ + /* Because the parser constructs pTblName from a single identifier, + ** sqlite3FixSrcList can never fail. */ + assert(0); + } + pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); + assert( db->mallocFailed==0 || pTab==0 ); + if( pTab==0 ) goto exit_create_index; + if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ + sqlite3ErrorMsg(pParse, + "cannot create a TEMP index on non-TEMP table \"%s\"", + pTab->zName); + goto exit_create_index; + } + if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab); + }else{ + assert( pName==0 ); + assert( pStart==0 ); + pTab = pParse->pNewTable; + if( !pTab ) goto exit_create_index; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + } + pDb = &db->aDb[iDb]; + + assert( pTab!=0 ); + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && db->init.busy==0 + && pTblName!=0 +#if SQLITE_USER_AUTHENTICATION + && sqlite3UserAuthTable(pTab->zName)==0 +#endif + ){ + sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); + goto exit_create_index; + } +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "views may not be indexed"); + goto exit_create_index; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); + goto exit_create_index; + } +#endif + + /* + ** Find the name of the index. Make sure there is not already another + ** index or table with the same name. + ** + ** Exception: If we are reading the names of permanent indices from the + ** sqlite_schema table (because some other process changed the schema) and + ** one of the index names collides with the name of a temporary table or + ** index, then we will continue to process this index. + ** + ** If pName==0 it means that we are + ** dealing with a primary key or UNIQUE constraint. We have to invent our + ** own name. + */ + if( pName ){ + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ) goto exit_create_index; + assert( pName->z!=0 ); + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ + goto exit_create_index; + } + if( !IN_RENAME_OBJECT ){ + if( !db->init.busy ){ + if( sqlite3FindTable(db, zName, pDb->zDbSName)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + goto exit_create_index; + } + } + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3ForceNotReadOnly(pParse); + } + goto exit_create_index; + } + } + }else{ + int n; + Index *pLoop; + for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} + zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); + if( zName==0 ){ + goto exit_create_index; + } + + /* Automatic index names generated from within sqlite3_declare_vtab() + ** must have names that are distinct from normal automatic index names. + ** The following statement converts "sqlite3_autoindex..." into + ** "sqlite3_butoindex..." in order to make the names distinct. + ** The "vtab_err.test" test demonstrates the need of this statement. */ + if( IN_SPECIAL_PARSE ) zName[7]++; + } + + /* Check for authorization to create an index. + */ +#ifndef SQLITE_OMIT_AUTHORIZATION + if( !IN_RENAME_OBJECT ){ + const char *zDb = pDb->zDbSName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ + goto exit_create_index; + } + i = SQLITE_CREATE_INDEX; + if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX; + if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ + goto exit_create_index; + } + } +#endif + + /* If pList==0, it means this routine was called to make a primary + ** key out of the last column added to the table under construction. + ** So create a fake list to simulate this. + */ + if( pList==0 ){ + Token prevCol; + Column *pCol = &pTab->aCol[pTab->nCol-1]; + pCol->colFlags |= COLFLAG_UNIQUE; + sqlite3TokenInit(&prevCol, pCol->zCnName); + pList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); + if( pList==0 ) goto exit_create_index; + assert( pList->nExpr==1 ); + sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED); + }else{ + sqlite3ExprListCheckLength(pParse, pList, "index"); + if( pParse->nErr ) goto exit_create_index; + } + + /* Figure out how many bytes of space are required to store explicitly + ** specified collation sequence names. + */ + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + assert( pExpr!=0 ); + if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); + } + } + + /* + ** Allocate the index structure. + */ + nName = sqlite3Strlen30(zName); + nExtraCol = pPk ? pPk->nKeyCol : 1; + assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ ); + pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, + nName + nExtra + 1, &zExtra); + if( db->mallocFailed ){ + goto exit_create_index; + } + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) ); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); + pIndex->zName = zExtra; + zExtra += nName + 1; + memcpy(pIndex->zName, zName, nName+1); + pIndex->pTable = pTab; + pIndex->onError = (u8)onError; + pIndex->uniqNotNull = onError!=OE_None; + pIndex->idxType = idxType; + pIndex->pSchema = db->aDb[iDb].pSchema; + pIndex->nKeyCol = pList->nExpr; + if( pPIWhere ){ + sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); + pIndex->pPartIdxWhere = pPIWhere; + pPIWhere = 0; + } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + + /* Check to see if we should honor DESC requests on index columns + */ + if( pDb->pSchema->file_format>=4 ){ + sortOrderMask = -1; /* Honor DESC */ + }else{ + sortOrderMask = 0; /* Ignore DESC */ + } + + /* Analyze the list of expressions that form the terms of the index and + ** report any errors. In the common case where the expression is exactly + ** a table column, store that column in aiColumn[]. For general expressions, + ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[]. + ** + ** TODO: Issue a warning if two or more columns of the index are identical. + ** TODO: Issue a warning if the table primary key is used as part of the + ** index key. + */ + pListItem = pList->a; + if( IN_RENAME_OBJECT ){ + pIndex->aColExpr = pList; + pList = 0; + } + for(i=0; inKeyCol; i++, pListItem++){ + Expr *pCExpr; /* The i-th index expression */ + int requestedSortOrder; /* ASC or DESC on the i-th expression */ + const char *zColl; /* Collation sequence name */ + + sqlite3StringToId(pListItem->pExpr); + sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0); + if( pParse->nErr ) goto exit_create_index; + pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr); + if( pCExpr->op!=TK_COLUMN ){ + if( pTab==pParse->pNewTable ){ + sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and " + "UNIQUE constraints"); + goto exit_create_index; + } + if( pIndex->aColExpr==0 ){ + pIndex->aColExpr = pList; + pList = 0; + } + j = XN_EXPR; + pIndex->aiColumn[i] = XN_EXPR; + pIndex->uniqNotNull = 0; + pIndex->bHasExpr = 1; + }else{ + j = pCExpr->iColumn; + assert( j<=0x7fff ); + if( j<0 ){ + j = pTab->iPKey; + }else{ + if( pTab->aCol[j].notNull==0 ){ + pIndex->uniqNotNull = 0; + } + if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ + pIndex->bHasVCol = 1; + pIndex->bHasExpr = 1; + } + } + pIndex->aiColumn[i] = (i16)j; + } + zColl = 0; + if( pListItem->pExpr->op==TK_COLLATE ){ + int nColl; + assert( !ExprHasProperty(pListItem->pExpr, EP_IntValue) ); + zColl = pListItem->pExpr->u.zToken; + nColl = sqlite3Strlen30(zColl) + 1; + assert( nExtra>=nColl ); + memcpy(zExtra, zColl, nColl); + zColl = zExtra; + zExtra += nColl; + nExtra -= nColl; + }else if( j>=0 ){ + zColl = sqlite3ColumnColl(&pTab->aCol[j]); + } + if( !zColl ) zColl = sqlite3StrBINARY; + if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ + goto exit_create_index; + } + pIndex->azColl[i] = zColl; + requestedSortOrder = pListItem->fg.sortFlags & sortOrderMask; + pIndex->aSortOrder[i] = (u8)requestedSortOrder; + } + + /* Append the table key to the end of the index. For WITHOUT ROWID + ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For + ** normal tables (when pPk==0) this will be the rowid. + */ + if( pPk ){ + for(j=0; jnKeyCol; j++){ + int x = pPk->aiColumn[j]; + assert( x>=0 ); + if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){ + pIndex->nColumn--; + }else{ + testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) ); + pIndex->aiColumn[i] = x; + pIndex->azColl[i] = pPk->azColl[j]; + pIndex->aSortOrder[i] = pPk->aSortOrder[j]; + i++; + } + } + assert( i==pIndex->nColumn ); + }else{ + pIndex->aiColumn[i] = XN_ROWID; + pIndex->azColl[i] = sqlite3StrBINARY; + } + sqlite3DefaultRowEst(pIndex); + if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); + + /* If this index contains every column of its table, then mark + ** it as a covering index */ + assert( HasRowid(pTab) + || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); + recomputeColumnsNotIndexed(pIndex); + if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ + pIndex->isCovering = 1; + for(j=0; jnCol; j++){ + if( j==pTab->iPKey ) continue; + if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue; + pIndex->isCovering = 0; + break; + } + } + + if( pTab==pParse->pNewTable ){ + /* This routine has been called to create an automatic index as a + ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or + ** a PRIMARY KEY or UNIQUE clause following the column definitions. + ** i.e. one of: + ** + ** CREATE TABLE t(x PRIMARY KEY, y); + ** CREATE TABLE t(x, y, UNIQUE(x, y)); + ** + ** Either way, check to see if the table already has such an index. If + ** so, don't bother creating this one. This only applies to + ** automatically created indices. Users can do as they wish with + ** explicit indices. + ** + ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent + ** (and thus suppressing the second one) even if they have different + ** sort orders. + ** + ** If there are different collating sequences or if the columns of + ** the constraint occur in different orders, then the constraints are + ** considered distinct and both result in separate indices. + */ + Index *pIdx; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int k; + assert( IsUniqueIndex(pIdx) ); + assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); + assert( IsUniqueIndex(pIndex) ); + + if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; + for(k=0; knKeyCol; k++){ + const char *z1; + const char *z2; + assert( pIdx->aiColumn[k]>=0 ); + if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; + z1 = pIdx->azColl[k]; + z2 = pIndex->azColl[k]; + if( sqlite3StrICmp(z1, z2) ) break; + } + if( k==pIdx->nKeyCol ){ + if( pIdx->onError!=pIndex->onError ){ + /* This constraint creates the same index as a previous + ** constraint specified somewhere in the CREATE TABLE statement. + ** However the ON CONFLICT clauses are different. If both this + ** constraint and the previous equivalent constraint have explicit + ** ON CONFLICT clauses this is an error. Otherwise, use the + ** explicitly specified behavior for the index. + */ + if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ + sqlite3ErrorMsg(pParse, + "conflicting ON CONFLICT clauses specified", 0); + } + if( pIdx->onError==OE_Default ){ + pIdx->onError = pIndex->onError; + } + } + if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType; + if( IN_RENAME_OBJECT ){ + pIndex->pNext = pParse->pNewIndex; + pParse->pNewIndex = pIndex; + pIndex = 0; + } + goto exit_create_index; + } + } + } + + if( !IN_RENAME_OBJECT ){ + + /* Link the new Index structure to its table and to the other + ** in-memory database structures. + */ + assert( pParse->nErr==0 ); + if( db->init.busy ){ + Index *p; + assert( !IN_SPECIAL_PARSE ); + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + if( sqlite3IndexHasDuplicateRootPage(pIndex) ){ + sqlite3ErrorMsg(pParse, "invalid rootpage"); + pParse->rc = SQLITE_CORRUPT_BKPT; + goto exit_create_index; + } + } + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + pIndex->zName, pIndex); + if( p ){ + assert( p==pIndex ); /* Malloc must have failed */ + sqlite3OomFault(db); + goto exit_create_index; + } + db->mDbFlags |= DBFLAG_SchemaChange; + } + + /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the + ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then + ** emit code to allocate the index rootpage on disk and make an entry for + ** the index in the sqlite_schema table and populate the index with + ** content. But, do not do this if we are simply reading the sqlite_schema + ** table to parse the schema, or if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table. + ** + ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY + ** or UNIQUE index in a CREATE TABLE statement. Since the table + ** has just been created, it contains no data and the index initialization + ** step can be skipped. + */ + else if( HasRowid(pTab) || pTblName!=0 ){ + Vdbe *v; + char *zStmt; + int iMem = ++pParse->nMem; + + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto exit_create_index; + + sqlite3BeginWriteOperation(pParse, 1, iDb); + + /* Create the rootpage for the index using CreateIndex. But before + ** doing so, code a Noop instruction and store its address in + ** Index.tnum. This is required in case this index is actually a + ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In + ** that case the convertToWithoutRowidTable() routine will replace + ** the Noop with a Goto to jump over the VDBE code generated below. */ + pIndex->tnum = (Pgno)sqlite3VdbeAddOp0(v, OP_Noop); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ + assert( pName!=0 || pStart==0 ); + if( pStart ){ + int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; + if( pName->z[n-1]==';' ) n--; + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", n, pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; + } + + /* Add an entry in sqlite_schema for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zDbSName, + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); + sqlite3DbFree(db, zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ + if( pTblName ){ + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0); + sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); + } + + sqlite3VdbeJumpHere(v, (int)pIndex->tnum); + } + } + if( db->init.busy || pTblName==0 ){ + pIndex->pNext = pTab->pIndex; + pTab->pIndex = pIndex; + pIndex = 0; + } + else if( IN_RENAME_OBJECT ){ + assert( pParse->pNewIndex==0 ); + pParse->pNewIndex = pIndex; + pIndex = 0; + } + + /* Clean up before exiting */ +exit_create_index: + if( pIndex ) sqlite3FreeIndex(db, pIndex); + if( pTab ){ + /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list. + ** The list was already ordered when this routine was entered, so at this + ** point at most a single index (the newly added index) will be out of + ** order. So we have to reorder at most one index. */ + Index **ppFrom; + Index *pThis; + for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ + Index *pNext; + if( pThis->onError!=OE_Replace ) continue; + while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){ + *ppFrom = pNext; + pThis->pNext = pNext->pNext; + pNext->pNext = pThis; + ppFrom = &pNext->pNext; + } + break; + } +#ifdef SQLITE_DEBUG + /* Verify that all REPLACE indexes really are now at the end + ** of the index list. In other words, no other index type ever + ** comes after a REPLACE index on the list. */ + for(pThis = pTab->pIndex; pThis; pThis=pThis->pNext){ + assert( pThis->onError!=OE_Replace + || pThis->pNext==0 + || pThis->pNext->onError==OE_Replace ); + } +#endif + } + sqlite3ExprDelete(db, pPIWhere); + sqlite3ExprListDelete(db, pList); + sqlite3SrcListDelete(db, pTblName); + sqlite3DbFree(db, zName); +} + +/* +** Fill the Index.aiRowEst[] array with default information - information +** to be used when we have not run the ANALYZE command. +** +** aiRowEst[0] is supposed to contain the number of elements in the index. +** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the +** number of rows in the table that match any particular value of the +** first column of the index. aiRowEst[2] is an estimate of the number +** of rows that match any particular combination of the first 2 columns +** of the index. And so forth. It must always be the case that +* +** aiRowEst[N]<=aiRowEst[N-1] +** aiRowEst[N]>=1 +** +** Apart from that, we have little to go on besides intuition as to +** how aiRowEst[] should be initialized. The numbers generated here +** are based on typical values found in actual indices. +*/ +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ + /* 10, 9, 8, 7, 6 */ + static const LogEst aVal[] = { 33, 32, 30, 28, 26 }; + LogEst *a = pIdx->aiRowLogEst; + LogEst x; + int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); + int i; + + /* Indexes with default row estimates should not have stat1 data */ + assert( !pIdx->hasStat1 ); + + /* Set the first entry (number of rows in the index) to the estimated + ** number of rows in the table, or half the number of rows in the table + ** for a partial index. + ** + ** 2020-05-27: If some of the stat data is coming from the sqlite_stat1 + ** table but other parts we are having to guess at, then do not let the + ** estimated number of rows in the table be less than 1000 (LogEst 99). + ** Failure to do this can cause the indexes for which we do not have + ** stat1 data to be ignored by the query planner. + */ + x = pIdx->pTable->nRowLogEst; + assert( 99==sqlite3LogEst(1000) ); + if( x<99 ){ + pIdx->pTable->nRowLogEst = x = 99; + } + if( pIdx->pPartIdxWhere!=0 ){ x -= 10; assert( 10==sqlite3LogEst(2) ); } + a[0] = x; + + /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is + ** 6 and each subsequent value (if any) is 5. */ + memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); + for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ + a[i] = 23; assert( 23==sqlite3LogEst(5) ); + } + + assert( 0==sqlite3LogEst(1) ); + if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; +} + +/* +** This routine will drop an existing named index. This routine +** implements the DROP INDEX statement. +*/ +SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ + Index *pIndex; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + if( db->mallocFailed ){ + goto exit_drop_index; + } + assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ + assert( pName->nSrc==1 ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_drop_index; + } + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); + if( pIndex==0 ){ + if( !ifExists ){ + sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3ForceNotReadOnly(pParse); + } + pParse->checkSchema = 1; + goto exit_drop_index; + } + if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ + sqlite3ErrorMsg(pParse, "index associated with UNIQUE " + "or PRIMARY KEY constraint cannot be dropped", 0); + goto exit_drop_index; + } + iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code = SQLITE_DROP_INDEX; + Table *pTab = pIndex->pTable; + const char *zDb = db->aDb[iDb].zDbSName; + const char *zTab = SCHEMA_TABLE(iDb); + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + goto exit_drop_index; + } + if( !OMIT_TEMPDB && iDb==1 ) code = SQLITE_DROP_TEMP_INDEX; + if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ + goto exit_drop_index; + } + } +#endif + + /* Generate code to remove the index and from the schema table */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'", + db->aDb[iDb].zDbSName, pIndex->zName + ); + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); + sqlite3ChangeCookie(pParse, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); + } + +exit_drop_index: + sqlite3SrcListDelete(db, pName); +} + +/* +** pArray is a pointer to an array of objects. Each object in the +** array is szEntry bytes in size. This routine uses sqlite3DbRealloc() +** to extend the array so that there is space for a new object at the end. +** +** When this function is called, *pnEntry contains the current size of +** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes +** in total). +** +** If the realloc() is successful (i.e. if no OOM condition occurs), the +** space allocated for the new object is zeroed, *pnEntry updated to +** reflect the new size of the array and a pointer to the new allocation +** returned. *pIdx is set to the index of the new array entry in this case. +** +** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains +** unchanged and a copy of pArray returned. +*/ +SQLITE_PRIVATE void *sqlite3ArrayAllocate( + sqlite3 *db, /* Connection to notify of malloc failures */ + void *pArray, /* Array of objects. Might be reallocated */ + int szEntry, /* Size of each object in the array */ + int *pnEntry, /* Number of objects currently in use */ + int *pIdx /* Write the index of a new slot here */ +){ + char *z; + sqlite3_int64 n = *pIdx = *pnEntry; + if( (n & (n-1))==0 ){ + sqlite3_int64 sz = (n==0) ? 1 : 2*n; + void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); + if( pNew==0 ){ + *pIdx = -1; + return pArray; + } + pArray = pNew; + } + z = (char*)pArray; + memset(&z[n * szEntry], 0, szEntry); + ++*pnEntry; + return pArray; +} + +/* +** Append a new element to the given IdList. Create a new IdList if +** need be. +** +** A new IdList is returned, or NULL if malloc() fails. +*/ +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ + sqlite3 *db = pParse->db; + int i; + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(IdList) ); + if( pList==0 ) return 0; + }else{ + IdList *pNew; + pNew = sqlite3DbRealloc(db, pList, + sizeof(IdList) + pList->nId*sizeof(pList->a)); + if( pNew==0 ){ + sqlite3IdListDelete(db, pList); + return 0; + } + pList = pNew; + } + i = pList->nId++; + pList->a[i].zName = sqlite3NameFromToken(db, pToken); + if( IN_RENAME_OBJECT && pList->a[i].zName ){ + sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); + } + return pList; +} + +/* +** Delete an IdList. +*/ +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ + int i; + assert( db!=0 ); + if( pList==0 ) return; + assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */ + for(i=0; inId; i++){ + sqlite3DbFree(db, pList->a[i].zName); + } + sqlite3DbNNFreeNN(db, pList); +} + +/* +** Return the index in pList of the identifier named zId. Return -1 +** if not found. +*/ +SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ + int i; + assert( pList!=0 ); + for(i=0; inId; i++){ + if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; + } + return -1; +} + +/* +** Maximum size of a SrcList object. +** The SrcList object is used to represent the FROM clause of a +** SELECT statement, and the query planner cannot deal with more +** than 64 tables in a join. So any value larger than 64 here +** is sufficient for most uses. Smaller values, like say 10, are +** appropriate for small and memory-limited applications. +*/ +#ifndef SQLITE_MAX_SRCLIST +# define SQLITE_MAX_SRCLIST 200 +#endif + +/* +** Expand the space allocated for the given SrcList object by +** creating nExtra new slots beginning at iStart. iStart is zero based. +** New slots are zeroed. +** +** For example, suppose a SrcList initially contains two entries: A,B. +** To append 3 new entries onto the end, do this: +** +** sqlite3SrcListEnlarge(db, pSrclist, 3, 2); +** +** After the call above it would contain: A, B, nil, nil, nil. +** If the iStart argument had been 1 instead of 2, then the result +** would have been: A, nil, nil, nil, B. To prepend the new slots, +** the iStart value would be 0. The result then would +** be: nil, nil, nil, A, B. +** +** If a memory allocation fails or the SrcList becomes too large, leave +** the original SrcList unchanged, return NULL, and leave an error message +** in pParse. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( + Parse *pParse, /* Parsing context into which errors are reported */ + SrcList *pSrc, /* The SrcList to be enlarged */ + int nExtra, /* Number of new slots to add to pSrc->a[] */ + int iStart /* Index in pSrc->a[] of first new slot */ +){ + int i; + + /* Sanity checking on calling parameters */ + assert( iStart>=0 ); + assert( nExtra>=1 ); + assert( pSrc!=0 ); + assert( iStart<=pSrc->nSrc ); + + /* Allocate additional space if needed */ + if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ + SrcList *pNew; + sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra; + sqlite3 *db = pParse->db; + + if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){ + sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", + SQLITE_MAX_SRCLIST); + return 0; + } + if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; + pNew = sqlite3DbRealloc(db, pSrc, + sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); + if( pNew==0 ){ + assert( db->mallocFailed ); + return 0; + } + pSrc = pNew; + pSrc->nAlloc = nAlloc; + } + + /* Move existing slots that come after the newly inserted slots + ** out of the way */ + for(i=pSrc->nSrc-1; i>=iStart; i--){ + pSrc->a[i+nExtra] = pSrc->a[i]; + } + pSrc->nSrc += nExtra; + + /* Zero the newly allocated slots */ + memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra); + for(i=iStart; ia[i].iCursor = -1; + } + + /* Return a pointer to the enlarged SrcList */ + return pSrc; +} + + +/* +** Append a new table name to the given SrcList. Create a new SrcList if +** need be. A new entry is created in the SrcList even if pTable is NULL. +** +** A SrcList is returned, or NULL if there is an OOM error or if the +** SrcList grows to large. The returned +** SrcList might be the same as the SrcList that was input or it might be +** a new one. If an OOM error does occurs, then the prior value of pList +** that is input to this routine is automatically freed. +** +** If pDatabase is not null, it means that the table has an optional +** database name prefix. Like this: "database.table". The pDatabase +** points to the table name and the pTable points to the database name. +** The SrcList.a[].zName field is filled with the table name which might +** come from pTable (if pDatabase is NULL) or from pDatabase. +** SrcList.a[].zDatabase is filled with the database name from pTable, +** or with NULL if no database is specified. +** +** In other words, if call like this: +** +** sqlite3SrcListAppend(D,A,B,0); +** +** Then B is a table name and the database name is unspecified. If called +** like this: +** +** sqlite3SrcListAppend(D,A,B,C); +** +** Then C is the table name and B is the database name. If C is defined +** then so is B. In other words, we never have a case where: +** +** sqlite3SrcListAppend(D,A,0,C); +** +** Both pTable and pDatabase are assumed to be quoted. They are dequoted +** before being added to the SrcList. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( + Parse *pParse, /* Parsing context, in which errors are reported */ + SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ + Token *pTable, /* Table to append */ + Token *pDatabase /* Database of the table */ +){ + SrcItem *pItem; + sqlite3 *db; + assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ + assert( pParse!=0 ); + assert( pParse->db!=0 ); + db = pParse->db; + if( pList==0 ){ + pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); + if( pList==0 ) return 0; + pList->nAlloc = 1; + pList->nSrc = 1; + memset(&pList->a[0], 0, sizeof(pList->a[0])); + pList->a[0].iCursor = -1; + }else{ + SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc); + if( pNew==0 ){ + sqlite3SrcListDelete(db, pList); + return 0; + }else{ + pList = pNew; + } + } + pItem = &pList->a[pList->nSrc-1]; + if( pDatabase && pDatabase->z==0 ){ + pDatabase = 0; + } + if( pDatabase ){ + pItem->zName = sqlite3NameFromToken(db, pDatabase); + pItem->zDatabase = sqlite3NameFromToken(db, pTable); + }else{ + pItem->zName = sqlite3NameFromToken(db, pTable); + pItem->zDatabase = 0; + } + return pList; +} + +/* +** Assign VdbeCursor index numbers to all tables in a SrcList +*/ +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ + int i; + SrcItem *pItem; + assert( pList || pParse->db->mallocFailed ); + if( ALWAYS(pList) ){ + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->iCursor>=0 ) continue; + pItem->iCursor = pParse->nTab++; + if( pItem->pSelect ){ + sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + } + } + } +} + +/* +** Delete an entire SrcList including all its substructure. +*/ +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ + int i; + SrcItem *pItem; + assert( db!=0 ); + if( pList==0 ) return; + for(pItem=pList->a, i=0; inSrc; i++, pItem++){ + if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); + if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); + if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); + if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); + sqlite3DeleteTable(db, pItem->pTab); + if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); + if( pItem->fg.isUsing ){ + sqlite3IdListDelete(db, pItem->u3.pUsing); + }else if( pItem->u3.pOn ){ + sqlite3ExprDelete(db, pItem->u3.pOn); + } + } + sqlite3DbNNFreeNN(db, pList); +} + +/* +** This routine is called by the parser to add a new term to the +** end of a growing FROM clause. The "p" parameter is the part of +** the FROM clause that has already been constructed. "p" is NULL +** if this is the first term of the FROM clause. pTable and pDatabase +** are the name of the table and database named in the FROM clause term. +** pDatabase is NULL if the database name qualifier is missing - the +** usual case. If the term has an alias, then pAlias points to the +** alias token. If the term is a subquery, then pSubquery is the +** SELECT statement that the subquery encodes. The pTable and +** pDatabase parameters are NULL for subqueries. The pOn and pUsing +** parameters are the content of the ON and USING clauses. +** +** Return a new SrcList which encodes is the FROM with the new +** term added. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( + Parse *pParse, /* Parsing context */ + SrcList *p, /* The left part of the FROM clause already seen */ + Token *pTable, /* Name of the table to add to the FROM clause */ + Token *pDatabase, /* Name of the database containing pTable */ + Token *pAlias, /* The right-hand side of the AS subexpression */ + Select *pSubquery, /* A subquery used in place of a table name */ + OnOrUsing *pOnUsing /* Either the ON clause or the USING clause */ +){ + SrcItem *pItem; + sqlite3 *db = pParse->db; + if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){ + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + (pOnUsing->pOn ? "ON" : "USING") + ); + goto append_from_error; + } + p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase); + if( p==0 ){ + goto append_from_error; + } + assert( p->nSrc>0 ); + pItem = &p->a[p->nSrc-1]; + assert( (pTable==0)==(pDatabase==0) ); + assert( pItem->zName==0 || pDatabase!=0 ); + if( IN_RENAME_OBJECT && pItem->zName ){ + Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; + sqlite3RenameTokenMap(pParse, pItem->zName, pToken); + } + assert( pAlias!=0 ); + if( pAlias->n ){ + pItem->zAlias = sqlite3NameFromToken(db, pAlias); + } + if( pSubquery ){ + pItem->pSelect = pSubquery; + if( pSubquery->selFlags & SF_NestedFrom ){ + pItem->fg.isNestedFrom = 1; + } + } + assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); + assert( pItem->fg.isUsing==0 ); + if( pOnUsing==0 ){ + pItem->u3.pOn = 0; + }else if( pOnUsing->pUsing ){ + pItem->fg.isUsing = 1; + pItem->u3.pUsing = pOnUsing->pUsing; + }else{ + pItem->u3.pOn = pOnUsing->pOn; + } + return p; + +append_from_error: + assert( p==0 ); + sqlite3ClearOnOrUsing(db, pOnUsing); + sqlite3SelectDelete(db, pSubquery); + return 0; +} + +/* +** Add an INDEXED BY or NOT INDEXED clause to the most recently added +** element of the source-list passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ + assert( pIndexedBy!=0 ); + if( p && pIndexedBy->n>0 ){ + SrcItem *pItem; + assert( p->nSrc>0 ); + pItem = &p->a[p->nSrc-1]; + assert( pItem->fg.notIndexed==0 ); + assert( pItem->fg.isIndexedBy==0 ); + assert( pItem->fg.isTabFunc==0 ); + if( pIndexedBy->n==1 && !pIndexedBy->z ){ + /* A "NOT INDEXED" clause was supplied. See parse.y + ** construct "indexed_opt" for details. */ + pItem->fg.notIndexed = 1; + }else{ + pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); + pItem->fg.isIndexedBy = 1; + assert( pItem->fg.isCte==0 ); /* No collision on union u2 */ + } + } +} + +/* +** Append the contents of SrcList p2 to SrcList p1 and return the resulting +** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2 +** are deleted by this function. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ + assert( p1 && p1->nSrc==1 ); + if( p2 ){ + SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, 1); + if( pNew==0 ){ + sqlite3SrcListDelete(pParse->db, p2); + }else{ + p1 = pNew; + memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); + sqlite3DbFree(pParse->db, p2); + p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype); + } + } + return p1; +} + +/* +** Add the list of function arguments to the SrcList entry for a +** table-valued-function. +*/ +SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ + if( p ){ + SrcItem *pItem = &p->a[p->nSrc-1]; + assert( pItem->fg.notIndexed==0 ); + assert( pItem->fg.isIndexedBy==0 ); + assert( pItem->fg.isTabFunc==0 ); + pItem->u1.pFuncArg = pList; + pItem->fg.isTabFunc = 1; + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } +} + +/* +** When building up a FROM clause in the parser, the join operator +** is initially attached to the left operand. But the code generator +** expects the join operator to be on the right operand. This routine +** Shifts all join operators from left to right for an entire FROM +** clause. +** +** Example: Suppose the join is like this: +** +** A natural cross join B +** +** The operator is "natural cross join". The A and B operands are stored +** in p->a[0] and p->a[1], respectively. The parser initially stores the +** operator with A. This routine shifts that operator over to B. +** +** Additional changes: +** +** * All tables to the left of the right-most RIGHT JOIN are tagged with +** JT_LTORJ (mnemonic: Left Table Of Right Join) so that the +** code generator can easily tell that the table is part of +** the left operand of at least one RIGHT JOIN. +*/ +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){ + (void)pParse; + if( p && p->nSrc>1 ){ + int i = p->nSrc-1; + u8 allFlags = 0; + do{ + allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype; + }while( (--i)>0 ); + p->a[0].fg.jointype = 0; + + /* All terms to the left of a RIGHT JOIN should be tagged with the + ** JT_LTORJ flags */ + if( allFlags & JT_RIGHT ){ + for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){} + i--; + assert( i>=0 ); + do{ + p->a[i].fg.jointype |= JT_LTORJ; + }while( (--i)>=0 ); + } + } +} + +/* +** Generate VDBE code for a BEGIN statement. +*/ +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ + sqlite3 *db; + Vdbe *v; + int i; + + assert( pParse!=0 ); + db = pParse->db; + assert( db!=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( !v ) return; + if( type!=TK_DEFERRED ){ + for(i=0; inDb; i++){ + int eTxnType; + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeIsReadonly(pBt) ){ + eTxnType = 0; /* Read txn */ + }else if( type==TK_EXCLUSIVE ){ + eTxnType = 2; /* Exclusive txn */ + }else{ + eTxnType = 1; /* Write txn */ + } + sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType); + sqlite3VdbeUsesBtree(v, i); + } + } + sqlite3VdbeAddOp0(v, OP_AutoCommit); +} + +/* +** Generate VDBE code for a COMMIT or ROLLBACK statement. +** Code for ROLLBACK is generated if eType==TK_ROLLBACK. Otherwise +** code is generated for a COMMIT. +*/ +SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){ + Vdbe *v; + int isRollback; + + assert( pParse!=0 ); + assert( pParse->db!=0 ); + assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK ); + isRollback = eType==TK_ROLLBACK; + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, + isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback); + } +} + +/* +** This function is called by the parser when it parses a command to create, +** release or rollback an SQL savepoint. +*/ +SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ + char *zName = sqlite3NameFromToken(pParse->db, pName); + if( zName ){ + Vdbe *v = sqlite3GetVdbe(pParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; + assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); +#endif + if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ + sqlite3DbFree(pParse->db, zName); + return; + } + sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); + } +} + +/* +** Make sure the TEMP database is open and available for use. Return +** the number of errors. Leave any error messages in the pParse structure. +*/ +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt==0 && !pParse->explain ){ + int rc; + Btree *pBt; + static const int flags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TEMP_DB; + + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "unable to open a temporary database " + "file for storing temporary tables"); + pParse->rc = rc; + return 1; + } + db->aDb[1].pBt = pBt; + assert( db->aDb[1].pSchema ); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){ + sqlite3OomFault(db); + return 1; + } + } + return 0; +} + +/* +** Record the fact that the schema cookie will need to be verified +** for database iDb. The code to actually verify the schema cookie +** will occur at the end of the top-level VDBE and will be generated +** later, by sqlite3FinishCoding(). +*/ +static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ + assert( iDb>=0 && iDbdb->nDb ); + assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDbdb, iDb, 0) ); + if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ + DbMaskSet(pToplevel->cookieMask, iDb); + if( !OMIT_TEMPDB && iDb==1 ){ + sqlite3OpenTempDatabase(pToplevel); + } + } +} +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb); +} + + +/* +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each +** attached database. Otherwise, invoke it for the database named zDb only. +*/ +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + int i; + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){ + sqlite3CodeVerifySchema(pParse, i); + } + } +} + +/* +** Generate VDBE code that prepares for doing an operation that +** might change the database. +** +** This routine starts a new transaction if we are not already within +** a transaction. If we are already within a transaction, then a checkpoint +** is set if the setStatement parameter is true. A checkpoint should +** be set for operations that might fail (due to a constraint) part of +** the way through and which will need to undo some writes without having to +** rollback the whole transaction. For operations where all constraints +** can be checked before any changes are made to the database, it is never +** necessary to undo a write and the checkpoint should not be set. +*/ +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb); + DbMaskSet(pToplevel->writeMask, iDb); + pToplevel->isMultiWrite |= setStatement; +} + +/* +** Indicate that the statement currently under construction might write +** more than one entry (example: deleting one row then inserting another, +** inserting multiple rows in a table, or inserting a row and index entries.) +** If an abort occurs after some of these writes have completed, then it will +** be necessary to undo the completed writes. +*/ +SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->isMultiWrite = 1; +} + +/* +** The code generator calls this routine if is discovers that it is +** possible to abort a statement prior to completion. In order to +** perform this abort without corrupting the database, we need to make +** sure that the statement is protected by a statement transaction. +** +** Technically, we only need to set the mayAbort flag if the +** isMultiWrite flag was previously set. There is a time dependency +** such that the abort must occur after the multiwrite. This makes +** some statements involving the REPLACE conflict resolution algorithm +** go a little faster. But taking advantage of this time dependency +** makes it more difficult to prove that the code is correct (in +** particular, it prevents us from writing an effective +** implementation of sqlite3AssertMayAbort()) and so we have chosen +** to take the safe route and skip the optimization. +*/ +SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->mayAbort = 1; +} + +/* +** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT +** error. The onError parameter determines which (if any) of the statement +** and/or current transaction is rolled back. +*/ +SQLITE_PRIVATE void sqlite3HaltConstraint( + Parse *pParse, /* Parsing context */ + int errCode, /* extended error code */ + int onError, /* Constraint type */ + char *p4, /* Error message */ + i8 p4type, /* P4_STATIC or P4_TRANSIENT */ + u8 p5Errmsg /* P5_ErrMsg type */ +){ + Vdbe *v; + assert( pParse->pVdbe!=0 ); + v = sqlite3GetVdbe(pParse); + assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested ); + if( onError==OE_Abort ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); + sqlite3VdbeChangeP5(v, p5Errmsg); +} + +/* +** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation. +*/ +SQLITE_PRIVATE void sqlite3UniqueConstraint( + Parse *pParse, /* Parsing context */ + int onError, /* Constraint type */ + Index *pIdx /* The index that triggers the constraint */ +){ + char *zErr; + int j; + StrAccum errMsg; + Table *pTab = pIdx->pTable; + + sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, + pParse->db->aLimit[SQLITE_LIMIT_LENGTH]); + if( pIdx->aColExpr ){ + sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); + }else{ + for(j=0; jnKeyCol; j++){ + char *zCol; + assert( pIdx->aiColumn[j]>=0 ); + zCol = pTab->aCol[pIdx->aiColumn[j]].zCnName; + if( j ) sqlite3_str_append(&errMsg, ", ", 2); + sqlite3_str_appendall(&errMsg, pTab->zName); + sqlite3_str_append(&errMsg, ".", 1); + sqlite3_str_appendall(&errMsg, zCol); + } + } + zErr = sqlite3StrAccumFinish(&errMsg); + sqlite3HaltConstraint(pParse, + IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY + : SQLITE_CONSTRAINT_UNIQUE, + onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); +} + + +/* +** Code an OP_Halt due to non-unique rowid. +*/ +SQLITE_PRIVATE void sqlite3RowidConstraint( + Parse *pParse, /* Parsing context */ + int onError, /* Conflict resolution algorithm */ + Table *pTab /* The table with the non-unique rowid */ +){ + char *zMsg; + int rc; + if( pTab->iPKey>=0 ){ + zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, + pTab->aCol[pTab->iPKey].zCnName); + rc = SQLITE_CONSTRAINT_PRIMARYKEY; + }else{ + zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); + rc = SQLITE_CONSTRAINT_ROWID; + } + sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC, + P5_ConstraintUnique); +} + +/* +** Check to see if pIndex uses the collating sequence pColl. Return +** true if it does and false if it does not. +*/ +#ifndef SQLITE_OMIT_REINDEX +static int collationMatch(const char *zColl, Index *pIndex){ + int i; + assert( zColl!=0 ); + for(i=0; inColumn; i++){ + const char *z = pIndex->azColl[i]; + assert( z!=0 || pIndex->aiColumn[i]<0 ); + if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){ + return 1; + } + } + return 0; +} +#endif + +/* +** Recompute all indices of pTab that use the collating sequence pColl. +** If pColl==0 then recompute all indices of pTab. +*/ +#ifndef SQLITE_OMIT_REINDEX +static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ + if( !IsVirtual(pTab) ){ + Index *pIndex; /* An index associated with pTab */ + + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( zColl==0 || collationMatch(zColl, pIndex) ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + } + } + } +} +#endif + +/* +** Recompute all indices of all tables in all databases where the +** indices use the collating sequence pColl. If pColl==0 then recompute +** all indices everywhere. +*/ +#ifndef SQLITE_OMIT_REINDEX +static void reindexDatabases(Parse *pParse, char const *zColl){ + Db *pDb; /* A single database */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + HashElem *k; /* For looping over tables in pDb */ + Table *pTab; /* A table in the database */ + + assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + assert( pDb!=0 ); + for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + reindexTable(pParse, pTab, zColl); + } + } +} +#endif + +/* +** Generate code for the REINDEX command. +** +** REINDEX -- 1 +** REINDEX -- 2 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** +** Form 1 causes all indices in all attached databases to be rebuilt. +** Form 2 rebuilds all indices in all databases that use the named +** collating function. Forms 3 and 4 rebuild the named index or all +** indices associated with the named table. +*/ +#ifndef SQLITE_OMIT_REINDEX +SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ + char *z; /* Name of a table or index */ + const char *zDb; /* Name of the database */ + Table *pTab; /* A table in the database */ + Index *pIndex; /* An index associated with pTab */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + if( pName1==0 ){ + reindexDatabases(pParse, 0); + return; + }else if( NEVER(pName2==0) || pName2->z==0 ){ + char *zColl; + assert( pName1->z ); + zColl = sqlite3NameFromToken(pParse->db, pName1); + if( !zColl ) return; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + if( pColl ){ + reindexDatabases(pParse, zColl); + sqlite3DbFree(db, zColl); + return; + } + sqlite3DbFree(db, zColl); + } + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iDb<0 ) return; + z = sqlite3NameFromToken(db, pObjName); + if( z==0 ) return; + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; + pTab = sqlite3FindTable(db, z, zDb); + if( pTab ){ + reindexTable(pParse, pTab, 0); + sqlite3DbFree(db, z); + return; + } + pIndex = sqlite3FindIndex(db, z, zDb); + sqlite3DbFree(db, z); + if( pIndex ){ + iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + return; + } + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); +} +#endif + +/* +** Return a KeyInfo structure that is appropriate for the given Index. +** +** The caller should invoke sqlite3KeyInfoUnref() on the returned object +** when it has finished using it. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ + int i; + int nCol = pIdx->nColumn; + int nKey = pIdx->nKeyCol; + KeyInfo *pKey; + if( pParse->nErr ) return 0; + if( pIdx->uniqNotNull ){ + pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); + }else{ + pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); + } + if( pKey ){ + assert( sqlite3KeyInfoIsWriteable(pKey) ); + for(i=0; iazColl[i]; + pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : + sqlite3LocateCollSeq(pParse, zColl); + pKey->aSortFlags[i] = pIdx->aSortOrder[i]; + assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) ); + } + if( pParse->nErr ){ + assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ ); + if( pIdx->bNoQuery==0 ){ + /* Deactivate the index because it contains an unknown collating + ** sequence. The only way to reactive the index is to reload the + ** schema. Adding the missing collating sequence later does not + ** reactive the index. The application had the chance to register + ** the missing index using the collation-needed callback. For + ** simplicity, SQLite will not give the application a second chance. + */ + pIdx->bNoQuery = 1; + pParse->rc = SQLITE_ERROR_RETRY; + } + sqlite3KeyInfoUnref(pKey); + pKey = 0; + } + } + return pKey; +} + +#ifndef SQLITE_OMIT_CTE +/* +** Create a new CTE object +*/ +SQLITE_PRIVATE Cte *sqlite3CteNew( + Parse *pParse, /* Parsing context */ + Token *pName, /* Name of the common-table */ + ExprList *pArglist, /* Optional column name list for the table */ + Select *pQuery, /* Query used to initialize the table */ + u8 eM10d /* The MATERIALIZED flag */ +){ + Cte *pNew; + sqlite3 *db = pParse->db; + + pNew = sqlite3DbMallocZero(db, sizeof(*pNew)); + assert( pNew!=0 || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + }else{ + pNew->pSelect = pQuery; + pNew->pCols = pArglist; + pNew->zName = sqlite3NameFromToken(pParse->db, pName); + pNew->eM10d = eM10d; + } + return pNew; +} + +/* +** Clear information from a Cte object, but do not deallocate storage +** for the object itself. +*/ +static void cteClear(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); +} + +/* +** Free the contents of the CTE object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + cteClear(db, pCte); + sqlite3DbFree(db, pCte); +} + +/* +** This routine is invoked once per CTE by the parser while parsing a +** WITH clause. The CTE described by the third argument is added to +** the WITH clause of the second argument. If the second argument is +** NULL, then a new WITH argument is created. +*/ +SQLITE_PRIVATE With *sqlite3WithAdd( + Parse *pParse, /* Parsing context */ + With *pWith, /* Existing WITH clause, or NULL */ + Cte *pCte /* CTE to add to the WITH clause */ +){ + sqlite3 *db = pParse->db; + With *pNew; + char *zName; + + if( pCte==0 ){ + return pWith; + } + + /* Check that the CTE name is unique within this WITH clause. If + ** not, store an error in the Parse structure. */ + zName = pCte->zName; + if( zName && pWith ){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); + } + } + } + + if( pWith ){ + sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); + pNew = sqlite3DbRealloc(db, pWith, nByte); + }else{ + pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); + } + assert( (pNew!=0 && zName!=0) || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3CteDelete(db, pCte); + pNew = pWith; + }else{ + pNew->a[pNew->nCte++] = *pCte; + sqlite3DbFree(db, pCte); + } + + return pNew; +} + +/* +** Free the contents of the With object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ + if( pWith ){ + int i; + for(i=0; inCte; i++){ + cteClear(db, &pWith->a[i]); + } + sqlite3DbFree(db, pWith); + } +} +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ + sqlite3WithDelete(db, (With*)pWith); +} +#endif /* !defined(SQLITE_OMIT_CTE) */ + +/************** End of build.c ***********************************************/ +/************** Begin file callback.c ****************************************/ +/* +** 2005 May 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains functions used to access the internal hash tables +** of user defined functions and collation sequences. +*/ + +/* #include "sqliteInt.h" */ + +/* +** Invoke the 'collation needed' callback to request a collation sequence +** in the encoding enc of name zName, length nName. +*/ +static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ + assert( !db->xCollNeeded || !db->xCollNeeded16 ); + if( db->xCollNeeded ){ + char *zExternal = sqlite3DbStrDup(db, zName); + if( !zExternal ) return; + db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); + sqlite3DbFree(db, zExternal); + } +#ifndef SQLITE_OMIT_UTF16 + if( db->xCollNeeded16 ){ + char const *zExternal; + sqlite3_value *pTmp = sqlite3ValueNew(db); + sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); + if( zExternal ){ + db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); + } + sqlite3ValueFree(pTmp); + } +#endif +} + +/* +** This routine is called if the collation factory fails to deliver a +** collation function in the best encoding but there may be other versions +** of this collation function (for other text encodings) available. Use one +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if +** possible. +*/ +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ + CollSeq *pColl2; + char *z = pColl->zName; + int i; + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; + for(i=0; i<3; i++){ + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); + if( pColl2->xCmp!=0 ){ + memcpy(pColl, pColl2, sizeof(CollSeq)); + pColl->xDel = 0; /* Do not copy the destructor */ + return SQLITE_OK; + } + } + return SQLITE_ERROR; +} + +/* +** This routine is called on a collation sequence before it is used to +** check that it is defined. An undefined collation sequence exists when +** a database is loaded that contains references to collation sequences +** that have not been defined by sqlite3_create_collation() etc. +** +** If required, this routine calls the 'collation needed' callback to +** request a definition of the collating sequence. If this doesn't work, +** an equivalent collating sequence that uses a text encoding different +** from the main database is substituted, if one is available. +*/ +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ + if( pColl && pColl->xCmp==0 ){ + const char *zName = pColl->zName; + sqlite3 *db = pParse->db; + CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); + if( !p ){ + return SQLITE_ERROR; + } + assert( p==pColl ); + } + return SQLITE_OK; +} + + + +/* +** Locate and return an entry from the db.aCollSeq hash table. If the entry +** specified by zName and nName is not found and parameter 'create' is +** true, then create a new entry. Otherwise return NULL. +** +** Each pointer stored in the sqlite3.aCollSeq hash table contains an +** array of three CollSeq structures. The first is the collation sequence +** preferred for UTF-8, the second UTF-16le, and the third UTF-16be. +** +** Stored immediately after the three collation sequences is a copy of +** the collation sequence name. A pointer to this string is stored in +** each collation sequence structure. +*/ +static CollSeq *findCollSeqEntry( + sqlite3 *db, /* Database connection */ + const char *zName, /* Name of the collating sequence */ + int create /* Create a new entry if true */ +){ + CollSeq *pColl; + pColl = sqlite3HashFind(&db->aCollSeq, zName); + + if( 0==pColl && create ){ + int nName = sqlite3Strlen30(zName) + 1; + pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName); + if( pColl ){ + CollSeq *pDel = 0; + pColl[0].zName = (char*)&pColl[3]; + pColl[0].enc = SQLITE_UTF8; + pColl[1].zName = (char*)&pColl[3]; + pColl[1].enc = SQLITE_UTF16LE; + pColl[2].zName = (char*)&pColl[3]; + pColl[2].enc = SQLITE_UTF16BE; + memcpy(pColl[0].zName, zName, nName); + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); + + /* If a malloc() failure occurred in sqlite3HashInsert(), it will + ** return the pColl pointer to be deleted (because it wasn't added + ** to the hash table). + */ + assert( pDel==0 || pDel==pColl ); + if( pDel!=0 ){ + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); + pColl = 0; + } + } + } + return pColl; +} + +/* +** Parameter zName points to a UTF-8 encoded string nName bytes long. +** Return the CollSeq* pointer for the collation sequence named zName +** for the encoding 'enc' from the database 'db'. +** +** If the entry specified is not found and 'create' is true, then create a +** new entry. Otherwise return NULL. +** +** A separate function sqlite3LocateCollSeq() is a wrapper around +** this routine. sqlite3LocateCollSeq() invokes the collation factory +** if necessary and generates an error message if the collating sequence +** cannot be found. +** +** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq( + sqlite3 *db, /* Database connection to search */ + u8 enc, /* Desired text encoding */ + const char *zName, /* Name of the collating sequence. Might be NULL */ + int create /* True to create CollSeq if doesn't already exist */ +){ + CollSeq *pColl; + assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); + if( zName ){ + pColl = findCollSeqEntry(db, zName, create); + if( pColl ) pColl += enc-1; + }else{ + pColl = db->pDfltColl; + } + return pColl; +} + +/* +** Change the text encoding for a database connection. This means that +** the pDfltColl must change as well. +*/ +SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){ + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + db->enc = enc; + /* EVIDENCE-OF: R-08308-17224 The default collating function for all + ** strings is BINARY. + */ + db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); + sqlite3ExpirePreparedStatements(db, 1); +} + +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the desired encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. If no collation is found, leave an error message. +** +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( + Parse *pParse, /* Parsing context */ + u8 enc, /* The desired encoding for the collating sequence */ + CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ + const char *zName /* Collating sequence name */ +){ + CollSeq *p; + sqlite3 *db = pParse->db; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; + } + return p; +} + +/* +** This function returns the collation sequence for database native text +** encoding identified by the string zName. +** +** If the requested collation sequence is not available, or not available +** in the database native encoding, the collation factory is invoked to +** request it. If the collation factory does not supply such a sequence, +** and the sequence is available in another text encoding, then that is +** returned instead. +** +** If no versions of the requested collations sequence are available, or +** another error occurs, NULL is returned and an error message written into +** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. +** +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; + u8 enc = ENC(db); + u8 initbusy = db->init.busy; + CollSeq *pColl; + + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); + if( !initbusy && (!pColl || !pColl->xCmp) ){ + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); + } + + return pColl; +} + +/* During the search for the best function definition, this procedure +** is called to test how well the function passed as the first argument +** matches the request for a function with nArg arguments in a system +** that uses encoding enc. The value returned indicates how well the +** request is matched. A higher value indicates a better match. +** +** If nArg is -1 that means to only return a match (non-zero) if p->nArg +** is also -1. In other words, we are searching for a function that +** takes a variable number of arguments. +** +** If nArg is -2 that means that we are searching for any function +** regardless of the number of arguments it uses, so return a positive +** match score for any +** +** The returned value is always between 0 and 6, as follows: +** +** 0: Not a match. +** 1: UTF8/16 conversion required and function takes any number of arguments. +** 2: UTF16 byte order change required and function takes any number of args. +** 3: encoding matches and function takes any number of arguments +** 4: UTF8/16 conversion required - argument count matches exactly +** 5: UTF16 byte order conversion required - argument count matches exactly +** 6: Perfect match: encoding and argument count match exactly. +** +** If nArg==(-2) then any function with a non-null xSFunc is +** a perfect match and any function with xSFunc NULL is +** a non-match. +*/ +#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ +static int matchQuality( + FuncDef *p, /* The function we are evaluating for match quality */ + int nArg, /* Desired number of arguments. (-1)==any */ + u8 enc /* Desired text encoding */ +){ + int match; + assert( p->nArg>=-1 ); + + /* Wrong number of arguments means "no match" */ + if( p->nArg!=nArg ){ + if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; + if( p->nArg>=0 ) return 0; + } + + /* Give a better score to a function with a specific number of arguments + ** than to function that accepts any number of arguments. */ + if( p->nArg==nArg ){ + match = 4; + }else{ + match = 1; + } + + /* Bonus points if the text encoding matches */ + if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){ + match += 2; /* Exact encoding match */ + }else if( (enc & p->funcFlags & 2)!=0 ){ + match += 1; /* Both are UTF16, but with different byte orders */ + } + + return match; +} + +/* +** Search a FuncDefHash for a function with the given name. Return +** a pointer to the matching FuncDef if found, or 0 if there is no match. +*/ +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch( + int h, /* Hash of the name */ + const char *zFunc /* Name of function */ +){ + FuncDef *p; + for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); + if( sqlite3StrICmp(p->zName, zFunc)==0 ){ + return p; + } + } + return 0; +} + +/* +** Insert a new FuncDef into a FuncDefHash hash table. +*/ +SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( + FuncDef *aDef, /* List of global functions to be inserted */ + int nDef /* Length of the apDef[] list */ +){ + int i; + for(i=0; ipNext!=&aDef[i] ); + aDef[i].pNext = pOther->pNext; + pOther->pNext = &aDef[i]; + }else{ + aDef[i].pNext = 0; + aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h]; + sqlite3BuiltinFunctions.a[h] = &aDef[i]; + } + } +} + + + +/* +** Locate a user function given a name, a number of arguments and a flag +** indicating whether the function prefers UTF-16 over UTF-8. Return a +** pointer to the FuncDef structure that defines that function, or return +** NULL if the function does not exist. +** +** If the createFlag argument is true, then a new (blank) FuncDef +** structure is created and liked into the "db" structure if a +** no matching function previously existed. +** +** If nArg is -2, then the first valid function found is returned. A +** function is valid if xSFunc is non-zero. The nArg==(-2) +** case is used to see if zName is a valid function name for some number +** of arguments. If nArg is -2, then createFlag must be 0. +** +** If createFlag is false, then a function with the required name and +** number of arguments may be returned even if the eTextRep flag does not +** match that requested. +*/ +SQLITE_PRIVATE FuncDef *sqlite3FindFunction( + sqlite3 *db, /* An open database */ + const char *zName, /* Name of the function. zero-terminated */ + int nArg, /* Number of arguments. -1 means any number */ + u8 enc, /* Preferred text encoding */ + u8 createFlag /* Create new entry if true and does not otherwise exist */ +){ + FuncDef *p; /* Iterator variable */ + FuncDef *pBest = 0; /* Best match found so far */ + int bestScore = 0; /* Score of best match */ + int h; /* Hash value */ + int nName; /* Length of the name */ + + assert( nArg>=(-2) ); + assert( nArg>=(-1) || createFlag==0 ); + nName = sqlite3Strlen30(zName); + + /* First search for a match amongst the application-defined functions. + */ + p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + + /* If no match is found, search the built-in functions. + ** + ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in + ** functions even if a prior app-defined function was found. And give + ** priority to built-in functions. + ** + ** Except, if createFlag is true, that means that we are trying to + ** install a new function. Whatever FuncDef structure is returned it will + ** have fields overwritten with new information appropriate for the + ** new function. But the FuncDefs for built-in functions are read-only. + ** So we must not search for built-ins when creating a new function. + */ + if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){ + bestScore = 0; + h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName); + p = sqlite3FunctionSearch(h, zName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + } + + /* If the createFlag parameter is true and the search did not reveal an + ** exact match for the name, number of arguments and encoding, then add a + ** new entry to the hash table and return it. + */ + if( createFlag && bestScorezName = (const char*)&pBest[1]; + pBest->nArg = (u16)nArg; + pBest->funcFlags = enc; + memcpy((char*)&pBest[1], zName, nName+1); + for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z]; + pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); + if( pOther==pBest ){ + sqlite3DbFree(db, pBest); + sqlite3OomFault(db); + return 0; + }else{ + pBest->pNext = pOther; + } + } + + if( pBest && (pBest->xSFunc || createFlag) ){ + return pBest; + } + return 0; +} + +/* +** Free all resources held by the schema structure. The void* argument points +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the +** pointer itself, it just cleans up subsidiary resources (i.e. the contents +** of the schema hash tables). +** +** The Schema.cache_size variable is not cleared. +*/ +SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ + Hash temp1; + Hash temp2; + HashElem *pElem; + Schema *pSchema = (Schema *)p; + sqlite3 xdb; + + memset(&xdb, 0, sizeof(xdb)); + temp1 = pSchema->tblHash; + temp2 = pSchema->trigHash; + sqlite3HashInit(&pSchema->trigHash); + sqlite3HashClear(&pSchema->idxHash); + for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ + sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem)); + } + sqlite3HashClear(&temp2); + sqlite3HashInit(&pSchema->tblHash); + for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + sqlite3DeleteTable(&xdb, pTab); + } + sqlite3HashClear(&temp1); + sqlite3HashClear(&pSchema->fkeyHash); + pSchema->pSeqTab = 0; + if( pSchema->schemaFlags & DB_SchemaLoaded ){ + pSchema->iGeneration++; + } + pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); +} + +/* +** Find and return the schema associated with a BTree. Create +** a new one if necessary. +*/ +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ + Schema * p; + if( pBt ){ + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); + }else{ + p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); + } + if( !p ){ + sqlite3OomFault(db); + }else if ( 0==p->file_format ){ + sqlite3HashInit(&p->tblHash); + sqlite3HashInit(&p->idxHash); + sqlite3HashInit(&p->trigHash); + sqlite3HashInit(&p->fkeyHash); + p->enc = SQLITE_UTF8; + } + return p; +} + +/************** End of callback.c ********************************************/ +/************** Begin file delete.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** in order to generate code for DELETE FROM statements. +*/ +/* #include "sqliteInt.h" */ + +/* +** While a SrcList can in general represent multiple tables and subqueries +** (as in the FROM clause of a SELECT statement) in this case it contains +** the name of a single table, as one might find in an INSERT, DELETE, +** or UPDATE statement. Look up that table in the symbol table and +** return a pointer. Set an error message and return NULL if the table +** name is not found or if any other error occurs. +** +** The following fields are initialized appropriate in pSrc: +** +** pSrc->a[0].pTab Pointer to the Table object +** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** +*/ +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ + SrcItem *pItem = pSrc->a; + Table *pTab; + assert( pItem && pSrc->nSrc>=1 ); + pTab = sqlite3LocateTableItem(pParse, 0, pItem); + if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); + pItem->pTab = pTab; + pItem->fg.notCte = 1; + if( pTab ){ + pTab->nTabRef++; + if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } + } + return pTab; +} + +/* Generate byte-code that will report the number of rows modified +** by a DELETE, INSERT, or UPDATE statement. +*/ +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC); +} + +/* Return true if table pTab is read-only. +** +** A table is read-only if any of the following are true: +** +** 1) It is a virtual table and no implementation of the xUpdate method +** has been provided +** +** 2) A trigger is currently being coded and the table is a virtual table +** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and +** the table is not SQLITE_VTAB_INNOCUOUS. +** +** 3) It is a system table (i.e. sqlite_schema), this call is not +** part of a nested parse and writable_schema pragma has not +** been specified +** +** 4) The table is a shadow table, the database connection is in +** defensive mode, and the current sqlite3_prepare() +** is for a top-level SQL statement. +*/ +static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ + return 1; + } + + /* Within triggers: + ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY + ** virtual tables + ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS + ** virtual tables if PRAGMA trusted_schema=ON. + */ + if( pParse->pToplevel!=0 + && pTab->u.vtab.p->eVtabRisk > + ((pParse->db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); + } + return 0; +} +static int tabIsReadOnly(Parse *pParse, Table *pTab){ + sqlite3 *db; + if( IsVirtual(pTab) ){ + return vtabIsReadOnly(pParse, pTab); + } + if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; + db = pParse->db; + if( (pTab->tabFlags & TF_Readonly)!=0 ){ + return sqlite3WritableSchema(db)==0 && pParse->nested==0; + } + assert( pTab->tabFlags & TF_Shadow ); + return sqlite3ReadOnlyShadowTables(db); +} + +/* +** Check to make sure the given table is writable. +** +** If pTab is not writable -> generate an error message and return 1. +** If pTab is writable but other errors have occurred -> return 1. +** If pTab is writable and no prior errors -> return 0; +*/ +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){ + if( tabIsReadOnly(pParse, pTab) ){ + sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); + return 1; + } +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) + && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0)) + ){ + sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); + return 1; + } +#endif + return 0; +} + + +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Evaluate a view and store its result in an ephemeral table. The +** pWhere argument is an optional WHERE clause that restricts the +** set of rows in the view that are to be added to the ephemeral table. +*/ +SQLITE_PRIVATE void sqlite3MaterializeView( + Parse *pParse, /* Parsing context */ + Table *pView, /* View definition */ + Expr *pWhere, /* Optional WHERE clause to be added */ + ExprList *pOrderBy, /* Optional ORDER BY clause */ + Expr *pLimit, /* Optional LIMIT clause */ + int iCur /* Cursor number for ephemeral table */ +){ + SelectDest dest; + Select *pSel; + SrcList *pFrom; + sqlite3 *db = pParse->db; + int iDb = sqlite3SchemaToIndex(db, pView->pSchema); + pWhere = sqlite3ExprDup(db, pWhere, 0); + pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pFrom ){ + assert( pFrom->nSrc==1 ); + pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); + pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pFrom->a[0].fg.isUsing==0 ); + assert( pFrom->a[0].u3.pOn==0 ); + } + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, + SF_IncludeHidden, pLimit); + sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); + sqlite3Select(pParse, pSel, &dest); + sqlite3SelectDelete(db, pSel); +} +#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ + +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Generate an expression tree to implement the WHERE, ORDER BY, +** and LIMIT/OFFSET portion of DELETE and UPDATE statements. +** +** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1; +** \__________________________/ +** pLimitWhere (pInClause) +*/ +SQLITE_PRIVATE Expr *sqlite3LimitWhere( + Parse *pParse, /* The parser context */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* The ORDER BY clause. May be null */ + Expr *pLimit, /* The LIMIT clause. May be null */ + char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ +){ + sqlite3 *db = pParse->db; + Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ + Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ + ExprList *pEList = NULL; /* Expression list containing only pSelectRowid*/ + SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ + Select *pSelect = NULL; /* Complete SELECT tree */ + Table *pTab; + + /* Check that there isn't an ORDER BY without a LIMIT clause. + */ + if( pOrderBy && pLimit==0 ) { + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); + sqlite3ExprDelete(pParse->db, pWhere); + sqlite3ExprListDelete(pParse->db, pOrderBy); + return 0; + } + + /* We only need to generate a select expression if there + ** is a limit/offset term to enforce. + */ + if( pLimit == 0 ) { + return pWhere; + } + + /* Generate a select expression tree to enforce the limit/offset + ** term for the DELETE or UPDATE statement. For example: + ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** becomes: + ** DELETE FROM table_a WHERE rowid IN ( + ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** ); + */ + + pTab = pSrc->a[0].pTab; + if( HasRowid(pTab) ){ + pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); + pEList = sqlite3ExprListAppend( + pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) + ); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol>=1 ); + if( pPk->nKeyCol==1 ){ + const char *zName; + assert( pPk->aiColumn[0]>=0 && pPk->aiColumn[0]nCol ); + zName = pTab->aCol[pPk->aiColumn[0]].zCnName; + pLhs = sqlite3Expr(db, TK_ID, zName); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); + }else{ + int i; + for(i=0; inKeyCol; i++){ + Expr *p; + assert( pPk->aiColumn[i]>=0 && pPk->aiColumn[i]nCol ); + p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); + pEList = sqlite3ExprListAppend(pParse, pEList, p); + } + pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( pLhs ){ + pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); + } + } + } + + /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree + ** and the SELECT subtree. */ + pSrc->a[0].pTab = 0; + pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); + pSrc->a[0].pTab = pTab; + if( pSrc->a[0].fg.isIndexedBy ){ + assert( pSrc->a[0].fg.isCte==0 ); + pSrc->a[0].u2.pIBIndex = 0; + pSrc->a[0].fg.isIndexedBy = 0; + sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy); + }else if( pSrc->a[0].fg.isCte ){ + pSrc->a[0].u2.pCteUse->nUse++; + } + + /* generate the SELECT expression tree. */ + pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, + pOrderBy,0,pLimit + ); + + /* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */ + pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); + sqlite3PExprAddSelect(pParse, pInClause, pSelect); + return pInClause; +} +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ + /* && !defined(SQLITE_OMIT_SUBQUERY) */ + +/* +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere +*/ +SQLITE_PRIVATE void sqlite3DeleteFrom( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table from which we should delete things */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* ORDER BY clause. May be null */ + Expr *pLimit /* LIMIT clause. May be null */ +){ + Vdbe *v; /* The virtual database engine */ + Table *pTab; /* The table from which records will be deleted */ + int i; /* Loop counter */ + WhereInfo *pWInfo; /* Information about the WHERE clause */ + Index *pIdx; /* For looping over indices of the table */ + int iTabCur; /* Cursor number for the table */ + int iDataCur = 0; /* VDBE cursor for the canonical data source */ + int iIdxCur = 0; /* Cursor number of the first index */ + int nIdx; /* Number of indices */ + sqlite3 *db; /* Main database structure */ + AuthContext sContext; /* Authorization context */ + NameContext sNC; /* Name context to resolve expressions in */ + int iDb; /* Database number */ + int memCnt = 0; /* Memory cell used for change counting */ + int rcauth; /* Value returned by authorization callback */ + int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ + Index *pPk; /* The PRIMARY KEY index on the table */ + int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ + i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ + int iKey; /* Memory cell holding key of row to be deleted */ + i16 nKey; /* Number of memory cells in the row key */ + int iEphCur = 0; /* Ephemeral table holding all primary key values */ + int iRowSet = 0; /* Register for rowset of rows to delete */ + int addrBypass = 0; /* Address of jump over the delete logic */ + int addrLoop = 0; /* Top of the delete loop */ + int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ + int bComplex; /* True if there are triggers or FKs or + ** subqueries in the WHERE clause */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to delete from a view */ + Trigger *pTrigger; /* List of table triggers, if required */ +#endif + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto delete_from_cleanup; + } + assert( db->mallocFailed==0 ); + assert( pTabList->nSrc==1 ); + + /* Locate the table which we want to delete. This table has to be + ** put in an SrcList structure because some of the subroutines we + ** will be calling are designed to work with multiple tables and expect + ** an SrcList* parameter instead of just a Table* parameter. + */ + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ) goto delete_from_cleanup; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + isView = IsView(pTab); +#else +# define pTrigger 0 +# define isView 0 +#endif + bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere, + pOrderBy, pLimit, pTrigger); + } +#endif + +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( !isView ){ + pWhere = sqlite3LimitWhere( + pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + + /* If pTab is really a view, make sure it has been initialized. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto delete_from_cleanup; + } + + if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + goto delete_from_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, + db->aDb[iDb].zDbSName); + assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); + if( rcauth==SQLITE_DENY ){ + goto delete_from_cleanup; + } + assert(!isView || pTrigger); + + /* Assign cursor numbers to the table and all its indices. + */ + assert( pTabList->nSrc==1 ); + iTabCur = pTabList->a[0].iCursor = pParse->nTab++; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + pParse->nTab++; + } + + /* Start the view context + */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto delete_from_cleanup; + } + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, bComplex, iDb); + + /* If we are trying to delete from a view, realize that view into + ** an ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( isView ){ + sqlite3MaterializeView(pParse, pTab, + pWhere, pOrderBy, pLimit, iTabCur + ); + iDataCur = iIdxCur = iTabCur; + pOrderBy = 0; + pLimit = 0; + } +#endif + + /* Resolve the column names in the WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto delete_from_cleanup; + } + + /* Initialize the counter of the number of rows deleted, if + ** we are counting rows. + */ + if( (db->flags & SQLITE_CountRows)!=0 + && !pParse->nested + && !pParse->pTriggerTab + && !pParse->bReturning + ){ + memCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); + } + +#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + /* Special case: A DELETE without a WHERE clause deletes everything. + ** It is easier just to erase the whole table. Prior to version 3.6.5, + ** this optimization caused the row change count (the value returned by + ** API function sqlite3_count_changes) to be set incorrectly. + ** + ** The "rcauth==SQLITE_OK" terms is the + ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and + ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but + ** the truncate optimization is disabled and all rows are deleted + ** individually. + */ + if( rcauth==SQLITE_OK + && pWhere==0 + && !bComplex + && !IsVirtual(pTab) +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + && db->xPreUpdateCallback==0 +#endif + ){ + assert( !isView ); + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, + pTab->zName, P4_STATIC); + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->pSchema==pTab->pSchema ); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1); + }else{ + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + } + } + }else +#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ + { + u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; + if( sNC.ncFlags & NC_Subquery ) bComplex = 1; + wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); + if( HasRowid(pTab) ){ + /* For a rowid table, initialize the RowSet to an empty set */ + pPk = 0; + assert( nPk==1 ); + iRowSet = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + }else{ + /* For a WITHOUT ROWID table, create an ephemeral table used to + ** hold all primary keys for rows to be deleted. */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + nPk = pPk->nKeyCol; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + iEphCur = pParse->nTab++; + addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + + /* Construct a query to find the rowid or primary key for every row + ** to be deleted, based on the WHERE clause. Set variable eOnePass + ** to indicate the strategy used to implement this delete: + ** + ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values. + ** ONEPASS_SINGLE: One-pass approach - at most one row deleted. + ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted. + */ + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1); + if( pWInfo==0 ) goto delete_from_cleanup; + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); + assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF + || OptimizationDisabled(db, SQLITE_OnePass) ); + if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); + if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); + } + + /* Keep track of the number of rows to be deleted */ + if( memCnt ){ + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); + } + + /* Extract the rowid or primary key for the current row */ + if( pPk ){ + for(i=0; iaiColumn[i]>=0 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, + pPk->aiColumn[i], iPk+i); + } + iKey = iPk; + }else{ + iKey = ++pParse->nMem; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); + } + + if( eOnePass!=ONEPASS_OFF ){ + /* For ONEPASS, no need to store the rowid/primary-key. There is only + ** one, so just keep it in its register(s) and fall through to the + ** delete code. */ + nKey = nPk; /* OP_Found will use an unpacked key */ + aToOpen = sqlite3DbMallocRawNN(db, nIdx+2); + if( aToOpen==0 ){ + sqlite3WhereEnd(pWInfo); + goto delete_from_cleanup; + } + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; + if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); + addrBypass = sqlite3VdbeMakeLabel(pParse); + }else{ + if( pPk ){ + /* Add the PK key for this row to the temporary table */ + iKey = ++pParse->nMem; + nKey = 0; /* Zero tells OP_Found to use a composite key */ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, + sqlite3IndexAffinityStr(pParse->db, pPk), nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk); + }else{ + /* Add the rowid of the row to be deleted to the RowSet */ + nKey = 1; /* OP_DeferredSeek always uses a single rowid */ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); + } + sqlite3WhereEnd(pWInfo); + } + + /* Unless this is a view, open cursors for the table we are + ** deleting from and all its indices. If this is a view, then the + ** only effect this statement has is to fire the INSTEAD OF + ** triggers. + */ + if( !isView ){ + int iAddrOnce = 0; + if( eOnePass==ONEPASS_MULTI ){ + iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + testcase( IsVirtual(pTab) ); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, + iTabCur, aToOpen, &iDataCur, &iIdxCur); + assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); + assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); + if( eOnePass==ONEPASS_MULTI ){ + sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce); + } + } + + /* Set up a loop over the rowids/primary-keys that were found in the + ** where-clause loop above. + */ + if( eOnePass!=ONEPASS_OFF ){ + assert( nKey==nPk ); /* OP_Found will use an unpacked key */ + if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){ + assert( pPk!=0 || IsView(pTab) ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); + VdbeCoverage(v); + } + }else if( pPk ){ + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); + } + assert( nKey==0 ); /* OP_Found will use a composite key */ + }else{ + addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); + VdbeCoverage(v); + assert( nKey==1 ); + } + + /* Delete the row */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); + sqlite3MayAbort(pParse); + if( eOnePass==ONEPASS_SINGLE ){ + sqlite3VdbeAddOp1(v, OP_Close, iTabCur); + if( sqlite3IsToplevel(pParse) ){ + pParse->isMultiWrite = 0; + } + } + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); + }else +#endif + { + int count = (pParse->nested==0); /* True to count changes */ + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]); + } + + /* End of the loop over all rowids/primary-keys. */ + if( eOnePass!=ONEPASS_OFF ){ + sqlite3VdbeResolveLabel(v, addrBypass); + sqlite3WhereEnd(pWInfo); + }else if( pPk ){ + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrLoop); + }else{ + sqlite3VdbeGoto(v, addrLoop); + sqlite3VdbeJumpHere(v, addrLoop); + } + } /* End non-truncate path */ + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* Return the number of rows that were deleted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( memCnt ){ + sqlite3CodeChangeCount(v, memCnt, "rows deleted"); + } + +delete_from_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprDelete(db, pWhere); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); +#endif + if( aToOpen ) sqlite3DbNNFreeNN(db, aToOpen); + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +/* +** This routine generates VDBE code that causes a single row of a +** single table to be deleted. Both the original table entry and +** all indices are removed. +** +** Preconditions: +** +** 1. iDataCur is an open cursor on the btree that is the canonical data +** store for the table. (This will be either the table itself, +** in the case of a rowid table, or the PRIMARY KEY index in the case +** of a WITHOUT ROWID table.) +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iIdxCur+i for the i-th index. +** +** 3. The primary key for the row to be deleted must be stored in a +** sequence of nPk memory cells starting at iPk. If nPk==0 that means +** that a search record formed from OP_MakeRecord is contained in the +** single memory location iPk. +** +** eMode: +** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or +** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor +** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF +** then this function must seek iDataCur to the entry identified by iPk +** and nPk before reading from it. +** +** If eMode is ONEPASS_MULTI, then this call is being made as part +** of a ONEPASS delete that affects multiple rows. In this case, if +** iIdxNoSeek is a valid cursor number (>=0) and is not the same as +** iDataCur, then its position should be preserved following the delete +** operation. Or, if iIdxNoSeek is not a valid cursor number, the +** position of iDataCur should be preserved instead. +** +** iIdxNoSeek: +** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur, +** then it identifies an index cursor (from within array of cursors +** starting at iIdxCur) that already points to the index entry to be deleted. +** Except, this optimization is disabled if there are BEFORE triggers since +** the trigger body might have moved the cursor. +*/ +SQLITE_PRIVATE void sqlite3GenerateRowDelete( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the row to be deleted */ + Trigger *pTrigger, /* List of triggers to (potentially) fire */ + int iDataCur, /* Cursor from which column data is extracted */ + int iIdxCur, /* First index cursor */ + int iPk, /* First memory cell containing the PRIMARY KEY */ + i16 nPk, /* Number of PRIMARY KEY memory cells */ + u8 count, /* If non-zero, increment the row change counter */ + u8 onconf, /* Default ON CONFLICT policy for triggers */ + u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */ + int iIdxNoSeek /* Cursor number of cursor that does not need seeking */ +){ + Vdbe *v = pParse->pVdbe; /* Vdbe */ + int iOld = 0; /* First register in OLD.* array */ + int iLabel; /* Label resolved to end of generated code */ + u8 opSeek; /* Seek opcode */ + + /* Vdbe is guaranteed to have been allocated by this stage. */ + assert( v ); + VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)", + iDataCur, iIdxCur, iPk, (int)nPk)); + + /* Seek cursor iCur to the row to delete. If this row no longer exists + ** (this can happen if a trigger program has already deleted it), do + ** not attempt to delete it or fire any DELETE triggers. */ + iLabel = sqlite3VdbeMakeLabel(pParse); + opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + if( eMode==ONEPASS_OFF ){ + sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + VdbeCoverageIf(v, opSeek==OP_NotExists); + VdbeCoverageIf(v, opSeek==OP_NotFound); + } + + /* If there are any triggers to fire, allocate a range of registers to + ** use for the old.* references in the triggers. */ + if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ + u32 mask; /* Mask of OLD.* columns in use */ + int iCol; /* Iterator used while populating OLD.* */ + int addrStart; /* Start of BEFORE trigger programs */ + + /* TODO: Could use temporary registers here. Also could attempt to + ** avoid copying the contents of the rowid register. */ + mask = sqlite3TriggerColmask( + pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf + ); + mask |= sqlite3FkOldmask(pParse, pTab); + iOld = pParse->nMem+1; + pParse->nMem += (1 + pTab->nCol); + + /* Populate the OLD.* pseudo-table register array. These values will be + ** used by any BEFORE and AFTER triggers that exist. */ + sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); + for(iCol=0; iColnCol; iCol++){ + testcase( mask!=0xffffffff && iCol==31 ); + testcase( mask!=0xffffffff && iCol==32 ); + if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ + int kk = sqlite3TableColumnToStorage(pTab, iCol); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1); + } + } + + /* Invoke BEFORE DELETE trigger programs. */ + addrStart = sqlite3VdbeCurrentAddr(v); + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel + ); + + /* If any BEFORE triggers were coded, then seek the cursor to the + ** row to be deleted again. It may be that the BEFORE triggers moved + ** the cursor or already deleted the row that the cursor was + ** pointing to. + ** + ** Also disable the iIdxNoSeek optimization since the BEFORE trigger + ** may have moved that cursor. + */ + if( addrStart=0 ); + iIdxNoSeek = -1; + } + + /* Do FK processing. This call checks that any FK constraints that + ** refer to this table (i.e. constraints attached to other tables) + ** are not violated by deleting this row. */ + sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); + } + + /* Delete the index and table entries. Skip this step if pTab is really + ** a view (in which case the only effect of the DELETE statement is to + ** fire the INSTEAD OF triggers). + ** + ** If variable 'count' is non-zero, then this OP_Delete instruction should + ** invoke the update-hook. The pre-update-hook, on the other hand should + ** be invoked unless table pTab is a system table. The difference is that + ** the update-hook is not invoked for rows removed by REPLACE, but the + ** pre-update-hook is. + */ + if( !IsView(pTab) ){ + u8 p5 = 0; + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); + if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){ + sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); + } + if( eMode!=ONEPASS_OFF ){ + sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); + } + if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){ + sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); + } + if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; + sqlite3VdbeChangeP5(v, p5); + } + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just deleted. */ + sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); + + /* Invoke AFTER DELETE trigger programs. */ + if( pTrigger ){ + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); + } + + /* Jump here if the row had already been deleted before any BEFORE + ** trigger programs were invoked. Or if a trigger program throws a + ** RAISE(IGNORE) exception. */ + sqlite3VdbeResolveLabel(v, iLabel); + VdbeModuleComment((v, "END: GenRowDel()")); +} + +/* +** This routine generates VDBE code that causes the deletion of all +** index entries associated with a single row of a single table, pTab +** +** Preconditions: +** +** 1. A read/write cursor "iDataCur" must be open on the canonical storage +** btree for the table pTab. (This will be either the table itself +** for rowid tables or to the primary key index for WITHOUT ROWID +** tables.) +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex +** index is the 0-th index.) +** +** 3. The "iDataCur" cursor must be already be positioned on the row +** that is to be deleted. +*/ +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Table containing the row to be deleted */ + int iDataCur, /* Cursor of table holding data. */ + int iIdxCur, /* First index cursor */ + int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ + int iIdxNoSeek /* Do not delete from this cursor */ +){ + int i; /* Index loop counter */ + int r1 = -1; /* Register holding an index key */ + int iPartIdxLabel; /* Jump destination for skipping partial index entries */ + Index *pIdx; /* Current index */ + Index *pPrior = 0; /* Prior index */ + Vdbe *v; /* The prepared statement under construction */ + Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ + + v = pParse->pVdbe; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + assert( iIdxCur+i!=iDataCur || pPk==pIdx ); + if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; + if( pIdx==pPk ) continue; + if( iIdxCur+i==iIdxNoSeek ) continue; + VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, + &iPartIdxLabel, pPrior, r1); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, + pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); + sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */ + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + pPrior = pIdx; + } +} + +/* +** Generate code that will assemble an index key and stores it in register +** regOut. The key with be for index pIdx which is an index on pTab. +** iCur is the index of a cursor open on the pTab table and pointing to +** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then +** iCur must be the cursor of the PRIMARY KEY index. +** +** Return a register number which is the first in a block of +** registers that holds the elements of the index key. The +** block of registers has already been deallocated by the time +** this routine returns. +** +** If *piPartIdxLabel is not NULL, fill it in with a label and jump +** to that label if pIdx is a partial index that should be skipped. +** The label should be resolved using sqlite3ResolvePartIdxLabel(). +** A partial index should be skipped if its WHERE clause evaluates +** to false or null. If pIdx is not a partial index, *piPartIdxLabel +** will be set to zero which is an empty label that is ignored by +** sqlite3ResolvePartIdxLabel(). +** +** The pPrior and regPrior parameters are used to implement a cache to +** avoid unnecessary register loads. If pPrior is not NULL, then it is +** a pointer to a different index for which an index key has just been +** computed into register regPrior. If the current pIdx index is generating +** its key into the same sequence of registers and if pPrior and pIdx share +** a column in common, then the register corresponding to that column already +** holds the correct value and the loading of that register is skipped. +** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK +** on a table with multiple indices, and especially with the ROWID or +** PRIMARY KEY columns of the index. +*/ +SQLITE_PRIVATE int sqlite3GenerateIndexKey( + Parse *pParse, /* Parsing context */ + Index *pIdx, /* The index for which to generate a key */ + int iDataCur, /* Cursor number from which to take column data */ + int regOut, /* Put the new key into this register if not 0 */ + int prefixOnly, /* Compute only a unique prefix of the key */ + int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */ + Index *pPrior, /* Previously generated index key */ + int regPrior /* Register holding previous generated key */ +){ + Vdbe *v = pParse->pVdbe; + int j; + int regBase; + int nCol; + + if( piPartIdxLabel ){ + if( pIdx->pPartIdxWhere ){ + *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse); + pParse->iSelfTab = iDataCur + 1; + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, + SQLITE_JUMPIFNULL); + pParse->iSelfTab = 0; + pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02; + ** pPartIdxWhere may have corrupted regPrior registers */ + }else{ + *piPartIdxLabel = 0; + } + } + nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; + regBase = sqlite3GetTempRange(pParse, nCol); + if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; + for(j=0; jaiColumn[j]==pIdx->aiColumn[j] + && pPrior->aiColumn[j]!=XN_EXPR + ){ + /* This column was already computed by the previous index */ + continue; + } + sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j); + if( pIdx->aiColumn[j]>=0 ){ + /* If the column affinity is REAL but the number is an integer, then it + ** might be stored in the table as an integer (using a compact + ** representation) then converted to REAL by an OP_RealAffinity opcode. + ** But we are getting ready to store this value back into an index, where + ** it should be converted by to INTEGER again. So omit the + ** OP_RealAffinity opcode if it is present */ + sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); + } + } + if( regOut ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); + } + sqlite3ReleaseTempRange(pParse, regBase, nCol); + return regBase; +} + +/* +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label +** because it was a partial index, then this routine should be called to +** resolve that label. +*/ +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ + if( iLabel ){ + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); + } +} + +/************** End of delete.c **********************************************/ +/************** Begin file func.c ********************************************/ +/* +** 2002 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C-language implementations for many of the SQL +** functions of SQLite. (Some function, and in particular the date and +** time functions, are implemented separately.) +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include */ +#ifndef SQLITE_OMIT_FLOATING_POINT +/* #include */ +#endif +/* #include "vdbeInt.h" */ + +/* +** Return the collating function associated with a function. +*/ +static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ + VdbeOp *pOp; + assert( context->pVdbe!=0 ); + pOp = &context->pVdbe->aOp[context->iOp-1]; + assert( pOp->opcode==OP_CollSeq ); + assert( pOp->p4type==P4_COLLSEQ ); + return pOp->p4.pColl; +} + +/* +** Indicate that the accumulator load should be skipped on this +** iteration of the aggregate loop. +*/ +static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ + assert( context->isError<=0 ); + context->isError = -1; + context->skipFlag = 1; +} + +/* +** Implementation of the non-aggregate min() and max() functions +*/ +static void minmaxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + int mask; /* 0 for min() or 0xffffffff for max() */ + int iBest; + CollSeq *pColl; + + assert( argc>1 ); + mask = sqlite3_user_data(context)==0 ? 0 : -1; + pColl = sqlite3GetFuncCollSeq(context); + assert( pColl ); + assert( mask==-1 || mask==0 ); + iBest = 0; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + for(i=1; i=0 ){ + testcase( mask==0 ); + iBest = i; + } + } + sqlite3_result_value(context, argv[iBest]); +} + +/* +** Return the type of the argument. +*/ +static void typeofFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + static const char *azType[] = { "integer", "real", "text", "blob", "null" }; + int i = sqlite3_value_type(argv[0]) - 1; + UNUSED_PARAMETER(NotUsed); + assert( i>=0 && i=0xc0 ){ + while( (*z & 0xc0)==0x80 ){ z++; z0++; } + } + } + sqlite3_result_int(context, (int)(z-z0)); + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* +** Implementation of the octet_length() function +*/ +static void bytelengthFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_BLOB: { + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + i64 m = sqlite3_context_db_handle(context)->enc<=SQLITE_UTF8 ? 1 : 2; + sqlite3_result_int64(context, sqlite3_value_bytes(argv[0])*m); + break; + } + case SQLITE_TEXT: { + if( sqlite3_value_encoding(argv[0])<=SQLITE_UTF8 ){ + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + }else{ + sqlite3_result_int(context, sqlite3_value_bytes16(argv[0])); + } + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* +** Implementation of the abs() function. +** +** IMP: R-23979-26855 The abs(X) function returns the absolute value of +** the numeric argument X. +*/ +static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal<0 ){ + if( iVal==SMALLEST_INT64 ){ + /* IMP: R-31676-45509 If X is the integer -9223372036854775808 + ** then abs(X) throws an integer overflow error since there is no + ** equivalent positive 64-bit two complement value. */ + sqlite3_result_error(context, "integer overflow", -1); + return; + } + iVal = -iVal; + } + sqlite3_result_int64(context, iVal); + break; + } + case SQLITE_NULL: { + /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ + sqlite3_result_null(context); + break; + } + default: { + /* Because sqlite3_value_double() returns 0.0 if the argument is not + ** something that can be converted into a number, we have: + ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob + ** that cannot be converted to a numeric value. + */ + double rVal = sqlite3_value_double(argv[0]); + if( rVal<0 ) rVal = -rVal; + sqlite3_result_double(context, rVal); + break; + } + } +} + +/* +** Implementation of the instr() function. +** +** instr(haystack,needle) finds the first occurrence of needle +** in haystack and returns the number of previous characters plus 1, +** or 0 if needle does not occur within haystack. +** +** If both haystack and needle are BLOBs, then the result is one more than +** the number of bytes in haystack prior to the first occurrence of needle, +** or 0 if needle never occurs in haystack. +*/ +static void instrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zHaystack; + const unsigned char *zNeedle; + int nHaystack; + int nNeedle; + int typeHaystack, typeNeedle; + int N = 1; + int isText; + unsigned char firstChar; + sqlite3_value *pC1 = 0; + sqlite3_value *pC2 = 0; + + UNUSED_PARAMETER(argc); + typeHaystack = sqlite3_value_type(argv[0]); + typeNeedle = sqlite3_value_type(argv[1]); + if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; + nHaystack = sqlite3_value_bytes(argv[0]); + nNeedle = sqlite3_value_bytes(argv[1]); + if( nNeedle>0 ){ + if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ + zHaystack = sqlite3_value_blob(argv[0]); + zNeedle = sqlite3_value_blob(argv[1]); + isText = 0; + }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){ + zHaystack = sqlite3_value_text(argv[0]); + zNeedle = sqlite3_value_text(argv[1]); + isText = 1; + }else{ + pC1 = sqlite3_value_dup(argv[0]); + zHaystack = sqlite3_value_text(pC1); + if( zHaystack==0 ) goto endInstrOOM; + nHaystack = sqlite3_value_bytes(pC1); + pC2 = sqlite3_value_dup(argv[1]); + zNeedle = sqlite3_value_text(pC2); + if( zNeedle==0 ) goto endInstrOOM; + nNeedle = sqlite3_value_bytes(pC2); + isText = 1; + } + if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM; + firstChar = zNeedle[0]; + while( nNeedle<=nHaystack + && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0) + ){ + N++; + do{ + nHaystack--; + zHaystack++; + }while( isText && (zHaystack[0]&0xc0)==0x80 ); + } + if( nNeedle>nHaystack ) N = 0; + } + sqlite3_result_int(context, N); +endInstr: + sqlite3_value_free(pC1); + sqlite3_value_free(pC2); + return; +endInstrOOM: + sqlite3_result_error_nomem(context); + goto endInstr; +} + +/* +** Implementation of the printf() (a.k.a. format()) SQL function. +*/ +static void printfFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + PrintfArguments x; + StrAccum str; + const char *zFormat; + int n; + sqlite3 *db = sqlite3_context_db_handle(context); + + if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + x.nArg = argc-1; + x.nUsed = 0; + x.apArg = argv+1; + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + str.printfFlags = SQLITE_PRINTF_SQLFUNC; + sqlite3_str_appendf(&str, zFormat, &x); + n = str.nChar; + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, + SQLITE_DYNAMIC); + } +} + +/* +** Implementation of the substr() function. +** +** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. +** p1 is 1-indexed. So substr(x,1,1) returns the first character +** of x. If x is text, then we actually count UTF-8 characters. +** If x is a blob, then we count bytes. +** +** If p1 is negative, then we begin abs(p1) from the end of x[]. +** +** If p2 is negative, return the p2 characters preceding p1. +*/ +static void substrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z; + const unsigned char *z2; + int len; + int p0type; + i64 p1, p2; + int negP2 = 0; + + assert( argc==3 || argc==2 ); + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) + ){ + return; + } + p0type = sqlite3_value_type(argv[0]); + p1 = sqlite3_value_int(argv[1]); + if( p0type==SQLITE_BLOB ){ + len = sqlite3_value_bytes(argv[0]); + z = sqlite3_value_blob(argv[0]); + if( z==0 ) return; + assert( len==sqlite3_value_bytes(argv[0]) ); + }else{ + z = sqlite3_value_text(argv[0]); + if( z==0 ) return; + len = 0; + if( p1<0 ){ + for(z2=z; *z2; len++){ + SQLITE_SKIP_UTF8(z2); + } + } + } +#ifdef SQLITE_SUBSTR_COMPATIBILITY + /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as + ** as substr(X,1,N) - it returns the first N characters of X. This + ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] + ** from 2009-02-02 for compatibility of applications that exploited the + ** old buggy behavior. */ + if( p1==0 ) p1 = 1; /* */ +#endif + if( argc==3 ){ + p2 = sqlite3_value_int(argv[2]); + if( p2<0 ){ + p2 = -p2; + negP2 = 1; + } + }else{ + p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; + } + if( p1<0 ){ + p1 += len; + if( p1<0 ){ + p2 += p1; + if( p2<0 ) p2 = 0; + p1 = 0; + } + }else if( p1>0 ){ + p1--; + }else if( p2>0 ){ + p2--; + } + if( negP2 ){ + p1 -= p2; + if( p1<0 ){ + p2 += p1; + p1 = 0; + } + } + assert( p1>=0 && p2>=0 ); + if( p0type!=SQLITE_BLOB ){ + while( *z && p1 ){ + SQLITE_SKIP_UTF8(z); + p1--; + } + for(z2=z; *z2 && p2; p2--){ + SQLITE_SKIP_UTF8(z2); + } + sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, + SQLITE_UTF8); + }else{ + if( p1+p2>len ){ + p2 = len-p1; + if( p2<0 ) p2 = 0; + } + sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); + } +} + +/* +** Implementation of the round() function +*/ +#ifndef SQLITE_OMIT_FLOATING_POINT +static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + int n = 0; + double r; + char *zBuf; + assert( argc==1 || argc==2 ); + if( argc==2 ){ + if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; + n = sqlite3_value_int(argv[1]); + if( n>30 ) n = 30; + if( n<0 ) n = 0; + } + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + r = sqlite3_value_double(argv[0]); + /* If Y==0 and X will fit in a 64-bit int, + ** handle the rounding directly, + ** otherwise use printf. + */ + if( r<-4503599627370496.0 || r>+4503599627370496.0 ){ + /* The value has no fractional part so there is nothing to round */ + }else if( n==0 ){ + r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); + }else{ + zBuf = sqlite3_mprintf("%!.*f",n,r); + if( zBuf==0 ){ + sqlite3_result_error_nomem(context); + return; + } + sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); + sqlite3_free(zBuf); + } + sqlite3_result_double(context, r); +} +#endif + +/* +** Allocate nByte bytes of space using sqlite3Malloc(). If the +** allocation fails, call sqlite3_result_error_nomem() to notify +** the database handle that malloc() has failed and return NULL. +** If nByte is larger than the maximum string or blob length, then +** raise an SQLITE_TOOBIG exception and return NULL. +*/ +static void *contextMalloc(sqlite3_context *context, i64 nByte){ + char *z; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( nByte>0 ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + z = 0; + }else{ + z = sqlite3Malloc(nByte); + if( !z ){ + sqlite3_result_error_nomem(context); + } + } + return z; +} + +/* +** Implementation of the upper() and lower() SQL functions. +*/ +static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + char *z1; + const char *z2; + int i, n; + UNUSED_PARAMETER(argc); + z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); + /* Verify that the call to _bytes() does not invalidate the _text() pointer */ + assert( z2==(char*)sqlite3_value_text(argv[0]) ); + if( z2 ){ + z1 = contextMalloc(context, ((i64)n)+1); + if( z1 ){ + for(i=0; imatchOne; /* "?" or "_" */ + u32 matchAll = pInfo->matchAll; /* "*" or "%" */ + u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */ + const u8 *zEscaped = 0; /* One past the last escaped input char */ + + while( (c = Utf8Read(zPattern))!=0 ){ + if( c==matchAll ){ /* Match "*" */ + /* Skip over multiple "*" characters in the pattern. If there + ** are also "?" characters, skip those as well, but consume a + ** single character of the input string for each "?" skipped */ + while( (c=Utf8Read(zPattern)) == matchAll + || (c == matchOne && matchOne!=0) ){ + if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ + return SQLITE_NOWILDCARDMATCH; + } + } + if( c==0 ){ + return SQLITE_MATCH; /* "*" at the end of the pattern matches */ + }else if( c==matchOther ){ + if( pInfo->matchSet==0 ){ + c = sqlite3Utf8Read(&zPattern); + if( c==0 ) return SQLITE_NOWILDCARDMATCH; + }else{ + /* "[...]" immediately follows the "*". We have to do a slow + ** recursive search in this case, but it is an unusual case. */ + assert( matchOther<0x80 ); /* '[' is a single-byte character */ + while( *zString ){ + int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; + SQLITE_SKIP_UTF8(zString); + } + return SQLITE_NOWILDCARDMATCH; + } + } + + /* At this point variable c contains the first character of the + ** pattern string past the "*". Search in the input string for the + ** first matching character and recursively continue the match from + ** that point. + ** + ** For a case-insensitive search, set variable cx to be the same as + ** c but in the other case and search the input string for either + ** c or cx. + */ + if( c<0x80 ){ + char zStop[3]; + int bMatch; + if( noCase ){ + zStop[0] = sqlite3Toupper(c); + zStop[1] = sqlite3Tolower(c); + zStop[2] = 0; + }else{ + zStop[0] = c; + zStop[1] = 0; + } + while(1){ + zString += strcspn((const char*)zString, zStop); + if( zString[0]==0 ) break; + zString++; + bMatch = patternCompare(zPattern,zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; + } + }else{ + int bMatch; + while( (c2 = Utf8Read(zString))!=0 ){ + if( c2!=c ) continue; + bMatch = patternCompare(zPattern,zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; + } + } + return SQLITE_NOWILDCARDMATCH; + } + if( c==matchOther ){ + if( pInfo->matchSet==0 ){ + c = sqlite3Utf8Read(&zPattern); + if( c==0 ) return SQLITE_NOMATCH; + zEscaped = zPattern; + }else{ + u32 prior_c = 0; + int seen = 0; + int invert = 0; + c = sqlite3Utf8Read(&zString); + if( c==0 ) return SQLITE_NOMATCH; + c2 = sqlite3Utf8Read(&zPattern); + if( c2=='^' ){ + invert = 1; + c2 = sqlite3Utf8Read(&zPattern); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = sqlite3Utf8Read(&zPattern); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ + c2 = sqlite3Utf8Read(&zPattern); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = sqlite3Utf8Read(&zPattern); + } + if( c2==0 || (seen ^ invert)==0 ){ + return SQLITE_NOMATCH; + } + continue; + } + } + c2 = Utf8Read(zString); + if( c==c2 ) continue; + if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){ + continue; + } + if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; + return SQLITE_NOMATCH; + } + return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH; +} + +/* +** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and +** non-zero if there is no match. +*/ +SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ + if( zString==0 ){ + return zGlobPattern!=0; + }else if( zGlobPattern==0 ){ + return 1; + }else { + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); + } +} + +/* +** The sqlite3_strlike() interface. Return 0 on a match and non-zero for +** a miss - like strcmp(). +*/ +SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ + if( zStr==0 ){ + return zPattern!=0; + }else if( zPattern==0 ){ + return 1; + }else{ + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); + } +} + +/* +** Count the number of times that the LIKE operator (or GLOB which is +** just a variation of LIKE) gets called. This is used for testing +** only. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_like_count = 0; +#endif + + +/* +** Implementation of the like() SQL function. This function implements +** the built-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B,A). +** +** This same function (with a different compareInfo structure) computes +** the GLOB operator. +*/ +static void likeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA, *zB; + u32 escape; + int nPat; + sqlite3 *db = sqlite3_context_db_handle(context); + struct compareInfo *pInfo = sqlite3_user_data(context); + struct compareInfo backupInfo; + +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( sqlite3_value_type(argv[0])==SQLITE_BLOB + || sqlite3_value_type(argv[1])==SQLITE_BLOB + ){ +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, 0); + return; + } +#endif + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + nPat = sqlite3_value_bytes(argv[0]); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); + if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + const unsigned char *zEsc = sqlite3_value_text(argv[2]); + if( zEsc==0 ) return; + if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + escape = sqlite3Utf8Read(&zEsc); + if( escape==pInfo->matchAll || escape==pInfo->matchOne ){ + memcpy(&backupInfo, pInfo, sizeof(backupInfo)); + pInfo = &backupInfo; + if( escape==pInfo->matchAll ) pInfo->matchAll = 0; + if( escape==pInfo->matchOne ) pInfo->matchOne = 0; + } + }else{ + escape = pInfo->matchSet; + } + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); + if( zA && zB ){ +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, + patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); + } +} + +/* +** Implementation of the NULLIF(x,y) function. The result is the first +** argument if the arguments are different. The result is NULL if the +** arguments are equal to each other. +*/ +static void nullifFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + UNUSED_PARAMETER(NotUsed); + if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ + sqlite3_result_value(context, argv[0]); + } +} + +/* +** Implementation of the sqlite_version() function. The result is the version +** of the SQLite library that is running. +*/ +static void versionFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-48699-48617 This function is an SQL wrapper around the + ** sqlite3_libversion() C-interface. */ + sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_source_id() function. The result is a string +** that identifies the particular version of the source code used to build +** SQLite. +*/ +static void sourceidFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-24470-31136 This function is an SQL wrapper around the + ** sqlite3_sourceid() C interface. */ + sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_log() function. This is a wrapper around +** sqlite3_log(). The return value is NULL. The function exists purely for +** its side-effects. +*/ +static void errlogFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(context); + sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); +} + +/* +** Implementation of the sqlite_compileoption_used() function. +** The result is an integer that identifies if the compiler option +** was used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptionusedFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zOptName; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL + ** function is a wrapper around the sqlite3_compileoption_used() C/C++ + ** function. + */ + if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); + } +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* +** Implementation of the sqlite_compileoption_get() function. +** The result is a string that identifies the compiler options +** used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptiongetFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. + */ + n = sqlite3_value_int(argv[0]); + sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* Array for converting from half-bytes (nybbles) into ASCII hex +** digits. */ +static const char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/* +** Append to pStr text that is the SQL literal representation of the +** value contained in pValue. +*/ +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ + /* As currently implemented, the string must be initially empty. + ** we might relax this requirement in the future, but that will + ** require enhancements to the implementation. */ + assert( pStr!=0 && pStr->nChar==0 ); + + switch( sqlite3_value_type(pValue) ){ + case SQLITE_FLOAT: { + double r1, r2; + const char *zVal; + r1 = sqlite3_value_double(pValue); + sqlite3_str_appendf(pStr, "%!0.15g", r1); + zVal = sqlite3_str_value(pStr); + if( zVal ){ + sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); + if( r1!=r2 ){ + sqlite3_str_reset(pStr); + sqlite3_str_appendf(pStr, "%!0.20e", r1); + } + } + break; + } + case SQLITE_INTEGER: { + sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue)); + break; + } + case SQLITE_BLOB: { + char const *zBlob = sqlite3_value_blob(pValue); + i64 nBlob = sqlite3_value_bytes(pValue); + assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ + sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); + if( pStr->accError==0 ){ + char *zText = pStr->zText; + int i; + for(i=0; i>4)&0x0F]; + zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; + } + zText[(nBlob*2)+2] = '\''; + zText[(nBlob*2)+3] = '\0'; + zText[0] = 'X'; + zText[1] = '\''; + pStr->nChar = nBlob*2 + 3; + } + break; + } + case SQLITE_TEXT: { + const unsigned char *zArg = sqlite3_value_text(pValue); + sqlite3_str_appendf(pStr, "%Q", zArg); + break; + } + default: { + assert( sqlite3_value_type(pValue)==SQLITE_NULL ); + sqlite3_str_append(pStr, "NULL", 4); + break; + } + } +} + +/* +** Implementation of the QUOTE() function. +** +** The quote(X) function returns the text of an SQL literal which is the +** value of its argument suitable for inclusion into an SQL statement. +** Strings are surrounded by single-quotes with escapes on interior quotes +** as needed. BLOBs are encoded as hexadecimal literals. Strings with +** embedded NUL characters cannot be represented as string literals in SQL +** and hence the returned string literal is truncated prior to the first NUL. +*/ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + sqlite3_str str; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( argc==1 ); + UNUSED_PARAMETER(argc); + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3QuoteValue(&str,argv[0]); + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, + SQLITE_DYNAMIC); + if( str.accError!=SQLITE_OK ){ + sqlite3_result_null(context); + sqlite3_result_error_code(context, str.accError); + } +} + +/* +** The unicode() function. Return the integer unicode code-point value +** for the first character of the input string. +*/ +static void unicodeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z = sqlite3_value_text(argv[0]); + (void)argc; + if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z)); +} + +/* +** The char() function takes zero or more arguments, each of which is +** an integer. It constructs a string where each character of the string +** is the unicode character for the corresponding integer argument. +*/ +static void charFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char *z, *zOut; + int i; + zOut = z = sqlite3_malloc64( argc*4+1 ); + if( z==0 ){ + sqlite3_result_error_nomem(context); + return; + } + for(i=0; i0x10ffff ) x = 0xfffd; + c = (unsigned)(x & 0x1fffff); + if( c<0x00080 ){ + *zOut++ = (u8)(c&0xFF); + }else if( c<0x00800 ){ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + }else if( c<0x10000 ){ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + }else{ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + } \ + } + *zOut = 0; + sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); +} + +/* +** The hex() function. Interpret the argument as a blob. Return +** a hexadecimal rendering as text. +*/ +static void hexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i, n; + const unsigned char *pBlob; + char *zHex, *z; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ + z = zHex = contextMalloc(context, ((i64)n)*2 + 1); + if( zHex ){ + for(i=0; i>4)&0xf]; + *(z++) = hexdigits[c&0xf]; + } + *z = 0; + sqlite3_result_text64(context, zHex, (u64)(z-zHex), + sqlite3_free, SQLITE_UTF8); + } +} + +/* +** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr +** contains character ch, or 0 if it does not. +*/ +static int strContainsChar(const u8 *zStr, int nStr, u32 ch){ + const u8 *zEnd = &zStr[nStr]; + const u8 *z = zStr; + while( zmallocFailed ); + return; + } + if( zPattern[0]==0 ){ + assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); + sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT); + return; + } + nPattern = sqlite3_value_bytes(argv[1]); + assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ + zRep = sqlite3_value_text(argv[2]); + if( zRep==0 ) return; + nRep = sqlite3_value_bytes(argv[2]); + assert( zRep==sqlite3_value_text(argv[2]) ); + nOut = nStr + 1; + assert( nOutnPattern ){ + nOut += nRep - nPattern; + testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + sqlite3_free(zOut); + return; + } + cntExpand++; + if( (cntExpand&(cntExpand-1))==0 ){ + /* Grow the size of the output buffer only on substitutions + ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */ + u8 *zOld; + zOld = zOut; + zOut = sqlite3Realloc(zOut, (int)nOut + (nOut - nStr - 1)); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + sqlite3_free(zOld); + return; + } + } + } + memcpy(&zOut[j], zRep, nRep); + j += nRep; + i += nPattern-1; + } + } + assert( j+nStr-i+1<=nOut ); + memcpy(&zOut[j], &zStr[i], nStr-i); + j += nStr - i; + assert( j<=nOut ); + zOut[j] = 0; + sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); +} + +/* +** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. +** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. +*/ +static void trimFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zIn; /* Input string */ + const unsigned char *zCharSet; /* Set of characters to trim */ + unsigned int nIn; /* Number of bytes in input */ + int flags; /* 1: trimleft 2: trimright 3: trim */ + int i; /* Loop counter */ + unsigned int *aLen = 0; /* Length of each character in zCharSet */ + unsigned char **azChar = 0; /* Individual characters in zCharSet */ + int nChar; /* Number of characters in zCharSet */ + + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + return; + } + zIn = sqlite3_value_text(argv[0]); + if( zIn==0 ) return; + nIn = (unsigned)sqlite3_value_bytes(argv[0]); + assert( zIn==sqlite3_value_text(argv[0]) ); + if( argc==1 ){ + static const unsigned lenOne[] = { 1 }; + static unsigned char * const azOne[] = { (u8*)" " }; + nChar = 1; + aLen = (unsigned*)lenOne; + azChar = (unsigned char **)azOne; + zCharSet = 0; + }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ + return; + }else{ + const unsigned char *z; + for(z=zCharSet, nChar=0; *z; nChar++){ + SQLITE_SKIP_UTF8(z); + } + if( nChar>0 ){ + azChar = contextMalloc(context, + ((i64)nChar)*(sizeof(char*)+sizeof(unsigned))); + if( azChar==0 ){ + return; + } + aLen = (unsigned*)&azChar[nChar]; + for(z=zCharSet, nChar=0; *z; nChar++){ + azChar[nChar] = (unsigned char *)z; + SQLITE_SKIP_UTF8(z); + aLen[nChar] = (unsigned)(z - azChar[nChar]); + } + } + } + if( nChar>0 ){ + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); + if( flags & 1 ){ + while( nIn>0 ){ + unsigned int len = 0; + for(i=0; i=nChar ) break; + zIn += len; + nIn -= len; + } + } + if( flags & 2 ){ + while( nIn>0 ){ + unsigned int len = 0; + for(i=0; i=nChar ) break; + nIn -= len; + } + } + if( zCharSet ){ + sqlite3_free(azChar); + } + } + sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); +} + +/* The core implementation of the CONCAT(...) and CONCAT_WS(SEP,...) +** functions. +** +** Return a string value that is the concatenation of all non-null +** entries in argv[]. Use zSep as the separator. +*/ +static void concatFuncCore( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + int nSep, + const char *zSep +){ + i64 j, k, n = 0; + int i; + char *z; + for(i=0; i0 ){ + const char *v = (const char*)sqlite3_value_text(argv[i]); + if( v!=0 ){ + if( j>0 && nSep>0 ){ + memcpy(&z[j], zSep, nSep); + j += nSep; + } + memcpy(&z[j], v, k); + j += k; + } + } + } + z[j] = 0; + assert( j<=n ); + sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8); +} + +/* +** The CONCAT(...) function. Generate a string result that is the +** concatentation of all non-null arguments. +*/ +static void concatFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + concatFuncCore(context, argc, argv, 0, ""); +} + +/* +** The CONCAT_WS(separator, ...) function. +** +** Generate a string that is the concatenation of 2nd through the Nth +** argument. Use the first argument (which must be non-NULL) as the +** separator. +*/ +static void concatwsFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nSep = sqlite3_value_bytes(argv[0]); + const char *zSep = (const char*)sqlite3_value_text(argv[0]); + if( zSep==0 ) return; + concatFuncCore(context, argc-1, argv+1, nSep, zSep); +} + + +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +/* +** The "unknown" function is automatically substituted in place of +** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN +** when the SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option is used. +** When the "sqlite3" command-line shell is built using this functionality, +** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries +** involving application-defined functions to be examined in a generic +** sqlite3 shell. +*/ +static void unknownFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + /* no-op */ + (void)context; + (void)argc; + (void)argv; +} +#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ + + +/* IMP: R-25361-16150 This function is omitted from SQLite by default. It +** is only available if the SQLITE_SOUNDEX compile-time option is used +** when SQLite is built. +*/ +#ifdef SQLITE_SOUNDEX +/* +** Compute the soundex encoding of a word. +** +** IMP: R-59782-00072 The soundex(X) function returns a string that is the +** soundex encoding of the string X. +*/ +static void soundexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + char zResult[8]; + const u8 *zIn; + int i, j; + static const unsigned char iCode[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + }; + assert( argc==1 ); + zIn = (u8*)sqlite3_value_text(argv[0]); + if( zIn==0 ) zIn = (u8*)""; + for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){} + if( zIn[i] ){ + u8 prevcode = iCode[zIn[i]&0x7f]; + zResult[0] = sqlite3Toupper(zIn[i]); + for(j=1; j<4 && zIn[i]; i++){ + int code = iCode[zIn[i]&0x7f]; + if( code>0 ){ + if( code!=prevcode ){ + prevcode = code; + zResult[j++] = code + '0'; + } + }else{ + prevcode = 0; + } + } + while( j<4 ){ + zResult[j++] = '0'; + } + zResult[j] = 0; + sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); + }else{ + /* IMP: R-64894-50321 The string "?000" is returned if the argument + ** is NULL or contains no ASCII alphabetic characters. */ + sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); + } +} +#endif /* SQLITE_SOUNDEX */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** A function that loads a shared-library extension then returns NULL. +*/ +static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ + const char *zFile = (const char *)sqlite3_value_text(argv[0]); + const char *zProc; + sqlite3 *db = sqlite3_context_db_handle(context); + char *zErrMsg = 0; + + /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc + ** flag is set. See the sqlite3_enable_load_extension() API. + */ + if( (db->flags & SQLITE_LoadExtFunc)==0 ){ + sqlite3_result_error(context, "not authorized", -1); + return; + } + + if( argc==2 ){ + zProc = (const char *)sqlite3_value_text(argv[1]); + }else{ + zProc = 0; + } + if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ + sqlite3_result_error(context, zErrMsg, -1); + sqlite3_free(zErrMsg); + } +} +#endif + + +/* +** An instance of the following structure holds the context of a +** sum() or avg() aggregate computation. +*/ +typedef struct SumCtx SumCtx; +struct SumCtx { + double rSum; /* Running sum as as a double */ + double rErr; /* Error term for Kahan-Babushka-Neumaier summation */ + i64 iSum; /* Running sum as a signed integer */ + i64 cnt; /* Number of elements summed */ + u8 approx; /* True if any non-integer value was input to the sum */ + u8 ovrfl; /* Integer overflow seen */ +}; + +/* +** Do one step of the Kahan-Babushka-Neumaier summation. +** +** https://en.wikipedia.org/wiki/Kahan_summation_algorithm +** +** Variables are marked "volatile" to defeat c89 x86 floating point +** optimizations can mess up this algorithm. +*/ +static void kahanBabuskaNeumaierStep( + volatile SumCtx *pSum, + volatile double r +){ + volatile double s = pSum->rSum; + volatile double t = s + r; + if( fabs(s) > fabs(r) ){ + pSum->rErr += (s - t) + r; + }else{ + pSum->rErr += (r - t) + s; + } + pSum->rSum = t; +} + +/* +** Add a (possibly large) integer to the running sum. +*/ +static void kahanBabuskaNeumaierStepInt64(volatile SumCtx *pSum, i64 iVal){ + if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ + i64 iBig, iSm; + iSm = iVal % 16384; + iBig = iVal - iSm; + kahanBabuskaNeumaierStep(pSum, iBig); + kahanBabuskaNeumaierStep(pSum, iSm); + }else{ + kahanBabuskaNeumaierStep(pSum, (double)iVal); + } +} + +/* +** Initialize the Kahan-Babaska-Neumaier sum from a 64-bit integer +*/ +static void kahanBabuskaNeumaierInit( + volatile SumCtx *p, + i64 iVal +){ + if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ + i64 iSm = iVal % 16384; + p->rSum = (double)(iVal - iSm); + p->rErr = (double)iSm; + }else{ + p->rSum = (double)iVal; + p->rErr = 0.0; + } +} + +/* +** Routines used to compute the sum, average, and total. +** +** The SUM() function follows the (broken) SQL standard which means +** that it returns NULL if it sums over no inputs. TOTAL returns +** 0.0 in that case. In addition, TOTAL always returns a float where +** SUM might return an integer if it never encounters a floating point +** value. TOTAL never fails, but SUM might through an exception if +** it overflows an integer. +*/ +static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + if( p && type!=SQLITE_NULL ){ + p->cnt++; + if( p->approx==0 ){ + if( type!=SQLITE_INTEGER ){ + kahanBabuskaNeumaierInit(p, p->iSum); + p->approx = 1; + kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); + }else{ + i64 x = p->iSum; + if( sqlite3AddInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ + p->iSum = x; + }else{ + p->ovrfl = 1; + kahanBabuskaNeumaierInit(p, p->iSum); + p->approx = 1; + kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); + } + } + }else{ + if( type==SQLITE_INTEGER ){ + kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); + }else{ + p->ovrfl = 0; + kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); + } + } + } +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + /* p is always non-NULL because sumStep() will have been called first + ** to initialize it */ + if( ALWAYS(p) && type!=SQLITE_NULL ){ + assert( p->cnt>0 ); + p->cnt--; + if( !p->approx ){ + p->iSum -= sqlite3_value_int64(argv[0]); + }else if( type==SQLITE_INTEGER ){ + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal!=SMALLEST_INT64 ){ + kahanBabuskaNeumaierStepInt64(p, -iVal); + }else{ + kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64); + kahanBabuskaNeumaierStepInt64(p, 1); + } + }else{ + kahanBabuskaNeumaierStep(p, -sqlite3_value_double(argv[0])); + } + } +} +#else +# define sumInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void sumFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + if( p->approx ){ + if( p->ovrfl ){ + sqlite3_result_error(context,"integer overflow",-1); + }else if( !sqlite3IsOverflow(p->rErr) ){ + sqlite3_result_double(context, p->rSum+p->rErr); + }else{ + sqlite3_result_double(context, p->rSum); + } + }else{ + sqlite3_result_int64(context, p->iSum); + } + } +} +static void avgFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + double r; + if( p->approx ){ + r = p->rSum; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; + }else{ + r = (double)(p->iSum); + } + sqlite3_result_double(context, r/(double)p->cnt); + } +} +static void totalFinalize(sqlite3_context *context){ + SumCtx *p; + double r = 0.0; + p = sqlite3_aggregate_context(context, 0); + if( p ){ + if( p->approx ){ + r = p->rSum; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; + }else{ + r = (double)(p->iSum); + } + } + sqlite3_result_double(context, r); +} + +/* +** The following structure keeps track of state information for the +** count() aggregate function. +*/ +typedef struct CountCtx CountCtx; +struct CountCtx { + i64 n; +#ifdef SQLITE_DEBUG + int bInverse; /* True if xInverse() ever called */ +#endif +}; + +/* +** Routines to implement the count() aggregate function. +*/ +static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(context, sizeof(*p)); + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ + p->n++; + } + +#ifndef SQLITE_OMIT_DEPRECATED + /* The sqlite3_aggregate_count() function is deprecated. But just to make + ** sure it still operates correctly, verify that its count agrees with our + ** internal count when using count(*) and when the total count can be + ** expressed as a 32-bit integer. */ + assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse + || p->n==sqlite3_aggregate_count(context) ); +#endif +} +static void countFinalize(sqlite3_context *context){ + CountCtx *p; + p = sqlite3_aggregate_context(context, 0); + sqlite3_result_int64(context, p ? p->n : 0); +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(ctx, sizeof(*p)); + /* p is always non-NULL since countStep() will have been called first */ + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){ + p->n--; +#ifdef SQLITE_DEBUG + p->bInverse = 1; +#endif + } +} +#else +# define countInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** Routines to implement min() and max() aggregate functions. +*/ +static void minmaxStep( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + Mem *pArg = (Mem *)argv[0]; + Mem *pBest; + UNUSED_PARAMETER(NotUsed); + + pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); + if( !pBest ) return; + + if( sqlite3_value_type(pArg)==SQLITE_NULL ){ + if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); + }else if( pBest->flags ){ + int max; + int cmp; + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + /* This step function is used for both the min() and max() aggregates, + ** the only difference between the two being that the sense of the + ** comparison is inverted. For the max() aggregate, the + ** sqlite3_user_data() function returns (void *)-1. For min() it + ** returns (void *)db, where db is the sqlite3* database pointer. + ** Therefore the next statement sets variable 'max' to 1 for the max() + ** aggregate, or 0 for min(). + */ + max = sqlite3_user_data(context)!=0; + cmp = sqlite3MemCompare(pBest, pArg, pColl); + if( (max && cmp<0) || (!max && cmp>0) ){ + sqlite3VdbeMemCopy(pBest, pArg); + }else{ + sqlite3SkipAccumulatorLoad(context); + } + }else{ + pBest->db = sqlite3_context_db_handle(context); + sqlite3VdbeMemCopy(pBest, pArg); + } +} +static void minMaxValueFinalize(sqlite3_context *context, int bValue){ + sqlite3_value *pRes; + pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); + if( pRes ){ + if( pRes->flags ){ + sqlite3_result_value(context, pRes); + } + if( bValue==0 ) sqlite3VdbeMemRelease(pRes); + } +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void minMaxValue(sqlite3_context *context){ + minMaxValueFinalize(context, 1); +} +#else +# define minMaxValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void minMaxFinalize(sqlite3_context *context){ + minMaxValueFinalize(context, 0); +} + +/* +** group_concat(EXPR, ?SEPARATOR?) +** string_agg(EXPR, SEPARATOR) +** +** The SEPARATOR goes before the EXPR string. This is tragic. The +** groupConcatInverse() implementation would have been easier if the +** SEPARATOR were appended after EXPR. And the order is undocumented, +** so we could change it, in theory. But the old behavior has been +** around for so long that we dare not, for fear of breaking something. +*/ +typedef struct { + StrAccum str; /* The accumulated concatenation */ +#ifndef SQLITE_OMIT_WINDOWFUNC + int nAccum; /* Number of strings presently concatenated */ + int nFirstSepLength; /* Used to detect separator length change */ + /* If pnSepLengths!=0, refs an array of inter-string separator lengths, + ** stored as actually incorporated into presently accumulated result. + ** (Hence, its slots in use number nAccum-1 between method calls.) + ** If pnSepLengths==0, nFirstSepLength is the length used throughout. + */ + int *pnSepLengths; +#endif +} GroupConcatCtx; + +static void groupConcatStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zVal; + GroupConcatCtx *pGCC; + const char *zSep; + int nVal, nSep; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); + if( pGCC ){ + sqlite3 *db = sqlite3_context_db_handle(context); + int firstTerm = pGCC->str.mxAlloc==0; + pGCC->str.mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; + if( argc==1 ){ + if( !firstTerm ){ + sqlite3_str_appendchar(&pGCC->str, 1, ','); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + pGCC->nFirstSepLength = 1; + } +#endif + }else if( !firstTerm ){ + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); + if( zSep ){ + sqlite3_str_append(&pGCC->str, zSep, nSep); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + nSep = 0; + } + if( nSep != pGCC->nFirstSepLength || pGCC->pnSepLengths != 0 ){ + int *pnsl = pGCC->pnSepLengths; + if( pnsl == 0 ){ + /* First separator length variation seen, start tracking them. */ + pnsl = (int*)sqlite3_malloc64((pGCC->nAccum+1) * sizeof(int)); + if( pnsl!=0 ){ + int i = 0, nA = pGCC->nAccum-1; + while( inFirstSepLength; + } + }else{ + pnsl = (int*)sqlite3_realloc64(pnsl, pGCC->nAccum * sizeof(int)); + } + if( pnsl!=0 ){ + if( ALWAYS(pGCC->nAccum>0) ){ + pnsl[pGCC->nAccum-1] = nSep; + } + pGCC->pnSepLengths = pnsl; + }else{ + sqlite3StrAccumSetError(&pGCC->str, SQLITE_NOMEM); + } + } +#endif + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + pGCC->nFirstSepLength = sqlite3_value_bytes(argv[1]); + } + pGCC->nAccum += 1; +#endif + zVal = (char*)sqlite3_value_text(argv[0]); + nVal = sqlite3_value_bytes(argv[0]); + if( zVal ) sqlite3_str_append(&pGCC->str, zVal, nVal); + } +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatInverse( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GroupConcatCtx *pGCC; + assert( argc==1 || argc==2 ); + (void)argc; /* Suppress unused parameter warning */ + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); + /* pGCC is always non-NULL since groupConcatStep() will have always + ** run first to initialize it */ + if( ALWAYS(pGCC) ){ + int nVS; + /* Must call sqlite3_value_text() to convert the argument into text prior + ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ + (void)sqlite3_value_text(argv[0]); + nVS = sqlite3_value_bytes(argv[0]); + pGCC->nAccum -= 1; + if( pGCC->pnSepLengths!=0 ){ + assert(pGCC->nAccum >= 0); + if( pGCC->nAccum>0 ){ + nVS += *pGCC->pnSepLengths; + memmove(pGCC->pnSepLengths, pGCC->pnSepLengths+1, + (pGCC->nAccum-1)*sizeof(int)); + } + }else{ + /* If removing single accumulated string, harmlessly over-do. */ + nVS += pGCC->nFirstSepLength; + } + if( nVS>=(int)pGCC->str.nChar ){ + pGCC->str.nChar = 0; + }else{ + pGCC->str.nChar -= nVS; + memmove(pGCC->str.zText, &pGCC->str.zText[nVS], pGCC->str.nChar); + } + if( pGCC->str.nChar==0 ){ + pGCC->str.mxAlloc = 0; + sqlite3_free(pGCC->pnSepLengths); + pGCC->pnSepLengths = 0; + } + } +} +#else +# define groupConcatInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void groupConcatFinalize(sqlite3_context *context){ + GroupConcatCtx *pGCC + = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); + if( pGCC ){ + sqlite3ResultStrAccum(context, &pGCC->str); +#ifndef SQLITE_OMIT_WINDOWFUNC + sqlite3_free(pGCC->pnSepLengths); +#endif + } +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatValue(sqlite3_context *context){ + GroupConcatCtx *pGCC + = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); + if( pGCC ){ + StrAccum *pAccum = &pGCC->str; + if( pAccum->accError==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(context); + }else if( pAccum->accError==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + const char *zText = sqlite3_str_value(pAccum); + sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); + } + } +} +#else +# define groupConcatValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** This routine does per-connection function registration. Most +** of the built-in functions above are part of the global function set. +** This routine only deals with those that are not global. +*/ +SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ + int rc = sqlite3_overload_function(db, "MATCH", 2); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } +} + +/* +** Re-register the built-in LIKE functions. The caseSensitive +** parameter determines whether or not the LIKE operator is case +** sensitive. +*/ +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + FuncDef *pDef; + struct compareInfo *pInfo; + int flags; + int nArg; + if( caseSensitive ){ + pInfo = (struct compareInfo*)&likeInfoAlt; + flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; + }else{ + pInfo = (struct compareInfo*)&likeInfoNorm; + flags = SQLITE_FUNC_LIKE; + } + for(nArg=2; nArg<=3; nArg++){ + sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, + 0, 0, 0, 0, 0); + pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); + pDef->funcFlags |= flags; + pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; + } +} + +/* +** pExpr points to an expression which implements a function. If +** it is appropriate to apply the LIKE optimization to that function +** then set aWc[0] through aWc[2] to the wildcard characters and the +** escape character and then return TRUE. If the function is not a +** LIKE-style function then return FALSE. +** +** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE +** operator if c is a string literal that is exactly one byte in length. +** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is +** no ESCAPE clause. +** +** *pIsNocase is set to true if uppercase and lowercase are equivalent for +** the function (default for LIKE). If the function makes the distinction +** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to +** false. +*/ +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ + FuncDef *pDef; + int nExpr; + assert( pExpr!=0 ); + assert( pExpr->op==TK_FUNCTION ); + assert( ExprUseXList(pExpr) ); + if( !pExpr->x.pList ){ + return 0; + } + nExpr = pExpr->x.pList->nExpr; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#endif + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ + return 0; + } + + /* The memcpy() statement assumes that the wildcard characters are + ** the first three statements in the compareInfo structure. The + ** asserts() that follow verify that assumption + */ + memcpy(aWc, pDef->pUserData, 3); + assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); + assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); + assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); + + if( nExpr<3 ){ + aWc[3] = 0; + }else{ + Expr *pEscape = pExpr->x.pList->a[2].pExpr; + char *zEscape; + if( pEscape->op!=TK_STRING ) return 0; + assert( !ExprHasProperty(pEscape, EP_IntValue) ); + zEscape = pEscape->u.zToken; + if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; + if( zEscape[0]==aWc[0] ) return 0; + if( zEscape[0]==aWc[1] ) return 0; + aWc[3] = zEscape[0]; + } + + *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0; + return 1; +} + +/* Mathematical Constants */ +#ifndef M_PI +# define M_PI 3.141592653589793238462643383279502884 +#endif +#ifndef M_LN10 +# define M_LN10 2.302585092994045684017991454684364208 +#endif +#ifndef M_LN2 +# define M_LN2 0.693147180559945309417232121458176568 +#endif + + +/* Extra math functions that require linking with -lm +*/ +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS +/* +** Implementation SQL functions: +** +** ceil(X) +** ceiling(X) +** floor(X) +** +** The sqlite3_user_data() pointer is a pointer to the libm implementation +** of the underlying C function. +*/ +static void ceilingFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: { + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + break; + } + case SQLITE_FLOAT: { + double (*x)(double) = (double(*)(double))sqlite3_user_data(context); + sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); + break; + } + default: { + break; + } + } +} + +/* +** On some systems, ceil() and floor() are intrinsic function. You are +** unable to take a pointer to these functions. Hence, we here wrap them +** in our own actual functions. +*/ +static double xCeil(double x){ return ceil(x); } +static double xFloor(double x){ return floor(x); } + +/* +** Some systems do not have log2() and log10() in their standard math +** libraries. +*/ +#if defined(HAVE_LOG10) && HAVE_LOG10==0 +# define log10(X) (0.4342944819032517867*log(X)) +#endif +#if defined(HAVE_LOG2) && HAVE_LOG2==0 +# define log2(X) (1.442695040888963456*log(X)) +#endif + + +/* +** Implementation of SQL functions: +** +** ln(X) - natural logarithm +** log(X) - log X base 10 +** log10(X) - log X base 10 +** log(B,X) - log X base B +*/ +static void logFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x, b, ans; + assert( argc==1 || argc==2 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + x = sqlite3_value_double(argv[0]); + if( x<=0.0 ) return; + break; + default: + return; + } + if( argc==2 ){ + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + b = log(x); + if( b<=0.0 ) return; + x = sqlite3_value_double(argv[1]); + if( x<=0.0 ) return; + break; + default: + return; + } + ans = log(x)/b; + }else{ + switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ + case 1: + ans = log10(x); + break; + case 2: + ans = log2(x); + break; + default: + ans = log(x); + break; + } + } + sqlite3_result_double(context, ans); +} + +/* +** Functions to converts degrees to radians and radians to degrees. +*/ +static double degToRad(double x){ return x*(M_PI/180.0); } +static double radToDeg(double x){ return x*(180.0/M_PI); } + +/* +** Implementation of 1-argument SQL math functions: +** +** exp(X) - Compute e to the X-th power +*/ +static void math1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double v0, ans; + double (*x)(double); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + x = (double(*)(double))sqlite3_user_data(context); + ans = x(v0); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void math2Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0, type1; + double v0, v1, ans; + double (*x)(double,double); + assert( argc==2 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + type1 = sqlite3_value_numeric_type(argv[1]); + if( type1!=SQLITE_INTEGER && type1!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + v1 = sqlite3_value_double(argv[1]); + x = (double(*)(double,double))sqlite3_user_data(context); + ans = x(v0, v1); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 0-argument pi() function. +*/ +static void piFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==0 ); + (void)argv; + sqlite3_result_double(context, M_PI); +} + +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + +/* +** Implementation of sign(X) function. +*/ +static void signFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double x; + UNUSED_PARAMETER(argc); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + x = sqlite3_value_double(argv[0]); + sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); +} + +#ifdef SQLITE_DEBUG +/* +** Implementation of fpdecode(x,y,z) function. +** +** x is a real number that is to be decoded. y is the precision. +** z is the maximum real precision. +*/ +static void fpdecodeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + FpDecode s; + double x; + int y, z; + char zBuf[100]; + UNUSED_PARAMETER(argc); + assert( argc==3 ); + x = sqlite3_value_double(argv[0]); + y = sqlite3_value_int(argv[1]); + z = sqlite3_value_int(argv[2]); + sqlite3FpDecode(&s, x, y, z); + if( s.isSpecial==2 ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); + }else{ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); + } + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); +} +#endif /* SQLITE_DEBUG */ + +/* +** All of the FuncDef structures in the aBuiltinFunc[] array above +** to the global function hash table. This occurs at start-time (as +** a consequence of calling sqlite3_initialize()). +** +** After this routine runs +*/ +SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ + /* + ** The following array holds FuncDef structures for all of the functions + ** defined in this file. + ** + ** The array cannot be constant since changes are made to the + ** FuncDef.pHash elements at start-time. The elements of this array + ** are read-only after initialization is complete. + ** + ** For peak efficiency, put the most frequently used function last. + */ + static FuncDef aBuiltinFunc[] = { +/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/ +#if !defined(SQLITE_UNTESTABLE) + TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0), + TEST_FUNC(expr_compare, 2, INLINEFUNC_expr_compare, 0), + TEST_FUNC(expr_implies_expr, 2, INLINEFUNC_expr_implies_expr, 0), + TEST_FUNC(affinity, 1, INLINEFUNC_affinity, 0), +#endif /* !defined(SQLITE_UNTESTABLE) */ +/***** Regular functions *****/ +#ifdef SQLITE_SOUNDEX + FUNCTION(soundex, 1, 0, 0, soundexFunc ), +#endif +#ifndef SQLITE_OMIT_LOAD_EXTENSION + SFUNCTION(load_extension, 1, 0, 0, loadExt ), + SFUNCTION(load_extension, 2, 0, 0, loadExt ), +#endif +#if SQLITE_USER_AUTHENTICATION + FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), +#endif +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), + DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), + INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), + INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ), +#endif + FUNCTION(ltrim, 1, 1, 0, trimFunc ), + FUNCTION(ltrim, 2, 1, 0, trimFunc ), + FUNCTION(rtrim, 1, 2, 0, trimFunc ), + FUNCTION(rtrim, 2, 2, 0, trimFunc ), + FUNCTION(trim, 1, 3, 0, trimFunc ), + FUNCTION(trim, 2, 3, 0, trimFunc ), + FUNCTION(min, -1, 0, 1, minmaxFunc ), + FUNCTION(min, 0, 0, 1, 0 ), + WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, + SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), + FUNCTION(max, -1, 1, 1, minmaxFunc ), + FUNCTION(max, 0, 1, 1, 0 ), + WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, + SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), + FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), + FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), + FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), + FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), + FUNCTION(instr, 2, 0, 0, instrFunc ), + FUNCTION(printf, -1, 0, 0, printfFunc ), + FUNCTION(format, -1, 0, 0, printfFunc ), + FUNCTION(unicode, 1, 0, 0, unicodeFunc ), + FUNCTION(char, -1, 0, 0, charFunc ), + FUNCTION(abs, 1, 0, 0, absFunc ), +#ifdef SQLITE_DEBUG + FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), +#endif +#ifndef SQLITE_OMIT_FLOATING_POINT + FUNCTION(round, 1, 0, 0, roundFunc ), + FUNCTION(round, 2, 0, 0, roundFunc ), +#endif + FUNCTION(upper, 1, 0, 0, upperFunc ), + FUNCTION(lower, 1, 0, 0, lowerFunc ), + FUNCTION(hex, 1, 0, 0, hexFunc ), + FUNCTION(unhex, 1, 0, 0, unhexFunc ), + FUNCTION(unhex, 2, 0, 0, unhexFunc ), + FUNCTION(concat, -1, 0, 0, concatFunc ), + FUNCTION(concat, 0, 0, 0, 0 ), + FUNCTION(concat_ws, -1, 0, 0, concatwsFunc ), + FUNCTION(concat_ws, 0, 0, 0, 0 ), + FUNCTION(concat_ws, 1, 0, 0, 0 ), + INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), + VFUNCTION(random, 0, 0, 0, randomFunc ), + VFUNCTION(randomblob, 1, 0, 0, randomBlob ), + FUNCTION(nullif, 2, 0, 1, nullifFunc ), + DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), + DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), + FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), + FUNCTION(quote, 1, 0, 0, quoteFunc ), + VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), + VFUNCTION(changes, 0, 0, 0, changes ), + VFUNCTION(total_changes, 0, 0, 0, total_changes ), + FUNCTION(replace, 3, 0, 0, replaceFunc ), + FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), + FUNCTION(substr, 2, 0, 0, substrFunc ), + FUNCTION(substr, 3, 0, 0, substrFunc ), + FUNCTION(substring, 2, 0, 0, substrFunc ), + FUNCTION(substring, 3, 0, 0, substrFunc ), + WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), + WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), + WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), + WAGGREGATE(count, 0,0,0, countStep, + countFinalize, countFinalize, countInverse, + SQLITE_FUNC_COUNT|SQLITE_FUNC_ANYORDER ), + WAGGREGATE(count, 1,0,0, countStep, + countFinalize, countFinalize, countInverse, SQLITE_FUNC_ANYORDER ), + WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + + LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), +#ifdef SQLITE_CASE_SENSITIVE_LIKE + LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), +#else + LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), + LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), +#endif +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + FUNCTION(unknown, -1, 0, 0, unknownFunc ), +#endif + FUNCTION(coalesce, 1, 0, 0, 0 ), + FUNCTION(coalesce, 0, 0, 0, 0 ), +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + MFUNCTION(ceil, 1, xCeil, ceilingFunc ), + MFUNCTION(ceiling, 1, xCeil, ceilingFunc ), + MFUNCTION(floor, 1, xFloor, ceilingFunc ), +#if SQLITE_HAVE_C99_MATH_FUNCS + MFUNCTION(trunc, 1, trunc, ceilingFunc ), +#endif + FUNCTION(ln, 1, 0, 0, logFunc ), + FUNCTION(log, 1, 1, 0, logFunc ), + FUNCTION(log10, 1, 1, 0, logFunc ), + FUNCTION(log2, 1, 2, 0, logFunc ), + FUNCTION(log, 2, 0, 0, logFunc ), + MFUNCTION(exp, 1, exp, math1Func ), + MFUNCTION(pow, 2, pow, math2Func ), + MFUNCTION(power, 2, pow, math2Func ), + MFUNCTION(mod, 2, fmod, math2Func ), + MFUNCTION(acos, 1, acos, math1Func ), + MFUNCTION(asin, 1, asin, math1Func ), + MFUNCTION(atan, 1, atan, math1Func ), + MFUNCTION(atan2, 2, atan2, math2Func ), + MFUNCTION(cos, 1, cos, math1Func ), + MFUNCTION(sin, 1, sin, math1Func ), + MFUNCTION(tan, 1, tan, math1Func ), + MFUNCTION(cosh, 1, cosh, math1Func ), + MFUNCTION(sinh, 1, sinh, math1Func ), + MFUNCTION(tanh, 1, tanh, math1Func ), +#if SQLITE_HAVE_C99_MATH_FUNCS + MFUNCTION(acosh, 1, acosh, math1Func ), + MFUNCTION(asinh, 1, asinh, math1Func ), + MFUNCTION(atanh, 1, atanh, math1Func ), +#endif + MFUNCTION(sqrt, 1, sqrt, math1Func ), + MFUNCTION(radians, 1, degToRad, math1Func ), + MFUNCTION(degrees, 1, radToDeg, math1Func ), + FUNCTION(pi, 0, 0, 0, piFunc ), +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + FUNCTION(sign, 1, 0, 0, signFunc ), + INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), + INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), + }; +#ifndef SQLITE_OMIT_ALTERTABLE + sqlite3AlterFunctions(); +#endif + sqlite3WindowFunctions(); + sqlite3RegisterDateTimeFunctions(); + sqlite3RegisterJsonFunctions(); + sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); + +#if 0 /* Enable to print out how the built-in functions are hashed */ + { + int i; + FuncDef *p; + for(i=0; iu.pHash){ + int n = sqlite3Strlen30(p->zName); + int h = p->zName[0] + n; + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); + printf(" %s(%d)", p->zName, h); + } + printf("\n"); + } + } +#endif +} + +/************** End of func.c ************************************************/ +/************** Begin file fkey.c ********************************************/ +/* +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used by the compiler to add foreign key +** support to compiled SQL statements. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + +/* +** Deferred and Immediate FKs +** -------------------------- +** +** Foreign keys in SQLite come in two flavours: deferred and immediate. +** If an immediate foreign key constraint is violated, +** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current +** statement transaction rolled back. If a +** deferred foreign key constraint is violated, no action is taken +** immediately. However if the application attempts to commit the +** transaction before fixing the constraint violation, the attempt fails. +** +** Deferred constraints are implemented using a simple counter associated +** with the database handle. The counter is set to zero each time a +** database transaction is opened. Each time a statement is executed +** that causes a foreign key violation, the counter is incremented. Each +** time a statement is executed that removes an existing violation from +** the database, the counter is decremented. When the transaction is +** committed, the commit fails if the current value of the counter is +** greater than zero. This scheme has two big drawbacks: +** +** * When a commit fails due to a deferred foreign key constraint, +** there is no way to tell which foreign constraint is not satisfied, +** or which row it is not satisfied for. +** +** * If the database contains foreign key violations when the +** transaction is opened, this may cause the mechanism to malfunction. +** +** Despite these problems, this approach is adopted as it seems simpler +** than the alternatives. +** +** INSERT operations: +** +** I.1) For each FK for which the table is the child table, search +** the parent table for a match. If none is found increment the +** constraint counter. +** +** I.2) For each FK for which the table is the parent table, +** search the child table for rows that correspond to the new +** row in the parent table. Decrement the counter for each row +** found (as the constraint is now satisfied). +** +** DELETE operations: +** +** D.1) For each FK for which the table is the child table, +** search the parent table for a row that corresponds to the +** deleted row in the child table. If such a row is not found, +** decrement the counter. +** +** D.2) For each FK for which the table is the parent table, search +** the child table for rows that correspond to the deleted row +** in the parent table. For each found increment the counter. +** +** UPDATE operations: +** +** An UPDATE command requires that all 4 steps above are taken, but only +** for FK constraints for which the affected columns are actually +** modified (values must be compared at runtime). +** +** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2. +** This simplifies the implementation a bit. +** +** For the purposes of immediate FK constraints, the OR REPLACE conflict +** resolution is considered to delete rows before the new row is inserted. +** If a delete caused by OR REPLACE violates an FK constraint, an exception +** is thrown, even if the FK constraint would be satisfied after the new +** row is inserted. +** +** Immediate constraints are usually handled similarly. The only difference +** is that the counter used is stored as part of each individual statement +** object (struct Vdbe). If, after the statement has run, its immediate +** constraint counter is greater than zero, +** it returns SQLITE_CONSTRAINT_FOREIGNKEY +** and the statement transaction is rolled back. An exception is an INSERT +** statement that inserts a single row only (no triggers). In this case, +** instead of using a counter, an exception is thrown immediately if the +** INSERT violates a foreign key constraint. This is necessary as such +** an INSERT does not open a statement transaction. +** +** TODO: How should dropping a table be handled? How should renaming a +** table be handled? +** +** +** Query API Notes +** --------------- +** +** Before coding an UPDATE or DELETE row operation, the code-generator +** for those two operations needs to know whether or not the operation +** requires any FK processing and, if so, which columns of the original +** row are required by the FK processing VDBE code (i.e. if FKs were +** implemented using triggers, which of the old.* columns would be +** accessed). No information is required by the code-generator before +** coding an INSERT operation. The functions used by the UPDATE/DELETE +** generation code to query for this information are: +** +** sqlite3FkRequired() - Test to see if FK processing is required. +** sqlite3FkOldmask() - Query for the set of required old.* columns. +** +** +** Externally accessible module functions +** -------------------------------------- +** +** sqlite3FkCheck() - Check for foreign key violations. +** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. +** sqlite3FkDelete() - Delete an FKey structure. +*/ + +/* +** VDBE Calling Convention +** ----------------------- +** +** Example: +** +** For the following INSERT statement: +** +** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c); +** INSERT INTO t1 VALUES(1, 2, 3.1); +** +** Register (x): 2 (type integer) +** Register (x+1): 1 (type integer) +** Register (x+2): NULL (type NULL) +** Register (x+3): 3.1 (type real) +*/ + +/* +** A foreign key constraint requires that the key columns in the parent +** table are collectively subject to a UNIQUE or PRIMARY KEY constraint. +** Given that pParent is the parent table for foreign key constraint pFKey, +** search the schema for a unique index on the parent key columns. +** +** If successful, zero is returned. If the parent key is an INTEGER PRIMARY +** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx +** is set to point to the unique index. +** +** If the parent key consists of a single column (the foreign key constraint +** is not a composite foreign key), output variable *paiCol is set to NULL. +** Otherwise, it is set to point to an allocated array of size N, where +** N is the number of columns in the parent key. The first element of the +** array is the index of the child table column that is mapped by the FK +** constraint to the parent table column stored in the left-most column +** of index *ppIdx. The second element of the array is the index of the +** child table column that corresponds to the second left-most column of +** *ppIdx, and so on. +** +** If the required index cannot be found, either because: +** +** 1) The named parent key columns do not exist, or +** +** 2) The named parent key columns do exist, but are not subject to a +** UNIQUE or PRIMARY KEY constraint, or +** +** 3) No parent key columns were provided explicitly as part of the +** foreign key definition, and the parent table does not have a +** PRIMARY KEY, or +** +** 4) No parent key columns were provided explicitly as part of the +** foreign key definition, and the PRIMARY KEY of the parent table +** consists of a different number of columns to the child key in +** the child table. +** +** then non-zero is returned, and a "foreign key mismatch" error loaded +** into pParse. If an OOM error occurs, non-zero is returned and the +** pParse->db->mallocFailed flag is set. +*/ +SQLITE_PRIVATE int sqlite3FkLocateIndex( + Parse *pParse, /* Parse context to store any error in */ + Table *pParent, /* Parent table of FK constraint pFKey */ + FKey *pFKey, /* Foreign key to find index for */ + Index **ppIdx, /* OUT: Unique index on parent table */ + int **paiCol /* OUT: Map of index columns in pFKey */ +){ + Index *pIdx = 0; /* Value to return via *ppIdx */ + int *aiCol = 0; /* Value to return via *paiCol */ + int nCol = pFKey->nCol; /* Number of columns in parent key */ + char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */ + + /* The caller is responsible for zeroing output parameters. */ + assert( ppIdx && *ppIdx==0 ); + assert( !paiCol || *paiCol==0 ); + assert( pParse ); + + /* If this is a non-composite (single column) foreign key, check if it + ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx + ** and *paiCol set to zero and return early. + ** + ** Otherwise, for a composite foreign key (more than one column), allocate + ** space for the aiCol array (returned via output parameter *paiCol). + ** Non-composite foreign keys do not require the aiCol array. + */ + if( nCol==1 ){ + /* The FK maps to the IPK if any of the following are true: + ** + ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly + ** mapped to the primary key of table pParent, or + ** 2) The FK is explicitly mapped to a column declared as INTEGER + ** PRIMARY KEY. + */ + if( pParent->iPKey>=0 ){ + if( !zKey ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zCnName, zKey) ){ + return 0; + } + } + }else if( paiCol ){ + assert( nCol>1 ); + aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); + if( !aiCol ) return 1; + *paiCol = aiCol; + } + + for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ + /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number + ** of columns. If each indexed column corresponds to a foreign key + ** column of pFKey, then this index is a winner. */ + + if( zKey==0 ){ + /* If zKey is NULL, then this foreign key is implicitly mapped to + ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be + ** identified by the test. */ + if( IsPrimaryKeyIndex(pIdx) ){ + if( aiCol ){ + int i; + for(i=0; iaCol[i].iFrom; + } + break; + } + }else{ + /* If zKey is non-NULL, then this foreign key was declared to + ** map to an explicit list of columns in table pParent. Check if this + ** index matches those columns. Also, check that the index uses + ** the default collation sequences for each column. */ + int i, j; + for(i=0; iaiColumn[i]; /* Index of column in parent tbl */ + const char *zDfltColl; /* Def. collation for column */ + char *zIdxCol; /* Name of indexed column */ + + if( iCol<0 ) break; /* No foreign keys against expression indexes */ + + /* If the index uses a collation sequence that is different from + ** the default collation sequence for the column, this index is + ** unusable. Bail out early in this case. */ + zDfltColl = sqlite3ColumnColl(&pParent->aCol[iCol]); + if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; + if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; + + zIdxCol = pParent->aCol[iCol].zCnName; + for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ + if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; + break; + } + } + if( j==nCol ) break; + } + if( i==nCol ) break; /* pIdx is usable */ + } + } + } + + if( !pIdx ){ + if( !pParse->disableTriggers ){ + sqlite3ErrorMsg(pParse, + "foreign key mismatch - \"%w\" referencing \"%w\"", + pFKey->pFrom->zName, pFKey->zTo); + } + sqlite3DbFree(pParse->db, aiCol); + return 1; + } + + *ppIdx = pIdx; + return 0; +} + +/* +** This function is called when a row is inserted into or deleted from the +** child table of foreign key constraint pFKey. If an SQL UPDATE is executed +** on the child table of pFKey, this function is invoked twice for each row +** affected - once to "delete" the old row, and then again to "insert" the +** new row. +** +** Each time it is called, this function generates VDBE code to locate the +** row in the parent table that corresponds to the row being inserted into +** or deleted from the child table. If the parent row can be found, no +** special action is taken. Otherwise, if the parent row can *not* be +** found in the parent table: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** INSERT immediate Increment the "immediate constraint counter". +** +** DELETE immediate Decrement the "immediate constraint counter". +** +** INSERT deferred Increment the "deferred constraint counter". +** +** DELETE deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.1" and "D.1". +*/ +static void fkLookupParent( + Parse *pParse, /* Parse context */ + int iDb, /* Index of database housing pTab */ + Table *pTab, /* Parent table of FK pFKey */ + Index *pIdx, /* Unique index on parent key columns in pTab */ + FKey *pFKey, /* Foreign key constraint */ + int *aiCol, /* Map from parent key columns to child table columns */ + int regData, /* Address of array containing child table row */ + int nIncr, /* Increment constraint counter by this */ + int isIgnore /* If true, pretend pTab contains all NULL values */ +){ + int i; /* Iterator variable */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ + int iCur = pParse->nTab - 1; /* Cursor number to use */ + int iOk = sqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */ + + sqlite3VdbeVerifyAbortable(v, + (!pFKey->isDeferred + && !(pParse->db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel + && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore); + + /* If nIncr is less than zero, then check at runtime if there are any + ** outstanding constraints to resolve. If there are not, there is no need + ** to check if deleting this row resolves any outstanding violations. + ** + ** Check if any of the key columns in the child table row are NULL. If + ** any are, then the constraint is considered satisfied. No need to + ** search for a matching row in the parent table. */ + if( nIncr<0 ){ + sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + VdbeCoverage(v); + } + for(i=0; inCol; i++){ + int iReg = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); + } + + if( isIgnore==0 ){ + if( pIdx==0 ){ + /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY + ** column of the parent table (table pTab). */ + int iMustBeInt; /* Address of MustBeInt instruction */ + int regTemp = sqlite3GetTempReg(pParse); + + /* Invoke MustBeInt to coerce the child key value to an integer (i.e. + ** apply the affinity of the parent key). If this fails, then there + ** is no matching parent key. Before using MustBeInt, make a copy of + ** the value. Otherwise, the value inserted into the child key column + ** will have INTEGER affinity applied to it, which may not be correct. */ + sqlite3VdbeAddOp2(v, OP_SCopy, + sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp); + iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + VdbeCoverage(v); + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + } + + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); + sqlite3VdbeGoto(v, iOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeJumpHere(v, iMustBeInt); + sqlite3ReleaseTempReg(pParse, regTemp); + }else{ + int nCol = pFKey->nCol; + int regTemp = sqlite3GetTempRange(pParse, nCol); + + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + for(i=0; ipFrom, aiCol[i])+1+regData, + regTemp+i); + } + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. + ** + ** If any of the parent-key values are NULL, then the row cannot match + ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any + ** of the parent-key values are NULL (at this point it is known that + ** none of the child key values are). + */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; + for(i=0; ipFrom,aiCol[i]) + +1+regData; + int iParent = 1+regData; + iParent += sqlite3TableColumnToStorage(pIdx->pTable, + pIdx->aiColumn[i]); + assert( pIdx->aiColumn[i]>=0 ); + assert( aiCol[i]!=pTab->iPKey ); + if( pIdx->aiColumn[i]==pTab->iPKey ){ + /* The parent key is a composite key that includes the IPK column */ + iParent = regData; + } + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + } + sqlite3VdbeGoto(v, iOk); + } + + sqlite3VdbeAddOp4(v, OP_Affinity, regTemp, nCol, 0, + sqlite3IndexAffinityStr(pParse->db,pIdx), nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol); + VdbeCoverage(v); + sqlite3ReleaseTempRange(pParse, regTemp, nCol); + } + } + + if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel + && !pParse->isMultiWrite + ){ + /* Special case: If this is an INSERT statement that will insert exactly + ** one row into the table, raise a constraint immediately instead of + ** incrementing a counter. This is necessary as the VM code is being + ** generated for will not open a statement transaction. */ + assert( nIncr==1 ); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, 0, P4_STATIC, P5_ConstraintFK); + }else{ + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + } + + sqlite3VdbeResolveLabel(v, iOk); + sqlite3VdbeAddOp1(v, OP_Close, iCur); +} + + +/* +** Return an Expr object that refers to a memory register corresponding +** to column iCol of table pTab. +** +** regBase is the first of an array of register that contains the data +** for pTab. regBase itself holds the rowid. regBase+1 holds the first +** column. regBase+2 holds the second column, and so forth. +*/ +static Expr *exprTableRegister( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* The table whose content is at r[regBase]... */ + int regBase, /* Contents of table pTab */ + i16 iCol /* Which column of pTab is desired */ +){ + Expr *pExpr; + Column *pCol; + const char *zColl; + sqlite3 *db = pParse->db; + + pExpr = sqlite3Expr(db, TK_REGISTER, 0); + if( pExpr ){ + if( iCol>=0 && iCol!=pTab->iPKey ){ + pCol = &pTab->aCol[iCol]; + pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; + pExpr->affExpr = pCol->affinity; + zColl = sqlite3ColumnColl(pCol); + if( zColl==0 ) zColl = db->pDfltColl->zName; + pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); + }else{ + pExpr->iTable = regBase; + pExpr->affExpr = SQLITE_AFF_INTEGER; + } + } + return pExpr; +} + +/* +** Return an Expr object that refers to column iCol of table pTab which +** has cursor iCur. +*/ +static Expr *exprTableColumn( + sqlite3 *db, /* The database connection */ + Table *pTab, /* The table whose column is desired */ + int iCursor, /* The open cursor on the table */ + i16 iCol /* The column that is wanted */ +){ + Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); + if( pExpr ){ + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pTab; + pExpr->iTable = iCursor; + pExpr->iColumn = iCol; + } + return pExpr; +} + +/* +** This function is called to generate code executed when a row is deleted +** from the parent table of foreign key constraint pFKey and, if pFKey is +** deferred, when a row is inserted into the same table. When generating +** code for an SQL UPDATE operation, this function may be called twice - +** once to "delete" the old row and once to "insert" the new row. +** +** Parameter nIncr is passed -1 when inserting a row (as this may decrease +** the number of FK violations in the db) or +1 when deleting one (as this +** may increase the number of FK constraint problems). +** +** The code generated by this function scans through the rows in the child +** table that correspond to the parent table row being deleted or inserted. +** For each child row found, one of the following actions is taken: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** DELETE immediate Increment the "immediate constraint counter". +** +** INSERT immediate Decrement the "immediate constraint counter". +** +** DELETE deferred Increment the "deferred constraint counter". +** +** INSERT deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.2" and "D.2". +*/ +static void fkScanChildren( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* The child table to be scanned */ + Table *pTab, /* The parent table */ + Index *pIdx, /* Index on parent covering the foreign key */ + FKey *pFKey, /* The foreign key linking pSrc to pTab */ + int *aiCol, /* Map from pIdx cols to child table cols */ + int regData, /* Parent row data starts here */ + int nIncr /* Amount to increment deferred counter by */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int i; /* Iterator variable */ + Expr *pWhere = 0; /* WHERE clause to scan with */ + NameContext sNameContext; /* Context used to resolve WHERE clause */ + WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ + int iFkIfZero = 0; /* Address of OP_FkIfZero */ + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( pIdx==0 || pIdx->pTable==pTab ); + assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); + assert( pIdx!=0 || pFKey->nCol==1 ); + assert( pIdx!=0 || HasRowid(pTab) ); + + if( nIncr<0 ){ + iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + VdbeCoverage(v); + } + + /* Create an Expr object representing an SQL expression like: + ** + ** = AND = ... + ** + ** The collation sequence used for the comparison should be that of + ** the parent key columns. The affinity of the parent key column should + ** be applied to each child key value before the comparison takes place. + */ + for(i=0; inCol; i++){ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + Expr *pEq; /* Expression (pLeft = pRight) */ + i16 iCol; /* Index of column in child table */ + const char *zCol; /* Name of column in child table */ + + iCol = pIdx ? pIdx->aiColumn[i] : -1; + pLeft = exprTableRegister(pParse, pTab, regData, iCol); + iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iCol>=0 ); + zCol = pFKey->pFrom->aCol[iCol].zCnName; + pRight = sqlite3Expr(db, TK_ID, zCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); + } + + /* If the child table is the same as the parent table, then add terms + ** to the WHERE clause that prevent this entry from being scanned. + ** The added WHERE clause terms are like this: + ** + ** $current_rowid!=rowid + ** NOT( $current_a==a AND $current_b==b AND ... ) + ** + ** The first form is used for rowid tables. The second form is used + ** for WITHOUT ROWID tables. In the second form, the *parent* key is + ** (a,b,...). Either the parent or primary key could be used to + ** uniquely identify the current row, but the parent key is more convenient + ** as the required values have already been loaded into registers + ** by the caller. + */ + if( pTab==pFKey->pFrom && nIncr>0 ){ + Expr *pNe; /* Expression (pLeft != pRight) */ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + if( HasRowid(pTab) ){ + pLeft = exprTableRegister(pParse, pTab, regData, -1); + pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); + pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); + }else{ + Expr *pEq, *pAll = 0; + assert( pIdx!=0 ); + for(i=0; inKeyCol; i++){ + i16 iCol = pIdx->aiColumn[i]; + assert( iCol>=0 ); + pLeft = exprTableRegister(pParse, pTab, regData, iCol); + pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zCnName); + pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); + pAll = sqlite3ExprAnd(pParse, pAll, pEq); + } + pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); + } + pWhere = sqlite3ExprAnd(pParse, pWhere, pNe); + } + + /* Resolve the references in the WHERE clause. */ + memset(&sNameContext, 0, sizeof(NameContext)); + sNameContext.pSrcList = pSrc; + sNameContext.pParse = pParse; + sqlite3ResolveExprNames(&sNameContext, pWhere); + + /* Create VDBE to loop through the entries in pSrc that match the WHERE + ** clause. For each row found, increment either the deferred or immediate + ** foreign key constraint counter. */ + if( pParse->nErr==0 ){ + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0); + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + if( pWInfo ){ + sqlite3WhereEnd(pWInfo); + } + } + + /* Clean up the WHERE clause constructed above. */ + sqlite3ExprDelete(db, pWhere); + if( iFkIfZero ){ + sqlite3VdbeJumpHereOrPopInst(v, iFkIfZero); + } +} + +/* +** This function returns a linked list of FKey objects (connected by +** FKey.pNextTo) holding all children of table pTab. For example, +** given the following schema: +** +** CREATE TABLE t1(a PRIMARY KEY); +** CREATE TABLE t2(b REFERENCES t1(a); +** +** Calling this function with table "t1" as an argument returns a pointer +** to the FKey structure representing the foreign key constraint on table +** "t2". Calling this function with "t2" as the argument would return a +** NULL pointer (as there are no FK constraints for which t2 is the parent +** table). +*/ +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); +} + +/* +** The second argument is a Trigger structure allocated by the +** fkActionTrigger() routine. This function deletes the Trigger structure +** and all of its sub-components. +** +** The Trigger structure or any of its sub-components may be allocated from +** the lookaside buffer belonging to database handle dbMem. +*/ +static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ + if( p ){ + TriggerStep *pStep = p->step_list; + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); + sqlite3ExprDelete(dbMem, p->pWhen); + sqlite3DbFree(dbMem, p); + } +} + +/* +** Clear the apTrigger[] cache of CASCADE triggers for all foreign keys +** in a particular database. This needs to happen when the schema +** changes. +*/ +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){ + HashElem *k; + Hash *pHash = &db->aDb[iDb].pSchema->tblHash; + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k)){ + Table *pTab = sqliteHashData(k); + FKey *pFKey; + if( !IsOrdinaryTable(pTab) ) continue; + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + fkTriggerDelete(db, pFKey->apTrigger[0]); pFKey->apTrigger[0] = 0; + fkTriggerDelete(db, pFKey->apTrigger[1]); pFKey->apTrigger[1] = 0; + } + } +} + +/* +** This function is called to generate code that runs when table pTab is +** being dropped from the database. The SrcList passed as the second argument +** to this function contains a single entry guaranteed to resolve to +** table pTab. +** +** Normally, no code is required. However, if either +** +** (a) The table is the parent table of a FK constraint, or +** (b) The table is the child table of a deferred FK constraint and it is +** determined at runtime that there are outstanding deferred FK +** constraint violations in the database, +** +** then the equivalent of "DELETE FROM " is executed before dropping +** the table from the database. Triggers are disabled while running this +** DELETE, but foreign key actions are not. +*/ +SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ + sqlite3 *db = pParse->db; + if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){ + int iSkip = 0; + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( v ); /* VDBE has already been allocated */ + assert( IsOrdinaryTable(pTab) ); + if( sqlite3FkReferences(pTab)==0 ){ + /* Search for a deferred foreign key constraint for which this table + ** is the child table. If one cannot be found, return without + ** generating any VDBE code. If one can be found, then jump over + ** the entire DELETE if there are no outstanding deferred constraints + ** when this statement is run. */ + FKey *p; + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ + if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; + } + if( !p ) return; + iSkip = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); + } + + pParse->disableTriggers = 1; + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); + pParse->disableTriggers = 0; + + /* If the DELETE has generated immediate foreign key constraint + ** violations, halt the VDBE and return an error at this point, before + ** any modifications to the schema are made. This is because statement + ** transactions are not able to rollback schema changes. + ** + ** If the SQLITE_DeferFKs flag is set, then this is not required, as + ** the statement transaction will not be rolled back even if FK + ** constraints are violated. + */ + if( (db->flags & SQLITE_DeferFKs)==0 ){ + sqlite3VdbeVerifyAbortable(v, OE_Abort); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, 0, P4_STATIC, P5_ConstraintFK); + } + + if( iSkip ){ + sqlite3VdbeResolveLabel(v, iSkip); + } + } +} + + +/* +** The second argument points to an FKey object representing a foreign key +** for which pTab is the child table. An UPDATE statement against pTab +** is currently being processed. For each column of the table that is +** actually updated, the corresponding element in the aChange[] array +** is zero or greater (if a column is unmodified the corresponding element +** is set to -1). If the rowid column is modified by the UPDATE statement +** the bChngRowid argument is non-zero. +** +** This function returns true if any of the columns that are part of the +** child key for FK constraint *p are modified. +*/ +static int fkChildIsModified( + Table *pTab, /* Table being updated */ + FKey *p, /* Foreign key for which pTab is the child */ + int *aChange, /* Array indicating modified columns */ + int bChngRowid /* True if rowid is modified by this update */ +){ + int i; + for(i=0; inCol; i++){ + int iChildKey = p->aCol[i].iFrom; + if( aChange[iChildKey]>=0 ) return 1; + if( iChildKey==pTab->iPKey && bChngRowid ) return 1; + } + return 0; +} + +/* +** The second argument points to an FKey object representing a foreign key +** for which pTab is the parent table. An UPDATE statement against pTab +** is currently being processed. For each column of the table that is +** actually updated, the corresponding element in the aChange[] array +** is zero or greater (if a column is unmodified the corresponding element +** is set to -1). If the rowid column is modified by the UPDATE statement +** the bChngRowid argument is non-zero. +** +** This function returns true if any of the columns that are part of the +** parent key for FK constraint *p are modified. +*/ +static int fkParentIsModified( + Table *pTab, + FKey *p, + int *aChange, + int bChngRowid +){ + int i; + for(i=0; inCol; i++){ + char *zKey = p->aCol[i].zCol; + int iKey; + for(iKey=0; iKeynCol; iKey++){ + if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ + Column *pCol = &pTab->aCol[iKey]; + if( zKey ){ + if( 0==sqlite3StrICmp(pCol->zCnName, zKey) ) return 1; + }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ + return 1; + } + } + } + } + return 0; +} + +/* +** Return true if the parser passed as the first argument is being +** used to code a trigger that is really a "SET NULL" action belonging +** to trigger pFKey. +*/ +static int isSetNullAction(Parse *pParse, FKey *pFKey){ + Parse *pTop = sqlite3ParseToplevel(pParse); + if( pTop->pTriggerPrg ){ + Trigger *p = pTop->pTriggerPrg->pTrigger; + if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) + || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) + ){ + assert( (pTop->db->flags & SQLITE_FkNoAction)==0 ); + return 1; + } + } + return 0; +} + +/* +** This function is called when inserting, deleting or updating a row of +** table pTab to generate VDBE code to perform foreign key constraint +** processing for the operation. +** +** For a DELETE operation, parameter regOld is passed the index of the +** first register in an array of (pTab->nCol+1) registers containing the +** rowid of the row being deleted, followed by each of the column values +** of the row being deleted, from left to right. Parameter regNew is passed +** zero in this case. +** +** For an INSERT operation, regOld is passed zero and regNew is passed the +** first register of an array of (pTab->nCol+1) registers containing the new +** row data. +** +** For an UPDATE operation, this function is called twice. Once before +** the original record is deleted from the table using the calling convention +** described for DELETE. Then again after the original record is deleted +** but before the new record is inserted using the INSERT convention. +*/ +SQLITE_PRIVATE void sqlite3FkCheck( + Parse *pParse, /* Parse context */ + Table *pTab, /* Row is being deleted from this table */ + int regOld, /* Previous row data is stored here */ + int regNew, /* New row data is stored here */ + int *aChange, /* Array indicating UPDATEd columns (or 0) */ + int bChngRowid /* True if rowid is UPDATEd */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + FKey *pFKey; /* Used to iterate through FKs */ + int iDb; /* Index of database containing pTab */ + const char *zDb; /* Name of database containing pTab */ + int isIgnoreErrors = pParse->disableTriggers; + + /* Exactly one of regOld and regNew should be non-zero. */ + assert( (regOld==0)!=(regNew==0) ); + + /* If foreign-keys are disabled, this function is a no-op. */ + if( (db->flags&SQLITE_ForeignKeys)==0 ) return; + if( !IsOrdinaryTable(pTab) ) return; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zDb = db->aDb[iDb].zDbSName; + + /* Loop through all the foreign key constraints for which pTab is the + ** child table (the table that the foreign key definition is part of). */ + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + Table *pTo; /* Parent table of foreign key pFKey */ + Index *pIdx = 0; /* Index on key columns in pTo */ + int *aiFree = 0; + int *aiCol; + int iCol; + int i; + int bIgnore = 0; + + if( aChange + && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 + && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 + ){ + continue; + } + + /* Find the parent table of this foreign key. Also find a unique index + ** on the parent key columns in the parent table. If either of these + ** schema items cannot be located, set an error in pParse and return + ** early. */ + if( pParse->disableTriggers ){ + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + }else{ + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + } + if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); + if( !isIgnoreErrors || db->mallocFailed ) return; + if( pTo==0 ){ + /* If isIgnoreErrors is true, then a table is being dropped. In this + ** case SQLite runs a "DELETE FROM xxx" on the table being dropped + ** before actually dropping it in order to check FK constraints. + ** If the parent table of an FK constraint on the current table is + ** missing, behave as if it is empty. i.e. decrement the relevant + ** FK counter for each row of the current table with non-NULL keys. + */ + Vdbe *v = sqlite3GetVdbe(pParse); + int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; + for(i=0; inCol; i++){ + int iFromCol, iReg; + iFromCol = pFKey->aCol[i].iFrom; + iReg = sqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); + } + continue; + } + assert( pFKey->nCol==1 || (aiFree && pIdx) ); + + if( aiFree ){ + aiCol = aiFree; + }else{ + iCol = pFKey->aCol[0].iFrom; + aiCol = &iCol; + } + for(i=0; inCol; i++){ + if( aiCol[i]==pTab->iPKey ){ + aiCol[i] = -1; + } + assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Request permission to read the parent key columns. If the + ** authorization callback returns SQLITE_IGNORE, behave as if any + ** values read from the parent table are NULL. */ + if( db->xAuth ){ + int rcauth; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zCnName; + rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); + bIgnore = (rcauth==SQLITE_IGNORE); + } +#endif + } + + /* Take a shared-cache advisory read-lock on the parent table. Allocate + ** a cursor to use to search the unique index on the parent key columns + ** in the parent table. */ + sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); + pParse->nTab++; + + if( regOld!=0 ){ + /* A row is being removed from the child table. Search for the parent. + ** If the parent does not exist, removing the child row resolves an + ** outstanding foreign key constraint violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore); + } + if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){ + /* A row is being added to the child table. If a parent row cannot + ** be found, adding the child row has violated the FK constraint. + ** + ** If this operation is being performed as part of a trigger program + ** that is actually a "SET NULL" action belonging to this very + ** foreign key, then omit this scan altogether. As all child key + ** values are guaranteed to be NULL, it is not possible for adding + ** this row to cause an FK violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore); + } + + sqlite3DbFree(db, aiFree); + } + + /* Loop through all the foreign key constraints that refer to this table. + ** (the "child" constraints) */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Index *pIdx = 0; /* Foreign key index for pFKey */ + SrcList *pSrc; + int *aiCol = 0; + + if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ + continue; + } + + if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel && !pParse->isMultiWrite + ){ + assert( regOld==0 && regNew!=0 ); + /* Inserting a single row into a parent table cannot cause (or fix) + ** an immediate foreign key violation. So do nothing in this case. */ + continue; + } + + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } + assert( aiCol || pFKey->nCol==1 ); + + /* Create a SrcList structure containing the child table. We need the + ** child table as a SrcList for sqlite3WhereBegin() */ + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc ){ + SrcItem *pItem = pSrc->a; + pItem->pTab = pFKey->pFrom; + pItem->zName = pFKey->pFrom->zName; + pItem->pTab->nTabRef++; + pItem->iCursor = pParse->nTab++; + + if( regNew!=0 ){ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); + } + if( regOld!=0 ){ + int eAction = pFKey->aAction[aChange!=0]; + if( (db->flags & SQLITE_FkNoAction) ) eAction = OE_None; + + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); + /* If this is a deferred FK constraint, or a CASCADE or SET NULL + ** action applies, then any foreign key violations caused by + ** removing the parent key will be rectified by the action trigger. + ** So do not set the "may-abort" flag in this case. + ** + ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the + ** may-abort flag will eventually be set on this statement anyway + ** (when this function is called as part of processing the UPDATE + ** within the action trigger). + ** + ** Note 2: At first glance it may seem like SQLite could simply omit + ** all OP_FkCounter related scans when either CASCADE or SET NULL + ** applies. The trouble starts if the CASCADE or SET NULL action + ** trigger causes other triggers or action rules attached to the + ** child table to fire. In these cases the fk constraint counters + ** might be set incorrectly if any OP_FkCounter related scans are + ** omitted. */ + if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){ + sqlite3MayAbort(pParse); + } + } + pItem->zName = 0; + sqlite3SrcListDelete(db, pSrc); + } + sqlite3DbFree(db, aiCol); + } +} + +#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. +*/ +SQLITE_PRIVATE u32 sqlite3FkOldmask( + Parse *pParse, /* Parse context */ + Table *pTab /* Table being modified */ +){ + u32 mask = 0; + if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){ + FKey *p; + int i; + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); + } + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Index *pIdx = 0; + sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); + if( pIdx ){ + for(i=0; inKeyCol; i++){ + assert( pIdx->aiColumn[i]>=0 ); + mask |= COLUMN_MASK(pIdx->aiColumn[i]); + } + } + } + } + return mask; +} + + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. If the operation is a DELETE, then +** parameter aChange is passed a NULL value. For an UPDATE, aChange points +** to an array of size N, where N is the number of columns in table pTab. +** If the i'th column is not modified by the UPDATE, then the corresponding +** entry in the aChange[] array is set to -1. If the column is modified, +** the value is 0 or greater. Parameter chngRowid is set to true if the +** UPDATE statement modifies the rowid fields of the table. +** +** If any foreign key processing will be required, this function returns +** non-zero. If there is no foreign key related processing, this function +** returns zero. +** +** For an UPDATE, this function returns 2 if: +** +** * There are any FKs for which pTab is the child and the parent table +** and any FK processing at all is required (even of a different FK), or +** +** * the UPDATE modifies one or more parent keys for which the action is +** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL). +** +** Or, assuming some other foreign key processing is required, 1. +*/ +SQLITE_PRIVATE int sqlite3FkRequired( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being modified */ + int *aChange, /* Non-NULL for UPDATE operations */ + int chngRowid /* True for UPDATE that affects rowid */ +){ + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ + if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){ + if( !aChange ){ + /* A DELETE operation. Foreign key processing is required if the + ** table in question is either the child or parent table for any + ** foreign key constraint. */ + bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey); + }else{ + /* This is an UPDATE. Foreign key processing is only required if the + ** operation modifies one or more child or parent key columns. */ + FKey *p; + + /* Check if any child key columns are being modified. */ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ + if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; + } + } + + /* Check if any parent key columns are being modified. */ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ + if( (pParse->db->flags & SQLITE_FkNoAction)==0 + && p->aAction[1]!=OE_None + ){ + return 2; + } + bHaveFK = 1; + } + } + } + } + return bHaveFK ? eRet : 0; +} + +/* +** This function is called when an UPDATE or DELETE operation is being +** compiled on table pTab, which is the parent table of foreign-key pFKey. +** If the current operation is an UPDATE, then the pChanges parameter is +** passed a pointer to the list of columns being modified. If it is a +** DELETE, pChanges is passed a NULL pointer. +** +** It returns a pointer to a Trigger structure containing a trigger +** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. +** If the action is "NO ACTION" then a NULL pointer is returned (these actions +** require no special handling by the triggers sub-system, code for them is +** created by fkScanChildren()). +** +** For example, if pFKey is the foreign key and pTab is table "p" in +** the following schema: +** +** CREATE TABLE p(pk PRIMARY KEY); +** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE); +** +** then the returned trigger structure is equivalent to: +** +** CREATE TRIGGER ... DELETE ON p BEGIN +** DELETE FROM c WHERE ck = old.pk; +** END; +** +** The returned pointer is cached as part of the foreign key object. It +** is eventually freed along with the rest of the foreign key object by +** sqlite3FkDelete(). +*/ +static Trigger *fkActionTrigger( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + FKey *pFKey, /* Foreign key to get action for */ + ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int action; /* One of OE_None, OE_Cascade etc. */ + Trigger *pTrigger; /* Trigger definition to return */ + int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ + + action = pFKey->aAction[iAction]; + if( (db->flags & SQLITE_FkNoAction) ) action = OE_None; + if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ + return 0; + } + pTrigger = pFKey->apTrigger[iAction]; + + if( action!=OE_None && !pTrigger ){ + char const *zFrom; /* Name of child table */ + int nFrom; /* Length in bytes of zFrom */ + Index *pIdx = 0; /* Parent key index for this FK */ + int *aiCol = 0; /* child table cols -> parent key cols */ + TriggerStep *pStep = 0; /* First (only) step of trigger program */ + Expr *pWhere = 0; /* WHERE clause of trigger step */ + ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ + Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ + int i; /* Iterator variable */ + Expr *pWhen = 0; /* WHEN clause for the trigger */ + + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; + assert( aiCol || pFKey->nCol==1 ); + + for(i=0; inCol; i++){ + Token tOld = { "old", 3 }; /* Literal "old" token */ + Token tNew = { "new", 3 }; /* Literal "new" token */ + Token tFromCol; /* Name of column in child table */ + Token tToCol; /* Name of column in parent table */ + int iFromCol; /* Idx of column in child table */ + Expr *pEq; /* tFromCol = OLD.tToCol */ + + iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iFromCol>=0 ); + assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); + assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); + sqlite3TokenInit(&tToCol, + pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zCnName); + sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zCnName); + + /* Create the expression "OLD.zToCol = zFromCol". It is important + ** that the "OLD.zToCol" term is on the LHS of the = operator, so + ** that the affinity and collation sequence associated with the + ** parent table are used for the comparison. */ + pEq = sqlite3PExpr(pParse, TK_EQ, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), + sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) + ); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); + + /* For ON UPDATE, construct the next term of the WHEN clause. + ** The final WHEN clause will be like this: + ** + ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) + */ + if( pChanges ){ + pEq = sqlite3PExpr(pParse, TK_IS, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) + ); + pWhen = sqlite3ExprAnd(pParse, pWhen, pEq); + } + + if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ + Expr *pNew; + if( action==OE_Cascade ){ + pNew = sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); + }else if( action==OE_SetDflt ){ + Column *pCol = pFKey->pFrom->aCol + iFromCol; + Expr *pDflt; + if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + pDflt = 0; + }else{ + pDflt = sqlite3ColumnExpr(pFKey->pFrom, pCol); + } + if( pDflt ){ + pNew = sqlite3ExprDup(db, pDflt, 0); + }else{ + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + } + }else{ + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + } + pList = sqlite3ExprListAppend(pParse, pList, pNew); + sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); + } + } + sqlite3DbFree(db, aiCol); + + zFrom = pFKey->pFrom->zName; + nFrom = sqlite3Strlen30(zFrom); + + if( action==OE_Restrict ){ + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + SrcList *pSrc; + Expr *pRaise; + + pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + if( pRaise ){ + pRaise->affExpr = OE_Abort; + } + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc ){ + assert( pSrc->nSrc==1 ); + pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); + pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + } + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), + pSrc, + pWhere, + 0, 0, 0, 0, 0 + ); + pWhere = 0; + } + + /* Disable lookaside memory allocation */ + DisableLookaside; + + pTrigger = (Trigger *)sqlite3DbMallocZero(db, + sizeof(Trigger) + /* struct Trigger */ + sizeof(TriggerStep) + /* Single step in trigger program */ + nFrom + 1 /* Space for pStep->zTarget */ + ); + if( pTrigger ){ + pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; + pStep->zTarget = (char *)&pStep[1]; + memcpy((char *)pStep->zTarget, zFrom, nFrom); + + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( pWhen ){ + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + } + + /* Re-enable the lookaside buffer, if it was disabled earlier. */ + EnableLookaside; + + sqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhen); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed==1 ){ + fkTriggerDelete(db, pTrigger); + return 0; + } + assert( pStep!=0 ); + assert( pTrigger!=0 ); + + switch( action ){ + case OE_Restrict: + pStep->op = TK_SELECT; + break; + case OE_Cascade: + if( !pChanges ){ + pStep->op = TK_DELETE; + break; + } + /* no break */ deliberate_fall_through + default: + pStep->op = TK_UPDATE; + } + pStep->pTrig = pTrigger; + pTrigger->pSchema = pTab->pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pFKey->apTrigger[iAction] = pTrigger; + pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE); + } + + return pTrigger; +} + +/* +** This function is called when deleting or updating a row to implement +** any required CASCADE, SET NULL or SET DEFAULT actions. +*/ +SQLITE_PRIVATE void sqlite3FkActions( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ + int regOld, /* Address of array containing old row */ + int *aChange, /* Array indicating UPDATEd columns (or 0) */ + int bChngRowid /* True if rowid is UPDATEd */ +){ + /* If foreign-key support is enabled, iterate through all FKs that + ** refer to table pTab. If there is an action associated with the FK + ** for this operation (either update or delete), invoke the associated + ** trigger sub-program. */ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *pFKey; /* Iterator variable */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){ + Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges); + if( pAct ){ + sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); + } + } + } + } +} + +#endif /* ifndef SQLITE_OMIT_TRIGGER */ + +/* +** Free all memory associated with foreign key definitions attached to +** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash +** hash table. +*/ +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ + FKey *pFKey; /* Iterator variable */ + FKey *pNext; /* Copy of pFKey->pNextFrom */ + + assert( IsOrdinaryTable(pTab) ); + assert( db!=0 ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + + /* Remove the FK from the fkeyHash hash table. */ + if( db->pnBytesFreed==0 ){ + if( pFKey->pPrevTo ){ + pFKey->pPrevTo->pNextTo = pFKey->pNextTo; + }else{ + const char *z = (pFKey->pNextTo ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, pFKey->pNextTo); + } + if( pFKey->pNextTo ){ + pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + } + } + + /* EV: R-30323-21917 Each foreign key constraint in SQLite is + ** classified as either immediate or deferred. + */ + assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); + + /* Delete any triggers created to implement actions for this FK. */ +#ifndef SQLITE_OMIT_TRIGGER + fkTriggerDelete(db, pFKey->apTrigger[0]); + fkTriggerDelete(db, pFKey->apTrigger[1]); +#endif + + pNext = pFKey->pNextFrom; + sqlite3DbFree(db, pFKey); + } +} +#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ + +/************** End of fkey.c ************************************************/ +/************** Begin file insert.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle INSERT statements in SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* +** Generate code that will +** +** (1) acquire a lock for table pTab then +** (2) open pTab as cursor iCur. +** +** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index +** for that table that is actually opened. +*/ +SQLITE_PRIVATE void sqlite3OpenTable( + Parse *pParse, /* Generate code into this VDBE */ + int iCur, /* The cursor number of the table */ + int iDb, /* The database index in sqlite3.aDb[] */ + Table *pTab, /* The table to be opened */ + int opcode /* OP_OpenRead or OP_OpenWrite */ +){ + Vdbe *v; + assert( !IsVirtual(pTab) ); + assert( pParse->pVdbe!=0 ); + v = pParse->pVdbe; + assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); + if( !pParse->db->noSharedCache ){ + sqlite3TableLock(pParse, iDb, pTab->tnum, + (opcode==OP_OpenWrite)?1:0, pTab->zName); + } + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); + VdbeComment((v, "%s", pTab->zName)); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->tnum==pTab->tnum || CORRUPT_DB ); + sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + VdbeComment((v, "%s", pTab->zName)); + } +} + +/* +** Return a pointer to the column affinity string associated with index +** pIdx. A column affinity string has one character for each column in +** the table, according to the affinity of the column: +** +** Character Column affinity +** ------------------------------ +** 'A' BLOB +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'F' REAL +** +** An extra 'D' is appended to the end of the string to cover the +** rowid that appears as the last column in every index. +** +** Memory for the buffer containing the column index affinity string +** is managed along with the rest of the Index structure. It will be +** released when sqlite3DeleteIndex() is called. +*/ +static SQLITE_NOINLINE const char *computeIndexAffStr(sqlite3 *db, Index *pIdx){ + /* The first time a column affinity string for a particular index is + ** required, it is allocated and populated here. It is then stored as + ** a member of the Index structure for subsequent use. + ** + ** The column affinity string will eventually be deleted by + ** sqliteDeleteIndex() when the Index structure itself is cleaned + ** up. + */ + int n; + Table *pTab = pIdx->pTable; + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); + if( !pIdx->zColAff ){ + sqlite3OomFault(db); + return 0; + } + for(n=0; nnColumn; n++){ + i16 x = pIdx->aiColumn[n]; + char aff; + if( x>=0 ){ + aff = pTab->aCol[x].affinity; + }else if( x==XN_ROWID ){ + aff = SQLITE_AFF_INTEGER; + }else{ + assert( x==XN_EXPR ); + assert( pIdx->bHasExpr ); + assert( pIdx->aColExpr!=0 ); + aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + } + if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; + pIdx->zColAff[n] = aff; + } + pIdx->zColAff[n] = 0; + return pIdx->zColAff; +} +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ + if( !pIdx->zColAff ) return computeIndexAffStr(db, pIdx); + return pIdx->zColAff; +} + + +/* +** Compute an affinity string for a table. Space is obtained +** from sqlite3DbMalloc(). The caller is responsible for freeing +** the space when done. +*/ +SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){ + char *zColAff; + zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1); + if( zColAff ){ + int i, j; + for(i=j=0; inCol; i++){ + if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + zColAff[j++] = pTab->aCol[i].affinity; + } + } + do{ + zColAff[j--] = 0; + }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); + } + return zColAff; +} + +/* +** Make changes to the evolving bytecode to do affinity transformations +** of values that are about to be gathered into a row for table pTab. +** +** For ordinary (legacy, non-strict) tables: +** ----------------------------------------- +** +** Compute the affinity string for table pTab, if it has not already been +** computed. As an optimization, omit trailing SQLITE_AFF_BLOB affinities. +** +** If the affinity string is empty (because it was all SQLITE_AFF_BLOB entries +** which were then optimized out) then this routine becomes a no-op. +** +** Otherwise if iReg>0 then code an OP_Affinity opcode that will set the +** affinities for register iReg and following. Or if iReg==0, +** then just set the P4 operand of the previous opcode (which should be +** an OP_MakeRecord) to the affinity string. +** +** A column affinity string has one character per column: +** +** Character Column affinity +** --------- --------------- +** 'A' BLOB +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'E' REAL +** +** For STRICT tables: +** ------------------ +** +** Generate an appropriate OP_TypeCheck opcode that will verify the +** datatypes against the column definitions in pTab. If iReg==0, that +** means an OP_MakeRecord opcode has already been generated and should be +** the last opcode generated. The new OP_TypeCheck needs to be inserted +** before the OP_MakeRecord. The new OP_TypeCheck should use the same +** register set as the OP_MakeRecord. If iReg>0 then register iReg is +** the first of a series of registers that will form the new record. +** Apply the type checking to that array of registers. +*/ +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ + int i; + char *zColAff; + if( pTab->tabFlags & TF_Strict ){ + if( iReg==0 ){ + /* Move the previous opcode (which should be OP_MakeRecord) forward + ** by one slot and insert a new OP_TypeCheck where the current + ** OP_MakeRecord is found */ + VdbeOp *pPrev; + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + pPrev = sqlite3VdbeGetLastOp(v); + assert( pPrev!=0 ); + assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); + pPrev->opcode = OP_TypeCheck; + sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); + }else{ + /* Insert an isolated OP_Typecheck */ + sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } + return; + } + zColAff = pTab->zColAff; + if( zColAff==0 ){ + zColAff = sqlite3TableAffinityStr(0, pTab); + if( !zColAff ){ + sqlite3OomFault(sqlite3VdbeDb(v)); + return; + } + pTab->zColAff = zColAff; + } + assert( zColAff!=0 ); + i = sqlite3Strlen30NN(zColAff); + if( i ){ + if( iReg ){ + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); + }else{ + assert( sqlite3VdbeGetLastOp(v)->opcode==OP_MakeRecord + || sqlite3VdbeDb(v)->mallocFailed ); + sqlite3VdbeChangeP4(v, -1, zColAff, i); + } + } +} + +/* +** Return non-zero if the table pTab in database iDb or any of its indices +** have been opened at any point in the VDBE program. This is used to see if +** a statement of the form "INSERT INTO SELECT ..." can +** run without using a temporary table for the results of the SELECT. +*/ +static int readsTable(Parse *p, int iDb, Table *pTab){ + Vdbe *v = sqlite3GetVdbe(p); + int i; + int iEnd = sqlite3VdbeCurrentAddr(v); +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; +#endif + + for(i=1; iopcode==OP_OpenRead && pOp->p3==iDb ){ + Index *pIndex; + Pgno tnum = pOp->p2; + if( tnum==pTab->tnum ){ + return 1; + } + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( tnum==pIndex->tnum ){ + return 1; + } + } + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){ + assert( pOp->p4.pVtab!=0 ); + assert( pOp->p4type==P4_VTAB ); + return 1; + } +#endif + } + return 0; +} + +/* This walker callback will compute the union of colFlags flags for all +** referenced columns in a CHECK constraint or generated column expression. +*/ +static int exprColumnFlagUnion(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 ){ + assert( pExpr->iColumn < pWalker->u.pTab->nCol ); + pWalker->eCode |= pWalker->u.pTab->aCol[pExpr->iColumn].colFlags; + } + return WRC_Continue; +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* +** All regular columns for table pTab have been puts into registers +** starting with iRegStore. The registers that correspond to STORED +** or VIRTUAL columns have not yet been initialized. This routine goes +** back and computes the values for those columns based on the previously +** computed normal columns. +*/ +SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( + Parse *pParse, /* Parsing context */ + int iRegStore, /* Register holding the first column */ + Table *pTab /* The table */ +){ + int i; + Walker w; + Column *pRedo; + int eProgress; + VdbeOp *pOp; + + assert( pTab->tabFlags & TF_HasGenerated ); + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + + /* Before computing generated columns, first go through and make sure + ** that appropriate affinity has been applied to the regular columns + */ + sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); + if( (pTab->tabFlags & TF_HasStored)!=0 ){ + pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + if( pOp->opcode==OP_Affinity ){ + /* Change the OP_Affinity argument to '@' (NONE) for all stored + ** columns. '@' is the no-op affinity and those columns have not + ** yet been computed. */ + int ii, jj; + char *zP4 = pOp->p4.z; + assert( zP4!=0 ); + assert( pOp->p4type==P4_DYNAMIC ); + for(ii=jj=0; zP4[jj]; ii++){ + if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){ + continue; + } + if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){ + zP4[jj] = SQLITE_AFF_NONE; + } + jj++; + } + }else if( pOp->opcode==OP_TypeCheck ){ + /* If an OP_TypeCheck was generated because the table is STRICT, + ** then set the P3 operand to indicate that generated columns should + ** not be checked */ + pOp->p3 = 1; + } + } + + /* Because there can be multiple generated columns that refer to one another, + ** this is a two-pass algorithm. On the first pass, mark all generated + ** columns as "not available". + */ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); + pTab->aCol[i].colFlags |= COLFLAG_NOTAVAIL; + } + } + + w.u.pTab = pTab; + w.xExprCallback = exprColumnFlagUnion; + w.xSelectCallback = 0; + w.xSelectCallback2 = 0; + + /* On the second pass, compute the value of each NOT-AVAILABLE column. + ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will + ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as + ** they are needed. + */ + pParse->iSelfTab = -iRegStore; + do{ + eProgress = 0; + pRedo = 0; + for(i=0; inCol; i++){ + Column *pCol = pTab->aCol + i; + if( (pCol->colFlags & COLFLAG_NOTAVAIL)!=0 ){ + int x; + pCol->colFlags |= COLFLAG_BUSY; + w.eCode = 0; + sqlite3WalkExpr(&w, sqlite3ColumnExpr(pTab, pCol)); + pCol->colFlags &= ~COLFLAG_BUSY; + if( w.eCode & COLFLAG_NOTAVAIL ){ + pRedo = pCol; + continue; + } + eProgress = 1; + assert( pCol->colFlags & COLFLAG_GENERATED ); + x = sqlite3TableColumnToStorage(pTab, i) + iRegStore; + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, x); + pCol->colFlags &= ~COLFLAG_NOTAVAIL; + } + } + }while( pRedo && eProgress ); + if( pRedo ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zCnName); + } + pParse->iSelfTab = 0; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* +** Locate or create an AutoincInfo structure associated with table pTab +** which is in database iDb. Return the register number for the register +** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT +** table. (Also return zero when doing a VACUUM since we do not want to +** update the AUTOINCREMENT counters during a VACUUM.) +** +** There is at most one AutoincInfo structure per table even if the +** same table is autoincremented multiple times due to inserts within +** triggers. A new AutoincInfo structure is created if this is the +** first use of table pTab. On 2nd and subsequent uses, the original +** AutoincInfo structure is used. +** +** Four consecutive registers are allocated: +** +** (1) The name of the pTab table. +** (2) The maximum ROWID of pTab. +** (3) The rowid in sqlite_sequence of pTab +** (4) The original value of the max ROWID in pTab, or NULL if none +** +** The 2nd register is the one that is returned. That is all the +** insert routine needs to know about. +*/ +static int autoIncBegin( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database holding pTab */ + Table *pTab /* The table we are writing to */ +){ + int memId = 0; /* Register holding maximum rowid */ + assert( pParse->db->aDb[iDb].pSchema!=0 ); + if( (pTab->tabFlags & TF_Autoincrement)!=0 + && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0 + ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + AutoincInfo *pInfo; + Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab; + + /* Verify that the sqlite_sequence table exists and is an ordinary + ** rowid table with exactly two columns. + ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */ + if( pSeqTab==0 + || !HasRowid(pSeqTab) + || NEVER(IsVirtual(pSeqTab)) + || pSeqTab->nCol!=2 + ){ + pParse->nErr++; + pParse->rc = SQLITE_CORRUPT_SEQUENCE; + return 0; + } + + pInfo = pToplevel->pAinc; + while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } + if( pInfo==0 ){ + pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); + sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo); + testcase( pParse->earlyCleanup ); + if( pParse->db->mallocFailed ) return 0; + pInfo->pNext = pToplevel->pAinc; + pToplevel->pAinc = pInfo; + pInfo->pTab = pTab; + pInfo->iDb = iDb; + pToplevel->nMem++; /* Register to hold name of table */ + pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ + pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */ + } + memId = pInfo->regCtr; + } + return memId; +} + +/* +** This routine generates code that will initialize all of the +** register used by the autoincrement tracker. +*/ +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ + AutoincInfo *p; /* Information about an AUTOINCREMENT */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* Database only autoinc table */ + int memId; /* Register holding max rowid */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + + /* This routine is never called during trigger-generation. It is + ** only called from the top-level */ + assert( pParse->pTriggerTab==0 ); + assert( sqlite3IsToplevel(pParse) ); + + assert( v ); /* We failed long ago if this is not so */ + for(p = pParse->pAinc; p; p = p->pNext){ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList autoInc[] = { + /* 0 */ {OP_Null, 0, 0, 0}, + /* 1 */ {OP_Rewind, 0, 10, 0}, + /* 2 */ {OP_Column, 0, 0, 0}, + /* 3 */ {OP_Ne, 0, 9, 0}, + /* 4 */ {OP_Rowid, 0, 0, 0}, + /* 5 */ {OP_Column, 0, 1, 0}, + /* 6 */ {OP_AddImm, 0, 0, 0}, + /* 7 */ {OP_Copy, 0, 0, 0}, + /* 8 */ {OP_Goto, 0, 11, 0}, + /* 9 */ {OP_Next, 0, 2, 0}, + /* 10 */ {OP_Integer, 0, 0, 0}, + /* 11 */ {OP_Close, 0, 0, 0} + }; + VdbeOp *aOp; + pDb = &db->aDb[p->iDb]; + memId = p->regCtr; + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); + if( aOp==0 ) break; + aOp[0].p2 = memId; + aOp[0].p3 = memId+2; + aOp[2].p3 = memId; + aOp[3].p1 = memId-1; + aOp[3].p3 = memId; + aOp[3].p5 = SQLITE_JUMPIFNULL; + aOp[4].p2 = memId+1; + aOp[5].p3 = memId; + aOp[6].p1 = memId; + aOp[7].p2 = memId+2; + aOp[7].p1 = memId; + aOp[10].p2 = memId; + if( pParse->nTab==0 ) pParse->nTab = 1; + } +} + +/* +** Update the maximum rowid for an autoincrement calculation. +** +** This routine should be called when the regRowid register holds a +** new rowid that is about to be inserted. If that new rowid is +** larger than the maximum rowid in the memId memory cell, then the +** memory cell is updated. +*/ +static void autoIncStep(Parse *pParse, int memId, int regRowid){ + if( memId>0 ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); + } +} + +/* +** This routine generates the code needed to write autoincrement +** maximum rowid values back into the sqlite_sequence register. +** Every statement that might do an INSERT into an autoincrement +** table (either directly or through triggers) needs to call this +** routine just before the "exit" code. +*/ +static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ + AutoincInfo *p; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( v ); + for(p = pParse->pAinc; p; p = p->pNext){ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList autoIncEnd[] = { + /* 0 */ {OP_NotNull, 0, 2, 0}, + /* 1 */ {OP_NewRowid, 0, 0, 0}, + /* 2 */ {OP_MakeRecord, 0, 2, 0}, + /* 3 */ {OP_Insert, 0, 0, 0}, + /* 4 */ {OP_Close, 0, 0, 0} + }; + VdbeOp *aOp; + Db *pDb = &db->aDb[p->iDb]; + int iRec; + int memId = p->regCtr; + + iRec = sqlite3GetTempReg(pParse); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId); + VdbeCoverage(v); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); + if( aOp==0 ) break; + aOp[0].p1 = memId+1; + aOp[1].p2 = memId+1; + aOp[2].p1 = memId-1; + aOp[2].p3 = iRec; + aOp[3].p2 = iRec; + aOp[3].p3 = memId+1; + aOp[3].p5 = OPFLAG_APPEND; + sqlite3ReleaseTempReg(pParse, iRec); + } +} +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ + if( pParse->pAinc ) autoIncrementEnd(pParse); +} +#else +/* +** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines +** above are all no-ops +*/ +# define autoIncBegin(A,B,C) (0) +# define autoIncStep(A,B,C) +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + + +/* Forward declaration */ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +); + +/* +** This routine is called to handle SQL of the following forms: +** +** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... +** insert into TABLE (IDLIST) select +** insert into TABLE (IDLIST) default values +** +** The IDLIST following the table name is always optional. If omitted, +** then a list of all (non-hidden) columns for the table is substituted. +** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST +** is omitted. +** +** For the pSelect parameter holds the values to be inserted for the +** first two forms shown above. A VALUES clause is really just short-hand +** for a SELECT statement that omits the FROM clause and everything else +** that follows. If the pSelect parameter is NULL, that means that the +** DEFAULT VALUES form of the INSERT statement is intended. +** +** The code generated follows one of four templates. For a simple +** insert with data coming from a single-row VALUES clause, the code executes +** once straight down through. Pseudo-code follows (we call this +** the "1st template"): +** +** open write cursor to
and its indices +** put VALUES clause expressions into registers +** write the resulting record into
+** cleanup +** +** The three remaining templates assume the statement is of the form +** +** INSERT INTO
SELECT ... +** +** If the SELECT clause is of the restricted form "SELECT * FROM " - +** in other words if the SELECT pulls all columns from a single table +** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and +** if and are distinct tables but have identical +** schemas, including all the same indices, then a special optimization +** is invoked that copies raw records from over to . +** See the xferOptimization() function for the implementation of this +** template. This is the 2nd template. +** +** open a write cursor to
+** open read cursor on +** transfer all records in over to
+** close cursors +** foreach index on
+** open a write cursor on the
index +** open a read cursor on the corresponding index +** transfer all records from the read to the write cursors +** close cursors +** end foreach +** +** The 3rd template is for when the second template does not apply +** and the SELECT clause does not read from
at any time. +** The generated code follows this template: +** +** X <- A +** goto B +** A: setup for the SELECT +** loop over the rows in the SELECT +** load values into registers R..R+n +** yield X +** end loop +** cleanup after the SELECT +** end-coroutine X +** B: open write cursor to
and its indices +** C: yield X, at EOF goto D +** insert the select result into
from R..R+n +** goto C +** D: cleanup +** +** The 4th template is used if the insert statement takes its +** values from a SELECT but the data is being inserted into a table +** that is also read as part of the SELECT. In the third form, +** we have to use an intermediate table to store the results of +** the select. The template is like this: +** +** X <- A +** goto B +** A: setup for the SELECT +** loop over the tables in the SELECT +** load value into register R..R+n +** yield X +** end loop +** cleanup after the SELECT +** end co-routine R +** B: open temp table +** L: yield X, at EOF goto M +** insert row from R..R+n into temp table +** goto L +** M: open write cursor to
and its indices +** rewind temp table +** C: loop over rows of intermediate table +** transfer values form intermediate table into
+** end loop +** D: cleanup +*/ +SQLITE_PRIVATE void sqlite3Insert( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* Name of table into which we are inserting */ + Select *pSelect, /* A SELECT statement to use as the data source */ + IdList *pColumn, /* Column names corresponding to IDLIST, or NULL. */ + int onError, /* How to handle constraint errors */ + Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */ +){ + sqlite3 *db; /* The main database structure */ + Table *pTab; /* The table to insert into. aka TABLE */ + int i, j; /* Loop counters */ + Vdbe *v; /* Generate code into this virtual machine */ + Index *pIdx; /* For looping over indices of the table */ + int nColumn; /* Number of columns in the data */ + int nHidden = 0; /* Number of hidden columns if TABLE is virtual */ + int iDataCur = 0; /* VDBE cursor that is the main data repository */ + int iIdxCur = 0; /* First index cursor */ + int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ + int endOfLoop; /* Label for the end of the insertion loop */ + int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ + int addrInsTop = 0; /* Jump to label "D" */ + int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ + SelectDest dest; /* Destination for SELECT on rhs of INSERT */ + int iDb; /* Index of database holding TABLE */ + u8 useTempTable = 0; /* Store SELECT results in intermediate table */ + u8 appendFlag = 0; /* True if the insert is likely to be an append */ + u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ + u8 bIdListInOrder; /* True if IDLIST is in table order */ + ExprList *pList = 0; /* List of VALUES() to be inserted */ + int iRegStore; /* Register in which to store next column */ + + /* Register allocations */ + int regFromSelect = 0;/* Base register for data coming from SELECT */ + int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ + int regRowCount = 0; /* Memory cell used for the row counter */ + int regIns; /* Block of regs holding rowid+data being inserted */ + int regRowid; /* registers holding insert rowid */ + int regData; /* register holding first column to insert */ + int *aRegIdx = 0; /* One register allocated to each index */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to insert into a view */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of trigger times */ +#endif + + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto insert_cleanup; + } + assert( db->mallocFailed==0 ); + dest.iSDParm = 0; /* Suppress a harmless compiler warning */ + + /* If the Select object is really just a simple VALUES() list with a + ** single row (the common case) then keep that one row of values + ** and discard the other (unused) parts of the pSelect object + */ + if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ + pList = pSelect->pEList; + pSelect->pEList = 0; + sqlite3SelectDelete(db, pSelect); + pSelect = 0; + } + + /* Locate the table into which we will be inserting new information. + */ + assert( pTabList->nSrc==1 ); + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ){ + goto insert_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, + db->aDb[iDb].zDbSName) ){ + goto insert_cleanup; + } + withoutRowid = !HasRowid(pTab); + + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); + isView = IsView(pTab); +#else +# define pTrigger 0 +# define tmask 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList, + onError, pUpsert, pTrigger); + } +#endif + + /* If pTab is really a view, make sure it has been initialized. + ** ViewGetColumnNames() is a no-op if pTab is not a view. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto insert_cleanup; + } + + /* Cannot insert into a read-only table. + */ + if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + goto insert_cleanup; + } + + /* Allocate a VDBE + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto insert_cleanup; + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); + +#ifndef SQLITE_OMIT_XFER_OPT + /* If the statement is of the form + ** + ** INSERT INTO SELECT * FROM ; + ** + ** Then special optimizations can be applied that make the transfer + ** very fast and which reduce fragmentation of indices. + ** + ** This is the 2nd template. + */ + if( pColumn==0 + && pSelect!=0 + && pTrigger==0 + && xferOptimization(pParse, pTab, pSelect, onError, iDb) + ){ + assert( !pTrigger ); + assert( pList==0 ); + goto insert_end; + } +#endif /* SQLITE_OMIT_XFER_OPT */ + + /* If this is an AUTOINCREMENT table, look up the sequence number in the + ** sqlite_sequence table and store it in memory cell regAutoinc. + */ + regAutoinc = autoIncBegin(pParse, iDb, pTab); + + /* Allocate a block registers to hold the rowid and the values + ** for all columns of the new row. + */ + regRowid = regIns = pParse->nMem+1; + pParse->nMem += pTab->nCol + 1; + if( IsVirtual(pTab) ){ + regRowid++; + pParse->nMem++; + } + regData = regRowid+1; + + /* If the INSERT statement included an IDLIST term, then make sure + ** all elements of the IDLIST really are columns of the table and + ** remember the column indices. + ** + ** If the table has an INTEGER PRIMARY KEY column and that column + ** is named in the IDLIST, then record in the ipkColumn variable + ** the index into IDLIST of the primary key column. ipkColumn is + ** the index of the primary key as it appears in IDLIST, not as + ** is appears in the original table. (The index of the INTEGER + ** PRIMARY KEY in the original table is pTab->iPKey.) After this + ** loop, if ipkColumn==(-1), that means that integer primary key + ** is unspecified, and hence the table is either WITHOUT ROWID or + ** it will automatically generated an integer primary key. + ** + ** bIdListInOrder is true if the columns in IDLIST are in storage + ** order. This enables an optimization that avoids shuffling the + ** columns into storage order. False negatives are harmless, + ** but false positives will cause database corruption. + */ + bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0; + if( pColumn ){ + assert( pColumn->eU4!=EU4_EXPR ); + pColumn->eU4 = EU4_IDX; + for(i=0; inId; i++){ + pColumn->a[i].u4.idx = -1; + } + for(i=0; inId; i++){ + for(j=0; jnCol; j++){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){ + pColumn->a[i].u4.idx = j; + if( i!=j ) bIdListInOrder = 0; + if( j==pTab->iPKey ){ + ipkColumn = i; assert( !withoutRowid ); + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ + sqlite3ErrorMsg(pParse, + "cannot INSERT into generated column \"%s\"", + pTab->aCol[j].zCnName); + goto insert_cleanup; + } +#endif + break; + } + } + if( j>=pTab->nCol ){ + if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ + ipkColumn = i; + bIdListInOrder = 0; + }else{ + sqlite3ErrorMsg(pParse, "table %S has no column named %s", + pTabList->a, pColumn->a[i].zName); + pParse->checkSchema = 1; + goto insert_cleanup; + } + } + } + } + + /* Figure out how many columns of data are supplied. If the data + ** is coming from a SELECT statement, then generate a co-routine that + ** produces a single row of the SELECT on each invocation. The + ** co-routine is the common header to the 3rd and 4th templates. + */ + if( pSelect ){ + /* Data is coming from a SELECT or from a multi-row VALUES clause. + ** Generate a co-routine to run the SELECT. */ + int regYield; /* Register holding co-routine entry-point */ + int addrTop; /* Top of the co-routine */ + int rc; /* Result code */ + + regYield = ++pParse->nMem; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + dest.iSdst = bIdListInOrder ? regData : 0; + dest.nSdst = pTab->nCol; + rc = sqlite3Select(pParse, pSelect, &dest); + regFromSelect = dest.iSdst; + assert( db->pParse==pParse ); + if( rc || pParse->nErr ) goto insert_cleanup; + assert( db->mallocFailed==0 ); + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ + assert( pSelect->pEList ); + nColumn = pSelect->pEList->nExpr; + + /* Set useTempTable to TRUE if the result of the SELECT statement + ** should be written into a temporary table (template 4). Set to + ** FALSE if each output row of the SELECT can be written directly into + ** the destination table (template 3). + ** + ** A temp table must be used if the table being updated is also one + ** of the tables being read by the SELECT statement. Also use a + ** temp table in the case of row triggers. + */ + if( pTrigger || readsTable(pParse, iDb, pTab) ){ + useTempTable = 1; + } + + if( useTempTable ){ + /* Invoke the coroutine to extract information from the SELECT + ** and add it to a transient table srcTab. The code generated + ** here is from the 4th template: + ** + ** B: open temp table + ** L: yield X, goto M at EOF + ** insert row from R..R+n into temp table + ** goto L + ** M: ... + */ + int regRec; /* Register to hold packed record */ + int regTempRowid; /* Register to hold temp table ROWID */ + int addrL; /* Label "L" */ + + srcTab = pParse->nTab++; + regRec = sqlite3GetTempReg(pParse); + regTempRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); + addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); + sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); + sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); + sqlite3VdbeGoto(v, addrL); + sqlite3VdbeJumpHere(v, addrL); + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempReg(pParse, regTempRowid); + } + }else{ + /* This is the case if the data for the INSERT is coming from a + ** single-row VALUES clause + */ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + srcTab = -1; + assert( useTempTable==0 ); + if( pList ){ + nColumn = pList->nExpr; + if( sqlite3ResolveExprListNames(&sNC, pList) ){ + goto insert_cleanup; + } + }else{ + nColumn = 0; + } + } + + /* If there is no IDLIST term but the table has an integer primary + ** key, the set the ipkColumn variable to the integer primary key + ** column index in the original table definition. + */ + if( pColumn==0 && nColumn>0 ){ + ipkColumn = pTab->iPKey; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( ipkColumn>=0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + for(i=ipkColumn-1; i>=0; i--){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); + ipkColumn--; + } + } + } +#endif + + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + assert( TF_HasHidden==COLFLAG_HIDDEN ); + assert( TF_HasGenerated==COLFLAG_GENERATED ); + assert( COLFLAG_NOINSERT==(COLFLAG_GENERATED|COLFLAG_HIDDEN) ); + if( (pTab->tabFlags & (TF_HasGenerated|TF_HasHidden))!=0 ){ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; + } + } + if( nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList->a, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } + } + if( pColumn!=0 && nColumn!=pColumn->nId ){ + sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); + goto insert_cleanup; + } + + /* Initialize the count of rows to be inserted + */ + if( (db->flags & SQLITE_CountRows)!=0 + && !pParse->nested + && !pParse->pTriggerTab + && !pParse->bReturning + ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + /* If this is not a view, open the table and and all indices */ + if( !isView ){ + int nIdx; + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, + &iDataCur, &iIdxCur); + aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2)); + if( aRegIdx==0 ){ + goto insert_cleanup; + } + for(i=0, pIdx=pTab->pIndex; ipNext, i++){ + assert( pIdx ); + aRegIdx[i] = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; + } + aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */ + } +#ifndef SQLITE_OMIT_UPSERT + if( pUpsert ){ + Upsert *pNx; + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", + pTab->zName); + goto insert_cleanup; + } + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); + goto insert_cleanup; + } + if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ + goto insert_cleanup; + } + pTabList->a[0].iCursor = iDataCur; + pNx = pUpsert; + do{ + pNx->pUpsertSrc = pTabList; + pNx->regData = regData; + pNx->iDataCur = iDataCur; + pNx->iIdxCur = iIdxCur; + if( pNx->pUpsertTarget ){ + if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){ + goto insert_cleanup; + } + } + pNx = pNx->pNextUpsert; + }while( pNx!=0 ); + } +#endif + + + /* This is the top of the main insertion loop */ + if( useTempTable ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 4): + ** + ** rewind temp table, if empty goto D + ** C: loop over rows of intermediate table + ** transfer values form intermediate table into
+ ** end loop + ** D: ... + */ + addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); + addrCont = sqlite3VdbeCurrentAddr(v); + }else if( pSelect ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 3): + ** + ** C: yield X, at EOF goto D + ** insert the select result into
from R..R+n + ** goto C + ** D: ... + */ + sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0); + addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + VdbeCoverage(v); + if( ipkColumn>=0 ){ + /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the + ** SELECT, go ahead and copy the value into the rowid slot now, so that + ** the value does not get overwritten by a NULL at tag-20191021-002. */ + sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); + } + } + + /* Compute data for ordinary columns of the new entry. Values + ** are written in storage order into registers starting with regData. + ** Only ordinary columns are computed in this loop. The rowid + ** (if there is one) is computed later and generated columns are + ** computed after the rowid since they might depend on the value + ** of the rowid. + */ + nHidden = 0; + iRegStore = regData; assert( regData==regRowid+1 ); + for(i=0; inCol; i++, iRegStore++){ + int k; + u32 colFlags; + assert( i>=nHidden ); + if( i==pTab->iPKey ){ + /* tag-20191021-002: References to the INTEGER PRIMARY KEY are filled + ** using the rowid. So put a NULL in the IPK slot of the record to avoid + ** using excess space. The file format definition requires this extra + ** NULL - we cannot optimize further by skipping the column completely */ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + continue; + } + if( ((colFlags = pTab->aCol[i].colFlags) & COLFLAG_NOINSERT)!=0 ){ + nHidden++; + if( (colFlags & COLFLAG_VIRTUAL)!=0 ){ + /* Virtual columns do not participate in OP_MakeRecord. So back up + ** iRegStore by one slot to compensate for the iRegStore++ in the + ** outer for() loop */ + iRegStore--; + continue; + }else if( (colFlags & COLFLAG_STORED)!=0 ){ + /* Stored columns are computed later. But if there are BEFORE + ** triggers, the slots used for stored columns will be OP_Copy-ed + ** to a second block of registers, so the register needs to be + ** initialized to NULL to avoid an uninitialized register read */ + if( tmask & TRIGGER_BEFORE ){ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + } + continue; + }else if( pColumn==0 ){ + /* Hidden columns that are not explicitly named in the INSERT + ** get there default value */ + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); + continue; + } + } + if( pColumn ){ + assert( pColumn->eU4==EU4_IDX ); + for(j=0; jnId && pColumn->a[j].u4.idx!=i; j++){} + if( j>=pColumn->nId ){ + /* A column not named in the insert column list gets its + ** default value */ + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); + continue; + } + k = j; + }else if( nColumn==0 ){ + /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); + continue; + }else{ + k = i - nHidden; + } + + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); + }else if( pSelect ){ + if( regFromSelect!=regData ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); + } + }else{ + Expr *pX = pList->a[k].pExpr; + int y = sqlite3ExprCodeTarget(pParse, pX, iRegStore); + if( y!=iRegStore ){ + sqlite3VdbeAddOp2(v, + ExprHasProperty(pX, EP_Subquery) ? OP_Copy : OP_SCopy, y, iRegStore); + } + } + } + + + /* Run the BEFORE and INSTEAD OF triggers, if there are any + */ + endOfLoop = sqlite3VdbeMakeLabel(pParse); + if( tmask & TRIGGER_BEFORE ){ + int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); + + /* build the NEW.* reference row. Note that if there is an INTEGER + ** PRIMARY KEY into which a NULL is being inserted, that NULL will be + ** translated into a unique ID for the row. But on a BEFORE trigger, + ** we do not know what the unique ID will be (because the insert has + ** not happened yet) so we substitute a rowid of -1 + */ + if( ipkColumn<0 ){ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + }else{ + int addr1; + assert( !withoutRowid ); + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols); + }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); + } + addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); + } + + /* Copy the new data already generated. */ + assert( pTab->nNVCol>0 || pParse->nErr>0 ); + sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Compute the new value for generated columns after all other + ** columns have already been computed. This must be done after + ** computing the ROWID in case one of the generated columns + ** refers to the ROWID. */ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab); + } +#endif + + /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, + ** do not attempt any conversions before assembling the record. + ** If this is a real table, attempt conversions as required by the + ** table column affinities. + */ + if( !isView ){ + sqlite3TableAffinity(v, pTab, regCols+1); + } + + /* Fire BEFORE or INSTEAD OF triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + pTab, regCols-pTab->nCol-1, onError, endOfLoop); + + sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); + } + + if( !isView ){ + if( IsVirtual(pTab) ){ + /* The row that the VUpdate opcode will delete: none */ + sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); + } + if( ipkColumn>=0 ){ + /* Compute the new rowid */ + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); + }else if( pSelect ){ + /* Rowid already initialized at tag-20191021-001 */ + }else{ + Expr *pIpk = pList->a[ipkColumn].pExpr; + if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){ + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + appendFlag = 1; + }else{ + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); + } + } + /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid + ** to generate a unique primary key value. + */ + if( !appendFlag ){ + int addr1; + if( !IsVirtual(pTab) ){ + addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeJumpHere(v, addr1); + }else{ + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v); + } + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); + } + }else if( IsVirtual(pTab) || withoutRowid ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); + }else{ + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + appendFlag = 1; + } + autoIncStep(pParse, regAutoinc, regRowid); + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Compute the new value for generated columns after all other + ** columns have already been computed. This must be done after + ** computing the ROWID in case one of the generated columns + ** is derived from the INTEGER PRIMARY KEY. */ + if( pTab->tabFlags & TF_HasGenerated ){ + sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab); + } +#endif + + /* Generate code to check constraints and generate index keys and + ** do the insertion. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); + sqlite3MayAbort(pParse); + }else +#endif + { + int isReplace = 0;/* Set to true if constraints may cause a replace */ + int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert + ); + if( db->flags & SQLITE_ForeignKeys ){ + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); + } + + /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE + ** constraints or (b) there are no triggers and this table is not a + ** parent table in a foreign key constraint. It is safe to set the + ** flag in the second case as if any REPLACE constraint is hit, an + ** OP_Delete or OP_IdxDelete instruction will be executed on each + ** cursor that is disturbed. And these instructions both clear the + ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT + ** functionality. */ + bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v)); + sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, + regIns, aRegIdx, 0, appendFlag, bUseSeek + ); + } +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + }else if( pParse->bReturning ){ + /* If there is a RETURNING clause, populate the rowid register with + ** constant value -1, in case one or more of the returned expressions + ** refer to the "rowid" of the view. */ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regRowid); +#endif + } + + /* Update the count of rows that are inserted + */ + if( regRowCount ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + if( pTrigger ){ + /* Code AFTER triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + pTab, regData-2-pTab->nCol, onError, endOfLoop); + } + + /* The bottom of the main insertion loop, if the data source + ** is a SELECT statement. + */ + sqlite3VdbeResolveLabel(v, endOfLoop); + if( useTempTable ){ + sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrInsTop); + sqlite3VdbeAddOp1(v, OP_Close, srcTab); + }else if( pSelect ){ + sqlite3VdbeGoto(v, addrCont); +#ifdef SQLITE_DEBUG + /* If we are jumping back to an OP_Yield that is preceded by an + ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the + ** OP_ReleaseReg will be included in the loop. */ + if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){ + assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield ); + sqlite3VdbeChangeP5(v, 1); + } +#endif + sqlite3VdbeJumpHere(v, addrInsTop); + } + +#ifndef SQLITE_OMIT_XFER_OPT +insert_end: +#endif /* SQLITE_OMIT_XFER_OPT */ + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** Return the number of rows inserted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( regRowCount ){ + sqlite3CodeChangeCount(v, regRowCount, "rows inserted"); + } + +insert_cleanup: + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pList); + sqlite3UpsertDelete(db, pUpsert); + sqlite3SelectDelete(db, pSelect); + sqlite3IdListDelete(db, pColumn); + if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx); +} + +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif +#ifdef tmask + #undef tmask +#endif + +/* +** Meanings of bits in of pWalker->eCode for +** sqlite3ExprReferencesUpdatedColumn() +*/ +#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ +#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ + +/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). +* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this +** expression node references any of the +** columns that are being modified by an UPDATE statement. +*/ +static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 ); + if( pExpr->iColumn>=0 ){ + if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){ + pWalker->eCode |= CKCNSTRNT_COLUMN; + } + }else{ + pWalker->eCode |= CKCNSTRNT_ROWID; + } + } + return WRC_Continue; +} + +/* +** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The +** only columns that are modified by the UPDATE are those for which +** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true. +** +** Return true if CHECK constraint pExpr uses any of the +** changing columns (or the rowid if it is changing). In other words, +** return true if this CHECK constraint must be validated for +** the new row in the UPDATE statement. +** +** 2018-09-15: pExpr might also be an expression for an index-on-expressions. +** The operation of this routine is the same - return true if an only if +** the expression uses one or more of columns identified by the second and +** third arguments. +*/ +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( + Expr *pExpr, /* The expression to be checked */ + int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */ + int chngRowid /* True if UPDATE changes the rowid */ +){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = 0; + w.xExprCallback = checkConstraintExprNode; + w.u.aiCol = aiChng; + sqlite3WalkExpr(&w, pExpr); + if( !chngRowid ){ + testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 ); + w.eCode &= ~CKCNSTRNT_ROWID; + } + testcase( w.eCode==0 ); + testcase( w.eCode==CKCNSTRNT_COLUMN ); + testcase( w.eCode==CKCNSTRNT_ROWID ); + testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) ); + return w.eCode!=0; +} + +/* +** The sqlite3GenerateConstraintChecks() routine usually wants to visit +** the indexes of a table in the order provided in the Table->pIndex list. +** However, sometimes (rarely - when there is an upsert) it wants to visit +** the indexes in a different order. The following data structures accomplish +** this. +** +** The IndexIterator object is used to walk through all of the indexes +** of a table in either Index.pNext order, or in some other order established +** by an array of IndexListTerm objects. +*/ +typedef struct IndexListTerm IndexListTerm; +typedef struct IndexIterator IndexIterator; +struct IndexIterator { + int eType; /* 0 for Index.pNext list. 1 for an array of IndexListTerm */ + int i; /* Index of the current item from the list */ + union { + struct { /* Use this object for eType==0: A Index.pNext list */ + Index *pIdx; /* The current Index */ + } lx; + struct { /* Use this object for eType==1; Array of IndexListTerm */ + int nIdx; /* Size of the array */ + IndexListTerm *aIdx; /* Array of IndexListTerms */ + } ax; + } u; +}; + +/* When IndexIterator.eType==1, then each index is an array of instances +** of the following object +*/ +struct IndexListTerm { + Index *p; /* The index */ + int ix; /* Which entry in the original Table.pIndex list is this index*/ +}; + +/* Return the first index on the list */ +static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ + assert( pIter->i==0 ); + if( pIter->eType ){ + *pIx = pIter->u.ax.aIdx[0].ix; + return pIter->u.ax.aIdx[0].p; + }else{ + *pIx = 0; + return pIter->u.lx.pIdx; + } +} + +/* Return the next index from the list. Return NULL when out of indexes */ +static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ + if( pIter->eType ){ + int i = ++pIter->i; + if( i>=pIter->u.ax.nIdx ){ + *pIx = i; + return 0; + } + *pIx = pIter->u.ax.aIdx[i].ix; + return pIter->u.ax.aIdx[i].p; + }else{ + ++(*pIx); + pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext; + return pIter->u.lx.pIdx; + } +} + +/* +** Generate code to do constraint checks prior to an INSERT or an UPDATE +** on table pTab. +** +** The regNewData parameter is the first register in a range that contains +** the data to be inserted or the data after the update. There will be +** pTab->nCol+1 registers in this range. The first register (the one +** that regNewData points to) will contain the new rowid, or NULL in the +** case of a WITHOUT ROWID table. The second register in the range will +** contain the content of the first table column. The third register will +** contain the content of the second table column. And so forth. +** +** The regOldData parameter is similar to regNewData except that it contains +** the data prior to an UPDATE rather than afterwards. regOldData is zero +** for an INSERT. This routine can distinguish between UPDATE and INSERT by +** checking regOldData for zero. +** +** For an UPDATE, the pkChng boolean is true if the true primary key (the +** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table) +** might be modified by the UPDATE. If pkChng is false, then the key of +** the iDataCur content table is guaranteed to be unchanged by the UPDATE. +** +** For an INSERT, the pkChng boolean indicates whether or not the rowid +** was explicitly specified as part of the INSERT statement. If pkChng +** is zero, it means that the either rowid is computed automatically or +** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT, +** pkChng will only be true if the INSERT statement provides an integer +** value for either the rowid column or its INTEGER PRIMARY KEY alias. +** +** The code generated by this routine will store new index entries into +** registers identified by aRegIdx[]. No index entry is created for +** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is +** the same as the order of indices on the linked list of indices +** at pTab->pIndex. +** +** (2019-05-07) The generated code also creates a new record for the +** main table, if pTab is a rowid table, and stores that record in the +** register identified by aRegIdx[nIdx] - in other words in the first +** entry of aRegIdx[] past the last index. It is important that the +** record be generated during constraint checks to avoid affinity changes +** to the register content that occur after constraint checks but before +** the new record is inserted. +** +** The caller must have already opened writeable cursors on the main +** table and all applicable indices (that is to say, all indices for which +** aRegIdx[] is not zero). iDataCur is the cursor for the main table when +** inserting or updating a rowid table, or the cursor for the PRIMARY KEY +** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor +** for the first index in the pTab->pIndex list. Cursors for other indices +** are at iIdxCur+N for the N-th element of the pTab->pIndex list. +** +** This routine also generates code to check constraints. NOT NULL, +** CHECK, and UNIQUE constraints are all checked. If a constraint fails, +** then the appropriate action is performed. There are five possible +** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. +** +** Constraint type Action What Happens +** --------------- ---------- ---------------------------------------- +** any ROLLBACK The current transaction is rolled back and +** sqlite3_step() returns immediately with a +** return code of SQLITE_CONSTRAINT. +** +** any ABORT Back out changes from the current command +** only (do not do a complete rollback) then +** cause sqlite3_step() to return immediately +** with SQLITE_CONSTRAINT. +** +** any FAIL Sqlite3_step() returns immediately with a +** return code of SQLITE_CONSTRAINT. The +** transaction is not rolled back and any +** changes to prior rows are retained. +** +** any IGNORE The attempt in insert or update the current +** row is skipped, without throwing an error. +** Processing continues with the next row. +** (There is an immediate jump to ignoreDest.) +** +** NOT NULL REPLACE The NULL value is replace by the default +** value for that column. If the default value +** is NULL, the action is the same as ABORT. +** +** UNIQUE REPLACE The other row that conflicts with the row +** being inserted is removed. +** +** CHECK REPLACE Illegal. The results in an exception. +** +** Which action to take is determined by the overrideError parameter. +** Or if overrideError==OE_Default, then the pParse->onError parameter +** is used. Or if pParse->onError==OE_Default then the onError value +** for the constraint is used. +*/ +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( + Parse *pParse, /* The parser context */ + Table *pTab, /* The table being inserted or updated */ + int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */ + int iDataCur, /* Canonical data cursor (main table or PK index) */ + int iIdxCur, /* First index cursor */ + int regNewData, /* First register in a range holding values to insert */ + int regOldData, /* Previous content. 0 for INSERTs */ + u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */ + u8 overrideError, /* Override onError to this if not OE_Default */ + int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ + int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ + int *aiChng, /* column i is unchanged if aiChng[i]<0 */ + Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ +){ + Vdbe *v; /* VDBE under construction */ + Index *pIdx; /* Pointer to one of the indices */ + Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ + sqlite3 *db; /* Database connection */ + int i; /* loop counter */ + int ix; /* Index loop counter */ + int nCol; /* Number of columns */ + int onError; /* Conflict resolution strategy */ + int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ + int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ + Upsert *pUpsertClause = 0; /* The specific ON CONFLICT clause for pIdx */ + u8 isUpdate; /* True if this is an UPDATE operation */ + u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ + int upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */ + int upsertIpkDelay = 0; /* Address of Goto to bypass initial IPK check */ + int ipkTop = 0; /* Top of the IPK uniqueness check */ + int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ + /* Variables associated with retesting uniqueness constraints after + ** replace triggers fire have run */ + int regTrigCnt; /* Register used to count replace trigger invocations */ + int addrRecheck = 0; /* Jump here to recheck all uniqueness constraints */ + int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ + Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ + int nReplaceTrig = 0; /* Number of replace triggers coded */ + IndexIterator sIdxIter; /* Index iterator */ + + isUpdate = regOldData!=0; + db = pParse->db; + v = pParse->pVdbe; + assert( v!=0 ); + assert( !IsView(pTab) ); /* This table is not a VIEW */ + nCol = pTab->nCol; + + /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for + ** normal rowid tables. nPkField is the number of key fields in the + ** pPk index or 1 for a rowid table. In other words, nPkField is the + ** number of fields in the true primary key of the table. */ + if( HasRowid(pTab) ){ + pPk = 0; + nPkField = 1; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + nPkField = pPk->nKeyCol; + } + + /* Record that this module has started */ + VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)", + iDataCur, iIdxCur, regNewData, regOldData, pkChng)); + + /* Test all NOT NULL constraints. + */ + if( pTab->tabFlags & TF_HasNotNull ){ + int b2ndPass = 0; /* True if currently running 2nd pass */ + int nSeenReplace = 0; /* Number of ON CONFLICT REPLACE operations */ + int nGenerated = 0; /* Number of generated columns with NOT NULL */ + while(1){ /* Make 2 passes over columns. Exit loop via "break" */ + for(i=0; iaCol[i]; /* The column to check for NOT NULL */ + int isGenerated; /* non-zero if column is generated */ + onError = pCol->notNull; + if( onError==OE_None ) continue; /* No NOT NULL on this column */ + if( i==pTab->iPKey ){ + continue; /* ROWID is never NULL */ + } + isGenerated = pCol->colFlags & COLFLAG_GENERATED; + if( isGenerated && !b2ndPass ){ + nGenerated++; + continue; /* Generated columns processed on 2nd pass */ + } + if( aiChng && aiChng[i]<0 && !isGenerated ){ + /* Do not check NOT NULL on columns that do not change */ + continue; + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + if( onError==OE_Replace ){ + if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */ + || pCol->iDflt==0 /* REPLACE is ABORT if no DEFAULT value */ + ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + testcase( pCol->colFlags & COLFLAG_GENERATED ); + onError = OE_Abort; + }else{ + assert( !isGenerated ); + } + }else if( b2ndPass && !isGenerated ){ + continue; + } + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); + testcase( i!=sqlite3TableColumnToStorage(pTab, i) ); + iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1; + switch( onError ){ + case OE_Replace: { + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg); + VdbeCoverage(v); + assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); + nSeenReplace++; + sqlite3ExprCodeCopy(pParse, + sqlite3ColumnExpr(pTab, pCol), iReg); + sqlite3VdbeJumpHere(v, addr1); + break; + } + case OE_Abort: + sqlite3MayAbort(pParse); + /* no break */ deliberate_fall_through + case OE_Rollback: + case OE_Fail: { + char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, + pCol->zCnName); + testcase( zMsg==0 && db->mallocFailed==0 ); + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, + onError, iReg); + sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); + sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); + VdbeCoverage(v); + break; + } + default: { + assert( onError==OE_Ignore ); + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest); + VdbeCoverage(v); + break; + } + } /* end switch(onError) */ + } /* end loop i over columns */ + if( nGenerated==0 && nSeenReplace==0 ){ + /* If there are no generated columns with NOT NULL constraints + ** and no NOT NULL ON CONFLICT REPLACE constraints, then a single + ** pass is sufficient */ + break; + } + if( b2ndPass ) break; /* Never need more than 2 passes */ + b2ndPass = 1; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( nSeenReplace>0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){ + /* If any NOT NULL ON CONFLICT REPLACE constraints fired on the + ** first pass, recomputed values for all generated columns, as + ** those values might depend on columns affected by the REPLACE. + */ + sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab); + } +#endif + } /* end of 2-pass loop */ + } /* end if( has-not-null-constraints ) */ + + /* Test all CHECK constraints + */ +#ifndef SQLITE_OMIT_CHECK + if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ + ExprList *pCheck = pTab->pCheck; + pParse->iSelfTab = -(regNewData+1); + onError = overrideError!=OE_Default ? overrideError : OE_Abort; + for(i=0; inExpr; i++){ + int allOk; + Expr *pCopy; + Expr *pExpr = pCheck->a[i].pExpr; + if( aiChng + && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) + ){ + /* The check constraints do not reference any of the columns being + ** updated so there is no point it verifying the check constraint */ + continue; + } + if( bAffinityDone==0 ){ + sqlite3TableAffinity(v, pTab, regNewData+1); + bAffinityDone = 1; + } + allOk = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeVerifyAbortable(v, onError); + pCopy = sqlite3ExprDup(db, pExpr, 0); + if( !db->mallocFailed ){ + sqlite3ExprIfTrue(pParse, pCopy, allOk, SQLITE_JUMPIFNULL); + } + sqlite3ExprDelete(db, pCopy); + if( onError==OE_Ignore ){ + sqlite3VdbeGoto(v, ignoreDest); + }else{ + char *zName = pCheck->a[i].zEName; + assert( zName!=0 || pParse->db->mallocFailed ); + if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */ + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, + onError, zName, P4_TRANSIENT, + P5_ConstraintCheck); + } + sqlite3VdbeResolveLabel(v, allOk); + } + pParse->iSelfTab = 0; + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ + + /* UNIQUE and PRIMARY KEY constraints should be handled in the following + ** order: + ** + ** (1) OE_Update + ** (2) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore + ** (3) OE_Replace + ** + ** OE_Fail and OE_Ignore must happen before any changes are made. + ** OE_Update guarantees that only a single row will change, so it + ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback + ** could happen in any order, but they are grouped up front for + ** convenience. + ** + ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43 + ** The order of constraints used to have OE_Update as (2) and OE_Abort + ** and so forth as (1). But apparently PostgreSQL checks the OE_Update + ** constraint before any others, so it had to be moved. + ** + ** Constraint checking code is generated in this order: + ** (A) The rowid constraint + ** (B) Unique index constraints that do not have OE_Replace as their + ** default conflict resolution strategy + ** (C) Unique index that do use OE_Replace by default. + ** + ** The ordering of (2) and (3) is accomplished by making sure the linked + ** list of indexes attached to a table puts all OE_Replace indexes last + ** in the list. See sqlite3CreateIndex() for where that happens. + */ + sIdxIter.eType = 0; + sIdxIter.i = 0; + sIdxIter.u.ax.aIdx = 0; /* Silence harmless compiler warning */ + sIdxIter.u.lx.pIdx = pTab->pIndex; + if( pUpsert ){ + if( pUpsert->pUpsertTarget==0 ){ + /* There is just on ON CONFLICT clause and it has no constraint-target */ + assert( pUpsert->pNextUpsert==0 ); + if( pUpsert->isDoUpdate==0 ){ + /* A single ON CONFLICT DO NOTHING clause, without a constraint-target. + ** Make all unique constraint resolution be OE_Ignore */ + overrideError = OE_Ignore; + pUpsert = 0; + }else{ + /* A single ON CONFLICT DO UPDATE. Make all resolutions OE_Update */ + overrideError = OE_Update; + } + }else if( pTab->pIndex!=0 ){ + /* Otherwise, we'll need to run the IndexListTerm array version of the + ** iterator to ensure that all of the ON CONFLICT conditions are + ** checked first and in order. */ + int nIdx, jj; + u64 nByte; + Upsert *pTerm; + u8 *bUsed; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + assert( aRegIdx[nIdx]>0 ); + } + sIdxIter.eType = 1; + sIdxIter.u.ax.nIdx = nIdx; + nByte = (sizeof(IndexListTerm)+1)*nIdx + nIdx; + sIdxIter.u.ax.aIdx = sqlite3DbMallocZero(db, nByte); + if( sIdxIter.u.ax.aIdx==0 ) return; /* OOM */ + bUsed = (u8*)&sIdxIter.u.ax.aIdx[nIdx]; + pUpsert->pToFree = sIdxIter.u.ax.aIdx; + for(i=0, pTerm=pUpsert; pTerm; pTerm=pTerm->pNextUpsert){ + if( pTerm->pUpsertTarget==0 ) break; + if( pTerm->pUpsertIdx==0 ) continue; /* Skip ON CONFLICT for the IPK */ + jj = 0; + pIdx = pTab->pIndex; + while( ALWAYS(pIdx!=0) && pIdx!=pTerm->pUpsertIdx ){ + pIdx = pIdx->pNext; + jj++; + } + if( bUsed[jj] ) continue; /* Duplicate ON CONFLICT clause ignored */ + bUsed[jj] = 1; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + for(jj=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, jj++){ + if( bUsed[jj] ) continue; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + assert( i==nIdx ); + } + } + + /* Determine if it is possible that triggers (either explicitly coded + ** triggers or FK resolution actions) might run as a result of deletes + ** that happen when OE_Replace conflict resolution occurs. (Call these + ** "replace triggers".) If any replace triggers run, we will need to + ** recheck all of the uniqueness constraints after they have all run. + ** But on the recheck, the resolution is OE_Abort instead of OE_Replace. + ** + ** If replace triggers are a possibility, then + ** + ** (1) Allocate register regTrigCnt and initialize it to zero. + ** That register will count the number of replace triggers that + ** fire. Constraint recheck only occurs if the number is positive. + ** (2) Initialize pTrigger to the list of all DELETE triggers on pTab. + ** (3) Initialize addrRecheck and lblRecheckOk + ** + ** The uniqueness rechecking code will create a series of tests to run + ** in a second pass. The addrRecheck and lblRecheckOk variables are + ** used to link together these tests which are separated from each other + ** in the generate bytecode. + */ + if( (db->flags & (SQLITE_RecTriggers|SQLITE_ForeignKeys))==0 ){ + /* There are not DELETE triggers nor FK constraints. No constraint + ** rechecks are needed. */ + pTrigger = 0; + regTrigCnt = 0; + }else{ + if( db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + regTrigCnt = pTrigger!=0 || sqlite3FkRequired(pParse, pTab, 0, 0); + }else{ + pTrigger = 0; + regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0); + } + if( regTrigCnt ){ + /* Replace triggers might exist. Allocate the counter and + ** initialize it to zero. */ + regTrigCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt); + VdbeComment((v, "trigger count")); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + addrRecheck = lblRecheckOk; + } + } + + /* If rowid is changing, make sure the new rowid does not previously + ** exist in the table. + */ + if( pkChng && pPk==0 ){ + int addrRowidOk = sqlite3VdbeMakeLabel(pParse); + + /* Figure out what action to take in case of a rowid collision */ + onError = pTab->keyConf; + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + /* figure out whether or not upsert applies in this case */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0); + if( pUpsertClause!=0 ){ + if( pUpsertClause->isDoUpdate==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + if( pUpsertClause!=pUpsert ){ + /* The first ON CONFLICT clause has a conflict target other than + ** the IPK. We have to jump ahead to that first ON CONFLICT clause + ** and then come back here and deal with the IPK afterwards */ + upsertIpkDelay = sqlite3VdbeAddOp0(v, OP_Goto); + } + } + + /* If the response to a rowid conflict is REPLACE but the response + ** to some other UNIQUE constraint is FAIL or IGNORE, then we need + ** to defer the running of the rowid conflict checking until after + ** the UNIQUE constraints have run. + */ + if( onError==OE_Replace /* IPK rule is REPLACE */ + && onError!=overrideError /* Rules for other constraints are different */ + && pTab->pIndex /* There exist other constraints */ + && !upsertIpkDelay /* IPK check already deferred by UPSERT */ + ){ + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + VdbeComment((v, "defer IPK REPLACE until last")); + } + + if( isUpdate ){ + /* pkChng!=0 does not mean that the rowid has changed, only that + ** it might have changed. Skip the conflict logic below if the rowid + ** is unchanged. */ + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + + /* Check to see if the new rowid already exists in the table. Skip + ** the following conflict logic if it does not. */ + VdbeNoopComment((v, "uniqueness check for ROWID")); + sqlite3VdbeVerifyAbortable(v, onError); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); + VdbeCoverage(v); + + switch( onError ){ + default: { + onError = OE_Abort; + /* no break */ deliberate_fall_through + } + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + testcase( onError==OE_Rollback ); + testcase( onError==OE_Abort ); + testcase( onError==OE_Fail ); + sqlite3RowidConstraint(pParse, onError, pTab); + break; + } + case OE_Replace: { + /* If there are DELETE triggers on this table and the + ** recursive-triggers flag is set, call GenerateRowDelete() to + ** remove the conflicting row from the table. This will fire + ** the triggers and remove both the table and index b-tree entries. + ** + ** Otherwise, if there are no triggers or the recursive-triggers + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. + ** + ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, + ** also invoke MultiWrite() to indicate that this VDBE may require + ** statement rollback (if the statement is aborted after the delete + ** takes place). Earlier versions called sqlite3MultiWrite() regardless, + ** but being more selective here allows statements like: + ** + ** REPLACE INTO t(rowid) VALUES($newrowid) + ** + ** to run without a statement journal if there are no indexes on the + ** table. + */ + if( regTrigCnt ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + regNewData, 1, 0, OE_Replace, 1, -1); + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + nReplaceTrig++; + }else{ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + assert( HasRowid(pTab) ); + /* This OP_Delete opcode fires the pre-update-hook only. It does + ** not modify the b-tree. It is more efficient to let the coming + ** OP_Insert replace the existing entry than it is to delete the + ** existing entry and then insert a new one. */ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + if( pTab->pIndex ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1); + } + } + seenReplace = 1; + break; + } +#ifndef SQLITE_OMIT_UPSERT + case OE_Update: { + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur); + /* no break */ deliberate_fall_through + } +#endif + case OE_Ignore: { + testcase( onError==OE_Ignore ); + sqlite3VdbeGoto(v, ignoreDest); + break; + } + } + sqlite3VdbeResolveLabel(v, addrRowidOk); + if( pUpsert && pUpsertClause!=pUpsert ){ + upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); + }else if( ipkTop ){ + ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, ipkTop-1); + } + } + + /* Test all UNIQUE constraints by creating entries for each UNIQUE + ** index and making sure that duplicate entries do not already exist. + ** Compute the revised record entries for indices as we go. + ** + ** This loop also handles the case of the PRIMARY KEY index for a + ** WITHOUT ROWID table. + */ + for(pIdx = indexIteratorFirst(&sIdxIter, &ix); + pIdx; + pIdx = indexIteratorNext(&sIdxIter, &ix) + ){ + int regIdx; /* Range of registers holding content for pIdx */ + int regR; /* Range of registers holding conflicting PK */ + int iThisCur; /* Cursor for this UNIQUE index */ + int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ + int addrConflictCk; /* First opcode in the conflict check logic */ + + if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert, pIdx); + if( upsertIpkDelay && pUpsertClause==pUpsert ){ + sqlite3VdbeJumpHere(v, upsertIpkDelay); + } + } + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( bAffinityDone==0 ){ + sqlite3TableAffinity(v, pTab, regNewData+1); + bAffinityDone = 1; + } + VdbeNoopComment((v, "prep index %s", pIdx->zName)); + iThisCur = iIdxCur+ix; + + + /* Skip partial indices for which the WHERE clause is not true */ + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); + pParse->iSelfTab = -(regNewData+1); + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk, + SQLITE_JUMPIFNULL); + pParse->iSelfTab = 0; + } + + /* Create a record for this index entry as it should appear after + ** the insert or update. Store that record in the aRegIdx[ix] register + */ + regIdx = aRegIdx[ix]+1; + for(i=0; inColumn; i++){ + int iField = pIdx->aiColumn[i]; + int x; + if( iField==XN_EXPR ){ + pParse->iSelfTab = -(regNewData+1); + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); + pParse->iSelfTab = 0; + VdbeComment((v, "%s column %d", pIdx->zName, i)); + }else if( iField==XN_ROWID || iField==pTab->iPKey ){ + x = regNewData; + sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i); + VdbeComment((v, "rowid")); + }else{ + testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField ); + x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; + sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); + VdbeComment((v, "%s", pTab->aCol[iField].zCnName)); + } + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); + VdbeComment((v, "for %s", pIdx->zName)); +#ifdef SQLITE_ENABLE_NULL_TRIM + if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ + sqlite3SetMakeRecordP5(v, pIdx->pTable); + } +#endif + sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0); + + /* In an UPDATE operation, if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table and there has been no change the + ** primary key, then no collision is possible. The collision detection + ** logic below can all be skipped. */ + if( isUpdate && pPk==pIdx && pkChng==0 ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } + + /* Find out what action to take in case there is a uniqueness conflict */ + onError = pIdx->onError; + if( onError==OE_None ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; /* pIdx is not a UNIQUE index */ + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + /* Figure out if the upsert clause applies to this index */ + if( pUpsertClause ){ + if( pUpsertClause->isDoUpdate==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + + /* Collision detection may be omitted if all of the following are true: + ** (1) The conflict resolution algorithm is REPLACE + ** (2) The table is a WITHOUT ROWID table + ** (3) There are no secondary indexes on the table + ** (4) No delete triggers need to be fired if there is a conflict + ** (5) No FK constraint counters need to be updated if a conflict occurs. + ** + ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row + ** must be explicitly deleted in order to ensure any pre-update hook + ** is invoked. */ + assert( IsOrdinaryTable(pTab) ); +#ifndef SQLITE_ENABLE_PREUPDATE_HOOK + if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ + && pPk==pIdx /* Condition 2 */ + && onError==OE_Replace /* Condition 1 */ + && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ + 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) + && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */ + (0==pTab->u.tab.pFKey && 0==sqlite3FkReferences(pTab))) + ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } +#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */ + + /* Check to see if the new index entry will be unique */ + sqlite3VdbeVerifyAbortable(v, onError); + addrConflictCk = + sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, + regIdx, pIdx->nKeyCol); VdbeCoverage(v); + + /* Generate code to handle collisions */ + regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField); + if( isUpdate || onError==OE_Replace ){ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); + /* Conflict only if the rowid of the existing index entry + ** is different from old-rowid */ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + }else{ + int x; + /* Extract the PRIMARY KEY from the end of the index entry and + ** store it in registers regR..regR+nPk-1 */ + if( pIdx!=pPk ){ + for(i=0; inKeyCol; i++){ + assert( pPk->aiColumn[i]>=0 ); + x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); + VdbeComment((v, "%s.%s", pTab->zName, + pTab->aCol[pPk->aiColumn[i]].zCnName)); + } + } + if( isUpdate ){ + /* If currently processing the PRIMARY KEY of a WITHOUT ROWID + ** table, only conflict if the new PRIMARY KEY values are actually + ** different from the old. See TH3 withoutrowid04.test. + ** + ** For a UNIQUE index, only conflict if the PRIMARY KEY values + ** of the matched index row are different from the original PRIMARY + ** KEY values of this row before the update. */ + int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; + int op = OP_Ne; + int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); + + for(i=0; inKeyCol; i++){ + char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); + x = pPk->aiColumn[i]; + assert( x>=0 ); + if( i==(pPk->nKeyCol-1) ){ + addrJump = addrUniqueOk; + op = OP_Eq; + } + x = sqlite3TableColumnToStorage(pTab, x); + sqlite3VdbeAddOp4(v, op, + regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ + ); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverageIf(v, op==OP_Eq); + VdbeCoverageIf(v, op==OP_Ne); + } + } + } + } + + /* Generate code that executes if the new index entry is not unique */ + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update ); + switch( onError ){ + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + testcase( onError==OE_Rollback ); + testcase( onError==OE_Abort ); + testcase( onError==OE_Fail ); + sqlite3UniqueConstraint(pParse, onError, pIdx); + break; + } +#ifndef SQLITE_OMIT_UPSERT + case OE_Update: { + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix); + /* no break */ deliberate_fall_through + } +#endif + case OE_Ignore: { + testcase( onError==OE_Ignore ); + sqlite3VdbeGoto(v, ignoreDest); + break; + } + default: { + int nConflictCk; /* Number of opcodes in conflict check logic */ + + assert( onError==OE_Replace ); + nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; + assert( nConflictCk>0 || db->mallocFailed ); + testcase( nConflictCk<=0 ); + testcase( nConflictCk>1 ); + if( regTrigCnt ){ + sqlite3MultiWrite(pParse); + nReplaceTrig++; + } + if( pTrigger && isUpdate ){ + sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur); + } + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + regR, nPkField, 0, OE_Replace, + (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); + if( pTrigger && isUpdate ){ + sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); + } + if( regTrigCnt ){ + int addrBypass; /* Jump destination to bypass recheck logic */ + + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ + VdbeComment((v, "bypass recheck")); + + /* Here we insert code that will be invoked after all constraint + ** checks have run, if and only if one or more replace triggers + ** fired. */ + sqlite3VdbeResolveLabel(v, lblRecheckOk); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + if( pIdx->pPartIdxWhere ){ + /* Bypass the recheck if this partial index is not defined + ** for the current row */ + sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); + VdbeCoverage(v); + } + /* Copy the constraint check code from above, except change + ** the constraint-ok jump destination to be the address of + ** the next retest block */ + while( nConflictCk>0 ){ + VdbeOp x; /* Conflict check opcode to copy */ + /* The sqlite3VdbeAddOp4() call might reallocate the opcode array. + ** Hence, make a complete copy of the opcode, rather than using + ** a pointer to the opcode. */ + x = *sqlite3VdbeGetOp(v, addrConflictCk); + if( x.opcode!=OP_IdxRowid ){ + int p2; /* New P2 value for copied conflict check opcode */ + const char *zP4; + if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ + p2 = lblRecheckOk; + }else{ + p2 = x.p2; + } + zP4 = x.p4type==P4_INT32 ? SQLITE_INT_TO_PTR(x.p4.i) : x.p4.z; + sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, zP4, x.p4type); + sqlite3VdbeChangeP5(v, x.p5); + VdbeCoverageIf(v, p2!=x.p2); + } + nConflictCk--; + addrConflictCk++; + } + /* If the retest fails, issue an abort */ + sqlite3UniqueConstraint(pParse, OE_Abort, pIdx); + + sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ + } + seenReplace = 1; + break; + } + } + sqlite3VdbeResolveLabel(v, addrUniqueOk); + if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); + if( pUpsertClause + && upsertIpkReturn + && sqlite3UpsertNextIsIPK(pUpsertClause) + ){ + sqlite3VdbeGoto(v, upsertIpkDelay+1); + sqlite3VdbeJumpHere(v, upsertIpkReturn); + upsertIpkReturn = 0; + } + } + + /* If the IPK constraint is a REPLACE, run it last */ + if( ipkTop ){ + sqlite3VdbeGoto(v, ipkTop); + VdbeComment((v, "Do IPK REPLACE")); + assert( ipkBottom>0 ); + sqlite3VdbeJumpHere(v, ipkBottom); + } + + /* Recheck all uniqueness constraints after replace triggers have run */ + testcase( regTrigCnt!=0 && nReplaceTrig==0 ); + assert( regTrigCnt!=0 || nReplaceTrig==0 ); + if( nReplaceTrig ){ + sqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v); + if( !pPk ){ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, OE_Abort, pTab); + }else{ + sqlite3VdbeGoto(v, addrRecheck); + } + sqlite3VdbeResolveLabel(v, lblRecheckOk); + } + + /* Generate the table record */ + if( HasRowid(pTab) ){ + int regRec = aRegIdx[ix]; + sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec); + sqlite3SetMakeRecordP5(v, pTab); + if( !bAffinityDone ){ + sqlite3TableAffinity(v, pTab, 0); + } + } + + *pbMayReplace = seenReplace; + VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); +} + +#ifdef SQLITE_ENABLE_NULL_TRIM +/* +** Change the P5 operand on the last opcode (which should be an OP_MakeRecord) +** to be the number of columns in table pTab that must not be NULL-trimmed. +** +** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero. +*/ +SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ + u16 i; + + /* Records with omitted columns are only allowed for schema format + ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */ + if( pTab->pSchema->file_format<2 ) return; + + for(i=pTab->nCol-1; i>0; i--){ + if( pTab->aCol[i].iDflt!=0 ) break; + if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break; + } + sqlite3VdbeChangeP5(v, i+1); +} +#endif + +/* +** Table pTab is a WITHOUT ROWID table that is being written to. The cursor +** number is iCur, and register regData contains the new record for the +** PK index. This function adds code to invoke the pre-update hook, +** if one is registered. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +static void codeWithoutRowidPreupdate( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated */ + int iCur, /* Cursor number for table */ + int regData /* Data containing new record */ +){ + Vdbe *v = pParse->pVdbe; + int r = sqlite3GetTempReg(pParse); + assert( !HasRowid(pTab) ); + assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) || CORRUPT_DB ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); +} +#else +# define codeWithoutRowidPreupdate(a,b,c,d) +#endif + +/* +** This routine generates code to finish the INSERT or UPDATE operation +** that was started by a prior call to sqlite3GenerateConstraintChecks. +** A consecutive range of registers starting at regNewData contains the +** rowid and the content to be inserted. +** +** The arguments to this routine should be the same as the first six +** arguments to sqlite3GenerateConstraintChecks. +*/ +SQLITE_PRIVATE void sqlite3CompleteInsertion( + Parse *pParse, /* The parser context */ + Table *pTab, /* the table into which we are inserting */ + int iDataCur, /* Cursor of the canonical data source */ + int iIdxCur, /* First index cursor */ + int regNewData, /* Range of content */ + int *aRegIdx, /* Register used by each index. 0 for unused indices */ + int update_flags, /* True for UPDATE, False for INSERT */ + int appendBias, /* True if this is likely to be an append */ + int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ +){ + Vdbe *v; /* Prepared statements under construction */ + Index *pIdx; /* An index being inserted or updated */ + u8 pik_flags; /* flag values passed to the btree insert */ + int i; /* Loop counter */ + + assert( update_flags==0 + || update_flags==OPFLAG_ISUPDATE + || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION) + ); + + v = pParse->pVdbe; + assert( v!=0 ); + assert( !IsView(pTab) ); /* This table is not a VIEW */ + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + /* All REPLACE indexes are at the end of the list */ + assert( pIdx->onError!=OE_Replace + || pIdx->pNext==0 + || pIdx->pNext->onError==OE_Replace ); + if( aRegIdx[i]==0 ) continue; + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + } + pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + pik_flags |= OPFLAG_NCHANGE; + pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); + if( update_flags==0 ){ + codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]); + } + } + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], + aRegIdx[i]+1, + pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn); + sqlite3VdbeChangeP5(v, pik_flags); + } + if( !HasRowid(pTab) ) return; + if( pParse->nested ){ + pik_flags = 0; + }else{ + pik_flags = OPFLAG_NCHANGE; + pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID); + } + if( appendBias ){ + pik_flags |= OPFLAG_APPEND; + } + if( useSeekResult ){ + pik_flags |= OPFLAG_USESEEKRESULT; + } + sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData); + if( !pParse->nested ){ + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } + sqlite3VdbeChangeP5(v, pik_flags); +} + +/* +** Allocate cursors for the pTab table and all its indices and generate +** code to open and initialized those cursors. +** +** The cursor for the object that contains the complete data (normally +** the table itself, but the PRIMARY KEY index in the case of a WITHOUT +** ROWID table) is returned in *piDataCur. The first index cursor is +** returned in *piIdxCur. The number of indices is returned. +** +** Use iBase as the first cursor (either the *piDataCur for rowid tables +** or the first index for WITHOUT ROWID tables) if it is non-negative. +** If iBase is negative, then allocate the next available cursor. +** +** For a rowid table, *piDataCur will be exactly one less than *piIdxCur. +** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range +** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the +** pTab->pIndex list. +** +** If pTab is a virtual table, then this routine is a no-op and the +** *piDataCur and *piIdxCur values are left uninitialized. +*/ +SQLITE_PRIVATE int sqlite3OpenTableAndIndices( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table to be opened */ + int op, /* OP_OpenRead or OP_OpenWrite */ + u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */ + int iBase, /* Use this for the table cursor, if there is one */ + u8 *aToOpen, /* If not NULL: boolean for each table and index */ + int *piDataCur, /* Write the database source cursor number here */ + int *piIdxCur /* Write the first index cursor number here */ +){ + int i; + int iDb; + int iDataCur; + Index *pIdx; + Vdbe *v; + + assert( op==OP_OpenRead || op==OP_OpenWrite ); + assert( op==OP_OpenWrite || p5==0 ); + assert( piDataCur!=0 ); + assert( piIdxCur!=0 ); + if( IsVirtual(pTab) ){ + /* This routine is a no-op for virtual tables. Leave the output + ** variables *piDataCur and *piIdxCur set to illegal cursor numbers + ** for improved error detection. */ + *piDataCur = *piIdxCur = -999; + return 0; + } + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + v = pParse->pVdbe; + assert( v!=0 ); + if( iBase<0 ) iBase = pParse->nTab; + iDataCur = iBase++; + *piDataCur = iDataCur; + if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ + sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); + }else if( pParse->db->noSharedCache==0 ){ + sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); + } + *piIdxCur = iBase; + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + int iIdxCur = iBase++; + assert( pIdx->pSchema==pTab->pSchema ); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + *piDataCur = iIdxCur; + p5 = 0; + } + if( aToOpen==0 || aToOpen[i+1] ){ + sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeChangeP5(v, p5); + VdbeComment((v, "%s", pIdx->zName)); + } + } + if( iBase>pParse->nTab ) pParse->nTab = iBase; + return i; +} + + +#ifdef SQLITE_TEST +/* +** The following global variable is incremented whenever the +** transfer optimization is used. This is used for testing +** purposes only - to make sure the transfer optimization really +** is happening when it is supposed to. +*/ +SQLITE_API int sqlite3_xferopt_count; +#endif /* SQLITE_TEST */ + + +#ifndef SQLITE_OMIT_XFER_OPT +/* +** Check to see if index pSrc is compatible as a source of data +** for index pDest in an insert transfer optimization. The rules +** for a compatible index: +** +** * The index is over the same set of columns +** * The same DESC and ASC markings occurs on all columns +** * The same onError processing (OE_Abort, OE_Ignore, etc) +** * The same collating sequence on each column +** * The index has the exact same WHERE clause +*/ +static int xferCompatibleIndex(Index *pDest, Index *pSrc){ + int i; + assert( pDest && pSrc ); + assert( pDest->pTable!=pSrc->pTable ); + if( pDest->nKeyCol!=pSrc->nKeyCol || pDest->nColumn!=pSrc->nColumn ){ + return 0; /* Different number of columns */ + } + if( pDest->onError!=pSrc->onError ){ + return 0; /* Different conflict resolution strategies */ + } + for(i=0; inKeyCol; i++){ + if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ + return 0; /* Different columns indexed */ + } + if( pSrc->aiColumn[i]==XN_EXPR ){ + assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 ); + if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr, + pDest->aColExpr->a[i].pExpr, -1)!=0 ){ + return 0; /* Different expressions in the index */ + } + } + if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ + return 0; /* Different sort orders */ + } + if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){ + return 0; /* Different collating sequences */ + } + } + if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ + return 0; /* Different WHERE clauses */ + } + + /* If no test above fails then the indices must be compatible */ + return 1; +} + +/* +** Attempt the transfer optimization on INSERTs of the form +** +** INSERT INTO tab1 SELECT * FROM tab2; +** +** The xfer optimization transfers raw records from tab2 over to tab1. +** Columns are not decoded and reassembled, which greatly improves +** performance. Raw index records are transferred in the same way. +** +** The xfer optimization is only attempted if tab1 and tab2 are compatible. +** There are lots of rules for determining compatibility - see comments +** embedded in the code for details. +** +** This routine returns TRUE if the optimization is guaranteed to be used. +** Sometimes the xfer optimization will only work if the destination table +** is empty - a factor that can only be determined at run-time. In that +** case, this routine generates code for the xfer optimization but also +** does a test to see if the destination table is empty and jumps over the +** xfer optimization code if the test fails. In that case, this routine +** returns FALSE so that the caller will know to go ahead and generate +** an unoptimized transfer. This routine also returns FALSE if there +** is no chance that the xfer optimization can be applied. +** +** This optimization is particularly useful at making VACUUM run faster. +*/ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +){ + sqlite3 *db = pParse->db; + ExprList *pEList; /* The result set of the SELECT */ + Table *pSrc; /* The table in the FROM clause of SELECT */ + Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ + SrcItem *pItem; /* An element of pSelect->pSrc */ + int i; /* Loop counter */ + int iDbSrc; /* The database of pSrc */ + int iSrc, iDest; /* Cursors from source and destination */ + int addr1, addr2; /* Loop addresses */ + int emptyDestTest = 0; /* Address of test for empty pDest */ + int emptySrcTest = 0; /* Address of test for empty pSrc */ + Vdbe *v; /* The VDBE we are building */ + int regAutoinc; /* Memory register used by AUTOINC */ + int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ + int regData, regRowid; /* Registers holding data and rowid */ + + assert( pSelect!=0 ); + if( pParse->pWith || pSelect->pWith ){ + /* Do not attempt to process this query if there are an WITH clauses + ** attached to it. Proceeding may generate a false "no such table: xxx" + ** error if pSelect reads from a CTE named "xxx". */ + return 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pDest) ){ + return 0; /* tab1 must not be a virtual table */ + } +#endif + if( onError==OE_Default ){ + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; + } + assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ + if( pSelect->pSrc->nSrc!=1 ){ + return 0; /* FROM clause must have exactly one term */ + } + if( pSelect->pSrc->a[0].pSelect ){ + return 0; /* FROM clause cannot contain a subquery */ + } + if( pSelect->pWhere ){ + return 0; /* SELECT may not have a WHERE clause */ + } + if( pSelect->pOrderBy ){ + return 0; /* SELECT may not have an ORDER BY clause */ + } + /* Do not need to test for a HAVING clause. If HAVING is present but + ** there is no ORDER BY, we will get an error. */ + if( pSelect->pGroupBy ){ + return 0; /* SELECT may not have a GROUP BY clause */ + } + if( pSelect->pLimit ){ + return 0; /* SELECT may not have a LIMIT clause */ + } + if( pSelect->pPrior ){ + return 0; /* SELECT may not be a compound query */ + } + if( pSelect->selFlags & SF_Distinct ){ + return 0; /* SELECT may not be DISTINCT */ + } + pEList = pSelect->pEList; + assert( pEList!=0 ); + if( pEList->nExpr!=1 ){ + return 0; /* The result set must have exactly one column */ + } + assert( pEList->a[0].pExpr ); + if( pEList->a[0].pExpr->op!=TK_ASTERISK ){ + return 0; /* The result set must be the special operator "*" */ + } + + /* At this point we have established that the statement is of the + ** correct syntactic form to participate in this optimization. Now + ** we have to check the semantics. + */ + pItem = pSelect->pSrc->a; + pSrc = sqlite3LocateTableItem(pParse, 0, pItem); + if( pSrc==0 ){ + return 0; /* FROM clause does not contain a real table */ + } + if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){ + testcase( pSrc!=pDest ); /* Possible due to bad sqlite_schema.rootpage */ + return 0; /* tab1 and tab2 may not be the same table */ + } + if( HasRowid(pDest)!=HasRowid(pSrc) ){ + return 0; /* source and destination must both be WITHOUT ROWID or not */ + } + if( !IsOrdinaryTable(pSrc) ){ + return 0; /* tab2 may not be a view or virtual table */ + } + if( pDest->nCol!=pSrc->nCol ){ + return 0; /* Number of columns must be the same in tab1 and tab2 */ + } + if( pDest->iPKey!=pSrc->iPKey ){ + return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ + } + if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){ + return 0; /* Cannot feed from a non-strict into a strict table */ + } + for(i=0; inCol; i++){ + Column *pDestCol = &pDest->aCol[i]; + Column *pSrcCol = &pSrc->aCol[i]; +#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN + ){ + return 0; /* Neither table may have __hidden__ columns */ + } +#endif +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Even if tables t1 and t2 have identical schemas, if they contain + ** generated columns, then this statement is semantically incorrect: + ** + ** INSERT INTO t2 SELECT * FROM t1; + ** + ** The reason is that generated column values are returned by the + ** the SELECT statement on the right but the INSERT statement on the + ** left wants them to be omitted. + ** + ** Nevertheless, this is a useful notational shorthand to tell SQLite + ** to do a bulk transfer all of the content from t1 over to t2. + ** + ** We could, in theory, disable this (except for internal use by the + ** VACUUM command where it is actually needed). But why do that? It + ** seems harmless enough, and provides a useful service. + */ + if( (pDestCol->colFlags & COLFLAG_GENERATED) != + (pSrcCol->colFlags & COLFLAG_GENERATED) ){ + return 0; /* Both columns have the same generated-column type */ + } + /* But the transfer is only allowed if both the source and destination + ** tables have the exact same expressions for generated columns. + ** This requirement could be relaxed for VIRTUAL columns, I suppose. + */ + if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ + if( sqlite3ExprCompare(0, + sqlite3ColumnExpr(pSrc, pSrcCol), + sqlite3ColumnExpr(pDest, pDestCol), -1)!=0 ){ + testcase( pDestCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pDestCol->colFlags & COLFLAG_STORED ); + return 0; /* Different generator expressions */ + } + } +#endif + if( pDestCol->affinity!=pSrcCol->affinity ){ + return 0; /* Affinity must be the same on all columns */ + } + if( sqlite3_stricmp(sqlite3ColumnColl(pDestCol), + sqlite3ColumnColl(pSrcCol))!=0 ){ + return 0; /* Collating sequence must be the same on all columns */ + } + if( pDestCol->notNull && !pSrcCol->notNull ){ + return 0; /* tab2 must be NOT NULL if tab1 is */ + } + /* Default values for second and subsequent columns need to match. */ + if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){ + Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol); + Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol); + assert( pDestExpr==0 || pDestExpr->op==TK_SPAN ); + assert( pDestExpr==0 || !ExprHasProperty(pDestExpr, EP_IntValue) ); + assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN ); + assert( pSrcExpr==0 || !ExprHasProperty(pSrcExpr, EP_IntValue) ); + if( (pDestExpr==0)!=(pSrcExpr==0) + || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken, + pSrcExpr->u.zToken)!=0) + ){ + return 0; /* Default values must be the same for all columns */ + } + } + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + if( IsUniqueIndex(pDestIdx) ){ + destHasUniqueIdx = 1; + } + for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + if( pSrcIdx==0 ){ + return 0; /* pDestIdx has no corresponding index in pSrc */ + } + if( pSrcIdx->tnum==pDestIdx->tnum && pSrc->pSchema==pDest->pSchema + && sqlite3FaultSim(411)==SQLITE_OK ){ + /* The sqlite3FaultSim() call allows this corruption test to be + ** bypassed during testing, in order to exercise other corruption tests + ** further downstream. */ + return 0; /* Corrupt schema - two indexes on the same btree */ + } + } +#ifndef SQLITE_OMIT_CHECK + if( pDest->pCheck + && (db->mDbFlags & DBFLAG_Vacuum)==0 + && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) + ){ + return 0; /* Tables have different CHECK constraints. Ticket #2252 */ + } +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + /* Disallow the transfer optimization if the destination table contains + ** any foreign key constraints. This is more restrictive than necessary. + ** But the main beneficiary of the transfer optimization is the VACUUM + ** command, and the VACUUM command disables foreign key constraints. So + ** the extra complication to make this rule less restrictive is probably + ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] + */ + assert( IsOrdinaryTable(pDest) ); + if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){ + return 0; + } +#endif + if( (db->flags & SQLITE_CountRows)!=0 ){ + return 0; /* xfer opt does not play well with PRAGMA count_changes */ + } + + /* If we get this far, it means that the xfer optimization is at + ** least a possibility, though it might only work if the destination + ** table (tab1) is initially empty. + */ +#ifdef SQLITE_TEST + sqlite3_xferopt_count++; +#endif + iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema); + v = sqlite3GetVdbe(pParse); + sqlite3CodeVerifySchema(pParse, iDbSrc); + iSrc = pParse->nTab++; + iDest = pParse->nTab++; + regAutoinc = autoIncBegin(pParse, iDbDest, pDest); + regData = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, regData); + regRowid = sqlite3GetTempReg(pParse); + sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); + assert( HasRowid(pDest) || destHasUniqueIdx ); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 && ( + (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + )){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. Unless the + ** DBFLAG_Vacuum flag is set, this block generates code to make + ** that determination. If DBFLAG_Vacuum is set, then the destination + ** table is always empty. + ** + ** Conditions under which the destination must be empty: + ** + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. + */ + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); + emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, addr1); + } + if( HasRowid(pSrc) ){ + u8 insFlags; + sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); + emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + if( pDest->iPKey>=0 ){ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeVerifyAbortable(v, onError); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); + } + autoIncStep(pParse, regAutoinc, regRowid); + }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ + addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); + }else{ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + assert( (pDest->tabFlags & TF_Autoincrement)==0 ); + } + + if( db->mDbFlags & DBFLAG_Vacuum ){ + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; + }else{ + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; + } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; + }else +#endif + { + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + } + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE); + } + sqlite3VdbeChangeP5(v, insFlags); + + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + }else{ + sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName); + sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + u8 idxInsFlags = 0; + for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + assert( pSrcIdx ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc); + sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx); + VdbeComment((v, "%s", pSrcIdx->zName)); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest); + sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); + VdbeComment((v, "%s", pDestIdx->zName)); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + if( db->mDbFlags & DBFLAG_Vacuum ){ + /* This INSERT command is part of a VACUUM operation, which guarantees + ** that the destination table is empty. If all indexed columns use + ** collation sequence BINARY, then it can also be assumed that the + ** index will be populated by inserting keys in strictly sorted + ** order. In this case, instead of seeking within the b-tree as part + ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the + ** OP_IdxInsert to seek to the point within the b-tree where each key + ** should be inserted. This is faster. + ** + ** If any of the indexed columns use a collation sequence other than + ** BINARY, this optimization is disabled. This is because the user + ** might change the definition of a collation sequence and then run + ** a VACUUM command. In that case keys may not be written in strictly + ** sorted order. */ + for(i=0; inColumn; i++){ + const char *zColl = pSrcIdx->azColl[i]; + if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; + } + if( i==pSrcIdx->nColumn ){ + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); + } + }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ + idxInsFlags |= OPFLAG_NCHANGE; + } + if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && !HasRowid(pDest) + && IsPrimaryKeyIndex(pDestIdx) + ){ + codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); + } + } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + } + if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regData); + if( emptyDestTest ){ + sqlite3AutoincrementEnd(pParse); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); + sqlite3VdbeJumpHere(v, emptyDestTest); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + return 0; + }else{ + return 1; + } +} +#endif /* SQLITE_OMIT_XFER_OPT */ + +/************** End of insert.c **********************************************/ +/************** Begin file legacy.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Main file for the SQLite library. The routines in this file +** implement the programmer interface to the library. Routines in +** other files are for internal use by SQLite and should not be +** accessed by users of the library. +*/ + +/* #include "sqliteInt.h" */ + +/* +** Execute SQL code. Return one of the SQLITE_ success/failure +** codes. Also write an error message into memory obtained from +** malloc() and make *pzErrMsg point to that message. +** +** If the SQL is a query, then for each row in the query result +** the xCallback() function is called. pArg becomes the first +** argument to xCallback(). If xCallback=NULL then no callback +** is invoked, even for queries. +*/ +SQLITE_API int sqlite3_exec( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + sqlite3_callback xCallback, /* Invoke this callback routine */ + void *pArg, /* First argument to xCallback() */ + char **pzErrMsg /* Write error messages here */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zLeftover; /* Tail of unprocessed SQL */ + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ + char **azCols = 0; /* Names of result columns */ + int callbackIsInit; /* True if callback data is initialized */ + + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( zSql==0 ) zSql = ""; + + sqlite3_mutex_enter(db->mutex); + sqlite3Error(db, SQLITE_OK); + while( rc==SQLITE_OK && zSql[0] ){ + int nCol = 0; + char **azVals = 0; + + pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); + assert( rc==SQLITE_OK || pStmt==0 ); + if( rc!=SQLITE_OK ){ + continue; + } + if( !pStmt ){ + /* this happens for a comment or white-space */ + zSql = zLeftover; + continue; + } + callbackIsInit = 0; + + while( 1 ){ + int i; + rc = sqlite3_step(pStmt); + + /* Invoke the callback function if required */ + if( xCallback && (SQLITE_ROW==rc || + (SQLITE_DONE==rc && !callbackIsInit + && db->flags&SQLITE_NullCallback)) ){ + if( !callbackIsInit ){ + nCol = sqlite3_column_count(pStmt); + azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); + if( azCols==0 ){ + goto exec_out; + } + for(i=0; ierrMask)==rc ); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/************** End of legacy.c **********************************************/ +/************** Begin file loadext.c *****************************************/ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to dynamically load extensions into +** the SQLite library. +*/ + +#ifndef SQLITE_CORE + #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#endif +/************** Include sqlite3ext.h in the middle of loadext.c **************/ +/************** Begin file sqlite3ext.h **************************************/ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +*/ +#ifndef SQLITE3EXT_H +#define SQLITE3EXT_H +/* #include "sqlite3.h" */ + +/* +** The following structure holds pointers to all of the SQLite API +** routines. +** +** WARNING: In order to maintain backwards compatibility, add new +** interfaces to the end of this structure only. If you insert new +** interfaces in the middle of this structure, then older different +** versions of SQLite will not be able to load each other's shared +** libraries! +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const void*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, + const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*xsnprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, + char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, + sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char *(*vmprintf)(const char*,va_list); + /* Added ??? */ + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); + /* Added by 3.3.13 */ + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); + /* Added by 3.4.1 */ + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, + void (*xDestroy)(void *)); + /* Added by 3.5.0 */ + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, + int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*), + void(*)(void*)); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); + int (*release_memory)(int); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); + int (*sleep)(int); + void (*soft_heap_limit)(int); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); + int (*extended_result_codes)(sqlite3*,int); + int (*limit)(sqlite3*,int,int); + sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); + const char *(*sql)(sqlite3_stmt*); + int (*status)(int,int*,int*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); + const char *(*compileoption_get)(int); + int (*compileoption_used)(const char*); + int (*create_function_v2)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*)); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); + void (*log)(int,const char*,...); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); + const char *(*sourceid)(void); + int (*stmt_status)(sqlite3_stmt*,int,int); + int (*strnicmp)(const char*,const char*,int); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); + /* Version 3.7.16 and later */ + int (*close_v2)(sqlite3*); + const char *(*db_filename)(sqlite3*,const char*); + int (*db_readonly)(sqlite3*,const char*); + int (*db_release_memory)(sqlite3*); + const char *(*errstr)(int); + int (*stmt_busy)(sqlite3_stmt*); + int (*stmt_readonly)(sqlite3_stmt*); + int (*stricmp)(const char*,const char*); + int (*uri_boolean)(const char*,const char*,int); + sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); + const char *(*uri_parameter)(const char*,const char*); + char *(*xvsnprintf)(int,char*,const char*,va_list); + int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); + /* Version 3.8.7 and later */ + int (*auto_extension)(void(*)(void)); + int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, + void(*)(void*)); + int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, + void(*)(void*),unsigned char); + int (*cancel_auto_extension)(void(*)(void)); + int (*load_extension)(sqlite3*,const char*,const char*,char**); + void *(*malloc64)(sqlite3_uint64); + sqlite3_uint64 (*msize)(void*); + void *(*realloc64)(void*,sqlite3_uint64); + void (*reset_auto_extension)(void); + void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, + void(*)(void*)); + void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, + void(*)(void*), unsigned char); + int (*strglob)(const char*,const char*); + /* Version 3.8.11 and later */ + sqlite3_value *(*value_dup)(const sqlite3_value*); + void (*value_free)(sqlite3_value*); + int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); + int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); + /* Version 3.9.0 and later */ + unsigned int (*value_subtype)(sqlite3_value*); + void (*result_subtype)(sqlite3_context*,unsigned int); + /* Version 3.10.0 and later */ + int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); + int (*strlike)(const char*,const char*,unsigned int); + int (*db_cacheflush)(sqlite3*); + /* Version 3.12.0 and later */ + int (*system_errno)(sqlite3*); + /* Version 3.14.0 and later */ + int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); + char *(*expanded_sql)(sqlite3_stmt*); + /* Version 3.18.0 and later */ + void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); + /* Version 3.20.0 and later */ + int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, + sqlite3_stmt**,const char**); + int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, + sqlite3_stmt**,const void**); + int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); + void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); + void *(*value_pointer)(sqlite3_value*,const char*); + int (*vtab_nochange)(sqlite3_context*); + int (*value_nochange)(sqlite3_value*); + const char *(*vtab_collation)(sqlite3_index_info*,int); + /* Version 3.24.0 and later */ + int (*keyword_count)(void); + int (*keyword_name)(int,const char**,int*); + int (*keyword_check)(const char*,int); + sqlite3_str *(*str_new)(sqlite3*); + char *(*str_finish)(sqlite3_str*); + void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); + void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); + void (*str_append)(sqlite3_str*, const char *zIn, int N); + void (*str_appendall)(sqlite3_str*, const char *zIn); + void (*str_appendchar)(sqlite3_str*, int N, char C); + void (*str_reset)(sqlite3_str*); + int (*str_errcode)(sqlite3_str*); + int (*str_length)(sqlite3_str*); + char *(*str_value)(sqlite3_str*); + /* Version 3.25.0 and later */ + int (*create_window_function)(sqlite3*,const char*,int,int,void*, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInv)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*)); + /* Version 3.26.0 and later */ + const char *(*normalized_sql)(sqlite3_stmt*); + /* Version 3.28.0 and later */ + int (*stmt_isexplain)(sqlite3_stmt*); + int (*value_frombind)(sqlite3_value*); + /* Version 3.30.0 and later */ + int (*drop_modules)(sqlite3*,const char**); + /* Version 3.31.0 and later */ + sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64); + const char *(*uri_key)(const char*,int); + const char *(*filename_database)(const char*); + const char *(*filename_journal)(const char*); + const char *(*filename_wal)(const char*); + /* Version 3.32.0 and later */ + const char *(*create_filename)(const char*,const char*,const char*, + int,const char**); + void (*free_filename)(const char*); + sqlite3_file *(*database_file_object)(const char*); + /* Version 3.34.0 and later */ + int (*txn_state)(sqlite3*,const char*); + /* Version 3.36.1 and later */ + sqlite3_int64 (*changes64)(sqlite3*); + sqlite3_int64 (*total_changes64)(sqlite3*); + /* Version 3.37.0 and later */ + int (*autovacuum_pages)(sqlite3*, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, void(*)(void*)); + /* Version 3.38.0 and later */ + int (*error_offset)(sqlite3*); + int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); + int (*vtab_distinct)(sqlite3_index_info*); + int (*vtab_in)(sqlite3_index_info*,int,int); + int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); + int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); + /* Version 3.39.0 and later */ + int (*deserialize)(sqlite3*,const char*,unsigned char*, + sqlite3_int64,sqlite3_int64,unsigned); + unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, + unsigned int); + const char *(*db_name)(sqlite3*,int); + /* Version 3.40.0 and later */ + int (*value_encoding)(sqlite3_value*); + /* Version 3.41.0 and later */ + int (*is_interrupted)(sqlite3*); + /* Version 3.43.0 and later */ + int (*stmt_explain)(sqlite3_stmt*,int); + /* Version 3.44.0 and later */ + void *(*get_clientdata)(sqlite3*,const char*); + int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); +}; + +/* +** This is the function signature used for all extension entry points. It +** is also defined in the file "loadext.c". +*/ +typedef int (*sqlite3_loadext_entry)( + sqlite3 *db, /* Handle to the database. */ + char **pzErrMsg, /* Used to set error string on failure. */ + const sqlite3_api_routines *pThunk /* Extension API function pointers. */ +); + +/* +** The following macros redefine the API routines so that they are +** redirected through the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#endif +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_expired sqlite3_api->expired +#endif +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_global_recover sqlite3_api->global_recover +#endif +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->xsnprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#endif +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_vsnprintf sqlite3_api->xvsnprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle +#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes +#define sqlite3_limit sqlite3_api->limit +#define sqlite3_next_stmt sqlite3_api->next_stmt +#define sqlite3_sql sqlite3_api->sql +#define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict +/* Version 3.7.16 and later */ +#define sqlite3_close_v2 sqlite3_api->close_v2 +#define sqlite3_db_filename sqlite3_api->db_filename +#define sqlite3_db_readonly sqlite3_api->db_readonly +#define sqlite3_db_release_memory sqlite3_api->db_release_memory +#define sqlite3_errstr sqlite3_api->errstr +#define sqlite3_stmt_busy sqlite3_api->stmt_busy +#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly +#define sqlite3_stricmp sqlite3_api->stricmp +#define sqlite3_uri_boolean sqlite3_api->uri_boolean +#define sqlite3_uri_int64 sqlite3_api->uri_int64 +#define sqlite3_uri_parameter sqlite3_api->uri_parameter +#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf +#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 +/* Version 3.8.7 and later */ +#define sqlite3_auto_extension sqlite3_api->auto_extension +#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 +#define sqlite3_bind_text64 sqlite3_api->bind_text64 +#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension +#define sqlite3_load_extension sqlite3_api->load_extension +#define sqlite3_malloc64 sqlite3_api->malloc64 +#define sqlite3_msize sqlite3_api->msize +#define sqlite3_realloc64 sqlite3_api->realloc64 +#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension +#define sqlite3_result_blob64 sqlite3_api->result_blob64 +#define sqlite3_result_text64 sqlite3_api->result_text64 +#define sqlite3_strglob sqlite3_api->strglob +/* Version 3.8.11 and later */ +#define sqlite3_value_dup sqlite3_api->value_dup +#define sqlite3_value_free sqlite3_api->value_free +#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 +#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 +/* Version 3.9.0 and later */ +#define sqlite3_value_subtype sqlite3_api->value_subtype +#define sqlite3_result_subtype sqlite3_api->result_subtype +/* Version 3.10.0 and later */ +#define sqlite3_status64 sqlite3_api->status64 +#define sqlite3_strlike sqlite3_api->strlike +#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush +/* Version 3.12.0 and later */ +#define sqlite3_system_errno sqlite3_api->system_errno +/* Version 3.14.0 and later */ +#define sqlite3_trace_v2 sqlite3_api->trace_v2 +#define sqlite3_expanded_sql sqlite3_api->expanded_sql +/* Version 3.18.0 and later */ +#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid +/* Version 3.20.0 and later */ +#define sqlite3_prepare_v3 sqlite3_api->prepare_v3 +#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 +#define sqlite3_bind_pointer sqlite3_api->bind_pointer +#define sqlite3_result_pointer sqlite3_api->result_pointer +#define sqlite3_value_pointer sqlite3_api->value_pointer +/* Version 3.22.0 and later */ +#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange +#define sqlite3_value_nochange sqlite3_api->value_nochange +#define sqlite3_vtab_collation sqlite3_api->vtab_collation +/* Version 3.24.0 and later */ +#define sqlite3_keyword_count sqlite3_api->keyword_count +#define sqlite3_keyword_name sqlite3_api->keyword_name +#define sqlite3_keyword_check sqlite3_api->keyword_check +#define sqlite3_str_new sqlite3_api->str_new +#define sqlite3_str_finish sqlite3_api->str_finish +#define sqlite3_str_appendf sqlite3_api->str_appendf +#define sqlite3_str_vappendf sqlite3_api->str_vappendf +#define sqlite3_str_append sqlite3_api->str_append +#define sqlite3_str_appendall sqlite3_api->str_appendall +#define sqlite3_str_appendchar sqlite3_api->str_appendchar +#define sqlite3_str_reset sqlite3_api->str_reset +#define sqlite3_str_errcode sqlite3_api->str_errcode +#define sqlite3_str_length sqlite3_api->str_length +#define sqlite3_str_value sqlite3_api->str_value +/* Version 3.25.0 and later */ +#define sqlite3_create_window_function sqlite3_api->create_window_function +/* Version 3.26.0 and later */ +#define sqlite3_normalized_sql sqlite3_api->normalized_sql +/* Version 3.28.0 and later */ +#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain +#define sqlite3_value_frombind sqlite3_api->value_frombind +/* Version 3.30.0 and later */ +#define sqlite3_drop_modules sqlite3_api->drop_modules +/* Version 3.31.0 and later */ +#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64 +#define sqlite3_uri_key sqlite3_api->uri_key +#define sqlite3_filename_database sqlite3_api->filename_database +#define sqlite3_filename_journal sqlite3_api->filename_journal +#define sqlite3_filename_wal sqlite3_api->filename_wal +/* Version 3.32.0 and later */ +#define sqlite3_create_filename sqlite3_api->create_filename +#define sqlite3_free_filename sqlite3_api->free_filename +#define sqlite3_database_file_object sqlite3_api->database_file_object +/* Version 3.34.0 and later */ +#define sqlite3_txn_state sqlite3_api->txn_state +/* Version 3.36.1 and later */ +#define sqlite3_changes64 sqlite3_api->changes64 +#define sqlite3_total_changes64 sqlite3_api->total_changes64 +/* Version 3.37.0 and later */ +#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +/* Version 3.38.0 and later */ +#define sqlite3_error_offset sqlite3_api->error_offset +#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value +#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct +#define sqlite3_vtab_in sqlite3_api->vtab_in +#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first +#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next +/* Version 3.39.0 and later */ +#ifndef SQLITE_OMIT_DESERIALIZE +#define sqlite3_deserialize sqlite3_api->deserialize +#define sqlite3_serialize sqlite3_api->serialize +#endif +#define sqlite3_db_name sqlite3_api->db_name +/* Version 3.40.0 and later */ +#define sqlite3_value_encoding sqlite3_api->value_encoding +/* Version 3.41.0 and later */ +#define sqlite3_is_interrupted sqlite3_api->is_interrupted +/* Version 3.43.0 and later */ +#define sqlite3_stmt_explain sqlite3_api->stmt_explain +/* Version 3.44.0 and later */ +#define sqlite3_get_clientdata sqlite3_api->get_clientdata +#define sqlite3_set_clientdata sqlite3_api->set_clientdata +#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + +#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) + /* This case when the file really is being compiled as a loadable + ** extension */ +# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; +# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; +# define SQLITE_EXTENSION_INIT3 \ + extern const sqlite3_api_routines *sqlite3_api; +#else + /* This case when the file is being statically linked into the + ** application */ +# define SQLITE_EXTENSION_INIT1 /*no-op*/ +# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ +# define SQLITE_EXTENSION_INIT3 /*no-op*/ +#endif + +#endif /* SQLITE3EXT_H */ + +/************** End of sqlite3ext.h ******************************************/ +/************** Continuing where we left off in loadext.c ********************/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Some API routines are omitted when various features are +** excluded from a build of SQLite. Substitute a NULL pointer +** for any missing APIs. +*/ +#ifndef SQLITE_ENABLE_COLUMN_METADATA +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_AUTHORIZATION +# define sqlite3_set_authorizer 0 +#endif + +#ifdef SQLITE_OMIT_UTF16 +# define sqlite3_bind_text16 0 +# define sqlite3_collation_needed16 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_name16 0 +# define sqlite3_column_text16 0 +# define sqlite3_complete16 0 +# define sqlite3_create_collation16 0 +# define sqlite3_create_function16 0 +# define sqlite3_errmsg16 0 +# define sqlite3_open16 0 +# define sqlite3_prepare16 0 +# define sqlite3_prepare16_v2 0 +# define sqlite3_prepare16_v3 0 +# define sqlite3_result_error16 0 +# define sqlite3_result_text16 0 +# define sqlite3_result_text16be 0 +# define sqlite3_result_text16le 0 +# define sqlite3_value_text16 0 +# define sqlite3_value_text16be 0 +# define sqlite3_value_text16le 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_COMPLETE +# define sqlite3_complete 0 +# define sqlite3_complete16 0 +#endif + +#ifdef SQLITE_OMIT_DECLTYPE +# define sqlite3_column_decltype16 0 +# define sqlite3_column_decltype 0 +#endif + +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK +# define sqlite3_progress_handler 0 +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3_create_module 0 +# define sqlite3_create_module_v2 0 +# define sqlite3_declare_vtab 0 +# define sqlite3_vtab_config 0 +# define sqlite3_vtab_on_conflict 0 +# define sqlite3_vtab_collation 0 +#endif + +#ifdef SQLITE_OMIT_SHARED_CACHE +# define sqlite3_enable_shared_cache 0 +#endif + +#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED) +# define sqlite3_profile 0 +# define sqlite3_trace 0 +#endif + +#ifdef SQLITE_OMIT_GET_TABLE +# define sqlite3_free_table 0 +# define sqlite3_get_table 0 +#endif + +#ifdef SQLITE_OMIT_INCRBLOB +#define sqlite3_bind_zeroblob 0 +#define sqlite3_blob_bytes 0 +#define sqlite3_blob_close 0 +#define sqlite3_blob_open 0 +#define sqlite3_blob_read 0 +#define sqlite3_blob_write 0 +#define sqlite3_blob_reopen 0 +#endif + +#if defined(SQLITE_OMIT_TRACE) +# define sqlite3_trace_v2 0 +#endif + +/* +** The following structure contains pointers to all SQLite API routines. +** A pointer to this structure is passed into extensions when they are +** loaded so that the extension can make calls back into the SQLite +** library. +** +** When adding new APIs, add them to the bottom of this structure +** in order to preserve backwards compatibility. +** +** Extensions that use newer APIs should first call the +** sqlite3_libversion_number() to make sure that the API they +** intend to use is supported by the library. Extensions should +** also check to make sure that the pointer to the function is +** not NULL before calling it. +*/ +static const sqlite3_api_routines sqlite3Apis = { + sqlite3_aggregate_context, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_aggregate_count, +#else + 0, +#endif + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_bind_value, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_column_value, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_create_module, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_declare_vtab, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_expired, +#else + 0, +#endif + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + 0, /* Was sqlite3_global_recover(), but that function is deprecated */ + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_malloc, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_realloc, + sqlite3_reset, + sqlite3_result_blob, + sqlite3_result_double, + sqlite3_result_error, + sqlite3_result_error16, + sqlite3_result_int, + sqlite3_result_int64, + sqlite3_result_null, + sqlite3_result_text, + sqlite3_result_text16, + sqlite3_result_text16be, + sqlite3_result_text16le, + sqlite3_result_value, + sqlite3_rollback_hook, + sqlite3_set_authorizer, + sqlite3_set_auxdata, + sqlite3_snprintf, + sqlite3_step, + sqlite3_table_column_metadata, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_thread_cleanup, +#else + 0, +#endif + sqlite3_total_changes, + sqlite3_trace, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_transfer_bindings, +#else + 0, +#endif + sqlite3_update_hook, + sqlite3_user_data, + sqlite3_value_blob, + sqlite3_value_bytes, + sqlite3_value_bytes16, + sqlite3_value_double, + sqlite3_value_int, + sqlite3_value_int64, + sqlite3_value_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, + /* + ** The original API set ends here. All extensions can call any + ** of the APIs above provided that the pointer is not NULL. But + ** before calling APIs that follow, extension should check the + ** sqlite3_libversion_number() to make sure they are dealing with + ** a library that is new enough to support that API. + ************************************************************************* + */ + sqlite3_overload_function, + + /* + ** Added after 3.3.13 + */ + sqlite3_prepare_v2, + sqlite3_prepare16_v2, + sqlite3_clear_bindings, + + /* + ** Added for 3.4.1 + */ + sqlite3_create_module_v2, + + /* + ** Added for 3.5.0 + */ + sqlite3_bind_zeroblob, + sqlite3_blob_bytes, + sqlite3_blob_close, + sqlite3_blob_open, + sqlite3_blob_read, + sqlite3_blob_write, + sqlite3_create_collation_v2, + sqlite3_file_control, + sqlite3_memory_highwater, + sqlite3_memory_used, +#ifdef SQLITE_MUTEX_OMIT + 0, + 0, + 0, + 0, + 0, +#else + sqlite3_mutex_alloc, + sqlite3_mutex_enter, + sqlite3_mutex_free, + sqlite3_mutex_leave, + sqlite3_mutex_try, +#endif + sqlite3_open_v2, + sqlite3_release_memory, + sqlite3_result_error_nomem, + sqlite3_result_error_toobig, + sqlite3_sleep, + sqlite3_soft_heap_limit, + sqlite3_vfs_find, + sqlite3_vfs_register, + sqlite3_vfs_unregister, + + /* + ** Added for 3.5.8 + */ + sqlite3_threadsafe, + sqlite3_result_zeroblob, + sqlite3_result_error_code, + sqlite3_test_control, + sqlite3_randomness, + sqlite3_context_db_handle, + + /* + ** Added for 3.6.0 + */ + sqlite3_extended_result_codes, + sqlite3_limit, + sqlite3_next_stmt, + sqlite3_sql, + sqlite3_status, + + /* + ** Added for 3.7.4 + */ + sqlite3_backup_finish, + sqlite3_backup_init, + sqlite3_backup_pagecount, + sqlite3_backup_remaining, + sqlite3_backup_step, +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + sqlite3_compileoption_get, + sqlite3_compileoption_used, +#else + 0, + 0, +#endif + sqlite3_create_function_v2, + sqlite3_db_config, + sqlite3_db_mutex, + sqlite3_db_status, + sqlite3_extended_errcode, + sqlite3_log, + sqlite3_soft_heap_limit64, + sqlite3_sourceid, + sqlite3_stmt_status, + sqlite3_strnicmp, +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + sqlite3_unlock_notify, +#else + 0, +#endif +#ifndef SQLITE_OMIT_WAL + sqlite3_wal_autocheckpoint, + sqlite3_wal_checkpoint, + sqlite3_wal_hook, +#else + 0, + 0, + 0, +#endif + sqlite3_blob_reopen, + sqlite3_vtab_config, + sqlite3_vtab_on_conflict, + sqlite3_close_v2, + sqlite3_db_filename, + sqlite3_db_readonly, + sqlite3_db_release_memory, + sqlite3_errstr, + sqlite3_stmt_busy, + sqlite3_stmt_readonly, + sqlite3_stricmp, + sqlite3_uri_boolean, + sqlite3_uri_int64, + sqlite3_uri_parameter, + sqlite3_vsnprintf, + sqlite3_wal_checkpoint_v2, + /* Version 3.8.7 and later */ + sqlite3_auto_extension, + sqlite3_bind_blob64, + sqlite3_bind_text64, + sqlite3_cancel_auto_extension, + sqlite3_load_extension, + sqlite3_malloc64, + sqlite3_msize, + sqlite3_realloc64, + sqlite3_reset_auto_extension, + sqlite3_result_blob64, + sqlite3_result_text64, + sqlite3_strglob, + /* Version 3.8.11 and later */ + (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup, + sqlite3_value_free, + sqlite3_result_zeroblob64, + sqlite3_bind_zeroblob64, + /* Version 3.9.0 and later */ + sqlite3_value_subtype, + sqlite3_result_subtype, + /* Version 3.10.0 and later */ + sqlite3_status64, + sqlite3_strlike, + sqlite3_db_cacheflush, + /* Version 3.12.0 and later */ + sqlite3_system_errno, + /* Version 3.14.0 and later */ + sqlite3_trace_v2, + sqlite3_expanded_sql, + /* Version 3.18.0 and later */ + sqlite3_set_last_insert_rowid, + /* Version 3.20.0 and later */ + sqlite3_prepare_v3, + sqlite3_prepare16_v3, + sqlite3_bind_pointer, + sqlite3_result_pointer, + sqlite3_value_pointer, + /* Version 3.22.0 and later */ + sqlite3_vtab_nochange, + sqlite3_value_nochange, + sqlite3_vtab_collation, + /* Version 3.24.0 and later */ + sqlite3_keyword_count, + sqlite3_keyword_name, + sqlite3_keyword_check, + sqlite3_str_new, + sqlite3_str_finish, + sqlite3_str_appendf, + sqlite3_str_vappendf, + sqlite3_str_append, + sqlite3_str_appendall, + sqlite3_str_appendchar, + sqlite3_str_reset, + sqlite3_str_errcode, + sqlite3_str_length, + sqlite3_str_value, + /* Version 3.25.0 and later */ + sqlite3_create_window_function, + /* Version 3.26.0 and later */ +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3_normalized_sql, +#else + 0, +#endif + /* Version 3.28.0 and later */ + sqlite3_stmt_isexplain, + sqlite3_value_frombind, + /* Version 3.30.0 and later */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_drop_modules, +#else + 0, +#endif + /* Version 3.31.0 and later */ + sqlite3_hard_heap_limit64, + sqlite3_uri_key, + sqlite3_filename_database, + sqlite3_filename_journal, + sqlite3_filename_wal, + /* Version 3.32.0 and later */ + sqlite3_create_filename, + sqlite3_free_filename, + sqlite3_database_file_object, + /* Version 3.34.0 and later */ + sqlite3_txn_state, + /* Version 3.36.1 and later */ + sqlite3_changes64, + sqlite3_total_changes64, + /* Version 3.37.0 and later */ + sqlite3_autovacuum_pages, + /* Version 3.38.0 and later */ + sqlite3_error_offset, +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_vtab_rhs_value, + sqlite3_vtab_distinct, + sqlite3_vtab_in, + sqlite3_vtab_in_first, + sqlite3_vtab_in_next, +#else + 0, + 0, + 0, + 0, + 0, +#endif + /* Version 3.39.0 and later */ +#ifndef SQLITE_OMIT_DESERIALIZE + sqlite3_deserialize, + sqlite3_serialize, +#else + 0, + 0, +#endif + sqlite3_db_name, + /* Version 3.40.0 and later */ + sqlite3_value_encoding, + /* Version 3.41.0 and later */ + sqlite3_is_interrupted, + /* Version 3.43.0 and later */ + sqlite3_stmt_explain, + /* Version 3.44.0 and later */ + sqlite3_get_clientdata, + sqlite3_set_clientdata +}; + +/* True if x is the directory separator character +*/ +#if SQLITE_OS_WIN +# define DirSep(X) ((X)=='/'||(X)=='\\') +#else +# define DirSep(X) ((X)=='/') +#endif + +/* +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case a +** default entry point name (sqlite3_extension_init) is used. Use +** of the default name is recommended. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3DbFree(db, ). +*/ +static int sqlite3LoadExtension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + sqlite3_vfs *pVfs = db->pVfs; + void *handle; + sqlite3_loadext_entry xInit; + char *zErrmsg = 0; + const char *zEntry; + char *zAltEntry = 0; + void **aHandle; + u64 nMsg = strlen(zFile); + int ii; + int rc; + + /* Shared library endings to try if zFile cannot be loaded as written */ + static const char *azEndings[] = { +#if SQLITE_OS_WIN + "dll" +#elif defined(__APPLE__) + "dylib" +#else + "so" +#endif + }; + + + if( pzErrMsg ) *pzErrMsg = 0; + + /* Ticket #1863. To avoid a creating security problems for older + ** applications that relink against newer versions of SQLite, the + ** ability to run load_extension is turned off by default. One + ** must call either sqlite3_enable_load_extension(db) or + ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) + ** to turn on extension loading. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("not authorized"); + } + return SQLITE_ERROR; + } + + zEntry = zProc ? zProc : "sqlite3_extension_init"; + + /* tag-20210611-1. Some dlopen() implementations will segfault if given + ** an oversize filename. Most filesystems have a pathname limit of 4K, + ** so limit the extension filename length to about twice that. + ** https://sqlite.org/forum/forumpost/08a0d6d9bf + ** + ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix. + ** See https://sqlite.org/forum/forumpost/24083b579d. + */ + if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; + + /* Do not allow sqlite3_load_extension() to link to a copy of the + ** running application, by passing in an empty filename. */ + if( nMsg==0 ) goto extension_not_found; + + handle = sqlite3OsDlOpen(pVfs, zFile); +#if SQLITE_OS_UNIX || SQLITE_OS_WIN + for(ii=0; ii sqlite3_example_init + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init + */ + if( xInit==0 && zProc==0 ){ + int iFile, iEntry, c; + int ncFile = sqlite3Strlen30(zFile); + zAltEntry = sqlite3_malloc64(ncFile+30); + if( zAltEntry==0 ){ + sqlite3OsDlClose(pVfs, handle); + return SQLITE_NOMEM_BKPT; + } + memcpy(zAltEntry, "sqlite3_", 8); + for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){} + iFile++; + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; + for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ + if( sqlite3Isalpha(c) ){ + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; + } + } + memcpy(zAltEntry+iEntry, "_init", 6); + zEntry = zAltEntry; + xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); + } + if( xInit==0 ){ + if( pzErrMsg ){ + nMsg += strlen(zEntry) + 300; + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); + if( zErrmsg ){ + assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */ + sqlite3_snprintf((int)nMsg, zErrmsg, + "no entry point [%s] in shared library [%s]", zEntry, zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + sqlite3OsDlClose(pVfs, handle); + sqlite3_free(zAltEntry); + return SQLITE_ERROR; + } + sqlite3_free(zAltEntry); + rc = xInit(db, &zErrmsg, &sqlite3Apis); + if( rc ){ + if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK; + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); + } + sqlite3_free(zErrmsg); + sqlite3OsDlClose(pVfs, handle); + return SQLITE_ERROR; + } + + /* Append the new shared library handle to the db->aExtension array. */ + aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); + if( aHandle==0 ){ + return SQLITE_NOMEM_BKPT; + } + if( db->nExtension>0 ){ + memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); + } + sqlite3DbFree(db, db->aExtension); + db->aExtension = aHandle; + + db->aExtension[db->nExtension++] = handle; + return SQLITE_OK; + +extension_not_found: + if( pzErrMsg ){ + nMsg += 300; + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); + if( zErrmsg ){ + assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */ + sqlite3_snprintf((int)nMsg, zErrmsg, + "unable to open shared library [%.*s]", SQLITE_MAX_PATHLEN, zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + return SQLITE_ERROR; +} +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + int rc; + sqlite3_mutex_enter(db->mutex); + rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Call this routine when the database connection is closing in order +** to clean up loaded extensions +*/ +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ + int i; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inExtension; i++){ + sqlite3OsDlClose(db->pVfs, db->aExtension[i]); + } + sqlite3DbFree(db, db->aExtension); +} + +/* +** Enable or disable extension loading. Extension loading is disabled by +** default so as not to open security holes in older applications. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + if( onoff ){ + db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; + }else{ + db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc); + } + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + +/* +** The following object holds the list of automatically loaded +** extensions. +** +** This list is shared across threads. The SQLITE_MUTEX_STATIC_MAIN +** mutex must be held while accessing this list. +*/ +typedef struct sqlite3AutoExtList sqlite3AutoExtList; +static SQLITE_WSD struct sqlite3AutoExtList { + u32 nExt; /* Number of entries in aExt[] */ + void (**aExt)(void); /* Pointers to the extension init functions */ +} sqlite3Autoext = { 0, 0 }; + +/* The "wsdAutoext" macro will resolve to the autoextension +** state vector. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdStat can refer directly +** to the "sqlite3Autoext" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdAutoextInit \ + sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext) +# define wsdAutoext x[0] +#else +# define wsdAutoextInit +# define wsdAutoext sqlite3Autoext +#endif + + +/* +** Register a statically linked extension that is automatically +** loaded by every new database connection. +*/ +SQLITE_API int sqlite3_auto_extension( + void (*xInit)(void) +){ + int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return SQLITE_MISUSE_BKPT; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ){ + return rc; + }else +#endif + { + u32 i; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + for(i=0; i=0; i--){ + if( wsdAutoext.aExt[i]==xInit ){ + wsdAutoext.nExt--; + wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; + n++; + break; + } + } + sqlite3_mutex_leave(mutex); + return n; +} + +/* +** Reset the automatic extension loading mechanism. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize()==SQLITE_OK ) +#endif + { +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + sqlite3_free(wsdAutoext.aExt); + wsdAutoext.aExt = 0; + wsdAutoext.nExt = 0; + sqlite3_mutex_leave(mutex); + } +} + +/* +** Load all automatic extensions. +** +** If anything goes wrong, set an error in the database connection. +*/ +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ + u32 i; + int go = 1; + int rc; + sqlite3_loadext_entry xInit; + + wsdAutoextInit; + if( wsdAutoext.nExt==0 ){ + /* Common case: early out without every having to acquire a mutex */ + return; + } + for(i=0; go; i++){ + char *zErrmsg; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION + const sqlite3_api_routines *pThunk = 0; +#else + const sqlite3_api_routines *pThunk = &sqlite3Apis; +#endif + sqlite3_mutex_enter(mutex); + if( i>=wsdAutoext.nExt ){ + xInit = 0; + go = 0; + }else{ + xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i]; + } + sqlite3_mutex_leave(mutex); + zErrmsg = 0; + if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){ + sqlite3ErrorWithMsg(db, rc, + "automatic extension loading failed: %s", zErrmsg); + go = 0; + } + sqlite3_free(zErrmsg); + } +} + +/************** End of loadext.c *********************************************/ +/************** Begin file pragma.c ******************************************/ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the PRAGMA command. +*/ +/* #include "sqliteInt.h" */ + +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/*************************************************************************** +** The "pragma.h" include file is an automatically generated file that +** that includes the PragType_XXXX macro definitions and the aPragmaName[] +** object. This ensures that the aPragmaName[] table is arranged in +** lexicographical order to facility a binary search of the pragma name. +** Do not edit pragma.h directly. Edit and rerun the script in at +** ../tool/mkpragmatab.tcl. */ +/************** Include pragma.h in the middle of pragma.c *******************/ +/************** Begin file pragma.h ******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script at +** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit +** that script and rerun it. +*/ + +/* The various pragma types */ +#define PragTyp_ACTIVATE_EXTENSIONS 0 +#define PragTyp_ANALYSIS_LIMIT 1 +#define PragTyp_HEADER_VALUE 2 +#define PragTyp_AUTO_VACUUM 3 +#define PragTyp_FLAG 4 +#define PragTyp_BUSY_TIMEOUT 5 +#define PragTyp_CACHE_SIZE 6 +#define PragTyp_CACHE_SPILL 7 +#define PragTyp_CASE_SENSITIVE_LIKE 8 +#define PragTyp_COLLATION_LIST 9 +#define PragTyp_COMPILE_OPTIONS 10 +#define PragTyp_DATA_STORE_DIRECTORY 11 +#define PragTyp_DATABASE_LIST 12 +#define PragTyp_DEFAULT_CACHE_SIZE 13 +#define PragTyp_ENCODING 14 +#define PragTyp_FOREIGN_KEY_CHECK 15 +#define PragTyp_FOREIGN_KEY_LIST 16 +#define PragTyp_FUNCTION_LIST 17 +#define PragTyp_HARD_HEAP_LIMIT 18 +#define PragTyp_INCREMENTAL_VACUUM 19 +#define PragTyp_INDEX_INFO 20 +#define PragTyp_INDEX_LIST 21 +#define PragTyp_INTEGRITY_CHECK 22 +#define PragTyp_JOURNAL_MODE 23 +#define PragTyp_JOURNAL_SIZE_LIMIT 24 +#define PragTyp_LOCK_PROXY_FILE 25 +#define PragTyp_LOCKING_MODE 26 +#define PragTyp_PAGE_COUNT 27 +#define PragTyp_MMAP_SIZE 28 +#define PragTyp_MODULE_LIST 29 +#define PragTyp_OPTIMIZE 30 +#define PragTyp_PAGE_SIZE 31 +#define PragTyp_PRAGMA_LIST 32 +#define PragTyp_SECURE_DELETE 33 +#define PragTyp_SHRINK_MEMORY 34 +#define PragTyp_SOFT_HEAP_LIMIT 35 +#define PragTyp_SYNCHRONOUS 36 +#define PragTyp_TABLE_INFO 37 +#define PragTyp_TABLE_LIST 38 +#define PragTyp_TEMP_STORE 39 +#define PragTyp_TEMP_STORE_DIRECTORY 40 +#define PragTyp_THREADS 41 +#define PragTyp_WAL_AUTOCHECKPOINT 42 +#define PragTyp_WAL_CHECKPOINT 43 +#define PragTyp_LOCK_STATUS 44 +#define PragTyp_STATS 45 + +/* Property flags associated with various pragma. */ +#define PragFlg_NeedSchema 0x01 /* Force schema load before running */ +#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ +#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */ +#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */ +#define PragFlg_Result0 0x10 /* Acts as query when no argument */ +#define PragFlg_Result1 0x20 /* Acts as query when has one argument */ +#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */ +#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */ + +/* Names of columns for pragmas that return multi-column result +** or that return single-column results where the name of the +** result column is different from the name of the pragma +*/ +static const char *const pragCName[] = { + /* 0 */ "id", /* Used by: foreign_key_list */ + /* 1 */ "seq", + /* 2 */ "table", + /* 3 */ "from", + /* 4 */ "to", + /* 5 */ "on_update", + /* 6 */ "on_delete", + /* 7 */ "match", + /* 8 */ "cid", /* Used by: table_xinfo */ + /* 9 */ "name", + /* 10 */ "type", + /* 11 */ "notnull", + /* 12 */ "dflt_value", + /* 13 */ "pk", + /* 14 */ "hidden", + /* table_info reuses 8 */ + /* 15 */ "schema", /* Used by: table_list */ + /* 16 */ "name", + /* 17 */ "type", + /* 18 */ "ncol", + /* 19 */ "wr", + /* 20 */ "strict", + /* 21 */ "seqno", /* Used by: index_xinfo */ + /* 22 */ "cid", + /* 23 */ "name", + /* 24 */ "desc", + /* 25 */ "coll", + /* 26 */ "key", + /* 27 */ "name", /* Used by: function_list */ + /* 28 */ "builtin", + /* 29 */ "type", + /* 30 */ "enc", + /* 31 */ "narg", + /* 32 */ "flags", + /* 33 */ "tbl", /* Used by: stats */ + /* 34 */ "idx", + /* 35 */ "wdth", + /* 36 */ "hght", + /* 37 */ "flgs", + /* 38 */ "seq", /* Used by: index_list */ + /* 39 */ "name", + /* 40 */ "unique", + /* 41 */ "origin", + /* 42 */ "partial", + /* 43 */ "table", /* Used by: foreign_key_check */ + /* 44 */ "rowid", + /* 45 */ "parent", + /* 46 */ "fkid", + /* index_info reuses 21 */ + /* 47 */ "seq", /* Used by: database_list */ + /* 48 */ "name", + /* 49 */ "file", + /* 50 */ "busy", /* Used by: wal_checkpoint */ + /* 51 */ "log", + /* 52 */ "checkpointed", + /* collation_list reuses 38 */ + /* 53 */ "database", /* Used by: lock_status */ + /* 54 */ "status", + /* 55 */ "cache_size", /* Used by: default_cache_size */ + /* module_list pragma_list reuses 9 */ + /* 56 */ "timeout", /* Used by: busy_timeout */ +}; + +/* Definitions of all built-in pragmas */ +typedef struct PragmaName { + const char *const zName; /* Name of pragma */ + u8 ePragTyp; /* PragTyp_XXX value */ + u8 mPragFlg; /* Zero or more PragFlg_XXX values */ + u8 iPragCName; /* Start of column names in pragCName[] */ + u8 nPragCName; /* Num of col names. 0 means use pragma name */ + u64 iArg; /* Extra argument */ +} PragmaName; +static const PragmaName aPragmaName[] = { +#if defined(SQLITE_ENABLE_CEROD) + {/* zName: */ "activate_extensions", + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif + {/* zName: */ "analysis_limit", + /* ePragTyp: */ PragTyp_ANALYSIS_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "application_id", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_APPLICATION_ID }, +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + {/* zName: */ "auto_vacuum", + /* ePragTyp: */ PragTyp_AUTO_VACUUM, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) + {/* zName: */ "automatic_index", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_AutoIndex }, +#endif +#endif + {/* zName: */ "busy_timeout", + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 56, 1, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "cache_size", + /* ePragTyp: */ PragTyp_CACHE_SIZE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "cache_spill", + /* ePragTyp: */ PragTyp_CACHE_SPILL, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA) + {/* zName: */ "case_sensitive_like", + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, + /* ePragFlg: */ PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif + {/* zName: */ "cell_size_check", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CellSizeCk }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "checkpoint_fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CkptFullFSync }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "collation_list", + /* ePragTyp: */ PragTyp_COLLATION_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 38, 2, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) + {/* zName: */ "compile_options", + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "count_changes", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CountRows }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN + {/* zName: */ "data_store_directory", + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, + /* ePragFlg: */ PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "data_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_DATA_VERSION }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "database_list", + /* ePragTyp: */ PragTyp_DATABASE_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 47, 3, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + {/* zName: */ "default_cache_size", + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 55, 1, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + {/* zName: */ "defer_foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_DeferFKs }, +#endif +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "empty_result_callbacks", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_NullCallback }, +#endif +#if !defined(SQLITE_OMIT_UTF16) + {/* zName: */ "encoding", + /* ePragTyp: */ PragTyp_ENCODING, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + {/* zName: */ "foreign_key_check", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 43, 4, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) + {/* zName: */ "foreign_key_list", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 0, 8, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + {/* zName: */ "foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ForeignKeys }, +#endif +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "freelist_count", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_FREE_PAGE_COUNT }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "full_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_FullColNames }, + {/* zName: */ "fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_FullFSync }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + {/* zName: */ "function_list", + /* ePragTyp: */ PragTyp_FUNCTION_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 27, 6, + /* iArg: */ 0 }, +#endif +#endif + {/* zName: */ "hard_heap_limit", + /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_CHECK) + {/* zName: */ "ignore_check_constraints", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_IgnoreChecks }, +#endif +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + {/* zName: */ "incremental_vacuum", + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "index_info", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 21, 3, + /* iArg: */ 0 }, + {/* zName: */ "index_list", + /* ePragTyp: */ PragTyp_INDEX_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 38, 5, + /* iArg: */ 0 }, + {/* zName: */ "index_xinfo", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 21, 6, + /* iArg: */ 1 }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + {/* zName: */ "integrity_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "journal_mode", + /* ePragTyp: */ PragTyp_JOURNAL_MODE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "journal_size_limit", + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "legacy_alter_table", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_LegacyAlter }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE + {/* zName: */ "lock_proxy_file", + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, + /* ePragFlg: */ PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + {/* zName: */ "lock_status", + /* ePragTyp: */ PragTyp_LOCK_STATUS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 53, 2, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "locking_mode", + /* ePragTyp: */ PragTyp_LOCKING_MODE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "max_page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "mmap_size", + /* ePragTyp: */ PragTyp_MMAP_SIZE, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) +#if !defined(SQLITE_OMIT_VIRTUALTABLE) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + {/* zName: */ "module_list", + /* ePragTyp: */ PragTyp_MODULE_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 9, 1, + /* iArg: */ 0 }, +#endif +#endif +#endif + {/* zName: */ "optimize", + /* ePragTyp: */ PragTyp_OPTIMIZE, + /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "page_size", + /* ePragTyp: */ PragTyp_PAGE_SIZE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + {/* zName: */ "parser_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ParserTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + {/* zName: */ "pragma_list", + /* ePragTyp: */ PragTyp_PRAGMA_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 9, 1, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "query_only", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_QueryOnly }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + {/* zName: */ "quick_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "read_uncommitted", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ReadUncommit }, + {/* zName: */ "recursive_triggers", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_RecTriggers }, + {/* zName: */ "reverse_unordered_selects", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ReverseOrder }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "schema_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_SCHEMA_VERSION }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "secure_delete", + /* ePragTyp: */ PragTyp_SECURE_DELETE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "short_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ShortColNames }, +#endif + {/* zName: */ "shrink_memory", + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, + /* ePragFlg: */ PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "soft_heap_limit", + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + {/* zName: */ "sql_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_SqlTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) + {/* zName: */ "stats", + /* ePragTyp: */ PragTyp_STATS, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 33, 5, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "synchronous", + /* ePragTyp: */ PragTyp_SYNCHRONOUS, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "table_info", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 8, 6, + /* iArg: */ 0 }, + {/* zName: */ "table_list", + /* ePragTyp: */ PragTyp_TABLE_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, + /* ColNames: */ 15, 6, + /* iArg: */ 0 }, + {/* zName: */ "table_xinfo", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 8, 7, + /* iArg: */ 1 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "temp_store", + /* ePragTyp: */ PragTyp_TEMP_STORE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "temp_store_directory", + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, + /* ePragFlg: */ PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif + {/* zName: */ "threads", + /* ePragTyp: */ PragTyp_THREADS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "trusted_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_TrustedSchema }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "user_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_USER_VERSION }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + {/* zName: */ "vdbe_addoptrace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeAddopTrace }, + {/* zName: */ "vdbe_debug", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, + {/* zName: */ "vdbe_eqp", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeEQP }, + {/* zName: */ "vdbe_listing", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeListing }, + {/* zName: */ "vdbe_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_WAL) + {/* zName: */ "wal_autocheckpoint", + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "wal_checkpoint", + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, + /* ePragFlg: */ PragFlg_NeedSchema, + /* ColNames: */ 50, 3, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "writable_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, +#endif +}; +/* Number of pragmas: 68 on by default, 78 total. */ + +/************** End of pragma.h **********************************************/ +/************** Continuing where we left off in pragma.c *********************/ + +/* +** Interpret the given string as a safety level. Return 0 for OFF, +** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or +** unrecognized string argument. The FULL and EXTRA option is disallowed +** if the omitFull parameter it 1. +** +** Note that the values returned are one less that the values that +** should be passed into sqlite3BtreeSetSafetyLevel(). The is done +** to support legacy SQL code. The safety level used to be boolean +** and older scripts may have used numbers 0 for OFF and 1 for ON. +*/ +static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ + /* 123456789 123456789 123 */ + static const char zText[] = "onoffalseyestruextrafull"; + static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20}; + static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4}; + static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; + /* on no off false yes true extra full */ + int i, n; + if( sqlite3Isdigit(*z) ){ + return (u8)sqlite3Atoi(z); + } + n = sqlite3Strlen30(z); + for(i=0; i=0&&i<=2)?i:0); +} +#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Interpret the given string as a temp db location. Return 1 for file +** backed temporary databases, 2 for the Red-Black tree in memory database +** and 0 to use the compile-time default. +*/ +static int getTempStore(const char *z){ + if( z[0]>='0' && z[0]<='2' ){ + return z[0] - '0'; + }else if( sqlite3StrICmp(z, "file")==0 ){ + return 1; + }else if( sqlite3StrICmp(z, "memory")==0 ){ + return 2; + }else{ + return 0; + } +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Invalidate temp storage, either when the temp storage is changed +** from default, or when 'file' and the temp_store_directory has changed +*/ +static int invalidateTempStorage(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt!=0 ){ + if( !db->autoCommit + || sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE + ){ + sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " + "from within a transaction"); + return SQLITE_ERROR; + } + sqlite3BtreeClose(db->aDb[1].pBt); + db->aDb[1].pBt = 0; + sqlite3ResetAllSchemasOfConnection(db); + } + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** If the TEMP database is open, close it and mark the database schema +** as needing reloading. This must be done when using the SQLITE_TEMP_STORE +** or DEFAULT_TEMP_STORE pragmas. +*/ +static int changeTempStorage(Parse *pParse, const char *zStorageType){ + int ts = getTempStore(zStorageType); + sqlite3 *db = pParse->db; + if( db->temp_store==ts ) return SQLITE_OK; + if( invalidateTempStorage( pParse ) != SQLITE_OK ){ + return SQLITE_ERROR; + } + db->temp_store = (u8)ts; + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +/* +** Set result column names for a pragma. +*/ +static void setPragmaResultColumnNames( + Vdbe *v, /* The query under construction */ + const PragmaName *pPragma /* The pragma */ +){ + u8 n = pPragma->nPragCName; + sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); + if( n==0 ){ + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); + }else{ + int i, j; + for(i=0, j=pPragma->iPragCName; iautoCommit ){ + Db *pDb = db->aDb; + int n = db->nDb; + assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); + assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); + assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); + assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) + == PAGER_FLAGS_MASK ); + assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); + while( (n--) > 0 ){ + if( pDb->pBt ){ + sqlite3BtreeSetPagerFlags(pDb->pBt, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); + } + pDb++; + } + } +} +#else +# define setAllPagerFlags(X) /* no-op */ +#endif + + +/* +** Return a human-readable name for a constraint resolution action. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static const char *actionName(u8 action){ + const char *zName; + switch( action ){ + case OE_SetNull: zName = "SET NULL"; break; + case OE_SetDflt: zName = "SET DEFAULT"; break; + case OE_Cascade: zName = "CASCADE"; break; + case OE_Restrict: zName = "RESTRICT"; break; + default: zName = "NO ACTION"; + assert( action==OE_None ); break; + } + return zName; +} +#endif + + +/* +** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants +** defined in pager.h. This function returns the associated lowercase +** journal-mode name. +*/ +SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){ + static char * const azModeName[] = { + "delete", "persist", "off", "truncate", "memory" +#ifndef SQLITE_OMIT_WAL + , "wal" +#endif + }; + assert( PAGER_JOURNALMODE_DELETE==0 ); + assert( PAGER_JOURNALMODE_PERSIST==1 ); + assert( PAGER_JOURNALMODE_OFF==2 ); + assert( PAGER_JOURNALMODE_TRUNCATE==3 ); + assert( PAGER_JOURNALMODE_MEMORY==4 ); + assert( PAGER_JOURNALMODE_WAL==5 ); + assert( eMode>=0 && eMode<=ArraySize(azModeName) ); + + if( eMode==ArraySize(azModeName) ) return 0; + return azModeName[eMode]; +} + +/* +** Locate a pragma in the aPragmaName[] array. +*/ +static const PragmaName *pragmaLocate(const char *zName){ + int upr, lwr, mid = 0, rc; + lwr = 0; + upr = ArraySize(aPragmaName)-1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + rc = sqlite3_stricmp(zName, aPragmaName[mid].zName); + if( rc==0 ) break; + if( rc<0 ){ + upr = mid - 1; + }else{ + lwr = mid + 1; + } + } + return lwr>upr ? 0 : &aPragmaName[mid]; +} + +/* +** Create zero or more entries in the output for the SQL functions +** defined by FuncDef p. +*/ +static void pragmaFunclistLine( + Vdbe *v, /* The prepared statement being created */ + FuncDef *p, /* A particular function definition */ + int isBuiltin, /* True if this is a built-in function */ + int showInternFuncs /* True if showing internal functions */ +){ + u32 mask = + SQLITE_DETERMINISTIC | + SQLITE_DIRECTONLY | + SQLITE_SUBTYPE | + SQLITE_INNOCUOUS | + SQLITE_FUNC_INTERNAL + ; + if( showInternFuncs ) mask = 0xffffffff; + for(; p; p=p->pNext){ + const char *zType; + static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" }; + + assert( SQLITE_FUNC_ENCMASK==0x3 ); + assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 ); + + if( p->xSFunc==0 ) continue; + if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && showInternFuncs==0 + ){ + continue; + } + if( p->xValue!=0 ){ + zType = "w"; + }else if( p->xFinalize!=0 ){ + zType = "a"; + }else{ + zType = "s"; + } + sqlite3VdbeMultiLoad(v, 1, "sissii", + p->zName, isBuiltin, + zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK], + p->nArg, + (p->funcFlags & mask) ^ SQLITE_INNOCUOUS + ); + } +} + + +/* +** Helper subroutine for PRAGMA integrity_check: +** +** Generate code to output a single-column result row with a value of the +** string held in register 3. Decrement the result count in register 1 +** and halt if the maximum number of result rows have been issued. +*/ +static int integrityCheckResultRow(Vdbe *v){ + int addr; + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); + VdbeCoverage(v); + sqlite3VdbeAddOp0(v, OP_Halt); + return addr; +} + +/* +** Process a pragma statement. +** +** Pragmas are of this form: +** +** PRAGMA [schema.]id [= value] +** +** The identifier might also be a string. The value is a string, and +** identifier, or a number. If minusFlag is true, then the value is +** a number that was preceded by a minus sign. +** +** If the left side is "database.id" then pId1 is the database name +** and pId2 is the id. If the left side is just "id" then pId1 is the +** id and pId2 is any empty string. +*/ +SQLITE_PRIVATE void sqlite3Pragma( + Parse *pParse, + Token *pId1, /* First part of [schema.]id field */ + Token *pId2, /* Second part of [schema.]id field, or NULL */ + Token *pValue, /* Token for , or NULL */ + int minusFlag /* True if a '-' sign preceded */ +){ + char *zLeft = 0; /* Nul-terminated UTF-8 string */ + char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ + const char *zDb = 0; /* The database name */ + Token *pId; /* Pointer to token */ + char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ + int iDb; /* Database index for */ + int rc; /* return value form SQLITE_FCNTL_PRAGMA */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* The specific database being pragmaed */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ + const PragmaName *pPragma; /* The pragma */ + + if( v==0 ) return; + sqlite3VdbeRunOnlyOnce(v); + pParse->nMem = 2; + + /* Interpret the [schema.] part of the pragma statement. iDb is the + ** index of the database this pragma is being applied to in db.aDb[]. */ + iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); + if( iDb<0 ) return; + pDb = &db->aDb[iDb]; + + /* If the temp database has been explicitly named as part of the + ** pragma, make sure it is open. + */ + if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ + return; + } + + zLeft = sqlite3NameFromToken(db, pId); + if( !zLeft ) return; + if( minusFlag ){ + zRight = sqlite3MPrintf(db, "-%T", pValue); + }else{ + zRight = sqlite3NameFromToken(db, pValue); + } + + assert( pId2 ); + zDb = pId2->n>0 ? pDb->zDbSName : 0; + if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ + goto pragma_out; + } + + /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS + ** connection. If it returns SQLITE_OK, then assume that the VFS + ** handled the pragma and generate a no-op prepared statement. + ** + ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, + ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file + ** object corresponding to the database file to which the pragma + ** statement refers. + ** + ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA + ** file control is an array of pointers to strings (char**) in which the + ** second element of the array is the name of the pragma and the third + ** element is the argument to the pragma or NULL if the pragma has no + ** argument. + */ + aFcntl[0] = 0; + aFcntl[1] = zLeft; + aFcntl[2] = zRight; + aFcntl[3] = 0; + db->busyHandler.nBusy = 0; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + if( rc==SQLITE_OK ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT); + returnSingleText(v, aFcntl[0]); + sqlite3_free(aFcntl[0]); + goto pragma_out; + } + if( rc!=SQLITE_NOTFOUND ){ + if( aFcntl[0] ){ + sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); + sqlite3_free(aFcntl[0]); + } + pParse->nErr++; + pParse->rc = rc; + goto pragma_out; + } + + /* Locate the pragma in the lookup table */ + pPragma = pragmaLocate(zLeft); + if( pPragma==0 ){ + /* IMP: R-43042-22504 No error messages are generated if an + ** unknown pragma is issued. */ + goto pragma_out; + } + + /* Make sure the database schema is loaded if the pragma requires that */ + if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + } + + /* Register the result column names for pragmas that return results */ + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 + && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) + ){ + setPragmaResultColumnNames(v, pPragma); + } + + /* Jump to the appropriate pragma handler */ + switch( pPragma->ePragTyp ){ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + /* + ** PRAGMA [schema.]default_cache_size + ** PRAGMA [schema.]default_cache_size=N + ** + ** The first form reports the current persistent setting for the + ** page cache size. The value returned is the maximum number of + ** pages in the page cache. The second form sets both the current + ** page cache size value and the persistent page cache size value + ** stored in the database file. + ** + ** Older versions of SQLite would set the default cache size to a + ** negative number to indicate synchronous=OFF. These days, synchronous + ** is always on by default regardless of the sign of the default cache + ** size. But continue to take the absolute value of the default cache + ** size of historical compatibility. + */ + case PragTyp_DEFAULT_CACHE_SIZE: { + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList getCacheSize[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ + { OP_IfPos, 1, 8, 0}, + { OP_Integer, 0, 2, 0}, + { OP_Subtract, 1, 2, 1}, + { OP_IfPos, 1, 8, 0}, + { OP_Integer, 0, 1, 0}, /* 6 */ + { OP_Noop, 0, 0, 0}, + { OP_ResultRow, 1, 1, 0}, + }; + VdbeOp *aOp; + sqlite3VdbeUsesBtree(v, iDb); + if( !zRight ){ + pParse->nMem += 2; + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; + }else{ + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + break; + } +#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + /* + ** PRAGMA [schema.]page_size + ** PRAGMA [schema.]page_size=N + ** + ** The first form reports the current setting for the + ** database page size in bytes. The second form sets the + ** database page size value. The value can only be set if + ** the database has not yet been created. + */ + case PragTyp_PAGE_SIZE: { + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; + returnSingleInt(v, size); + }else{ + /* Malloc may fail when setting the page-size, as there is an internal + ** buffer that the pager module resizes using sqlite3_realloc(). + */ + db->nextPagesize = sqlite3Atoi(zRight); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){ + sqlite3OomFault(db); + } + } + break; + } + + /* + ** PRAGMA [schema.]secure_delete + ** PRAGMA [schema.]secure_delete=ON/OFF/FAST + ** + ** The first form reports the current setting for the + ** secure_delete flag. The second form changes the secure_delete + ** flag setting and reports the new value. + */ + case PragTyp_SECURE_DELETE: { + Btree *pBt = pDb->pBt; + int b = -1; + assert( pBt!=0 ); + if( zRight ){ + if( sqlite3_stricmp(zRight, "fast")==0 ){ + b = 2; + }else{ + b = sqlite3GetBoolean(zRight, 0); + } + } + if( pId2->n==0 && b>=0 ){ + int ii; + for(ii=0; iinDb; ii++){ + sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); + } + } + b = sqlite3BtreeSecureDelete(pBt, b); + returnSingleInt(v, b); + break; + } + + /* + ** PRAGMA [schema.]max_page_count + ** PRAGMA [schema.]max_page_count=N + ** + ** The first form reports the current setting for the + ** maximum number of pages in the database file. The + ** second form attempts to change this setting. Both + ** forms return the current setting. + ** + ** The absolute value of N is used. This is undocumented and might + ** change. The only purpose is to provide an easy way to test + ** the sqlite3AbsInt32() function. + ** + ** PRAGMA [schema.]page_count + ** + ** Return the number of pages in the specified database. + */ + case PragTyp_PAGE_COUNT: { + int iReg; + i64 x = 0; + sqlite3CodeVerifySchema(pParse, iDb); + iReg = ++pParse->nMem; + if( sqlite3Tolower(zLeft[0])=='p' ){ + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + }else{ + if( zRight && sqlite3DecOrHexToI64(zRight,&x)==0 ){ + if( x<0 ) x = 0; + else if( x>0xfffffffe ) x = 0xfffffffe; + }else{ + x = 0; + } + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, (int)x); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); + break; + } + + /* + ** PRAGMA [schema.]locking_mode + ** PRAGMA [schema.]locking_mode = (normal|exclusive) + */ + case PragTyp_LOCKING_MODE: { + const char *zRet = "normal"; + int eMode = getLockingMode(zRight); + + if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ + /* Simple "PRAGMA locking_mode;" statement. This is a query for + ** the current default locking mode (which may be different to + ** the locking-mode of the main database). + */ + eMode = db->dfltLockMode; + }else{ + Pager *pPager; + if( pId2->n==0 ){ + /* This indicates that no database name was specified as part + ** of the PRAGMA command. In this case the locking-mode must be + ** set on all attached databases, as well as the main db file. + ** + ** Also, the sqlite3.dfltLockMode variable is set so that + ** any subsequently attached databases also use the specified + ** locking mode. + */ + int ii; + assert(pDb==&db->aDb[0]); + for(ii=2; iinDb; ii++){ + pPager = sqlite3BtreePager(db->aDb[ii].pBt); + sqlite3PagerLockingMode(pPager, eMode); + } + db->dfltLockMode = (u8)eMode; + } + pPager = sqlite3BtreePager(pDb->pBt); + eMode = sqlite3PagerLockingMode(pPager, eMode); + } + + assert( eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ + zRet = "exclusive"; + } + returnSingleText(v, zRet); + break; + } + + /* + ** PRAGMA [schema.]journal_mode + ** PRAGMA [schema.]journal_mode = + ** (delete|persist|off|truncate|memory|wal|off) + */ + case PragTyp_JOURNAL_MODE: { + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ + int ii; /* Loop counter */ + + if( zRight==0 ){ + /* If there is no "=MODE" part of the pragma, do a query for the + ** current mode */ + eMode = PAGER_JOURNALMODE_QUERY; + }else{ + const char *zMode; + int n = sqlite3Strlen30(zRight); + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; + } + if( !zMode ){ + /* If the "=MODE" part does not match any known journal mode, + ** then do a query */ + eMode = PAGER_JOURNALMODE_QUERY; + } + if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){ + /* Do not allow journal-mode "OFF" in defensive since the database + ** can become corrupted using ordinary SQL when the journal is off */ + eMode = PAGER_JOURNALMODE_QUERY; + } + } + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ + iDb = 0; + pId2->n = 1; + } + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3VdbeUsesBtree(v, ii); + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); + } + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + break; + } + + /* + ** PRAGMA [schema.]journal_size_limit + ** PRAGMA [schema.]journal_size_limit=N + ** + ** Get or set the size limit on rollback journal files. + */ + case PragTyp_JOURNAL_SIZE_LIMIT: { + Pager *pPager = sqlite3BtreePager(pDb->pBt); + i64 iLimit = -2; + if( zRight ){ + sqlite3DecOrHexToI64(zRight, &iLimit); + if( iLimit<-1 ) iLimit = -1; + } + iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); + returnSingleInt(v, iLimit); + break; + } + +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + + /* + ** PRAGMA [schema.]auto_vacuum + ** PRAGMA [schema.]auto_vacuum=N + ** + ** Get or set the value of the database 'auto-vacuum' parameter. + ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + case PragTyp_AUTO_VACUUM: { + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt)); + }else{ + int eAuto = getAutoVacuum(zRight); + assert( eAuto>=0 && eAuto<=2 ); + db->nextAutovac = (u8)eAuto; + /* Call SetAutoVacuum() to set initialize the internal auto and + ** incr-vacuum flags. This is required in case this connection + ** creates the database file. It is important that it is created + ** as an auto-vacuum capable db. + */ + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ + /* When setting the auto_vacuum mode to either "full" or + ** "incremental", write the value of meta[6] in the database + ** file. Before writing to meta[6], check that meta[3] indicates + ** that this really is an auto-vacuum capable database. + */ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList setMeta6[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, + { OP_If, 1, 0, 0}, /* 2 */ + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */ + }; + VdbeOp *aOp; + int iAddr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[2].p2 = iAddr+4; + aOp[4].p1 = iDb; + aOp[4].p3 = eAuto - 1; + sqlite3VdbeUsesBtree(v, iDb); + } + } + break; + } +#endif + + /* + ** PRAGMA [schema.]incremental_vacuum(N) + ** + ** Do N steps of incremental vacuuming on a database. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + case PragTyp_INCREMENTAL_VACUUM: { + int iLimit = 0, addr; + if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ + iLimit = 0x7fffffff; + } + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_ResultRow, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + break; + } +#endif + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + /* + ** PRAGMA [schema.]cache_size + ** PRAGMA [schema.]cache_size=N + ** + ** The first form reports the current local setting for the + ** page cache size. The second form sets the local + ** page cache size value. If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. + */ + case PragTyp_CACHE_SIZE: { + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !zRight ){ + returnSingleInt(v, pDb->pSchema->cache_size); + }else{ + int size = sqlite3Atoi(zRight); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + break; + } + + /* + ** PRAGMA [schema.]cache_spill + ** PRAGMA cache_spill=BOOLEAN + ** PRAGMA [schema.]cache_spill=N + ** + ** The first form reports the current local setting for the + ** page cache spill size. The second form turns cache spill on + ** or off. When turning cache spill on, the size is set to the + ** current cache_size. The third form sets a spill size that + ** may be different form the cache size. + ** If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. + ** + ** If the number of cache_spill pages is less then the number of + ** cache_size pages, no spilling occurs until the page count exceeds + ** the number of cache_size pages. + ** + ** The cache_spill=BOOLEAN setting applies to all attached schemas, + ** not just the schema specified. + */ + case PragTyp_CACHE_SPILL: { + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !zRight ){ + returnSingleInt(v, + (db->flags & SQLITE_CacheSpill)==0 ? 0 : + sqlite3BtreeSetSpillSize(pDb->pBt,0)); + }else{ + int size = 1; + if( sqlite3GetInt32(zRight, &size) ){ + sqlite3BtreeSetSpillSize(pDb->pBt, size); + } + if( sqlite3GetBoolean(zRight, size!=0) ){ + db->flags |= SQLITE_CacheSpill; + }else{ + db->flags &= ~(u64)SQLITE_CacheSpill; + } + setAllPagerFlags(db); + } + break; + } + + /* + ** PRAGMA [schema.]mmap_size(N) + ** + ** Used to set mapping size limit. The mapping size limit is + ** used to limit the aggregate size of all memory mapped regions of the + ** database file. If this parameter is set to zero, then memory mapping + ** is not used at all. If N is negative, then the default memory map + ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. + ** The parameter N is measured in bytes. + ** + ** This value is advisory. The underlying VFS is free to memory map + ** as little or as much as it wants. Except, if N is set to 0 then the + ** upper layers will never invoke the xFetch interfaces to the VFS. + */ + case PragTyp_MMAP_SIZE: { + sqlite3_int64 sz; +#if SQLITE_MAX_MMAP_SIZE>0 + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( zRight ){ + int ii; + sqlite3DecOrHexToI64(zRight, &sz); + if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; + if( pId2->n==0 ) db->szMmap = sz; + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); + } + } + } + sz = -1; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); +#else + sz = 0; + rc = SQLITE_OK; +#endif + if( rc==SQLITE_OK ){ + returnSingleInt(v, sz); + }else if( rc!=SQLITE_NOTFOUND ){ + pParse->nErr++; + pParse->rc = rc; + } + break; + } + + /* + ** PRAGMA temp_store + ** PRAGMA temp_store = "default"|"memory"|"file" + ** + ** Return or set the local value of the temp_store flag. Changing + ** the local value does not make changes to the disk file and the default + ** value will be restored the next time the database is opened. + ** + ** Note that it is possible for the library compile-time options to + ** override this setting + */ + case PragTyp_TEMP_STORE: { + if( !zRight ){ + returnSingleInt(v, db->temp_store); + }else{ + changeTempStorage(pParse, zRight); + } + break; + } + + /* + ** PRAGMA temp_store_directory + ** PRAGMA temp_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the temp_store_directory flag. Changing + ** the value sets a specific directory to be used for temporary files. + ** Setting to a null string reverts to the default temporary directory search. + ** If temporary directory is changed, then invalidateTempStorage. + ** + */ + case PragTyp_TEMP_STORE_DIRECTORY: { + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + if( !zRight ){ + returnSingleText(v, sqlite3_temp_directory); + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + goto pragma_out; + } + } + if( SQLITE_TEMP_STORE==0 + || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) + || (SQLITE_TEMP_STORE==2 && db->temp_store==1) + ){ + invalidateTempStorage(pParse); + } + sqlite3_free(sqlite3_temp_directory); + if( zRight[0] ){ + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_temp_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + break; + } + +#if SQLITE_OS_WIN + /* + ** PRAGMA data_store_directory + ** PRAGMA data_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the data_store_directory flag. Changing + ** the value sets a specific directory to be used for database files that + ** were specified with a relative pathname. Setting to a null string reverts + ** to the default database directory, which for database files specified with + ** a relative path will probably be based on the current directory for the + ** process. Database file specified with an absolute path are not impacted + ** by this setting, regardless of its value. + ** + */ + case PragTyp_DATA_STORE_DIRECTORY: { + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + if( !zRight ){ + returnSingleText(v, sqlite3_data_directory); + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + goto pragma_out; + } + } + sqlite3_free(sqlite3_data_directory); + if( zRight[0] ){ + sqlite3_data_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_data_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + break; + } +#endif + +#if SQLITE_ENABLE_LOCKING_STYLE + /* + ** PRAGMA [schema.]lock_proxy_file + ** PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path" + ** + ** Return or set the value of the lock_proxy_file flag. Changing + ** the value sets a specific file to be used for database access locks. + ** + */ + case PragTyp_LOCK_PROXY_FILE: { + if( !zRight ){ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + char *proxy_file_path = NULL; + sqlite3_file *pFile = sqlite3PagerFile(pPager); + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, + &proxy_file_path); + returnSingleText(v, proxy_file_path); + }else{ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + sqlite3_file *pFile = sqlite3PagerFile(pPager); + int res; + if( zRight[0] ){ + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + zRight); + } else { + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + NULL); + } + if( res!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); + goto pragma_out; + } + } + break; + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + + /* + ** PRAGMA [schema.]synchronous + ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA + ** + ** Return or set the local value of the synchronous flag. Changing + ** the local value does not make changes to the disk file and the + ** default value will be restored the next time the database is + ** opened. + */ + case PragTyp_SYNCHRONOUS: { + if( !zRight ){ + returnSingleInt(v, pDb->safety_level-1); + }else{ + if( !db->autoCommit ){ + sqlite3ErrorMsg(pParse, + "Safety level may not be changed inside a transaction"); + }else if( iDb!=1 ){ + int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; + if( iLevel==0 ) iLevel = 1; + pDb->safety_level = iLevel; + pDb->bSyncSet = 1; + setAllPagerFlags(db); + } + } + break; + } +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_FLAG_PRAGMAS + case PragTyp_FLAG: { + if( zRight==0 ){ + setPragmaResultColumnNames(v, pPragma); + returnSingleInt(v, (db->flags & pPragma->iArg)!=0 ); + }else{ + u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */ + if( db->autoCommit==0 ){ + /* Foreign key support may not be enabled or disabled while not + ** in auto-commit mode. */ + mask &= ~(SQLITE_ForeignKeys); + } +#if SQLITE_USER_AUTHENTICATION + if( db->auth.authLevel==UAUTH_User ){ + /* Do not allow non-admin users to modify the schema arbitrarily */ + mask &= ~(SQLITE_WriteSchema); + } +#endif + + if( sqlite3GetBoolean(zRight, 0) ){ + if( (mask & SQLITE_WriteSchema)==0 + || (db->flags & SQLITE_Defensive)==0 + ){ + db->flags |= mask; + } + }else{ + db->flags &= ~mask; + if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; + if( (mask & SQLITE_WriteSchema)!=0 + && sqlite3_stricmp(zRight, "reset")==0 + ){ + /* IMP: R-60817-01178 If the argument is "RESET" then schema + ** writing is disabled (as with "PRAGMA writable_schema=OFF") and, + ** in addition, the schema is reloaded. */ + sqlite3ResetAllSchemasOfConnection(db); + } + } + + /* Many of the flag-pragmas modify the code generated by the SQL + ** compiler (eg. count_changes). So add an opcode to expire all + ** compiled SQL statements after modifying a pragma value. + */ + sqlite3VdbeAddOp0(v, OP_Expire); + setAllPagerFlags(db); + } + break; + } +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ + +#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS + /* + ** PRAGMA table_info(
) + ** + ** Return a single row for each column of the named table. The columns of + ** the returned data set are: + ** + ** cid: Column id (numbered from left to right, starting at 0) + ** name: Column name + ** type: Column declaration type. + ** notnull: True if 'NOT NULL' is part of column declaration + ** dflt_value: The default value for the column, if any. + ** pk: Non-zero for PK fields. + */ + case PragTyp_TABLE_INFO: if( zRight ){ + Table *pTab; + sqlite3CodeVerifyNamedSchema(pParse, zDb); + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); + if( pTab ){ + int i, k; + int nHidden = 0; + Column *pCol; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + pParse->nMem = 7; + sqlite3ViewGetColumnNames(pParse, pTab); + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + int isHidden = 0; + const Expr *pColExpr; + if( pCol->colFlags & COLFLAG_NOINSERT ){ + if( pPragma->iArg==0 ){ + nHidden++; + continue; + } + if( pCol->colFlags & COLFLAG_VIRTUAL ){ + isHidden = 2; /* GENERATED ALWAYS AS ... VIRTUAL */ + }else if( pCol->colFlags & COLFLAG_STORED ){ + isHidden = 3; /* GENERATED ALWAYS AS ... STORED */ + }else{ assert( pCol->colFlags & COLFLAG_HIDDEN ); + isHidden = 1; /* HIDDEN */ + } + } + if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ + k = 0; + }else if( pPk==0 ){ + k = 1; + }else{ + for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} + } + pColExpr = sqlite3ColumnExpr(pTab,pCol); + assert( pColExpr==0 || pColExpr->op==TK_SPAN || isHidden>=2 ); + assert( pColExpr==0 || !ExprHasProperty(pColExpr, EP_IntValue) + || isHidden>=2 ); + sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", + i-nHidden, + pCol->zCnName, + sqlite3ColumnType(pCol,""), + pCol->notNull ? 1 : 0, + (isHidden>=2 || pColExpr==0) ? 0 : pColExpr->u.zToken, + k, + isHidden); + } + } + } + break; + + /* + ** PRAGMA table_list + ** + ** Return a single row for each table, virtual table, or view in the + ** entire schema. + ** + ** schema: Name of attached database hold this table + ** name: Name of the table itself + ** type: "table", "view", "virtual", "shadow" + ** ncol: Number of columns + ** wr: True for a WITHOUT ROWID table + ** strict: True for a STRICT table + */ + case PragTyp_TABLE_LIST: { + int ii; + pParse->nMem = 6; + sqlite3CodeVerifyNamedSchema(pParse, zDb); + for(ii=0; iinDb; ii++){ + HashElem *k; + Hash *pHash; + int initNCol; + if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue; + + /* Ensure that the Table.nCol field is initialized for all views + ** and virtual tables. Each time we initialize a Table.nCol value + ** for a table, that can potentially disrupt the hash table, so restart + ** the initialization scan. + */ + pHash = &db->aDb[ii].pSchema->tblHash; + initNCol = sqliteHashCount(pHash); + while( initNCol-- ){ + for(k=sqliteHashFirst(pHash); 1; k=sqliteHashNext(k) ){ + Table *pTab; + if( k==0 ){ initNCol = 0; break; } + pTab = sqliteHashData(k); + if( pTab->nCol==0 ){ + char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); + if( zSql ){ + sqlite3_stmt *pDummy = 0; + (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0); + (void)sqlite3_finalize(pDummy); + sqlite3DbFree(db, zSql); + } + if( db->mallocFailed ){ + sqlite3ErrorMsg(db->pParse, "out of memory"); + db->pParse->rc = SQLITE_NOMEM_BKPT; + } + pHash = &db->aDb[ii].pSchema->tblHash; + break; + } + } + } + + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){ + Table *pTab = sqliteHashData(k); + const char *zType; + if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue; + if( IsView(pTab) ){ + zType = "view"; + }else if( IsVirtual(pTab) ){ + zType = "virtual"; + }else if( pTab->tabFlags & TF_Shadow ){ + zType = "shadow"; + }else{ + zType = "table"; + } + sqlite3VdbeMultiLoad(v, 1, "sssiii", + db->aDb[ii].zDbSName, + sqlite3PreferredTableName(pTab->zName), + zType, + pTab->nCol, + (pTab->tabFlags & TF_WithoutRowid)!=0, + (pTab->tabFlags & TF_Strict)!=0 + ); + } + } + } + break; + +#ifdef SQLITE_DEBUG + case PragTyp_STATS: { + Index *pIdx; + HashElem *i; + pParse->nMem = 5; + sqlite3CodeVerifySchema(pParse, iDb); + for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + sqlite3VdbeMultiLoad(v, 1, "ssiii", + sqlite3PreferredTableName(pTab->zName), + 0, + pTab->szTabRow, + pTab->nRowLogEst, + pTab->tabFlags); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeMultiLoad(v, 2, "siiiX", + pIdx->zName, + pIdx->szIdxRow, + pIdx->aiRowLogEst[0], + pIdx->hasStat1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); + } + } + } + break; +#endif + + case PragTyp_INDEX_INFO: if( zRight ){ + Index *pIdx; + Table *pTab; + pIdx = sqlite3FindIndex(db, zRight, zDb); + if( pIdx==0 ){ + /* If there is no index named zRight, check to see if there is a + ** WITHOUT ROWID table named zRight, and if there is, show the + ** structure of the PRIMARY KEY index for that table. */ + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); + if( pTab && !HasRowid(pTab) ){ + pIdx = sqlite3PrimaryKeyIndex(pTab); + } + } + if( pIdx ){ + int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); + int i; + int mx; + if( pPragma->iArg ){ + /* PRAGMA index_xinfo (newer version with more rows and columns) */ + mx = pIdx->nColumn; + pParse->nMem = 6; + }else{ + /* PRAGMA index_info (legacy version) */ + mx = pIdx->nKeyCol; + pParse->nMem = 3; + } + pTab = pIdx->pTable; + sqlite3CodeVerifySchema(pParse, iIdxDb); + assert( pParse->nMem<=pPragma->nPragCName ); + for(i=0; iaiColumn[i]; + sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, + cnum<0 ? 0 : pTab->aCol[cnum].zCnName); + if( pPragma->iArg ){ + sqlite3VdbeMultiLoad(v, 4, "isiX", + pIdx->aSortOrder[i], + pIdx->azColl[i], + inKeyCol); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); + } + } + } + break; + + case PragTyp_INDEX_LIST: if( zRight ){ + Index *pIdx; + Table *pTab; + int i; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pParse->nMem = 5; + sqlite3CodeVerifySchema(pParse, iTabDb); + for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ + const char *azOrigin[] = { "c", "u", "pk" }; + sqlite3VdbeMultiLoad(v, 1, "isisi", + i, + pIdx->zName, + IsUniqueIndex(pIdx), + azOrigin[pIdx->idxType], + pIdx->pPartIdxWhere!=0); + } + } + } + break; + + case PragTyp_DATABASE_LIST: { + int i; + pParse->nMem = 3; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt==0 ) continue; + assert( db->aDb[i].zDbSName!=0 ); + sqlite3VdbeMultiLoad(v, 1, "iss", + i, + db->aDb[i].zDbSName, + sqlite3BtreeGetFilename(db->aDb[i].pBt)); + } + } + break; + + case PragTyp_COLLATION_LIST: { + int i = 0; + HashElem *p; + pParse->nMem = 2; + for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(p); + sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); + } + } + break; + +#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS + case PragTyp_FUNCTION_LIST: { + int i; + HashElem *j; + FuncDef *p; + int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0; + pParse->nMem = 6; + for(i=0; iu.pHash ){ + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); + pragmaFunclistLine(v, p, 1, showInternFunc); + } + } + for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ + p = (FuncDef*)sqliteHashData(j); + assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); + pragmaFunclistLine(v, p, 0, showInternFunc); + } + } + break; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + case PragTyp_MODULE_LIST: { + HashElem *j; + pParse->nMem = 1; + for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ + Module *pMod = (Module*)sqliteHashData(j); + sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); + } + } + break; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + case PragTyp_PRAGMA_LIST: { + int i; + for(i=0; iu.tab.pFKey; + if( pFK ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + int i = 0; + pParse->nMem = 8; + sqlite3CodeVerifySchema(pParse, iTabDb); + while(pFK){ + int j; + for(j=0; jnCol; j++){ + sqlite3VdbeMultiLoad(v, 1, "iissssss", + i, + j, + pFK->zTo, + pTab->aCol[pFK->aCol[j].iFrom].zCnName, + pFK->aCol[j].zCol, + actionName(pFK->aAction[1]), /* ON UPDATE */ + actionName(pFK->aAction[0]), /* ON DELETE */ + "NONE"); + } + ++i; + pFK = pFK->pNextFrom; + } + } + } + } + break; +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + case PragTyp_FOREIGN_KEY_CHECK: { + FKey *pFK; /* A foreign key constraint */ + Table *pTab; /* Child table contain "REFERENCES" keyword */ + Table *pParent; /* Parent table that child points to */ + Index *pIdx; /* Index in the parent table */ + int i; /* Loop counter: Foreign key number for pTab */ + int j; /* Loop counter: Field of the foreign key */ + HashElem *k; /* Loop counter: Next table in schema */ + int x; /* result variable */ + int regResult; /* 3 registers to hold a result row */ + int regRow; /* Registers to hold a row from pTab */ + int addrTop; /* Top of a loop checking foreign keys */ + int addrOk; /* Jump here if the key is OK */ + int *aiCols; /* child to parent column mapping */ + + regResult = pParse->nMem+1; + pParse->nMem += 4; + regRow = ++pParse->nMem; + k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); + while( k ){ + if( zRight ){ + pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); + k = 0; + }else{ + pTab = (Table*)sqliteHashData(k); + k = sqliteHashNext(k); + } + if( pTab==0 || !IsOrdinaryTable(pTab) || pTab->u.tab.pFKey==0 ) continue; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zDb = db->aDb[iDb].zDbSName; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + sqlite3TouchRegister(pParse, pTab->nCol+regRow); + sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); + sqlite3VdbeLoadString(v, regResult, pTab->zName); + assert( IsOrdinaryTable(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + if( pParent==0 ) continue; + pIdx = 0; + sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); + if( x==0 ){ + if( pIdx==0 ){ + sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); + }else{ + sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + } + }else{ + k = 0; + break; + } + } + assert( pParse->nErr>0 || pFK==0 ); + if( pFK ) break; + if( pParse->nTabnTab = i; + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); + assert( IsOrdinaryTable(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + pIdx = 0; + aiCols = 0; + if( pParent ){ + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); + assert( x==0 || db->mallocFailed ); + } + addrOk = sqlite3VdbeMakeLabel(pParse); + + /* Generate code to read the child key values into registers + ** regRow..regRow+n. If any of the child key values are NULL, this + ** row cannot cause an FK violation. Jump directly to addrOk in + ** this case. */ + sqlite3TouchRegister(pParse, regRow + pFK->nCol); + for(j=0; jnCol; j++){ + int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; + sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); + } + + /* Generate code to query the parent index for a matching parent + ** key. If a match is found, jump to addrOk. */ + if( pIdx ){ + sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0, + sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol); + VdbeCoverage(v); + }else if( pParent ){ + int jmp = sqlite3VdbeCurrentAddr(v)+2; + sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); + sqlite3VdbeGoto(v, addrOk); + assert( pFK->nCol==1 || db->mallocFailed ); + } + + /* Generate code to report an FK violation to the caller. */ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); + } + sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); + sqlite3VdbeResolveLabel(v, addrOk); + sqlite3DbFree(db, aiCols); + } + sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + } + } + break; +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA + /* Reinstall the LIKE and GLOB functions. The variant of LIKE + ** used will be case sensitive or not depending on the RHS. + */ + case PragTyp_CASE_SENSITIVE_LIKE: { + if( zRight ){ + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); + } + } + break; +#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */ + +#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX +# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 +#endif + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + /* PRAGMA integrity_check + ** PRAGMA integrity_check(N) + ** PRAGMA quick_check + ** PRAGMA quick_check(N) + ** + ** Verify the integrity of the database. + ** + ** The "quick_check" is reduced version of + ** integrity_check designed to detect most database corruption + ** without the overhead of cross-checking indexes. Quick_check + ** is linear time whereas integrity_check is O(NlogN). + ** + ** The maximum number of errors is 100 by default. A different default + ** can be specified using a numeric parameter N. + ** + ** Or, the parameter N can be the name of a table. In that case, only + ** the one table named is verified. The freelist is only verified if + ** the named table is "sqlite_schema" (or one of its aliases). + ** + ** All schemas are checked by default. To check just a single + ** schema, use the form: + ** + ** PRAGMA schema.integrity_check; + */ + case PragTyp_INTEGRITY_CHECK: { + int i, j, addr, mxErr; + Table *pObjTab = 0; /* Check only this one table, if not NULL */ + + int isQuick = (sqlite3Tolower(zLeft[0])=='q'); + + /* If the PRAGMA command was of the form "PRAGMA .integrity_check", + ** then iDb is set to the index of the database identified by . + ** In this case, the integrity of database iDb only is verified by + ** the VDBE created below. + ** + ** Otherwise, if the command was simply "PRAGMA integrity_check" (or + ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb + ** to -1 here, to indicate that the VDBE should verify the integrity + ** of all attached databases. */ + assert( iDb>=0 ); + assert( iDb==0 || pId2->z ); + if( pId2->z==0 ) iDb = -1; + + /* Initialize the VDBE program */ + pParse->nMem = 6; + + /* Set the maximum error count */ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + if( zRight ){ + if( sqlite3GetInt32(zRight, &mxErr) ){ + if( mxErr<=0 ){ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + } + }else{ + pObjTab = sqlite3LocateTable(pParse, 0, zRight, + iDb>=0 ? db->aDb[iDb].zDbSName : 0); + } + } + sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */ + + /* Do an integrity check on each database file */ + for(i=0; inDb; i++){ + HashElem *x; /* For looping over tables in the schema */ + Hash *pTbls; /* Set of all tables in the schema */ + int *aRoot; /* Array of root page numbers of all btrees */ + int cnt = 0; /* Number of entries in aRoot[] */ + int mxIdx = 0; /* Maximum number of indexes for any table */ + + if( OMIT_TEMPDB && i==1 ) continue; + if( iDb>=0 && i!=iDb ) continue; + + sqlite3CodeVerifySchema(pParse, i); + pParse->okConstFactor = 0; /* tag-20230327-1 */ + + /* Do an integrity check of the B-Tree + ** + ** Begin by finding the root pages numbers + ** for all tables and indices in the database. + */ + assert( sqlite3SchemaMutexHeld(db, i, 0) ); + pTbls = &db->aDb[i].pSchema->tblHash; + for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); /* Current table */ + Index *pIdx; /* An index on pTab */ + int nIdx; /* Number of indexes on pTab */ + if( pObjTab && pObjTab!=pTab ) continue; + if( HasRowid(pTab) ) cnt++; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } + if( nIdx>mxIdx ) mxIdx = nIdx; + } + if( cnt==0 ) continue; + if( pObjTab ) cnt++; + aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); + if( aRoot==0 ) break; + cnt = 0; + if( pObjTab ) aRoot[++cnt] = 0; + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( pObjTab && pObjTab!=pTab ) continue; + if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + aRoot[++cnt] = pIdx->tnum; + } + } + aRoot[0] = cnt; + + /* Make sure sufficient number of registers have been allocated */ + sqlite3TouchRegister(pParse, 8+mxIdx); + sqlite3ClearTempRegCache(pParse); + + /* Do the b-tree integrity checks */ + sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); + sqlite3VdbeChangeP5(v, (u8)i); + addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), + P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, addr); + + /* Make sure all the indices are constructed correctly. + */ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx, *pPk; + Index *pPrior = 0; /* Previous index */ + int loopTop; + int iDataCur, iIdxCur; + int r1 = -1; + int bStrict; /* True for a STRICT table */ + int r2; /* Previous key for WITHOUT ROWID tables */ + int mxCol; /* Maximum non-virtual column number */ + + if( pObjTab && pObjTab!=pTab ) continue; + if( !IsOrdinaryTable(pTab) ) continue; + if( isQuick || HasRowid(pTab) ){ + pPk = 0; + r2 = 0; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + r2 = sqlite3GetTempRange(pParse, pPk->nKeyCol); + sqlite3VdbeAddOp3(v, OP_Null, 1, r2, r2+pPk->nKeyCol-1); + } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, + 1, 0, &iDataCur, &iIdxCur); + /* reg[7] counts the number of entries in the table. + ** reg[8+i] counts the number of entries in the i-th index + */ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ + } + assert( pParse->nMem>=8+j ); + assert( sqlite3NoTempsInRange(pParse,1,7+j) ); + sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); + loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + + /* Fetch the right-most column from the table. This will cause + ** the entire record header to be parsed and sanity checked. It + ** will also prepopulate the cursor column cache that is used + ** by the OP_IsType code, so it is a required step. + */ + assert( !IsVirtual(pTab) ); + if( HasRowid(pTab) ){ + mxCol = -1; + for(j=0; jnCol; j++){ + if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++; + } + if( mxCol==pTab->iPKey ) mxCol--; + }else{ + /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID + ** PK index column-count, so there is no need to account for them + ** in this case. */ + mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1; + } + if( mxCol>=0 ){ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3); + sqlite3VdbeTypeofColumn(v, 3); + } + + if( !isQuick ){ + if( pPk ){ + /* Verify WITHOUT ROWID keys are in ascending order */ + int a1; + char *zErr; + a1 = sqlite3VdbeAddOp4Int(v, OP_IdxGT, iDataCur, 0,r2,pPk->nKeyCol); + VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); + zErr = sqlite3MPrintf(db, + "row not in PRIMARY KEY order for %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + sqlite3VdbeJumpHere(v, a1+1); + for(j=0; jnKeyCol; j++){ + sqlite3ExprCodeLoadIndexColumn(pParse, pPk, iDataCur, j, r2+j); + } + } + } + /* Verify datatypes for all columns: + ** + ** (1) NOT NULL columns may not contain a NULL + ** (2) Datatype must be exact for non-ANY columns in STRICT tables + ** (3) Datatype for TEXT columns in non-STRICT tables must be + ** NULL, TEXT, or BLOB. + ** (4) Datatype for numeric columns in non-STRICT tables must not + ** be a TEXT value that can be losslessly converted to numeric. + */ + bStrict = (pTab->tabFlags & TF_Strict)!=0; + for(j=0; jnCol; j++){ + char *zErr; + Column *pCol = pTab->aCol + j; /* The column to be checked */ + int labelError; /* Jump here to report an error */ + int labelOk; /* Jump here if all looks ok */ + int p1, p3, p4; /* Operands to the OP_IsType opcode */ + int doTypeCheck; /* Check datatypes (besides NOT NULL) */ + + if( j==pTab->iPKey ) continue; + if( bStrict ){ + doTypeCheck = pCol->eCType>COLTYPE_ANY; + }else{ + doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB; + } + if( pCol->notNull==0 && !doTypeCheck ) continue; + + /* Compute the operands that will be needed for OP_IsType */ + p4 = SQLITE_NULL; + if( pCol->colFlags & COLFLAG_VIRTUAL ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + p1 = -1; + p3 = 3; + }else{ + if( pCol->iDflt ){ + sqlite3_value *pDfltValue = 0; + sqlite3ValueFromExpr(db, sqlite3ColumnExpr(pTab,pCol), ENC(db), + pCol->affinity, &pDfltValue); + if( pDfltValue ){ + p4 = sqlite3_value_type(pDfltValue); + sqlite3ValueFree(pDfltValue); + } + } + p1 = iDataCur; + if( !HasRowid(pTab) ){ + testcase( j!=sqlite3TableColumnToStorage(pTab, j) ); + p3 = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), j); + }else{ + p3 = sqlite3TableColumnToStorage(pTab,j); + testcase( p3!=j); + } + } + + labelError = sqlite3VdbeMakeLabel(pParse); + labelOk = sqlite3VdbeMakeLabel(pParse); + if( pCol->notNull ){ + /* (1) NOT NULL columns may not contain a NULL */ + int jmp3; + int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + VdbeCoverage(v); + if( p1<0 ){ + sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */ + jmp3 = jmp2; + }else{ + sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */ + /* OP_IsType does not detect NaN values in the database file + ** which should be treated as a NULL. So if the header type + ** is REAL, we have to load the actual data using OP_Column + ** to reliably determine if the value is a NULL. */ + sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); + sqlite3ColumnDefault(v, pTab, j, 3); + jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); + VdbeCoverage(v); + } + zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, + pCol->zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + if( doTypeCheck ){ + sqlite3VdbeGoto(v, labelError); + sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeJumpHere(v, jmp3); + }else{ + /* VDBE byte code will fall thru */ + } + } + if( bStrict && doTypeCheck ){ + /* (2) Datatype must be exact for non-ANY columns in STRICT tables*/ + static unsigned char aStdTypeMask[] = { + 0x1f, /* ANY */ + 0x18, /* BLOB */ + 0x11, /* INT */ + 0x11, /* INTEGER */ + 0x13, /* REAL */ + 0x14 /* TEXT */ + }; + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) ); + sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]); + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", + sqlite3StdType[pCol->eCType-1], + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + }else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ + /* (3) Datatype for TEXT columns in non-STRICT tables must be + ** NULL, TEXT, or BLOB. */ + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s", + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + }else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ + /* (4) Datatype for numeric columns in non-STRICT tables must not + ** be a TEXT value that can be converted to numeric. */ + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */ + VdbeCoverage(v); + if( p1>=0 ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + } + sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC); + sqlite3VdbeAddOp4Int(v, OP_IsType, -1, labelOk, 3, p4); + sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "TEXT value in %s.%s", + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + } + sqlite3VdbeResolveLabel(v, labelError); + integrityCheckResultRow(v); + sqlite3VdbeResolveLabel(v, labelOk); + } + /* Verify CHECK constraints */ + if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ + ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); + if( db->mallocFailed==0 ){ + int addrCkFault = sqlite3VdbeMakeLabel(pParse); + int addrCkOk = sqlite3VdbeMakeLabel(pParse); + char *zErr; + int k; + pParse->iSelfTab = iDataCur + 1; + for(k=pCheck->nExpr-1; k>0; k--){ + sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + } + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + SQLITE_JUMPIFNULL); + sqlite3VdbeResolveLabel(v, addrCkFault); + pParse->iSelfTab = 0; + zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v); + sqlite3VdbeResolveLabel(v, addrCkOk); + } + sqlite3ExprListDelete(db, pCheck); + } + if( !isQuick ){ /* Omit the remaining tests for quick_check */ + /* Validate index entries for the current row */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + int jmp2, jmp3, jmp4, jmp5, label6; + int kk; + int ckUniq = sqlite3VdbeMakeLabel(pParse); + if( pPk==pIdx ) continue; + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, + pPrior, r1); + pPrior = pIdx; + sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ + /* Verify that an index entry exists for the current table row */ + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + pIdx->nColumn); VdbeCoverage(v); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " missing from index "); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp4 = integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, jmp2); + + /* The OP_IdxRowid opcode is an optimized version of OP_Column + ** that extracts the rowid off the end of the index record. + ** But it only works correctly if index record does not have + ** any extra bytes at the end. Verify that this is the case. */ + if( HasRowid(pTab) ){ + int jmp7; + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3); + jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1); + VdbeCoverageNeverNull(v); + sqlite3VdbeLoadString(v, 3, + "rowid not at end-of-record for row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " of index "); + sqlite3VdbeGoto(v, jmp5-1); + sqlite3VdbeJumpHere(v, jmp7); + } + + /* Any indexed columns with non-BINARY collations must still hold + ** the exact same text value as the table. */ + label6 = 0; + for(kk=0; kknKeyCol; kk++){ + if( pIdx->azColl[kk]==sqlite3StrBINARY ) continue; + if( label6==0 ) label6 = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur+j, kk, 3); + sqlite3VdbeAddOp3(v, OP_Ne, 3, label6, r1+kk); VdbeCoverage(v); + } + if( label6 ){ + int jmp6 = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeResolveLabel(v, label6); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " values differ from index "); + sqlite3VdbeGoto(v, jmp5-1); + sqlite3VdbeJumpHere(v, jmp6); + } + + /* For UNIQUE indexes, verify that only one entry exists with the + ** current key. The entry is unique if (1) any column is NULL + ** or (2) the next entry has a different key */ + if( IsUniqueIndex(pIdx) ){ + int uniqOk = sqlite3VdbeMakeLabel(pParse); + int jmp6; + for(kk=0; kknKeyCol; kk++){ + int iCol = pIdx->aiColumn[kk]; + assert( iCol!=XN_ROWID && iColnCol ); + if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; + sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); + VdbeCoverage(v); + } + jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); + sqlite3VdbeGoto(v, uniqOk); + sqlite3VdbeJumpHere(v, jmp6); + sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, + pIdx->nKeyCol); VdbeCoverage(v); + sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); + sqlite3VdbeGoto(v, jmp5); + sqlite3VdbeResolveLabel(v, uniqOk); + } + sqlite3VdbeJumpHere(v, jmp4); + sqlite3ResolvePartIdxLabel(pParse, jmp3); + } + } + sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, loopTop-1); + if( !isQuick ){ + sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + if( pPk==pIdx ) continue; + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, addr); + } + if( pPk ){ + sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); + } + } + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Second pass to invoke the xIntegrity method on all virtual + ** tables. + */ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + sqlite3_vtab *pVTab; + int a1; + if( pObjTab && pObjTab!=pTab ) continue; + if( IsOrdinaryTable(pTab) ) continue; + if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); + pTab->nTabRef++; + sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + continue; + } +#endif + } + { + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList endCode[] = { + { OP_AddImm, 1, 0, 0}, /* 0 */ + { OP_IfNotZero, 1, 4, 0}, /* 1 */ + { OP_String8, 0, 3, 0}, /* 2 */ + { OP_ResultRow, 3, 1, 0}, /* 3 */ + { OP_Halt, 0, 0, 0}, /* 4 */ + { OP_String8, 0, 3, 0}, /* 5 */ + { OP_Goto, 0, 3, 0}, /* 6 */ + }; + VdbeOp *aOp; + + aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); + if( aOp ){ + aOp[0].p2 = 1-mxErr; + aOp[2].p4type = P4_STATIC; + aOp[2].p4.z = "ok"; + aOp[5].p4type = P4_STATIC; + aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT); + } + sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2); + } + } + break; +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_UTF16 + /* + ** PRAGMA encoding + ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" + ** + ** In its first form, this pragma returns the encoding of the main + ** database. If the database is not initialized, it is initialized now. + ** + ** The second form of this pragma is a no-op if the main database file + ** has not already been initialized. In this case it sets the default + ** encoding that will be used for the main database file if a new file + ** is created. If an existing main database file is opened, then the + ** default text encoding for the existing database is used. + ** + ** In all cases new databases created using the ATTACH command are + ** created to use the same default text encoding as the main database. If + ** the main database has not been initialized and/or created when ATTACH + ** is executed, this is done before the ATTACH operation. + ** + ** In the second form this pragma sets the text encoding to be used in + ** new database files created using this database handle. It is only + ** useful if invoked immediately after the main database i + */ + case PragTyp_ENCODING: { + static const struct EncName { + char *zName; + u8 enc; + } encnames[] = { + { "UTF8", SQLITE_UTF8 }, + { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */ + { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */ + { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */ + { "UTF16le", SQLITE_UTF16LE }, + { "UTF16be", SQLITE_UTF16BE }, + { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ + { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ + { 0, 0 } + }; + const struct EncName *pEnc; + if( !zRight ){ /* "PRAGMA encoding" */ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); + assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); + assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); + returnSingleText(v, encnames[ENC(pParse->db)].zName); + }else{ /* "PRAGMA encoding = XXX" */ + /* Only change the value of sqlite.enc if the database handle is not + ** initialized. If the main database exists, the new sqlite.enc value + ** will be overwritten when the schema is next loaded. If it does not + ** already exists, it will be created to use the new encoding value. + */ + if( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){ + for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ + if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ + u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; + SCHEMA_ENC(db) = enc; + sqlite3SetTextEncoding(db, enc); + break; + } + } + if( !pEnc->zName ){ + sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); + } + } + } + } + break; +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + /* + ** PRAGMA [schema.]schema_version + ** PRAGMA [schema.]schema_version = + ** + ** PRAGMA [schema.]user_version + ** PRAGMA [schema.]user_version = + ** + ** PRAGMA [schema.]freelist_count + ** + ** PRAGMA [schema.]data_version + ** + ** PRAGMA [schema.]application_id + ** PRAGMA [schema.]application_id = + ** + ** The pragma's schema_version and user_version are used to set or get + ** the value of the schema-version and user-version, respectively. Both + ** the schema-version and the user-version are 32-bit signed integers + ** stored in the database header. + ** + ** The schema-cookie is usually only manipulated internally by SQLite. It + ** is incremented by SQLite whenever the database schema is modified (by + ** creating or dropping a table or index). The schema version is used by + ** SQLite each time a query is executed to ensure that the internal cache + ** of the schema used when compiling the SQL query matches the schema of + ** the database against which the compiled query is actually executed. + ** Subverting this mechanism by using "PRAGMA schema_version" to modify + ** the schema-version is potentially dangerous and may lead to program + ** crashes or database corruption. Use with caution! + ** + ** The user-version is not used internally by SQLite. It may be used by + ** applications for any purpose. + */ + case PragTyp_HEADER_VALUE: { + int iCookie = pPragma->iArg; /* Which cookie to read or write */ + sqlite3VdbeUsesBtree(v, iDb); + if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){ + /* Write the specified cookie value */ + static const VdbeOpList setCookie[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_SetCookie, 0, 0, 0}, /* 1 */ + }; + VdbeOp *aOp; + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[1].p2 = iCookie; + aOp[1].p3 = sqlite3Atoi(zRight); + aOp[1].p5 = 1; + if( iCookie==BTREE_SCHEMA_VERSION && (db->flags & SQLITE_Defensive)!=0 ){ + /* Do not allow the use of PRAGMA schema_version=VALUE in defensive + ** mode. Change the OP_SetCookie opcode into a no-op. */ + aOp[1].opcode = OP_Noop; + } + }else{ + /* Read the specified cookie value */ + static const VdbeOpList readCookie[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, 0}, /* 1 */ + { OP_ResultRow, 1, 1, 0} + }; + VdbeOp *aOp; + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[1].p3 = iCookie; + sqlite3VdbeReusable(v); + } + } + break; +#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + /* + ** PRAGMA compile_options + ** + ** Return the names of all compile-time options used in this build, + ** one option per row. + */ + case PragTyp_COMPILE_OPTIONS: { + int i = 0; + const char *zOpt; + pParse->nMem = 1; + while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ + sqlite3VdbeLoadString(v, 1, zOpt); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + sqlite3VdbeReusable(v); + } + break; +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +#ifndef SQLITE_OMIT_WAL + /* + ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate + ** + ** Checkpoint the database. + */ + case PragTyp_WAL_CHECKPOINT: { + int iBt = (pId2->z?iDb:SQLITE_MAX_DB); + int eMode = SQLITE_CHECKPOINT_PASSIVE; + if( zRight ){ + if( sqlite3StrICmp(zRight, "full")==0 ){ + eMode = SQLITE_CHECKPOINT_FULL; + }else if( sqlite3StrICmp(zRight, "restart")==0 ){ + eMode = SQLITE_CHECKPOINT_RESTART; + }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ + eMode = SQLITE_CHECKPOINT_TRUNCATE; + } + } + pParse->nMem = 3; + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + } + break; + + /* + ** PRAGMA wal_autocheckpoint + ** PRAGMA wal_autocheckpoint = N + ** + ** Configure a database connection to automatically checkpoint a database + ** after accumulating N frames in the log. Or query for the current value + ** of N. + */ + case PragTyp_WAL_AUTOCHECKPOINT: { + if( zRight ){ + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); + } + returnSingleInt(v, + db->xWalCallback==sqlite3WalDefaultHook ? + SQLITE_PTR_TO_INT(db->pWalArg) : 0); + } + break; +#endif + + /* + ** PRAGMA shrink_memory + ** + ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database + ** connection on which it is invoked to free up as much memory as it + ** can, by calling sqlite3_db_release_memory(). + */ + case PragTyp_SHRINK_MEMORY: { + sqlite3_db_release_memory(db); + break; + } + + /* + ** PRAGMA optimize + ** PRAGMA optimize(MASK) + ** PRAGMA schema.optimize + ** PRAGMA schema.optimize(MASK) + ** + ** Attempt to optimize the database. All schemas are optimized in the first + ** two forms, and only the specified schema is optimized in the latter two. + ** + ** The details of optimizations performed by this pragma are expected + ** to change and improve over time. Applications should anticipate that + ** this pragma will perform new optimizations in future releases. + ** + ** The optional argument is a bitmask of optimizations to perform: + ** + ** 0x0001 Debugging mode. Do not actually perform any optimizations + ** but instead return one line of text for each optimization + ** that would have been done. Off by default. + ** + ** 0x0002 Run ANALYZE on tables that might benefit. On by default. + ** See below for additional information. + ** + ** 0x0004 (Not yet implemented) Record usage and performance + ** information from the current session in the + ** database file so that it will be available to "optimize" + ** pragmas run by future database connections. + ** + ** 0x0008 (Not yet implemented) Create indexes that might have + ** been helpful to recent queries + ** + ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all + ** of the optimizations listed above except Debug Mode, including new + ** optimizations that have not yet been invented. If new optimizations are + ** ever added that should be off by default, those off-by-default + ** optimizations will have bitmasks of 0x10000 or larger. + ** + ** DETERMINATION OF WHEN TO RUN ANALYZE + ** + ** In the current implementation, a table is analyzed if only if all of + ** the following are true: + ** + ** (1) MASK bit 0x02 is set. + ** + ** (2) The query planner used sqlite_stat1-style statistics for one or + ** more indexes of the table at some point during the lifetime of + ** the current connection. + ** + ** (3) One or more indexes of the table are currently unanalyzed OR + ** the number of rows in the table has increased by 25 times or more + ** since the last time ANALYZE was run. + ** + ** The rules for when tables are analyzed are likely to change in + ** future releases. + */ + case PragTyp_OPTIMIZE: { + int iDbLast; /* Loop termination point for the schema loop */ + int iTabCur; /* Cursor for a table whose size needs checking */ + HashElem *k; /* Loop over tables of a schema */ + Schema *pSchema; /* The current schema */ + Table *pTab; /* A table in the schema */ + Index *pIdx; /* An index of the table */ + LogEst szThreshold; /* Size threshold above which reanalysis needed */ + char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ + u32 opMask; /* Mask of operations to perform */ + + if( zRight ){ + opMask = (u32)sqlite3Atoi(zRight); + if( (opMask & 0x02)==0 ) break; + }else{ + opMask = 0xfffe; + } + iTabCur = pParse->nTab++; + for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ + if( iDb==1 ) continue; + sqlite3CodeVerifySchema(pParse, iDb); + pSchema = db->aDb[iDb].pSchema; + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + + /* If table pTab has not been used in a way that would benefit from + ** having analysis statistics during the current session, then skip it. + ** This also has the effect of skipping virtual tables and views */ + if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; + + /* Reanalyze if the table is 25 times larger than the last analysis */ + szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( !pIdx->hasStat1 ){ + szThreshold = 0; /* Always analyze if any index lacks statistics */ + break; + } + } + if( szThreshold ){ + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); + VdbeCoverage(v); + } + zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", + db->aDb[iDb].zDbSName, pTab->zName); + if( opMask & 0x01 ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); + }else{ + sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + } + } + } + sqlite3VdbeAddOp0(v, OP_Expire); + break; + } + + /* + ** PRAGMA busy_timeout + ** PRAGMA busy_timeout = N + ** + ** Call sqlite3_busy_timeout(db, N). Return the current timeout value + ** if one is set. If no busy handler or a different busy handler is set + ** then 0 is returned. Setting the busy_timeout to 0 or negative + ** disables the timeout. + */ + /*case PragTyp_BUSY_TIMEOUT*/ default: { + assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); + if( zRight ){ + sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); + } + returnSingleInt(v, db->busyTimeout); + break; + } + + /* + ** PRAGMA soft_heap_limit + ** PRAGMA soft_heap_limit = N + ** + ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the + ** sqlite3_soft_heap_limit64() interface with the argument N, if N is + ** specified and is a non-negative integer. + ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always + ** returns the same integer that would be returned by the + ** sqlite3_soft_heap_limit64(-1) C-language function. + */ + case PragTyp_SOFT_HEAP_LIMIT: { + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_soft_heap_limit64(N); + } + returnSingleInt(v, sqlite3_soft_heap_limit64(-1)); + break; + } + + /* + ** PRAGMA hard_heap_limit + ** PRAGMA hard_heap_limit = N + ** + ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap + ** limit. The hard heap limit can be activated or lowered by this + ** pragma, but not raised or deactivated. Only the + ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate + ** the hard heap limit. This allows an application to set a heap limit + ** constraint that cannot be relaxed by an untrusted SQL script. + */ + case PragTyp_HARD_HEAP_LIMIT: { + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1); + if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N); + } + returnSingleInt(v, sqlite3_hard_heap_limit64(-1)); + break; + } + + /* + ** PRAGMA threads + ** PRAGMA threads = N + ** + ** Configure the maximum number of worker threads. Return the new + ** maximum, which might be less than requested. + */ + case PragTyp_THREADS: { + sqlite3_int64 N; + if( zRight + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK + && N>=0 + ){ + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); + } + returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); + break; + } + + /* + ** PRAGMA analysis_limit + ** PRAGMA analysis_limit = N + ** + ** Configure the maximum number of rows that ANALYZE will examine + ** in each index that it looks at. Return the new limit. + */ + case PragTyp_ANALYSIS_LIMIT: { + sqlite3_int64 N; + if( zRight + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK /* IMP: R-40975-20399 */ + && N>=0 + ){ + db->nAnalysisLimit = (int)(N&0x7fffffff); + } + returnSingleInt(v, db->nAnalysisLimit); /* IMP: R-57594-65522 */ + break; + } + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* + ** Report the current state of file logs for all databases + */ + case PragTyp_LOCK_STATUS: { + static const char *const azLockName[] = { + "unlocked", "shared", "reserved", "pending", "exclusive" + }; + int i; + pParse->nMem = 2; + for(i=0; inDb; i++){ + Btree *pBt; + const char *zState = "unknown"; + int j; + if( db->aDb[i].zDbSName==0 ) continue; + pBt = db->aDb[i].pBt; + if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ + zState = "closed"; + }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, + SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ + zState = azLockName[j]; + } + sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); + } + break; + } +#endif + +#if defined(SQLITE_ENABLE_CEROD) + case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ + if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ + sqlite3_activate_cerod(&zRight[6]); + } + } + break; +#endif + + } /* End of the PRAGMA switch */ + + /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only + ** purpose is to execute assert() statements to verify that if the + ** PragFlg_NoColumns1 flag is set and the caller specified an argument + ** to the PRAGMA, the implementation has not added any OP_ResultRow + ** instructions to the VM. */ + if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ + sqlite3VdbeVerifyNoResultRow(v); + } + +pragma_out: + sqlite3DbFree(db, zLeft); + sqlite3DbFree(db, zRight); +} +#ifndef SQLITE_OMIT_VIRTUALTABLE +/***************************************************************************** +** Implementation of an eponymous virtual table that runs a pragma. +** +*/ +typedef struct PragmaVtab PragmaVtab; +typedef struct PragmaVtabCursor PragmaVtabCursor; +struct PragmaVtab { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database connection to which it belongs */ + const PragmaName *pName; /* Name of the pragma */ + u8 nHidden; /* Number of hidden columns */ + u8 iHidden; /* Index of the first hidden column */ +}; +struct PragmaVtabCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pPragma; /* The pragma statement to run */ + sqlite_int64 iRowid; /* Current rowid */ + char *azArg[2]; /* Value of the argument and schema */ +}; + +/* +** Pragma virtual table module xConnect method. +*/ +static int pragmaVtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + const PragmaName *pPragma = (const PragmaName*)pAux; + PragmaVtab *pTab = 0; + int rc; + int i, j; + char cSep = '('; + StrAccum acc; + char zBuf[200]; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3_str_appendall(&acc, "CREATE TABLE x"); + for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ + sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); + cSep = ','; + } + if( i==0 ){ + sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); + i++; + } + j = 0; + if( pPragma->mPragFlg & PragFlg_Result1 ){ + sqlite3_str_appendall(&acc, ",arg HIDDEN"); + j++; + } + if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ + sqlite3_str_appendall(&acc, ",schema HIDDEN"); + j++; + } + sqlite3_str_append(&acc, ")", 1); + sqlite3StrAccumFinish(&acc); + assert( strlen(zBuf) < sizeof(zBuf)-1 ); + rc = sqlite3_declare_vtab(db, zBuf); + if( rc==SQLITE_OK ){ + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pTab, 0, sizeof(PragmaVtab)); + pTab->pName = pPragma; + pTab->db = db; + pTab->iHidden = i; + pTab->nHidden = j; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Pragma virtual table module xDisconnect method. +*/ +static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ + PragmaVtab *pTab = (PragmaVtab*)pVtab; + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* Figure out the best index to use to search a pragma virtual table. +** +** There are not really any index choices. But we want to encourage the +** query planner to give == constraints on as many hidden parameters as +** possible, and especially on the first hidden parameter. So return a +** high cost if hidden parameters are unconstrained. +*/ +static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + PragmaVtab *pTab = (PragmaVtab*)tab; + const struct sqlite3_index_constraint *pConstraint; + int i, j; + int seen[2]; + + pIdxInfo->estimatedCost = (double)1; + if( pTab->nHidden==0 ){ return SQLITE_OK; } + pConstraint = pIdxInfo->aConstraint; + seen[0] = 0; + seen[1] = 0; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->iColumn < pTab->iHidden ) continue; + j = pConstraint->iColumn - pTab->iHidden; + assert( j < 2 ); + seen[j] = i+1; + } + if( seen[0]==0 ){ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = 2147483647; + return SQLITE_OK; + } + j = seen[0]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 1; + pIdxInfo->aConstraintUsage[j].omit = 1; + if( seen[1]==0 ){ + pIdxInfo->estimatedCost = (double)1000; + pIdxInfo->estimatedRows = 1000; + return SQLITE_OK; + } + pIdxInfo->estimatedCost = (double)20; + pIdxInfo->estimatedRows = 20; + j = seen[1]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 2; + pIdxInfo->aConstraintUsage[j].omit = 1; + return SQLITE_OK; +} + +/* Create a new cursor for the pragma virtual table */ +static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ + PragmaVtabCursor *pCsr; + pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr)); + if( pCsr==0 ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(PragmaVtabCursor)); + pCsr->base.pVtab = pVtab; + *ppCursor = &pCsr->base; + return SQLITE_OK; +} + +/* Clear all content from pragma virtual table cursor. */ +static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ + int i; + sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + for(i=0; iazArg); i++){ + sqlite3_free(pCsr->azArg[i]); + pCsr->azArg[i] = 0; + } +} + +/* Close a pragma virtual table cursor */ +static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; + pragmaVtabCursorClear(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* Advance the pragma virtual table cursor to the next row */ +static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + int rc = SQLITE_OK; + + /* Increment the xRowid value */ + pCsr->iRowid++; + assert( pCsr->pPragma ); + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + pragmaVtabCursorClear(pCsr); + } + return rc; +} + +/* +** Pragma virtual table module xFilter method. +*/ +static int pragmaVtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + int rc; + int i, j; + StrAccum acc; + char *zSql; + + UNUSED_PARAMETER(idxNum); + UNUSED_PARAMETER(idxStr); + pragmaVtabCursorClear(pCsr); + j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; + for(i=0; iazArg) ); + assert( pCsr->azArg[j]==0 ); + if( zText ){ + pCsr->azArg[j] = sqlite3_mprintf("%s", zText); + if( pCsr->azArg[j]==0 ){ + return SQLITE_NOMEM; + } + } + } + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); + sqlite3_str_appendall(&acc, "PRAGMA "); + if( pCsr->azArg[1] ){ + sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]); + } + sqlite3_str_appendall(&acc, pTab->pName->zName); + if( pCsr->azArg[0] ){ + sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]); + } + zSql = sqlite3StrAccumFinish(&acc); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); + sqlite3_free(zSql); + if( rc!=SQLITE_OK ){ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + return rc; + } + return pragmaVtabNext(pVtabCursor); +} + +/* +** Pragma virtual table module xEof method. +*/ +static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + return (pCsr->pPragma==0); +} + +/* The xColumn method simply returns the corresponding column from +** the PRAGMA. +*/ +static int pragmaVtabColumn( + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, + int i +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + if( iiHidden ){ + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i)); + }else{ + sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); + } + return SQLITE_OK; +} + +/* +** Pragma virtual table module xRowid method. +*/ +static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + *p = pCsr->iRowid; + return SQLITE_OK; +} + +/* The pragma virtual table object */ +static const sqlite3_module pragmaVtabModule = { + 0, /* iVersion */ + 0, /* xCreate - create a table */ + pragmaVtabConnect, /* xConnect - connect to an existing table */ + pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */ + pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */ + 0, /* xDestroy - Drop a table */ + pragmaVtabOpen, /* xOpen - open a cursor */ + pragmaVtabClose, /* xClose - close a cursor */ + pragmaVtabFilter, /* xFilter - configure scan constraints */ + pragmaVtabNext, /* xNext - advance a cursor */ + pragmaVtabEof, /* xEof */ + pragmaVtabColumn, /* xColumn - read data */ + pragmaVtabRowid, /* xRowid - read data */ + 0, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + 0, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ +}; + +/* +** Check to see if zTabName is really the name of a pragma. If it is, +** then register an eponymous virtual table for that pragma and return +** a pointer to the Module object for the new virtual table. +*/ +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ + const PragmaName *pName; + assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 ); + pName = pragmaLocate(zName+7); + if( pName==0 ) return 0; + if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; + assert( sqlite3HashFind(&db->aModule, zName)==0 ); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#endif /* SQLITE_OMIT_PRAGMA */ + +/************** End of pragma.c **********************************************/ +/************** Begin file prepare.c *****************************************/ +/* +** 2005 May 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the implementation of the sqlite3_prepare() +** interface, and routines that contribute to loading the database schema +** from disk. +*/ +/* #include "sqliteInt.h" */ + +/* +** Fill the InitData structure with an error message that indicates +** that the database is corrupt. +*/ +static void corruptSchema( + InitData *pData, /* Initialization context */ + char **azObj, /* Type and name of object being parsed */ + const char *zExtra /* Error information */ +){ + sqlite3 *db = pData->db; + if( db->mallocFailed ){ + pData->rc = SQLITE_NOMEM_BKPT; + }else if( pData->pzErrMsg[0]!=0 ){ + /* A error message has already been generated. Do not overwrite it */ + }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){ + static const char *azAlterType[] = { + "rename", + "drop column", + "add column" + }; + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1], + zExtra + ); + pData->rc = SQLITE_ERROR; + }else if( db->flags & SQLITE_WriteSchema ){ + pData->rc = SQLITE_CORRUPT_BKPT; + }else{ + char *z; + const char *zObj = azObj[1] ? azObj[1] : "?"; + z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); + if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); + *pData->pzErrMsg = z; + pData->rc = SQLITE_CORRUPT_BKPT; + } +} + +/* +** Check to see if any sibling index (another index on the same table) +** of pIndex has the same root page number, and if it does, return true. +** This would indicate a corrupt schema. +*/ +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){ + Index *p; + for(p=pIndex->pTable->pIndex; p; p=p->pNext){ + if( p->tnum==pIndex->tnum && p!=pIndex ) return 1; + } + return 0; +} + +/* forward declaration */ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +); + + +/* +** This is the callback routine for the code that initializes the +** database. See sqlite3Init() below for additional information. +** This routine is also called from the OP_ParseSchema opcode of the VDBE. +** +** Each callback contains the following information: +** +** argv[0] = type of object: "table", "index", "trigger", or "view". +** argv[1] = name of thing being created +** argv[2] = associated table if an index or trigger +** argv[3] = root page number for table or index. 0 for trigger or view. +** argv[4] = SQL text for the CREATE statement. +** +*/ +SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ + InitData *pData = (InitData*)pInit; + sqlite3 *db = pData->db; + int iDb = pData->iDb; + + assert( argc==5 ); + UNUSED_PARAMETER2(NotUsed, argc); + assert( sqlite3_mutex_held(db->mutex) ); + db->mDbFlags |= DBFLAG_EncodingFixed; + if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ + pData->nInitRow++; + if( db->mallocFailed ){ + corruptSchema(pData, argv, 0); + return 1; + } + + assert( iDb>=0 && iDbnDb ); + if( argv[3]==0 ){ + corruptSchema(pData, argv, 0); + }else if( argv[4] + && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]] + && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){ + /* Call the parser to process a CREATE TABLE, INDEX or VIEW. + ** But because db->init.busy is set to 1, no VDBE code is generated + ** or executed. All the parser does is build the internal data + ** structures that describe the table, index, or view. + ** + ** No other valid SQL statement, other than the variable CREATE statements, + ** can begin with the letters "C" and "R". Thus, it is not possible run + ** any other kind of statement while parsing the schema, even a corrupt + ** schema. + */ + int rc; + u8 saved_iDb = db->init.iDb; + sqlite3_stmt *pStmt; + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ + + assert( db->init.busy ); + db->init.iDb = iDb; + if( sqlite3GetUInt32(argv[3], &db->init.newTnum)==0 + || (db->init.newTnum>pData->mxPage && pData->mxPage>0) + ){ + if( sqlite3Config.bExtraSchemaChecks ){ + corruptSchema(pData, argv, "invalid rootpage"); + } + } + db->init.orphanTrigger = 0; + db->init.azInit = (const char**)argv; + pStmt = 0; + TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); + rc = db->errCode; + assert( (rc&0xFF)==(rcp&0xFF) ); + db->init.iDb = saved_iDb; + /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */ + if( SQLITE_OK!=rc ){ + if( db->init.orphanTrigger ){ + assert( iDb==1 ); + }else{ + if( rc > pData->rc ) pData->rc = rc; + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ + corruptSchema(pData, argv, sqlite3_errmsg(db)); + } + } + } + db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ + sqlite3_finalize(pStmt); + }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ + corruptSchema(pData, argv, 0); + }else{ + /* If the SQL column is blank it means this is an index that + ** was created to be the PRIMARY KEY or to fulfill a UNIQUE + ** constraint for a CREATE TABLE. The index should have already + ** been created when we processed the CREATE TABLE. All we have + ** to do here is record the root page number for that index. + */ + Index *pIndex; + pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); + if( pIndex==0 ){ + corruptSchema(pData, argv, "orphan index"); + }else + if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0 + || pIndex->tnum<2 + || pIndex->tnum>pData->mxPage + || sqlite3IndexHasDuplicateRootPage(pIndex) + ){ + if( sqlite3Config.bExtraSchemaChecks ){ + corruptSchema(pData, argv, "invalid rootpage"); + } + } + } + return 0; +} + +/* +** Attempt to read the database schema and initialize internal +** data structures for a single database file. The index of the +** database file is given by iDb. iDb==0 is used for the main +** database. iDb==1 should never be used. iDb>=2 is used for +** auxiliary databases. Return one of the SQLITE_ error codes to +** indicate success or failure. +*/ +SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ + int rc; + int i; +#ifndef SQLITE_OMIT_DEPRECATED + int size; +#endif + Db *pDb; + char const *azArg[6]; + int meta[5]; + InitData initData; + const char *zSchemaTabName; + int openedTransaction = 0; + int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed); + + assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + + db->init.busy = 1; + + /* Construct the in-memory representation schema tables (sqlite_schema or + ** sqlite_temp_schema) by invoking the parser directly. The appropriate + ** table name will be inserted automatically by the parser so we can just + ** use the abbreviation "x" here. The parser will also automatically tag + ** the schema table as read-only. */ + azArg[0] = "table"; + azArg[1] = zSchemaTabName = SCHEMA_TABLE(iDb); + azArg[2] = azArg[1]; + azArg[3] = "1"; + azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text," + "rootpage int,sql text)"; + azArg[5] = 0; + initData.db = db; + initData.iDb = iDb; + initData.rc = SQLITE_OK; + initData.pzErrMsg = pzErrMsg; + initData.mInitFlags = mFlags; + initData.nInitRow = 0; + initData.mxPage = 0; + sqlite3InitCallback(&initData, 5, (char **)azArg, 0); + db->mDbFlags &= mask; + if( initData.rc ){ + rc = initData.rc; + goto error_out; + } + + /* Create a cursor to hold the database open + */ + pDb = &db->aDb[iDb]; + if( pDb->pBt==0 ){ + assert( iDb==1 ); + DbSetProperty(db, 1, DB_SchemaLoaded); + rc = SQLITE_OK; + goto error_out; + } + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed before this function returns. */ + sqlite3BtreeEnter(pDb->pBt); + if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){ + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); + if( rc!=SQLITE_OK ){ + sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); + goto initone_error_out; + } + openedTransaction = 1; + } + + /* Get the database meta information. + ** + ** Meta values are as follows: + ** meta[0] Schema cookie. Changes with each schema change. + ** meta[1] File format of schema layer. + ** meta[2] Size of the page cache. + ** meta[3] Largest rootpage (auto/incr_vacuum mode) + ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE + ** meta[5] User version + ** meta[6] Incremental vacuum mode + ** meta[7] unused + ** meta[8] unused + ** meta[9] unused + ** + ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to + ** the possible values of meta[4]. + */ + for(i=0; ipBt, i+1, (u32 *)&meta[i]); + } + if( (db->flags & SQLITE_ResetDatabase)!=0 ){ + memset(meta, 0, sizeof(meta)); + } + pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; + + /* If opening a non-empty database, check the text encoding. For the + ** main database, set sqlite3.enc to the encoding of the main database. + ** For an attached db, it is an error if the encoding is not the same + ** as sqlite3.enc. + */ + if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ + if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){ + u8 encoding; +#ifndef SQLITE_OMIT_UTF16 + /* If opening the main database, set ENC(db). */ + encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; + if( encoding==0 ) encoding = SQLITE_UTF8; +#else + encoding = SQLITE_UTF8; +#endif + if( db->nVdbeActive>0 && encoding!=ENC(db) + && (db->mDbFlags & DBFLAG_Vacuum)==0 + ){ + rc = SQLITE_LOCKED; + goto initone_error_out; + }else{ + sqlite3SetTextEncoding(db, encoding); + } + }else{ + /* If opening an attached database, the encoding much match ENC(db) */ + if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ + sqlite3SetString(pzErrMsg, db, "attached databases must use the same" + " text encoding as main database"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + } + } + pDb->pSchema->enc = ENC(db); + + if( pDb->pSchema->cache_size==0 ){ +#ifndef SQLITE_OMIT_DEPRECATED + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); + if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } + pDb->pSchema->cache_size = size; +#else + pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; +#endif + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + + /* + ** file_format==1 Version 3.0.0. + ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN + ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults + ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants + */ + pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1]; + if( pDb->pSchema->file_format==0 ){ + pDb->pSchema->file_format = 1; + } + if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ + sqlite3SetString(pzErrMsg, db, "unsupported file format"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + + /* Ticket #2804: When we open a database in the newer file format, + ** clear the legacy_file_format pragma flag so that a VACUUM will + ** not downgrade the database and thus invalidate any descending + ** indices that the user might have created. + */ + if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){ + db->flags &= ~(u64)SQLITE_LegacyFileFmt; + } + + /* Read the schema information out of the schema tables + */ + assert( db->init.busy ); + initData.mxPage = sqlite3BtreeLastPage(pDb->pBt); + { + char *zSql; + zSql = sqlite3MPrintf(db, + "SELECT*FROM\"%w\".%s ORDER BY rowid", + db->aDb[iDb].zDbSName, zSchemaTabName); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + sqlite3_xauth xAuth; + xAuth = db->xAuth; + db->xAuth = 0; +#endif + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; + } +#endif + if( rc==SQLITE_OK ) rc = initData.rc; + sqlite3DbFree(db, zSql); +#ifndef SQLITE_OMIT_ANALYZE + if( rc==SQLITE_OK ){ + sqlite3AnalysisLoad(db, iDb); + } +#endif + } + assert( pDb == &(db->aDb[iDb]) ); + if( db->mallocFailed ){ + rc = SQLITE_NOMEM_BKPT; + sqlite3ResetAllSchemasOfConnection(db); + pDb = &db->aDb[iDb]; + }else + if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){ + /* Hack: If the SQLITE_NoSchemaError flag is set, then consider + ** the schema loaded, even if errors (other than OOM) occurred. In + ** this situation the current sqlite3_prepare() operation will fail, + ** but the following one will attempt to compile the supplied statement + ** against whatever subset of the schema was loaded before the error + ** occurred. + ** + ** The primary purpose of this is to allow access to the sqlite_schema + ** table even when its contents have been corrupted. + */ + DbSetProperty(db, iDb, DB_SchemaLoaded); + rc = SQLITE_OK; + } + + /* Jump here for an error that occurs after successfully allocating + ** curMain and calling sqlite3BtreeEnter(). For an error that occurs + ** before that point, jump to error_out. + */ +initone_error_out: + if( openedTransaction ){ + sqlite3BtreeCommit(pDb->pBt); + } + sqlite3BtreeLeave(pDb->pBt); + +error_out: + if( rc ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + } + sqlite3ResetOneSchema(db, iDb); + } + db->init.busy = 0; + return rc; +} + +/* +** Initialize all database files - the main database file, the file +** used to store temporary tables, and any additional database files +** created using ATTACH statements. Return a success code. If an +** error occurs, write an error message into *pzErrMsg. +** +** After a database is initialized, the DB_SchemaLoaded bit is set +** bit is set in the flags field of the Db structure. +*/ +SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ + int i, rc; + int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange); + + assert( sqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); + assert( db->init.busy==0 ); + ENC(db) = SCHEMA_ENC(db); + assert( db->nDb>0 ); + /* Do the main schema first */ + if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 0, pzErrMsg, 0); + if( rc ) return rc; + } + /* All other schemas after the main schema. The "temp" schema must be last */ + for(i=db->nDb-1; i>0; i--){ + assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); + if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, i, pzErrMsg, 0); + if( rc ) return rc; + } + } + if( commit_internal ){ + sqlite3CommitInternalChanges(db); + } + return SQLITE_OK; +} + +/* +** This routine is a no-op if the database schema is already initialized. +** Otherwise, the schema is loaded. An error code is returned. +*/ +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){ + int rc = SQLITE_OK; + sqlite3 *db = pParse->db; + assert( sqlite3_mutex_held(db->mutex) ); + if( !db->init.busy ){ + rc = sqlite3Init(db, &pParse->zErrMsg); + if( rc!=SQLITE_OK ){ + pParse->rc = rc; + pParse->nErr++; + }else if( db->noSharedCache ){ + db->mDbFlags |= DBFLAG_SchemaKnownOk; + } + } + return rc; +} + + +/* +** Check schema cookies in all databases. If any cookie is out +** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies +** make no changes to pParse->rc. +*/ +static void schemaIsValid(Parse *pParse){ + sqlite3 *db = pParse->db; + int iDb; + int rc; + int cookie; + + assert( pParse->checkSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + for(iDb=0; iDbnDb; iDb++){ + int openedTransaction = 0; /* True if a transaction is opened */ + Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ + if( pBt==0 ) continue; + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed immediately after reading the meta-value. */ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + pParse->rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ) return; + openedTransaction = 1; + } + + /* Read the schema cookie from the database. If it does not match the + ** value stored as part of the in-memory schema representation, + ** set Parse.rc to SQLITE_SCHEMA. */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + if( DbHasProperty(db, iDb, DB_SchemaLoaded) ) pParse->rc = SQLITE_SCHEMA; + sqlite3ResetOneSchema(db, iDb); + } + + /* Close the transaction, if one was opened. */ + if( openedTransaction ){ + sqlite3BtreeCommit(pBt); + } + } +} + +/* +** Convert a schema pointer into the iDb index that indicates +** which database file in db->aDb[] the schema refers to. +** +** If the same database is attached more than once, the first +** attached database is returned. +*/ +SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ + int i = -32768; + + /* If pSchema is NULL, then return -32768. This happens when code in + ** expr.c is trying to resolve a reference to a transient table (i.e. one + ** created by a sub-select). In this case the return value of this + ** function should never be used. + ** + ** We return -32768 instead of the more usual -1 simply because using + ** -32768 as the incorrect index into db->aDb[] is much + ** more likely to cause a segfault than -1 (of course there are assert() + ** statements too, but it never hurts to play the odds) and + ** -32768 will still fit into a 16-bit signed integer. + */ + assert( sqlite3_mutex_held(db->mutex) ); + if( pSchema ){ + for(i=0; 1; i++){ + assert( inDb ); + if( db->aDb[i].pSchema==pSchema ){ + break; + } + } + assert( i>=0 && inDb ); + } + return i; +} + +/* +** Free all memory allocations in the pParse object +*/ +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ + sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse ); + assert( pParse->nested==0 ); +#ifndef SQLITE_OMIT_SHARED_CACHE + if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); +#endif + while( pParse->pCleanup ){ + ParseCleanup *pCleanup = pParse->pCleanup; + pParse->pCleanup = pCleanup->pNext; + pCleanup->xCleanup(db, pCleanup->pPtr); + sqlite3DbNNFreeNN(db, pCleanup); + } + if( pParse->aLabel ) sqlite3DbNNFreeNN(db, pParse->aLabel); + if( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } + assert( db->lookaside.bDisable >= pParse->disableLookaside ); + db->lookaside.bDisable -= pParse->disableLookaside; + db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; + assert( pParse->db->pParse==pParse ); + db->pParse = pParse->pOuterParse; +} + +/* +** Add a new cleanup operation to a Parser. The cleanup should happen when +** the parser object is destroyed. But, beware: the cleanup might happen +** immediately. +** +** Use this mechanism for uncommon cleanups. There is a higher setup +** cost for this mechanism (an extra malloc), so it should not be used +** for common cleanups that happen on most calls. But for less +** common cleanups, we save a single NULL-pointer comparison in +** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. +** +** If a memory allocation error occurs, then the cleanup happens immediately. +** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the +** pParse->earlyCleanup flag is set in that case. Calling code show verify +** that test cases exist for which this happens, to guard against possible +** use-after-free errors following an OOM. The preferred way to do this is +** to immediately follow the call to this routine with: +** +** testcase( pParse->earlyCleanup ); +** +** This routine returns a copy of its pPtr input (the third parameter) +** except if an early cleanup occurs, in which case it returns NULL. So +** another way to check for early cleanup is to check the return value. +** Or, stop using the pPtr parameter with this call and use only its +** return value thereafter. Something like this: +** +** pObj = sqlite3ParserAddCleanup(pParse, destructor, pObj); +*/ +SQLITE_PRIVATE void *sqlite3ParserAddCleanup( + Parse *pParse, /* Destroy when this Parser finishes */ + void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ + void *pPtr /* Pointer to object to be cleaned up */ +){ + ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + if( pCleanup ){ + pCleanup->pNext = pParse->pCleanup; + pParse->pCleanup = pCleanup; + pCleanup->pPtr = pPtr; + pCleanup->xCleanup = xCleanup; + }else{ + xCleanup(pParse->db, pPtr); + pPtr = 0; +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + pParse->earlyCleanup = 1; +#endif + } + return pPtr; +} + +/* +** Turn bulk memory into a valid Parse object and link that Parse object +** into database connection db. +** +** Call sqlite3ParseObjectReset() to undo this operation. +** +** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which +** is generated by Lemon. +*/ +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){ + memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); + assert( db->pParse!=pParse ); + pParse->pOuterParse = db->pParse; + db->pParse = pParse; + pParse->db = db; + if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory"); +} + +/* +** Maximum number of times that we will try again to prepare a statement +** that returns SQLITE_ERROR_RETRY. +*/ +#ifndef SQLITE_MAX_PREPARE_RETRY +# define SQLITE_MAX_PREPARE_RETRY 25 +#endif + +/* +** Compile the UTF-8 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc = SQLITE_OK; /* Result code */ + int i; /* Loop counter */ + Parse sParse; /* Parsing context */ + + /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */ + memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); + sParse.pOuterParse = db->pParse; + db->pParse = &sParse; + sParse.db = db; + if( pReprepare ){ + sParse.pReprepare = pReprepare; + sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare); + }else{ + assert( sParse.pReprepare==0 ); + } + assert( ppStmt && *ppStmt==0 ); + if( db->mallocFailed ){ + sqlite3ErrorMsg(&sParse, "out of memory"); + db->errCode = rc = SQLITE_NOMEM; + goto end_prepare; + } + assert( sqlite3_mutex_held(db->mutex) ); + + /* For a long-term use prepared statement avoid the use of + ** lookaside memory. + */ + if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ + sParse.disableLookaside++; + DisableLookaside; + } + sParse.prepFlags = prepFlags & 0xff; + + /* Check to verify that it is possible to get a read lock on all + ** database schemas. The inability to get a read lock indicates that + ** some other database connection is holding a write-lock, which in + ** turn means that the other connection has made uncommitted changes + ** to the schema. + ** + ** Were we to proceed and prepare the statement against the uncommitted + ** schema changes and if those schema changes are subsequently rolled + ** back and different changes are made in their place, then when this + ** prepared statement goes to run the schema cookie would fail to detect + ** the schema change. Disaster would follow. + ** + ** This thread is currently holding mutexes on all Btrees (because + ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it + ** is not possible for another thread to start a new schema change + ** while this routine is running. Hence, we do not need to hold + ** locks on the schema, we just need to make sure nobody else is + ** holding them. + ** + ** Note that setting READ_UNCOMMITTED overrides most lock detection, + ** but it does *not* override schema lock detection, so this all still + ** works even if READ_UNCOMMITTED is set. + */ + if( !db->noSharedCache ){ + for(i=0; inDb; i++) { + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + assert( sqlite3BtreeHoldsMutex(pBt) ); + rc = sqlite3BtreeSchemaLocked(pBt); + if( rc ){ + const char *zDb = db->aDb[i].zDbSName; + sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); + testcase( db->flags & SQLITE_ReadUncommit ); + goto end_prepare; + } + } + } + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( db->pDisconnect ) sqlite3VtabUnlockList(db); +#endif + + if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ + char *zSqlCopy; + int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + testcase( nBytes==mxLen ); + testcase( nBytes==mxLen+1 ); + if( nBytes>mxLen ){ + sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); + rc = sqlite3ApiExit(db, SQLITE_TOOBIG); + goto end_prepare; + } + zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); + if( zSqlCopy ){ + sqlite3RunParser(&sParse, zSqlCopy); + sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; + sqlite3DbFree(db, zSqlCopy); + }else{ + sParse.zTail = &zSql[nBytes]; + } + }else{ + sqlite3RunParser(&sParse, zSql); + } + assert( 0==sParse.nQueryLoop ); + + if( pzTail ){ + *pzTail = sParse.zTail; + } + + if( db->init.busy==0 ){ + sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); + } + if( db->mallocFailed ){ + sParse.rc = SQLITE_NOMEM_BKPT; + sParse.checkSchema = 0; + } + if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ + if( sParse.checkSchema && db->init.busy==0 ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( sParse.zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); + }else{ + sqlite3Error(db, rc); + } + }else{ + assert( sParse.zErrMsg==0 ); + *ppStmt = (sqlite3_stmt*)sParse.pVdbe; + rc = SQLITE_OK; + sqlite3ErrorClear(db); + } + + + /* Delete any TriggerPrg structures allocated while parsing this statement. */ + while( sParse.pTriggerPrg ){ + TriggerPrg *pT = sParse.pTriggerPrg; + sParse.pTriggerPrg = pT->pNext; + sqlite3DbFree(db, pT); + } + +end_prepare: + + sqlite3ParseObjectReset(&sParse); + return rc; +} +static int sqlite3LockAndPrepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pOld, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + int cnt = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + do{ + /* Make multiple attempts to compile the SQL, until it either succeeds + ** or encounters a permanent error. A schema problem after one schema + ** reset is considered a permanent error. */ + rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); + assert( rc==SQLITE_OK || *ppStmt==0 ); + if( rc==SQLITE_OK || db->mallocFailed ) break; + }while( (rc==SQLITE_ERROR_RETRY && (cnt++)errMask)==rc ); + db->busyHandler.nBusy = 0; + sqlite3_mutex_leave(db->mutex); + assert( rc==SQLITE_OK || (*ppStmt)==0 ); + return rc; +} + + +/* +** Rerun the compilation of a statement after a schema change. +** +** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, +** if the statement cannot be recompiled because another connection has +** locked the sqlite3_schema table, return SQLITE_LOCKED. If any other error +** occurs, return SQLITE_SCHEMA. +*/ +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){ + int rc; + sqlite3_stmt *pNew; + const char *zSql; + sqlite3 *db; + u8 prepFlags; + + assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); + zSql = sqlite3_sql((sqlite3_stmt *)p); + assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ + db = sqlite3VdbeDb(p); + assert( sqlite3_mutex_held(db->mutex) ); + prepFlags = sqlite3VdbePrepareFlags(p); + rc = sqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0); + if( rc ){ + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } + assert( pNew==0 ); + return rc; + }else{ + assert( pNew!=0 ); + } + sqlite3VdbeSwap((Vdbe*)pNew, p); + sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); + sqlite3VdbeResetStepResult((Vdbe*)pNew); + sqlite3VdbeFinalize((Vdbe*)pNew); + return SQLITE_OK; +} + + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works + ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags + ** parameter. + ** + ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */ + rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0, + ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); + return rc; +} +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from + ** sqlite3_prepare_v2() only in having the extra prepFlags parameter, + ** which is a bit array consisting of zero or more of the + ** SQLITE_PREPARE_* flags. + ** + ** Proof by comparison to the implementation of sqlite3_prepare_v2() + ** directly above. */ + rc = sqlite3LockAndPrepare(db,zSql,nBytes, + SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), + 0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); + return rc; +} + + +#ifndef SQLITE_OMIT_UTF16 +/* +** Compile the UTF-16 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + /* This function currently works by first transforming the UTF-16 + ** encoded string to UTF-8, then invoking sqlite3_prepare(). The + ** tricky bit is figuring out the pointer to return in *pzTail. + */ + char *zSql8; + const char *zTail8 = 0; + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ + return SQLITE_MISUSE_BKPT; + } + if( nBytes>=0 ){ + int sz; + const char *z = (const char*)zSql; + for(sz=0; szmutex); + zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); + if( zSql8 ){ + rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8); + } + + if( zTail8 && pzTail ){ + /* If sqlite3_prepare returns a tail pointer, we calculate the + ** equivalent pointer into the UTF-16 string by counting the unicode + ** characters between zSql8 and zTail8, and then returning a pointer + ** the same number of characters into the UTF-16 string. + */ + int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); + } + sqlite3DbFree(db, zSql8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes, + SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), + ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} + +#endif /* SQLITE_OMIT_UTF16 */ + +/************** End of prepare.c *********************************************/ +/************** Begin file select.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle SELECT statements in SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* +** An instance of the following object is used to record information about +** how to process the DISTINCT keyword, to simplify passing that information +** into the selectInnerLoop() routine. +*/ +typedef struct DistinctCtx DistinctCtx; +struct DistinctCtx { + u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */ + u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ + int tabTnct; /* Ephemeral table used for DISTINCT processing */ + int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ +}; + +/* +** An instance of the following object is used to record information about +** the ORDER BY (or GROUP BY) clause of query is being coded. +** +** The aDefer[] array is used by the sorter-references optimization. For +** example, assuming there is no index that can be used for the ORDER BY, +** for the query: +** +** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10; +** +** it may be more efficient to add just the "a" values to the sorter, and +** retrieve the associated "bigblob" values directly from table t1 as the +** 10 smallest "a" values are extracted from the sorter. +** +** When the sorter-reference optimization is used, there is one entry in the +** aDefer[] array for each database table that may be read as values are +** extracted from the sorter. +*/ +typedef struct SortCtx SortCtx; +struct SortCtx { + ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */ + int nOBSat; /* Number of ORDER BY terms satisfied by indices */ + int iECursor; /* Cursor number for the sorter */ + int regReturn; /* Register holding block-output return address */ + int labelBkOut; /* Start label for the block-output subroutine */ + int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ + int labelDone; /* Jump here when done, ex: LIMIT reached */ + int labelOBLopt; /* Jump here when sorter is full */ + u8 sortFlags; /* Zero or more SORTFLAG_* bits */ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + u8 nDefer; /* Number of valid entries in aDefer[] */ + struct DeferredCsr { + Table *pTab; /* Table definition */ + int iCsr; /* Cursor number for table */ + int nKey; /* Number of PK columns for table pTab (>=1) */ + } aDefer[4]; +#endif + struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrPush; /* First instruction to push data into sorter */ + int addrPushEnd; /* Last instruction that pushes data into sorter */ +#endif +}; +#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ + +/* +** Delete all the content of a Select structure. Deallocate the structure +** itself depending on the value of bFree +** +** If bFree==1, call sqlite3DbFree() on the p object. +** If bFree==0, Leave the first Select object unfreed +*/ +static void clearSelect(sqlite3 *db, Select *p, int bFree){ + assert( db!=0 ); + while( p ){ + Select *pPrior = p->pPrior; + sqlite3ExprListDelete(db, p->pEList); + sqlite3SrcListDelete(db, p->pSrc); + sqlite3ExprDelete(db, p->pWhere); + sqlite3ExprListDelete(db, p->pGroupBy); + sqlite3ExprDelete(db, p->pHaving); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pLimit); + if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ + sqlite3WindowListDelete(db, p->pWinDefn); + } + while( p->pWin ){ + assert( p->pWin->ppThis==&p->pWin ); + sqlite3WindowUnlinkFromSelect(p->pWin); + } +#endif + if( bFree ) sqlite3DbNNFreeNN(db, p); + p = pPrior; + bFree = 1; + } +} + +/* +** Initialize a SelectDest structure. +*/ +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ + pDest->eDest = (u8)eDest; + pDest->iSDParm = iParm; + pDest->iSDParm2 = 0; + pDest->zAffSdst = 0; + pDest->iSdst = 0; + pDest->nSdst = 0; +} + + +/* +** Allocate a new Select structure and return a pointer to that +** structure. +*/ +SQLITE_PRIVATE Select *sqlite3SelectNew( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* which columns to include in the result */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* the WHERE clause */ + ExprList *pGroupBy, /* the GROUP BY clause */ + Expr *pHaving, /* the HAVING clause */ + ExprList *pOrderBy, /* the ORDER BY clause */ + u32 selFlags, /* Flag parameters, such as SF_Distinct */ + Expr *pLimit /* LIMIT value. NULL means not used */ +){ + Select *pNew, *pAllocated; + Select standin; + pAllocated = pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); + if( pNew==0 ){ + assert( pParse->db->mallocFailed ); + pNew = &standin; + } + if( pEList==0 ){ + pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3Expr(pParse->db,TK_ASTERISK,0)); + } + pNew->pEList = pEList; + pNew->op = TK_SELECT; + pNew->selFlags = selFlags; + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selId = ++pParse->nSelect; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->nSelectRow = 0; + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); + pNew->pSrc = pSrc; + pNew->pWhere = pWhere; + pNew->pGroupBy = pGroupBy; + pNew->pHaving = pHaving; + pNew->pOrderBy = pOrderBy; + pNew->pPrior = 0; + pNew->pNext = 0; + pNew->pLimit = pLimit; + pNew->pWith = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = 0; +#endif + if( pParse->db->mallocFailed ) { + clearSelect(pParse->db, pNew, pNew!=&standin); + pAllocated = 0; + }else{ + assert( pNew->pSrc!=0 || pParse->nErr>0 ); + } + return pAllocated; +} + + +/* +** Delete the given Select structure and all of its substructures. +*/ +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ + if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); +} +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1); +} + +/* +** Return a pointer to the right-most SELECT statement in a compound. +*/ +static Select *findRightmost(Select *p){ + while( p->pNext ) p = p->pNext; + return p; +} + +/* +** Given 1 to 3 identifiers preceding the JOIN keyword, determine the +** type of join. Return an integer constant that expresses that type +** in terms of the following bit values: +** +** JT_INNER +** JT_CROSS +** JT_OUTER +** JT_NATURAL +** JT_LEFT +** JT_RIGHT +** +** A full outer join is the combination of JT_LEFT and JT_RIGHT. +** +** If an illegal or unsupported join type is seen, then still return +** a join type, but put an error in the pParse structure. +** +** These are the valid join types: +** +** +** pA pB pC Return Value +** ------- ----- ----- ------------ +** CROSS - - JT_CROSS +** INNER - - JT_INNER +** LEFT - - JT_LEFT|JT_OUTER +** LEFT OUTER - JT_LEFT|JT_OUTER +** RIGHT - - JT_RIGHT|JT_OUTER +** RIGHT OUTER - JT_RIGHT|JT_OUTER +** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER +** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER +** NATURAL INNER - JT_NATURAL|JT_INNER +** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER +** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER +** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER +** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER +** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT +** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT +** +** To preserve historical compatibly, SQLite also accepts a variety +** of other non-standard and in many cases nonsensical join types. +** This routine makes as much sense at it can from the nonsense join +** type and returns a result. Examples of accepted nonsense join types +** include but are not limited to: +** +** INNER CROSS JOIN -> same as JOIN +** NATURAL CROSS JOIN -> same as NATURAL JOIN +** OUTER LEFT JOIN -> same as LEFT JOIN +** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN +** LEFT RIGHT JOIN -> same as FULL JOIN +** RIGHT OUTER FULL JOIN -> same as FULL JOIN +** CROSS CROSS CROSS JOIN -> same as JOIN +** +** The only restrictions on the join type name are: +** +** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT", +** or "FULL". +** +** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT, +** or "FULL". +** +** * If "OUTER" is present then there must also be one of +** "LEFT", "RIGHT", or "FULL" +*/ +SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ + int jointype = 0; + Token *apAll[3]; + Token *p; + /* 0123456789 123456789 123456789 123 */ + static const char zKeyText[] = "naturaleftouterightfullinnercross"; + static const struct { + u8 i; /* Beginning of keyword text in zKeyText[] */ + u8 nChar; /* Length of the keyword in characters */ + u8 code; /* Join type mask */ + } aKeyword[] = { + /* (0) natural */ { 0, 7, JT_NATURAL }, + /* (1) left */ { 6, 4, JT_LEFT|JT_OUTER }, + /* (2) outer */ { 10, 5, JT_OUTER }, + /* (3) right */ { 14, 5, JT_RIGHT|JT_OUTER }, + /* (4) full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, + /* (5) inner */ { 23, 5, JT_INNER }, + /* (6) cross */ { 28, 5, JT_INNER|JT_CROSS }, + }; + int i, j; + apAll[0] = pA; + apAll[1] = pB; + apAll[2] = pC; + for(i=0; i<3 && apAll[i]; i++){ + p = apAll[i]; + for(j=0; jn==aKeyword[j].nChar + && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ + jointype |= aKeyword[j].code; + break; + } + } + testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 ); + if( j>=ArraySize(aKeyword) ){ + jointype |= JT_ERROR; + break; + } + } + if( + (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || + (jointype & JT_ERROR)!=0 || + (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER + ){ + const char *zSp1 = " "; + const char *zSp2 = " "; + if( pB==0 ){ zSp1++; } + if( pC==0 ){ zSp2++; } + sqlite3ErrorMsg(pParse, "unknown join type: " + "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); + jointype = JT_INNER; + } + return jointype; +} + +/* +** Return the index of a column in a table. Return -1 if the column +** is not contained in the table. +*/ +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ + int i; + u8 h = sqlite3StrIHash(zCol); + Column *pCol; + for(pCol=pTab->aCol, i=0; inCol; pCol++, i++){ + if( pCol->hName==h && sqlite3StrICmp(pCol->zCnName, zCol)==0 ) return i; + } + return -1; +} + +/* +** Mark a subquery result column as having been used. +*/ +SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ + assert( pItem!=0 ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + if( pItem->fg.isNestedFrom ){ + ExprList *pResults; + assert( pItem->pSelect!=0 ); + pResults = pItem->pSelect->pEList; + assert( pResults!=0 ); + assert( iCol>=0 && iColnExpr ); + pResults->a[iCol].fg.bUsed = 1; + } +} + +/* +** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a +** table that has a column named zCol. The search is left-to-right. +** The first match found is returned. +** +** When found, set *piTab and *piCol to the table index and column index +** of the matching column and return TRUE. +** +** If not found, return FALSE. +*/ +static int tableAndColumnIndex( + SrcList *pSrc, /* Array of tables to search */ + int iStart, /* First member of pSrc->a[] to check */ + int iEnd, /* Last member of pSrc->a[] to check */ + const char *zCol, /* Name of the column we are looking for */ + int *piTab, /* Write index of pSrc->a[] here */ + int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ + int bIgnoreHidden /* Ignore hidden columns */ +){ + int i; /* For looping over tables in pSrc */ + int iCol; /* Index of column matching zCol */ + + assert( iEndnSrc ); + assert( iStart>=0 ); + assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ + + for(i=iStart; i<=iEnd; i++){ + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); + if( iCol>=0 + && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) + ){ + if( piTab ){ + sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); + *piTab = i; + *piCol = iCol; + } + return 1; + } + } + return 0; +} + +/* +** Set the EP_OuterON property on all terms of the given expression. +** And set the Expr.w.iJoin to iTable for every term in the +** expression. +** +** The EP_OuterON property is used on terms of an expression to tell +** the OUTER JOIN processing logic that this term is part of the +** join restriction specified in the ON or USING clause and not a part +** of the more general WHERE clause. These terms are moved over to the +** WHERE clause during join processing but we need to remember that they +** originated in the ON or USING clause. +** +** The Expr.w.iJoin tells the WHERE clause processing that the +** expression depends on table w.iJoin even if that table is not +** explicitly mentioned in the expression. That information is needed +** for cases like this: +** +** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 +** +** The where clause needs to defer the handling of the t1.x=5 +** term until after the t2 loop of the join. In that way, a +** NULL t2 row will be inserted whenever t1.x!=5. If we do not +** defer the handling of t1.x=5, it will be processed immediately +** after the t1 loop and rows with t1.x!=5 will never appear in +** the output, which is incorrect. +*/ +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){ + assert( joinFlag==EP_OuterON || joinFlag==EP_InnerON ); + while( p ){ + ExprSetProperty(p, joinFlag); + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(p, EP_NoReduce); + p->w.iJoin = iTable; + if( p->op==TK_FUNCTION ){ + assert( ExprUseXList(p) ); + if( p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag); + } + } + } + sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag); + p = p->pRight; + } +} + +/* Undo the work of sqlite3SetJoinExpr(). This is used when a LEFT JOIN +** is simplified into an ordinary JOIN, and when an ON expression is +** "pushed down" into the WHERE clause of a subquery. +** +** Convert every term that is marked with EP_OuterON and w.iJoin==iTable into +** an ordinary term that omits the EP_OuterON mark. Or if iTable<0, then +** just clear every EP_OuterON and EP_InnerON mark from the expression tree. +** +** If nullable is true, that means that Expr p might evaluate to NULL even +** if it is a reference to a NOT NULL column. This can happen, for example, +** if the table that p references is on the left side of a RIGHT JOIN. +** If nullable is true, then take care to not remove the EP_CanBeNull bit. +** See forum thread https://sqlite.org/forum/forumpost/b40696f50145d21c +*/ +static void unsetJoinExpr(Expr *p, int iTable, int nullable){ + while( p ){ + if( iTable<0 || (ExprHasProperty(p, EP_OuterON) && p->w.iJoin==iTable) ){ + ExprClearProperty(p, EP_OuterON|EP_InnerON); + if( iTable>=0 ) ExprSetProperty(p, EP_InnerON); + } + if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){ + ExprClearProperty(p, EP_CanBeNull); + } + if( p->op==TK_FUNCTION ){ + assert( ExprUseXList(p) ); + assert( p->pLeft==0 ); + if( p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + unsetJoinExpr(p->x.pList->a[i].pExpr, iTable, nullable); + } + } + } + unsetJoinExpr(p->pLeft, iTable, nullable); + p = p->pRight; + } +} + +/* +** This routine processes the join information for a SELECT statement. +** +** * A NATURAL join is converted into a USING join. After that, we +** do not need to be concerned with NATURAL joins and we only have +** think about USING joins. +** +** * ON and USING clauses result in extra terms being added to the +** WHERE clause to enforce the specified constraints. The extra +** WHERE clause terms will be tagged with EP_OuterON or +** EP_InnerON so that we know that they originated in ON/USING. +** +** The terms of a FROM clause are contained in the Select.pSrc structure. +** The left most table is the first entry in Select.pSrc. The right-most +** table is the last entry. The join operator is held in the entry to +** the right. Thus entry 1 contains the join operator for the join between +** entries 0 and 1. Any ON or USING clauses associated with the join are +** also attached to the right entry. +** +** This routine returns the number of errors encountered. +*/ +static int sqlite3ProcessJoin(Parse *pParse, Select *p){ + SrcList *pSrc; /* All tables in the FROM clause */ + int i, j; /* Loop counters */ + SrcItem *pLeft; /* Left table being joined */ + SrcItem *pRight; /* Right table being joined */ + + pSrc = p->pSrc; + pLeft = &pSrc->a[0]; + pRight = &pLeft[1]; + for(i=0; inSrc-1; i++, pRight++, pLeft++){ + Table *pRightTab = pRight->pTab; + u32 joinType; + + if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; + joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; + + /* If this is a NATURAL join, synthesize an appropriate USING clause + ** to specify which columns should be joined. + */ + if( pRight->fg.jointype & JT_NATURAL ){ + IdList *pUsing = 0; + if( pRight->fg.isUsing || pRight->u3.pOn ){ + sqlite3ErrorMsg(pParse, "a NATURAL join may not have " + "an ON or USING clause", 0); + return 1; + } + for(j=0; jnCol; j++){ + char *zName; /* Name of column in the right table */ + + if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; + zName = pRightTab->aCol[j].zCnName; + if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){ + pUsing = sqlite3IdListAppend(pParse, pUsing, 0); + if( pUsing ){ + assert( pUsing->nId>0 ); + assert( pUsing->a[pUsing->nId-1].zName==0 ); + pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName); + } + } + } + if( pUsing ){ + pRight->fg.isUsing = 1; + pRight->fg.isSynthUsing = 1; + pRight->u3.pUsing = pUsing; + } + if( pParse->nErr ) return 1; + } + + /* Create extra terms on the WHERE clause for each column named + ** in the USING clause. Example: If the two tables to be joined are + ** A and B and the USING clause names X, Y, and Z, then add this + ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z + ** Report an error if any column mentioned in the USING clause is + ** not contained in both tables to be joined. + */ + if( pRight->fg.isUsing ){ + IdList *pList = pRight->u3.pUsing; + sqlite3 *db = pParse->db; + assert( pList!=0 ); + for(j=0; jnId; j++){ + char *zName; /* Name of the term in the USING clause */ + int iLeft; /* Table on the left with matching column name */ + int iLeftCol; /* Column number of matching column on the left */ + int iRightCol; /* Column number of matching column on the right */ + Expr *pE1; /* Reference to the column on the LEFT of the join */ + Expr *pE2; /* Reference to the column on the RIGHT of the join */ + Expr *pEq; /* Equality constraint. pE1 == pE2 */ + + zName = pList->a[j].zName; + iRightCol = sqlite3ColumnIndex(pRightTab, zName); + if( iRightCol<0 + || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing)==0 + ){ + sqlite3ErrorMsg(pParse, "cannot join using column %s - column " + "not present in both tables", zName); + return 1; + } + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + /* This branch runs if the query contains one or more RIGHT or FULL + ** JOINs. If only a single table on the left side of this join + ** contains the zName column, then this branch is a no-op. + ** But if there are two or more tables on the left side + ** of the join, construct a coalesce() function that gathers all + ** such tables. Raise an error if more than one of those references + ** to zName is not also within a prior USING clause. + ** + ** We really ought to raise an error if there are two or more + ** non-USING references to zName on the left of an INNER or LEFT + ** JOIN. But older versions of SQLite do not do that, so we avoid + ** adding a new error so as to not break legacy applications. + */ + ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ + static const Token tkCoalesce = { "coalesce", 8 }; + while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing)!=0 ){ + if( pSrc->a[iLeft].fg.isUsing==0 + || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 + ){ + sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()", + zName); + break; + } + pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); + } + if( pFuncArgs ){ + pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); + pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); + } + } + pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); + sqlite3SrcItemColumnUsed(pRight, iRightCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); + assert( pE2!=0 || pEq==0 ); + if( pEq ){ + ExprSetProperty(pEq, joinType); + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pEq, EP_NoReduce); + pEq->w.iJoin = pE2->iTable; + } + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq); + } + } + + /* Add the ON clause to the end of the WHERE clause, connected by + ** an AND operator. + */ + else if( pRight->u3.pOn ){ + sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType); + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn); + pRight->u3.pOn = 0; + pRight->fg.isOn = 1; + } + } + return 0; +} + +/* +** An instance of this object holds information (beyond pParse and pSelect) +** needed to load the next result row that is to be added to the sorter. +*/ +typedef struct RowLoadInfo RowLoadInfo; +struct RowLoadInfo { + int regResult; /* Store results in array of registers here */ + u8 ecelFlags; /* Flag argument to ExprCodeExprList() */ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + ExprList *pExtra; /* Extra columns needed by sorter refs */ + int regExtraResult; /* Where to load the extra columns */ +#endif +}; + +/* +** This routine does the work of loading query data into an array of +** registers so that it can be added to the sorter. +*/ +static void innerLoopLoadRow( + Parse *pParse, /* Statement under construction */ + Select *pSelect, /* The query being coded */ + RowLoadInfo *pInfo /* Info needed to complete the row load */ +){ + sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, + 0, pInfo->ecelFlags); +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( pInfo->pExtra ){ + sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); + sqlite3ExprListDelete(pParse->db, pInfo->pExtra); + } +#endif +} + +/* +** Code the OP_MakeRecord instruction that generates the entry to be +** added into the sorter. +** +** Return the register in which the result is stored. +*/ +static int makeSorterRecord( + Parse *pParse, + SortCtx *pSort, + Select *pSelect, + int regBase, + int nBase +){ + int nOBSat = pSort->nOBSat; + Vdbe *v = pParse->pVdbe; + int regOut = ++pParse->nMem; + if( pSort->pDeferredRowLoad ){ + innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); + return regOut; +} + +/* +** Generate code that will push the record in registers regData +** through regData+nData-1 onto the sorter. +*/ +static void pushOntoSorter( + Parse *pParse, /* Parser context */ + SortCtx *pSort, /* Information about the ORDER BY clause */ + Select *pSelect, /* The whole SELECT statement */ + int regData, /* First register holding data to be sorted */ + int regOrigData, /* First register holding data before packing */ + int nData, /* Number of elements in the regData data array */ + int nPrefixReg /* No. of reg prior to regData available for use */ +){ + Vdbe *v = pParse->pVdbe; /* Stmt under construction */ + int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0); + int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ + int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ + int regBase; /* Regs for sorter record */ + int regRecord = 0; /* Assembled sorter record */ + int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ + int op; /* Opcode to add sorter record to sorter */ + int iLimit; /* LIMIT counter */ + int iSkip = 0; /* End of the sorter insert loop */ + + assert( bSeq==0 || bSeq==1 ); + + /* Three cases: + ** (1) The data to be sorted has already been packed into a Record + ** by a prior OP_MakeRecord. In this case nData==1 and regData + ** will be completely unrelated to regOrigData. + ** (2) All output columns are included in the sort record. In that + ** case regData==regOrigData. + ** (3) Some output columns are omitted from the sort record due to + ** the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the + ** SQLITE_ECEL_OMITREF optimization, or due to the + ** SortCtx.pDeferredRowLoad optimization. In any of these cases + ** regOrigData is 0 to prevent this routine from trying to copy + ** values that might not yet exist. + */ + assert( nData==1 || regData==regOrigData || regOrigData==0 ); + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pSort->addrPush = sqlite3VdbeCurrentAddr(v); +#endif + + if( nPrefixReg ){ + assert( nPrefixReg==nExpr+bSeq ); + regBase = regData - nPrefixReg; + }else{ + regBase = pParse->nMem + 1; + pParse->nMem += nBase; + } + assert( pSelect->iOffset==0 || pSelect->iLimit!=0 ); + iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; + pSort->labelDone = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, + SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0)); + if( bSeq ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); + } + if( nPrefixReg==0 && nData>0 ){ + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); + } + if( nOBSat>0 ){ + int regPrevKey; /* The first nOBSat columns of the previous row */ + int addrFirst; /* Address of the OP_IfNot opcode */ + int addrJmp; /* Address of the OP_Jump opcode */ + VdbeOp *pOp; /* Opcode that opens the sorter */ + int nKey; /* Number of sorting key columns, including OP_Sequence */ + KeyInfo *pKI; /* Original KeyInfo on the sorter table */ + + regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); + regPrevKey = pParse->nMem+1; + pParse->nMem += pSort->nOBSat; + nKey = nExpr - pSort->nOBSat + bSeq; + if( bSeq ){ + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); + }else{ + addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); + } + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); + pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); + if( pParse->db->mallocFailed ) return; + pOp->p2 = nKey + nData; + pKI = pOp->p4.pKeyInfo; + memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */ + sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); + testcase( pKI->nAllField > pKI->nKeyField+2 ); + pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, + pKI->nAllField-pKI->nKeyField-1); + pOp = 0; /* Ensure pOp not used after sqlite3VdbeAddOp3() */ + addrJmp = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); + pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); + pSort->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); + if( iLimit ){ + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone); + VdbeCoverage(v); + } + sqlite3VdbeJumpHere(v, addrFirst); + sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); + sqlite3VdbeJumpHere(v, addrJmp); + } + if( iLimit ){ + /* At this point the values for the new sorter entry are stored + ** in an array of registers. They need to be composed into a record + ** and inserted into the sorter if either (a) there are currently + ** less than LIMIT+OFFSET items or (b) the new record is smaller than + ** the largest record currently in the sorter. If (b) is true and there + ** are already LIMIT+OFFSET items in the sorter, delete the largest + ** entry before inserting the new one. This way there are never more + ** than LIMIT+OFFSET items in the sorter. + ** + ** If the new record does not need to be inserted into the sorter, + ** jump to the next iteration of the loop. If the pSort->labelOBLopt + ** value is not zero, then it is a label of where to jump. Otherwise, + ** just bypass the row insert logic. See the header comment on the + ** sqlite3WhereOrderByLimitOptLabel() function for additional info. + */ + int iCsr = pSort->iECursor; + sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); + iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE, + iCsr, 0, regBase+nOBSat, nExpr-nOBSat); + VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Delete, iCsr); + } + if( regRecord==0 ){ + regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); + } + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + op = OP_SorterInsert; + }else{ + op = OP_IdxInsert; + } + sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, + regBase+nOBSat, nBase-nOBSat); + if( iSkip ){ + sqlite3VdbeChangeP2(v, iSkip, + pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); + } +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pSort->addrPushEnd = sqlite3VdbeCurrentAddr(v)-1; +#endif +} + +/* +** Add code to implement the OFFSET +*/ +static void codeOffset( + Vdbe *v, /* Generate code into this VM */ + int iOffset, /* Register holding the offset counter */ + int iContinue /* Jump here to skip the current record */ +){ + if( iOffset>0 ){ + sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v); + VdbeComment((v, "OFFSET")); + } +} + +/* +** Add code that will check to make sure the array of registers starting at +** iMem form a distinct entry. This is used by both "SELECT DISTINCT ..." and +** distinct aggregates ("SELECT count(DISTINCT ) ..."). Three strategies +** are available. Which is used depends on the value of parameter eTnctType, +** as follows: +** +** WHERE_DISTINCT_UNORDERED/WHERE_DISTINCT_NOOP: +** Build an ephemeral table that contains all entries seen before and +** skip entries which have been seen before. +** +** Parameter iTab is the cursor number of an ephemeral table that must +** be opened before the VM code generated by this routine is executed. +** The ephemeral cursor table is queried for a record identical to the +** record formed by the current array of registers. If one is found, +** jump to VM address addrRepeat. Otherwise, insert a new record into +** the ephemeral cursor and proceed. +** +** The returned value in this case is a copy of parameter iTab. +** +** WHERE_DISTINCT_ORDERED: +** In this case rows are being delivered sorted order. The ephemeral +** table is not required. Instead, the current set of values +** is compared against previous row. If they match, the new row +** is not distinct and control jumps to VM address addrRepeat. Otherwise, +** the VM program proceeds with processing the new row. +** +** The returned value in this case is the register number of the first +** in an array of registers used to store the previous result row so that +** it can be compared to the next. The caller must ensure that this +** register is initialized to NULL. (The fixDistinctOpenEph() routine +** will take care of this initialization.) +** +** WHERE_DISTINCT_UNIQUE: +** In this case it has already been determined that the rows are distinct. +** No special action is required. The return value is zero. +** +** Parameter pEList is the list of expressions used to generated the +** contents of each row. It is used by this routine to determine (a) +** how many elements there are in the array of registers and (b) the +** collation sequences that should be used for the comparisons if +** eTnctType is WHERE_DISTINCT_ORDERED. +*/ +static int codeDistinct( + Parse *pParse, /* Parsing and code generating context */ + int eTnctType, /* WHERE_DISTINCT_* value */ + int iTab, /* A sorting index used to test for distinctness */ + int addrRepeat, /* Jump to here if not distinct */ + ExprList *pEList, /* Expression for each element */ + int regElem /* First element */ +){ + int iRet = 0; + int nResultCol = pEList->nExpr; + Vdbe *v = pParse->pVdbe; + + switch( eTnctType ){ + case WHERE_DISTINCT_ORDERED: { + int i; + int iJump; /* Jump destination */ + int regPrev; /* Previous row content */ + + /* Allocate space for the previous row */ + iRet = regPrev = pParse->nMem+1; + pParse->nMem += nResultCol; + + iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; + for(i=0; ia[i].pExpr); + if( idb->mallocFailed ); + sqlite3VdbeAddOp3(v, OP_Copy, regElem, regPrev, nResultCol-1); + break; + } + + case WHERE_DISTINCT_UNIQUE: { + /* nothing to do */ + break; + } + + default: { + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, regElem, nResultCol); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regElem, nResultCol, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, regElem, nResultCol); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, r1); + iRet = iTab; + break; + } + } + + return iRet; +} + +/* +** This routine runs after codeDistinct(). It makes necessary +** adjustments to the OP_OpenEphemeral opcode that the codeDistinct() +** routine made use of. This processing must be done separately since +** sometimes codeDistinct is called before the OP_OpenEphemeral is actually +** laid down. +** +** WHERE_DISTINCT_NOOP: +** WHERE_DISTINCT_UNORDERED: +** +** No adjustments necessary. This function is a no-op. +** +** WHERE_DISTINCT_UNIQUE: +** +** The ephemeral table is not needed. So change the +** OP_OpenEphemeral opcode into an OP_Noop. +** +** WHERE_DISTINCT_ORDERED: +** +** The ephemeral table is not needed. But we do need register +** iVal to be initialized to NULL. So change the OP_OpenEphemeral +** into an OP_Null on the iVal register. +*/ +static void fixDistinctOpenEph( + Parse *pParse, /* Parsing and code generating context */ + int eTnctType, /* WHERE_DISTINCT_* value */ + int iVal, /* Value returned by codeDistinct() */ + int iOpenEphAddr /* Address of OP_OpenEphemeral instruction for iTab */ +){ + if( pParse->nErr==0 + && (eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED) + ){ + Vdbe *v = pParse->pVdbe; + sqlite3VdbeChangeToNoop(v, iOpenEphAddr); + if( sqlite3VdbeGetOp(v, iOpenEphAddr+1)->opcode==OP_Explain ){ + sqlite3VdbeChangeToNoop(v, iOpenEphAddr+1); + } + if( eTnctType==WHERE_DISTINCT_ORDERED ){ + /* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared + ** bit on the first register of the previous value. This will cause the + ** OP_Ne added in codeDistinct() to always fail on the first iteration of + ** the loop even if the first row is all NULLs. */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, iOpenEphAddr); + pOp->opcode = OP_Null; + pOp->p1 = 1; + pOp->p2 = iVal; + } + } +} + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES +/* +** This function is called as part of inner-loop generation for a SELECT +** statement with an ORDER BY that is not optimized by an index. It +** determines the expressions, if any, that the sorter-reference +** optimization should be used for. The sorter-reference optimization +** is used for SELECT queries like: +** +** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10 +** +** If the optimization is used for expression "bigblob", then instead of +** storing values read from that column in the sorter records, the PK of +** the row from table t1 is stored instead. Then, as records are extracted from +** the sorter to return to the user, the required value of bigblob is +** retrieved directly from table t1. If the values are very large, this +** can be more efficient than storing them directly in the sorter records. +** +** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList +** for which the sorter-reference optimization should be enabled. +** Additionally, the pSort->aDefer[] array is populated with entries +** for all cursors required to evaluate all selected expressions. Finally. +** output variable (*ppExtra) is set to an expression list containing +** expressions for all extra PK values that should be stored in the +** sorter records. +*/ +static void selectExprDefer( + Parse *pParse, /* Leave any error here */ + SortCtx *pSort, /* Sorter context */ + ExprList *pEList, /* Expressions destined for sorter */ + ExprList **ppExtra /* Expressions to append to sorter record */ +){ + int i; + int nDefer = 0; + ExprList *pExtra = 0; + for(i=0; inExpr; i++){ + struct ExprList_item *pItem = &pEList->a[i]; + if( pItem->u.x.iOrderByCol==0 ){ + Expr *pExpr = pItem->pExpr; + Table *pTab; + if( pExpr->op==TK_COLUMN + && pExpr->iColumn>=0 + && ALWAYS( ExprUseYTab(pExpr) ) + && (pTab = pExpr->y.pTab)!=0 + && IsOrdinaryTable(pTab) + && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)!=0 + ){ + int j; + for(j=0; jaDefer[j].iCsr==pExpr->iTable ) break; + } + if( j==nDefer ){ + if( nDefer==ArraySize(pSort->aDefer) ){ + continue; + }else{ + int nKey = 1; + int k; + Index *pPk = 0; + if( !HasRowid(pTab) ){ + pPk = sqlite3PrimaryKeyIndex(pTab); + nKey = pPk->nKeyCol; + } + for(k=0; kiTable = pExpr->iTable; + assert( ExprUseYTab(pNew) ); + pNew->y.pTab = pExpr->y.pTab; + pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; + pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); + } + } + pSort->aDefer[nDefer].pTab = pExpr->y.pTab; + pSort->aDefer[nDefer].iCsr = pExpr->iTable; + pSort->aDefer[nDefer].nKey = nKey; + nDefer++; + } + } + pItem->fg.bSorterRef = 1; + } + } + } + pSort->nDefer = (u8)nDefer; + *ppExtra = pExtra; +} +#endif + +/* +** This routine generates the code for the inside of the inner loop +** of a SELECT. +** +** If srcTab is negative, then the p->pEList expressions +** are evaluated in order to get the data for this row. If srcTab is +** zero or more, then data is pulled from srcTab and p->pEList is used only +** to get the number of columns and the collation sequence for each column. +*/ +static void selectInnerLoop( + Parse *pParse, /* The parser context */ + Select *p, /* The complete select statement being coded */ + int srcTab, /* Pull data from this table if non-negative */ + SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ + DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ + SelectDest *pDest, /* How to dispose of the results */ + int iContinue, /* Jump here to continue with next row */ + int iBreak /* Jump here to break out of the inner loop */ +){ + Vdbe *v = pParse->pVdbe; + int i; + int hasDistinct; /* True if the DISTINCT keyword is present */ + int eDest = pDest->eDest; /* How to dispose of results */ + int iParm = pDest->iSDParm; /* First argument to disposal method */ + int nResultCol; /* Number of result columns */ + int nPrefixReg = 0; /* Number of extra registers before regResult */ + RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */ + + /* Usually, regResult is the first cell in an array of memory cells + ** containing the current result row. In this case regOrig is set to the + ** same value. However, if the results are being sent to the sorter, the + ** values for any expressions that are also part of the sort-key are omitted + ** from this array. In this case regOrig is set to zero. */ + int regResult; /* Start of memory holding current results */ + int regOrig; /* Start of memory holding full result (or 0) */ + + assert( v ); + assert( p->pEList!=0 ); + hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; + if( pSort && pSort->pOrderBy==0 ) pSort = 0; + if( pSort==0 && !hasDistinct ){ + assert( iContinue!=0 ); + codeOffset(v, p->iOffset, iContinue); + } + + /* Pull the requested columns. + */ + nResultCol = p->pEList->nExpr; + + if( pDest->iSdst==0 ){ + if( pSort ){ + nPrefixReg = pSort->pOrderBy->nExpr; + if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++; + pParse->nMem += nPrefixReg; + } + pDest->iSdst = pParse->nMem+1; + pParse->nMem += nResultCol; + }else if( pDest->iSdst+nResultCol > pParse->nMem ){ + /* This is an error condition that can result, for example, when a SELECT + ** on the right-hand side of an INSERT contains more result columns than + ** there are columns in the table on the left. The error will be caught + ** and reported later. But we need to make sure enough memory is allocated + ** to avoid other spurious errors in the meantime. */ + pParse->nMem += nResultCol; + } + pDest->nSdst = nResultCol; + regOrig = regResult = pDest->iSdst; + if( srcTab>=0 ){ + for(i=0; ipEList->a[i].zEName)); + } + }else if( eDest!=SRT_Exists ){ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + ExprList *pExtra = 0; +#endif + /* If the destination is an EXISTS(...) expression, the actual + ** values returned by the SELECT are not required. + */ + u8 ecelFlags; /* "ecel" is an abbreviation of "ExprCodeExprList" */ + ExprList *pEList; + if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){ + ecelFlags = SQLITE_ECEL_DUP; + }else{ + ecelFlags = 0; + } + if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ + /* For each expression in p->pEList that is a copy of an expression in + ** the ORDER BY clause (pSort->pOrderBy), set the associated + ** iOrderByCol value to one more than the index of the ORDER BY + ** expression within the sort-key that pushOntoSorter() will generate. + ** This allows the p->pEList field to be omitted from the sorted record, + ** saving space and CPU cycles. */ + ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF); + + for(i=pSort->nOBSat; ipOrderBy->nExpr; i++){ + int j; + if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){ + p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; + } + } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + selectExprDefer(pParse, pSort, p->pEList, &pExtra); + if( pExtra && pParse->db->mallocFailed==0 ){ + /* If there are any extra PK columns to add to the sorter records, + ** allocate extra memory cells and adjust the OpenEphemeral + ** instruction to account for the larger records. This is only + ** required if there are one or more WITHOUT ROWID tables with + ** composite primary keys in the SortCtx.aDefer[] array. */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); + pOp->p2 += (pExtra->nExpr - pSort->nDefer); + pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer); + pParse->nMem += pExtra->nExpr; + } +#endif + + /* Adjust nResultCol to account for columns that are omitted + ** from the sorter by the optimizations in this branch */ + pEList = p->pEList; + for(i=0; inExpr; i++){ + if( pEList->a[i].u.x.iOrderByCol>0 +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + || pEList->a[i].fg.bSorterRef +#endif + ){ + nResultCol--; + regOrig = 0; + } + } + + testcase( regOrig ); + testcase( eDest==SRT_Set ); + testcase( eDest==SRT_Mem ); + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + assert( eDest==SRT_Set || eDest==SRT_Mem + || eDest==SRT_Coroutine || eDest==SRT_Output + || eDest==SRT_Upfrom ); + } + sRowLoadInfo.regResult = regResult; + sRowLoadInfo.ecelFlags = ecelFlags; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + sRowLoadInfo.pExtra = pExtra; + sRowLoadInfo.regExtraResult = regResult + nResultCol; + if( pExtra ) nResultCol += pExtra->nExpr; +#endif + if( p->iLimit + && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 + && nPrefixReg>0 + ){ + assert( pSort!=0 ); + assert( hasDistinct==0 ); + pSort->pDeferredRowLoad = &sRowLoadInfo; + regOrig = 0; + }else{ + innerLoopLoadRow(pParse, p, &sRowLoadInfo); + } + } + + /* If the DISTINCT keyword was present on the SELECT statement + ** and this row has been seen before, then do not make this row + ** part of the result. + */ + if( hasDistinct ){ + int eType = pDistinct->eTnctType; + int iTab = pDistinct->tabTnct; + assert( nResultCol==p->pEList->nExpr ); + iTab = codeDistinct(pParse, eType, iTab, iContinue, p->pEList, regResult); + fixDistinctOpenEph(pParse, eType, iTab, pDistinct->addrTnct); + if( pSort==0 ){ + codeOffset(v, p->iOffset, iContinue); + } + } + + switch( eDest ){ + /* In this mode, write each query result to the key of the temporary + ** table iParm. + */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT + case SRT_Union: { + int r1; + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + + /* Construct a record from the query result, but instead of + ** saving that record, use it as a key to delete elements from + ** the temporary table iParm. + */ + case SRT_Except: { + sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); + break; + } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + + /* Store the result as data using a unique key. + */ + case SRT_Fifo: + case SRT_DistFifo: + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1); + testcase( eDest==SRT_Table ); + testcase( eDest==SRT_EphemTab ); + testcase( eDest==SRT_Fifo ); + testcase( eDest==SRT_DistFifo ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); +#if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) + /* A destination of SRT_Table and a non-zero iSDParm2 parameter means + ** that this is an "UPDATE ... FROM" on a virtual table or view. In this + ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. + ** This does not affect operation in any way - it just allows MakeRecord + ** to process OPFLAG_NOCHANGE values without an assert() failing. */ + if( eDest==SRT_Table && pDest->iSDParm2 ){ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); + } +#endif +#ifndef SQLITE_OMIT_CTE + if( eDest==SRT_DistFifo ){ + /* If the destination is DistFifo, then cursor (iParm+1) is open + ** on an ephemeral index. If the current row is already present + ** in the index, do not write it to the output. If not, add the + ** current row to the index and proceed with writing it to the + ** output table as well. */ + int addr = sqlite3VdbeCurrentAddr(v) + 4; + sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); + VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol); + assert( pSort==0 ); + } +#endif + if( pSort ){ + assert( regResult==regOrig ); + pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg); + }else{ + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + } + sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); + break; + } + + case SRT_Upfrom: { + if( pSort ){ + pushOntoSorter( + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + }else{ + int i2 = pDest->iSDParm2; + int r1 = sqlite3GetTempReg(pParse); + + /* If the UPDATE FROM join is an aggregate that matches no rows, it + ** might still be trying to return one row, because that is what + ** aggregates do. Don't record that empty row in the output table. */ + sqlite3VdbeAddOp2(v, OP_IsNull, regResult, iBreak); VdbeCoverage(v); + + sqlite3VdbeAddOp3(v, OP_MakeRecord, + regResult+(i2<0), nResultCol-(i2<0), r1); + if( i2<0 ){ + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, regResult); + }else{ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, i2); + } + } + break; + } + +#ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)" construct, + ** then there should be a single item on the stack. Write this + ** item into the set table with bogus data. + */ + case SRT_Set: { + if( pSort ){ + /* At first glance you would think we could optimize out the + ** ORDER BY in this case since the order of entries in the set + ** does not matter. But there might be a LIMIT clause, in which + ** case the order does matter */ + pushOntoSorter( + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + }else{ + int r1 = sqlite3GetTempReg(pParse); + assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, + r1, pDest->zAffSdst, nResultCol); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + sqlite3ReleaseTempReg(pParse, r1); + } + break; + } + + + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } + + /* If this is a scalar select that is part of an expression, then + ** store the results in the appropriate memory cell or array of + ** memory cells and break out of the scan loop. + */ + case SRT_Mem: { + if( pSort ){ + assert( nResultCol<=pDest->nSdst ); + pushOntoSorter( + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + }else{ + assert( nResultCol==pDest->nSdst ); + assert( regResult==iParm ); + /* The LIMIT clause will jump out of the loop for us */ + } + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + case SRT_Coroutine: /* Send data to a co-routine */ + case SRT_Output: { /* Return the results */ + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + if( pSort ){ + pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol, + nPrefixReg); + }else if( eDest==SRT_Coroutine ){ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + }else{ + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); + } + break; + } + +#ifndef SQLITE_OMIT_CTE + /* Write the results into a priority queue that is order according to + ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an + ** index with pSO->nExpr+2 columns. Build a key using pSO for the first + ** pSO->nExpr columns, then make sure all keys are unique by adding a + ** final OP_Sequence column. The last column is the record as a blob. + */ + case SRT_DistQueue: + case SRT_Queue: { + int nKey; + int r1, r2, r3; + int addrTest = 0; + ExprList *pSO; + pSO = pDest->pOrderBy; + assert( pSO ); + nKey = pSO->nExpr; + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); + r3 = r2+nKey+1; + if( eDest==SRT_DistQueue ){ + /* If the destination is DistQueue, then cursor (iParm+1) is open + ** on a second ephemeral index that holds all values every previously + ** added to the queue. */ + addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, + regResult, nResultCol); + VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); + if( eDest==SRT_DistQueue ){ + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + for(i=0; ia[i].u.x.iOrderByCol - 1, + r2+i); + } + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); + if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); + break; + } +#endif /* SQLITE_OMIT_CTE */ + + + +#if !defined(SQLITE_OMIT_TRIGGER) + /* Discard the results. This is used for SELECT statements inside + ** the body of a TRIGGER. The purpose of such selects is to call + ** user-defined functions that have side effects. We do not care + ** about the actual results of the select. + */ + default: { + assert( eDest==SRT_Discard ); + break; + } +#endif + } + + /* Jump to the end of the loop if the LIMIT is reached. Except, if + ** there is a sorter, in which case the sorter has already limited + ** the output for us. + */ + if( pSort==0 && p->iLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + } +} + +/* +** Allocate a KeyInfo object sufficient for an index of N key columns and +** X extra columns. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ + int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); + KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); + if( p ){ + p->aSortFlags = (u8*)&p->aColl[N+X]; + p->nKeyField = (u16)N; + p->nAllField = (u16)(N+X); + p->enc = ENC(db); + p->db = db; + p->nRef = 1; + memset(&p[1], 0, nExtra); + }else{ + return (KeyInfo*)sqlite3OomFault(db); + } + return p; +} + +/* +** Deallocate a KeyInfo object +*/ +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ + if( p ){ + assert( p->db!=0 ); + assert( p->nRef>0 ); + p->nRef--; + if( p->nRef==0 ) sqlite3DbNNFreeNN(p->db, p); + } +} + +/* +** Make a new pointer to a KeyInfo object +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){ + if( p ){ + assert( p->nRef>0 ); + p->nRef++; + } + return p; +} + +#ifdef SQLITE_DEBUG +/* +** Return TRUE if a KeyInfo object can be change. The KeyInfo object +** can only be changed if this is just a single reference to the object. +** +** This routine is used only inside of assert() statements. +*/ +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } +#endif /* SQLITE_DEBUG */ + +/* +** Given an expression list, generate a KeyInfo structure that records +** the collating sequence for each expression in that expression list. +** +** If the ExprList is an ORDER BY or GROUP BY clause then the resulting +** KeyInfo structure is appropriate for initializing a virtual index to +** implement that clause. If the ExprList is the result set of a SELECT +** then the KeyInfo structure is appropriate for initializing a virtual +** index to implement a DISTINCT test. +** +** Space to hold the KeyInfo structure is obtained from malloc. The calling +** function is responsible for seeing that this structure is eventually +** freed. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Form the KeyInfo object from this ExprList */ + int iStart, /* Begin with this column of pList */ + int nExtra /* Add this many extra columns to the end */ +){ + int nExpr; + KeyInfo *pInfo; + struct ExprList_item *pItem; + sqlite3 *db = pParse->db; + int i; + + nExpr = pList->nExpr; + pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); + if( pInfo ){ + assert( sqlite3KeyInfoIsWriteable(pInfo) ); + for(i=iStart, pItem=pList->a+iStart; iaColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); + pInfo->aSortFlags[i-iStart] = pItem->fg.sortFlags; + } + } + return pInfo; +} + +/* +** Name of the connection operator, used for error messages. +*/ +SQLITE_PRIVATE const char *sqlite3SelectOpName(int id){ + char *z; + switch( id ){ + case TK_ALL: z = "UNION ALL"; break; + case TK_INTERSECT: z = "INTERSECT"; break; + case TK_EXCEPT: z = "EXCEPT"; break; + default: z = "UNION"; break; + } + return z; +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of the form: +** +** "USE TEMP B-TREE FOR xxx" +** +** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which +** is determined by the zUsage argument. +*/ +static void explainTempTable(Parse *pParse, const char *zUsage){ + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage)); +} + +/* +** Assign expression b to lvalue a. A second, no-op, version of this macro +** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code +** in sqlite3Select() to assign values to structure member variables that +** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the +** code with #ifndef directives. +*/ +# define explainSetInteger(a, b) a = b + +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainTempTable(y,z) +# define explainSetInteger(y,z) +#endif + + +/* +** If the inner loop was generated using a non-null pOrderBy argument, +** then the results were placed in a sorter. After the loop is terminated +** we need to run the sorter and output the results. The following +** routine generates the code needed to do that. +*/ +static void generateSortTail( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + SortCtx *pSort, /* Information on the ORDER BY clause */ + int nColumn, /* Number of columns of data */ + SelectDest *pDest /* Write the sorted results here */ +){ + Vdbe *v = pParse->pVdbe; /* The prepared statement */ + int addrBreak = pSort->labelDone; /* Jump here to exit loop */ + int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */ + int addr; /* Top of output loop. Jump for Next. */ + int addrOnce = 0; + int iTab; + ExprList *pOrderBy = pSort->pOrderBy; + int eDest = pDest->eDest; + int iParm = pDest->iSDParm; + int regRow; + int regRowid; + int iCol; + int nKey; /* Number of key columns in sorter record */ + int iSortTab; /* Sorter cursor to read from */ + int i; + int bSeq; /* True if sorter record includes seq. no. */ + int nRefKey = 0; + struct ExprList_item *aOutEx = p->pEList->a; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExplain; /* Address of OP_Explain instruction */ +#endif + + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") + ); + sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); + sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); + + + assert( addrBreak<0 ); + if( pSort->labelBkOut ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeGoto(v, addrBreak); + sqlite3VdbeResolveLabel(v, pSort->labelBkOut); + } + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + /* Open any cursors needed for sorter-reference expressions */ + for(i=0; inDefer; i++){ + Table *pTab = pSort->aDefer[i].pTab; + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); + nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); + } +#endif + + iTab = pSort->iECursor; + if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ + if( eDest==SRT_Mem && p->iOffset ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pDest->iSdst); + } + regRowid = 0; + regRow = pDest->iSdst; + }else{ + regRowid = sqlite3GetTempReg(pParse); + if( eDest==SRT_EphemTab || eDest==SRT_Table ){ + regRow = sqlite3GetTempReg(pParse); + nColumn = 0; + }else{ + regRow = sqlite3GetTempRange(pParse, nColumn); + } + } + nKey = pOrderBy->nExpr - pSort->nOBSat; + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + int regSortOut = ++pParse->nMem; + iSortTab = pParse->nTab++; + if( pSort->labelBkOut ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, + nKey+1+nColumn+nRefKey); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + VdbeCoverage(v); + assert( p->iLimit==0 && p->iOffset==0 ); + sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); + bSeq = 0; + }else{ + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); + codeOffset(v, p->iOffset, addrContinue); + iSortTab = iTab; + bSeq = 1; + if( p->iOffset>0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); + } + } + for(i=0, iCol=nKey+bSeq-1; inDefer ){ + int iKey = iCol+1; + int regKey = sqlite3GetTempRange(pParse, nRefKey); + + for(i=0; inDefer; i++){ + int iCsr = pSort->aDefer[i].iCsr; + Table *pTab = pSort->aDefer[i].pTab; + int nKey = pSort->aDefer[i].nKey; + + sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, + sqlite3VdbeCurrentAddr(v)+1, regKey); + }else{ + int k; + int iJmp; + assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey ); + for(k=0; k=0; i--){ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( aOutEx[i].fg.bSorterRef ){ + sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); + }else +#endif + { + int iRead; + if( aOutEx[i].u.x.iOrderByCol ){ + iRead = aOutEx[i].u.x.iOrderByCol-1; + }else{ + iRead = iCol--; + } + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); + VdbeComment((v, "%s", aOutEx[i].zEName)); + } + } + sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + switch( eDest ){ + case SRT_Table: + case SRT_EphemTab: { + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case SRT_Set: { + assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, + pDest->zAffSdst, nColumn); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); + break; + } + case SRT_Mem: { + /* The LIMIT clause will terminate the loop for us */ + break; + } +#endif + case SRT_Upfrom: { + int i2 = pDest->iSDParm2; + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord,regRow+(i2<0),nColumn-(i2<0),r1); + if( i2<0 ){ + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, regRow); + }else{ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regRow, i2); + } + break; + } + default: { + assert( eDest==SRT_Output || eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + testcase( eDest==SRT_Coroutine ); + if( eDest==SRT_Output ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); + }else{ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + } + break; + } + } + if( regRowid ){ + if( eDest==SRT_Set ){ + sqlite3ReleaseTempRange(pParse, regRow, nColumn); + }else{ + sqlite3ReleaseTempReg(pParse, regRow); + } + sqlite3ReleaseTempReg(pParse, regRowid); + } + /* The bottom of the loop + */ + sqlite3VdbeResolveLabel(v, addrContinue); + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); + } + sqlite3VdbeScanStatusRange(v, addrExplain, sqlite3VdbeCurrentAddr(v)-1, -1); + if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); + sqlite3VdbeResolveLabel(v, addrBreak); +} + +/* +** Return a pointer to a string containing the 'declaration type' of the +** expression pExpr. The string may be treated as static by the caller. +** +** The declaration type is the exact datatype definition extracted from the +** original CREATE TABLE statement if the expression is a column. The +** declaration type for a ROWID field is INTEGER. Exactly when an expression +** is considered a column can be complex in the presence of subqueries. The +** result-set expression in all of the following SELECT statements is +** considered a column by this function. +** +** SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl); +** SELECT abc FROM (SELECT col AS abc FROM tbl); +** +** The declaration type for any expression other than a column is NULL. +** +** This routine has either 3 or 6 parameters depending on whether or not +** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. +*/ +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E) +#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ +# define columnType(A,B,C,D,E) columnTypeImpl(A,B) +#endif +static const char *columnTypeImpl( + NameContext *pNC, +#ifndef SQLITE_ENABLE_COLUMN_METADATA + Expr *pExpr +#else + Expr *pExpr, + const char **pzOrigDb, + const char **pzOrigTab, + const char **pzOrigCol +#endif +){ + char const *zType = 0; + int j; +#ifdef SQLITE_ENABLE_COLUMN_METADATA + char const *zOrigDb = 0; + char const *zOrigTab = 0; + char const *zOrigCol = 0; +#endif + + assert( pExpr!=0 ); + assert( pNC->pSrcList!=0 ); + switch( pExpr->op ){ + case TK_COLUMN: { + /* The expression is a column. Locate the table the column is being + ** extracted from in NameContext.pSrcList. This table may be real + ** database table or a subquery. + */ + Table *pTab = 0; /* Table structure column is extracted from */ + Select *pS = 0; /* Select the column is extracted from */ + int iCol = pExpr->iColumn; /* Index of column in pTab */ + while( pNC && !pTab ){ + SrcList *pTabList = pNC->pSrcList; + for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); + if( jnSrc ){ + pTab = pTabList->a[j].pTab; + pS = pTabList->a[j].pSelect; + }else{ + pNC = pNC->pNext; + } + } + + if( pTab==0 ){ + /* At one time, code such as "SELECT new.x" within a trigger would + ** cause this condition to run. Since then, we have restructured how + ** trigger code is generated and so this condition is no longer + ** possible. However, it can still be true for statements like + ** the following: + ** + ** CREATE TABLE t1(col INTEGER); + ** SELECT (SELECT t1.col) FROM FROM t1; + ** + ** when columnType() is called on the expression "t1.col" in the + ** sub-select. In this case, set the column type to NULL, even + ** though it should really be "INTEGER". + ** + ** This is not a problem, as the column type of "t1.col" is never + ** used. When columnType() is called on the expression + ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT + ** branch below. */ + break; + } + + assert( pTab && ExprUseYTab(pExpr) && pExpr->y.pTab==pTab ); + if( pS ){ + /* The "table" is actually a sub-select or a view in the FROM clause + ** of the SELECT statement. Return the declaration type and origin + ** data for the result-set column of the sub-select. + */ + if( iColpEList->nExpr + && (!ViewCanHaveRowid || iCol>=0) + ){ + /* If iCol is less than zero, then the expression requests the + ** rowid of the sub-select or view. This expression is legal (see + ** test case misc2.2.2) - it always evaluates to NULL. + */ + NameContext sNC; + Expr *p = pS->pEList->a[iCol].pExpr; + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); + } + }else{ + /* A real table or a CTE table */ + assert( !pS ); +#ifdef SQLITE_ENABLE_COLUMN_METADATA + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==XN_ROWID || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zType = "INTEGER"; + zOrigCol = "rowid"; + }else{ + zOrigCol = pTab->aCol[iCol].zCnName; + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); + } + zOrigTab = pTab->zName; + if( pNC->pParse && pTab->pSchema ){ + int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); + zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; + } +#else + assert( iCol==XN_ROWID || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zType = "INTEGER"; + }else{ + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); + } +#endif + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: { + /* The expression is a sub-select. Return the declaration type and + ** origin info for the single column in the result set of the SELECT + ** statement. + */ + NameContext sNC; + Select *pS; + Expr *p; + assert( ExprUseXSelect(pExpr) ); + pS = pExpr->x.pSelect; + p = pS->pEList->a[0].pExpr; + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + break; + } +#endif + } + +#ifdef SQLITE_ENABLE_COLUMN_METADATA + if( pzOrigDb ){ + assert( pzOrigTab && pzOrigCol ); + *pzOrigDb = zOrigDb; + *pzOrigTab = zOrigTab; + *pzOrigCol = zOrigCol; + } +#endif + return zType; +} + +/* +** Generate code that will tell the VDBE the declaration types of columns +** in the result set. +*/ +static void generateColumnTypes( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* List of tables */ + ExprList *pEList /* Expressions defining the result set */ +){ +#ifndef SQLITE_OMIT_DECLTYPE + Vdbe *v = pParse->pVdbe; + int i; + NameContext sNC; + sNC.pSrcList = pTabList; + sNC.pParse = pParse; + sNC.pNext = 0; + for(i=0; inExpr; i++){ + Expr *p = pEList->a[i].pExpr; + const char *zType; +#ifdef SQLITE_ENABLE_COLUMN_METADATA + const char *zOrigDb = 0; + const char *zOrigTab = 0; + const char *zOrigCol = 0; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + + /* The vdbe must make its own copy of the column-type and other + ** column specific strings, in case the schema is reset before this + ** virtual machine is deleted. + */ + sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); +#else + zType = columnType(&sNC, p, 0, 0, 0); +#endif + sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); + } +#endif /* !defined(SQLITE_OMIT_DECLTYPE) */ +} + + +/* +** Compute the column names for a SELECT statement. +** +** The only guarantee that SQLite makes about column names is that if the +** column has an AS clause assigning it a name, that will be the name used. +** That is the only documented guarantee. However, countless applications +** developed over the years have made baseless assumptions about column names +** and will break if those assumptions changes. Hence, use extreme caution +** when modifying this routine to avoid breaking legacy. +** +** See Also: sqlite3ColumnsFromExprList() +** +** The PRAGMA short_column_names and PRAGMA full_column_names settings are +** deprecated. The default setting is short=ON, full=OFF. 99.9% of all +** applications should operate this way. Nevertheless, we need to support the +** other modes for legacy: +** +** short=OFF, full=OFF: Column name is the text of the expression has it +** originally appears in the SELECT statement. In +** other words, the zSpan of the result expression. +** +** short=ON, full=OFF: (This is the default setting). If the result +** refers directly to a table column, then the +** result column name is just the table column +** name: COLUMN. Otherwise use zSpan. +** +** full=ON, short=ANY: If the result refers directly to a table column, +** then the result column name with the table name +** prefix, ex: TABLE.COLUMN. Otherwise use zSpan. +*/ +SQLITE_PRIVATE void sqlite3GenerateColumnNames( + Parse *pParse, /* Parser context */ + Select *pSelect /* Generate column names for this SELECT statement */ +){ + Vdbe *v = pParse->pVdbe; + int i; + Table *pTab; + SrcList *pTabList; + ExprList *pEList; + sqlite3 *db = pParse->db; + int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ + int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ + + if( pParse->colNamesSet ) return; + /* Column names are determined by the left-most term of a compound select */ + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + TREETRACE(0x80,pParse,pSelect,("generating column names\n")); + pTabList = pSelect->pSrc; + pEList = pSelect->pEList; + assert( v!=0 ); + assert( pTabList!=0 ); + pParse->colNamesSet = 1; + fullName = (db->flags & SQLITE_FullColNames)!=0; + srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName; + sqlite3VdbeSetNumCols(v, pEList->nExpr); + for(i=0; inExpr; i++){ + Expr *p = pEList->a[i].pExpr; + + assert( p!=0 ); + assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ + assert( p->op!=TK_COLUMN + || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */ + if( pEList->a[i].zEName && pEList->a[i].fg.eEName==ENAME_NAME ){ + /* An AS clause always takes first priority */ + char *zName = pEList->a[i].zEName; + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); + }else if( srcName && p->op==TK_COLUMN ){ + char *zCol; + int iCol = p->iColumn; + pTab = p->y.pTab; + assert( pTab!=0 ); + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==-1 || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zCol = "rowid"; + }else{ + zCol = pTab->aCol[iCol].zCnName; + } + if( fullName ){ + char *zName = 0; + zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); + }else{ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); + } + }else{ + const char *z = pEList->a[i].zEName; + z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); + } + } + generateColumnTypes(pParse, pTabList, pEList); +} + +/* +** Given an expression list (which is really the list of expressions +** that form the result set of a SELECT statement) compute appropriate +** column names for a table that would hold the expression list. +** +** All column names will be unique. +** +** Only the column names are computed. Column.zType, Column.zColl, +** and other fields of Column are zeroed. +** +** Return SQLITE_OK on success. If a memory allocation error occurs, +** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. +** +** The only guarantee that SQLite makes about column names is that if the +** column has an AS clause assigning it a name, that will be the name used. +** That is the only documented guarantee. However, countless applications +** developed over the years have made baseless assumptions about column names +** and will break if those assumptions changes. Hence, use extreme caution +** when modifying this routine to avoid breaking legacy. +** +** See Also: sqlite3GenerateColumnNames() +*/ +SQLITE_PRIVATE int sqlite3ColumnsFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* Expr list from which to derive column names */ + i16 *pnCol, /* Write the number of columns here */ + Column **paCol /* Write the new column list here */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + int i, j; /* Loop counters */ + u32 cnt; /* Index added to make the name unique */ + Column *aCol, *pCol; /* For looping over result columns */ + int nCol; /* Number of columns in the result set */ + char *zName; /* Column name */ + int nName; /* Size of name in zName[] */ + Hash ht; /* Hash table of column names */ + Table *pTab; + + sqlite3HashInit(&ht); + if( pEList ){ + nCol = pEList->nExpr; + aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); + testcase( aCol==0 ); + if( NEVER(nCol>32767) ) nCol = 32767; + }else{ + nCol = 0; + aCol = 0; + } + assert( nCol==(i16)nCol ); + *pnCol = nCol; + *paCol = aCol; + + for(i=0, pCol=aCol; inErr; i++, pCol++){ + struct ExprList_item *pX = &pEList->a[i]; + struct ExprList_item *pCollide; + /* Get an appropriate name for the column + */ + if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){ + /* If the column contains an "AS " phrase, use as the name */ + }else{ + Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr); + while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){ + pColExpr = pColExpr->pRight; + assert( pColExpr!=0 ); + } + if( pColExpr->op==TK_COLUMN + && ALWAYS( ExprUseYTab(pColExpr) ) + && ALWAYS( pColExpr->y.pTab!=0 ) + ){ + /* For columns use the column name name */ + int iCol = pColExpr->iColumn; + pTab = pColExpr->y.pTab; + if( iCol<0 ) iCol = pTab->iPKey; + zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid"; + }else if( pColExpr->op==TK_ID ){ + assert( !ExprHasProperty(pColExpr, EP_IntValue) ); + zName = pColExpr->u.zToken; + }else{ + /* Use the original text of the column expression as its name */ + assert( zName==pX->zEName ); /* pointer comparison intended */ + } + } + if( zName && !sqlite3IsTrueOrFalse(zName) ){ + zName = sqlite3DbStrDup(db, zName); + }else{ + zName = sqlite3MPrintf(db,"column%d",i+1); + } + + /* Make sure the column name is unique. If the name is not unique, + ** append an integer to the name so that it becomes unique. + */ + cnt = 0; + while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){ + if( pCollide->fg.bUsingTerm ){ + pCol->colFlags |= COLFLAG_NOEXPAND; + } + nName = sqlite3Strlen30(zName); + if( nName>0 ){ + for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} + if( zName[j]==':' ) nName = j; + } + zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); + sqlite3ProgressCheck(pParse); + if( cnt>3 ){ + sqlite3_randomness(sizeof(cnt), &cnt); + } + } + pCol->zCnName = zName; + pCol->hName = sqlite3StrIHash(zName); + if( pX->fg.bNoExpand ){ + pCol->colFlags |= COLFLAG_NOEXPAND; + } + sqlite3ColumnPropertiesFromName(0, pCol); + if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){ + sqlite3OomFault(db); + } + } + sqlite3HashClear(&ht); + if( pParse->nErr ){ + for(j=0; jrc; + } + return SQLITE_OK; +} + +/* +** pTab is a transient Table object that represents a subquery of some +** kind (maybe a parenthesized subquery in the FROM clause of a larger +** query, or a VIEW, or a CTE). This routine computes type information +** for that Table object based on the Select object that implements the +** subquery. For the purposes of this routine, "type information" means: +** +** * The datatype name, as it might appear in a CREATE TABLE statement +** * Which collating sequence to use for the column +** * The affinity of the column +*/ +SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( + Parse *pParse, /* Parsing contexts */ + Table *pTab, /* Add column type information to this table */ + Select *pSelect, /* SELECT used to determine types and collations */ + char aff /* Default affinity. */ +){ + sqlite3 *db = pParse->db; + Column *pCol; + CollSeq *pColl; + int i,j; + Expr *p; + struct ExprList_item *a; + NameContext sNC; + + assert( pSelect!=0 ); + testcase( (pSelect->selFlags & SF_Resolved)==0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); + assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); + assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); + if( db->mallocFailed || IN_RENAME_OBJECT ) return; + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + a = pSelect->pEList->a; + memset(&sNC, 0, sizeof(sNC)); + sNC.pSrcList = pSelect->pSrc; + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + const char *zType; + i64 n; + pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); + p = a[i].pExpr; + /* pCol->szEst = ... // Column size est for SELECT tables never used */ + pCol->affinity = sqlite3ExprAffinity(p); + if( pCol->affinity<=SQLITE_AFF_NONE ){ + pCol->affinity = aff; + } + if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ + int m = 0; + Select *pS2; + for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ + m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); + } + if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ + pCol->affinity = SQLITE_AFF_BLOB; + }else + if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){ + pCol->affinity = SQLITE_AFF_BLOB; + } + if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){ + pCol->affinity = SQLITE_AFF_FLEXNUM; + } + } + zType = columnType(&sNC, p, 0, 0, 0); + if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){ + if( pCol->affinity==SQLITE_AFF_NUMERIC + || pCol->affinity==SQLITE_AFF_FLEXNUM + ){ + zType = "NUM"; + }else{ + zType = 0; + for(j=1; jaffinity ){ + zType = sqlite3StdType[j]; + break; + } + } + } + } + if( zType ){ + i64 m = sqlite3Strlen30(zType); + n = sqlite3Strlen30(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); + if( pCol->zCnName ){ + memcpy(&pCol->zCnName[n+1], zType, m+1); + pCol->colFlags |= COLFLAG_HASTYPE; + } + } + pColl = sqlite3ExprCollSeq(pParse, p); + if( pColl ){ + assert( pTab->pIndex==0 ); + sqlite3ColumnSetColl(db, pCol, pColl->zName); + } + } + pTab->szTabRow = 1; /* Any non-zero value works */ +} + +/* +** Given a SELECT statement, generate a Table structure that describes +** the result set of that SELECT. +*/ +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){ + Table *pTab; + sqlite3 *db = pParse->db; + u64 savedFlags; + + savedFlags = db->flags; + db->flags &= ~(u64)SQLITE_FullColNames; + db->flags |= SQLITE_ShortColNames; + sqlite3SelectPrep(pParse, pSelect, 0); + db->flags = savedFlags; + if( pParse->nErr ) return 0; + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + pTab = sqlite3DbMallocZero(db, sizeof(Table) ); + if( pTab==0 ){ + return 0; + } + pTab->nTabRef = 1; + pTab->zName = 0; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); + sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff); + pTab->iPKey = -1; + if( db->mallocFailed ){ + sqlite3DeleteTable(db, pTab); + return 0; + } + return pTab; +} + +/* +** Get a VDBE for the given parser context. Create a new one if necessary. +** If an error occurs, return NULL and leave a message in pParse. +*/ +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ + if( pParse->pVdbe ){ + return pParse->pVdbe; + } + if( pParse->pToplevel==0 + && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) + ){ + pParse->okConstFactor = 1; + } + return sqlite3VdbeCreate(pParse); +} + + +/* +** Compute the iLimit and iOffset fields of the SELECT based on the +** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions +** that appear in the original SQL statement after the LIMIT and OFFSET +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then +** iLimit and iOffset are negative. +** +** This routine changes the values of iLimit and iOffset only if +** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit +** and iOffset should have been preset to appropriate default values (zero) +** prior to calling this routine. +** +** The iOffset register (if it exists) is initialized to the value +** of the OFFSET. The iLimit register is initialized to LIMIT. Register +** iOffset+1 is initialized to LIMIT+OFFSET. +** +** Only if pLimit->pLeft!=0 do the limit registers get +** redefined. The UNION ALL operator uses this property to force +** the reuse of the same limit and offset registers across multiple +** SELECT statements. +*/ +static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ + Vdbe *v = 0; + int iLimit = 0; + int iOffset; + int n; + Expr *pLimit = p->pLimit; + + if( p->iLimit ) return; + + /* + ** "LIMIT -1" always shows all rows. There is some + ** controversy about what the correct behavior should be. + ** The current implementation interprets "LIMIT 0" to mean + ** no rows. + */ + if( pLimit ){ + assert( pLimit->op==TK_LIMIT ); + assert( pLimit->pLeft!=0 ); + p->iLimit = iLimit = ++pParse->nMem; + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ + sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); + VdbeComment((v, "LIMIT counter")); + if( n==0 ){ + sqlite3VdbeGoto(v, iBreak); + }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){ + p->nSelectRow = sqlite3LogEst((u64)n); + p->selFlags |= SF_FixedLimit; + } + }else{ + sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); + VdbeComment((v, "LIMIT counter")); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); + } + if( pLimit->pRight ){ + p->iOffset = iOffset = ++pParse->nMem; + pParse->nMem++; /* Allocate an extra register for limit+offset */ + sqlite3ExprCode(pParse, pLimit->pRight, iOffset); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); + VdbeComment((v, "OFFSET counter")); + sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); + VdbeComment((v, "LIMIT+OFFSET")); + } + } +} + +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** Return the appropriate collating sequence for the iCol-th column of +** the result set for the compound-select statement "p". Return NULL if +** the column has no default collating sequence. +** +** The collating sequence for the compound select is taken from the +** left-most term of the select that has a collating sequence. +*/ +static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ + CollSeq *pRet; + if( p->pPrior ){ + pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); + }else{ + pRet = 0; + } + assert( iCol>=0 ); + /* iCol must be less than p->pEList->nExpr. Otherwise an error would + ** have been thrown during name resolution and we would not have gotten + ** this far */ + if( pRet==0 && ALWAYS(iColpEList->nExpr) ){ + pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); + } + return pRet; +} + +/* +** The select statement passed as the second parameter is a compound SELECT +** with an ORDER BY clause. This function allocates and returns a KeyInfo +** structure suitable for implementing the ORDER BY. +** +** Space to hold the KeyInfo structure is obtained from malloc. The calling +** function is responsible for ensuring that this structure is eventually +** freed. +*/ +static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ + ExprList *pOrderBy = p->pOrderBy; + int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0; + sqlite3 *db = pParse->db; + KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); + if( pRet ){ + int i; + for(i=0; ia[i]; + Expr *pTerm = pItem->pExpr; + CollSeq *pColl; + + if( pTerm->flags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pTerm); + }else{ + pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); + if( pColl==0 ) pColl = db->pDfltColl; + pOrderBy->a[i].pExpr = + sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); + } + assert( sqlite3KeyInfoIsWriteable(pRet) ); + pRet->aColl[i] = pColl; + pRet->aSortFlags[i] = pOrderBy->a[i].fg.sortFlags; + } + } + + return pRet; +} + +#ifndef SQLITE_OMIT_CTE +/* +** This routine generates VDBE code to compute the content of a WITH RECURSIVE +** query of the form: +** +** AS ( UNION [ALL] ) +** \___________/ \_______________/ +** p->pPrior p +** +** +** There is exactly one reference to the recursive-table in the FROM clause +** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag. +** +** The setup-query runs once to generate an initial set of rows that go +** into a Queue table. Rows are extracted from the Queue table one by +** one. Each row extracted from Queue is output to pDest. Then the single +** extracted row (now in the iCurrent table) becomes the content of the +** recursive-table for a recursive-query run. The output of the recursive-query +** is added back into the Queue table. Then another row is extracted from Queue +** and the iteration continues until the Queue table is empty. +** +** If the compound query operator is UNION then no duplicate rows are ever +** inserted into the Queue table. The iDistinct table keeps a copy of all rows +** that have ever been inserted into Queue and causes duplicates to be +** discarded. If the operator is UNION ALL, then duplicates are allowed. +** +** If the query has an ORDER BY, then entries in the Queue table are kept in +** ORDER BY order and the first entry is extracted for each cycle. Without +** an ORDER BY, the Queue table is just a FIFO. +** +** If a LIMIT clause is provided, then the iteration stops after LIMIT rows +** have been output to pDest. A LIMIT of zero means to output no rows and a +** negative LIMIT means to output all rows. If there is also an OFFSET clause +** with a positive value, then the first OFFSET outputs are discarded rather +** than being sent to pDest. The LIMIT count does not begin until after OFFSET +** rows have been skipped. +*/ +static void generateWithRecursiveQuery( + Parse *pParse, /* Parsing context */ + Select *p, /* The recursive SELECT to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ + int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ + Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + Select *pSetup; /* The setup query */ + Select *pFirstRec; /* Left-most recursive term */ + int addrTop; /* Top of the loop */ + int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ + int iCurrent = 0; /* The Current table */ + int regCurrent; /* Register holding Current table */ + int iQueue; /* The Queue table */ + int iDistinct = 0; /* To ensure unique results if UNION */ + int eDest = SRT_Fifo; /* How to write to Queue */ + SelectDest destQueue; /* SelectDest targeting the Queue table */ + int i; /* Loop counter */ + int rc; /* Result code */ + ExprList *pOrderBy; /* The ORDER BY clause */ + Expr *pLimit; /* Saved LIMIT and OFFSET */ + int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); + return; + } +#endif + + /* Obtain authorization to do a recursive query */ + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; + + /* Process the LIMIT and OFFSET clauses, if they exist */ + addrBreak = sqlite3VdbeMakeLabel(pParse); + p->nSelectRow = 320; /* 4 billion rows */ + computeLimitRegisters(pParse, p, addrBreak); + pLimit = p->pLimit; + regLimit = p->iLimit; + regOffset = p->iOffset; + p->pLimit = 0; + p->iLimit = p->iOffset = 0; + pOrderBy = p->pOrderBy; + + /* Locate the cursor number of the Current table */ + for(i=0; ALWAYS(inSrc); i++){ + if( pSrc->a[i].fg.isRecursive ){ + iCurrent = pSrc->a[i].iCursor; + break; + } + } + + /* Allocate cursors numbers for Queue and Distinct. The cursor number for + ** the Distinct table must be exactly one greater than Queue in order + ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */ + iQueue = pParse->nTab++; + if( p->op==TK_UNION ){ + eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo; + iDistinct = pParse->nTab++; + }else{ + eDest = pOrderBy ? SRT_Queue : SRT_Fifo; + } + sqlite3SelectDestInit(&destQueue, eDest, iQueue); + + /* Allocate cursors for Current, Queue, and Distinct. */ + regCurrent = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + if( pOrderBy ){ + KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, + (char*)pKeyInfo, P4_KEYINFO); + destQueue.pOrderBy = pOrderBy; + }else{ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + } + VdbeComment((v, "Queue table")); + if( iDistinct ){ + p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); + p->selFlags |= SF_UsesEphemeral; + } + + /* Detach the ORDER BY clause from the compound SELECT */ + p->pOrderBy = 0; + + /* Figure out how many elements of the compound SELECT are part of the + ** recursive query. Make sure no recursive elements use aggregate + ** functions. Mark the recursive elements as UNION ALL even if they + ** are really UNION because the distinctness will be enforced by the + ** iDistinct table. pFirstRec is left pointing to the left-most + ** recursive term of the CTE. + */ + for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){ + if( pFirstRec->selFlags & SF_Aggregate ){ + sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); + goto end_of_recursive_query; + } + pFirstRec->op = TK_ALL; + if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break; + } + + /* Store the results of the setup-query in Queue. */ + pSetup = pFirstRec->pPrior; + pSetup->pNext = 0; + ExplainQueryPlan((pParse, 1, "SETUP")); + rc = sqlite3Select(pParse, pSetup, &destQueue); + pSetup->pNext = p; + if( rc ) goto end_of_recursive_query; + + /* Find the next row in the Queue and output that row */ + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); + + /* Transfer the next row in Queue over to Current */ + sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ + if( pOrderBy ){ + sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + } + sqlite3VdbeAddOp1(v, OP_Delete, iQueue); + + /* Output the single row in Current */ + addrCont = sqlite3VdbeMakeLabel(pParse); + codeOffset(v, regOffset, addrCont); + selectInnerLoop(pParse, p, iCurrent, + 0, 0, pDest, addrCont, addrBreak); + if( regLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); + VdbeCoverage(v); + } + sqlite3VdbeResolveLabel(v, addrCont); + + /* Execute the recursive SELECT taking the single row in Current as + ** the value for the recursive-table. Store the results in the Queue. + */ + pFirstRec->pPrior = 0; + ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); + sqlite3Select(pParse, p, &destQueue); + assert( pFirstRec->pPrior==0 ); + pFirstRec->pPrior = pSetup; + + /* Keep running the loop until the Queue is empty */ + sqlite3VdbeGoto(v, addrTop); + sqlite3VdbeResolveLabel(v, addrBreak); + +end_of_recursive_query: + sqlite3ExprListDelete(pParse->db, p->pOrderBy); + p->pOrderBy = pOrderBy; + p->pLimit = pLimit; + return; +} +#endif /* SQLITE_OMIT_CTE */ + +/* Forward references */ +static int multiSelectOrderBy( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +); + +/* +** Handle the special case of a compound-select that originates from a +** VALUES clause. By handling this as a special case, we avoid deep +** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT +** on a VALUES clause. +** +** Because the Select object originates from a VALUES clause: +** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1 +** (2) All terms are UNION ALL +** (3) There is no ORDER BY clause +** +** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES +** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). +** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. +** Since the limit is exactly 1, we only need to evaluate the left-most VALUES. +*/ +static int multiSelectValues( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int nRow = 1; + int rc = 0; + int bShowAll = p->pLimit==0; + assert( p->selFlags & SF_MultiValue ); + do{ + assert( p->selFlags & SF_Values ); + assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); + assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) return -1; +#endif + if( p->pPrior==0 ) break; + assert( p->pPrior->pNext==p ); + p = p->pPrior; + nRow += bShowAll; + }while(1); + ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow, + nRow==1 ? "" : "S")); + while( p ){ + selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1); + if( !bShowAll ) break; + p->nSelectRow = nRow; + p = p->pNext; + } + return rc; +} + +/* +** Return true if the SELECT statement which is known to be the recursive +** part of a recursive CTE still has its anchor terms attached. If the +** anchor terms have already been removed, then return false. +*/ +static int hasAnchor(Select *p){ + while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; } + return p!=0; +} + +/* +** This routine is called to process a compound query form from +** two or more separate queries using UNION, UNION ALL, EXCEPT, or +** INTERSECT +** +** "p" points to the right-most of the two queries. the query on the +** left is p->pPrior. The left query could also be a compound query +** in which case this routine will be called recursively. +** +** The results of the total query are to be written into a destination +** of type eDest with parameter iParm. +** +** Example 1: Consider a three-way compound SQL statement. +** +** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 +** +** This statement is parsed up as follows: +** +** SELECT c FROM t3 +** | +** `-----> SELECT b FROM t2 +** | +** `------> SELECT a FROM t1 +** +** The arrows in the diagram above represent the Select.pPrior pointer. +** So if this routine is called with p equal to the t3 query, then +** pPrior will be the t2 query. p->op will be TK_UNION in this case. +** +** Notice that because of the way SQLite parses compound SELECTs, the +** individual selects always group from left to right. +*/ +static int multiSelect( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int rc = SQLITE_OK; /* Success code from a subroutine */ + Select *pPrior; /* Another SELECT immediately to our left */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest dest; /* Alternative data destination */ + Select *pDelete = 0; /* Chain of simple selects to delete */ + sqlite3 *db; /* Database connection */ + + /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only + ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. + */ + assert( p && p->pPrior ); /* Calling function guarantees this much */ + assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); + assert( p->selFlags & SF_Compound ); + db = pParse->db; + pPrior = p->pPrior; + dest = *pDest; + assert( pPrior->pOrderBy==0 ); + assert( pPrior->pLimit==0 ); + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); /* The VDBE already created by calling function */ + + /* Create the destination temporary table if necessary + */ + if( dest.eDest==SRT_EphemTab ){ + assert( p->pEList ); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); + dest.eDest = SRT_Table; + } + + /* Special handling for a compound-select that originates as a VALUES clause. + */ + if( p->selFlags & SF_MultiValue ){ + rc = multiSelectValues(pParse, p, &dest); + if( rc>=0 ) goto multi_select_end; + rc = SQLITE_OK; + } + + /* Make sure all SELECTs in the statement have the same number of elements + ** in their result sets. + */ + assert( p->pEList && pPrior->pEList ); + assert( p->pEList->nExpr==pPrior->pEList->nExpr ); + +#ifndef SQLITE_OMIT_CTE + if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){ + generateWithRecursiveQuery(pParse, p, &dest); + }else +#endif + + /* Compound SELECTs that have an ORDER BY clause are handled separately. + */ + if( p->pOrderBy ){ + return multiSelectOrderBy(pParse, p, pDest); + }else{ + +#ifndef SQLITE_OMIT_EXPLAIN + if( pPrior->pPrior==0 ){ + ExplainQueryPlan((pParse, 1, "COMPOUND QUERY")); + ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY")); + } +#endif + + /* Generate code for the left and right SELECT statements. + */ + switch( p->op ){ + case TK_ALL: { + int addr = 0; + int nLimit = 0; /* Initialize to suppress harmless compiler warning */ + assert( !pPrior->pLimit ); + pPrior->iLimit = p->iLimit; + pPrior->iOffset = p->iOffset; + pPrior->pLimit = p->pLimit; + TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); + rc = sqlite3Select(pParse, pPrior, &dest); + pPrior->pLimit = 0; + if( rc ){ + goto multi_select_end; + } + p->pPrior = 0; + p->iLimit = pPrior->iLimit; + p->iOffset = pPrior->iOffset; + if( p->iLimit ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); + VdbeComment((v, "Jump ahead if LIMIT reached")); + if( p->iOffset ){ + sqlite3VdbeAddOp3(v, OP_OffsetLimit, + p->iLimit, p->iOffset+1, p->iOffset); + } + } + ExplainQueryPlan((pParse, 1, "UNION ALL")); + TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); + rc = sqlite3Select(pParse, p, &dest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + if( p->pLimit + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) + && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) + ){ + p->nSelectRow = sqlite3LogEst((u64)nLimit); + } + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + } + break; + } + case TK_EXCEPT: + case TK_UNION: { + int unionTab; /* Cursor number of the temp table holding result */ + u8 op = 0; /* One of the SRT_ operations to apply to self */ + int priorOp; /* The SRT_ operation to apply to prior selects */ + Expr *pLimit; /* Saved values of p->nLimit */ + int addr; + SelectDest uniondest; + + testcase( p->op==TK_EXCEPT ); + testcase( p->op==TK_UNION ); + priorOp = SRT_Union; + if( dest.eDest==priorOp ){ + /* We can reuse a temporary table generated by a SELECT to our + ** right. + */ + assert( p->pLimit==0 ); /* Not allowed on leftward elements */ + unionTab = dest.iSDParm; + }else{ + /* We will need to create our own temporary table to hold the + ** intermediate results. + */ + unionTab = pParse->nTab++; + assert( p->pOrderBy==0 ); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + findRightmost(p)->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + } + + + /* Code the SELECT statements to our left + */ + assert( !pPrior->pOrderBy ); + sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); + rc = sqlite3Select(pParse, pPrior, &uniondest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT statement + */ + if( p->op==TK_EXCEPT ){ + op = SRT_Except; + }else{ + assert( p->op==TK_UNION ); + op = SRT_Union; + } + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + uniondest.eDest = op; + ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", + sqlite3SelectOpName(p->op))); + TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); + rc = sqlite3Select(pParse, p, &uniondest); + testcase( rc!=SQLITE_OK ); + assert( p->pOrderBy==0 ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->pOrderBy = 0; + if( p->op==TK_UNION ){ + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + p->iLimit = 0; + p->iOffset = 0; + + /* Convert the data in the temporary table into whatever form + ** it is that we currently need. + */ + assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); + assert( p->pEList || db->mallocFailed ); + if( dest.eDest!=priorOp && db->mallocFailed==0 ){ + int iCont, iBreak, iStart; + iBreak = sqlite3VdbeMakeLabel(pParse); + iCont = sqlite3VdbeMakeLabel(pParse); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); + iStart = sqlite3VdbeCurrentAddr(v); + selectInnerLoop(pParse, p, unionTab, + 0, 0, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); + } + break; + } + default: assert( p->op==TK_INTERSECT ); { + int tab1, tab2; + int iCont, iBreak, iStart; + Expr *pLimit; + int addr; + SelectDest intersectdest; + int r1; + + /* INTERSECT is different from the others since it requires + ** two temporary tables. Hence it has its own case. Begin + ** by allocating the tables we will need. + */ + tab1 = pParse->nTab++; + tab2 = pParse->nTab++; + assert( p->pOrderBy==0 ); + + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + findRightmost(p)->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + + /* Code the SELECTs to our left into temporary table "tab1". + */ + sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n")); + rc = sqlite3Select(pParse, pPrior, &intersectdest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT into temporary table "tab2" + */ + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); + assert( p->addrOpenEphm[1] == -1 ); + p->addrOpenEphm[1] = addr; + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + intersectdest.iSDParm = tab2; + ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", + sqlite3SelectOpName(p->op))); + TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n")); + rc = sqlite3Select(pParse, p, &intersectdest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + if( p->nSelectRow>pPrior->nSelectRow ){ + p->nSelectRow = pPrior->nSelectRow; + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + + /* Generate code to take the intersection of the two temporary + ** tables. + */ + if( rc ) break; + assert( p->pEList ); + iBreak = sqlite3VdbeMakeLabel(pParse); + iCont = sqlite3VdbeMakeLabel(pParse); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); + r1 = sqlite3GetTempReg(pParse); + iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); + sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, r1); + selectInnerLoop(pParse, p, tab1, + 0, 0, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); + sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); + break; + } + } + + #ifndef SQLITE_OMIT_EXPLAIN + if( p->pNext==0 ){ + ExplainQueryPlanPop(pParse); + } + #endif + } + if( pParse->nErr ) goto multi_select_end; + + /* Compute collating sequences used by + ** temporary tables needed to implement the compound select. + ** Attach the KeyInfo structure to all temporary tables. + ** + ** This section is run by the right-most SELECT statement only. + ** SELECT statements to the left always skip this part. The right-most + ** SELECT might also skip this part if it has no ORDER BY clause and + ** no temp tables are required. + */ + if( p->selFlags & SF_UsesEphemeral ){ + int i; /* Loop counter */ + KeyInfo *pKeyInfo; /* Collating sequence for the result set */ + Select *pLoop; /* For looping through SELECT statements */ + CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ + int nCol; /* Number of columns in result set */ + + assert( p->pNext==0 ); + assert( p->pEList!=0 ); + nCol = p->pEList->nExpr; + pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); + if( !pKeyInfo ){ + rc = SQLITE_NOMEM_BKPT; + goto multi_select_end; + } + for(i=0, apColl=pKeyInfo->aColl; ipDfltColl; + } + } + + for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ + for(i=0; i<2; i++){ + int addr = pLoop->addrOpenEphm[i]; + if( addr<0 ){ + /* If [0] is unused then [1] is also unused. So we can + ** always safely abort as soon as the first unused slot is found */ + assert( pLoop->addrOpenEphm[1]<0 ); + break; + } + sqlite3VdbeChangeP2(v, addr, nCol); + sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo), + P4_KEYINFO); + pLoop->addrOpenEphm[i] = -1; + } + } + sqlite3KeyInfoUnref(pKeyInfo); + } + +multi_select_end: + pDest->iSdst = dest.iSdst; + pDest->nSdst = dest.nSdst; + if( pDelete ){ + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); + } + return rc; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +/* +** Error message for when two or more terms of a compound select have different +** size result sets. +*/ +SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ + if( p->selFlags & SF_Values ){ + sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); + }else{ + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" + " do not have the same number of result columns", + sqlite3SelectOpName(p->op)); + } +} + +/* +** Code an output subroutine for a coroutine implementation of a +** SELECT statement. +** +** The data to be output is contained in pIn->iSdst. There are +** pIn->nSdst columns to be output. pDest is where the output should +** be sent. +** +** regReturn is the number of the register holding the subroutine +** return address. +** +** If regPrev>0 then it is the first register in a vector that +** records the previous output. mem[regPrev] is a flag that is false +** if there has been no previous output. If regPrev>0 then code is +** generated to suppress duplicates. pKeyInfo is used for comparing +** keys. +** +** If the LIMIT found in p->iLimit is reached, jump immediately to +** iBreak. +*/ +static int generateOutputSubroutine( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + SelectDest *pIn, /* Coroutine supplying data */ + SelectDest *pDest, /* Where to send the data */ + int regReturn, /* The return address register */ + int regPrev, /* Previous result register. No uniqueness if 0 */ + KeyInfo *pKeyInfo, /* For comparing with previous entry */ + int iBreak /* Jump here if we hit the LIMIT */ +){ + Vdbe *v = pParse->pVdbe; + int iContinue; + int addr; + + addr = sqlite3VdbeCurrentAddr(v); + iContinue = sqlite3VdbeMakeLabel(pParse); + + /* Suppress duplicates for UNION, EXCEPT, and INTERSECT + */ + if( regPrev ){ + int addr1, addr2; + addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); + addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); + } + if( pParse->db->mallocFailed ) return 0; + + /* Suppress the first OFFSET entries if there is an OFFSET clause + */ + codeOffset(v, p->iOffset, iContinue); + + assert( pDest->eDest!=SRT_Exists ); + assert( pDest->eDest!=SRT_Table ); + switch( pDest->eDest ){ + /* Store the result as data using a unique key. + */ + case SRT_EphemTab: { + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); + sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + +#ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)". + */ + case SRT_Set: { + int r1; + testcase( pIn->nSdst>1 ); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, + r1, pDest->zAffSdst, pIn->nSdst); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, + pIn->iSdst, pIn->nSdst); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + + /* If this is a scalar select that is part of an expression, then + ** store the results in the appropriate memory cell and break out + ** of the scan loop. Note that the select might return multiple columns + ** if it is the RHS of a row-value IN operator. + */ + case SRT_Mem: { + testcase( pIn->nSdst>1 ); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); + /* The LIMIT clause will jump out of the loop for us */ + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + /* The results are stored in a sequence of registers + ** starting at pDest->iSdst. Then the co-routine yields. + */ + case SRT_Coroutine: { + if( pDest->iSdst==0 ){ + pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); + pDest->nSdst = pIn->nSdst; + } + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + break; + } + + /* If none of the above, then the result destination must be + ** SRT_Output. This routine is never called with any other + ** destination other than the ones handled above or SRT_Output. + ** + ** For SRT_Output, results are stored in a sequence of registers. + ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to + ** return the next row of result. + */ + default: { + assert( pDest->eDest==SRT_Output ); + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); + break; + } + } + + /* Jump to the end of the loop if the LIMIT is reached. + */ + if( p->iLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + } + + /* Generate the subroutine return + */ + sqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp1(v, OP_Return, regReturn); + + return addr; +} + +/* +** Alternative compound select code generator for cases when there +** is an ORDER BY clause. +** +** We assume a query of the following form: +** +** ORDER BY +** +** is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea +** is to code both and with the ORDER BY clause as +** co-routines. Then run the co-routines in parallel and merge the results +** into the output. In addition to the two coroutines (called selectA and +** selectB) there are 7 subroutines: +** +** outA: Move the output of the selectA coroutine into the output +** of the compound query. +** +** outB: Move the output of the selectB coroutine into the output +** of the compound query. (Only generated for UNION and +** UNION ALL. EXCEPT and INSERTSECT never output a row that +** appears only in B.) +** +** AltB: Called when there is data from both coroutines and AB. +** +** EofA: Called when data is exhausted from selectA. +** +** EofB: Called when data is exhausted from selectB. +** +** The implementation of the latter five subroutines depend on which +** is used: +** +** +** UNION ALL UNION EXCEPT INTERSECT +** ------------- ----------------- -------------- ----------------- +** AltB: outA, nextA outA, nextA outA, nextA nextA +** +** AeqB: outA, nextA nextA nextA outA, nextA +** +** AgtB: outB, nextB outB, nextB nextB nextB +** +** EofA: outB, nextB outB, nextB halt halt +** +** EofB: outA, nextA outA, nextA outA, nextA halt +** +** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA +** causes an immediate jump to EofA and an EOF on B following nextB causes +** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or +** following nextX causes a jump to the end of the select processing. +** +** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled +** within the output subroutine. The regPrev register set holds the previously +** output value. A comparison is made against this value and the output +** is skipped if the next results would be the same as the previous. +** +** The implementation plan is to implement the two coroutines and seven +** subroutines first, then put the control logic at the bottom. Like this: +** +** goto Init +** coA: coroutine for left query (A) +** coB: coroutine for right query (B) +** outA: output one row of A +** outB: output one row of B (UNION and UNION ALL only) +** EofA: ... +** EofB: ... +** AltB: ... +** AeqB: ... +** AgtB: ... +** Init: initialize coroutine registers +** yield coA +** if eof(A) goto EofA +** yield coB +** if eof(B) goto EofB +** Cmpr: Compare A, B +** Jump AltB, AeqB, AgtB +** End: ... +** +** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not +** actually called using Gosub and they do not Return. EofA and EofB loop +** until all data is exhausted then jump to the "end" label. AltB, AeqB, +** and AgtB jump to either L2 or to one of EofA or EofB. +*/ +#ifndef SQLITE_OMIT_COMPOUND_SELECT +static int multiSelectOrderBy( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int i, j; /* Loop counters */ + Select *pPrior; /* Another SELECT immediately to our left */ + Select *pSplit; /* Left-most SELECT in the right-hand group */ + int nSelect; /* Number of SELECT statements in the compound */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest destA; /* Destination for coroutine A */ + SelectDest destB; /* Destination for coroutine B */ + int regAddrA; /* Address register for select-A coroutine */ + int regAddrB; /* Address register for select-B coroutine */ + int addrSelectA; /* Address of the select-A coroutine */ + int addrSelectB; /* Address of the select-B coroutine */ + int regOutA; /* Address register for the output-A subroutine */ + int regOutB; /* Address register for the output-B subroutine */ + int addrOutA; /* Address of the output-A subroutine */ + int addrOutB = 0; /* Address of the output-B subroutine */ + int addrEofA; /* Address of the select-A-exhausted subroutine */ + int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */ + int addrEofB; /* Address of the select-B-exhausted subroutine */ + int addrAltB; /* Address of the AB subroutine */ + int regLimitA; /* Limit register for select-A */ + int regLimitB; /* Limit register for select-A */ + int regPrev; /* A range of registers to hold previous output */ + int savedLimit; /* Saved value of p->iLimit */ + int savedOffset; /* Saved value of p->iOffset */ + int labelCmpr; /* Label for the start of the merge algorithm */ + int labelEnd; /* Label for the end of the overall SELECT stmt */ + int addr1; /* Jump instructions that get retargeted */ + int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ + KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ + KeyInfo *pKeyMerge; /* Comparison information for merging rows */ + sqlite3 *db; /* Database connection */ + ExprList *pOrderBy; /* The ORDER BY clause */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + u32 *aPermute; /* Mapping from ORDER BY terms to result set columns */ + + assert( p->pOrderBy!=0 ); + assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ + db = pParse->db; + v = pParse->pVdbe; + assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ + labelEnd = sqlite3VdbeMakeLabel(pParse); + labelCmpr = sqlite3VdbeMakeLabel(pParse); + + + /* Patch up the ORDER BY clause + */ + op = p->op; + assert( p->pPrior->pOrderBy==0 ); + pOrderBy = p->pOrderBy; + assert( pOrderBy ); + nOrderBy = pOrderBy->nExpr; + + /* For operators other than UNION ALL we have to make sure that + ** the ORDER BY clause covers every term of the result set. Add + ** terms to the ORDER BY clause as necessary. + */ + if( op!=TK_ALL ){ + for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ + struct ExprList_item *pItem; + for(j=0, pItem=pOrderBy->a; ju.x.iOrderByCol>0 ); + if( pItem->u.x.iOrderByCol==i ) break; + } + if( j==nOrderBy ){ + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + if( pNew==0 ) return SQLITE_NOMEM_BKPT; + pNew->flags |= EP_IntValue; + pNew->u.iValue = i; + p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); + if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; + } + } + } + + /* Compute the comparison permutation and keyinfo that is used with + ** the permutation used to determine if the next + ** row of results comes from selectA or selectB. Also add explicit + ** collations to the ORDER BY clause terms so that when the subqueries + ** to the right and the left are evaluated, they use the correct + ** collation. + */ + aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1)); + if( aPermute ){ + struct ExprList_item *pItem; + aPermute[0] = nOrderBy; + for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ + assert( pItem!=0 ); + assert( pItem->u.x.iOrderByCol>0 ); + assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->u.x.iOrderByCol - 1; + } + pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); + }else{ + pKeyMerge = 0; + } + + /* Allocate a range of temporary registers and the KeyInfo needed + ** for the logic that removes duplicate result rows when the + ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). + */ + if( op==TK_ALL ){ + regPrev = 0; + }else{ + int nExpr = p->pEList->nExpr; + assert( nOrderBy>=nExpr || db->mallocFailed ); + regPrev = pParse->nMem+1; + pParse->nMem += nExpr+1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); + pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); + if( pKeyDup ){ + assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); + for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); + pKeyDup->aSortFlags[i] = 0; + } + } + } + + /* Separate the left and the right query from one another + */ + nSelect = 1; + if( (op==TK_ALL || op==TK_UNION) + && OptimizationEnabled(db, SQLITE_BalancedMerge) + ){ + for(pSplit=p; pSplit->pPrior!=0 && pSplit->op==op; pSplit=pSplit->pPrior){ + nSelect++; + assert( pSplit->pPrior->pNext==pSplit ); + } + } + if( nSelect<=3 ){ + pSplit = p; + }else{ + pSplit = p; + for(i=2; ipPrior; } + } + pPrior = pSplit->pPrior; + assert( pPrior!=0 ); + pSplit->pPrior = 0; + pPrior->pNext = 0; + assert( p->pOrderBy == pOrderBy ); + assert( pOrderBy!=0 || db->mallocFailed ); + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); + sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); + + /* Compute the limit registers */ + computeLimitRegisters(pParse, p, labelEnd); + if( p->iLimit && op==TK_ALL ){ + regLimitA = ++pParse->nMem; + regLimitB = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, + regLimitA); + sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); + }else{ + regLimitA = regLimitB = 0; + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = 0; + + regAddrA = ++pParse->nMem; + regAddrB = ++pParse->nMem; + regOutA = ++pParse->nMem; + regOutB = ++pParse->nMem; + sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); + sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); + + ExplainQueryPlan((pParse, 1, "MERGE (%s)", sqlite3SelectOpName(p->op))); + + /* Generate a coroutine to evaluate the SELECT statement to the + ** left of the compound operator - the "A" select. + */ + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); + VdbeComment((v, "left SELECT")); + pPrior->iLimit = regLimitA; + ExplainQueryPlan((pParse, 1, "LEFT")); + sqlite3Select(pParse, pPrior, &destA); + sqlite3VdbeEndCoroutine(v, regAddrA); + sqlite3VdbeJumpHere(v, addr1); + + /* Generate a coroutine to evaluate the SELECT statement on + ** the right - the "B" select + */ + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); + VdbeComment((v, "right SELECT")); + savedLimit = p->iLimit; + savedOffset = p->iOffset; + p->iLimit = regLimitB; + p->iOffset = 0; + ExplainQueryPlan((pParse, 1, "RIGHT")); + sqlite3Select(pParse, p, &destB); + p->iLimit = savedLimit; + p->iOffset = savedOffset; + sqlite3VdbeEndCoroutine(v, regAddrB); + + /* Generate a subroutine that outputs the current row of the A + ** select as the next output row of the compound select. + */ + VdbeNoopComment((v, "Output routine for A")); + addrOutA = generateOutputSubroutine(pParse, + p, &destA, pDest, regOutA, + regPrev, pKeyDup, labelEnd); + + /* Generate a subroutine that outputs the current row of the B + ** select as the next output row of the compound select. + */ + if( op==TK_ALL || op==TK_UNION ){ + VdbeNoopComment((v, "Output routine for B")); + addrOutB = generateOutputSubroutine(pParse, + p, &destB, pDest, regOutB, + regPrev, pKeyDup, labelEnd); + } + sqlite3KeyInfoUnref(pKeyDup); + + /* Generate a subroutine to run when the results from select A + ** are exhausted and only data in select B remains. + */ + if( op==TK_EXCEPT || op==TK_INTERSECT ){ + addrEofA_noB = addrEofA = labelEnd; + }else{ + VdbeNoopComment((v, "eof-A subroutine")); + addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); + VdbeCoverage(v); + sqlite3VdbeGoto(v, addrEofA); + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + } + + /* Generate a subroutine to run when the results from select B + ** are exhausted and only data in select A remains. + */ + if( op==TK_INTERSECT ){ + addrEofB = addrEofA; + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + }else{ + VdbeNoopComment((v, "eof-B subroutine")); + addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); + sqlite3VdbeGoto(v, addrEofB); + } + + /* Generate code to handle the case of AB + */ + VdbeNoopComment((v, "A-gt-B subroutine")); + addrAgtB = sqlite3VdbeCurrentAddr(v); + if( op==TK_ALL || op==TK_UNION ){ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + } + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + sqlite3VdbeGoto(v, labelCmpr); + + /* This code runs once to initialize everything. + */ + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + + /* Implement the main merge loop + */ + sqlite3VdbeResolveLabel(v, labelCmpr); + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); + sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, + (char*)pKeyMerge, P4_KEYINFO); + sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); + + /* Jump to the this point in order to terminate the query. + */ + sqlite3VdbeResolveLabel(v, labelEnd); + + /* Make arrangements to free the 2nd and subsequent arms of the compound + ** after the parse has finished */ + if( pSplit->pPrior ){ + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior); + } + pSplit->pPrior = pPrior; + pPrior->pNext = pSplit; + sqlite3ExprListDelete(db, pPrior->pOrderBy); + pPrior->pOrderBy = 0; + + /*** TBD: Insert subroutine calls to close cursors on incomplete + **** subqueries ****/ + ExplainQueryPlanPop(pParse); + return pParse->nErr!=0; +} +#endif + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + +/* An instance of the SubstContext object describes an substitution edit +** to be performed on a parse tree. +** +** All references to columns in table iTable are to be replaced by corresponding +** expressions in pEList. +** +** ## About "isOuterJoin": +** +** The isOuterJoin column indicates that the replacement will occur into a +** position in the parent that NULL-able due to an OUTER JOIN. Either the +** target slot in the parent is the right operand of a LEFT JOIN, or one of +** the left operands of a RIGHT JOIN. In either case, we need to potentially +** bypass the substituted expression with OP_IfNullRow. +** +** Suppose the original expression is an integer constant. Even though the table +** has the nullRow flag set, because the expression is an integer constant, +** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode +** that checks to see if the nullRow flag is set on the table. If the nullRow +** flag is set, then the value in the register is set to NULL and the original +** expression is bypassed. If the nullRow flag is not set, then the original +** expression runs to populate the register. +** +** Example where this is needed: +** +** CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); +** CREATE TABLE t2(x INT UNIQUE); +** +** SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x; +** +** When the subquery on the right side of the LEFT JOIN is flattened, we +** have to add OP_IfNullRow in front of the OP_Integer that implements the +** "m" value of the subquery so that a NULL will be loaded instead of 59 +** when processing a non-matched row of the left. +*/ +typedef struct SubstContext { + Parse *pParse; /* The parsing context */ + int iTable; /* Replace references to this table */ + int iNewTable; /* New table number */ + int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ + ExprList *pEList; /* Replacement expressions */ + ExprList *pCList; /* Collation sequences for replacement expr */ +} SubstContext; + +/* Forward Declarations */ +static void substExprList(SubstContext*, ExprList*); +static void substSelect(SubstContext*, Select*, int); + +/* +** Scan through the expression pExpr. Replace every reference to +** a column in table number iTable with a copy of the iColumn-th +** entry in pEList. (But leave references to the ROWID column +** unchanged.) +** +** This routine is part of the flattening procedure. A subquery +** whose result set is defined by pEList appears as entry in the +** FROM clause of a SELECT such that the VDBE cursor assigned to that +** FORM clause entry is iTable. This routine makes the necessary +** changes to pExpr so that it refers directly to the source table +** of the subquery rather the result set of the subquery. +*/ +static Expr *substExpr( + SubstContext *pSubst, /* Description of the substitution */ + Expr *pExpr /* Expr in which substitution occurs */ +){ + if( pExpr==0 ) return 0; + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) + && pExpr->w.iJoin==pSubst->iTable + ){ + testcase( ExprHasProperty(pExpr, EP_InnerON) ); + pExpr->w.iJoin = pSubst->iNewTable; + } + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pSubst->iTable + && !ExprHasProperty(pExpr, EP_FixedCol) + ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( pExpr->iColumn<0 ){ + pExpr->op = TK_NULL; + }else +#endif + { + Expr *pNew; + int iColumn; + Expr *pCopy; + Expr ifNullRow; + iColumn = pExpr->iColumn; + assert( iColumn>=0 ); + assert( pSubst->pEList!=0 && iColumnpEList->nExpr ); + assert( pExpr->pRight==0 ); + pCopy = pSubst->pEList->a[iColumn].pExpr; + if( sqlite3ExprIsVector(pCopy) ){ + sqlite3VectorErrorMsg(pSubst->pParse, pCopy); + }else{ + sqlite3 *db = pSubst->pParse->db; + if( pSubst->isOuterJoin + && (pCopy->op!=TK_COLUMN || pCopy->iTable!=pSubst->iNewTable) + ){ + memset(&ifNullRow, 0, sizeof(ifNullRow)); + ifNullRow.op = TK_IF_NULL_ROW; + ifNullRow.pLeft = pCopy; + ifNullRow.iTable = pSubst->iNewTable; + ifNullRow.iColumn = -99; + ifNullRow.flags = EP_IfNullRow; + pCopy = &ifNullRow; + } + testcase( ExprHasProperty(pCopy, EP_Subquery) ); + pNew = sqlite3ExprDup(db, pCopy, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pNew); + return pExpr; + } + if( pSubst->isOuterJoin ){ + ExprSetProperty(pNew, EP_CanBeNull); + } + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_OuterON|EP_InnerON)); + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; + if( pExpr->op==TK_TRUEFALSE ){ + pExpr->u.iValue = sqlite3ExprTruthValue(pExpr); + pExpr->op = TK_INTEGER; + ExprSetProperty(pExpr, EP_IntValue); + } + + /* Ensure that the expression now has an implicit collation sequence, + ** just as it did when it was a column of a view or sub-query. */ + { + CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, + pSubst->pCList->a[iColumn].pExpr + ); + if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + (pColl ? pColl->zName : "BINARY") + ); + } + } + ExprClearProperty(pExpr, EP_Collate); + } + } + }else{ + if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ + pExpr->iTable = pSubst->iNewTable; + } + pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); + pExpr->pRight = substExpr(pSubst, pExpr->pRight); + if( ExprUseXSelect(pExpr) ){ + substSelect(pSubst, pExpr->x.pSelect, 1); + }else{ + substExprList(pSubst, pExpr->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + Window *pWin = pExpr->y.pWin; + pWin->pFilter = substExpr(pSubst, pWin->pFilter); + substExprList(pSubst, pWin->pPartition); + substExprList(pSubst, pWin->pOrderBy); + } +#endif + } + return pExpr; +} +static void substExprList( + SubstContext *pSubst, /* Description of the substitution */ + ExprList *pList /* List to scan and in which to make substitutes */ +){ + int i; + if( pList==0 ) return; + for(i=0; inExpr; i++){ + pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr); + } +} +static void substSelect( + SubstContext *pSubst, /* Description of the substitution */ + Select *p, /* SELECT statement in which to make substitutions */ + int doPrior /* Do substitutes on p->pPrior too */ +){ + SrcList *pSrc; + SrcItem *pItem; + int i; + if( !p ) return; + do{ + substExprList(pSubst, p->pEList); + substExprList(pSubst, p->pGroupBy); + substExprList(pSubst, p->pOrderBy); + p->pHaving = substExpr(pSubst, p->pHaving); + p->pWhere = substExpr(pSubst, p->pWhere); + pSrc = p->pSrc; + assert( pSrc!=0 ); + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + substSelect(pSubst, pItem->pSelect, 1); + if( pItem->fg.isTabFunc ){ + substExprList(pSubst, pItem->u1.pFuncArg); + } + } + }while( doPrior && (p = p->pPrior)!=0 ); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** pSelect is a SELECT statement and pSrcItem is one item in the FROM +** clause of that SELECT. +** +** This routine scans the entire SELECT statement and recomputes the +** pSrcItem->colUsed mask. +*/ +static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ + SrcItem *pItem; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + pItem = pWalker->u.pSrcItem; + if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue; + if( pExpr->iColumn<0 ) return WRC_Continue; + pItem->colUsed |= sqlite3ExprColUsed(pExpr); + return WRC_Continue; +} +static void recomputeColumnsUsed( + Select *pSelect, /* The complete SELECT statement */ + SrcItem *pSrcItem /* Which FROM clause item to recompute */ +){ + Walker w; + if( NEVER(pSrcItem->pTab==0) ) return; + memset(&w, 0, sizeof(w)); + w.xExprCallback = recomputeColumnsUsedExpr; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.u.pSrcItem = pSrcItem; + pSrcItem->colUsed = 0; + sqlite3WalkSelect(&w, pSelect); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Assign new cursor numbers to each of the items in pSrc. For each +** new cursor number assigned, set an entry in the aCsrMap[] array +** to map the old cursor number to the new: +** +** aCsrMap[iOld+1] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. aCsrMap[0] is the array size. +** +** If pSrc contains any sub-selects, call this routine recursively +** on the FROM clause of each such sub-select, with iExcept set to -1. +*/ +static void srclistRenumberCursors( + Parse *pParse, /* Parse context */ + int *aCsrMap, /* Array to store cursor mappings in */ + SrcList *pSrc, /* FROM clause to renumber */ + int iExcept /* FROM clause item to skip */ +){ + int i; + SrcItem *pItem; + for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + assert( pItem->iCursor < aCsrMap[0] ); + if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){ + aCsrMap[pItem->iCursor+1] = pParse->nTab++; + } + pItem->iCursor = aCsrMap[pItem->iCursor+1]; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } +} + +/* +** *piCursor is a cursor number. Change it if it needs to be mapped. +*/ +static void renumberCursorDoMapping(Walker *pWalker, int *piCursor){ + int *aCsrMap = pWalker->u.aiCol; + int iCsr = *piCursor; + if( iCsr < aCsrMap[0] && aCsrMap[iCsr+1]>0 ){ + *piCursor = aCsrMap[iCsr+1]; + } +} + +/* +** Expression walker callback used by renumberCursors() to update +** Expr objects to match newly assigned cursor numbers. +*/ +static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ + int op = pExpr->op; + if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ + renumberCursorDoMapping(pWalker, &pExpr->iTable); + } + if( ExprHasProperty(pExpr, EP_OuterON) ){ + renumberCursorDoMapping(pWalker, &pExpr->w.iJoin); + } + return WRC_Continue; +} + +/* +** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc) +** of the SELECT statement passed as the second argument, and to each +** cursor in the FROM clause of any FROM clause sub-selects, recursively. +** Except, do not assign a new cursor number to the iExcept'th element in +** the FROM clause of (*p). Update all expressions and other references +** to refer to the new cursor numbers. +** +** Argument aCsrMap is an array that may be used for temporary working +** space. Two guarantees are made by the caller: +** +** * the array is larger than the largest cursor number used within the +** select statement passed as an argument, and +** +** * the array entries for all cursor numbers that do *not* appear in +** FROM clauses of the select statement as described above are +** initialized to zero. +*/ +static void renumberCursors( + Parse *pParse, /* Parse context */ + Select *p, /* Select to renumber cursors within */ + int iExcept, /* FROM clause item to skip */ + int *aCsrMap /* Working space */ +){ + Walker w; + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, iExcept); + memset(&w, 0, sizeof(w)); + w.u.aiCol = aCsrMap; + w.xExprCallback = renumberCursorsCb; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkSelect(&w, p); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** If pSel is not part of a compound SELECT, return a pointer to its +** expression list. Otherwise, return a pointer to the expression list +** of the leftmost SELECT in the compound. +*/ +static ExprList *findLeftmostExprlist(Select *pSel){ + while( pSel->pPrior ){ + pSel = pSel->pPrior; + } + return pSel->pEList; +} + +/* +** Return true if any of the result-set columns in the compound query +** have incompatible affinities on one or more arms of the compound. +*/ +static int compoundHasDifferentAffinities(Select *p){ + int ii; + ExprList *pList; + assert( p!=0 ); + assert( p->pEList!=0 ); + assert( p->pPrior!=0 ); + pList = p->pEList; + for(ii=0; iinExpr; ii++){ + char aff; + Select *pSub1; + assert( pList->a[ii].pExpr!=0 ); + aff = sqlite3ExprAffinity(pList->a[ii].pExpr); + for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){ + assert( pSub1->pEList!=0 ); + assert( pSub1->pEList->nExpr>ii ); + assert( pSub1->pEList->a[ii].pExpr!=0 ); + if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){ + return 1; + } + } + } + return 0; +} + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** This routine attempts to flatten subqueries as a performance optimization. +** This routine returns 1 if it makes changes and 0 if no flattening occurs. +** +** To understand the concept of flattening, consider the following +** query: +** +** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 +** +** The default way of implementing this query is to execute the +** subquery first and store the results in a temporary table, then +** run the outer query on that temporary table. This requires two +** passes over the data. Furthermore, because the temporary table +** has no indices, the WHERE clause on the outer query cannot be +** optimized. +** +** This routine attempts to rewrite queries such as the above into +** a single flat select, like this: +** +** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 +** +** The code generated for this simplification gives the same result +** but only has to scan the data once. And because indices might +** exist on the table t1, a complete scan of the data might be +** avoided. +** +** Flattening is subject to the following constraints: +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** The subquery and the outer query cannot both be aggregates. +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** (2) If the subquery is an aggregate then +** (2a) the outer query must not be a join and +** (2b) the outer query must not use subqueries +** other than the one FROM-clause subquery that is a candidate +** for flattening. (This is due to ticket [2f7170d73bf9abf80] +** from 2015-02-09.) +** +** (3) If the subquery is the right operand of a LEFT JOIN then +** (3a) the subquery may not be a join and +** (3b) the FROM clause of the subquery may not contain a virtual +** table and +** (**) Was: "The outer query may not have a GROUP BY." This case +** is now managed correctly +** (3d) the outer query may not be DISTINCT. +** See also (26) for restrictions on RIGHT JOIN. +** +** (4) The subquery can not be DISTINCT. +** +** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT +** sub-queries that were excluded from this optimization. Restriction +** (4) has since been expanded to exclude all DISTINCT subqueries. +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** If the subquery is aggregate, the outer query may not be DISTINCT. +** +** (7) The subquery must have a FROM clause. TODO: For subqueries without +** A FROM clause, consider adding a FROM clause with the special +** table sqlite_once that consists of a single row containing a +** single NULL. +** +** (8) If the subquery uses LIMIT then the outer query may not be a join. +** +** (9) If the subquery uses LIMIT then the outer query may not be aggregate. +** +** (**) Restriction (10) was removed from the code on 2005-02-05 but we +** accidentally carried the comment forward until 2014-09-15. Original +** constraint: "If the subquery is aggregate then the outer query +** may not use LIMIT." +** +** (11) The subquery and the outer query may not both have ORDER BY clauses. +** +** (**) Not implemented. Subsumed into restriction (3). Was previously +** a separate restriction deriving from ticket #350. +** +** (13) The subquery and outer query may not both use LIMIT. +** +** (14) The subquery may not use OFFSET. +** +** (15) If the outer query is part of a compound select, then the +** subquery may not use LIMIT. +** (See ticket #2339 and ticket [02a8e81d44]). +** +** (16) If the outer query is aggregate, then the subquery may not +** use ORDER BY. (Ticket #2942) This used to not matter +** until we introduced the group_concat() function. +** +** (17) If the subquery is a compound select, then +** (17a) all compound operators must be a UNION ALL, and +** (17b) no terms within the subquery compound may be aggregate +** or DISTINCT, and +** (17c) every term within the subquery compound must have a FROM clause +** (17d) the outer query may not be +** (17d1) aggregate, or +** (17d2) DISTINCT +** (17e) the subquery may not contain window functions, and +** (17f) the subquery must not be the RHS of a LEFT JOIN. +** (17g) either the subquery is the first element of the outer +** query or there are no RIGHT or FULL JOINs in any arm +** of the subquery. (This is a duplicate of condition (27b).) +** (17h) The corresponding result set expressions in all arms of the +** compound must have the same affinity. +** +** The parent and sub-query may contain WHERE clauses. Subject to +** rules (11), (13) and (14), they may also contain ORDER BY, +** LIMIT and OFFSET clauses. The subquery cannot use any compound +** operator other than UNION ALL because all the other compound +** operators have an implied DISTINCT which is disallowed by +** restriction (4). +** +** Also, each component of the sub-query must return the same number +** of result columns. This is actually a requirement for any compound +** SELECT statement, but all the code here does is make sure that no +** such (illegal) sub-query is flattened. The caller will detect the +** syntax error and return a detailed message. +** +** (18) If the sub-query is a compound select, then all terms of the +** ORDER BY clause of the parent must be copies of a term returned +** by the parent query. +** +** (19) If the subquery uses LIMIT then the outer query may not +** have a WHERE clause. +** +** (20) If the sub-query is a compound select, then it must not use +** an ORDER BY clause. Ticket #3773. We could relax this constraint +** somewhat by saying that the terms of the ORDER BY clause must +** appear as unmodified result columns in the outer query. But we +** have other optimizations in mind to deal with that case. +** +** (21) If the subquery uses LIMIT then the outer query may not be +** DISTINCT. (See ticket [752e1646fc]). +** +** (22) The subquery may not be a recursive CTE. +** +** (23) If the outer query is a recursive CTE, then the sub-query may not be +** a compound query. This restriction is because transforming the +** parent to a compound query confuses the code that handles +** recursive queries in multiSelect(). +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** The subquery may not be an aggregate that uses the built-in min() or +** or max() functions. (Without this restriction, a query like: +** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily +** return the value X for which Y was maximal.) +** +** (25) If either the subquery or the parent query contains a window +** function in the select list or ORDER BY clause, flattening +** is not attempted. +** +** (26) The subquery may not be the right operand of a RIGHT JOIN. +** See also (3) for restrictions on LEFT JOIN. +** +** (27) The subquery may not contain a FULL or RIGHT JOIN unless it +** is the first element of the parent query. Two subcases: +** (27a) the subquery is not a compound query. +** (27b) the subquery is a compound query and the RIGHT JOIN occurs +** in any arm of the compound query. (See also (17g).) +** +** (28) The subquery is not a MATERIALIZED CTE. (This is handled +** in the caller before ever reaching this routine.) +** +** +** In this routine, the "p" parameter is a pointer to the outer query. +** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query +** uses aggregates. +** +** If flattening is not attempted, this routine is a no-op and returns 0. +** If flattening is attempted this routine returns 1. +** +** All of the expression analysis must occur on both the outer query and +** the subquery before this routine runs. +*/ +static int flattenSubquery( + Parse *pParse, /* Parsing context */ + Select *p, /* The parent or outer SELECT statement */ + int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ + int isAgg /* True if outer SELECT uses aggregate functions */ +){ + const char *zSavedAuthContext = pParse->zAuthContext; + Select *pParent; /* Current UNION ALL term of the other query */ + Select *pSub; /* The inner query or "subquery" */ + Select *pSub1; /* Pointer to the rightmost select in sub-query */ + SrcList *pSrc; /* The FROM clause of the outer query */ + SrcList *pSubSrc; /* The FROM clause of the subquery */ + int iParent; /* VDBE cursor number of the pSub result set temp table */ + int iNewParent = -1;/* Replacement table for iParent */ + int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ + int i; /* Loop counter */ + Expr *pWhere; /* The WHERE clause */ + SrcItem *pSubitem; /* The subquery */ + sqlite3 *db = pParse->db; + Walker w; /* Walker to persist agginfo data */ + int *aCsrMap = 0; + + /* Check to see if flattening is permitted. Return 0 if not. + */ + assert( p!=0 ); + assert( p->pPrior==0 ); + if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; + pSrc = p->pSrc; + assert( pSrc && iFrom>=0 && iFromnSrc ); + pSubitem = &pSrc->a[iFrom]; + iParent = pSubitem->iCursor; + pSub = pSubitem->pSelect; + assert( pSub!=0 ); + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */ +#endif + + pSubSrc = pSub->pSrc; + assert( pSubSrc ); + /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, + ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET + ** because they could be computed at compile-time. But when LIMIT and OFFSET + ** became arbitrary expressions, we were forced to add restrictions (13) + ** and (14). */ + if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ + if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */ + if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ + return 0; /* Restriction (15) */ + } + if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ + if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */ + if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ + return 0; /* Restrictions (8)(9) */ + } + if( p->pOrderBy && pSub->pOrderBy ){ + return 0; /* Restriction (11) */ + } + if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ + if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ + if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ + return 0; /* Restriction (21) */ + } + if( pSub->selFlags & (SF_Recursive) ){ + return 0; /* Restrictions (22) */ + } + + /* + ** If the subquery is the right operand of a LEFT JOIN, then the + ** subquery may not be a join itself (3a). Example of why this is not + ** allowed: + ** + ** t1 LEFT OUTER JOIN (t2 JOIN t3) + ** + ** If we flatten the above, we would get + ** + ** (t1 LEFT OUTER JOIN t2) JOIN t3 + ** + ** which is not at all the same thing. + ** + ** See also tickets #306, #350, and #3300. + */ + if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ + if( pSubSrc->nSrc>1 /* (3a) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ + ){ + return 0; + } + isOuterJoin = 1; + } + + assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ + if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + return 0; /* Restriction (27a) */ + } + + /* Condition (28) is blocked by the caller */ + assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes ); + + /* Restriction (17): If the sub-query is a compound SELECT, then it must + ** use only the UNION ALL operator. And none of the simple select queries + ** that make up the compound SELECT are allowed to be aggregate or distinct + ** queries. + */ + if( pSub->pPrior ){ + int ii; + if( pSub->pOrderBy ){ + return 0; /* Restriction (20) */ + } + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){ + return 0; /* (17d1), (17d2), or (17f) */ + } + for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); + assert( (pSub->selFlags & SF_Recursive)==0 ); + assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); + if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ + || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ + || pSub1->pSrc->nSrc<1 /* (17c) */ +#ifndef SQLITE_OMIT_WINDOWFUNC + || pSub1->pWin /* (17e) */ +#endif + ){ + return 0; + } + if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + /* Without this restriction, the JT_LTORJ flag would end up being + ** omitted on left-hand tables of the right join that is being + ** flattened. */ + return 0; /* Restrictions (17g), (27b) */ + } + testcase( pSub1->pSrc->nSrc>1 ); + } + + /* Restriction (18). */ + if( p->pOrderBy ){ + for(ii=0; iipOrderBy->nExpr; ii++){ + if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; + } + } + + /* Restriction (23) */ + if( (p->selFlags & SF_Recursive) ) return 0; + + /* Restriction (17h) */ + if( compoundHasDifferentAffinities(pSub) ) return 0; + + if( pSrc->nSrc>1 ){ + if( pParse->nSelect>500 ) return 0; + if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; + aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); + if( aCsrMap ) aCsrMap[0] = pParse->nTab; + } + } + + /***** If we reach this point, flattening is permitted. *****/ + TREETRACE(0x4,pParse,p,("flatten %u.%p from term %d\n", + pSub->selId, pSub, iFrom)); + + /* Authorize the subquery */ + pParse->zAuthContext = pSubitem->zName; + TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); + testcase( i==SQLITE_DENY ); + pParse->zAuthContext = zSavedAuthContext; + + /* Delete the transient structures associated with the subquery */ + pSub1 = pSubitem->pSelect; + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; + pSubitem->pSelect = 0; + assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); + + /* If the sub-query is a compound SELECT statement, then (by restrictions + ** 17 and 18 above) it must be a UNION ALL and the parent query must + ** be of the form: + ** + ** SELECT FROM () + ** + ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block + ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or + ** OFFSET clauses and joins them to the left-hand-side of the original + ** using UNION ALL operators. In this case N is the number of simple + ** select statements in the compound sub-query. + ** + ** Example: + ** + ** SELECT a+1 FROM ( + ** SELECT x FROM tab + ** UNION ALL + ** SELECT y FROM tab + ** UNION ALL + ** SELECT abs(z*2) FROM tab2 + ** ) WHERE a!=5 ORDER BY 1 + ** + ** Transformed into: + ** + ** SELECT x+1 FROM tab WHERE x+1!=5 + ** UNION ALL + ** SELECT y+1 FROM tab WHERE y+1!=5 + ** UNION ALL + ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5 + ** ORDER BY 1 + ** + ** We call this the "compound-subquery flattening". + */ + for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ + Select *pNew; + ExprList *pOrderBy = p->pOrderBy; + Expr *pLimit = p->pLimit; + Select *pPrior = p->pPrior; + Table *pItemTab = pSubitem->pTab; + pSubitem->pTab = 0; + p->pOrderBy = 0; + p->pPrior = 0; + p->pLimit = 0; + pNew = sqlite3SelectDup(db, p, 0); + p->pLimit = pLimit; + p->pOrderBy = pOrderBy; + p->op = TK_ALL; + pSubitem->pTab = pItemTab; + if( pNew==0 ){ + p->pPrior = pPrior; + }else{ + pNew->selId = ++pParse->nSelect; + if( aCsrMap && ALWAYS(db->mallocFailed==0) ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } + pNew->pPrior = pPrior; + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = p; + p->pPrior = pNew; + TREETRACE(0x4,pParse,p,("compound-subquery flattener" + " creates %u as peer\n",pNew->selId)); + } + assert( pSubitem->pSelect==0 ); + } + sqlite3DbFree(db, aCsrMap); + if( db->mallocFailed ){ + pSubitem->pSelect = pSub1; + return 1; + } + + /* Defer deleting the Table object associated with the + ** subquery until code generation is + ** complete, since there may still exist Expr.pTab entries that + ** refer to the subquery even after flattening. Ticket #3346. + ** + ** pSubitem->pTab is always non-NULL by test restrictions and tests above. + */ + if( ALWAYS(pSubitem->pTab!=0) ){ + Table *pTabToDel = pSubitem->pTab; + if( pTabToDel->nTabRef==1 ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); + testcase( pToplevel->earlyCleanup ); + }else{ + pTabToDel->nTabRef--; + } + pSubitem->pTab = 0; + } + + /* The following loop runs once for each term in a compound-subquery + ** flattening (as described above). If we are doing a different kind + ** of flattening - a flattening other than a compound-subquery flattening - + ** then this loop only runs once. + ** + ** This loop moves all of the FROM elements of the subquery into the + ** the FROM clause of the outer query. Before doing this, remember + ** the cursor number for the original outer query FROM element in + ** iParent. The iParent cursor will never be used. Subsequent code + ** will scan expressions looking for iParent references and replace + ** those references with expressions that resolve to the subquery FROM + ** elements we are now copying in. + */ + pSub = pSub1; + for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ + int nSubSrc; + u8 jointype = 0; + u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ; + assert( pSub!=0 ); + pSubSrc = pSub->pSrc; /* FROM clause of subquery */ + nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ + pSrc = pParent->pSrc; /* FROM clause of the outer query */ + + if( pParent==p ){ + jointype = pSubitem->fg.jointype; /* First time through the loop */ + } + + /* The subquery uses a single slot of the FROM clause of the outer + ** query. If the subquery has more than one element in its FROM clause, + ** then expand the outer query to make space for it to hold all elements + ** of the subquery. + ** + ** Example: + ** + ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB; + ** + ** The outer query has 3 slots in its FROM clause. One slot of the + ** outer query (the middle slot) is used by the subquery. The next + ** block of code will expand the outer query FROM clause to 4 slots. + ** The middle slot is expanded to two slots in order to make space + ** for the two elements in the FROM clause of the subquery. + */ + if( nSubSrc>1 ){ + pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1); + if( pSrc==0 ) break; + pParent->pSrc = pSrc; + } + + /* Transfer the FROM clause terms from the subquery into the + ** outer query. + */ + for(i=0; ia[i+iFrom]; + if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); + assert( pItem->fg.isTabFunc==0 ); + *pItem = pSubSrc->a[i]; + pItem->fg.jointype |= ltorj; + iNewParent = pSubSrc->a[i].iCursor; + memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); + } + pSrc->a[iFrom].fg.jointype &= JT_LTORJ; + pSrc->a[iFrom].fg.jointype |= jointype | ltorj; + + /* Now begin substituting subquery result set expressions for + ** references to the iParent in the outer query. + ** + ** Example: + ** + ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; + ** \ \_____________ subquery __________/ / + ** \_____________________ outer query ______________________________/ + ** + ** We look at every expression in the outer query and every place we see + ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". + */ + if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){ + /* At this point, any non-zero iOrderByCol values indicate that the + ** ORDER BY column expression is identical to the iOrderByCol'th + ** expression returned by SELECT statement pSub. Since these values + ** do not necessarily correspond to columns in SELECT statement pParent, + ** zero them before transferring the ORDER BY clause. + ** + ** Not doing this may cause an error if a subsequent call to this + ** function attempts to flatten a compound sub-query into pParent + ** (the only way this can happen is if the compound sub-query is + ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ + ExprList *pOrderBy = pSub->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + assert( pParent->pOrderBy==0 ); + pParent->pOrderBy = pOrderBy; + pSub->pOrderBy = 0; + } + pWhere = pSub->pWhere; + pSub->pWhere = 0; + if( isOuterJoin>0 ){ + sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); + } + if( pWhere ){ + if( pParent->pWhere ){ + pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere); + }else{ + pParent->pWhere = pWhere; + } + } + if( db->mallocFailed==0 ){ + SubstContext x; + x.pParse = pParse; + x.iTable = iParent; + x.iNewTable = iNewParent; + x.isOuterJoin = isOuterJoin; + x.pEList = pSub->pEList; + x.pCList = findLeftmostExprlist(pSub); + substSelect(&x, pParent, 0); + } + + /* The flattened query is a compound if either the inner or the + ** outer query is a compound. */ + pParent->selFlags |= pSub->selFlags & SF_Compound; + assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */ + + /* + ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; + ** + ** One is tempted to try to add a and b to combine the limits. But this + ** does not work if either limit is negative. + */ + if( pSub->pLimit ){ + pParent->pLimit = pSub->pLimit; + pSub->pLimit = 0; + } + + /* Recompute the SrcItem.colUsed masks for the flattened + ** tables. */ + for(i=0; ia[i+iFrom]); + } + } + + /* Finally, delete what is left of the subquery and return success. + */ + sqlite3AggInfoPersistWalkerInit(&w, pParse); + sqlite3WalkSelect(&w,pSub1); + sqlite3SelectDelete(db, pSub1); + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x4 ){ + TREETRACE(0x4,pParse,p,("After flattening:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + return 1; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** A structure to keep track of all of the column values that are fixed to +** a known value due to WHERE clause constraints of the form COLUMN=VALUE. +*/ +typedef struct WhereConst WhereConst; +struct WhereConst { + Parse *pParse; /* Parsing context */ + u8 *pOomFault; /* Pointer to pParse->db->mallocFailed */ + int nConst; /* Number for COLUMN=CONSTANT terms */ + int nChng; /* Number of times a constant is propagated */ + int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */ + u32 mExcludeOn; /* Which ON expressions to exclude from considertion. + ** Either EP_OuterON or EP_InnerON|EP_OuterON */ + Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ +}; + +/* +** Add a new entry to the pConst object. Except, do not add duplicate +** pColumn entries. Also, do not add if doing so would not be appropriate. +** +** The caller guarantees the pColumn is a column and pValue is a constant. +** This routine has to do some additional checks before completing the +** insert. +*/ +static void constInsert( + WhereConst *pConst, /* The WhereConst into which we are inserting */ + Expr *pColumn, /* The COLUMN part of the constraint */ + Expr *pValue, /* The VALUE part of the constraint */ + Expr *pExpr /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */ +){ + int i; + assert( pColumn->op==TK_COLUMN ); + assert( sqlite3ExprIsConstant(pValue) ); + + if( ExprHasProperty(pColumn, EP_FixedCol) ) return; + if( sqlite3ExprAffinity(pValue)!=0 ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ + return; + } + + /* 2018-10-25 ticket [cf5ed20f] + ** Make sure the same pColumn is not inserted more than once */ + for(i=0; inConst; i++){ + const Expr *pE2 = pConst->apExpr[i*2]; + assert( pE2->op==TK_COLUMN ); + if( pE2->iTable==pColumn->iTable + && pE2->iColumn==pColumn->iColumn + ){ + return; /* Already present. Return without doing anything. */ + } + } + if( sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){ + pConst->bHasAffBlob = 1; + } + + pConst->nConst++; + pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, + pConst->nConst*2*sizeof(Expr*)); + if( pConst->apExpr==0 ){ + pConst->nConst = 0; + }else{ + pConst->apExpr[pConst->nConst*2-2] = pColumn; + pConst->apExpr[pConst->nConst*2-1] = pValue; + } +} + +/* +** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE +** is a constant expression and where the term must be true because it +** is part of the AND-connected terms of the expression. For each term +** found, add it to the pConst structure. +*/ +static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ + Expr *pRight, *pLeft; + if( NEVER(pExpr==0) ) return; + if( ExprHasProperty(pExpr, pConst->mExcludeOn) ){ + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pExpr, EP_InnerON) ); + return; + } + if( pExpr->op==TK_AND ){ + findConstInWhere(pConst, pExpr->pRight); + findConstInWhere(pConst, pExpr->pLeft); + return; + } + if( pExpr->op!=TK_EQ ) return; + pRight = pExpr->pRight; + pLeft = pExpr->pLeft; + assert( pRight!=0 ); + assert( pLeft!=0 ); + if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){ + constInsert(pConst,pRight,pLeft,pExpr); + } + if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){ + constInsert(pConst,pLeft,pRight,pExpr); + } +} + +/* +** This is a helper function for Walker callback propagateConstantExprRewrite(). +** +** Argument pExpr is a candidate expression to be replaced by a value. If +** pExpr is equivalent to one of the columns named in pWalker->u.pConst, +** then overwrite it with the corresponding value. Except, do not do so +** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr +** is SQLITE_AFF_BLOB. +*/ +static int propagateConstantExprRewriteOne( + WhereConst *pConst, + Expr *pExpr, + int bIgnoreAffBlob +){ + int i; + if( pConst->pOomFault[0] ) return WRC_Prune; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol|pConst->mExcludeOn) ){ + testcase( ExprHasProperty(pExpr, EP_FixedCol) ); + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pExpr, EP_InnerON) ); + return WRC_Continue; + } + for(i=0; inConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; + if( pColumn==pExpr ) continue; + if( pColumn->iTable!=pExpr->iTable ) continue; + if( pColumn->iColumn!=pExpr->iColumn ) continue; + if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){ + break; + } + /* A match is found. Add the EP_FixedCol property */ + pConst->nChng++; + ExprClearProperty(pExpr, EP_Leaf); + ExprSetProperty(pExpr, EP_FixedCol); + assert( pExpr->pLeft==0 ); + pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); + if( pConst->pParse->db->mallocFailed ) return WRC_Prune; + break; + } + return WRC_Prune; +} + +/* +** This is a Walker expression callback. pExpr is a node from the WHERE +** clause of a SELECT statement. This function examines pExpr to see if +** any substitutions based on the contents of pWalker->u.pConst should +** be made to pExpr or its immediate children. +** +** A substitution is made if: +** +** + pExpr is a column with an affinity other than BLOB that matches +** one of the columns in pWalker->u.pConst, or +** +** + pExpr is a binary comparison operator (=, <=, >=, <, >) that +** uses an affinity other than TEXT and one of its immediate +** children is a column that matches one of the columns in +** pWalker->u.pConst. +*/ +static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + WhereConst *pConst = pWalker->u.pConst; + assert( TK_GT==TK_EQ+1 ); + assert( TK_LE==TK_EQ+2 ); + assert( TK_LT==TK_EQ+3 ); + assert( TK_GE==TK_EQ+4 ); + if( pConst->bHasAffBlob ){ + if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE) + || pExpr->op==TK_IS + ){ + propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0); + if( pConst->pOomFault[0] ) return WRC_Prune; + if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){ + propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0); + } + } + } + return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob); +} + +/* +** The WHERE-clause constant propagation optimization. +** +** If the WHERE clause contains terms of the form COLUMN=CONSTANT or +** CONSTANT=COLUMN that are top-level AND-connected terms that are not +** part of a ON clause from a LEFT JOIN, then throughout the query +** replace all other occurrences of COLUMN with CONSTANT. +** +** For example, the query: +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b +** +** Is transformed into +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39 +** +** Return true if any transformations where made and false if not. +** +** Implementation note: Constant propagation is tricky due to affinity +** and collating sequence interactions. Consider this example: +** +** CREATE TABLE t1(a INT,b TEXT); +** INSERT INTO t1 VALUES(123,'0123'); +** SELECT * FROM t1 WHERE a=123 AND b=a; +** SELECT * FROM t1 WHERE a=123 AND b=123; +** +** The two SELECT statements above should return different answers. b=a +** is always true because the comparison uses numeric affinity, but b=123 +** is false because it uses text affinity and '0123' is not the same as '123'. +** To work around this, the expression tree is not actually changed from +** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol +** and the "123" value is hung off of the pLeft pointer. Code generator +** routines know to generate the constant "123" instead of looking up the +** column value. Also, to avoid collation problems, this optimization is +** only attempted if the "a=123" term uses the default BINARY collation. +** +** 2021-05-25 forum post 6a06202608: Another troublesome case is... +** +** CREATE TABLE t1(x); +** INSERT INTO t1 VALUES(10.0); +** SELECT 1 FROM t1 WHERE x=10 AND x LIKE 10; +** +** The query should return no rows, because the t1.x value is '10.0' not '10' +** and '10.0' is not LIKE '10'. But if we are not careful, the first WHERE +** term "x=10" will cause the second WHERE term to become "10 LIKE 10", +** resulting in a false positive. To avoid this, constant propagation for +** columns with BLOB affinity is only allowed if the constant is used with +** operators ==, <=, <, >=, >, or IS in a way that will cause the correct +** type conversions to occur. See logic associated with the bHasAffBlob flag +** for details. +*/ +static int propagateConstants( + Parse *pParse, /* The parsing context */ + Select *p /* The query in which to propagate constants */ +){ + WhereConst x; + Walker w; + int nChng = 0; + x.pParse = pParse; + x.pOomFault = &pParse->db->mallocFailed; + do{ + x.nConst = 0; + x.nChng = 0; + x.apExpr = 0; + x.bHasAffBlob = 0; + if( ALWAYS(p->pSrc!=0) + && p->pSrc->nSrc>0 + && (p->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 + ){ + /* Do not propagate constants on any ON clause if there is a + ** RIGHT JOIN anywhere in the query */ + x.mExcludeOn = EP_InnerON | EP_OuterON; + }else{ + /* Do not propagate constants through the ON clause of a LEFT JOIN */ + x.mExcludeOn = EP_OuterON; + } + findConstInWhere(&x, p->pWhere); + if( x.nConst ){ + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = propagateConstantExprRewrite; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = 0; + w.walkerDepth = 0; + w.u.pConst = &x; + sqlite3WalkExpr(&w, p->pWhere); + sqlite3DbFree(x.pParse->db, x.apExpr); + nChng += x.nChng; + } + }while( x.nChng ); + return nChng; +} + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +# if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** This function is called to determine whether or not it is safe to +** push WHERE clause expression pExpr down to FROM clause sub-query +** pSubq, which contains at least one window function. Return 1 +** if it is safe and the expression should be pushed down, or 0 +** otherwise. +** +** It is only safe to push the expression down if it consists only +** of constants and copies of expressions that appear in the PARTITION +** BY clause of all window function used by the sub-query. It is safe +** to filter out entire partitions, but not rows within partitions, as +** this may change the results of the window functions. +** +** At the time this function is called it is guaranteed that +** +** * the sub-query uses only one distinct window frame, and +** * that the window frame has a PARTITION BY clause. +*/ +static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ + assert( pSubq->pWin->pPartition ); + assert( (pSubq->selFlags & SF_MultiPart)==0 ); + assert( pSubq->pPrior==0 ); + return sqlite3ExprIsConstantOrGroupBy(pParse, pExpr, pSubq->pWin->pPartition); +} +# endif /* SQLITE_OMIT_WINDOWFUNC */ +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Make copies of relevant WHERE clause terms of the outer query into +** the WHERE clause of subquery. Example: +** +** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10; +** +** Transformed into: +** +** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10) +** WHERE x=5 AND y=10; +** +** The hope is that the terms added to the inner query will make it more +** efficient. +** +** Do not attempt this optimization if: +** +** (1) (** This restriction was removed on 2017-09-29. We used to +** disallow this optimization for aggregate subqueries, but now +** it is allowed by putting the extra terms on the HAVING clause. +** The added HAVING clause is pointless if the subquery lacks +** a GROUP BY clause. But such a HAVING clause is also harmless +** so there does not appear to be any reason to add extra logic +** to suppress it. **) +** +** (2) The inner query is the recursive part of a common table expression. +** +** (3) The inner query has a LIMIT clause (since the changes to the WHERE +** clause would change the meaning of the LIMIT). +** +** (4) The inner query is the right operand of a LEFT JOIN and the +** expression to be pushed down does not come from the ON clause +** on that LEFT JOIN. +** +** (5) The WHERE clause expression originates in the ON or USING clause +** of a LEFT JOIN where iCursor is not the right-hand table of that +** left join. An example: +** +** SELECT * +** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa +** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2) +** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2); +** +** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9). +** But if the (b2=2) term were to be pushed down into the bb subquery, +** then the (1,1,NULL) row would be suppressed. +** +** (6) Window functions make things tricky as changes to the WHERE clause +** of the inner query could change the window over which window +** functions are calculated. Therefore, do not attempt the optimization +** if: +** +** (6a) The inner query uses multiple incompatible window partitions. +** +** (6b) The inner query is a compound and uses window-functions. +** +** (6c) The WHERE clause does not consist entirely of constants and +** copies of expressions found in the PARTITION BY clause of +** all window-functions used by the sub-query. It is safe to +** filter out entire partitions, as this does not change the +** window over which any window-function is calculated. +** +** (7) The inner query is a Common Table Expression (CTE) that should +** be materialized. (This restriction is implemented in the calling +** routine.) +** +** (8) If the subquery is a compound that uses UNION, INTERSECT, +** or EXCEPT, then all of the result set columns for all arms of +** the compound must use the BINARY collating sequence. +** +** (9) All three of the following are true: +** +** (9a) The WHERE clause expression originates in the ON or USING clause +** of a join (either an INNER or an OUTER join), and +** +** (9b) The subquery is to the right of the ON/USING clause +** +** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING +** clause and the subquery. +** +** Without this restriction, the push-down optimization might move +** the ON/USING filter expression from the left side of a RIGHT JOIN +** over to the right side, which leads to incorrect answers. See +** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). +** +** (10) The inner query is not the right-hand table of a RIGHT JOIN. +** +** (11) The subquery is not a VALUES clause +** +** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This +** case only comes up if SQLite is compiled using +** SQLITE_ALLOW_ROWID_IN_VIEW. +** +** Return 0 if no changes are made and non-zero if one or more WHERE clause +** terms are duplicated into the subquery. +*/ +static int pushDownWhereTerms( + Parse *pParse, /* Parse context (for malloc() and error reporting) */ + Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ + Expr *pWhere, /* The WHERE clause of the outer query */ + SrcList *pSrcList, /* The complete from clause of the outer query */ + int iSrc /* Which FROM clause term to try to push into */ +){ + Expr *pNew; + SrcItem *pSrc; /* The subquery FROM term into which WHERE is pushed */ + int nChng = 0; + pSrc = &pSrcList->a[iSrc]; + if( pWhere==0 ) return 0; + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ){ + return 0; /* restrictions (2) and (11) */ + } + if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ){ + return 0; /* restrictions (10) */ + } + + if( pSubq->pPrior ){ + Select *pSel; + int notUnionAll = 0; + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + u8 op = pSel->op; + assert( op==TK_ALL || op==TK_SELECT + || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT ); + if( op!=TK_ALL && op!=TK_SELECT ){ + notUnionAll = 1; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return 0; /* restriction (6b) */ +#endif + } + if( notUnionAll ){ + /* If any of the compound arms are connected using UNION, INTERSECT, + ** or EXCEPT, then we must ensure that none of the columns use a + ** non-BINARY collating sequence. */ + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + int ii; + const ExprList *pList = pSel->pEList; + assert( pList!=0 ); + for(ii=0; iinExpr; ii++){ + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[ii].pExpr); + if( !sqlite3IsBinary(pColl) ){ + return 0; /* Restriction (8) */ + } + } + } + } + }else{ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; +#endif + } + +#ifdef SQLITE_DEBUG + /* Only the first term of a compound can have a WITH clause. But make + ** sure no other terms are marked SF_Recursive in case something changes + ** in the future. + */ + { + Select *pX; + for(pX=pSubq; pX; pX=pX->pPrior){ + assert( (pX->selFlags & (SF_Recursive))==0 ); + } + } +#endif + + if( pSubq->pLimit!=0 ){ + return 0; /* restriction (3) */ + } + while( pWhere->op==TK_AND ){ + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc); + pWhere = pWhere->pLeft; + } + +#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ + if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */ + && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (9c) */ + ){ + int jj; + for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ + /* If we reach this point, both (9a) and (9b) are satisfied. + ** The following loop checks (9c): + */ + for(jj++; jja[jj].fg.jointype & JT_RIGHT)!=0 ){ + return 0; /* restriction (9) */ + } + } + } + } + } + if( isLeftJoin + && (ExprHasProperty(pWhere,EP_OuterON)==0 + || pWhere->w.iJoin!=iCursor) + ){ + return 0; /* restriction (4) */ + } + if( ExprHasProperty(pWhere,EP_OuterON) + && pWhere->w.iJoin!=iCursor + ){ + return 0; /* restriction (5) */ + } +#endif + +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){ + Expr *pLeft = pWhere->pLeft; + if( ALWAYS(pLeft) + && pLeft->op==TK_COLUMN + && pLeft->iColumn < 0 + ){ + return 0; /* Restriction (12) */ + } + } +#endif + + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ + nChng++; + pSubq->selFlags |= SF_PushDown; + while( pSubq ){ + SubstContext x; + pNew = sqlite3ExprDup(pParse->db, pWhere, 0); + unsetJoinExpr(pNew, -1, 1); + x.pParse = pParse; + x.iTable = pSrc->iCursor; + x.iNewTable = pSrc->iCursor; + x.isOuterJoin = 0; + x.pEList = pSubq->pEList; + x.pCList = findLeftmostExprlist(pSubq); + pNew = substExpr(&x, pNew); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ + /* Restriction 6c has prevented push-down in this case */ + sqlite3ExprDelete(pParse->db, pNew); + nChng--; + break; + } +#endif + if( pSubq->selFlags & SF_Aggregate ){ + pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); + }else{ + pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew); + } + pSubq = pSubq->pPrior; + } + } + return nChng; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** Check to see if a subquery contains result-set columns that are +** never used. If it does, change the value of those result-set columns +** to NULL so that they do not cause unnecessary work to compute. +** +** Return the number of column that were changed to NULL. +*/ +static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ + int nCol; + Select *pSub; /* The subquery to be simplified */ + Select *pX; /* For looping over compound elements of pSub */ + Table *pTab; /* The table that describes the subquery */ + int j; /* Column number */ + int nChng = 0; /* Number of columns converted to NULL */ + Bitmask colUsed; /* Columns that may not be NULLed out */ + + assert( pItem!=0 ); + if( pItem->fg.isCorrelated || pItem->fg.isCte ){ + return 0; + } + assert( pItem->pTab!=0 ); + pTab = pItem->pTab; + assert( pItem->pSelect!=0 ); + pSub = pItem->pSelect; + assert( pSub->pEList->nExpr==pTab->nCol ); + for(pX=pSub; pX; pX=pX->pPrior){ + if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ + testcase( pX->selFlags & SF_Distinct ); + testcase( pX->selFlags & SF_Aggregate ); + return 0; + } + if( pX->pPrior && pX->op!=TK_ALL ){ + /* This optimization does not work for compound subqueries that + ** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */ + return 0; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pX->pWin ){ + /* This optimization does not work for subqueries that use window + ** functions. */ + return 0; + } +#endif + } + colUsed = pItem->colUsed; + if( pSub->pOrderBy ){ + ExprList *pList = pSub->pOrderBy; + for(j=0; jnExpr; j++){ + u16 iCol = pList->a[j].u.x.iOrderByCol; + if( iCol>0 ){ + iCol--; + colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + } + } + nCol = pTab->nCol; + for(j=0; jpPrior) { + Expr *pY = pX->pEList->a[j].pExpr; + if( pY->op==TK_NULL ) continue; + pY->op = TK_NULL; + ExprClearProperty(pY, EP_Skip|EP_Unlikely); + pX->selFlags |= SF_PushDown; + nChng++; + } + } + return nChng; +} + + +/* +** The pFunc is the only aggregate function in the query. Check to see +** if the query is a candidate for the min/max optimization. +** +** If the query is a candidate for the min/max optimization, then set +** *ppMinMax to be an ORDER BY clause to be used for the optimization +** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on +** whether pFunc is a min() or max() function. +** +** If the query is not a candidate for the min/max optimization, return +** WHERE_ORDERBY_NORMAL (which must be zero). +** +** This routine must be called after aggregate functions have been +** located but before their arguments have been subjected to aggregate +** analysis. +*/ +static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ + int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ + ExprList *pEList; /* Arguments to agg function */ + const char *zFunc; /* Name of aggregate function pFunc */ + ExprList *pOrderBy; + u8 sortFlags = 0; + + assert( *ppMinMax==0 ); + assert( pFunc->op==TK_AGG_FUNCTION ); + assert( !IsWindowFunc(pFunc) ); + assert( ExprUseXList(pFunc) ); + pEList = pFunc->x.pList; + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ + return eRet; + } + assert( !ExprHasProperty(pFunc, EP_IntValue) ); + zFunc = pFunc->u.zToken; + if( sqlite3StrICmp(zFunc, "min")==0 ){ + eRet = WHERE_ORDERBY_MIN; + if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){ + sortFlags = KEYINFO_ORDER_BIGNULL; + } + }else if( sqlite3StrICmp(zFunc, "max")==0 ){ + eRet = WHERE_ORDERBY_MAX; + sortFlags = KEYINFO_ORDER_DESC; + }else{ + return eRet; + } + *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); + assert( pOrderBy!=0 || db->mallocFailed ); + if( pOrderBy ) pOrderBy->a[0].fg.sortFlags = sortFlags; + return eRet; +} + +/* +** The select statement passed as the first argument is an aggregate query. +** The second argument is the associated aggregate-info object. This +** function tests if the SELECT is of the form: +** +** SELECT count(*) FROM +** +** where table is a database table, not a sub-select or view. If the query +** does match this pattern, then a pointer to the Table object representing +** is returned. Otherwise, NULL is returned. +** +** This routine checks to see if it is safe to use the count optimization. +** A correct answer is still obtained (though perhaps more slowly) if +** this routine returns NULL when it could have returned a table pointer. +** But returning the pointer when NULL should have been returned can +** result in incorrect answers and/or crashes. So, when in doubt, return NULL. +*/ +static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ + Table *pTab; + Expr *pExpr; + + assert( !p->pGroupBy ); + + if( p->pWhere + || p->pEList->nExpr!=1 + || p->pSrc->nSrc!=1 + || p->pSrc->a[0].pSelect + || pAggInfo->nFunc!=1 + || p->pHaving + ){ + return 0; + } + pTab = p->pSrc->a[0].pTab; + assert( pTab!=0 ); + assert( !IsView(pTab) ); + if( !IsOrdinaryTable(pTab) ) return 0; + pExpr = p->pEList->a[0].pExpr; + assert( pExpr!=0 ); + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; + if( pExpr->pAggInfo!=pAggInfo ) return 0; + if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; + assert( pAggInfo->aFunc[0].pFExpr==pExpr ); + testcase( ExprHasProperty(pExpr, EP_Distinct) ); + testcase( ExprHasProperty(pExpr, EP_WinFunc) ); + if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0; + + return pTab; +} + +/* +** If the source-list item passed as an argument was augmented with an +** INDEXED BY clause, then try to locate the specified index. If there +** was such a clause and the named index cannot be found, return +** SQLITE_ERROR and leave an error in pParse. Otherwise, populate +** pFrom->pIndex and return SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ + Table *pTab = pFrom->pTab; + char *zIndexedBy = pFrom->u1.zIndexedBy; + Index *pIdx; + assert( pTab!=0 ); + assert( pFrom->fg.isIndexedBy!=0 ); + + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; + } + assert( pFrom->fg.isCte==0 ); + pFrom->u2.pIBIndex = pIdx; + return SQLITE_OK; +} + +/* +** Detect compound SELECT statements that use an ORDER BY clause with +** an alternative collating sequence. +** +** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ... +** +** These are rewritten as a subquery: +** +** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) +** ORDER BY ... COLLATE ... +** +** This transformation is necessary because the multiSelectOrderBy() routine +** above that generates the code for a compound SELECT with an ORDER BY clause +** uses a merge algorithm that requires the same collating sequence on the +** result columns as on the ORDER BY clause. See ticket +** http://www.sqlite.org/src/info/6709574d2a +** +** This transformation is only needed for EXCEPT, INTERSECT, and UNION. +** The UNION ALL operator works fine with multiSelectOrderBy() even when +** there are COLLATE terms in the ORDER BY. +*/ +static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ + int i; + Select *pNew; + Select *pX; + sqlite3 *db; + struct ExprList_item *a; + SrcList *pNewSrc; + Parse *pParse; + Token dummy; + + if( p->pPrior==0 ) return WRC_Continue; + if( p->pOrderBy==0 ) return WRC_Continue; + for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){} + if( pX==0 ) return WRC_Continue; + a = p->pOrderBy->a; +#ifndef SQLITE_OMIT_WINDOWFUNC + /* If iOrderByCol is already non-zero, then it has already been matched + ** to a result column of the SELECT statement. This occurs when the + ** SELECT is rewritten for window-functions processing and then passed + ** to sqlite3SelectPrep() and similar a second time. The rewriting done + ** by this function is not required in this case. */ + if( a[0].u.x.iOrderByCol ) return WRC_Continue; +#endif + for(i=p->pOrderBy->nExpr-1; i>=0; i--){ + if( a[i].pExpr->flags & EP_Collate ) break; + } + if( i<0 ) return WRC_Continue; + + /* If we reach this point, that means the transformation is required. */ + + pParse = pWalker->pParse; + db = pParse->db; + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); + if( pNew==0 ) return WRC_Abort; + memset(&dummy, 0, sizeof(dummy)); + pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); + if( pNewSrc==0 ) return WRC_Abort; + *pNew = *p; + p->pSrc = pNewSrc; + p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); + p->op = TK_SELECT; + p->pWhere = 0; + pNew->pGroupBy = 0; + pNew->pHaving = 0; + pNew->pOrderBy = 0; + p->pPrior = 0; + p->pNext = 0; + p->pWith = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + p->pWinDefn = 0; +#endif + p->selFlags &= ~SF_Compound; + assert( (p->selFlags & SF_Converted)==0 ); + p->selFlags |= SF_Converted; + assert( pNew->pPrior!=0 ); + pNew->pPrior->pNext = pNew; + pNew->pLimit = 0; + return WRC_Continue; +} + +/* +** Check to see if the FROM clause term pFrom has table-valued function +** arguments. If it does, leave an error message in pParse and return +** non-zero, since pFrom is not allowed to be a table-valued function. +*/ +static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){ + if( pFrom->fg.isTabFunc ){ + sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); + return 1; + } + return 0; +} + +#ifndef SQLITE_OMIT_CTE +/* +** Argument pWith (which may be NULL) points to a linked list of nested +** WITH contexts, from inner to outermost. If the table identified by +** FROM clause element pItem is really a common-table-expression (CTE) +** then return a pointer to the CTE definition for that table. Otherwise +** return NULL. +** +** If a non-NULL value is returned, set *ppContext to point to the With +** object that the returned CTE belongs to. +*/ +static struct Cte *searchWith( + With *pWith, /* Current innermost WITH clause */ + SrcItem *pItem, /* FROM clause element to resolve */ + With **ppContext /* OUT: WITH clause return value belongs to */ +){ + const char *zName = pItem->zName; + With *p; + assert( pItem->zDatabase==0 ); + assert( zName!=0 ); + for(p=pWith; p; p=p->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; + } + } + if( p->bView ) break; + } + return 0; +} + +/* The code generator maintains a stack of active WITH clauses +** with the inner-most WITH clause being at the top of the stack. +** +** This routine pushes the WITH clause passed as the second argument +** onto the top of the stack. If argument bFree is true, then this +** WITH clause will never be popped from the stack but should instead +** be freed along with the Parse object. In other cases, when +** bFree==0, the With object will be freed along with the SELECT +** statement with which it is associated. +** +** This routine returns a copy of pWith. Or, if bFree is true and +** the pWith object is destroyed immediately due to an OOM condition, +** then this routine return NULL. +** +** If bFree is true, do not continue to use the pWith pointer after +** calling this routine, Instead, use only the return value. +*/ +SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ + if( pWith ){ + if( bFree ){ + pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric, + pWith); + if( pWith==0 ) return 0; + } + if( pParse->nErr==0 ){ + assert( pParse->pWith!=pWith ); + pWith->pOuter = pParse->pWith; + pParse->pWith = pWith; + } + } + return pWith; +} + +/* +** This function checks if argument pFrom refers to a CTE declared by +** a WITH clause on the stack currently maintained by the parser (on the +** pParse->pWith linked list). And if currently processing a CTE +** CTE expression, through routine checks to see if the reference is +** a recursive reference to the CTE. +** +** If pFrom matches a CTE according to either of these two above, pFrom->pTab +** and other fields are populated accordingly. +** +** Return 0 if no match is found. +** Return 1 if a match is found. +** Return 2 if an error condition is detected. +*/ +static int resolveFromTermToCte( + Parse *pParse, /* The parsing context */ + Walker *pWalker, /* Current tree walker */ + SrcItem *pFrom /* The FROM clause term to check */ +){ + Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* The matching WITH */ + + assert( pFrom->pTab==0 ); + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + return 0; + } + if( pParse->nErr ){ + /* Prior errors might have left pParse->pWith in a goofy state, so + ** go no further. */ + return 0; + } + if( pFrom->zDatabase!=0 ){ + /* The FROM term contains a schema qualifier (ex: main.t1) and so + ** it cannot possibly be a CTE reference. */ + return 0; + } + if( pFrom->fg.notCte ){ + /* The FROM term is specifically excluded from matching a CTE. + ** (1) It is part of a trigger that used to have zDatabase but had + ** zDatabase removed by sqlite3FixTriggerStep(). + ** (2) This is the first term in the FROM clause of an UPDATE. + */ + return 0; + } + pCte = searchWith(pParse->pWith, pFrom, &pWith); + if( pCte ){ + sqlite3 *db = pParse->db; + Table *pTab; + ExprList *pEList; + Select *pSel; + Select *pLeft; /* Left-most SELECT statement */ + Select *pRecTerm; /* Left-most recursive term */ + int bMayRecursive; /* True if compound joined by UNION [ALL] */ + With *pSavedWith; /* Initial value of pParse->pWith */ + int iRecTab = -1; /* Cursor for recursive table */ + CteUse *pCteUse; + + /* If pCte->zCteErr is non-NULL at this point, then this is an illegal + ** recursive reference to CTE pCte. Leave an error in pParse and return + ** early. If pCte->zCteErr is NULL, then this is not a recursive reference. + ** In this case, proceed. */ + if( pCte->zCteErr ){ + sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); + return 2; + } + if( cannotBeFunction(pParse, pFrom) ) return 2; + + assert( pFrom->pTab==0 ); + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return 2; + pCteUse = pCte->pUse; + if( pCteUse==0 ){ + pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0])); + if( pCteUse==0 + || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0 + ){ + sqlite3DbFree(db, pTab); + return 2; + } + pCteUse->eM10d = pCte->eM10d; + } + pFrom->pTab = pTab; + pTab->nTabRef = 1; + pTab->zName = sqlite3DbStrDup(db, pCte->zName); + pTab->iPKey = -1; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; + pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + if( db->mallocFailed ) return 2; + pFrom->pSelect->selFlags |= SF_CopyCte; + assert( pFrom->pSelect ); + if( pFrom->fg.isIndexedBy ){ + sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); + return 2; + } + pFrom->fg.isCte = 1; + pFrom->u2.pCteUse = pCteUse; + pCteUse->nUse++; + + /* Check if this is a recursive CTE. */ + pRecTerm = pSel = pFrom->pSelect; + bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); + while( bMayRecursive && pRecTerm->op==pSel->op ){ + int i; + SrcList *pSrc = pRecTerm->pSrc; + assert( pRecTerm->pPrior!=0 ); + for(i=0; inSrc; i++){ + SrcItem *pItem = &pSrc->a[i]; + if( pItem->zDatabase==0 + && pItem->zName!=0 + && 0==sqlite3StrICmp(pItem->zName, pCte->zName) + ){ + pItem->pTab = pTab; + pTab->nTabRef++; + pItem->fg.isRecursive = 1; + if( pRecTerm->selFlags & SF_Recursive ){ + sqlite3ErrorMsg(pParse, + "multiple references to recursive table: %s", pCte->zName + ); + return 2; + } + pRecTerm->selFlags |= SF_Recursive; + if( iRecTab<0 ) iRecTab = pParse->nTab++; + pItem->iCursor = iRecTab; + } + } + if( (pRecTerm->selFlags & SF_Recursive)==0 ) break; + pRecTerm = pRecTerm->pPrior; + } + + pCte->zCteErr = "circular reference: %s"; + pSavedWith = pParse->pWith; + pParse->pWith = pWith; + if( pSel->selFlags & SF_Recursive ){ + int rc; + assert( pRecTerm!=0 ); + assert( (pRecTerm->selFlags & SF_Recursive)==0 ); + assert( pRecTerm->pNext!=0 ); + assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 ); + assert( pRecTerm->pWith==0 ); + pRecTerm->pWith = pSel->pWith; + rc = sqlite3WalkSelect(pWalker, pRecTerm); + pRecTerm->pWith = 0; + if( rc ){ + pParse->pWith = pSavedWith; + return 2; + } + }else{ + if( sqlite3WalkSelect(pWalker, pSel) ){ + pParse->pWith = pSavedWith; + return 2; + } + } + pParse->pWith = pWith; + + for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); + pEList = pLeft->pEList; + if( pCte->pCols ){ + if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){ + sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", + pCte->zName, pEList->nExpr, pCte->pCols->nExpr + ); + pParse->pWith = pSavedWith; + return 2; + } + pEList = pCte->pCols; + } + + sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + if( bMayRecursive ){ + if( pSel->selFlags & SF_Recursive ){ + pCte->zCteErr = "multiple recursive references: %s"; + }else{ + pCte->zCteErr = "recursive reference in a subquery: %s"; + } + sqlite3WalkSelect(pWalker, pSel); + } + pCte->zCteErr = 0; + pParse->pWith = pSavedWith; + return 1; /* Success */ + } + return 0; /* No match */ +} +#endif + +#ifndef SQLITE_OMIT_CTE +/* +** If the SELECT passed as the second argument has an associated WITH +** clause, pop it from the stack stored as part of the Parse object. +** +** This function is used as the xSelectCallback2() callback by +** sqlite3SelectExpand() when walking a SELECT tree to resolve table +** names and other FROM clause elements. +*/ +SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ + With *pWith = findRightmost(p)->pWith; + if( pWith!=0 ){ + assert( pParse->pWith==pWith || pParse->nErr ); + pParse->pWith = pWith->pOuter; + } + } +} +#endif + +/* +** The SrcItem structure passed as the second argument represents a +** sub-query in the FROM clause of a SELECT statement. This function +** allocates and populates the SrcItem.pTab object. If successful, +** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, +** SQLITE_NOMEM. +*/ +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ + Select *pSel = pFrom->pSelect; + Table *pTab; + + assert( pSel ); + pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + if( pTab==0 ) return SQLITE_NOMEM; + pTab->nTabRef = 1; + if( pFrom->zAlias ){ + pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); + }else{ + pTab->zName = sqlite3MPrintf(pParse->db, "%!S", pFrom); + } + while( pSel->pPrior ){ pSel = pSel->pPrior; } + sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); + pTab->iPKey = -1; + pTab->eTabType = TABTYP_VIEW; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW + /* The usual case - do not allow ROWID on a subquery */ + pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; +#else + /* Legacy compatibility mode */ + pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid; +#endif + return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; +} + + +/* +** Check the N SrcItem objects to the right of pBase. (N might be zero!) +** If any of those SrcItem objects have a USING clause containing zName +** then return true. +** +** If N is zero, or none of the N SrcItem objects to the right of pBase +** contains a USING clause, or if none of the USING clauses contain zName, +** then return false. +*/ +static int inAnyUsingClause( + const char *zName, /* Name we are looking for */ + SrcItem *pBase, /* The base SrcItem. Looking at pBase[1] and following */ + int N /* How many SrcItems to check */ +){ + while( N>0 ){ + N--; + pBase++; + if( pBase->fg.isUsing==0 ) continue; + if( NEVER(pBase->u3.pUsing==0) ) continue; + if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1; + } + return 0; +} + + +/* +** This routine is a Walker callback for "expanding" a SELECT statement. +** "Expanding" means to do the following: +** +** (1) Make sure VDBE cursor numbers have been assigned to every +** element of the FROM clause. +** +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** defines FROM clause. When views appear in the FROM clause, +** fill pTabList->a[].pSelect with a copy of the SELECT statement +** that implements the view. A copy is made of the view's SELECT +** statement so that we can freely modify or delete that statement +** without worrying about messing up the persistent representation +** of the view. +** +** (3) Add terms to the WHERE clause to accommodate the NATURAL keyword +** on joins and the ON and USING clause of joins. +** +** (4) Scan the list of columns in the result set (pEList) looking +** for instances of the "*" operator or the TABLE.* operator. +** If found, expand each "*" to be every column in every table +** and TABLE.* to be every column in TABLE. +** +*/ +static int selectExpander(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i, j, k, rc; + SrcList *pTabList; + ExprList *pEList; + SrcItem *pFrom; + sqlite3 *db = pParse->db; + Expr *pE, *pRight, *pExpr; + u16 selFlags = p->selFlags; + u32 elistFlags = 0; + + p->selFlags |= SF_Expanded; + if( db->mallocFailed ){ + return WRC_Abort; + } + assert( p->pSrc!=0 ); + if( (selFlags & SF_Expanded)!=0 ){ + return WRC_Prune; + } + if( pWalker->eCode ){ + /* Renumber selId because it has been copied from a view */ + p->selId = ++pParse->nSelect; + } + pTabList = p->pSrc; + pEList = p->pEList; + if( pParse->pWith && (p->selFlags & SF_View) ){ + if( p->pWith==0 ){ + p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With)); + if( p->pWith==0 ){ + return WRC_Abort; + } + } + p->pWith->bView = 1; + } + sqlite3WithPush(pParse, p->pWith, 0); + + /* Make sure cursor numbers have been assigned to all entries in + ** the FROM clause of the SELECT statement. + */ + sqlite3SrcListAssignCursors(pParse, pTabList); + + /* Look up every table named in the FROM clause of the select. If + ** an entry of the FROM clause is a subquery instead of a table or view, + ** then create a transient table structure to describe the subquery. + */ + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab; + assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); + if( pFrom->pTab ) continue; + assert( pFrom->fg.isRecursive==0 ); + if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY + Select *pSel = pFrom->pSelect; + /* A sub-query in the FROM clause of a SELECT */ + assert( pSel!=0 ); + assert( pFrom->pTab==0 ); + if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; + if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; +#endif +#ifndef SQLITE_OMIT_CTE + }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ + if( rc>1 ) return WRC_Abort; + pTab = pFrom->pTab; + assert( pTab!=0 ); +#endif + }else{ + /* An ordinary table or view name in the FROM clause */ + assert( pFrom->pTab==0 ); + pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); + if( pTab==0 ) return WRC_Abort; + if( pTab->nTabRef>=0xffff ){ + sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", + pTab->zName); + pFrom->pTab = 0; + return WRC_Abort; + } + pTab->nTabRef++; + if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ + return WRC_Abort; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( !IsOrdinaryTable(pTab) ){ + i16 nCol; + u8 eCodeOrig = pWalker->eCode; + if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; + assert( pFrom->pSelect==0 ); + if( IsView(pTab) ){ + if( (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + pTab->zName); + } + pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( ALWAYS(IsVirtual(pTab)) + && pFrom->fg.fromDDL + && ALWAYS(pTab->u.vtab.p!=0) + && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); + } + assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); +#endif + nCol = pTab->nCol; + pTab->nCol = -1; + pWalker->eCode = 1; /* Turn on Select.selId renumbering */ + sqlite3WalkSelect(pWalker, pFrom->pSelect); + pWalker->eCode = eCodeOrig; + pTab->nCol = nCol; + } +#endif + } + + /* Locate the index named by the INDEXED BY clause, if any. */ + if( pFrom->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pFrom) ){ + return WRC_Abort; + } + } + + /* Process NATURAL keywords, and ON and USING clauses of joins. + */ + assert( db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){ + return WRC_Abort; + } + + /* For every "*" that occurs in the column list, insert the names of + ** all columns in all tables. And for every TABLE.* insert the names + ** of all columns in TABLE. The parser inserted a special expression + ** with the TK_ASTERISK operator for each "*" that it found in the column + ** list. The following code just has to locate the TK_ASTERISK + ** expressions and expand each one to the list of all columns in + ** all tables. + ** + ** The first loop just checks to see if there are any "*" operators + ** that need expanding. + */ + for(k=0; knExpr; k++){ + pE = pEList->a[k].pExpr; + if( pE->op==TK_ASTERISK ) break; + assert( pE->op!=TK_DOT || pE->pRight!=0 ); + assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); + if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; + elistFlags |= pE->flags; + } + if( knExpr ){ + /* + ** If we get here it means the result set contains one or more "*" + ** operators that need to be expanded. Loop through each expression + ** in the result set and expand them one by one. + */ + struct ExprList_item *a = pEList->a; + ExprList *pNew = 0; + int flags = pParse->db->flags; + int longNames = (flags & SQLITE_FullColNames)!=0 + && (flags & SQLITE_ShortColNames)==0; + + for(k=0; knExpr; k++){ + pE = a[k].pExpr; + elistFlags |= pE->flags; + pRight = pE->pRight; + assert( pE->op!=TK_DOT || pRight!=0 ); + if( pE->op!=TK_ASTERISK + && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK) + ){ + /* This particular expression does not need to be expanded. + */ + pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); + if( pNew ){ + pNew->a[pNew->nExpr-1].zEName = a[k].zEName; + pNew->a[pNew->nExpr-1].fg.eEName = a[k].fg.eEName; + a[k].zEName = 0; + } + a[k].pExpr = 0; + }else{ + /* This expression is a "*" or a "TABLE.*" and needs to be + ** expanded. */ + int tableSeen = 0; /* Set to 1 when TABLE matches */ + char *zTName = 0; /* text of name of TABLE */ + int iErrOfst; + if( pE->op==TK_DOT ){ + assert( (selFlags & SF_NestedFrom)==0 ); + assert( pE->pLeft!=0 ); + assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); + zTName = pE->pLeft->u.zToken; + assert( ExprUseWOfst(pE->pLeft) ); + iErrOfst = pE->pRight->w.iOfst; + }else{ + assert( ExprUseWOfst(pE) ); + iErrOfst = pE->w.iOfst; + } + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + int nAdd; /* Number of cols including rowid */ + Table *pTab = pFrom->pTab; /* Table for this data source */ + ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ + char *zTabName; /* AS name for this data source */ + const char *zSchemaName = 0; /* Schema name for this data source */ + int iDb; /* Schema index for this data src */ + IdList *pUsing; /* USING clause for pFrom[1] */ + + if( (zTabName = pFrom->zAlias)==0 ){ + zTabName = pTab->zName; + } + if( db->mallocFailed ) break; + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + if( pFrom->fg.isNestedFrom ){ + assert( pFrom->pSelect!=0 ); + pNestedFrom = pFrom->pSelect->pEList; + assert( pNestedFrom!=0 ); + assert( pNestedFrom->nExpr==pTab->nCol ); + assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); + }else{ + if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ + continue; + } + pNestedFrom = 0; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; + } + if( i+1nSrc + && pFrom[1].fg.isUsing + && (selFlags & SF_NestedFrom)!=0 + ){ + int ii; + pUsing = pFrom[1].u3.pUsing; + for(ii=0; iinId; ii++){ + const char *zUName = pUsing->a[ii].zName; + pRight = sqlite3Expr(db, TK_ID, zUName); + sqlite3ExprSetErrorOffset(pRight, iErrOfst); + pNew = sqlite3ExprListAppend(pParse, pNew, pRight); + if( pNew ){ + struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; + assert( pX->zEName==0 ); + pX->zEName = sqlite3MPrintf(db,"..%s", zUName); + pX->fg.eEName = ENAME_TAB; + pX->fg.bUsingTerm = 1; + } + } + }else{ + pUsing = 0; + } + + nAdd = pTab->nCol; + if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++; + for(j=0; jnCol ){ + zName = sqlite3RowidAlias(pTab); + if( zName==0 ) continue; + }else{ + zName = pTab->aCol[j].zCnName; + + /* If pTab is actually an SF_NestedFrom sub-select, do not + ** expand any ENAME_ROWID columns. */ + if( pNestedFrom && pNestedFrom->a[j].fg.eEName==ENAME_ROWID ){ + continue; + } + + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 + ){ + continue; + } + + /* If a column is marked as 'hidden', omit it from the expanded + ** result-set list unless the SELECT has the SF_IncludeHidden + ** bit set. + */ + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; + } + } + assert( zName ); + tableSeen = 1; + + if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ + if( pFrom->fg.isUsing + && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0 + ){ + /* In a join with a USING clause, omit columns in the + ** using clause from the table on the right. */ + continue; + } + } + pRight = sqlite3Expr(db, TK_ID, zName); + if( (pTabList->nSrc>1 + && ( (pFrom->fg.jointype & JT_LTORJ)==0 + || (selFlags & SF_NestedFrom)!=0 + || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) + ) + ) + || IN_RENAME_OBJECT + ){ + Expr *pLeft; + pLeft = sqlite3Expr(db, TK_ID, zTabName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + if( IN_RENAME_OBJECT && pE->pLeft ){ + sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft); + } + if( zSchemaName ){ + pLeft = sqlite3Expr(db, TK_ID, zSchemaName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); + } + }else{ + pExpr = pRight; + } + sqlite3ExprSetErrorOffset(pExpr, iErrOfst); + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); + if( pNew==0 ){ + break; /* OOM */ + } + pX = &pNew->a[pNew->nExpr-1]; + assert( pX->zEName==0 ); + if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ + if( pNestedFrom && (!ViewCanHaveRowid || jnExpr) ){ + assert( jnExpr ); + pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); + testcase( pX->zEName==0 ); + }else{ + pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", + zSchemaName, zTabName, zName); + testcase( pX->zEName==0 ); + } + pX->fg.eEName = (j==pTab->nCol ? ENAME_ROWID : ENAME_TAB); + if( (pFrom->fg.isUsing + && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) + || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) + || (jnCol && (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)) + ){ + pX->fg.bNoExpand = 1; + } + }else if( longNames ){ + pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + pX->fg.eEName = ENAME_NAME; + }else{ + pX->zEName = sqlite3DbStrDup(db, zName); + pX->fg.eEName = ENAME_NAME; + } + } + } + if( !tableSeen ){ + if( zTName ){ + sqlite3ErrorMsg(pParse, "no such table: %s", zTName); + }else{ + sqlite3ErrorMsg(pParse, "no tables specified"); + } + } + } + } + sqlite3ExprListDelete(db, pEList); + p->pEList = pNew; + } + if( p->pEList ){ + if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns in result set"); + return WRC_Abort; + } + if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ + p->selFlags |= SF_ComplexResult; + } + } +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x8 ){ + TREETRACE(0x8,pParse,p,("After result-set wildcard expansion:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + return WRC_Continue; +} + +#if SQLITE_DEBUG +/* +** Always assert. This xSelectCallback2 implementation proves that the +** xSelectCallback2 is never invoked. +*/ +SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + assert( 0 ); +} +#endif +/* +** This routine "expands" a SELECT statement and all of its subqueries. +** For additional information on what it means to "expand" a SELECT +** statement, see the comment on the selectExpand worker callback above. +** +** Expanding a SELECT statement is the first step in processing a +** SELECT statement. The SELECT statement must be expanded before +** name resolution is performed. +** +** If anything goes wrong, an error message is written into pParse. +** The calling function can detect the problem by looking at pParse->nErr +** and/or pParse->db->mallocFailed. +*/ +static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ + Walker w; + w.xExprCallback = sqlite3ExprWalkNoop; + w.pParse = pParse; + if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){ + w.xSelectCallback = convertCompoundSelectToSubquery; + w.xSelectCallback2 = 0; + sqlite3WalkSelect(&w, pSelect); + } + w.xSelectCallback = selectExpander; + w.xSelectCallback2 = sqlite3SelectPopWith; + w.eCode = 0; + sqlite3WalkSelect(&w, pSelect); +} + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() +** interface. +** +** For each FROM-clause subquery, add Column.zType, Column.zColl, and +** Column.affinity information to the Table structure that represents +** the result set of that subquery. +** +** The Table structure that represents the result set was constructed +** by selectExpander() but the type and collation and affinity information +** was omitted at that point because identifiers had not yet been resolved. +** This routine is called after identifier resolution. +*/ +static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ + Parse *pParse; + int i; + SrcList *pTabList; + SrcItem *pFrom; + + if( p->selFlags & SF_HasTypeInfo ) return; + p->selFlags |= SF_HasTypeInfo; + pParse = pWalker->pParse; + testcase( (p->selFlags & SF_Resolved)==0 ); + assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT ); + pTabList = p->pSrc; + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab = pFrom->pTab; + assert( pTab!=0 ); + if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ + /* A sub-query in the FROM clause of a SELECT */ + Select *pSel = pFrom->pSelect; + if( pSel ){ + sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); + } + } + } +} +#endif + + +/* +** This routine adds datatype and collating sequence information to +** the Table structures of all FROM-clause subqueries in a +** SELECT statement. +** +** Use this routine after name resolution. +*/ +static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ +#ifndef SQLITE_OMIT_SUBQUERY + Walker w; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = selectAddSubqueryTypeInfo; + w.xExprCallback = sqlite3ExprWalkNoop; + w.pParse = pParse; + sqlite3WalkSelect(&w, pSelect); +#endif +} + + +/* +** This routine sets up a SELECT statement for processing. The +** following is accomplished: +** +** * VDBE Cursor numbers are assigned to all FROM-clause terms. +** * Ephemeral Table objects are created for all FROM-clause subqueries. +** * ON and USING clauses are shifted into WHERE statements +** * Wildcards "*" and "TABLE.*" in result sets are expanded. +** * Identifiers in expression are matched to tables. +** +** This routine acts recursively on all subqueries within the SELECT. +*/ +SQLITE_PRIVATE void sqlite3SelectPrep( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for container */ +){ + assert( p!=0 || pParse->db->mallocFailed ); + assert( pParse->db->pParse==pParse ); + if( pParse->db->mallocFailed ) return; + if( p->selFlags & SF_HasTypeInfo ) return; + sqlite3SelectExpand(pParse, p); + if( pParse->nErr ) return; + sqlite3ResolveSelectNames(pParse, p, pOuterNC); + if( pParse->nErr ) return; + sqlite3SelectAddTypeInfo(pParse, p); +} + +#if TREETRACE_ENABLED +/* +** Display all information about an AggInfo object +*/ +static void printAggInfo(AggInfo *pAggInfo){ + int ii; + for(ii=0; iinColumn; ii++){ + struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; + sqlite3DebugPrintf( + "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d" + " iSorterColumn=%d %s\n", + ii, pCol->pTab ? pCol->pTab->zName : "NULL", + pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii, + pCol->iSorterColumn, + ii>=pAggInfo->nAccumulator ? "" : " Accumulator"); + sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); + } + for(ii=0; iinFunc; ii++){ + sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", + ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii); + sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); + } +} +#endif /* TREETRACE_ENABLED */ + +/* +** Analyze the arguments to aggregate functions. Create new pAggInfo->aCol[] +** entries for columns that are arguments to aggregate functions but which +** are not otherwise used. +** +** The aCol[] entries in AggInfo prior to nAccumulator are columns that +** are referenced outside of aggregate functions. These might be columns +** that are part of the GROUP by clause, for example. Other database engines +** would throw an error if there is a column reference that is not in the +** GROUP BY clause and that is not part of an aggregate function argument. +** But SQLite allows this. +** +** The aCol[] entries beginning with the aCol[nAccumulator] and following +** are column references that are used exclusively as arguments to +** aggregate functions. This routine is responsible for computing +** (or recomputing) those aCol[] entries. +*/ +static void analyzeAggFuncArgs( + AggInfo *pAggInfo, + NameContext *pNC +){ + int i; + assert( pAggInfo!=0 ); + assert( pAggInfo->iFirstReg==0 ); + pNC->ncFlags |= NC_InAggFunc; + for(i=0; inFunc; i++){ + Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); + assert( ExprUseXList(pExpr) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( !IsWindowFunc(pExpr) ); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ExprAnalyzeAggregates(pNC, pExpr->y.pWin->pFilter); + } +#endif + } + pNC->ncFlags &= ~NC_InAggFunc; +} + +/* +** An index on expressions is being used in the inner loop of an +** aggregate query with a GROUP BY clause. This routine attempts +** to adjust the AggInfo object to take advantage of index and to +** perhaps use the index as a covering index. +** +*/ +static void optimizeAggregateUseOfIndexedExpr( + Parse *pParse, /* Parsing context */ + Select *pSelect, /* The SELECT statement being processed */ + AggInfo *pAggInfo, /* The aggregate info */ + NameContext *pNC /* Name context used to resolve agg-func args */ +){ + assert( pAggInfo->iFirstReg==0 ); + assert( pSelect!=0 ); + assert( pSelect->pGroupBy!=0 ); + pAggInfo->nColumn = pAggInfo->nAccumulator; + if( ALWAYS(pAggInfo->nSortingColumn>0) ){ + int mx = pSelect->pGroupBy->nExpr - 1; + int j, k; + for(j=0; jnColumn; j++){ + k = pAggInfo->aCol[j].iSorterColumn; + if( k>mx ) mx = k; + } + pAggInfo->nSortingColumn = mx+1; + } + analyzeAggFuncArgs(pAggInfo, pNC); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + IndexedExpr *pIEpr; + TREETRACE(0x20, pParse, pSelect, + ("AggInfo (possibly) adjusted for Indexed Exprs\n")); + sqlite3TreeViewSelect(0, pSelect, 0); + for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ + printf("data-cursor=%d index={%d,%d}\n", + pIEpr->iDataCur, pIEpr->iIdxCur, pIEpr->iIdxCol); + sqlite3TreeViewExpr(0, pIEpr->pExpr, 0); + } + printAggInfo(pAggInfo); + } +#else + UNUSED_PARAMETER(pSelect); + UNUSED_PARAMETER(pParse); +#endif +} + +/* +** Walker callback for aggregateConvertIndexedExprRefToColumn(). +*/ +static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ + AggInfo *pAggInfo; + struct AggInfo_col *pCol; + UNUSED_PARAMETER(pWalker); + if( pExpr->pAggInfo==0 ) return WRC_Continue; + if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; + if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; + if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; + pAggInfo = pExpr->pAggInfo; + if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue; + assert( pExpr->iAgg>=0 ); + pCol = &pAggInfo->aCol[pExpr->iAgg]; + pExpr->op = TK_AGG_COLUMN; + pExpr->iTable = pCol->iTable; + pExpr->iColumn = pCol->iColumn; + ExprClearProperty(pExpr, EP_Skip|EP_Collate|EP_Unlikely); + return WRC_Prune; +} + +/* +** Convert every pAggInfo->aFunc[].pExpr such that any node within +** those expressions that has pAppInfo set is changed into a TK_AGG_COLUMN +** opcode. +*/ +static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){ + int i; + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = aggregateIdxEprRefToColCallback; + for(i=0; inFunc; i++){ + sqlite3WalkExpr(&w, pAggInfo->aFunc[i].pFExpr); + } +} + + +/* +** Allocate a block of registers so that there is one register for each +** pAggInfo->aCol[] and pAggInfo->aFunc[] entry in pAggInfo. The first +** register in this block is stored in pAggInfo->iFirstReg. +** +** This routine may only be called once for each AggInfo object. Prior +** to calling this routine: +** +** * The aCol[] and aFunc[] arrays may be modified +** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used +** +** After calling this routine: +** +** * The aCol[] and aFunc[] arrays are fixed +** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used +** +*/ +static void assignAggregateRegisters(Parse *pParse, AggInfo *pAggInfo){ + assert( pAggInfo!=0 ); + assert( pAggInfo->iFirstReg==0 ); + pAggInfo->iFirstReg = pParse->nMem + 1; + pParse->nMem += pAggInfo->nColumn + pAggInfo->nFunc; +} + +/* +** Reset the aggregate accumulator. +** +** The aggregate accumulator is a set of memory cells that hold +** intermediate results while calculating an aggregate. This +** routine generates code that stores NULLs in all of those memory +** cells. +*/ +static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pFunc; + int nReg = pAggInfo->nFunc + pAggInfo->nColumn; + assert( pAggInfo->iFirstReg>0 ); + assert( pParse->db->pParse==pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + if( nReg==0 ) return; + if( pParse->nErr ) return; + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->iFirstReg, + pAggInfo->iFirstReg+nReg-1); + for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ + if( pFunc->iDistinct>=0 ){ + Expr *pE = pFunc->pFExpr; + assert( ExprUseXList(pE) ); + if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " + "argument"); + pFunc->iDistinct = -1; + }else{ + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); + pFunc->iDistAddr = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(DISTINCT)", + pFunc->pFunc->zName)); + } + } + if( pFunc->iOBTab>=0 ){ + ExprList *pOBList; + KeyInfo *pKeyInfo; + int nExtra = 0; + assert( pFunc->pFExpr->pLeft!=0 ); + assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + assert( pFunc->pFunc!=0 ); + pOBList = pFunc->pFExpr->pLeft->x.pList; + if( !pFunc->bOBUnique ){ + nExtra++; /* One extra column for the OP_Sequence */ + } + if( pFunc->bOBPayload ){ + /* extra columns for the function arguments */ + assert( ExprUseXList(pFunc->pFExpr) ); + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + if( pFunc->bUseSubtype ){ + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); + if( !pFunc->bOBUnique && pParse->nErr==0 ){ + pKeyInfo->nKeyField++; + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iOBTab, pOBList->nExpr+nExtra, 0, + (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(ORDER BY)", + pFunc->pFunc->zName)); + } + } +} + +/* +** Invoke the OP_AggFinalize opcode for every aggregate function +** in the AggInfo structure. +*/ +static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pF; + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + ExprList *pList; + assert( ExprUseXList(pF->pFExpr) ); + pList = pF->pFExpr->x.pList; + if( pF->iOBTab>=0 ){ + /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs + ** were stored in emphermal table pF->iOBTab. Here, we extract those + ** inputs (in ORDER BY order) and make all calls to OP_AggStep + ** before doing the OP_AggFinal call. */ + int iTop; /* Start of loop for extracting columns */ + int nArg; /* Number of columns to extract */ + int nKey; /* Key columns to be skipped */ + int regAgg; /* Extract into this array */ + int j; /* Loop counter */ + + assert( pF->pFunc!=0 ); + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + + if( pF->bOBPayload==0 ){ + nKey = 0; + }else{ + assert( pF->pFExpr->pLeft!=0 ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + assert( pF->pFExpr->pLeft->x.pList!=0 ); + nKey = pF->pFExpr->pLeft->x.pList->nExpr; + if( ALWAYS(!pF->bOBUnique) ) nKey++; + } + iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); + } + if( pF->bUseSubtype ){ + int regSubtype = sqlite3GetTempReg(pParse); + int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); + sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); + } + sqlite3ReleaseTempReg(pParse, regSubtype); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, iTop); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } + sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), + pList ? pList->nExpr : 0); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + } +} + +/* +** Generate code that will update the accumulator memory cells for an +** aggregate based on the current cursor position. +** +** If regAcc is non-zero and there are no min() or max() aggregates +** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator +** registers if register regAcc contains 0. The caller will take care +** of setting and clearing regAcc. +** +** For an ORDER BY aggregate, the actual accumulator memory cell update +** is deferred until after all input rows have been received, so that they +** can be run in the requested order. In that case, instead of invoking +** OP_AggStep to update the accumulator, just add the arguments that would +** have been passed into OP_AggStep into the sorting ephemeral table +** (along with the appropriate sort key). +*/ +static void updateAccumulator( + Parse *pParse, + int regAcc, + AggInfo *pAggInfo, + int eDistinctType +){ + Vdbe *v = pParse->pVdbe; + int i; + int regHit = 0; + int addrHitTest = 0; + struct AggInfo_func *pF; + struct AggInfo_col *pC; + + assert( pAggInfo->iFirstReg>0 ); + if( pParse->nErr ) return; + pAggInfo->directMode = 1; + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + int nArg; + int addrNext = 0; + int regAgg; + int regAggSz = 0; + int regDistinct = 0; + ExprList *pList; + assert( ExprUseXList(pF->pFExpr) ); + assert( !IsWindowFunc(pF->pFExpr) ); + assert( pF->pFunc!=0 ); + pList = pF->pFExpr->x.pList; + if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ + Expr *pFilter = pF->pFExpr->y.pWin->pFilter; + if( pAggInfo->nAccumulator + && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + && regAcc + ){ + /* If regAcc==0, there there exists some min() or max() function + ** without a FILTER clause that will ensure the magnet registers + ** are populated. */ + if( regHit==0 ) regHit = ++pParse->nMem; + /* If this is the first row of the group (regAcc contains 0), clear the + ** "magnet" register regHit so that the accumulator registers + ** are populated if the FILTER clause jumps over the the + ** invocation of min() or max() altogether. Or, if this is not + ** the first row (regAcc contains 1), set the magnet register so that + ** the accumulators are not populated unless the min()/max() is invoked + ** and indicates that they should be. */ + sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit); + } + addrNext = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); + } + if( pF->iOBTab>=0 ){ + /* Instead of invoking AggStep, we must push the arguments that would + ** have been passed to AggStep onto the sorting table. */ + int jj; /* Registered used so far in building the record */ + ExprList *pOBList; /* The ORDER BY clause */ + assert( pList!=0 ); + nArg = pList->nExpr; + assert( nArg>0 ); + assert( pF->pFExpr->pLeft!=0 ); + assert( pF->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + pOBList = pF->pFExpr->pLeft->x.pList; + assert( pOBList!=0 ); + assert( pOBList->nExpr>0 ); + regAggSz = pOBList->nExpr; + if( !pF->bOBUnique ){ + regAggSz++; /* One register for OP_Sequence */ + } + if( pF->bOBPayload ){ + regAggSz += nArg; + } + if( pF->bUseSubtype ){ + regAggSz += nArg; + } + regAggSz++; /* One extra register to hold result of MakeRecord */ + regAgg = sqlite3GetTempRange(pParse, regAggSz); + regDistinct = regAgg; + sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP); + jj = pOBList->nExpr; + if( !pF->bOBUnique ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pF->iOBTab, regAgg+jj); + jj++; + } + if( pF->bOBPayload ){ + regDistinct = regAgg+jj; + sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + jj += nArg; + } + if( pF->bUseSubtype ){ + int kk; + int regBase = pF->bOBPayload ? regDistinct : regAgg; + for(kk=0; kknExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + regDistinct = regAgg; + sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); + }else{ + nArg = 0; + regAgg = 0; + } + if( pF->iDistinct>=0 && pList ){ + if( addrNext==0 ){ + addrNext = sqlite3VdbeMakeLabel(pParse); + } + pF->iDistinct = codeDistinct(pParse, eDistinctType, + pF->iDistinct, addrNext, pList, regDistinct); + } + if( pF->iOBTab>=0 ){ + /* Insert a new record into the ORDER BY table */ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regAgg, regAggSz-1, + regAgg+regAggSz-1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pF->iOBTab, regAgg+regAggSz-1, + regAgg, regAggSz-1); + sqlite3ReleaseTempRange(pParse, regAgg, regAggSz); + }else{ + /* Invoke the AggStep function */ + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, + (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } + if( addrNext ){ + sqlite3VdbeResolveLabel(v, addrNext); + } + } + if( regHit==0 && pAggInfo->nAccumulator ){ + regHit = regAcc; + } + if( regHit ){ + addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); + } + for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ + sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + } + + pAggInfo->directMode = 0; + if( addrHitTest ){ + sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); + } +} + +/* +** Add a single OP_Explain instruction to the VDBE to explain a simple +** count(*) query ("SELECT count(*) FROM pTab"). +*/ +#ifndef SQLITE_OMIT_EXPLAIN +static void explainSimpleCount( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being queried */ + Index *pIdx /* Index used to optimize scan, or NULL */ +){ + if( pParse->explain==2 ){ + int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); + sqlite3VdbeExplain(pParse, 0, "SCAN %s%s%s", + pTab->zName, + bCover ? " USING COVERING INDEX " : "", + bCover ? pIdx->zName : "" + ); + } +} +#else +# define explainSimpleCount(a,b,c) +#endif + +/* +** sqlite3WalkExpr() callback used by havingToWhere(). +** +** If the node passed to the callback is a TK_AND node, return +** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes. +** +** Otherwise, return WRC_Prune. In this case, also check if the +** sub-expression matches the criteria for being moved to the WHERE +** clause. If so, add it to the WHERE clause and replace the sub-expression +** within the HAVING expression with a constant "1". +*/ +static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op!=TK_AND ){ + Select *pS = pWalker->u.pSelect; + /* This routine is called before the HAVING clause of the current + ** SELECT is analyzed for aggregates. So if pExpr->pAggInfo is set + ** here, it indicates that the expression is a correlated reference to a + ** column from an outer aggregate query, or an aggregate function that + ** belongs to an outer query. Do not move the expression to the WHERE + ** clause in this obscure case, as doing so may corrupt the outer Select + ** statements AggInfo structure. */ + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) + && ExprAlwaysFalse(pExpr)==0 + && pExpr->pAggInfo==0 + ){ + sqlite3 *db = pWalker->pParse->db; + Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); + if( pNew ){ + Expr *pWhere = pS->pWhere; + SWAP(Expr, *pNew, *pExpr); + pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew); + pS->pWhere = pNew; + pWalker->eCode = 1; + } + } + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Transfer eligible terms from the HAVING clause of a query, which is +** processed after grouping, to the WHERE clause, which is processed before +** grouping. For example, the query: +** +** SELECT * FROM WHERE a=? GROUP BY b HAVING b=? AND c=? +** +** can be rewritten as: +** +** SELECT * FROM WHERE a=? AND b=? GROUP BY b HAVING c=? +** +** A term of the HAVING expression is eligible for transfer if it consists +** entirely of constants and expressions that are also GROUP BY terms that +** use the "BINARY" collation sequence. +*/ +static void havingToWhere(Parse *pParse, Select *p){ + Walker sWalker; + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = havingToWhereExprCb; + sWalker.u.pSelect = p; + sqlite3WalkExpr(&sWalker, p->pHaving); +#if TREETRACE_ENABLED + if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ + TREETRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif +} + +/* +** Check to see if the pThis entry of pTabList is a self-join of another view. +** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst +** but stopping before iEnd. +** +** If pThis is a self-join, then return the SrcItem for the first other +** instance of that view found. If pThis is not a self-join then return 0. +*/ +static SrcItem *isSelfJoinView( + SrcList *pTabList, /* Search for self-joins in this FROM clause */ + SrcItem *pThis, /* Search for prior reference to this subquery */ + int iFirst, int iEnd /* Range of FROM-clause entries to search. */ +){ + SrcItem *pItem; + assert( pThis->pSelect!=0 ); + if( pThis->pSelect->selFlags & SF_PushDown ) return 0; + while( iFirsta[iFirst++]; + if( pItem->pSelect==0 ) continue; + if( pItem->fg.viaCoroutine ) continue; + if( pItem->zName==0 ) continue; + assert( pItem->pTab!=0 ); + assert( pThis->pTab!=0 ); + if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue; + if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; + pS1 = pItem->pSelect; + if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){ + /* The query flattener left two different CTE tables with identical + ** names in the same FROM clause. */ + continue; + } + if( pItem->pSelect->selFlags & SF_PushDown ){ + /* The view was modified by some other optimization such as + ** pushDownWhereTerms() */ + continue; + } + return pItem; + } + return 0; +} + +/* +** Deallocate a single AggInfo object +*/ +static void agginfoFree(sqlite3 *db, void *pArg){ + AggInfo *p = (AggInfo*)pArg; + sqlite3DbFree(db, p->aCol); + sqlite3DbFree(db, p->aFunc); + sqlite3DbFreeNN(db, p); +} + +/* +** Attempt to transform a query of the form +** +** SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2) +** +** Into this: +** +** SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2) +** +** The transformation only works if all of the following are true: +** +** * The subquery is a UNION ALL of two or more terms +** * The subquery does not have a LIMIT clause +** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries +** * The outer query is a simple count(*) with no WHERE clause or other +** extraneous syntax. +** +** Return TRUE if the optimization is undertaken. +*/ +static int countOfViewOptimization(Parse *pParse, Select *p){ + Select *pSub, *pPrior; + Expr *pExpr; + Expr *pCount; + sqlite3 *db; + if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ + if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ + if( p->pWhere ) return 0; + if( p->pHaving ) return 0; + if( p->pGroupBy ) return 0; + if( p->pOrderBy ) return 0; + pExpr = p->pEList->a[0].pExpr; + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ + assert( ExprUseUToken(pExpr) ); + if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ + if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ + if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ + pSub = p->pSrc->a[0].pSelect; + if( pSub==0 ) return 0; /* The FROM is a subquery */ + if( pSub->pPrior==0 ) return 0; /* Must be a compound */ + if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ + do{ + if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ + if( pSub->pWhere ) return 0; /* No WHERE clause */ + if( pSub->pLimit ) return 0; /* No LIMIT clause */ + if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ + assert( pSub->pHaving==0 ); /* Due to the previous */ + pSub = pSub->pPrior; /* Repeat over compound */ + }while( pSub ); + + /* If we reach this point then it is OK to perform the transformation */ + + db = pParse->db; + pCount = pExpr; + pExpr = 0; + pSub = p->pSrc->a[0].pSelect; + p->pSrc->a[0].pSelect = 0; + sqlite3SrcListDelete(db, p->pSrc); + p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); + while( pSub ){ + Expr *pTerm; + pPrior = pSub->pPrior; + pSub->pPrior = 0; + pSub->pNext = 0; + pSub->selFlags |= SF_Aggregate; + pSub->selFlags &= ~SF_Compound; + pSub->nSelectRow = 0; + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); + pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; + pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); + pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, pTerm, pSub); + if( pExpr==0 ){ + pExpr = pTerm; + }else{ + pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr); + } + pSub = pPrior; + } + p->pEList->a[0].pExpr = pExpr; + p->selFlags &= ~SF_Aggregate; + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x200 ){ + TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + return 1; +} + +/* +** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same +** as pSrcItem but has the same alias as p0, then return true. +** Otherwise return false. +*/ +static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ + int i; + for(i=0; inSrc; i++){ + SrcItem *p1 = &pSrc->a[i]; + if( p1==p0 ) continue; + if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ + return 1; + } + if( p1->pSelect + && (p1->pSelect->selFlags & SF_NestedFrom)!=0 + && sameSrcAlias(p0, p1->pSelect->pSrc) + ){ + return 1; + } + } + return 0; +} + +/* +** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can +** be implemented as a co-routine. The i-th entry is guaranteed to be +** a subquery. +** +** The subquery is implemented as a co-routine if all of the following are +** true: +** +** (1) The subquery will likely be implemented in the outer loop of +** the query. This will be the case if any one of the following +** conditions hold: +** (a) The subquery is the only term in the FROM clause +** (b) The subquery is the left-most term and a CROSS JOIN or similar +** requires it to be the outer loop +** (c) All of the following are true: +** (i) The subquery is the left-most subquery in the FROM clause +** (ii) There is nothing that would prevent the subquery from +** being used as the outer loop if the sqlite3WhereBegin() +** routine nominates it to that position. +** (iii) The query is not a UPDATE ... FROM +** (2) The subquery is not a CTE that should be materialized because +** (a) the AS MATERIALIZED keyword is used, or +** (b) the CTE is used multiple times and does not have the +** NOT MATERIALIZED keyword +** (3) The subquery is not part of a left operand for a RIGHT JOIN +** (4) The SQLITE_Coroutine optimization disable flag is not set +** (5) The subquery is not self-joined +*/ +static int fromClauseTermCanBeCoroutine( + Parse *pParse, /* Parsing context */ + SrcList *pTabList, /* FROM clause */ + int i, /* Which term of the FROM clause holds the subquery */ + int selFlags /* Flags on the SELECT statement */ +){ + SrcItem *pItem = &pTabList->a[i]; + if( pItem->fg.isCte ){ + const CteUse *pCteUse = pItem->u2.pCteUse; + if( pCteUse->eM10d==M10d_Yes ) return 0; /* (2a) */ + if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0; /* (2b) */ + } + if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ + if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ + if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){ + return 0; /* (5) */ + } + if( i==0 ){ + if( pTabList->nSrc==1 ) return 1; /* (1a) */ + if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1; /* (1b) */ + if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ + return 1; + } + if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ + while( 1 /*exit-by-break*/ ){ + if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ + if( i==0 ) break; + i--; + pItem--; + if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ + } + return 1; +} + +/* +** Generate code for the SELECT statement given in the p argument. +** +** The results are returned according to the SelectDest structure. +** See comments in sqliteInt.h for further information. +** +** This routine returns the number of errors. If any errors are +** encountered, then an appropriate error message is left in +** pParse->zErrMsg. +** +** This routine does NOT free the Select structure passed in. The +** calling function needs to do that. +*/ +SQLITE_PRIVATE int sqlite3Select( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + SelectDest *pDest /* What to do with the query results */ +){ + int i, j; /* Loop counters */ + WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ + Vdbe *v; /* The virtual machine under construction */ + int isAgg; /* True for select lists like "count(*)" */ + ExprList *pEList = 0; /* List of columns to extract. */ + SrcList *pTabList; /* List of tables to select from */ + Expr *pWhere; /* The WHERE clause. May be NULL */ + ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ + Expr *pHaving; /* The HAVING clause. May be NULL */ + AggInfo *pAggInfo = 0; /* Aggregate information */ + int rc = 1; /* Value to return from this function */ + DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ + SortCtx sSort; /* Info on how to code the ORDER BY clause */ + int iEnd; /* Address of the end of the query */ + sqlite3 *db; /* The database connection */ + ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ + u8 minMaxFlag; /* Flag for min/max queries */ + + db = pParse->db; + assert( pParse==db->pParse ); + v = sqlite3GetVdbe(pParse); + if( p==0 || pParse->nErr ){ + return 1; + } + assert( db->mallocFailed==0 ); + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; +#if TREETRACE_ENABLED + TREETRACE(0x1,pParse,p, ("begin processing:\n", pParse->addrExplain)); + if( sqlite3TreeTrace & 0x10000 ){ + if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", + __FILE__, __LINE__); + } + sqlite3ShowSelect(p); + } +#endif + + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); + if( IgnorableDistinct(pDest) ){ + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || + pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); + /* All of these destinations are also able to ignore the ORDER BY clause */ + if( p->pOrderBy ){ +#if TREETRACE_ENABLED + TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3TreeTrace & 0x800 ){ + sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); + } +#endif + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + p->pOrderBy); + testcase( pParse->earlyCleanup ); + p->pOrderBy = 0; + } + p->selFlags &= ~SF_Distinct; + p->selFlags |= SF_NoopOrderBy; + } + sqlite3SelectPrep(pParse, p, 0); + if( pParse->nErr ){ + goto select_end; + } + assert( db->mallocFailed==0 ); + assert( p->pEList!=0 ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10 ){ + TREETRACE(0x10,pParse,p, ("after name resolution:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + /* If the SF_UFSrcCheck flag is set, then this function is being called + ** as part of populating the temp table for an UPDATE...FROM statement. + ** In this case, it is an error if the target object (pSrc->a[0]) name + ** or alias is duplicated within FROM clause (pSrc->a[1..n]). + ** + ** Postgres disallows this case too. The reason is that some other + ** systems handle this case differently, and not all the same way, + ** which is just confusing. To avoid this, we follow PG's lead and + ** disallow it altogether. */ + if( p->selFlags & SF_UFSrcCheck ){ + SrcItem *p0 = &p->pSrc->a[0]; + if( sameSrcAlias(p0, p->pSrc) ){ + sqlite3ErrorMsg(pParse, + "target object/alias may not appear in FROM clause: %s", + p0->zAlias ? p0->zAlias : p0->pTab->zName + ); + goto select_end; + } + + /* Clear the SF_UFSrcCheck flag. The check has already been performed, + ** and leaving this flag set can cause errors if a compound sub-query + ** in p->pSrc is flattened into this query and this function called + ** again as part of compound SELECT processing. */ + p->selFlags &= ~SF_UFSrcCheck; + } + + if( pDest->eDest==SRT_Output ){ + sqlite3GenerateColumnNames(pParse, p); + } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( sqlite3WindowRewrite(pParse, p) ){ + assert( pParse->nErr ); + goto select_end; + } +#if TREETRACE_ENABLED + if( p->pWin && (sqlite3TreeTrace & 0x40)!=0 ){ + TREETRACE(0x40,pParse,p, ("after window rewrite:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif +#endif /* SQLITE_OMIT_WINDOWFUNC */ + pTabList = p->pSrc; + isAgg = (p->selFlags & SF_Aggregate)!=0; + memset(&sSort, 0, sizeof(sSort)); + sSort.pOrderBy = p->pOrderBy; + + /* Try to do various optimizations (flattening subqueries, and strength + ** reduction of join operators) in the FROM clause up into the main query + */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + for(i=0; !p->pPrior && inSrc; i++){ + SrcItem *pItem = &pTabList->a[i]; + Select *pSub = pItem->pSelect; + Table *pTab = pItem->pTab; + + /* The expander should have already created transient Table objects + ** even for FROM clause elements such as subqueries that do not correspond + ** to a real table */ + assert( pTab!=0 ); + + /* Try to simplify joins: + ** + ** LEFT JOIN -> JOIN + ** RIGHT JOIN -> JOIN + ** FULL JOIN -> RIGHT JOIN + ** + ** If terms of the i-th table are used in the WHERE clause in such a + ** way that the i-th table cannot be the NULL row of a join, then + ** perform the appropriate simplification. This is called + ** "OUTER JOIN strength reduction" in the SQLite documentation. + */ + if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, + pItem->fg.jointype & JT_LTORJ) + && OptimizationEnabled(db, SQLITE_SimplifyJoin) + ){ + if( pItem->fg.jointype & JT_LEFT ){ + if( pItem->fg.jointype & JT_RIGHT ){ + TREETRACE(0x1000,pParse,p, + ("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i)); + pItem->fg.jointype &= ~JT_LEFT; + }else{ + TREETRACE(0x1000,pParse,p, + ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); + pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + unsetJoinExpr(p->pWhere, pItem->iCursor, 0); + } + } + if( pItem->fg.jointype & JT_LTORJ ){ + for(j=i+1; jnSrc; j++){ + SrcItem *pI2 = &pTabList->a[j]; + if( pI2->fg.jointype & JT_RIGHT ){ + if( pI2->fg.jointype & JT_LEFT ){ + TREETRACE(0x1000,pParse,p, + ("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j)); + pI2->fg.jointype &= ~JT_RIGHT; + }else{ + TREETRACE(0x1000,pParse,p, + ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); + pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); + unsetJoinExpr(p->pWhere, pI2->iCursor, 1); + } + } + } + for(j=pTabList->nSrc-1; j>=0; j--){ + pTabList->a[j].fg.jointype &= ~JT_LTORJ; + if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; + } + } + } + + /* No further action if this term of the FROM clause is not a subquery */ + if( pSub==0 ) continue; + + /* Catch mismatch in the declared columns of a view and the number of + ** columns in the SELECT on the RHS */ + if( pTab->nCol!=pSub->pEList->nExpr ){ + sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", + pTab->nCol, pTab->zName, pSub->pEList->nExpr); + goto select_end; + } + + /* Do not attempt the usual optimizations (flattening and ORDER BY + ** elimination) on a MATERIALIZED common table expression because + ** a MATERIALIZED common table expression is an optimization fence. + */ + if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){ + continue; + } + + /* Do not try to flatten an aggregate subquery. + ** + ** Flattening an aggregate subquery is only possible if the outer query + ** is not a join. But if the outer query is not a join, then the subquery + ** will be implemented as a co-routine and there is no advantage to + ** flattening in that case. + */ + if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; + assert( pSub->pGroupBy==0 ); + + /* If a FROM-clause subquery has an ORDER BY clause that is not + ** really doing anything, then delete it now so that it does not + ** interfere with query flattening. See the discussion at + ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a + ** + ** Beware of these cases where the ORDER BY clause may not be safely + ** omitted: + ** + ** (1) There is also a LIMIT clause + ** (2) The subquery was added to help with window-function + ** processing + ** (3) The subquery is in the FROM clause of an UPDATE + ** (4) The outer query uses an aggregate function other than + ** the built-in count(), min(), or max(). + ** (5) The ORDER BY isn't going to accomplish anything because + ** one of: + ** (a) The outer query has a different ORDER BY clause + ** (b) The subquery is part of a join + ** See forum post 062d576715d277c8 + ** + ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. + */ + if( pSub->pOrderBy!=0 + && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ + && pSub->pLimit==0 /* Condition (1) */ + && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ + && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ + && OptimizationEnabled(db, SQLITE_OmitOrderBy) + ){ + TREETRACE(0x800,pParse,p, + ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + pSub->pOrderBy); + pSub->pOrderBy = 0; + } + + /* If the outer query contains a "complex" result set (that is, + ** if the result set of the outer query uses functions or subqueries) + ** and if the subquery contains an ORDER BY clause and if + ** it will be implemented as a co-routine, then do not flatten. This + ** restriction allows SQL constructs like this: + ** + ** SELECT expensive_function(x) + ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10); + ** + ** The expensive_function() is only computed on the 10 rows that + ** are output, rather than every row of the table. + ** + ** The requirement that the outer query have a complex result set + ** means that flattening does occur on simpler SQL constraints without + ** the expensive_function() like: + ** + ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10); + */ + if( pSub->pOrderBy!=0 + && i==0 + && (p->selFlags & SF_ComplexResult)!=0 + && (pTabList->nSrc==1 + || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) + ){ + continue; + } + + if( flattenSubquery(pParse, p, i, isAgg) ){ + if( pParse->nErr ) goto select_end; + /* This subquery can be absorbed into its parent. */ + i = -1; + } + pTabList = p->pSrc; + if( db->mallocFailed ) goto select_end; + if( !IgnorableOrderby(pDest) ){ + sSort.pOrderBy = p->pOrderBy; + } + } +#endif + +#ifndef SQLITE_OMIT_COMPOUND_SELECT + /* Handle compound SELECT statements using the separate multiSelect() + ** procedure. + */ + if( p->pPrior ){ + rc = multiSelect(pParse, p, pDest); +#if TREETRACE_ENABLED + TREETRACE(0x400,pParse,p,("end compound-select processing\n")); + if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); + } +#endif + if( p->pNext==0 ) ExplainQueryPlanPop(pParse); + return rc; + } +#endif + + /* Do the WHERE-clause constant propagation optimization if this is + ** a join. No need to speed time on this operation for non-join queries + ** as the equivalent optimization will be handled by query planner in + ** sqlite3WhereBegin(). + */ + if( p->pWhere!=0 + && p->pWhere->op==TK_AND + && OptimizationEnabled(db, SQLITE_PropagateConst) + && propagateConstants(pParse, p) + ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x2000 ){ + TREETRACE(0x2000,pParse,p,("After constant propagation:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + }else{ + TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); + } + + if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) + && countOfViewOptimization(pParse, p) + ){ + if( db->mallocFailed ) goto select_end; + pTabList = p->pSrc; + } + + /* For each term in the FROM clause, do two things: + ** (1) Authorized unreferenced tables + ** (2) Generate code for all sub-queries + */ + for(i=0; inSrc; i++){ + SrcItem *pItem = &pTabList->a[i]; + SrcItem *pPrior; + SelectDest dest; + Select *pSub; +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + const char *zSavedAuthContext; +#endif + + /* Issue SQLITE_READ authorizations with a fake column name for any + ** tables that are referenced but from which no values are extracted. + ** Examples of where these kinds of null SQLITE_READ authorizations + ** would occur: + ** + ** SELECT count(*) FROM t1; -- SQLITE_READ t1."" + ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2."" + ** + ** The fake column name is an empty string. It is possible for a table to + ** have a column named by the empty string, in which case there is no way to + ** distinguish between an unreferenced table and an actual reference to the + ** "" column. The original design was for the fake column name to be a NULL, + ** which would be unambiguous. But legacy authorization callbacks might + ** assume the column name is non-NULL and segfault. The use of an empty + ** string for the fake column name seems safer. + */ + if( pItem->colUsed==0 && pItem->zName!=0 ){ + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); + } + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + /* Generate code for all sub-queries in the FROM clause + */ + pSub = pItem->pSelect; + if( pSub==0 ) continue; + + /* The code for a subquery should only be generated once. */ + assert( pItem->addrFillSub==0 ); + + /* Increment Parse.nHeight by the height of the largest expression + ** tree referred to by this, the parent select. The child select + ** may contain expression trees of at most + ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit + ** more conservative than necessary, but much easier than enforcing + ** an exact limit. + */ + pParse->nHeight += sqlite3SelectExprHeight(p); + + /* Make copies of constant WHERE-clause terms in the outer query down + ** inside the subquery. This can help the subquery to run more efficiently. + */ + if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 + || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) + ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x4000 ){ + TREETRACE(0x4000,pParse,p, + ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); + }else{ + TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); + } + + /* Convert unused result columns of the subquery into simple NULL + ** expressions, to avoid unneeded searching and computation. + */ + if( OptimizationEnabled(db, SQLITE_NullUnusedCols) + && disableUnusedSubqueryResultColumns(pItem) + ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x4000 ){ + TREETRACE(0x4000,pParse,p, + ("Change unused result columns to NULL for subquery %d:\n", + pSub->selId)); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + } + + zSavedAuthContext = pParse->zAuthContext; + pParse->zAuthContext = pItem->zName; + + /* Generate code to implement the subquery + */ + if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ + /* Implement a co-routine that will return a single row of the result + ** set on each invocation. + */ + int addrTop = sqlite3VdbeCurrentAddr(v)+1; + + pItem->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + VdbeComment((v, "%!S", pItem)); + pItem->addrFillSub = addrTop; + sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); + sqlite3Select(pParse, pSub, &dest); + pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->fg.viaCoroutine = 1; + pItem->regResult = dest.iSdst; + sqlite3VdbeEndCoroutine(v, pItem->regReturn); + sqlite3VdbeJumpHere(v, addrTop-1); + sqlite3ClearTempRegCache(pParse); + }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ + /* This is a CTE for which materialization code has already been + ** generated. Invoke the subroutine to compute the materialization, + ** the make the pItem->iCursor be a copy of the ephemeral table that + ** holds the result of the materialization. */ + CteUse *pCteUse = pItem->u2.pCteUse; + sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); + if( pItem->iCursor!=pCteUse->iCur ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); + VdbeComment((v, "%!S", pItem)); + } + pSub->nSelectRow = pCteUse->nRowEst; + }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ + /* This view has already been materialized by a prior entry in + ** this same FROM clause. Reuse it. */ + if( pPrior->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + } + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + pSub->nSelectRow = pPrior->pSelect->nSelectRow; + }else{ + /* Materialize the view. If the view is not correlated, generate a + ** subroutine to do the materialization so that subsequent uses of + ** the same view can reuse the materialization. */ + int topAddr; + int onceAddr = 0; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExplain; +#endif + + pItem->regReturn = ++pParse->nMem; + topAddr = sqlite3VdbeAddOp0(v, OP_Goto); + pItem->addrFillSub = topAddr+1; + pItem->fg.isMaterialized = 1; + if( pItem->fg.isCorrelated==0 ){ + /* If the subquery is not correlated and if we are not inside of + ** a trigger, then we only need to compute the value of the subquery + ** once. */ + onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + VdbeComment((v, "materialize %!S", pItem)); + }else{ + VdbeNoopComment((v, "materialize %!S", pItem)); + } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + + ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); + sqlite3Select(pParse, pSub, &dest); + pItem->pTab->nRowLogEst = pSub->nSelectRow; + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); + sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); + VdbeComment((v, "end %!S", pItem)); + sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + sqlite3VdbeJumpHere(v, topAddr); + sqlite3ClearTempRegCache(pParse); + if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ + CteUse *pCteUse = pItem->u2.pCteUse; + pCteUse->addrM9e = pItem->addrFillSub; + pCteUse->regRtn = pItem->regReturn; + pCteUse->iCur = pItem->iCursor; + pCteUse->nRowEst = pSub->nSelectRow; + } + } + if( db->mallocFailed ) goto select_end; + pParse->nHeight -= sqlite3SelectExprHeight(p); + pParse->zAuthContext = zSavedAuthContext; +#endif + } + + /* Various elements of the SELECT copied into local variables for + ** convenience */ + pEList = p->pEList; + pWhere = p->pWhere; + pGroupBy = p->pGroupBy; + pHaving = p->pHaving; + sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x8000 ){ + TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + ** if the select-list is the same as the ORDER BY list, then this query + ** can be rewritten as a GROUP BY. In other words, this: + ** + ** SELECT DISTINCT xyz FROM ... ORDER BY xyz + ** + ** is transformed to: + ** + ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz + ** + ** The second form is preferred as a single index (or temp-table) may be + ** used for both the ORDER BY and DISTINCT processing. As originally + ** written the query must use a temp-table for at least one of the ORDER + ** BY and DISTINCT, and an index or separate temp-table for the other. + */ + if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct + && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 +#ifndef SQLITE_OMIT_WINDOWFUNC + && p->pWin==0 +#endif + ){ + p->selFlags &= ~SF_Distinct; + pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); + p->selFlags |= SF_Aggregate; + /* Notice that even thought SF_Distinct has been cleared from p->selFlags, + ** the sDistinct.isTnct is still set. Hence, isTnct represents the + ** original setting of the SF_Distinct flag, not the current setting */ + assert( sDistinct.isTnct ); + sDistinct.isTnct = 2; + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20000 ){ + TREETRACE(0x20000,pParse,p,("Transform DISTINCT into GROUP BY:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + } + + /* If there is an ORDER BY clause, then create an ephemeral index to + ** do the sorting. But this sorting ephemeral index might end up + ** being unused if the data can be extracted in pre-sorted order. + ** If that is the case, then the OP_OpenEphemeral instruction will be + ** changed to an OP_Noop once we figure out that the sorting index is + ** not needed. The sSort.addrSortIndex variable is used to facilitate + ** that change. + */ + if( sSort.pOrderBy ){ + KeyInfo *pKeyInfo; + pKeyInfo = sqlite3KeyInfoFromExprList( + pParse, sSort.pOrderBy, 0, pEList->nExpr); + sSort.iECursor = pParse->nTab++; + sSort.addrSortIndex = + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, + (char*)pKeyInfo, P4_KEYINFO + ); + }else{ + sSort.addrSortIndex = -1; + } + + /* If the output is destined for a temporary table, open that table. + */ + if( pDest->eDest==SRT_EphemTab ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); + if( p->selFlags & SF_NestedFrom ){ + /* Delete or NULL-out result columns that will never be used */ + int ii; + for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){ + sqlite3ExprDelete(db, pEList->a[ii].pExpr); + sqlite3DbFree(db, pEList->a[ii].zEName); + pEList->nExpr--; + } + for(ii=0; iinExpr; ii++){ + if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; + } + } + } + + /* Set the limiter. + */ + iEnd = sqlite3VdbeMakeLabel(pParse); + if( (p->selFlags & SF_FixedLimit)==0 ){ + p->nSelectRow = 320; /* 4 billion rows */ + } + if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd); + if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ + sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); + sSort.sortFlags |= SORTFLAG_UseSorter; + } + + /* Open an ephemeral index to use for the distinct set. + */ + if( p->selFlags & SF_Distinct ){ + sDistinct.tabTnct = pParse->nTab++; + sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sDistinct.tabTnct, 0, 0, + (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), + P4_KEYINFO); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; + }else{ + sDistinct.eTnctType = WHERE_DISTINCT_NOOP; + } + + if( !isAgg && pGroupBy==0 ){ + /* No aggregate functions and no GROUP BY clause */ + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) + | (p->selFlags & SF_FixedLimit); +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin = p->pWin; /* Main window object (or NULL) */ + if( pWin ){ + sqlite3WindowCodeInit(pParse, p); + } +#endif + assert( WHERE_USE_LIMIT==SF_FixedLimit ); + + + /* Begin the database scan. */ + TREETRACE(0x2,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, + p->pEList, p, wctrlFlags, p->nSelectRow); + if( pWInfo==0 ) goto select_end; + if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ + p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); + } + if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ + sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); + } + if( sSort.pOrderBy ){ + sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); + sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); + if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ + sSort.pOrderBy = 0; + } + } + TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + + /* If sorting index that was created by a prior OP_OpenEphemeral + ** instruction ended up not being needed, then change the OP_OpenEphemeral + ** into an OP_Noop. + */ + if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + } + + assert( p->pEList==pEList ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + int addrGosub = sqlite3VdbeMakeLabel(pParse); + int iCont = sqlite3VdbeMakeLabel(pParse); + int iBreak = sqlite3VdbeMakeLabel(pParse); + int regGosub = ++pParse->nMem; + + sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); + + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + sqlite3VdbeResolveLabel(v, addrGosub); + VdbeNoopComment((v, "inner-loop subroutine")); + sSort.labelOBLopt = 0; + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); + VdbeComment((v, "end inner-loop subroutine")); + sqlite3VdbeResolveLabel(v, iBreak); + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, + sqlite3WhereContinueLabel(pWInfo), + sqlite3WhereBreakLabel(pWInfo)); + + /* End the database scan loop. + */ + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + } + }else{ + /* This case when there exist aggregate functions or a GROUP BY clause + ** or both */ + NameContext sNC; /* Name context for processing aggregate information */ + int iAMem; /* First Mem address for storing current GROUP BY */ + int iBMem; /* First Mem address for previous GROUP BY */ + int iUseFlag; /* Mem address holding flag indicating that at least + ** one row of the input to the aggregator has been + ** processed */ + int iAbortFlag; /* Mem address which causes query abort if positive */ + int groupBySort; /* Rows come from source in GROUP BY order */ + int addrEnd; /* End of processing for this SELECT */ + int sortPTab = 0; /* Pseudotable used to decode sorting results */ + int sortOut = 0; /* Output register from the sorter */ + int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */ + + /* Remove any and all aliases between the result set and the + ** GROUP BY clause. + */ + if( pGroupBy ){ + int k; /* Loop counter */ + struct ExprList_item *pItem; /* For looping over expression in a list */ + + for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ + pItem->u.x.iAlias = 0; + } + for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ + pItem->u.x.iAlias = 0; + } + assert( 66==sqlite3LogEst(100) ); + if( p->nSelectRow>66 ) p->nSelectRow = 66; + + /* If there is both a GROUP BY and an ORDER BY clause and they are + ** identical, then it may be possible to disable the ORDER BY clause + ** on the grounds that the GROUP BY will cause elements to come out + ** in the correct order. It also may not - the GROUP BY might use a + ** database index that causes rows to be grouped together as required + ** but not actually sorted. Either way, record the fact that the + ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp + ** variable. */ + if( sSort.pOrderBy && pGroupBy->nExpr==sSort.pOrderBy->nExpr ){ + int ii; + /* The GROUP BY processing doesn't care whether rows are delivered in + ** ASC or DESC order - only that each group is returned contiguously. + ** So set the ASC/DESC flags in the GROUP BY to match those in the + ** ORDER BY to maximize the chances of rows being delivered in an + ** order that makes the ORDER BY redundant. */ + for(ii=0; iinExpr; ii++){ + u8 sortFlags; + sortFlags = sSort.pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; + pGroupBy->a[ii].fg.sortFlags = sortFlags; + } + if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ + orderByGrp = 1; + } + } + }else{ + assert( 0==sqlite3LogEst(1) ); + p->nSelectRow = 0; + } + + /* Create a label to jump to when we want to abort the query */ + addrEnd = sqlite3VdbeMakeLabel(pParse); + + /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in + ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the + ** SELECT statement. + */ + pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); + if( pAggInfo ){ + sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo); + testcase( pParse->earlyCleanup ); + } + if( db->mallocFailed ){ + goto select_end; + } + pAggInfo->selId = p->selId; +#ifdef SQLITE_DEBUG + pAggInfo->pSelect = p; +#endif + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + sNC.uNC.pAggInfo = pAggInfo; + VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) + pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; + pAggInfo->pGroupBy = pGroupBy; + sqlite3ExprAnalyzeAggList(&sNC, pEList); + sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); + if( pHaving ){ + if( pGroupBy ){ + assert( pWhere==p->pWhere ); + assert( pHaving==p->pHaving ); + assert( pGroupBy==p->pGroupBy ); + havingToWhere(pParse, p); + pWhere = p->pWhere; + } + sqlite3ExprAnalyzeAggregates(&sNC, pHaving); + } + pAggInfo->nAccumulator = pAggInfo->nColumn; + if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){ + minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pFExpr, &pMinMaxOrderBy); + }else{ + minMaxFlag = WHERE_ORDERBY_NORMAL; + } + analyzeAggFuncArgs(pAggInfo, &sNC); + if( db->mallocFailed ) goto select_end; +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); + sqlite3TreeViewSelect(0, p, 0); + if( minMaxFlag ){ + sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); + sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); + } + printAggInfo(pAggInfo); + } +#endif + + + /* Processing for aggregates with GROUP BY is very different and + ** much more complex than aggregates without a GROUP BY. + */ + if( pGroupBy ){ + KeyInfo *pKeyInfo; /* Keying information for the group by clause */ + int addr1; /* A-vs-B comparison jump */ + int addrOutputRow; /* Start of subroutine that outputs a result row */ + int regOutputRow; /* Return address register for output subroutine */ + int addrSetAbort; /* Set the abort flag and return */ + int addrTopOfLoop; /* Top of the input loop */ + int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ + int addrReset; /* Subroutine for resetting the accumulator */ + int regReset; /* Return address register for reset subroutine */ + ExprList *pDistinct = 0; + u16 distFlag = 0; + int eDist = WHERE_DISTINCT_NOOP; + + if( pAggInfo->nFunc==1 + && pAggInfo->aFunc[0].iDistinct>=0 + && ALWAYS(pAggInfo->aFunc[0].pFExpr!=0) + && ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr)) + && pAggInfo->aFunc[0].pFExpr->x.pList!=0 + ){ + Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr; + pExpr = sqlite3ExprDup(db, pExpr, 0); + pDistinct = sqlite3ExprListDup(db, pGroupBy, 0); + pDistinct = sqlite3ExprListAppend(pParse, pDistinct, pExpr); + distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; + } + + /* If there is a GROUP BY clause we might need a sorting index to + ** implement it. Allocate that sorting index now. If it turns out + ** that we do not need it after all, the OP_SorterOpen instruction + ** will be converted into a Noop. + */ + pAggInfo->sortingIdx = pParse->nTab++; + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pGroupBy, + 0, pAggInfo->nColumn); + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, + pAggInfo->sortingIdx, pAggInfo->nSortingColumn, + 0, (char*)pKeyInfo, P4_KEYINFO); + + /* Initialize memory locations used by GROUP BY aggregate processing + */ + iUseFlag = ++pParse->nMem; + iAbortFlag = ++pParse->nMem; + regOutputRow = ++pParse->nMem; + addrOutputRow = sqlite3VdbeMakeLabel(pParse); + regReset = ++pParse->nMem; + addrReset = sqlite3VdbeMakeLabel(pParse); + iAMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + iBMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); + VdbeComment((v, "clear abort flag")); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); + + /* Begin a loop that will extract all source rows in GROUP BY order. + ** This might involve two separate loops with an OP_Sort in between, or + ** it might be a single loop that uses an index to extract information + ** in the right order to begin with. + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + TREETRACE(0x2,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, + p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) + | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 + ); + if( pWInfo==0 ){ + sqlite3ExprListDelete(db, pDistinct); + goto select_end; + } + if( pParse->pIdxEpr ){ + optimizeAggregateUseOfIndexedExpr(pParse, p, pAggInfo, &sNC); + } + assignAggregateRegisters(pParse, pAggInfo); + eDist = sqlite3WhereIsDistinct(pWInfo); + TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ + /* The optimizer is able to deliver rows in group by order so + ** we do not have to sort. The OP_OpenEphemeral table will be + ** cancelled later because we still need to use the pKeyInfo + */ + groupBySort = 0; + }else{ + /* Rows are coming out in undetermined order. We have to push + ** each row into a sorting index, terminate the first loop, + ** then loop over the sorting index in order to get the output + ** in sorted order + */ + int regBase; + int regRecord; + int nCol; + int nGroupBy; + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExp; /* Address of OP_Explain instruction */ +#endif + ExplainQueryPlan2(addrExp, (pParse, 0, "USE TEMP B-TREE FOR %s", + (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? + "DISTINCT" : "GROUP BY" + )); + + groupBySort = 1; + nGroupBy = pGroupBy->nExpr; + nCol = nGroupBy; + j = nGroupBy; + for(i=0; inColumn; i++){ + if( pAggInfo->aCol[i].iSorterColumn>=j ){ + nCol++; + j++; + } + } + regBase = sqlite3GetTempRange(pParse, nCol); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); + j = nGroupBy; + pAggInfo->directMode = 1; + for(i=0; inColumn; i++){ + struct AggInfo_col *pCol = &pAggInfo->aCol[i]; + if( pCol->iSorterColumn>=j ){ + sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase); + j++; + } + } + pAggInfo->directMode = 0; + regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeScanStatusCounters(v, addrExp, 0, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); + sqlite3VdbeScanStatusRange(v, addrExp, sqlite3VdbeCurrentAddr(v)-2, -1); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nCol); + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; + sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeScanStatusCounters(v, addrExp, sqlite3VdbeCurrentAddr(v), 0); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); + sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); + VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); + pAggInfo->useSortingIdx = 1; + sqlite3VdbeScanStatusRange(v, addrExp, -1, sortPTab); + sqlite3VdbeScanStatusRange(v, addrExp, -1, pAggInfo->sortingIdx); + } + + /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions + ** that are indexed (and that were previously identified and tagged + ** in optimizeAggregateUseOfIndexedExpr()) then those subexpressions + ** must now be converted into a TK_AGG_COLUMN node so that the value + ** is correctly pulled from the index rather than being recomputed. */ + if( pParse->pIdxEpr ){ + aggregateConvertIndexedExprRefToColumn(pAggInfo); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20, pParse, p, + ("AggInfo function expressions converted to reference index\n")); + sqlite3TreeViewSelect(0, p, 0); + printAggInfo(pAggInfo); + } +#endif + } + + /* If the index or temporary table used by the GROUP BY sort + ** will naturally deliver rows in the order required by the ORDER BY + ** clause, cancel the ephemeral table open coded earlier. + ** + ** This is an optimization - the correct answer should result regardless. + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to + ** disable this optimization for testing purposes. */ + if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) + && (groupBySort || sqlite3WhereIsSorted(pWInfo)) + ){ + sSort.pOrderBy = 0; + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + } + + /* Evaluate the current GROUP BY terms and store in b0, b1, b2... + ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) + ** Then compare the current GROUP BY terms against the GROUP BY terms + ** from the previous row currently stored in a0, a1, a2... + */ + addrTopOfLoop = sqlite3VdbeCurrentAddr(v); + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx, + sortOut, sortPTab); + } + for(j=0; jnExpr; j++){ + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); + }else{ + pAggInfo->directMode = 1; + sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); + } + } + sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); + + /* Generate code that runs whenever the GROUP BY changes. + ** Changes in the GROUP BY are detected by the previous code + ** block. If there were no changes, this block is skipped. + ** + ** This code copies current group by terms in b0,b1,b2,... + ** over to a0,a1,a2. It then calls the output subroutine + ** and resets the aggregate accumulator registers in preparation + ** for the next GROUP BY batch. + */ + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output one row")); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); + VdbeComment((v, "check abort flag")); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + VdbeComment((v, "reset accumulator")); + + /* Update the aggregate accumulators based on the content of + ** the current row + */ + sqlite3VdbeJumpHere(v, addr1); + updateAccumulator(pParse, iUseFlag, pAggInfo, eDist); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); + VdbeComment((v, "indicate data in accumulator")); + + /* End of the loop + */ + if( groupBySort ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); + VdbeCoverage(v); + }else{ + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); + } + sqlite3ExprListDelete(db, pDistinct); + + /* Output the final row of result + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output final row")); + + /* Jump over the subroutines + */ + sqlite3VdbeGoto(v, addrEnd); + + /* Generate a subroutine that outputs a single row of the result + ** set. This subroutine first looks at the iUseFlag. If iUseFlag + ** is less than or equal to zero, the subroutine is a no-op. If + ** the processing calls for the query to abort, this subroutine + ** increments the iAbortFlag memory location before returning in + ** order to signal the caller to abort. + */ + addrSetAbort = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); + VdbeComment((v, "set abort flag")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeResolveLabel(v, addrOutputRow); + addrOutputRow = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); + VdbeCoverage(v); + VdbeComment((v, "Groupby result generator entry point")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + finalizeAggFunctions(pParse, pAggInfo); + sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, -1, &sSort, + &sDistinct, pDest, + addrOutputRow+1, addrSetAbort); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + VdbeComment((v, "end groupby result generator")); + + /* Generate a subroutine that will reset the group-by accumulator + */ + sqlite3VdbeResolveLabel(v, addrReset); + resetAccumulator(pParse, pAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator empty")); + sqlite3VdbeAddOp1(v, OP_Return, regReset); + + if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ + struct AggInfo_func *pF = &pAggInfo->aFunc[0]; + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } + } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ + else { + Table *pTab; + if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ + /* If isSimpleCount() returns a pointer to a Table structure, then + ** the SQL statement is of the form: + ** + ** SELECT count(*) FROM + ** + ** where the Table structure returned represents table . + ** + ** This statement is so common that it is optimized specially. The + ** OP_Count instruction is executed either on the intkey table that + ** contains the data for table or on one of its indexes. It + ** is better to execute the op on an index, as indexes are almost + ** always spread across less pages than their corresponding tables. + */ + const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */ + Index *pIdx; /* Iterator variable */ + KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */ + Index *pBest = 0; /* Best index found so far */ + Pgno iRoot = pTab->tnum; /* Root page of scanned b-tree */ + + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + /* Search for the index that has the lowest scan cost. + ** + ** (2011-04-15) Do not do a full scan of an unordered index. + ** + ** (2013-10-03) Do not count the entries in a partial index. + ** + ** In practice the KeyInfo structure will not be used. It is only + ** passed to keep OP_OpenRead happy. + */ + if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); + if( !p->pSrc->a[0].fg.notIndexed ){ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->bUnordered==0 + && pIdx->szIdxRowszTabRow + && pIdx->pPartIdxWhere==0 + && (!pBest || pIdx->szIdxRowszIdxRow) + ){ + pBest = pIdx; + } + } + } + if( pBest ){ + iRoot = pBest->tnum; + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest); + } + + /* Open a read-only cursor, execute the OP_Count, close the cursor. */ + sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, (int)iRoot, iDb, 1); + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); + } + assignAggregateRegisters(pParse, pAggInfo); + sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + explainSimpleCount(pParse, pTab, pBest); + }else{ + int regAcc = 0; /* "populate accumulators" flag */ + ExprList *pDistinct = 0; + u16 distFlag = 0; + int eDist; + + /* If there are accumulator registers but no min() or max() functions + ** without FILTER clauses, allocate register regAcc. Register regAcc + ** will contain 0 the first time the inner loop runs, and 1 thereafter. + ** The code generated by updateAccumulator() uses this to ensure + ** that the accumulator registers are (a) updated only once if + ** there are no min() or max functions or (b) always updated for the + ** first row visited by the aggregate, so that they are updated at + ** least once even if the FILTER clause means the min() or max() + ** function visits zero rows. */ + if( pAggInfo->nAccumulator ){ + for(i=0; inFunc; i++){ + if( ExprHasProperty(pAggInfo->aFunc[i].pFExpr, EP_WinFunc) ){ + continue; + } + if( pAggInfo->aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ){ + break; + } + } + if( i==pAggInfo->nFunc ){ + regAcc = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); + } + }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){ + assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) ); + pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; + distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; + } + assignAggregateRegisters(pParse, pAggInfo); + + /* This case runs if the aggregate has no GROUP BY clause. The + ** processing is much simpler since there is only a single row + ** of output. + */ + assert( p->pGroupBy==0 ); + resetAccumulator(pParse, pAggInfo); + + /* If this query is a candidate for the min/max optimization, then + ** minMaxFlag will have been previously set to either + ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will + ** be an appropriate ORDER BY expression for the optimization. + */ + assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); + assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); + + TREETRACE(0x2,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, + pDistinct, p, minMaxFlag|distFlag, 0); + if( pWInfo==0 ){ + goto select_end; + } + TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + eDist = sqlite3WhereIsDistinct(pWInfo); + updateAccumulator(pParse, regAcc, pAggInfo, eDist); + if( eDist!=WHERE_DISTINCT_NOOP ){ + struct AggInfo_func *pF = pAggInfo->aFunc; + if( pF ){ + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } + } + + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); + if( minMaxFlag ){ + sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); + } + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + finalizeAggFunctions(pParse, pAggInfo); + } + + sSort.pOrderBy = 0; + sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, -1, 0, 0, + pDest, addrEnd, addrEnd); + } + sqlite3VdbeResolveLabel(v, addrEnd); + + } /* endif aggregate query */ + + if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ + explainTempTable(pParse, "DISTINCT"); + } + + /* If there is an ORDER BY clause, then we need to sort the results + ** and send them to the callback one by one. + */ + if( sSort.pOrderBy ){ + assert( p->pEList==pEList ); + generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); + } + + /* Jump here to skip this query + */ + sqlite3VdbeResolveLabel(v, iEnd); + + /* The SELECT has been coded. If there is an error in the Parse structure, + ** set the return code to 1. Otherwise 0. */ + rc = (pParse->nErr>0); + + /* Control jumps to here if an error is encountered above, or upon + ** successful coding of the SELECT. + */ +select_end: + assert( db->mallocFailed==0 || db->mallocFailed==1 ); + assert( db->mallocFailed==0 || pParse->nErr!=0 ); + sqlite3ExprListDelete(db, pMinMaxOrderBy); +#ifdef SQLITE_DEBUG + if( pAggInfo && !db->mallocFailed ){ + for(i=0; inColumn; i++){ + Expr *pExpr = pAggInfo->aCol[i].pCExpr; + if( pExpr==0 ) continue; + assert( pExpr->pAggInfo==pAggInfo ); + assert( pExpr->iAgg==i ); + } + for(i=0; inFunc; i++){ + Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr!=0 ); + assert( pExpr->pAggInfo==pAggInfo ); + assert( pExpr->iAgg==i ); + } + } +#endif + +#if TREETRACE_ENABLED + TREETRACE(0x1,pParse,p,("end processing\n")); + if( (sqlite3TreeTrace & 0x40000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); + } +#endif + ExplainQueryPlanPop(pParse); + return rc; +} + +/************** End of select.c **********************************************/ +/************** Begin file table.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the sqlite3_get_table() and sqlite3_free_table() +** interface routines. These are just wrappers around the main +** interface routine of sqlite3_exec(). +** +** These routines are in a separate files so that they will not be linked +** if they are not used. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_GET_TABLE + +/* +** This structure is used to pass data from sqlite3_get_table() through +** to the callback function is uses to build the result. +*/ +typedef struct TabResult { + char **azResult; /* Accumulated output */ + char *zErrMsg; /* Error message text, if an error occurs */ + u32 nAlloc; /* Slots allocated for azResult[] */ + u32 nRow; /* Number of rows in the result */ + u32 nColumn; /* Number of columns in the result */ + u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ + int rc; /* Return code from sqlite3_exec() */ +} TabResult; + +/* +** This routine is called once for each row in the result table. Its job +** is to fill in the TabResult structure appropriately, allocating new +** memory as necessary. +*/ +static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ + TabResult *p = (TabResult*)pArg; /* Result accumulator */ + int need; /* Slots needed in p->azResult[] */ + int i; /* Loop counter */ + char *z; /* A single column of result */ + + /* Make sure there is enough space in p->azResult to hold everything + ** we need to remember from this invocation of the callback. + */ + if( p->nRow==0 && argv!=0 ){ + need = nCol*2; + }else{ + need = nCol; + } + if( p->nData + need > p->nAlloc ){ + char **azNew; + p->nAlloc = p->nAlloc*2 + need; + azNew = sqlite3Realloc( p->azResult, sizeof(char*)*p->nAlloc ); + if( azNew==0 ) goto malloc_failed; + p->azResult = azNew; + } + + /* If this is the first row, then generate an extra row containing + ** the names of all columns. + */ + if( p->nRow==0 ){ + p->nColumn = nCol; + for(i=0; iazResult[p->nData++] = z; + } + }else if( (int)p->nColumn!=nCol ){ + sqlite3_free(p->zErrMsg); + p->zErrMsg = sqlite3_mprintf( + "sqlite3_get_table() called with two or more incompatible queries" + ); + p->rc = SQLITE_ERROR; + return 1; + } + + /* Copy over the row data + */ + if( argv!=0 ){ + for(i=0; iazResult[p->nData++] = z; + } + p->nRow++; + } + return 0; + +malloc_failed: + p->rc = SQLITE_NOMEM_BKPT; + return 1; +} + +/* +** Query the database. But instead of invoking a callback for each row, +** malloc() for space to hold the result and return the entire results +** at the conclusion of the call. +** +** The result that is written to ***pazResult is held in memory obtained +** from malloc(). But the caller cannot free this memory directly. +** Instead, the entire table should be passed to sqlite3_free_table() when +** the calling procedure is finished using it. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + char ***pazResult, /* Write the result table here */ + int *pnRow, /* Write the number of rows in the result here */ + int *pnColumn, /* Write the number of columns of result here */ + char **pzErrMsg /* Write error messages here */ +){ + int rc; + TabResult res; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; +#endif + *pazResult = 0; + if( pnColumn ) *pnColumn = 0; + if( pnRow ) *pnRow = 0; + if( pzErrMsg ) *pzErrMsg = 0; + res.zErrMsg = 0; + res.nRow = 0; + res.nColumn = 0; + res.nData = 1; + res.nAlloc = 20; + res.rc = SQLITE_OK; + res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); + if( res.azResult==0 ){ + db->errCode = SQLITE_NOMEM; + return SQLITE_NOMEM_BKPT; + } + res.azResult[0] = 0; + rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); + assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); + res.azResult[0] = SQLITE_INT_TO_PTR(res.nData); + if( (rc&0xff)==SQLITE_ABORT ){ + sqlite3_free_table(&res.azResult[1]); + if( res.zErrMsg ){ + if( pzErrMsg ){ + sqlite3_free(*pzErrMsg); + *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); + } + sqlite3_free(res.zErrMsg); + } + db->errCode = res.rc; /* Assume 32-bit assignment is atomic */ + return res.rc; + } + sqlite3_free(res.zErrMsg); + if( rc!=SQLITE_OK ){ + sqlite3_free_table(&res.azResult[1]); + return rc; + } + if( res.nAlloc>res.nData ){ + char **azNew; + azNew = sqlite3Realloc( res.azResult, sizeof(char*)*res.nData ); + if( azNew==0 ){ + sqlite3_free_table(&res.azResult[1]); + db->errCode = SQLITE_NOMEM; + return SQLITE_NOMEM_BKPT; + } + res.azResult = azNew; + } + *pazResult = &res.azResult[1]; + if( pnColumn ) *pnColumn = res.nColumn; + if( pnRow ) *pnRow = res.nRow; + return rc; +} + +/* +** This routine frees the space the sqlite3_get_table() malloced. +*/ +SQLITE_API void sqlite3_free_table( + char **azResult /* Result returned from sqlite3_get_table() */ +){ + if( azResult ){ + int i, n; + azResult--; + assert( azResult!=0 ); + n = SQLITE_PTR_TO_INT(azResult[0]); + for(i=1; ipNext; + + sqlite3ExprDelete(db, pTmp->pWhere); + sqlite3ExprListDelete(db, pTmp->pExprList); + sqlite3SelectDelete(db, pTmp->pSelect); + sqlite3IdListDelete(db, pTmp->pIdList); + sqlite3UpsertDelete(db, pTmp->pUpsert); + sqlite3SrcListDelete(db, pTmp->pFrom); + sqlite3DbFree(db, pTmp->zSpan); + + sqlite3DbFree(db, pTmp); + } +} + +/* +** Given table pTab, return a list of all the triggers attached to +** the table. The list is connected by Trigger.pNext pointers. +** +** All of the triggers on pTab that are in the same database as pTab +** are already attached to pTab->pTrigger. But there might be additional +** triggers on pTab in the TEMP schema. This routine prepends all +** TEMP triggers on pTab to the beginning of the pTab->pTrigger list +** and returns the combined list. +** +** To state it another way: This routine returns a list of all triggers +** that fire off of pTab. The list will include any TEMP triggers on +** pTab as well as the triggers lised in pTab->pTrigger. +*/ +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ + Schema *pTmpSchema; /* Schema of the pTab table */ + Trigger *pList; /* List of triggers to return */ + HashElem *p; /* Loop variable for TEMP triggers */ + + assert( pParse->disableTriggers==0 ); + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + pList = pTab->pTrigger; + while( p ){ + Trigger *pTrig = (Trigger *)sqliteHashData(p); + if( pTrig->pTabSchema==pTab->pSchema + && pTrig->table + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning) + ){ + pTrig->pNext = pList; + pList = pTrig; + }else if( pTrig->op==TK_RETURNING ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + assert( pParse->db->pVtabCtx==0 ); +#endif + assert( pParse->bReturning ); + assert( &(pParse->u1.pReturning->retTrig) == pTrig ); + pTrig->table = pTab->zName; + pTrig->pTabSchema = pTab->pSchema; + pTrig->pNext = pList; + pList = pTrig; + } + p = sqliteHashNext(p); + } +#if 0 + if( pList ){ + Trigger *pX; + printf("Triggers for %s:", pTab->zName); + for(pX=pList; pX; pX=pX->pNext){ + printf(" %s", pX->zName); + } + printf("\n"); + fflush(stdout); + } +#endif + return pList; +} + +/* +** This is called by the parser when it sees a CREATE TRIGGER statement +** up to the point of the BEGIN before the trigger actions. A Trigger +** structure is generated based on the information available and stored +** in pParse->pNewTrigger. After the trigger actions have been parsed, the +** sqlite3FinishTrigger() function is called to complete the trigger +** construction process. +*/ +SQLITE_PRIVATE void sqlite3BeginTrigger( + Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ + Token *pName1, /* The name of the trigger */ + Token *pName2, /* The name of the trigger */ + int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */ + int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ + IdList *pColumns, /* column list if this is an UPDATE OF trigger */ + SrcList *pTableName,/* The name of the table/view the trigger applies to */ + Expr *pWhen, /* WHEN clause */ + int isTemp, /* True if the TEMPORARY keyword is present */ + int noErr /* Suppress errors if the trigger already exists */ +){ + Trigger *pTrigger = 0; /* The new trigger */ + Table *pTab; /* Table that the trigger fires off of */ + char *zName = 0; /* Name of the trigger */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb; /* The database to store the trigger in */ + Token *pName; /* The unqualified db name */ + DbFixer sFix; /* State vector for the DB fixer */ + + assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ + assert( pName2!=0 ); + assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE ); + assert( op>0 && op<0xff ); + if( isTemp ){ + /* If TEMP was specified, then the trigger name may not be qualified. */ + if( pName2->n>0 ){ + sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); + goto trigger_cleanup; + } + iDb = 1; + pName = pName1; + }else{ + /* Figure out the db that the trigger will be created in */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ){ + goto trigger_cleanup; + } + } + if( !pTableName || db->mallocFailed ){ + goto trigger_cleanup; + } + + /* A long-standing parser bug is that this syntax was allowed: + ** + ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... + ** ^^^^^^^^ + ** + ** To maintain backwards compatibility, ignore the database + ** name on pTableName if we are reparsing out of the schema table + */ + if( db->init.busy && iDb!=1 ){ + sqlite3DbFree(db, pTableName->a[0].zDatabase); + pTableName->a[0].zDatabase = 0; + } + + /* If the trigger name was unqualified, and the table is a temp table, + ** then set iDb to 1 to create the trigger in the temporary database. + ** If sqlite3SrcListLookup() returns 0, indicating the table does not + ** exist, the error is caught by the block below. + */ + pTab = sqlite3SrcListLookup(pParse, pTableName); + if( db->init.busy==0 && pName2->n==0 && pTab + && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } + + /* Ensure the table name matches database name and that the table exists */ + if( db->mallocFailed ) goto trigger_cleanup; + assert( pTableName->nSrc==1 ); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); + if( sqlite3FixSrcList(&sFix, pTableName) ){ + goto trigger_cleanup; + } + pTab = sqlite3SrcListLookup(pParse, pTableName); + if( !pTab ){ + /* The table does not exist. */ + goto trigger_orphan_error; + } + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); + goto trigger_orphan_error; + } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on shadow tables"); + goto trigger_orphan_error; + } + + /* Check that the trigger name is not reserved and that no trigger of the + ** specified name exists */ + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ){ + assert( db->mallocFailed ); + goto trigger_cleanup; + } + if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){ + goto trigger_cleanup; + } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !IN_RENAME_OBJECT ){ + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + VVA_ONLY( pParse->ifNotExists = 1; ) + } + goto trigger_cleanup; + } + } + + /* Do not create a trigger on a system table */ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); + goto trigger_cleanup; + } + + /* INSTEAD of triggers are only for views and views only support INSTEAD + ** of triggers. + */ + if( IsView(pTab) && tr_tm!=TK_INSTEAD ){ + sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", + (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName->a); + goto trigger_orphan_error; + } + if( !IsView(pTab) && tr_tm==TK_INSTEAD ){ + sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" + " trigger on table: %S", pTableName->a); + goto trigger_orphan_error; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( !IN_RENAME_OBJECT ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + int code = SQLITE_CREATE_TRIGGER; + const char *zDb = db->aDb[iTabDb].zDbSName; + const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; + if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; + if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ + goto trigger_cleanup; + } + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ + goto trigger_cleanup; + } + } +#endif + + /* INSTEAD OF triggers can only appear on views and BEFORE triggers + ** cannot appear on views. So we might as well translate every + ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code + ** elsewhere. + */ + if (tr_tm == TK_INSTEAD){ + tr_tm = TK_BEFORE; + } + + /* Build the Trigger object */ + pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); + if( pTrigger==0 ) goto trigger_cleanup; + pTrigger->zName = zName; + zName = 0; + pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); + pTrigger->pSchema = db->aDb[iDb].pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pTrigger->op = (u8)op; + pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); + pTrigger->pWhen = pWhen; + pWhen = 0; + }else{ + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + pTrigger->pColumns = pColumns; + pColumns = 0; + assert( pParse->pNewTrigger==0 ); + pParse->pNewTrigger = pTrigger; + +trigger_cleanup: + sqlite3DbFree(db, zName); + sqlite3SrcListDelete(db, pTableName); + sqlite3IdListDelete(db, pColumns); + sqlite3ExprDelete(db, pWhen); + if( !pParse->pNewTrigger ){ + sqlite3DeleteTrigger(db, pTrigger); + }else{ + assert( pParse->pNewTrigger==pTrigger ); + } + return; + +trigger_orphan_error: + if( db->init.iDb==1 ){ + /* Ticket #3810. + ** Normally, whenever a table is dropped, all associated triggers are + ** dropped too. But if a TEMP trigger is created on a non-TEMP table + ** and the table is dropped by a different database connection, the + ** trigger is not visible to the database connection that does the + ** drop so the trigger cannot be dropped. This results in an + ** "orphaned trigger" - a trigger whose associated table is missing. + ** + ** 2020-11-05 see also https://sqlite.org/forum/forumpost/157dc791df + */ + db->init.orphanTrigger = 1; + } + goto trigger_cleanup; +} + +/* +** This routine is called after all of the trigger actions have been parsed +** in order to complete the process of building the trigger. +*/ +SQLITE_PRIVATE void sqlite3FinishTrigger( + Parse *pParse, /* Parser context */ + TriggerStep *pStepList, /* The triggered program */ + Token *pAll /* Token that describes the complete CREATE TRIGGER */ +){ + Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */ + char *zName; /* Name of trigger */ + sqlite3 *db = pParse->db; /* The database */ + DbFixer sFix; /* Fixer object */ + int iDb; /* Database containing the trigger */ + Token nameToken; /* Trigger name for error reporting */ + + pParse->pNewTrigger = 0; + if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; + zName = pTrig->zName; + iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + pTrig->step_list = pStepList; + while( pStepList ){ + pStepList->pTrig = pTrig; + pStepList = pStepList->pNext; + } + sqlite3TokenInit(&nameToken, pTrig->zName); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) + || sqlite3FixExpr(&sFix, pTrig->pWhen) + ){ + goto triggerfinish_cleanup; + } + +#ifndef SQLITE_OMIT_ALTERTABLE + if( IN_RENAME_OBJECT ){ + assert( !db->init.busy ); + pParse->pNewTrigger = pTrig; + pTrig = 0; + }else +#endif + + /* if we are not initializing, + ** build the sqlite_schema entry + */ + if( !db->init.busy ){ + Vdbe *v; + char *z; + + /* If this is a new CREATE TABLE statement, and if shadow tables + ** are read-only, and the trigger makes a change to a shadow table, + ** then raise an error - do not allow the trigger to be created. */ + if( sqlite3ReadOnlyShadowTables(db) ){ + TriggerStep *pStep; + for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget!=0 + && sqlite3ShadowTableName(db, pStep->zTarget) + ){ + sqlite3ErrorMsg(pParse, + "trigger \"%s\" may not write to shadow table \"%s\"", + pTrig->zName, pStep->zTarget); + goto triggerfinish_cleanup; + } + } + } + + /* Make an entry in the sqlite_schema table */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto triggerfinish_cleanup; + sqlite3BeginWriteOperation(pParse, 0, iDb); + z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); + testcase( z==0 ); + sqlite3NestedParse(pParse, + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE + " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", + db->aDb[iDb].zDbSName, zName, + pTrig->table, z); + sqlite3DbFree(db, z); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0); + } + + if( db->init.busy ){ + Trigger *pLink = pTrig; + Hash *pHash = &db->aDb[iDb].pSchema->trigHash; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( pLink!=0 ); + pTrig = sqlite3HashInsert(pHash, zName, pTrig); + if( pTrig ){ + sqlite3OomFault(db); + }else if( pLink->pSchema==pLink->pTabSchema ){ + Table *pTab; + pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); + assert( pTab!=0 ); + pLink->pNext = pTab->pTrigger; + pTab->pTrigger = pLink; + } + } + +triggerfinish_cleanup: + sqlite3DeleteTrigger(db, pTrig); + assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); + sqlite3DeleteTriggerStep(db, pStepList); +} + +/* +** Duplicate a range of text from an SQL statement, then convert all +** whitespace characters into ordinary space characters. +*/ +static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + char *z = sqlite3DbSpanDup(db, zStart, zEnd); + int i; + if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' '; + return z; +} + +/* +** Turn a SELECT statement (that the pSelect parameter points to) into +** a trigger step. Return a pointer to a TriggerStep structure. +** +** The parser calls this routine when it finds a SELECT statement in +** body of a TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( + sqlite3 *db, /* Database connection */ + Select *pSelect, /* The SELECT statement */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); + if( pTriggerStep==0 ) { + sqlite3SelectDelete(db, pSelect); + return 0; + } + pTriggerStep->op = TK_SELECT; + pTriggerStep->pSelect = pSelect; + pTriggerStep->orconf = OE_Default; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + return pTriggerStep; +} + +/* +** Allocate space to hold a new trigger step. The allocated space +** holds both the TriggerStep object and the TriggerStep.target.z string. +** +** If an OOM error occurs, NULL is returned and db->mallocFailed is set. +*/ +static TriggerStep *triggerStepAllocate( + Parse *pParse, /* Parser context */ + u8 op, /* Trigger opcode */ + Token *pName, /* The target name */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + if( pParse->nErr ) return 0; + pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); + if( pTriggerStep ){ + char *z = (char*)&pTriggerStep[1]; + memcpy(z, pName->z, pName->n); + sqlite3Dequote(z); + pTriggerStep->zTarget = z; + pTriggerStep->op = op; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); + } + } + return pTriggerStep; +} + +/* +** Build a trigger step out of an INSERT statement. Return a pointer +** to the new trigger step. +** +** The parser calls this routine when it sees an INSERT inside the +** body of a trigger. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( + Parse *pParse, /* Parser */ + Token *pTableName, /* Name of the table into which we insert */ + IdList *pColumn, /* List of columns in pTableName to insert into */ + Select *pSelect, /* A SELECT statement that supplies values */ + u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ + Upsert *pUpsert, /* ON CONFLICT clauses for upsert */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + assert(pSelect != 0 || db->mallocFailed); + + pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pSelect = pSelect; + pSelect = 0; + }else{ + pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } + pTriggerStep->pIdList = pColumn; + pTriggerStep->pUpsert = pUpsert; + pTriggerStep->orconf = orconf; + if( pUpsert ){ + sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); + } + }else{ + testcase( pColumn ); + sqlite3IdListDelete(db, pColumn); + testcase( pUpsert ); + sqlite3UpsertDelete(db, pUpsert); + } + sqlite3SelectDelete(db, pSelect); + + return pTriggerStep; +} + +/* +** Construct a trigger step that implements an UPDATE statement and return +** a pointer to that trigger step. The parser calls this routine when it +** sees an UPDATE statement inside the body of a CREATE TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( + Parse *pParse, /* Parser */ + Token *pTableName, /* Name of the table to be updated */ + SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */ + ExprList *pEList, /* The SET clause: list of column and new values */ + Expr *pWhere, /* The WHERE clause */ + u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pExprList = pEList; + pTriggerStep->pWhere = pWhere; + pTriggerStep->pFrom = pFrom; + pEList = 0; + pWhere = 0; + pFrom = 0; + }else{ + pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pTriggerStep->pFrom = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE); + } + pTriggerStep->orconf = orconf; + } + sqlite3ExprListDelete(db, pEList); + sqlite3ExprDelete(db, pWhere); + sqlite3SrcListDelete(db, pFrom); + return pTriggerStep; +} + +/* +** Construct a trigger step that implements a DELETE statement and return +** a pointer to that trigger step. The parser calls this routine when it +** sees a DELETE statement inside the body of a CREATE TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( + Parse *pParse, /* Parser */ + Token *pTableName, /* The table from which rows are deleted */ + Expr *pWhere, /* The WHERE clause */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pWhere = pWhere; + pWhere = 0; + }else{ + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + } + pTriggerStep->orconf = OE_Default; + } + sqlite3ExprDelete(db, pWhere); + return pTriggerStep; +} + +/* +** Recursively delete a Trigger structure +*/ +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ + if( pTrigger==0 || pTrigger->bReturning ) return; + sqlite3DeleteTriggerStep(db, pTrigger->step_list); + sqlite3DbFree(db, pTrigger->zName); + sqlite3DbFree(db, pTrigger->table); + sqlite3ExprDelete(db, pTrigger->pWhen); + sqlite3IdListDelete(db, pTrigger->pColumns); + sqlite3DbFree(db, pTrigger); +} + +/* +** This function is called to drop a trigger from the database schema. +** +** This may be called directly from the parser and therefore identifies +** the trigger by name. The sqlite3DropTriggerPtr() routine does the +** same job as this routine except it takes a pointer to the trigger +** instead of the trigger name. +**/ +SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ + Trigger *pTrigger = 0; + int i; + const char *zDb; + const char *zName; + sqlite3 *db = pParse->db; + + if( db->mallocFailed ) goto drop_trigger_cleanup; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto drop_trigger_cleanup; + } + + assert( pName->nSrc==1 ); + zDb = pName->a[0].zDatabase; + zName = pName->a[0].zName; + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); + if( pTrigger ) break; + } + if( !pTrigger ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName->a); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, zDb); + } + pParse->checkSchema = 1; + goto drop_trigger_cleanup; + } + sqlite3DropTriggerPtr(pParse, pTrigger); + +drop_trigger_cleanup: + sqlite3SrcListDelete(db, pName); +} + +/* +** Return a pointer to the Table structure for the table that a trigger +** is set on. +*/ +static Table *tableOfTrigger(Trigger *pTrigger){ + return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); +} + + +/* +** Drop a trigger given a pointer to that trigger. +*/ +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ + Table *pTable; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); + assert( iDb>=0 && iDbnDb ); + pTable = tableOfTrigger(pTrigger); + assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pTable ){ + int code = SQLITE_DROP_TRIGGER; + const char *zDb = db->aDb[iDb].zDbSName; + const char *zTab = SCHEMA_TABLE(iDb); + if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; + if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || + sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + return; + } + } +#endif + + /* Generate code to destroy the database record of the trigger. + */ + if( (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'", + db->aDb[iDb].zDbSName, pTrigger->zName + ); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); + } +} + +/* +** Remove a trigger from the hash tables of the sqlite* pointer. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ + Trigger *pTrigger; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &(db->aDb[iDb].pSchema->trigHash); + pTrigger = sqlite3HashInsert(pHash, zName, 0); + if( ALWAYS(pTrigger) ){ + if( pTrigger->pSchema==pTrigger->pTabSchema ){ + Table *pTab = tableOfTrigger(pTrigger); + if( pTab ){ + Trigger **pp; + for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ + if( *pp==pTrigger ){ + *pp = (*pp)->pNext; + break; + } + } + } + } + sqlite3DeleteTrigger(db, pTrigger); + db->mDbFlags |= DBFLAG_SchemaChange; + } +} + +/* +** pEList is the SET clause of an UPDATE statement. Each entry +** in pEList is of the format =. If any of the entries +** in pEList have an which matches an identifier in pIdList, +** then return TRUE. If pIdList==NULL, then it is considered a +** wildcard that matches anything. Likewise if pEList==NULL then +** it matches anything so always return true. Return false only +** if there is no match. +*/ +static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ + int e; + if( pIdList==0 || NEVER(pEList==0) ) return 1; + for(e=0; enExpr; e++){ + if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; + } + return 0; +} + +/* +** Return true if any TEMP triggers exist +*/ +static int tempTriggersExist(sqlite3 *db){ + if( NEVER(db->aDb[1].pSchema==0) ) return 0; + if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0; + return 1; +} + +/* +** Return a list of all triggers on table pTab if there exists at least +** one trigger that must be fired when an operation of type 'op' is +** performed on the table, and, if that operation is an UPDATE, if at +** least one of the columns in pChanges is being modified. +*/ +static SQLITE_NOINLINE Trigger *triggersReallyExist( + Parse *pParse, /* Parse context */ + Table *pTab, /* The table the contains the triggers */ + int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ + ExprList *pChanges, /* Columns that change in an UPDATE statement */ + int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +){ + int mask = 0; + Trigger *pList = 0; + Trigger *p; + + pList = sqlite3TriggerList(pParse, pTab); + assert( pList==0 || IsVirtual(pTab)==0 + || (pList->bReturning && pList->pNext==0) ); + if( pList!=0 ){ + p = pList; + if( (pParse->db->flags & SQLITE_EnableTrigger)==0 + && pTab->pTrigger!=0 + ){ + /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that + ** only TEMP triggers are allowed. Truncate the pList so that it + ** includes only TEMP triggers */ + if( pList==pTab->pTrigger ){ + pList = 0; + goto exit_triggers_exist; + } + while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext; + p->pNext = 0; + p = pList; + } + do{ + if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ + mask |= p->tr_tm; + }else if( p->op==TK_RETURNING ){ + /* The first time a RETURNING trigger is seen, the "op" value tells + ** us what time of trigger it should be. */ + assert( sqlite3IsToplevel(pParse) ); + p->op = op; + if( IsVirtual(pTab) ){ + if( op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } + p->tr_tm = TRIGGER_BEFORE; + }else{ + p->tr_tm = TRIGGER_AFTER; + } + mask |= p->tr_tm; + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE + && sqlite3IsToplevel(pParse) ){ + /* Also fire a RETURNING trigger for an UPSERT */ + mask |= p->tr_tm; + } + p = p->pNext; + }while( p ); + } +exit_triggers_exist: + if( pMask ){ + *pMask = mask; + } + return (mask ? pList : 0); +} +SQLITE_PRIVATE Trigger *sqlite3TriggersExist( + Parse *pParse, /* Parse context */ + Table *pTab, /* The table the contains the triggers */ + int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ + ExprList *pChanges, /* Columns that change in an UPDATE statement */ + int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +){ + assert( pTab!=0 ); + if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db)) + || pParse->disableTriggers + ){ + if( pMask ) *pMask = 0; + return 0; + } + return triggersReallyExist(pParse,pTab,op,pChanges,pMask); +} + +/* +** Convert the pStep->zTarget string into a SrcList and return a pointer +** to that SrcList. +** +** This routine adds a specific database name, if needed, to the target when +** forming the SrcList. This prevents a trigger in one database from +** referring to a target in another database. An exception is when the +** trigger is in TEMP in which case it can refer to any other database it +** wants. +*/ +SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( + Parse *pParse, /* The parsing context */ + TriggerStep *pStep /* The trigger containing the target token */ +){ + sqlite3 *db = pParse->db; + SrcList *pSrc; /* SrcList to be returned */ + char *zName = sqlite3DbStrDup(db, pStep->zTarget); + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + assert( pSrc==0 || pSrc->nSrc==1 ); + assert( zName || pSrc==0 ); + if( pSrc ){ + Schema *pSchema = pStep->pTrig->pSchema; + pSrc->a[0].zName = zName; + if( pSchema!=db->aDb[1].pSchema ){ + pSrc->a[0].pSchema = pSchema; + } + if( pStep->pFrom ){ + SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); + if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){ + Select *pSubquery; + Token as; + pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0); + as.n = 0; + as.z = 0; + pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); + } + pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup); + } + }else{ + sqlite3DbFree(db, zName); + } + return pSrc; +} + +/* +** Return true if the pExpr term from the RETURNING clause argument +** list is of the form "*". Raise an error if the terms if of the +** form "table.*". +*/ +static int isAsteriskTerm( + Parse *pParse, /* Parsing context */ + Expr *pTerm /* A term in the RETURNING clause */ +){ + assert( pTerm!=0 ); + if( pTerm->op==TK_ASTERISK ) return 1; + if( pTerm->op!=TK_DOT ) return 0; + assert( pTerm->pRight!=0 ); + assert( pTerm->pLeft!=0 ); + if( pTerm->pRight->op!=TK_ASTERISK ) return 0; + sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards"); + return 1; +} + +/* The input list pList is the list of result set terms from a RETURNING +** clause. The table that we are returning from is pTab. +** +** This routine makes a copy of the pList, and at the same time expands +** any "*" wildcards to be the complete set of columns from pTab. +*/ +static ExprList *sqlite3ExpandReturning( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The arguments to RETURNING */ + Table *pTab /* The table being updated */ +){ + ExprList *pNew = 0; + sqlite3 *db = pParse->db; + int i; + + for(i=0; inExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ + int jj; + for(jj=0; jjnCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zCnName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); + pItem->fg.eEName = ENAME_NAME; + } + } + }else{ + Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); + pItem->fg.eEName = pList->a[i].fg.eEName; + } + } + } + return pNew; +} + +/* +** Generate code for the RETURNING trigger. Unlike other triggers +** that invoke a subprogram in the bytecode, the code for RETURNING +** is generated in-line. +*/ +static void codeReturningTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* The trigger step that defines the RETURNING */ + Table *pTab, /* The table to code triggers from */ + int regIn /* The first in an array of registers */ +){ + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + ExprList *pNew; + Returning *pReturning; + Select sSelect; + SrcList sFrom; + + assert( v!=0 ); + if( !pParse->bReturning ){ + /* This RETURNING trigger must be for a different statement as + ** this statement lacks a RETURNING clause. */ + return; + } + assert( db->pParse==pParse ); + pReturning = pParse->u1.pReturning; + if( pTrigger != &(pReturning->retTrig) ){ + /* This RETURNING trigger is for a different statement */ + return; + } + memset(&sSelect, 0, sizeof(sSelect)); + memset(&sFrom, 0, sizeof(sFrom)); + sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); + sSelect.pSrc = &sFrom; + sFrom.nSrc = 1; + sFrom.a[0].pTab = pTab; + sFrom.a[0].iCursor = -1; + sqlite3SelectPrep(pParse, &sSelect, 0); + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); + sqlite3GenerateColumnNames(pParse, &sSelect); + } + sqlite3ExprListDelete(db, sSelect.pEList); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pParse->nErr==0 ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + if( pReturning->nRetCol==0 ){ + pReturning->nRetCol = pNew->nExpr; + pReturning->iRetCur = pParse->nTab++; + } + sNC.pParse = pParse; + sNC.uNC.iBaseReg = regIn; + sNC.ncFlags = NC_UBaseReg; + pParse->eTriggerOp = pTrigger->op; + pParse->pTriggerTab = pTab; + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK + && ALWAYS(!db->mallocFailed) + ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; ia[i].pExpr; + assert( pCol!=0 ); /* Due to !db->mallocFailed ~9 lines above */ + sqlite3ExprCodeFactorable(pParse, pCol, reg+i); + if( sqlite3ExprAffinity(pCol)==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, reg+i); + } + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); + sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); + sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); + } + } + sqlite3ExprListDelete(db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; +} + + + +/* +** Generate VDBE code for the statements inside the body of a single +** trigger. +*/ +static int codeTriggerProgram( + Parse *pParse, /* The parser context */ + TriggerStep *pStepList, /* List of statements inside the trigger body */ + int orconf /* Conflict algorithm. (OE_Abort, etc) */ +){ + TriggerStep *pStep; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( pParse->pTriggerTab && pParse->pToplevel ); + assert( pStepList ); + assert( v!=0 ); + for(pStep=pStepList; pStep; pStep=pStep->pNext){ + /* Figure out the ON CONFLICT policy that will be used for this step + ** of the trigger program. If the statement that caused this trigger + ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use + ** the ON CONFLICT policy that was specified as part of the trigger + ** step statement. Example: + ** + ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN; + ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); + ** END; + ** + ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy + ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy + */ + pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; + assert( pParse->okConstFactor==0 ); + +#ifndef SQLITE_OMIT_TRACE + if( pStep->zSpan ){ + sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, + sqlite3MPrintf(db, "-- %s", pStep->zSpan), + P4_DYNAMIC); + } +#endif + + switch( pStep->op ){ + case TK_UPDATE: { + sqlite3Update(pParse, + sqlite3TriggerStepSrc(pParse, pStep), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), + pParse->eOrconf, 0, 0, 0 + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); + break; + } + case TK_INSERT: { + sqlite3Insert(pParse, + sqlite3TriggerStepSrc(pParse, pStep), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), + pParse->eOrconf, + sqlite3UpsertDup(db, pStep->pUpsert) + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); + break; + } + case TK_DELETE: { + sqlite3DeleteFrom(pParse, + sqlite3TriggerStepSrc(pParse, pStep), + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); + break; + } + default: assert( pStep->op==TK_SELECT ); { + SelectDest sDest; + Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); + sqlite3SelectDestInit(&sDest, SRT_Discard, 0); + sqlite3Select(pParse, pSelect, &sDest); + sqlite3SelectDelete(db, pSelect); + break; + } + } + } + + return 0; +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* +** This function is used to add VdbeComment() annotations to a VDBE +** program. It is not used in production code, only for debugging. +*/ +static const char *onErrorText(int onError){ + switch( onError ){ + case OE_Abort: return "abort"; + case OE_Rollback: return "rollback"; + case OE_Fail: return "fail"; + case OE_Replace: return "replace"; + case OE_Ignore: return "ignore"; + case OE_Default: return "default"; + } + return "n/a"; +} +#endif + +/* +** Parse context structure pFrom has just been used to create a sub-vdbe +** (trigger program). If an error has occurred, transfer error information +** from pFrom to pTo. +*/ +static void transferParseError(Parse *pTo, Parse *pFrom){ + assert( pFrom->zErrMsg==0 || pFrom->nErr ); + assert( pTo->zErrMsg==0 || pTo->nErr ); + if( pTo->nErr==0 ){ + pTo->zErrMsg = pFrom->zErrMsg; + pTo->nErr = pFrom->nErr; + pTo->rc = pFrom->rc; + }else{ + sqlite3DbFree(pFrom->db, pFrom->zErrMsg); + } +} + +/* +** Create and populate a new TriggerPrg object with a sub-program +** implementing trigger pTrigger with ON CONFLICT policy orconf. +*/ +static TriggerPrg *codeRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table pTrigger is attached to */ + int orconf /* ON CONFLICT policy to code trigger program with */ +){ + Parse *pTop = sqlite3ParseToplevel(pParse); + sqlite3 *db = pParse->db; /* Database handle */ + TriggerPrg *pPrg; /* Value to return */ + Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ + Vdbe *v; /* Temporary VM */ + NameContext sNC; /* Name context for sub-vdbe */ + SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ + int iEndTrigger = 0; /* Label to jump to if WHEN is false */ + Parse sSubParse; /* Parse context for sub-vdbe */ + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + assert( pTop->pVdbe ); + + /* Allocate the TriggerPrg and SubProgram objects. To ensure that they + ** are freed if an error occurs, link them into the Parse.pTriggerPrg + ** list of the top-level Parse object sooner rather than later. */ + pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); + if( !pPrg ) return 0; + pPrg->pNext = pTop->pTriggerPrg; + pTop->pTriggerPrg = pPrg; + pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); + if( !pProgram ) return 0; + sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); + pPrg->pTrigger = pTrigger; + pPrg->orconf = orconf; + pPrg->aColmask[0] = 0xffffffff; + pPrg->aColmask[1] = 0xffffffff; + + /* Allocate and populate a new Parse context to use for coding the + ** trigger sub-program. */ + sqlite3ParseObjectInit(&sSubParse, db); + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sSubParse; + sSubParse.pTriggerTab = pTab; + sSubParse.pToplevel = pTop; + sSubParse.zAuthContext = pTrigger->zName; + sSubParse.eTriggerOp = pTrigger->op; + sSubParse.nQueryLoop = pParse->nQueryLoop; + sSubParse.prepFlags = pParse->prepFlags; + + v = sqlite3GetVdbe(&sSubParse); + if( v ){ + VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", + pTrigger->zName, onErrorText(orconf), + (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), + (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), + (pTrigger->op==TK_INSERT ? "INSERT" : ""), + (pTrigger->op==TK_DELETE ? "DELETE" : ""), + pTab->zName + )); +#ifndef SQLITE_OMIT_TRACE + if( pTrigger->zName ){ + sqlite3VdbeChangeP4(v, -1, + sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC + ); + } +#endif + + /* If one was specified, code the WHEN clause. If it evaluates to false + ** (or NULL) the sub-vdbe is immediately halted by jumping to the + ** OP_Halt inserted at the end of the program. */ + if( pTrigger->pWhen ){ + pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); + if( db->mallocFailed==0 + && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) + ){ + iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse); + sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + } + sqlite3ExprDelete(db, pWhen); + } + + /* Code the trigger program into the sub-vdbe. */ + codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf); + + /* Insert an OP_Halt at the end of the sub-program. */ + if( iEndTrigger ){ + sqlite3VdbeResolveLabel(v, iEndTrigger); + } + sqlite3VdbeAddOp0(v, OP_Halt); + VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); + transferParseError(pParse, &sSubParse); + + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); + pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); + } + pProgram->nMem = sSubParse.nMem; + pProgram->nCsr = sSubParse.nTab; + pProgram->token = (void *)pTrigger; + pPrg->aColmask[0] = sSubParse.oldmask; + pPrg->aColmask[1] = sSubParse.newmask; + sqlite3VdbeDelete(v); + }else{ + transferParseError(pParse, &sSubParse); + } + + assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg ); + sqlite3ParseObjectReset(&sSubParse); + return pPrg; +} + +/* +** Return a pointer to a TriggerPrg object containing the sub-program for +** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such +** TriggerPrg object exists, a new object is allocated and populated before +** being returned. +*/ +static TriggerPrg *getRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table trigger pTrigger is attached to */ + int orconf /* ON CONFLICT algorithm. */ +){ + Parse *pRoot = sqlite3ParseToplevel(pParse); + TriggerPrg *pPrg; + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + + /* It may be that this trigger has already been coded (or is in the + ** process of being coded). If this is the case, then an entry with + ** a matching TriggerPrg.pTrigger field will be present somewhere + ** in the Parse.pTriggerPrg list. Search for such an entry. */ + for(pPrg=pRoot->pTriggerPrg; + pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); + pPrg=pPrg->pNext + ); + + /* If an existing TriggerPrg could not be located, create a new one. */ + if( !pPrg ){ + pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); + pParse->db->errByteOffset = -1; + } + + return pPrg; +} + +/* +** Generate code for the trigger program associated with trigger p on +** table pTab. The reg, orconf and ignoreJump parameters passed to this +** function are the same as those described in the header function for +** sqlite3CodeRowTrigger() +*/ +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( + Parse *pParse, /* Parse context */ + Trigger *p, /* Trigger to code */ + Table *pTab, /* The table to code triggers from */ + int reg, /* Reg array containing OLD.* and NEW.* values */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + assert( pPrg || pParse->nErr ); + + /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program + ** is a pointer to the sub-vdbe containing the trigger program. */ + if( pPrg ){ + int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); + + sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, + (const char *)pPrg->pProgram, P4_SUBPROGRAM); + VdbeComment( + (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); + + /* Set the P5 operand of the OP_Program instruction to non-zero if + ** recursive invocation of this trigger program is disallowed. Recursive + ** invocation is disallowed if (a) the sub-program is really a trigger, + ** not a foreign key action, and (b) the flag to enable recursive triggers + ** is clear. */ + sqlite3VdbeChangeP5(v, (u8)bRecursive); + } +} + +/* +** This is called to code the required FOR EACH ROW triggers for an operation +** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) +** is given by the op parameter. The tr_tm parameter determines whether the +** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then +** parameter pChanges is passed the list of columns being modified. +** +** If there are no triggers that fire at the specified time for the specified +** operation on pTab, this function is a no-op. +** +** The reg argument is the address of the first in an array of registers +** that contain the values substituted for the new.* and old.* references +** in the trigger program. If N is the number of columns in table pTab +** (a copy of pTab->nCol), then registers are populated as follows: +** +** Register Contains +** ------------------------------------------------------ +** reg+0 OLD.rowid +** reg+1 OLD.* value of left-most column of pTab +** ... ... +** reg+N OLD.* value of right-most column of pTab +** reg+N+1 NEW.rowid +** reg+N+2 NEW.* value of left-most column of pTab +** ... ... +** reg+N+N+1 NEW.* value of right-most column of pTab +** +** For ON DELETE triggers, the registers containing the NEW.* values will +** never be accessed by the trigger program, so they are not allocated or +** populated by the caller (there is no data to populate them with anyway). +** Similarly, for ON INSERT triggers the values stored in the OLD.* registers +** are never accessed, and so are not allocated by the caller. So, for an +** ON INSERT trigger, the value passed to this function as parameter reg +** is not a readable register, although registers (reg+N) through +** (reg+N+N+1) are. +** +** Parameter orconf is the default conflict resolution algorithm for the +** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump +** is the instruction that control should jump to if a trigger program +** raises an IGNORE exception. +*/ +SQLITE_PRIVATE void sqlite3CodeRowTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + Table *pTab, /* The table to code triggers from */ + int reg, /* The first in an array of registers (see above) */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Trigger *p; /* Used to iterate through pTrigger list */ + + assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE ); + assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); + assert( (op==TK_UPDATE)==(pChanges!=0) ); + + for(p=pTrigger; p; p=p->pNext){ + + /* Sanity checking: The schema for the trigger and for the table are + ** always defined. The trigger must be in the same schema as the table + ** or else it must be a TEMP trigger. */ + assert( p->pSchema!=0 ); + assert( p->pTabSchema!=0 ); + assert( p->pSchema==p->pTabSchema + || p->pSchema==pParse->db->aDb[1].pSchema ); + + /* Determine whether we should code this trigger. One of two choices: + ** 1. The trigger is an exact match to the current DML statement + ** 2. This is a RETURNING trigger for INSERT but we are currently + ** doing the UPDATE part of an UPSERT. + */ + if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) + && p->tr_tm==tr_tm + && checkColumnOverlap(p->pColumns, pChanges) + ){ + if( !p->bReturning ){ + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + }else if( sqlite3IsToplevel(pParse) ){ + codeReturningTrigger(pParse, p, pTab, reg); + } + } + } +} + +/* +** Triggers may access values stored in the old.* or new.* pseudo-table. +** This function returns a 32-bit bitmask indicating which columns of the +** old.* or new.* tables actually are used by triggers. This information +** may be used by the caller, for example, to avoid having to load the entire +** old.* record into memory when executing an UPDATE or DELETE command. +** +** Bit 0 of the returned mask is set if the left-most column of the +** table may be accessed using an [old|new].reference. Bit 1 is set if +** the second leftmost column value is required, and so on. If there +** are more than 32 columns in the table, and at least one of the columns +** with an index greater than 32 may be accessed, 0xffffffff is returned. +** +** It is not possible to determine if the old.rowid or new.rowid column is +** accessed by triggers. The caller must always assume that it is. +** +** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned +** applies to the old.* table. If 1, the new.* table. +** +** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE +** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only +** included in the returned mask if the TRIGGER_BEFORE bit is set in the +** tr_tm parameter. Similarly, values accessed by AFTER triggers are only +** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm. +*/ +SQLITE_PRIVATE u32 sqlite3TriggerColmask( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */ + int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ + Table *pTab, /* The table to code triggers from */ + int orconf /* Default ON CONFLICT policy for trigger steps */ +){ + const int op = pChanges ? TK_UPDATE : TK_DELETE; + u32 mask = 0; + Trigger *p; + + assert( isNew==1 || isNew==0 ); + if( IsView(pTab) ){ + return 0xffffffff; + } + for(p=pTrigger; p; p=p->pNext){ + if( p->op==op + && (tr_tm&p->tr_tm) + && checkColumnOverlap(p->pColumns,pChanges) + ){ + if( p->bReturning ){ + mask = 0xffffffff; + }else{ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->aColmask[isNew]; + } + } + } + } + + return mask; +} + +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ + +/************** End of trigger.c *********************************************/ +/************** Begin file update.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle UPDATE statements. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Forward declaration */ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowidExpr, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ +); +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** The most recently coded instruction was an OP_Column to retrieve the +** i-th column of table pTab. This routine sets the P4 parameter of the +** OP_Column to the default value, if any. +** +** The default value of a column is specified by a DEFAULT clause in the +** column definition. This was either supplied by the user when the table +** was created, or added later to the table definition by an ALTER TABLE +** command. If the latter, then the row-records in the table btree on disk +** may not contain a value for the column and the default value, taken +** from the P4 parameter of the OP_Column instruction, is returned instead. +** If the former, then all row-records are guaranteed to include a value +** for the column and the P4 value is not required. +** +** Column definitions created by an ALTER TABLE command may only have +** literal default values specified: a number, null or a string. (If a more +** complicated default expression value was provided, it is evaluated +** when the ALTER TABLE is executed and one of the literal values written +** into the sqlite_schema table.) +** +** Therefore, the P4 parameter is only required if the default value for +** the column is a literal number, string or null. The sqlite3ValueFromExpr() +** function is capable of transforming these types of expressions into +** sqlite3_value objects. +** +** If column as REAL affinity and the table is an ordinary b-tree table +** (not a virtual table) then the value might have been stored as an +** integer. In that case, add an OP_RealAffinity opcode to make sure +** it has been converted into REAL. +*/ +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ + Column *pCol; + assert( pTab!=0 ); + assert( pTab->nCol>i ); + pCol = &pTab->aCol[i]; + if( pCol->iDflt ){ + sqlite3_value *pValue = 0; + u8 enc = ENC(sqlite3VdbeDb(v)); + assert( !IsView(pTab) ); + VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); + assert( inCol ); + sqlite3ValueFromExpr(sqlite3VdbeDb(v), + sqlite3ColumnExpr(pTab,pCol), enc, + pCol->affinity, &pValue); + if( pValue ){ + sqlite3VdbeAppendP4(v, pValue, P4_MEM); + } + } +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pCol->affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } +#endif +} + +/* +** Check to see if column iCol of index pIdx references any of the +** columns defined by aXRef and chngRowid. Return true if it does +** and false if not. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexColumnIsBeingUpdated( + Index *pIdx, /* The index to check */ + int iCol, /* Which column of the index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + i16 iIdxCol = pIdx->aiColumn[iCol]; + assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */ + if( iIdxCol>=0 ){ + return aXRef[iIdxCol]>=0; + } + assert( iIdxCol==XN_EXPR ); + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->a[iCol].pExpr!=0 ); + return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, + aXRef,chngRowid); +} + +/* +** Check to see if index pIdx is a partial index whose conditional +** expression might change values due to an UPDATE. Return true if +** the index is subject to change and false if the index is guaranteed +** to be unchanged. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexWhereClauseMightChange( + Index *pIdx, /* The index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + if( pIdx->pPartIdxWhere==0 ) return 0; + return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, + aXRef, chngRowid); +} + +/* +** Allocate and return a pointer to an expression of type TK_ROW with +** Expr.iColumn set to value (iCol+1). The resolver will modify the +** expression to be a TK_COLUMN reading column iCol of the first +** table in the source-list (pSrc->a[0]). +*/ +static Expr *exprRowColumn(Parse *pParse, int iCol){ + Expr *pRet = sqlite3PExpr(pParse, TK_ROW, 0, 0); + if( pRet ) pRet->iColumn = iCol+1; + return pRet; +} + +/* +** Assuming both the pLimit and pOrderBy parameters are NULL, this function +** generates VM code to run the query: +** +** SELECT , pChanges FROM pTabList WHERE pWhere +** +** and write the results to the ephemeral table already opened as cursor +** iEph. None of pChanges, pTabList or pWhere are modified or consumed by +** this function, they must be deleted by the caller. +** +** Or, if pLimit and pOrderBy are not NULL, and pTab is not a view: +** +** SELECT , pChanges FROM pTabList +** WHERE pWhere +** GROUP BY +** ORDER BY pOrderBy LIMIT pLimit +** +** If pTab is a view, the GROUP BY clause is omitted. +** +** Exactly how results are written to table iEph, and exactly what +** the in the query above are is determined by the type +** of table pTabList->a[0].pTab. +** +** If the table is a WITHOUT ROWID table, then argument pPk must be its +** PRIMARY KEY. In this case are the primary key columns +** of the table, in order. The results of the query are written to ephemeral +** table iEph as index keys, using OP_IdxInsert. +** +** If the table is actually a view, then are all columns of +** the view. The results are written to the ephemeral table iEph as records +** with automatically assigned integer keys. +** +** If the table is a virtual or ordinary intkey table, then +** is its rowid. For a virtual table, the results are written to iEph as +** records with automatically assigned integer keys For intkey tables, the +** rowid value in is used as the integer key, and the +** remaining fields make up the table record. +*/ +static void updateFromSelect( + Parse *pParse, /* Parse context */ + int iEph, /* Cursor for open eph. table */ + Index *pPk, /* PK if table 0 is WITHOUT ROWID */ + ExprList *pChanges, /* List of expressions to return */ + SrcList *pTabList, /* List of tables to select from */ + Expr *pWhere, /* WHERE clause for query */ + ExprList *pOrderBy, /* ORDER BY clause */ + Expr *pLimit /* LIMIT clause */ +){ + int i; + SelectDest dest; + Select *pSelect = 0; + ExprList *pList = 0; + ExprList *pGrp = 0; + Expr *pLimit2 = 0; + ExprList *pOrderBy2 = 0; + sqlite3 *db = pParse->db; + Table *pTab = pTabList->a[0].pTab; + SrcList *pSrc; + Expr *pWhere2; + int eDest; + +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( pOrderBy && pLimit==0 ) { + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on UPDATE"); + return; + } + pOrderBy2 = sqlite3ExprListDup(db, pOrderBy, 0); + pLimit2 = sqlite3ExprDup(db, pLimit, 0); +#else + UNUSED_PARAMETER(pOrderBy); + UNUSED_PARAMETER(pLimit); +#endif + + pSrc = sqlite3SrcListDup(db, pTabList, 0); + pWhere2 = sqlite3ExprDup(db, pWhere, 0); + + assert( pTabList->nSrc>1 ); + if( pSrc ){ + assert( pSrc->a[0].fg.notCte ); + pSrc->a[0].iCursor = -1; + pSrc->a[0].pTab->nTabRef--; + pSrc->a[0].pTab = 0; + } + if( pPk ){ + for(i=0; inKeyCol; i++){ + Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]); +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( pLimit ){ + pGrp = sqlite3ExprListAppend(pParse, pGrp, sqlite3ExprDup(db, pNew, 0)); + } +#endif + pList = sqlite3ExprListAppend(pParse, pList, pNew); + } + eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; + }else if( IsView(pTab) ){ + for(i=0; inCol; i++){ + pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); + } + eDest = SRT_Table; + }else{ + eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; + pList = sqlite3ExprListAppend(pParse, 0, sqlite3PExpr(pParse,TK_ROW,0,0)); +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( pLimit ){ + pGrp = sqlite3ExprListAppend(pParse, 0, sqlite3PExpr(pParse,TK_ROW,0,0)); + } +#endif + } + assert( pChanges!=0 || pParse->db->mallocFailed ); + if( pChanges ){ + for(i=0; inExpr; i++){ + pList = sqlite3ExprListAppend(pParse, pList, + sqlite3ExprDup(db, pChanges->a[i].pExpr, 0) + ); + } + } + pSelect = sqlite3SelectNew(pParse, pList, + pSrc, pWhere2, pGrp, 0, pOrderBy2, + SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2 + ); + if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; + sqlite3SelectDestInit(&dest, eDest, iEph); + dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); + sqlite3Select(pParse, pSelect, &dest); + sqlite3SelectDelete(db, pSelect); +} + +/* +** Process an UPDATE statement. +** +** UPDATE OR IGNORE tbl SET a=b, c=d FROM tbl2... WHERE e<5 AND f NOT NULL; +** \_______/ \_/ \______/ \_____/ \________________/ +** onError | pChanges | pWhere +** \_______________________/ +** pTabList +*/ +SQLITE_PRIVATE void sqlite3Update( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table in which we should change things */ + ExprList *pChanges, /* Things to be changed */ + Expr *pWhere, /* The WHERE clause. May be null */ + int onError, /* How to handle constraint errors */ + ExprList *pOrderBy, /* ORDER BY clause. May be null */ + Expr *pLimit, /* LIMIT clause. May be null */ + Upsert *pUpsert /* ON CONFLICT clause, or null */ +){ + int i, j, k; /* Loop counters */ + Table *pTab; /* The table to be updated */ + int addrTop = 0; /* VDBE instruction address of the start of the loop */ + WhereInfo *pWInfo = 0; /* Information about the WHERE clause */ + Vdbe *v; /* The virtual database engine */ + Index *pIdx; /* For looping over indices */ + Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ + int nIdx; /* Number of indices that need updating */ + int nAllIdx; /* Total number of indexes */ + int iBaseCur; /* Base cursor number */ + int iDataCur; /* Cursor for the canonical data btree */ + int iIdxCur; /* Cursor for the first index */ + sqlite3 *db; /* The database structure */ + int *aRegIdx = 0; /* Registers for to each index and the main table */ + int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the + ** an expression for the i-th column of the table. + ** aXRef[i]==-1 if the i-th column is not changed. */ + u8 *aToOpen; /* 1 for tables and indices to be opened */ + u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */ + u8 chngRowid; /* Rowid changed in a normal table */ + u8 chngKey; /* Either chngPk or chngRowid */ + Expr *pRowidExpr = 0; /* Expression defining the new record number */ + int iRowidExpr = -1; /* Index of "rowid=" (or IPK) assignment in pChanges */ + AuthContext sContext; /* The authorization context */ + NameContext sNC; /* The name-context to resolve expressions in */ + int iDb; /* Database containing the table being updated */ + int eOnePass; /* ONEPASS_XXX value from where.c */ + int hasFK; /* True if foreign key processing is required */ + int labelBreak; /* Jump here to break out of UPDATE loop */ + int labelContinue; /* Jump here to continue next step of UPDATE loop */ + int flags; /* Flags for sqlite3WhereBegin() */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True when updating a view (INSTEAD OF trigger) */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +#endif + int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */ + int iEph = 0; /* Ephemeral table holding all primary key values */ + int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + int addrOpen = 0; /* Address of OP_OpenEphemeral */ + int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */ + i16 nPk = 0; /* Number of components of the PRIMARY KEY */ + int bReplace = 0; /* True if REPLACE conflict resolution might happen */ + int bFinishSeek = 1; /* The OP_FinishSeek opcode is needed */ + int nChangeFrom = 0; /* If there is a FROM, pChanges->nExpr, else 0 */ + + /* Register Allocations */ + int regRowCount = 0; /* A count of rows changed */ + int regOldRowid = 0; /* The old rowid */ + int regNewRowid = 0; /* The new rowid */ + int regNew = 0; /* Content of the NEW.* table in triggers */ + int regOld = 0; /* Content of OLD.* table in triggers */ + int regRowSet = 0; /* Rowset of rows to be updated */ + int regKey = 0; /* composite PRIMARY KEY value */ + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto update_cleanup; + } + assert( db->mallocFailed==0 ); + + /* Locate the table which we want to update. + */ + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ) goto update_cleanup; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + + /* Figure out if we have any triggers and if the table being + ** updated is a view. + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); + isView = IsView(pTab); + assert( pTrigger || tmask==0 ); +#else +# define pTrigger 0 +# define isView 0 +# define tmask 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere, + onError, pOrderBy, pLimit, pUpsert, pTrigger); + } +#endif + + /* If there was a FROM clause, set nChangeFrom to the number of expressions + ** in the change-list. Otherwise, set it to 0. There cannot be a FROM + ** clause if this function is being called to generate code for part of + ** an UPSERT statement. */ + nChangeFrom = (pTabList->nSrc>1) ? pChanges->nExpr : 0; + assert( nChangeFrom==0 || pUpsert==0 ); + +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( !isView && nChangeFrom==0 ){ + pWhere = sqlite3LimitWhere( + pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE" + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto update_cleanup; + } + if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + goto update_cleanup; + } + + /* Allocate a cursors for the main database table and for all indices. + ** The index cursors might not be used, but if they are used they + ** need to occur right after the database cursor. So go ahead and + ** allocate enough space, just in case. + */ + iBaseCur = iDataCur = pParse->nTab++; + iIdxCur = iDataCur+1; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + testcase( pPk!=0 && pPk!=pTab->pIndex ); + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + if( pPk==pIdx ){ + iDataCur = pParse->nTab; + } + pParse->nTab++; + } + if( pUpsert ){ + /* On an UPSERT, reuse the same cursors already opened by INSERT */ + iDataCur = pUpsert->iDataCur; + iIdxCur = pUpsert->iIdxCur; + pParse->nTab = iBaseCur; + } + pTabList->a[0].iCursor = iDataCur; + + /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. + ** Initialize aXRef[] and aToOpen[] to their default values. + */ + aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 ); + if( aXRef==0 ) goto update_cleanup; + aRegIdx = aXRef+pTab->nCol; + aToOpen = (u8*)(aRegIdx+nIdx+1); + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + for(i=0; inCol; i++) aXRef[i] = -1; + + /* Initialize the name-context */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; + + /* Begin generating code. */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto update_cleanup; + + /* Resolve the column names in all the expressions of the + ** of the UPDATE statement. Also find the column index + ** for each column to be updated in the pChanges array. For each + ** column to be updated, make sure we have authorization to change + ** that column. + */ + chngRowid = chngPk = 0; + for(i=0; inExpr; i++){ + u8 hCol = sqlite3StrIHash(pChanges->a[i].zEName); + /* If this is an UPDATE with a FROM clause, do not resolve expressions + ** here. The call to sqlite3Select() below will do that. */ + if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ + goto update_cleanup; + } + for(j=0; jnCol; j++){ + if( pTab->aCol[j].hName==hCol + && sqlite3StrICmp(pTab->aCol[j].zCnName, pChanges->a[i].zEName)==0 + ){ + if( j==pTab->iPKey ){ + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + iRowidExpr = i; + }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ + chngPk = 1; + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "cannot UPDATE generated column \"%s\"", + pTab->aCol[j].zCnName); + goto update_cleanup; + } +#endif + aXRef[j] = i; + break; + } + } + if( j>=pTab->nCol ){ + if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){ + j = -1; + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + iRowidExpr = i; + }else{ + sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName); + pParse->checkSchema = 1; + goto update_cleanup; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int rc; + rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, + j<0 ? "ROWID" : pTab->aCol[j].zCnName, + db->aDb[iDb].zDbSName); + if( rc==SQLITE_DENY ){ + goto update_cleanup; + }else if( rc==SQLITE_IGNORE ){ + aXRef[j] = -1; + } + } +#endif + } + assert( (chngRowid & chngPk)==0 ); + assert( chngRowid==0 || chngRowid==1 ); + assert( chngPk==0 || chngPk==1 ); + chngKey = chngRowid + chngPk; + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Mark generated columns as changing if their generator expressions + ** reference any changing column. The actual aXRef[] value for + ** generated expressions is not used, other than to check to see that it + ** is non-negative, so the value of aXRef[] for generated columns can be + ** set to any non-negative number. We use 99999 so that the value is + ** obvious when looking at aXRef[] in a symbolic debugger. + */ + if( pTab->tabFlags & TF_HasGenerated ){ + int bProgress; + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + do{ + bProgress = 0; + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ) continue; + if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue; + if( sqlite3ExprReferencesUpdatedColumn( + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + aXRef, chngRowid) + ){ + aXRef[i] = 99999; + bProgress = 1; + } + } + }while( bProgress ); + } +#endif + + /* The SET expressions are not actually used inside the WHERE loop. + ** So reset the colUsed mask. Unless this is a virtual table. In that + ** case, set all bits of the colUsed mask (to ensure that the virtual + ** table implementation makes all columns available). + */ + pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0; + + hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); + + /* There is one entry in the aRegIdx[] array for each index on the table + ** being updated. Fill in aRegIdx[] with a register number that will hold + ** the key for accessing each index. + */ + if( onError==OE_Replace ) bReplace = 1; + for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){ + int reg; + if( chngKey || hasFK>1 || pIdx==pPk + || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) + ){ + reg = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; + }else{ + reg = 0; + for(i=0; inKeyCol; i++){ + if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){ + reg = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; + if( onError==OE_Default && pIdx->onError==OE_Replace ){ + bReplace = 1; + } + break; + } + } + } + if( reg==0 ) aToOpen[nAllIdx+1] = 0; + aRegIdx[nAllIdx] = reg; + } + aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */ + if( bReplace ){ + /* If REPLACE conflict resolution might be invoked, open cursors on all + ** indexes in case they are needed to delete records. */ + memset(aToOpen, 1, nIdx+1); + } + + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); + + /* Allocate required registers. */ + if( !IsVirtual(pTab) ){ + /* For now, regRowSet and aRegIdx[nAllIdx] share the same register. + ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be + ** reallocated. aRegIdx[nAllIdx] is the register in which the main + ** table record is written. regRowSet holds the RowSet for the + ** two-pass update algorithm. */ + assert( aRegIdx[nAllIdx]==pParse->nMem ); + regRowSet = aRegIdx[nAllIdx]; + regOldRowid = regNewRowid = ++pParse->nMem; + if( chngPk || pTrigger || hasFK ){ + regOld = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + } + if( chngKey || pTrigger || hasFK ){ + regNewRowid = ++pParse->nMem; + } + regNew = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + } + + /* Start the view context. */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* If we are trying to update a view, realize that view into + ** an ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( nChangeFrom==0 && isView ){ + sqlite3MaterializeView(pParse, pTab, + pWhere, pOrderBy, pLimit, iDataCur + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + + /* Resolve the column names in all the expressions in the + ** WHERE clause. + */ + if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto update_cleanup; + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Virtual tables must be handled separately */ + if( IsVirtual(pTab) ){ + updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, + pWhere, onError); + goto update_cleanup; + } +#endif + + /* Jump to labelBreak to abandon further processing of this UPDATE */ + labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse); + + /* Not an UPSERT. Normal processing. Begin by + ** initialize the count of updated rows */ + if( (db->flags&SQLITE_CountRows)!=0 + && !pParse->pTriggerTab + && !pParse->nested + && !pParse->bReturning + && pUpsert==0 + ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + if( nChangeFrom==0 && HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); + iEph = pParse->nTab++; + addrOpen = sqlite3VdbeAddOp3(v, OP_OpenEphemeral, iEph, 0, regRowSet); + }else{ + assert( pPk!=0 || HasRowid(pTab) ); + nPk = pPk ? pPk->nKeyCol : 0; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + pParse->nMem += nChangeFrom; + regKey = ++pParse->nMem; + if( pUpsert==0 ){ + int nEphCol = nPk + nChangeFrom + (isView ? pTab->nCol : 0); + iEph = pParse->nTab++; + if( pPk ) sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); + addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nEphCol); + if( pPk ){ + KeyInfo *pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pPk); + if( pKeyInfo ){ + pKeyInfo->nAllField = nEphCol; + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + } + } + if( nChangeFrom ){ + updateFromSelect( + pParse, iEph, pPk, pChanges, pTabList, pWhere, pOrderBy, pLimit + ); +#ifndef SQLITE_OMIT_SUBQUERY + if( isView ) iDataCur = iEph; +#endif + } + } + } + + if( nChangeFrom ){ + sqlite3MultiWrite(pParse); + eOnePass = ONEPASS_OFF; + nKey = nPk; + regKey = iPk; + }else{ + if( pUpsert ){ + /* If this is an UPSERT, then all cursors have already been opened by + ** the outer INSERT and the data cursor should be pointing at the row + ** that is to be updated. So bypass the code that searches for the + ** row(s) to be updated. + */ + pWInfo = 0; + eOnePass = ONEPASS_SINGLE; + sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); + bFinishSeek = 0; + }else{ + /* Begin the database scan. + ** + ** Do not consider a single-pass strategy for a multi-row update if + ** there is anything that might disrupt the cursor being used to do + ** the UPDATE: + ** (1) This is a nested UPDATE + ** (2) There are triggers + ** (3) There are FOREIGN KEY constraints + ** (4) There are REPLACE conflict handlers + ** (5) There are subqueries in the WHERE clause + */ + flags = WHERE_ONEPASS_DESIRED; + if( !pParse->nested + && !pTrigger + && !hasFK + && !chngKey + && !bReplace + && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery)) + ){ + flags |= WHERE_ONEPASS_MULTIROW; + } + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); + if( pWInfo==0 ) goto update_cleanup; + + /* A one-pass strategy that might update more than one row may not + ** be used if any column of the index used for the scan is being + ** updated. Otherwise, if there is an index on "b", statements like + ** the following could create an infinite loop: + ** + ** UPDATE t1 SET b=b+1 WHERE b>? + ** + ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI + ** strategy that uses an index for which one or more columns are being + ** updated. */ + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + bFinishSeek = sqlite3WhereUsesDeferredSeek(pWInfo); + if( eOnePass!=ONEPASS_SINGLE ){ + sqlite3MultiWrite(pParse); + if( eOnePass==ONEPASS_MULTI ){ + int iCur = aiCurOnePass[1]; + if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ + eOnePass = ONEPASS_OFF; + } + assert( iCur!=iDataCur || !HasRowid(pTab) ); + } + } + } + + if( HasRowid(pTab) ){ + /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF + ** mode, write the rowid into the FIFO. In either of the one-pass modes, + ** leave it in register regOldRowid. */ + sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); + if( eOnePass==ONEPASS_OFF ){ + aRegIdx[nAllIdx] = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_Insert, iEph, regRowSet, regOldRowid); + }else{ + if( ALWAYS(addrOpen) ) sqlite3VdbeChangeToNoop(v, addrOpen); + } + }else{ + /* Read the PK of the current row into an array of registers. In + ** ONEPASS_OFF mode, serialize the array into a record and store it in + ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change + ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table + ** is not required) and leave the PK fields in the array of registers. */ + for(i=0; iaiColumn[i]>=0 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, + pPk->aiColumn[i], iPk+i); + } + if( eOnePass ){ + if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen); + nKey = nPk; + regKey = iPk; + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, + sqlite3IndexAffinityStr(db, pPk), nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); + } + } + } + + if( pUpsert==0 ){ + if( nChangeFrom==0 && eOnePass!=ONEPASS_MULTI ){ + sqlite3WhereEnd(pWInfo); + } + + if( !isView ){ + int addrOnce = 0; + int iNotUsed1 = 0; + int iNotUsed2 = 0; + + /* Open every index that needs updating. */ + if( eOnePass!=ONEPASS_OFF ){ + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; + } + + if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, + aToOpen, &iNotUsed1, &iNotUsed2); + if( addrOnce ){ + sqlite3VdbeJumpHereOrPopInst(v, addrOnce); + } + } + + /* Top of the update loop */ + if( eOnePass!=ONEPASS_OFF ){ + if( aiCurOnePass[0]!=iDataCur + && aiCurOnePass[1]!=iDataCur +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + && !isView +#endif + ){ + assert( pPk ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); + VdbeCoverage(v); + } + if( eOnePass!=ONEPASS_SINGLE ){ + labelContinue = sqlite3VdbeMakeLabel(pParse); + } + sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); + VdbeCoverageIf(v, pPk==0); + VdbeCoverageIf(v, pPk!=0); + }else if( pPk || nChangeFrom ){ + labelContinue = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + addrTop = sqlite3VdbeCurrentAddr(v); + if( nChangeFrom ){ + if( !isView ){ + if( pPk ){ + for(i=0; i=0 ); + if( nChangeFrom==0 ){ + sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iEph, iRowidExpr, regNewRowid); + } + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); + } + + /* Compute the old pre-UPDATE content of the row being changed, if that + ** information is needed */ + if( chngPk || hasFK || pTrigger ){ + u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); + oldmask |= sqlite3TriggerColmask(pParse, + pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError + ); + for(i=0; inCol; i++){ + u32 colFlags = pTab->aCol[i].colFlags; + k = sqlite3TableColumnToStorage(pTab, i) + regOld; + if( oldmask==0xffffffff + || (i<32 && (oldmask & MASKBIT32(i))!=0) + || (colFlags & COLFLAG_PRIMKEY)!=0 + ){ + testcase( oldmask!=0xffffffff && i==31 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + } + } + if( chngRowid==0 && pPk==0 ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); +#endif + sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); + } + } + + /* Populate the array of registers beginning at regNew with the new + ** row data. This array is used to check constants, create the new + ** table and index records, and as the values for any new.* references + ** made by triggers. + ** + ** If there are one or more BEFORE triggers, then do not populate the + ** registers associated with columns that are (a) not modified by + ** this UPDATE statement and (b) not accessed by new.* references. The + ** values for registers not modified by the UPDATE must be reloaded from + ** the database after the BEFORE triggers are fired anyway (as the trigger + ** may have modified them). So not loading those that are not going to + ** be used eliminates some redundant opcodes. + */ + newmask = sqlite3TriggerColmask( + pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError + ); + for(i=0, k=regNew; inCol; i++, k++){ + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + }else if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)!=0 ){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; + }else{ + j = aXRef[i]; + if( j>=0 ){ + if( nChangeFrom ){ + int nOff = (isView ? pTab->nCol : nPk); + assert( eOnePass==ONEPASS_OFF ); + sqlite3VdbeAddOp3(v, OP_Column, iEph, nOff+j, k); + }else{ + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, k); + } + }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ + /* This branch loads the value of a column that will not be changed + ** into a register. This is done if there are no BEFORE triggers, or + ** if there are one or more BEFORE triggers that use this value via + ** a new.* reference in a trigger program. + */ + testcase( i==31 ); + testcase( i==32 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + bFinishSeek = 0; + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + } + } + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + } +#endif + + /* Fire any BEFORE UPDATE triggers. This happens before constraints are + ** verified. One could argue that this is wrong. + */ + if( tmask&TRIGGER_BEFORE ){ + sqlite3TableAffinity(v, pTab, regNew); + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); + + if( !isView ){ + /* The row-trigger may have deleted the row being updated. In this + ** case, jump to the next row. No updates or AFTER triggers are + ** required. This behavior - what happens when the row being updated + ** is deleted or renamed by a BEFORE trigger - is left undefined in the + ** documentation. + */ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); + VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); + VdbeCoverage(v); + } + + /* After-BEFORE-trigger-reload-loop: + ** If it did not delete it, the BEFORE trigger may still have modified + ** some of the columns of the row being updated. Load the values for + ** all columns not modified by the update statement into their registers + ** in case this has happened. Only unmodified columns are reloaded. + ** The values computed for modified columns use the values before the + ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26) + ** for an example. + */ + for(i=0, k=regNew; inCol; i++, k++){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; + }else if( aXRef[i]<0 && i!=pTab->iPKey ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + } + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + } +#endif + } + } + + if( !isView ){ + /* Do constraint checks. */ + assert( regOldRowid>0 ); + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, + aXRef, 0); + + /* If REPLACE conflict handling may have been used, or if the PK of the + ** row is changing, then the GenerateConstraintChecks() above may have + ** moved cursor iDataCur. Reseek it. */ + if( bReplace || chngKey ){ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); + }else{ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); + } + VdbeCoverage(v); + } + + /* Do FK constraint checks. */ + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); + } + + /* Delete the index entries associated with the current record. */ + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); + + /* We must run the OP_FinishSeek opcode to resolve a prior + ** OP_DeferredSeek if there is any possibility that there have been + ** no OP_Column opcodes since the OP_DeferredSeek was issued. But + ** we want to avoid the OP_FinishSeek if possible, as running it + ** costs CPU cycles. */ + if( bFinishSeek ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur); + } + + /* If changing the rowid value, or if there are foreign key constraints + ** to process, delete the old record. Otherwise, add a noop OP_Delete + ** to invoke the pre-update hook. + ** + ** That (regNew==regnewRowid+1) is true is also important for the + ** pre-update hook. If the caller invokes preupdate_new(), the returned + ** value is copied from memory cell (regNewRowid+1+iCol), where iCol + ** is the column index supplied by the user. + */ + assert( regNew==regNewRowid+1 ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, + OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP), + regNewRowid + ); + if( eOnePass==ONEPASS_MULTI ){ + assert( hasFK==0 && chngKey==0 ); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + } + if( !pParse->nested ){ + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } +#else + if( hasFK>1 || chngKey ){ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); + } +#endif + + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); + } + + /* Insert the new index entries and the new record. */ + sqlite3CompleteInsertion( + pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, + OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), + 0, 0 + ); + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just updated. */ + if( hasFK ){ + sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); + } + } + + /* Increment the row counter + */ + if( regRowCount ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + if( pTrigger ){ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); + } + + /* Repeat the above with the next record to be updated, until + ** all record selected by the WHERE clause have been updated. + */ + if( eOnePass==ONEPASS_SINGLE ){ + /* Nothing to do at end-of-loop for a single-pass */ + }else if( eOnePass==ONEPASS_MULTI ){ + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3WhereEnd(pWInfo); + }else{ + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); + } + sqlite3VdbeResolveLabel(v, labelBreak); + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** Return the number of rows that were changed, if we are tracking + ** that information. + */ + if( regRowCount ){ + sqlite3CodeChangeCount(v, regRowCount, "rows updated"); + } + +update_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pChanges); + sqlite3ExprDelete(db, pWhere); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); +#endif + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Generate code for an UPDATE of a virtual table. +** +** There are two possible strategies - the default and the special +** "onepass" strategy. Onepass is only used if the virtual table +** implementation indicates that pWhere may match at most one row. +** +** The default strategy is to create an ephemeral table that contains +** for each row to be changed: +** +** (A) The original rowid of that row. +** (B) The revised rowid for the row. +** (C) The content of every column in the row. +** +** Then loop through the contents of this ephemeral table executing a +** VUpdate for each row. When finished, drop the ephemeral table. +** +** The "onepass" strategy does not use an ephemeral table. Instead, it +** stores the same values (A, B and C above) in a register array and +** makes a single invocation of VUpdate. +*/ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowid, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ +){ + Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ + int ephemTab; /* Table holding the result of the SELECT */ + int i; /* Loop counter */ + sqlite3 *db = pParse->db; /* Database connection */ + const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); + WhereInfo *pWInfo = 0; + int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ + int regArg; /* First register in VUpdate arg array */ + int regRec; /* Register in which to assemble record */ + int regRowid; /* Register for ephemeral table rowid */ + int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ + int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ + int eOnePass; /* True to use onepass strategy */ + int addr; /* Address of OP_OpenEphemeral */ + + /* Allocate nArg registers in which to gather the arguments for VUpdate. Then + ** create and open the ephemeral table in which the records created from + ** these arguments will be temporarily stored. */ + assert( v ); + ephemTab = pParse->nTab++; + addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg); + regArg = pParse->nMem + 1; + pParse->nMem += nArg; + if( pSrc->nSrc>1 ){ + Index *pPk = 0; + Expr *pRow; + ExprList *pList; + if( HasRowid(pTab) ){ + if( pRowid ){ + pRow = sqlite3ExprDup(db, pRowid, 0); + }else{ + pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0); + } + }else{ + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + if( aXRef[iPk]>=0 ){ + pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0); + }else{ + pRow = exprRowColumn(pParse, iPk); + } + } + pList = sqlite3ExprListAppend(pParse, 0, pRow); + + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ){ + pList = sqlite3ExprListAppend(pParse, pList, + sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) + ); + }else{ + Expr *pRowExpr = exprRowColumn(pParse, i); + if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG; + pList = sqlite3ExprListAppend(pParse, pList, pRowExpr); + } + } + + updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0); + sqlite3ExprListDelete(db, pList); + eOnePass = ONEPASS_OFF; + }else{ + regRec = ++pParse->nMem; + regRowid = ++pParse->nMem; + + /* Start scanning the virtual table */ + pWInfo = sqlite3WhereBegin( + pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0 + ); + if( pWInfo==0 ) return; + + /* Populate the argument registers. */ + for(i=0; inCol; i++){ + assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ); + if( aXRef[i]>=0 ){ + sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); + }else{ + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* For sqlite3_vtab_nochange() */ + } + } + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); + if( pRowid ){ + sqlite3ExprCode(pParse, pRowid, regArg+1); + }else{ + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); + } + }else{ + Index *pPk; /* PRIMARY KEY index */ + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1); + } + + eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); + + /* There is no ONEPASS_MULTI on virtual tables */ + assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); + + if( eOnePass ){ + /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded + ** above. */ + sqlite3VdbeChangeToNoop(v, addr); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + }else{ + /* Create a record from the argument register contents and insert it into + ** the ephemeral table. */ + sqlite3MultiWrite(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); +#if defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_NULL_TRIM) + /* Signal an assert() within OP_MakeRecord that it is allowed to + ** accept no-change records with serial_type 10 */ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); +#endif + sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); + } + } + + + if( eOnePass==ONEPASS_OFF ){ + /* End the virtual table scan */ + if( pSrc->nSrc==1 ){ + sqlite3WhereEnd(pWInfo); + } + + /* Begin scanning through the ephemeral table. */ + addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); + + /* Extract arguments from the current row of the ephemeral table and + ** invoke the VUpdate method. */ + for(i=0; ipNextUpsert; + sqlite3ExprListDelete(db, p->pUpsertTarget); + sqlite3ExprDelete(db, p->pUpsertTargetWhere); + sqlite3ExprListDelete(db, p->pUpsertSet); + sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p->pToFree); + sqlite3DbFree(db, p); + p = pNext; + }while( p ); +} +SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ) upsertDelete(db, p); +} + + +/* +** Duplicate an Upsert object. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ + if( p==0 ) return 0; + return sqlite3UpsertNew(db, + sqlite3ExprListDup(db, p->pUpsertTarget, 0), + sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), + sqlite3ExprListDup(db, p->pUpsertSet, 0), + sqlite3ExprDup(db, p->pUpsertWhere, 0), + sqlite3UpsertDup(db, p->pNextUpsert) + ); +} + +/* +** Create a new Upsert object. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertNew( + sqlite3 *db, /* Determines which memory allocator to use */ + ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ + Expr *pTargetWhere, /* Optional WHERE clause on the target */ + ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ + Expr *pWhere, /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNext /* Next ON CONFLICT clause in the list */ +){ + Upsert *pNew; + pNew = sqlite3DbMallocZero(db, sizeof(Upsert)); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pTarget); + sqlite3ExprDelete(db, pTargetWhere); + sqlite3ExprListDelete(db, pSet); + sqlite3ExprDelete(db, pWhere); + sqlite3UpsertDelete(db, pNext); + return 0; + }else{ + pNew->pUpsertTarget = pTarget; + pNew->pUpsertTargetWhere = pTargetWhere; + pNew->pUpsertSet = pSet; + pNew->pUpsertWhere = pWhere; + pNew->isDoUpdate = pSet!=0; + pNew->pNextUpsert = pNext; + } + return pNew; +} + +/* +** Analyze the ON CONFLICT clause described by pUpsert. Resolve all +** symbols in the conflict-target. +** +** Return SQLITE_OK if everything works, or an error code is something +** is wrong. +*/ +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( + Parse *pParse, /* The parsing context */ + SrcList *pTabList, /* Table into which we are inserting */ + Upsert *pUpsert, /* The ON CONFLICT clauses */ + Upsert *pAll /* Complete list of all ON CONFLICT clauses */ +){ + Table *pTab; /* That table into which we are inserting */ + int rc; /* Result code */ + int iCursor; /* Cursor used by pTab */ + Index *pIdx; /* One of the indexes of pTab */ + ExprList *pTarget; /* The conflict-target clause */ + Expr *pTerm; /* One term of the conflict-target clause */ + NameContext sNC; /* Context for resolving symbolic names */ + Expr sCol[2]; /* Index column converted into an Expr */ + int nClause = 0; /* Counter of ON CONFLICT clauses */ + + assert( pTabList->nSrc==1 ); + assert( pTabList->a[0].pTab!=0 ); + assert( pUpsert!=0 ); + assert( pUpsert->pUpsertTarget!=0 ); + + /* Resolve all symbolic names in the conflict-target clause, which + ** includes both the list of columns and the optional partial-index + ** WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + for(; pUpsert && pUpsert->pUpsertTarget; + pUpsert=pUpsert->pNextUpsert, nClause++){ + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc ) return rc; + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + if( rc ) return rc; + + /* Check to see if the conflict target matches the rowid. */ + pTab = pTabList->a[0].pTab; + pTarget = pUpsert->pUpsertTarget; + iCursor = pTabList->a[0].iCursor; + if( HasRowid(pTab) + && pTarget->nExpr==1 + && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN + && pTerm->iColumn==XN_ROWID + ){ + /* The conflict-target is the rowid of the primary table */ + assert( pUpsert->pUpsertIdx==0 ); + continue; + } + + /* Initialize sCol[0..1] to be an expression parse tree for a + ** single column of an index. The sCol[0] node will be the TK_COLLATE + ** operator and sCol[1] will be the TK_COLUMN operator. Code below + ** will populate the specific collation and column number values + ** prior to comparing against the conflict-target expression. + */ + memset(sCol, 0, sizeof(sCol)); + sCol[0].op = TK_COLLATE; + sCol[0].pLeft = &sCol[1]; + sCol[1].op = TK_COLUMN; + sCol[1].iTable = pTabList->a[0].iCursor; + + /* Check for matches against other indexes */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii, jj, nn; + if( !IsUniqueIndex(pIdx) ) continue; + if( pTarget->nExpr!=pIdx->nKeyCol ) continue; + if( pIdx->pPartIdxWhere ){ + if( pUpsert->pUpsertTargetWhere==0 ) continue; + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + pIdx->pPartIdxWhere, iCursor)!=0 ){ + continue; + } + } + nn = pIdx->nKeyCol; + for(ii=0; iiazColl[ii]; + if( pIdx->aiColumn[ii]==XN_EXPR ){ + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->nExpr>ii ); + assert( pIdx->bHasExpr ); + pExpr = pIdx->aColExpr->a[ii].pExpr; + if( pExpr->op!=TK_COLLATE ){ + sCol[0].pLeft = pExpr; + pExpr = &sCol[0]; + } + }else{ + sCol[0].pLeft = &sCol[1]; + sCol[1].iColumn = pIdx->aiColumn[ii]; + pExpr = &sCol[0]; + } + for(jj=0; jja[jj].pExpr,pExpr,iCursor)<2 ){ + break; /* Column ii of the index matches column jj of target */ + } + } + if( jj>=nn ){ + /* The target contains no match for column jj of the index */ + break; + } + } + if( iipUpsertIdx = pIdx; + if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){ + /* Really this should be an error. The isDup ON CONFLICT clause will + ** never fire. But this problem was not discovered until three years + ** after multi-CONFLICT upsert was added, and so we silently ignore + ** the problem to prevent breaking applications that might actually + ** have redundant ON CONFLICT clauses. */ + pUpsert->isDup = 1; + } + break; + } + if( pUpsert->pUpsertIdx==0 ){ + char zWhich[16]; + if( nClause==0 && pUpsert->pNextUpsert==0 ){ + zWhich[0] = 0; + }else{ + sqlite3_snprintf(sizeof(zWhich),zWhich,"%r ", nClause+1); + } + sqlite3ErrorMsg(pParse, "%sON CONFLICT clause does not match any " + "PRIMARY KEY or UNIQUE constraint", zWhich); + return SQLITE_ERROR; + } + } + return SQLITE_OK; +} + +/* +** Return true if pUpsert is the last ON CONFLICT clause with a +** conflict target, or if pUpsert is followed by another ON CONFLICT +** clause that targets the INTEGER PRIMARY KEY. +*/ +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ + Upsert *pNext; + if( NEVER(pUpsert==0) ) return 0; + pNext = pUpsert->pNextUpsert; + while( 1 /*exit-by-return*/ ){ + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + if( !pNext->isDup ) return 0; + pNext = pNext->pNextUpsert; + } + return 0; +} + +/* +** Given the list of ON CONFLICT clauses described by pUpsert, and +** a particular index pIdx, return a pointer to the particular ON CONFLICT +** clause that applies to the index. Or, if the index is not subject to +** any ON CONFLICT clause, return NULL. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){ + while( + pUpsert + && pUpsert->pUpsertTarget!=0 + && pUpsert->pUpsertIdx!=pIdx + ){ + pUpsert = pUpsert->pNextUpsert; + } + return pUpsert; +} + +/* +** Generate bytecode that does an UPDATE as part of an upsert. +** +** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK. +** In this case parameter iCur is a cursor open on the table b-tree that +** currently points to the conflicting table row. Otherwise, if pIdx +** is not NULL, then pIdx is the constraint that failed and iCur is a +** cursor points to the conflicting row. +*/ +SQLITE_PRIVATE void sqlite3UpsertDoUpdate( + Parse *pParse, /* The parsing and code-generating context */ + Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */ + Table *pTab, /* The table being updated */ + Index *pIdx, /* The UNIQUE constraint that failed */ + int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ +){ + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + SrcList *pSrc; /* FROM clause for the UPDATE */ + int iDataCur; + int i; + Upsert *pTop = pUpsert; + + assert( v!=0 ); + assert( pUpsert!=0 ); + iDataCur = pUpsert->iDataCur; + pUpsert = sqlite3UpsertOfIndex(pTop, pIdx); + VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); + if( pIdx && iCur!=iDataCur ){ + if( HasRowid(pTab) ){ + int regRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regRowid); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk = pParse->nMem+1; + pParse->nMem += nPk; + for(i=0; iaiColumn[i]>=0 ); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); + VdbeComment((v, "%s.%s", pIdx->zName, + pTab->aCol[pPk->aiColumn[i]].zCnName)); + } + sqlite3VdbeVerifyAbortable(v, OE_Abort); + i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); + VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, + "corrupt database", P4_STATIC); + sqlite3MayAbort(pParse); + sqlite3VdbeJumpHere(v, i); + } + } + /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does. + ** So we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0); + /* excluded.* columns of type REAL need to be converted to a hard real */ + for(i=0; inCol; i++){ + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); + } + } + sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), + sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert); + VdbeNoopComment((v, "End DO UPDATE of UPSERT")); +} + +#endif /* SQLITE_OMIT_UPSERT */ + +/************** End of upsert.c **********************************************/ +/************** Begin file vacuum.c ******************************************/ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the VACUUM command. +** +** Most of the code in this file may be omitted by defining the +** SQLITE_OMIT_VACUUM macro. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) + +/* +** Execute zSql on database db. +** +** If zSql returns rows, then each row will have exactly one +** column. (This will only happen if zSql begins with "SELECT".) +** Take each row of result and call execSql() again recursively. +** +** The execSqlF() routine does the same thing, except it accepts +** a format string as its third argument +*/ +static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + sqlite3_stmt *pStmt; + int rc; + + /* printf("SQL: [%s]\n", zSql); fflush(stdout); */ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); + assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); + /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX, + ** or INSERT. Historically there have been attacks that first + ** corrupt the sqlite_schema.sql field with other kinds of statements + ** then run VACUUM to get those statements to execute at inappropriate + ** times. */ + if( zSubSql + && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0) + ){ + rc = execSql(db, pzErrMsg, zSubSql); + if( rc!=SQLITE_OK ) break; + } + } + assert( rc!=SQLITE_ROW ); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + if( rc ){ + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); + } + (void)sqlite3_finalize(pStmt); + return rc; +} +static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ + char *z; + va_list ap; + int rc; + va_start(ap, zSql); + z = sqlite3VMPrintf(db, zSql, ap); + va_end(ap); + if( z==0 ) return SQLITE_NOMEM; + rc = execSql(db, pzErrMsg, z); + sqlite3DbFree(db, z); + return rc; +} + +/* +** The VACUUM command is used to clean up the database, +** collapse free space, etc. It is modelled after the VACUUM command +** in PostgreSQL. The VACUUM command works as follows: +** +** (1) Create a new transient database file +** (2) Copy all content from the database being vacuumed into +** the new transient database file +** (3) Copy content from the transient database back into the +** original database. +** +** The transient database requires temporary disk space approximately +** equal to the size of the original database. The copy operation of +** step (3) requires additional temporary disk space approximately equal +** to the size of the original database for the rollback journal. +** Hence, temporary disk space that is approximately 2x the size of the +** original database is required. Every page of the database is written +** approximately 3 times: Once for step (2) and twice for step (3). +** Two writes per page are required in step (3) because the original +** database content must be written into the rollback journal prior to +** overwriting the database with the vacuumed content. +** +** Only 1x temporary space and only 1x writes would be required if +** the copy of step (3) were replaced by deleting the original database +** and renaming the transient database as the original. But that will +** not work if other processes are attached to the original database. +** And a power loss in between deleting the original and renaming the +** transient would cause the database file to appear to be deleted +** following reboot. +*/ +SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ + Vdbe *v = sqlite3GetVdbe(pParse); + int iDb = 0; + if( v==0 ) goto build_vacuum_end; + if( pParse->nErr ) goto build_vacuum_end; + if( pNm ){ +#ifndef SQLITE_BUG_COMPATIBLE_20160819 + /* Default behavior: Report an error if the argument to VACUUM is + ** not recognized */ + iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); + if( iDb<0 ) goto build_vacuum_end; +#else + /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments + ** to VACUUM are silently ignored. This is a back-out of a bug fix that + ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270). + ** The buggy behavior is required for binary compatibility with some + ** legacy applications. */ + iDb = sqlite3FindDb(pParse->db, pNm); + if( iDb<0 ) iDb = 0; +#endif + } + if( iDb!=1 ){ + int iIntoReg = 0; + if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){ + iIntoReg = ++pParse->nMem; + sqlite3ExprCode(pParse, pInto, iIntoReg); + } + sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg); + sqlite3VdbeUsesBtree(v, iDb); + } +build_vacuum_end: + sqlite3ExprDelete(pParse->db, pInto); + return; +} + +/* +** This routine implements the OP_Vacuum opcode of the VDBE. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( + char **pzErrMsg, /* Write error message here */ + sqlite3 *db, /* Database connection */ + int iDb, /* Which attached DB to vacuum */ + sqlite3_value *pOut /* Write results here, if not NULL. VACUUM INTO */ +){ + int rc = SQLITE_OK; /* Return code from service routines */ + Btree *pMain; /* The database being vacuumed */ + Btree *pTemp; /* The temporary database we vacuum into */ + u32 saved_mDbFlags; /* Saved value of db->mDbFlags */ + u64 saved_flags; /* Saved value of db->flags */ + i64 saved_nChange; /* Saved value of db->nChange */ + i64 saved_nTotalChange; /* Saved value of db->nTotalChange */ + u32 saved_openFlags; /* Saved value of db->openFlags */ + u8 saved_mTrace; /* Saved trace settings */ + Db *pDb = 0; /* Database to detach at end of vacuum */ + int isMemDb; /* True if vacuuming a :memory: database */ + int nRes; /* Bytes of reserved space at the end of each page */ + int nDb; /* Number of attached databases */ + const char *zDbMain; /* Schema name of database to vacuum */ + const char *zOut; /* Name of output file */ + u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + + if( !db->autoCommit ){ + sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); + return SQLITE_ERROR; /* IMP: R-12218-18073 */ + } + if( db->nVdbeActive>1 ){ + sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); + return SQLITE_ERROR; /* IMP: R-15610-35227 */ + } + saved_openFlags = db->openFlags; + if( pOut ){ + if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){ + sqlite3SetString(pzErrMsg, db, "non-text filename"); + return SQLITE_ERROR; + } + zOut = (const char*)sqlite3_value_text(pOut); + db->openFlags &= ~SQLITE_OPEN_READONLY; + db->openFlags |= SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; + }else{ + zOut = ""; + } + + /* Save the current value of the database flags so that it can be + ** restored before returning. Then set the writable-schema flag, and + ** disable CHECK and foreign key constraints. */ + saved_flags = db->flags; + saved_mDbFlags = db->mDbFlags; + saved_nChange = db->nChange; + saved_nTotalChange = db->nTotalChange; + saved_mTrace = db->mTrace; + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; + db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; + db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder + | SQLITE_Defensive | SQLITE_CountRows); + db->mTrace = 0; + + zDbMain = db->aDb[iDb].zDbSName; + pMain = db->aDb[iDb].pBt; + isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); + + /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + ** can be set to 'off' for this file, as it is not recovered if a crash + ** occurs anyway. The integrity of the database is maintained by a + ** (possibly synchronous) transaction opened on the main database before + ** sqlite3BtreeCopyFile() is called. + ** + ** An optimization would be to use a non-journaled pager. + ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** that actually made the VACUUM run slower. Very little journalling + ** actually occurs when doing a vacuum since the vacuum_db is initially + ** empty. Only the journal header is written. Apparently it takes more + ** time to parse and run the PRAGMA to turn journalling off than it does + ** to write the journal header file. + */ + nDb = db->nDb; + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); + db->openFlags = saved_openFlags; + if( rc!=SQLITE_OK ) goto end_of_vacuum; + assert( (db->nDb-1)==nDb ); + pDb = &db->aDb[nDb]; + assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + pTemp = pDb->pBt; + if( pOut ){ + sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); + i64 sz = 0; + if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ + rc = SQLITE_ERROR; + sqlite3SetString(pzErrMsg, db, "output file already exists"); + goto end_of_vacuum; + } + db->mDbFlags |= DBFLAG_VacuumInto; + + /* For a VACUUM INTO, the pager-flags are set to the same values as + ** they are for the database being vacuumed, except that PAGER_CACHESPILL + ** is always set. */ + pgflags = db->aDb[iDb].safety_level | (db->flags & PAGER_FLAGS_MASK); + } + nRes = sqlite3BtreeGetRequestedReserve(pMain); + + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); + sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); + sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL); + + /* Begin a transaction and take an exclusive lock on the main database + ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, + ** to ensure that we do not try to change the page-size on a WAL database. + */ + rc = execSql(db, pzErrMsg, "BEGIN"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Do not attempt to change the page size for a WAL database */ + if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) + ==PAGER_JOURNALMODE_WAL + && pOut==0 + ){ + db->nextPagesize = 0; + } + + if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0) + || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) + || NEVER(db->mallocFailed) + ){ + rc = SQLITE_NOMEM_BKPT; + goto end_of_vacuum; + } + +#ifndef SQLITE_OMIT_AUTOVACUUM + sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : + sqlite3BtreeGetAutoVacuum(pMain)); +#endif + + /* Query the schema of the main database. Create a mirror schema + ** in the temporary database. + */ + db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */ + rc = execSqlF(db, pzErrMsg, + "SELECT sql FROM \"%w\".sqlite_schema" + " WHERE type='table'AND name<>'sqlite_sequence'" + " AND coalesce(rootpage,1)>0", + zDbMain + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execSqlF(db, pzErrMsg, + "SELECT sql FROM \"%w\".sqlite_schema" + " WHERE type='index'", + zDbMain + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + db->init.iDb = 0; + + /* Loop through the tables in the main database. For each, do + ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy + ** the contents to the temporary database. + */ + rc = execSqlF(db, pzErrMsg, + "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "||' SELECT*FROM\"%w\".'||quote(name)" + "FROM vacuum_db.sqlite_schema " + "WHERE type='table'AND coalesce(rootpage,1)>0", + zDbMain + ); + assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); + db->mDbFlags &= ~DBFLAG_Vacuum; + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Copy the triggers, views, and virtual tables from the main database + ** over to the temporary database. None of these objects has any + ** associated storage, so all we have to do is copy their entries + ** from the schema table. + */ + rc = execSqlF(db, pzErrMsg, + "INSERT INTO vacuum_db.sqlite_schema" + " SELECT*FROM \"%w\".sqlite_schema" + " WHERE type IN('view','trigger')" + " OR(type='table'AND rootpage=0)", + zDbMain + ); + if( rc ) goto end_of_vacuum; + + /* At this point, there is a write transaction open on both the + ** vacuum database and the main database. Assuming no error occurs, + ** both transactions are closed by this block - the main database + ** transaction by sqlite3BtreeCopyFile() and the other by an explicit + ** call to sqlite3BtreeCommit(). + */ + { + u32 meta; + int i; + + /* This array determines which meta meta values are preserved in the + ** vacuum. Even entries are the meta value number and odd entries + ** are an increment to apply to the meta value after the vacuum. + ** The increment is used to increase the schema cookie so that other + ** connections to the same database will know to reread the schema. + */ + static const unsigned char aCopy[] = { + BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */ + BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */ + BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */ + BTREE_USER_VERSION, 0, /* Preserve the user version */ + BTREE_APPLICATION_ID, 0, /* Preserve the application id */ + }; + + assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) ); + assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) ); + + /* Copy Btree meta values */ + for(i=0; iflags */ + db->init.iDb = 0; + db->mDbFlags = saved_mDbFlags; + db->flags = saved_flags; + db->nChange = saved_nChange; + db->nTotalChange = saved_nTotalChange; + db->mTrace = saved_mTrace; + sqlite3BtreeSetPageSize(pMain, -1, 0, 1); + + /* Currently there is an SQL level transaction open on the vacuum + ** database. No locks are held on any other files (since the main file + ** was committed at the btree level). So it safe to end the transaction + ** by manually setting the autoCommit flag to true and detaching the + ** vacuum database. The vacuum_db journal file is deleted when the pager + ** is closed by the DETACH. + */ + db->autoCommit = 1; + + if( pDb ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + } + + /* This both clears the schemas and reduces the size of the db->aDb[] + ** array. */ + sqlite3ResetAllSchemasOfConnection(db); + + return rc; +} + +#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ + +/************** End of vacuum.c **********************************************/ +/************** Begin file vtab.c ********************************************/ +/* +** 2006 June 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to help implement virtual tables. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* #include "sqliteInt.h" */ + +/* +** Before a virtual table xCreate() or xConnect() method is invoked, the +** sqlite3.pVtabCtx member variable is set to point to an instance of +** this struct allocated on the stack. It is used by the implementation of +** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which +** are invoked only from within xCreate and xConnect methods. +*/ +struct VtabCtx { + VTable *pVTable; /* The virtual table being constructed */ + Table *pTab; /* The Table object to which the virtual table belongs */ + VtabCtx *pPrior; /* Parent context (if any) */ + int bDeclared; /* True after sqlite3_declare_vtab() is called */ +}; + +/* +** Construct and install a Module object for a virtual table. When this +** routine is called, it is guaranteed that all appropriate locks are held +** and the module is not already part of the connection. +** +** If there already exists a module with zName, replace it with the new one. +** If pModule==0, then delete the module zName if it exists. +*/ +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + Module *pMod; + Module *pDel; + char *zCopy; + if( pModule==0 ){ + zCopy = (char*)zName; + pMod = 0; + }else{ + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); + if( pMod==0 ){ + sqlite3OomFault(db); + return 0; + } + zCopy = (char *)(&pMod[1]); + memcpy(zCopy, zName, nName+1); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod->xDestroy = xDestroy; + pMod->pEpoTab = 0; + pMod->nRefModule = 1; + } + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + if( pDel ){ + if( pDel==pMod ){ + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); + pMod = 0; + }else{ + sqlite3VtabEponymousTableClear(db, pDel); + sqlite3VtabModuleUnref(db, pDel); + } + } + return pMod; +} + +/* +** The actual function that does the work of creating a new module. +** This function implements the sqlite3_create_module() and +** sqlite3_create_module_v2() interfaces. +*/ +static int createModule( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + int rc = SQLITE_OK; + + sqlite3_mutex_enter(db->mutex); + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); + rc = sqlite3ApiExit(db, rc); + if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); + sqlite3_mutex_leave(db->mutex); + return rc; +} + + +/* +** External API function used to create a new virtual-table module. +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux /* Context pointer for xCreate/xConnect */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pAux, 0); +} + +/* +** External API function used to create a new virtual-table module. +*/ +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pAux, xDestroy); +} + +/* +** External API to drop all virtual-table modules, except those named +** on the azNames list. +*/ +SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ + HashElem *pThis, *pNext; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ + Module *pMod = (Module*)sqliteHashData(pThis); + pNext = sqliteHashNext(pThis); + if( azNames ){ + int ii; + for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){} + if( azNames[ii]!=0 ) continue; + } + createModule(db, pMod->zName, 0, 0, 0); + } + return SQLITE_OK; +} + +/* +** Decrement the reference count on a Module object. Destroy the +** module when the reference count reaches zero. +*/ +SQLITE_PRIVATE void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){ + assert( pMod->nRefModule>0 ); + pMod->nRefModule--; + if( pMod->nRefModule==0 ){ + if( pMod->xDestroy ){ + pMod->xDestroy(pMod->pAux); + } + assert( pMod->pEpoTab==0 ); + sqlite3DbFree(db, pMod); + } +} + +/* +** Lock the virtual table so that it cannot be disconnected. +** Locks nest. Every lock should have a corresponding unlock. +** If an unlock is omitted, resources leaks will occur. +** +** If a disconnect is attempted while a virtual table is locked, +** the disconnect is deferred until all locks have been removed. +*/ +SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ + pVTab->nRef++; +} + + +/* +** pTab is a pointer to a Table structure representing a virtual-table. +** Return a pointer to the VTable object used by connection db to access +** this virtual-table, if one has been created, or NULL otherwise. +*/ +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ + VTable *pVtab; + assert( IsVirtual(pTab) ); + for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + return pVtab; +} + +/* +** Decrement the ref-count on a virtual table object. When the ref-count +** reaches zero, call the xDisconnect() method to delete the object. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ + sqlite3 *db = pVTab->db; + + assert( db ); + assert( pVTab->nRef>0 ); + assert( db->eOpenState==SQLITE_STATE_OPEN + || db->eOpenState==SQLITE_STATE_ZOMBIE ); + + pVTab->nRef--; + if( pVTab->nRef==0 ){ + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + p->pModule->xDisconnect(p); + } + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); + sqlite3DbFree(db, pVTab); + } +} + +/* +** Table p is a virtual table. This function moves all elements in the +** p->u.vtab.p list to the sqlite3.pDisconnect lists of their associated +** database connections to be disconnected at the next opportunity. +** Except, if argument db is not NULL, then the entry associated with +** connection db is left in the p->u.vtab.p list. +*/ +static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ + VTable *pRet = 0; + VTable *pVTable; + + assert( IsVirtual(p) ); + pVTable = p->u.vtab.p; + p->u.vtab.p = 0; + + /* Assert that the mutex (if any) associated with the BtShared database + ** that contains table p is held by the caller. See header comments + ** above function sqlite3VtabUnlockList() for an explanation of why + ** this makes it safe to access the sqlite3.pDisconnect list of any + ** database connection that may have an entry in the p->u.vtab.p list. + */ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + + while( pVTable ){ + sqlite3 *db2 = pVTable->db; + VTable *pNext = pVTable->pNext; + assert( db2 ); + if( db2==db ){ + pRet = pVTable; + p->u.vtab.p = pRet; + pRet->pNext = 0; + }else{ + pVTable->pNext = db2->pDisconnect; + db2->pDisconnect = pVTable; + } + pVTable = pNext; + } + + assert( !db || pRet ); + return pRet; +} + +/* +** Table *p is a virtual table. This function removes the VTable object +** for table *p associated with database connection db from the linked +** list in p->pVTab. It also decrements the VTable ref count. This is +** used when closing database connection db to free all of its VTable +** objects without disturbing the rest of the Schema object (which may +** be being used by other shared-cache connections). +*/ +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ + VTable **ppVTab; + + assert( IsVirtual(p) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + for(ppVTab=&p->u.vtab.p; *ppVTab; ppVTab=&(*ppVTab)->pNext){ + if( (*ppVTab)->db==db ){ + VTable *pVTab = *ppVTab; + *ppVTab = pVTab->pNext; + sqlite3VtabUnlock(pVTab); + break; + } + } +} + + +/* +** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. +** +** This function may only be called when the mutexes associated with all +** shared b-tree databases opened using connection db are held by the +** caller. This is done to protect the sqlite3.pDisconnect list. The +** sqlite3.pDisconnect list is accessed only as follows: +** +** 1) By this function. In this case, all BtShared mutexes and the mutex +** associated with the database handle itself must be held. +** +** 2) By function vtabDisconnectAll(), when it adds a VTable entry to +** the sqlite3.pDisconnect list. In this case either the BtShared mutex +** associated with the database the virtual table is stored in is held +** or, if the virtual table is stored in a non-sharable database, then +** the database handle mutex is held. +** +** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously +** by multiple threads. It is thread-safe. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ + VTable *p = db->pDisconnect; + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + if( p ){ + db->pDisconnect = 0; + do { + VTable *pNext = p->pNext; + sqlite3VtabUnlock(p); + p = pNext; + }while( p ); + } +} + +/* +** Clear any and all virtual-table information from the Table record. +** This routine is called, for example, just before deleting the Table +** record. +** +** Since it is a virtual-table, the Table structure contains a pointer +** to the head of a linked list of VTable structures. Each VTable +** structure is associated with a single sqlite3* user of the schema. +** The reference count of the VTable structure associated with database +** connection db is decremented immediately (which may lead to the +** structure being xDisconnected and free). Any other VTable structures +** in the list are moved to the sqlite3.pDisconnect list of the associated +** database connection. +*/ +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ + assert( IsVirtual(p) ); + assert( db!=0 ); + if( db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); + if( p->u.vtab.azArg ){ + int i; + for(i=0; iu.vtab.nArg; i++){ + if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]); + } + sqlite3DbFree(db, p->u.vtab.azArg); + } +} + +/* +** Add a new module argument to pTable->u.vtab.azArg[]. +** The string is not copied - the pointer is stored. The +** string will be freed automatically when the table is +** deleted. +*/ +static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ + sqlite3_int64 nBytes; + char **azModuleArg; + sqlite3 *db = pParse->db; + + assert( IsVirtual(pTable) ); + nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg); + if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); + } + azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes); + if( azModuleArg==0 ){ + sqlite3DbFree(db, zArg); + }else{ + int i = pTable->u.vtab.nArg++; + azModuleArg[i] = zArg; + azModuleArg[i+1] = 0; + pTable->u.vtab.azArg = azModuleArg; + } +} + +/* +** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE +** statement. The module name has been parsed, but the optional list +** of parameters that follow the module name are still pending. +*/ +SQLITE_PRIVATE void sqlite3VtabBeginParse( + Parse *pParse, /* Parsing context */ + Token *pName1, /* Name of new table, or database name */ + Token *pName2, /* Name of new table or NULL */ + Token *pModuleName, /* Name of the module for the virtual table */ + int ifNotExists /* No error if the table already exists */ +){ + Table *pTable; /* The new virtual table */ + sqlite3 *db; /* Database connection */ + + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); + pTable = pParse->pNewTable; + if( pTable==0 ) return; + assert( 0==pTable->pIndex ); + pTable->eTabType = TABTYP_VTAB; + + db = pParse->db; + + assert( pTable->u.vtab.nArg==0 ); + addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName)); + addModuleArgument(pParse, pTable, 0); + addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName)); + assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) + || (pParse->sNameToken.z==pName1->z && pName2->z==0) + ); + pParse->sNameToken.n = (int)( + &pModuleName->z[pModuleName->n] - pParse->sNameToken.z + ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Creating a virtual table invokes the authorization callback twice. + ** The first invocation, to obtain permission to INSERT a row into the + ** sqlite_schema table, has already been made by sqlite3StartTable(). + ** The second call, to obtain permission to create the table, is made now. + */ + if( pTable->u.vtab.azArg ){ + int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); + assert( iDb>=0 ); /* The database the table is being created in */ + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + pTable->u.vtab.azArg[0], pParse->db->aDb[iDb].zDbSName); + } +#endif +} + +/* +** This routine takes the module argument that has been accumulating +** in pParse->zArg[] and appends it to the list of arguments on the +** virtual table currently under construction in pParse->pTable. +*/ +static void addArgumentToVtab(Parse *pParse){ + if( pParse->sArg.z && pParse->pNewTable ){ + const char *z = (const char*)pParse->sArg.z; + int n = pParse->sArg.n; + sqlite3 *db = pParse->db; + addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); + } +} + +/* +** The parser calls this routine after the CREATE VIRTUAL TABLE statement +** has been completely parsed. +*/ +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ + Table *pTab = pParse->pNewTable; /* The table being constructed */ + sqlite3 *db = pParse->db; /* The database connection */ + + if( pTab==0 ) return; + assert( IsVirtual(pTab) ); + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + if( pTab->u.vtab.nArg<1 ) return; + + /* If the CREATE VIRTUAL TABLE statement is being entered for the + ** first time (in other words if the virtual table is actually being + ** created now instead of just being read out of sqlite_schema) then + ** do additional initialization work and store the statement text + ** in the sqlite_schema table. + */ + if( !db->init.busy ){ + char *zStmt; + char *zWhere; + int iDb; + int iReg; + Vdbe *v; + + sqlite3MayAbort(pParse); + + /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ + if( pEnd ){ + pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n; + } + zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); + + /* A slot for the record has already been allocated in the + ** schema table. We just need to update that slot with all + ** the information we've collected. + ** + ** The VM register number pParse->regRowid holds the rowid of an + ** entry in the sqlite_schema table that was created for this vtab + ** by sqlite3StartTable(). + */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE " " + "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " + "WHERE rowid=#%d", + db->aDb[iDb].zDbSName, + pTab->zName, + pTab->zName, + zStmt, + pParse->regRowid + ); + v = sqlite3GetVdbe(pParse); + sqlite3ChangeCookie(pParse, iDb); + + sqlite3VdbeAddOp0(v, OP_Expire); + zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0); + sqlite3DbFree(db, zStmt); + + iReg = ++pParse->nMem; + sqlite3VdbeLoadString(v, iReg, pTab->zName); + sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); + }else{ + /* If we are rereading the sqlite_schema table create the in-memory + ** record of the table. */ + Table *pOld; + Schema *pSchema = pTab->pSchema; + const char *zName = pTab->zName; + assert( zName!=0 ); + sqlite3MarkAllShadowTablesOf(db, pTab); + pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); + if( pOld ){ + sqlite3OomFault(db); + assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ + return; + } + pParse->pNewTable = 0; + } +} + +/* +** The parser calls this routine when it sees the first token +** of an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){ + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + pParse->sArg.n = 0; +} + +/* +** The parser calls this routine for each token after the first token +** in an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ + Token *pArg = &pParse->sArg; + if( pArg->z==0 ){ + pArg->z = p->z; + pArg->n = p->n; + }else{ + assert(pArg->z <= p->z); + pArg->n = (int)(&p->z[p->n] - pArg->z); + } +} + +/* +** Invoke a virtual table constructor (either xCreate or xConnect). The +** pointer to the function to invoke is passed as the fourth parameter +** to this procedure. +*/ +static int vtabCallConstructor( + sqlite3 *db, + Table *pTab, + Module *pMod, + int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), + char **pzErr +){ + VtabCtx sCtx; + VTable *pVTable; + int rc; + const char *const*azArg; + int nArg = pTab->u.vtab.nArg; + char *zErr = 0; + char *zModuleName; + int iDb; + VtabCtx *pCtx; + + assert( IsVirtual(pTab) ); + azArg = (const char *const*)pTab->u.vtab.azArg; + + /* Check that the virtual-table is not already being initialized */ + for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ + if( pCtx->pTab==pTab ){ + *pzErr = sqlite3MPrintf(db, + "vtable constructor called recursively: %s", pTab->zName + ); + return SQLITE_LOCKED; + } + } + + zModuleName = sqlite3DbStrDup(db, pTab->zName); + if( !zModuleName ){ + return SQLITE_NOMEM_BKPT; + } + + pVTable = sqlite3MallocZero(sizeof(VTable)); + if( !pVTable ){ + sqlite3OomFault(db); + sqlite3DbFree(db, zModuleName); + return SQLITE_NOMEM_BKPT; + } + pVTable->db = db; + pVTable->pMod = pMod; + pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pTab->u.vtab.azArg[1] = db->aDb[iDb].zDbSName; + + /* Invoke the virtual table constructor */ + assert( &db->pVtabCtx ); + assert( xConstruct ); + sCtx.pTab = pTab; + sCtx.pVTable = pVTable; + sCtx.pPrior = db->pVtabCtx; + sCtx.bDeclared = 0; + db->pVtabCtx = &sCtx; + pTab->nTabRef++; + rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + sqlite3DeleteTable(db, pTab); + db->pVtabCtx = sCtx.pPrior; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + assert( sCtx.pTab==pTab ); + + if( SQLITE_OK!=rc ){ + if( zErr==0 ){ + *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); + }else { + *pzErr = sqlite3MPrintf(db, "%s", zErr); + sqlite3_free(zErr); + } + sqlite3DbFree(db, pVTable); + }else if( ALWAYS(pVTable->pVtab) ){ + /* Justification of ALWAYS(): A correct vtab constructor must allocate + ** the sqlite3_vtab object if successful. */ + memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); + pVTable->pVtab->pModule = pMod->pModule; + pMod->nRefModule++; + pVTable->nRef = 1; + if( sCtx.bDeclared==0 ){ + const char *zFormat = "vtable constructor did not declare schema: %s"; + *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); + sqlite3VtabUnlock(pVTable); + rc = SQLITE_ERROR; + }else{ + int iCol; + u16 oooHidden = 0; + /* If everything went according to plan, link the new VTable structure + ** into the linked list headed by pTab->u.vtab.p. Then loop through the + ** columns of the table to see if any of them contain the token "hidden". + ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from + ** the type string. */ + pVTable->pNext = pTab->u.vtab.p; + pTab->u.vtab.p = pVTable; + + for(iCol=0; iColnCol; iCol++){ + char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); + int nType; + int i = 0; + nType = sqlite3Strlen30(zType); + for(i=0; i0 ){ + assert(zType[i-1]==' '); + zType[i-1] = '\0'; + } + pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + pTab->tabFlags |= TF_HasHidden; + oooHidden = TF_OOOHidden; + }else{ + pTab->tabFlags |= oooHidden; + } + } + } + } + + sqlite3DbFree(db, zModuleName); + return rc; +} + +/* +** This function is invoked by the parser to call the xConnect() method +** of the virtual table pTab. If an error occurs, an error code is returned +** and an error left in pParse. +** +** This call is a no-op if table pTab is not a virtual table. +*/ +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ + sqlite3 *db = pParse->db; + const char *zMod; + Module *pMod; + int rc; + + assert( pTab ); + assert( IsVirtual(pTab) ); + if( sqlite3GetVTable(db, pTab) ){ + return SQLITE_OK; + } + + /* Locate the required virtual table module */ + zMod = pTab->u.vtab.azArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); + + if( !pMod ){ + const char *zModule = pTab->u.vtab.azArg[0]; + sqlite3ErrorMsg(pParse, "no such module: %s", zModule); + rc = SQLITE_ERROR; + }else{ + char *zErr = 0; + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + pParse->rc = rc; + } + sqlite3DbFree(db, zErr); + } + + return rc; +} +/* +** Grow the db->aVTrans[] array so that there is room for at least one +** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. +*/ +static int growVTrans(sqlite3 *db){ + const int ARRAY_INCR = 5; + + /* Grow the sqlite3.aVTrans array if required */ + if( (db->nVTrans%ARRAY_INCR)==0 ){ + VTable **aVTrans; + sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)* + ((sqlite3_int64)db->nVTrans + ARRAY_INCR); + aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); + if( !aVTrans ){ + return SQLITE_NOMEM_BKPT; + } + memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); + db->aVTrans = aVTrans; + } + + return SQLITE_OK; +} + +/* +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should +** have already been reserved using growVTrans(). +*/ +static void addToVTrans(sqlite3 *db, VTable *pVTab){ + /* Add pVtab to the end of sqlite3.aVTrans */ + db->aVTrans[db->nVTrans++] = pVTab; + sqlite3VtabLock(pVTab); +} + +/* +** This function is invoked by the vdbe to call the xCreate method +** of the virtual table named zTab in database iDb. +** +** If an error occurs, *pzErr is set to point to an English language +** description of the error and an SQLITE_XXX error code is returned. +** In this case the caller must call sqlite3DbFree(db, ) on *pzErr. +*/ +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ + int rc = SQLITE_OK; + Table *pTab; + Module *pMod; + const char *zMod; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + assert( pTab && IsVirtual(pTab) && !pTab->u.vtab.p ); + + /* Locate the required virtual table module */ + zMod = pTab->u.vtab.azArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); + + /* If the module has been registered and includes a Create method, + ** invoke it now. If the module has not been registered, return an + ** error. Otherwise, do nothing. + */ + if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){ + *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); + rc = SQLITE_ERROR; + }else{ + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); + } + + /* Justification of ALWAYS(): The xConstructor method is required to + ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ + if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + addToVTrans(db, sqlite3GetVTable(db, pTab)); + } + } + + return rc; +} + +/* +** This function is used to set the schema of a virtual table. It is only +** valid to call this function from within the xCreate() or xConnect() of a +** virtual table module. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ + VtabCtx *pCtx; + int rc = SQLITE_OK; + Table *pTab; + Parse sParse; + int initBusy; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + pCtx = db->pVtabCtx; + if( !pCtx || pCtx->bDeclared ){ + sqlite3Error(db, SQLITE_MISUSE_BKPT); + sqlite3_mutex_leave(db->mutex); + return SQLITE_MISUSE_BKPT; + } + pTab = pCtx->pTab; + assert( IsVirtual(pTab) ); + + sqlite3ParseObjectInit(&sParse, db); + sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; + sParse.disableTriggers = 1; + /* We should never be able to reach this point while loading the + ** schema. Nevertheless, defend against that (turn off db->init.busy) + ** in case a bug arises. */ + assert( db->init.busy==0 ); + initBusy = db->init.busy; + db->init.busy = 0; + sParse.nQueryLoop = 1; + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) + && ALWAYS(sParse.pNewTable!=0) + && ALWAYS(!db->mallocFailed) + && IsOrdinaryTable(sParse.pNewTable) + ){ + assert( sParse.zErrMsg==0 ); + if( !pTab->aCol ){ + Table *pNew = sParse.pNewTable; + Index *pIdx; + pTab->aCol = pNew->aCol; + sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); + pTab->nNVCol = pTab->nCol = pNew->nCol; + pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); + pNew->nCol = 0; + pNew->aCol = 0; + assert( pTab->pIndex==0 ); + assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); + if( !HasRowid(pNew) + && pCtx->pVTable->pMod->pModule->xUpdate!=0 + && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1 + ){ + /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0) + ** or else must have a single-column PRIMARY KEY */ + rc = SQLITE_ERROR; + } + pIdx = pNew->pIndex; + if( pIdx ){ + assert( pIdx->pNext==0 ); + pTab->pIndex = pIdx; + pNew->pIndex = 0; + pIdx->pTable = pTab; + } + } + pCtx->bDeclared = 1; + }else{ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, + (sParse.zErrMsg ? "%s" : 0), sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); + rc = SQLITE_ERROR; + } + sParse.eParseMode = PARSE_MODE_NORMAL; + + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + sqlite3DeleteTable(db, sParse.pNewTable); + sqlite3ParseObjectReset(&sParse); + db->init.busy = initBusy; + + assert( (rc&0xff)==rc ); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is invoked by the vdbe to call the xDestroy method +** of the virtual table named zTab in database iDb. This occurs +** when a DROP TABLE is mentioned. +** +** This call is a no-op if zTab is not a virtual table. +*/ +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ + int rc = SQLITE_OK; + Table *pTab; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + if( ALWAYS(pTab!=0) + && ALWAYS(IsVirtual(pTab)) + && ALWAYS(pTab->u.vtab.p!=0) + ){ + VTable *p; + int (*xDestroy)(sqlite3_vtab *); + for(p=pTab->u.vtab.p; p; p=p->pNext){ + assert( p->pVtab ); + if( p->pVtab->nRef>0 ){ + return SQLITE_LOCKED; + } + } + p = vtabDisconnectAll(db, pTab); + xDestroy = p->pMod->pModule->xDestroy; + if( xDestroy==0 ) xDestroy = p->pMod->pModule->xDisconnect; + assert( xDestroy!=0 ); + pTab->nTabRef++; + rc = xDestroy(p->pVtab); + /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ + if( rc==SQLITE_OK ){ + assert( pTab->u.vtab.p==p && p->pNext==0 ); + p->pVtab = 0; + pTab->u.vtab.p = 0; + sqlite3VtabUnlock(p); + } + sqlite3DeleteTable(db, pTab); + } + + return rc; +} + +/* +** This function invokes either the xRollback or xCommit method +** of each of the virtual tables in the sqlite3.aVTrans array. The method +** called is identified by the second argument, "offset", which is +** the offset of the method to call in the sqlite3_module structure. +** +** The array is cleared after invoking the callbacks. +*/ +static void callFinaliser(sqlite3 *db, int offset){ + int i; + if( db->aVTrans ){ + VTable **aVTrans = db->aVTrans; + db->aVTrans = 0; + for(i=0; inVTrans; i++){ + VTable *pVTab = aVTrans[i]; + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + int (*x)(sqlite3_vtab *); + x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); + if( x ) x(p); + } + pVTab->iSavepoint = 0; + sqlite3VtabUnlock(pVTab); + } + sqlite3DbFree(db, aVTrans); + db->nVTrans = 0; + } +} + +/* +** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans +** array. Return the error code for the first error that occurs, or +** SQLITE_OK if all xSync operations are successful. +** +** If an error message is available, leave it in p->zErrMsg. +*/ +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){ + int i; + int rc = SQLITE_OK; + VTable **aVTrans = db->aVTrans; + + db->aVTrans = 0; + for(i=0; rc==SQLITE_OK && inVTrans; i++){ + int (*x)(sqlite3_vtab *); + sqlite3_vtab *pVtab = aVTrans[i]->pVtab; + if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ + rc = x(pVtab); + sqlite3VtabImportErrmsg(p, pVtab); + } + } + db->aVTrans = aVTrans; + return rc; +} + +/* +** Invoke the xRollback method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xRollback)); + return SQLITE_OK; +} + +/* +** Invoke the xCommit method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xCommit)); + return SQLITE_OK; +} + +/* +** If the virtual table pVtab supports the transaction interface +** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is +** not currently open, invoke the xBegin method now. +** +** If the xBegin call is successful, place the sqlite3_vtab pointer +** in the sqlite3.aVTrans array. +*/ +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ + int rc = SQLITE_OK; + const sqlite3_module *pModule; + + /* Special case: If db->aVTrans is NULL and db->nVTrans is greater + ** than zero, then this function is being called from within a + ** virtual module xSync() callback. It is illegal to write to + ** virtual module tables in this case, so return SQLITE_LOCKED. + */ + if( sqlite3VtabInSync(db) ){ + return SQLITE_LOCKED; + } + if( !pVTab ){ + return SQLITE_OK; + } + pModule = pVTab->pVtab->pModule; + + if( pModule->xBegin ){ + int i; + + /* If pVtab is already in the aVTrans array, return early */ + for(i=0; inVTrans; i++){ + if( db->aVTrans[i]==pVTab ){ + return SQLITE_OK; + } + } + + /* Invoke the xBegin method. If successful, add the vtab to the + ** sqlite3.aVTrans[] array. */ + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + rc = pModule->xBegin(pVTab->pVtab); + if( rc==SQLITE_OK ){ + int iSvpt = db->nStatement + db->nSavepoint; + addToVTrans(db, pVTab); + if( iSvpt && pModule->xSavepoint ){ + pVTab->iSavepoint = iSvpt; + rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1); + } + } + } + } + return rc; +} + +/* +** Invoke either the xSavepoint, xRollbackTo or xRelease method of all +** virtual tables that currently have an open transaction. Pass iSavepoint +** as the second argument to the virtual table method invoked. +** +** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is +** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is +** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with +** an open transaction is invoked. +** +** If any virtual table method returns an error code other than SQLITE_OK, +** processing is abandoned and the error returned to the caller of this +** function immediately. If all calls to virtual table methods are successful, +** SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ + int rc = SQLITE_OK; + + assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); + assert( iSavepoint>=-1 ); + if( db->aVTrans ){ + int i; + for(i=0; rc==SQLITE_OK && inVTrans; i++){ + VTable *pVTab = db->aVTrans[i]; + const sqlite3_module *pMod = pVTab->pMod->pModule; + if( pVTab->pVtab && pMod->iVersion>=2 ){ + int (*xMethod)(sqlite3_vtab *, int); + sqlite3VtabLock(pVTab); + switch( op ){ + case SAVEPOINT_BEGIN: + xMethod = pMod->xSavepoint; + pVTab->iSavepoint = iSavepoint+1; + break; + case SAVEPOINT_ROLLBACK: + xMethod = pMod->xRollbackTo; + break; + default: + xMethod = pMod->xRelease; + break; + } + if( xMethod && pVTab->iSavepoint>iSavepoint ){ + u64 savedFlags = (db->flags & SQLITE_Defensive); + db->flags &= ~(u64)SQLITE_Defensive; + rc = xMethod(pVTab->pVtab, iSavepoint); + db->flags |= savedFlags; + } + sqlite3VtabUnlock(pVTab); + } + } + } + return rc; +} + +/* +** The first parameter (pDef) is a function implementation. The +** second parameter (pExpr) is the first argument to this function. +** If pExpr is a column in a virtual table, then let the virtual +** table implementation have an opportunity to overload the function. +** +** This routine is used to allow virtual table implementations to +** overload MATCH, LIKE, GLOB, and REGEXP operators. +** +** Return either the pDef argument (indicating no change) or a +** new FuncDef structure that is marked as ephemeral using the +** SQLITE_FUNC_EPHEM flag. +*/ +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( + sqlite3 *db, /* Database connection for reporting malloc problems */ + FuncDef *pDef, /* Function to possibly overload */ + int nArg, /* Number of arguments to the function */ + Expr *pExpr /* First argument to the function */ +){ + Table *pTab; + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0; + void *pArg = 0; + FuncDef *pNew; + int rc = 0; + + /* Check to see the left operand is a column in a virtual table */ + if( NEVER(pExpr==0) ) return pDef; + if( pExpr->op!=TK_COLUMN ) return pDef; + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + if( NEVER(pTab==0) ) return pDef; + if( !IsVirtual(pTab) ) return pDef; + pVtab = sqlite3GetVTable(db, pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction==0 ) return pDef; + + /* Call the xFindFunction method on the virtual table implementation + ** to see if the implementation wants to overload this function. + ** + ** Though undocumented, we have historically always invoked xFindFunction + ** with an all lower-case function name. Continue in this tradition to + ** avoid any chance of an incompatibility. + */ +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; pDef->zName[i]; i++){ + unsigned char x = (unsigned char)pDef->zName[i]; + assert( x==sqlite3UpperToLower[x] ); + } + } +#endif + rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg); + if( rc==0 ){ + return pDef; + } + + /* Create a new ephemeral function definition for the overloaded + ** function */ + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + + sqlite3Strlen30(pDef->zName) + 1); + if( pNew==0 ){ + return pDef; + } + *pNew = *pDef; + pNew->zName = (const char*)&pNew[1]; + memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1); + pNew->xSFunc = xSFunc; + pNew->pUserData = pArg; + pNew->funcFlags |= SQLITE_FUNC_EPHEM; + return pNew; +} + +/* +** Make sure virtual table pTab is contained in the pParse->apVirtualLock[] +** array so that an OP_VBegin will get generated for it. Add pTab to the +** array if it is missing. If pTab is already in the array, this routine +** is a no-op. +*/ +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + int i, n; + Table **apVtabLock; + + assert( IsVirtual(pTab) ); + for(i=0; inVtabLock; i++){ + if( pTab==pToplevel->apVtabLock[i] ) return; + } + n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); + apVtabLock = sqlite3Realloc(pToplevel->apVtabLock, n); + if( apVtabLock ){ + pToplevel->apVtabLock = apVtabLock; + pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; + }else{ + sqlite3OomFault(pToplevel->db); + } +} + +/* +** Check to see if virtual table module pMod can be have an eponymous +** virtual table instance. If it can, create one if one does not already +** exist. Return non-zero if either the eponymous virtual table instance +** exists when this routine returns or if an attempt to create it failed +** and an error message was left in pParse. +** +** An eponymous virtual table instance is one that is named after its +** module, and more importantly, does not require a CREATE VIRTUAL TABLE +** statement in order to come into existence. Eponymous virtual table +** instances always exist. They cannot be DROP-ed. +** +** Any virtual table module for which xConnect and xCreate are the same +** method can have an eponymous virtual table instance. +*/ +SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ + const sqlite3_module *pModule = pMod->pModule; + Table *pTab; + char *zErr = 0; + int rc; + sqlite3 *db = pParse->db; + if( pMod->pEpoTab ) return 1; + if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0; + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return 0; + pTab->zName = sqlite3DbStrDup(db, pMod->zName); + if( pTab->zName==0 ){ + sqlite3DbFree(db, pTab); + return 0; + } + pMod->pEpoTab = pTab; + pTab->nTabRef = 1; + pTab->eTabType = TABTYP_VTAB; + pTab->pSchema = db->aDb[0].pSchema; + assert( pTab->u.vtab.nArg==0 ); + pTab->iPKey = -1; + pTab->tabFlags |= TF_Eponymous; + addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); + addModuleArgument(pParse, pTab, 0); + addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); + rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); + if( rc ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + sqlite3DbFree(db, zErr); + sqlite3VtabEponymousTableClear(db, pMod); + } + return 1; +} + +/* +** Erase the eponymous virtual table instance associated with +** virtual table module pMod, if it exists. +*/ +SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ + Table *pTab = pMod->pEpoTab; + if( pTab!=0 ){ + /* Mark the table as Ephemeral prior to deleting it, so that the + ** sqlite3DeleteTable() routine will know that it is not stored in + ** the schema. */ + pTab->tabFlags |= TF_Ephemeral; + sqlite3DeleteTable(db, pTab); + pMod->pEpoTab = 0; + } +} + +/* +** Return the ON CONFLICT resolution mode in effect for the virtual +** table update operation currently in progress. +** +** The results of this routine are undefined unless it is called from +** within an xUpdate method. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ + static const unsigned char aMap[] = { + SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE + }; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); + assert( OE_Ignore==4 && OE_Replace==5 ); + assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 ); + return (int)aMap[db->vtabOnConflict-1]; +} + +/* +** Call from within the xCreate() or xConnect() methods to provide +** the SQLite core with additional information about the behavior +** of the virtual table being implemented. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc = SQLITE_OK; + VtabCtx *p; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + p = db->pVtabCtx; + if( !p ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + assert( p->pTab==0 || IsVirtual(p->pTab) ); + va_start(ap, op); + switch( op ){ + case SQLITE_VTAB_CONSTRAINT_SUPPORT: { + p->pVTable->bConstraint = (u8)va_arg(ap, int); + break; + } + case SQLITE_VTAB_INNOCUOUS: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_Low; + break; + } + case SQLITE_VTAB_DIRECTONLY: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; + break; + } + case SQLITE_VTAB_USES_ALL_SCHEMAS: { + p->pVTable->bAllSchemas = 1; + break; + } + default: { + rc = SQLITE_MISUSE_BKPT; + break; + } + } + va_end(ap); + } + + if( rc!=SQLITE_OK ) sqlite3Error(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/************** End of vtab.c ************************************************/ +/************** Begin file wherecode.c ***************************************/ +/* +** 2015-06-06 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. +** +** This file was split off from where.c on 2015-06-06 in order to reduce the +** size of where.c and make it easier to edit. This file contains the routines +** that actually generate the bulk of the WHERE loop code. The original where.c +** file retains the code that does query planning and analysis. +*/ +/* #include "sqliteInt.h" */ +/************** Include whereInt.h in the middle of wherecode.c **************/ +/************** Begin file whereInt.h ****************************************/ +/* +** 2013-11-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains structure and macro definitions for the query +** planner logic in "where.c". These definitions are broken out into +** a separate source file for easier editing. +*/ +#ifndef SQLITE_WHEREINT_H +#define SQLITE_WHEREINT_H + + +/* Forward references +*/ +typedef struct WhereClause WhereClause; +typedef struct WhereMaskSet WhereMaskSet; +typedef struct WhereOrInfo WhereOrInfo; +typedef struct WhereAndInfo WhereAndInfo; +typedef struct WhereLevel WhereLevel; +typedef struct WhereLoop WhereLoop; +typedef struct WherePath WherePath; +typedef struct WhereTerm WhereTerm; +typedef struct WhereLoopBuilder WhereLoopBuilder; +typedef struct WhereScan WhereScan; +typedef struct WhereOrCost WhereOrCost; +typedef struct WhereOrSet WhereOrSet; +typedef struct WhereMemBlock WhereMemBlock; +typedef struct WhereRightJoin WhereRightJoin; + +/* +** This object is a header on a block of allocated memory that will be +** automatically freed when its WInfo object is destructed. +*/ +struct WhereMemBlock { + WhereMemBlock *pNext; /* Next block in the chain */ + u64 sz; /* Bytes of space */ +}; + +/* +** Extra information attached to a WhereLevel that is a RIGHT JOIN. +*/ +struct WhereRightJoin { + int iMatch; /* Cursor used to determine prior matched rows */ + int regBloom; /* Bloom filter for iRJMatch */ + int regReturn; /* Return register for the interior subroutine */ + int addrSubrtn; /* Starting address for the interior subroutine */ + int endSubrtn; /* The last opcode in the interior subroutine */ +}; + +/* +** This object contains information needed to implement a single nested +** loop in WHERE clause. +** +** Contrast this object with WhereLoop. This object describes the +** implementation of the loop. WhereLoop describes the algorithm. +** This object contains a pointer to the WhereLoop algorithm as one of +** its elements. +** +** The WhereInfo object contains a single instance of this object for +** each term in the FROM clause (which is to say, for each of the +** nested loops as implemented). The order of WhereLevel objects determines +** the loop nested order, with WhereInfo.a[0] being the outer loop and +** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop. +*/ +struct WhereLevel { + int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ + int iTabCur; /* The VDBE cursor used to access the table */ + int iIdxCur; /* The VDBE cursor used to access pIdx */ + int addrBrk; /* Jump here to break out of the loop */ + int addrNxt; /* Jump here to start the next IN combination */ + int addrSkip; /* Jump here for next iteration of skip-scan */ + int addrCont; /* Jump here to continue with the next loop cycle */ + int addrFirst; /* First instruction of interior of the loop */ + int addrBody; /* Beginning of the body of this loop */ + int regBignull; /* big-null flag reg. True if a NULL-scan is needed */ + int addrBignull; /* Jump here for next part of big-null scan */ +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ + int addrLikeRep; /* LIKE range processing address */ +#endif + int regFilter; /* Bloom filter */ + WhereRightJoin *pRJ; /* Extra information for RIGHT JOIN */ + u8 iFrom; /* Which entry in the FROM clause */ + u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ + int p1, p2; /* Operands of the opcode used to end the loop */ + union { /* Information that depends on pWLoop->wsFlags */ + struct { + int nIn; /* Number of entries in aInLoop[] */ + struct InLoop { + int iCur; /* The VDBE cursor used by this IN operator */ + int addrInTop; /* Top of the IN loop */ + int iBase; /* Base register of multi-key index record */ + int nPrefix; /* Number of prior entries in the key */ + u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ + } *aInLoop; /* Information about each nested IN operator */ + } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ + Index *pCoveringIdx; /* Possible covering index for WHERE_MULTI_OR */ + } u; + struct WhereLoop *pWLoop; /* The selected WhereLoop object */ + Bitmask notReady; /* FROM entries not usable at this level */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrVisit; /* Address at which row is visited */ +#endif +}; + +/* +** Each instance of this object represents an algorithm for evaluating one +** term of a join. Every term of the FROM clause will have at least +** one corresponding WhereLoop object (unless INDEXED BY constraints +** prevent a query solution - which is an error) and many terms of the +** FROM clause will have multiple WhereLoop objects, each describing a +** potential way of implementing that FROM-clause term, together with +** dependencies and cost estimates for using the chosen algorithm. +** +** Query planning consists of building up a collection of these WhereLoop +** objects, then computing a particular sequence of WhereLoop objects, with +** one WhereLoop object per FROM clause term, that satisfy all dependencies +** and that minimize the overall cost. +*/ +struct WhereLoop { + Bitmask prereq; /* Bitmask of other loops that must run first */ + Bitmask maskSelf; /* Bitmask identifying table iTab */ +#ifdef SQLITE_DEBUG + char cId; /* Symbolic ID of this loop for debugging use */ +#endif + u8 iTab; /* Position in FROM clause of table for this loop */ + u8 iSortIdx; /* Sorting index number. 0==None */ + LogEst rSetup; /* One-time setup cost (ex: create transient index) */ + LogEst rRun; /* Cost of running each loop */ + LogEst nOut; /* Estimated number of output rows */ + union { + struct { /* Information for internal btree tables */ + u16 nEq; /* Number of equality constraints */ + u16 nBtm; /* Size of BTM vector */ + u16 nTop; /* Size of TOP vector */ + u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ + Index *pIndex; /* Index used, or NULL */ + } btree; + struct { /* Information for virtual tables */ + int idxNum; /* Index number */ + u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ + u32 bOmitOffset : 1; /* True to let virtual table handle offset */ + i8 isOrdered; /* True if satisfies ORDER BY */ + u16 omitMask; /* Terms that may be omitted */ + char *idxStr; /* Index identifier string */ + u32 mHandleIn; /* Terms to handle as IN(...) instead of == */ + } vtab; + } u; + u32 wsFlags; /* WHERE_* flags describing the plan */ + u16 nLTerm; /* Number of entries in aLTerm[] */ + u16 nSkip; /* Number of NULL aLTerm[] entries */ + /**** whereLoopXfer() copies fields above ***********************/ +# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) + u16 nLSlot; /* Number of slots allocated for aLTerm[] */ + WhereTerm **aLTerm; /* WhereTerms used */ + WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ + WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ +}; + +/* This object holds the prerequisites and the cost of running a +** subquery on one operand of an OR operator in the WHERE clause. +** See WhereOrSet for additional information +*/ +struct WhereOrCost { + Bitmask prereq; /* Prerequisites */ + LogEst rRun; /* Cost of running this subquery */ + LogEst nOut; /* Number of outputs for this subquery */ +}; + +/* The WhereOrSet object holds a set of possible WhereOrCosts that +** correspond to the subquery(s) of OR-clause processing. Only the +** best N_OR_COST elements are retained. +*/ +#define N_OR_COST 3 +struct WhereOrSet { + u16 n; /* Number of valid a[] entries */ + WhereOrCost a[N_OR_COST]; /* Set of best costs */ +}; + +/* +** Each instance of this object holds a sequence of WhereLoop objects +** that implement some or all of a query plan. +** +** Think of each WhereLoop object as a node in a graph with arcs +** showing dependencies and costs for travelling between nodes. (That is +** not a completely accurate description because WhereLoop costs are a +** vector, not a scalar, and because dependencies are many-to-one, not +** one-to-one as are graph nodes. But it is a useful visualization aid.) +** Then a WherePath object is a path through the graph that visits some +** or all of the WhereLoop objects once. +** +** The "solver" works by creating the N best WherePath objects of length +** 1. Then using those as a basis to compute the N best WherePath objects +** of length 2. And so forth until the length of WherePaths equals the +** number of nodes in the FROM clause. The best (lowest cost) WherePath +** at the end is the chosen query plan. +*/ +struct WherePath { + Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ + Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ + LogEst nRow; /* Estimated number of rows generated by this path */ + LogEst rCost; /* Total cost of this path */ + LogEst rUnsorted; /* Total cost of this path ignoring sorting costs */ + i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ + WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ +}; + +/* +** The query generator uses an array of instances of this structure to +** help it analyze the subexpressions of the WHERE clause. Each WHERE +** clause subexpression is separated from the others by AND operators, +** usually, or sometimes subexpressions separated by OR. +** +** All WhereTerms are collected into a single WhereClause structure. +** The following identity holds: +** +** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm +** +** When a term is of the form: +** +** X +** +** where X is a column name and is one of certain operators, +** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the +** cursor number and column number for X. WhereTerm.eOperator records +** the using a bitmask encoding defined by WO_xxx below. The +** use of a bitmask encoding for the operator allows us to search +** quickly for terms that match any of several different operators. +** +** A WhereTerm might also be two or more subterms connected by OR: +** +** (t1.X ) OR (t1.Y ) OR .... +** +** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR +** and the WhereTerm.u.pOrInfo field points to auxiliary information that +** is collected about the OR clause. +** +** If a term in the WHERE clause does not match either of the two previous +** categories, then eOperator==0. The WhereTerm.pExpr field is still set +** to the original subexpression content and wtFlags is set up appropriately +** but no other fields in the WhereTerm object are meaningful. +** +** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers, +** but they do so indirectly. A single WhereMaskSet structure translates +** cursor number into bits and the translated bit is stored in the prereq +** fields. The translation is used in order to maximize the number of +** bits that will fit in a Bitmask. The VDBE cursor numbers might be +** spread out over the non-negative integers. For example, the cursor +** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet +** translates these sparse cursor numbers into consecutive integers +** beginning with 0 in order to make the best possible use of the available +** bits in the Bitmask. So, in the example above, the cursor numbers +** would be mapped into integers 0 through 7. +** +** The number of terms in a join is limited by the number of bits +** in prereqRight and prereqAll. The default is 64 bits, hence SQLite +** is only able to process joins with 64 or fewer tables. +*/ +struct WhereTerm { + Expr *pExpr; /* Pointer to the subexpression that is this term */ + WhereClause *pWC; /* The clause this term is part of */ + LogEst truthProb; /* Probability of truth for this expression */ + u16 wtFlags; /* TERM_xxx bit flags. See below */ + u16 eOperator; /* A WO_xx value describing */ + u8 nChild; /* Number of children that must disable us */ + u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ + int iParent; /* Disable pWC->a[iParent] when this term disabled */ + int leftCursor; /* Cursor number of X in "X " */ + union { + struct { + int leftColumn; /* Column number of X in "X " */ + int iField; /* Field in (?,?,?) IN (SELECT...) vector */ + } x; /* Opcode other than OP_OR or OP_AND */ + WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ + WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ + } u; + Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ + Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ +}; + +/* +** Allowed values of WhereTerm.wtFlags +*/ +#define TERM_DYNAMIC 0x0001 /* Need to call sqlite3ExprDelete(db, pExpr) */ +#define TERM_VIRTUAL 0x0002 /* Added by the optimizer. Do not code */ +#define TERM_CODED 0x0004 /* This term is already coded */ +#define TERM_COPIED 0x0008 /* Has a child */ +#define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ +#define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ +#define TERM_OK 0x0040 /* Used during OR-clause processing */ +#define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ +#define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ +#define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ +#define TERM_LIKE 0x0400 /* The original LIKE operator */ +#define TERM_IS 0x0800 /* Term.pExpr is an IS operator */ +#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ +#define TERM_HEURTRUTH 0x2000 /* Heuristic truthProb used */ +#ifdef SQLITE_ENABLE_STAT4 +# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */ +#else +# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */ +#endif +#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */ + +/* +** An instance of the WhereScan object is used as an iterator for locating +** terms in the WHERE clause that are useful to the query planner. +*/ +struct WhereScan { + WhereClause *pOrigWC; /* Original, innermost WhereClause */ + WhereClause *pWC; /* WhereClause currently being scanned */ + const char *zCollName; /* Required collating sequence, if not NULL */ + Expr *pIdxExpr; /* Search for this index expression */ + int k; /* Resume scanning at this->pWC->a[this->k] */ + u32 opMask; /* Acceptable operators */ + char idxaff; /* Must match this affinity, if zCollName!=NULL */ + unsigned char iEquiv; /* Current slot in aiCur[] and aiColumn[] */ + unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */ + int aiCur[11]; /* Cursors in the equivalence class */ + i16 aiColumn[11]; /* Corresponding column number in the eq-class */ +}; + +/* +** An instance of the following structure holds all information about a +** WHERE clause. Mostly this is a container for one or more WhereTerms. +** +** Explanation of pOuter: For a WHERE clause of the form +** +** a AND ((b AND c) OR (d AND e)) AND f +** +** There are separate WhereClause objects for the whole clause and for +** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the +** subclauses points to the WhereClause object for the whole clause. +*/ +struct WhereClause { + WhereInfo *pWInfo; /* WHERE clause processing context */ + WhereClause *pOuter; /* Outer conjunction */ + u8 op; /* Split operator. TK_AND or TK_OR */ + u8 hasOr; /* True if any a[].eOperator is WO_OR */ + int nTerm; /* Number of terms */ + int nSlot; /* Number of entries in a[] */ + int nBase; /* Number of terms through the last non-Virtual */ + WhereTerm *a; /* Each a[] describes a term of the WHERE clause */ +#if defined(SQLITE_SMALL_STACK) + WhereTerm aStatic[1]; /* Initial static space for a[] */ +#else + WhereTerm aStatic[8]; /* Initial static space for a[] */ +#endif +}; + +/* +** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to +** a dynamically allocated instance of the following structure. +*/ +struct WhereOrInfo { + WhereClause wc; /* Decomposition into subterms */ + Bitmask indexable; /* Bitmask of all indexable tables in the clause */ +}; + +/* +** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to +** a dynamically allocated instance of the following structure. +*/ +struct WhereAndInfo { + WhereClause wc; /* The subexpression broken out */ +}; + +/* +** An instance of the following structure keeps track of a mapping +** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. +** +** The VDBE cursor numbers are small integers contained in +** SrcItem.iCursor and Expr.iTable fields. For any given WHERE +** clause, the cursor numbers might not begin with 0 and they might +** contain gaps in the numbering sequence. But we want to make maximum +** use of the bits in our bitmasks. This structure provides a mapping +** from the sparse cursor numbers into consecutive integers beginning +** with 0. +** +** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask +** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<3, 5->1, 8->2, 29->0, +** 57->5, 73->4. Or one of 719 other combinations might be used. It +** does not really matter. What is important is that sparse cursor +** numbers all get mapped into bit numbers that begin with 0 and contain +** no gaps. +*/ +struct WhereMaskSet { + int bVarSelect; /* Used by sqlite3WhereExprUsage() */ + int n; /* Number of assigned cursor values */ + int ix[BMS]; /* Cursor assigned to each bit */ +}; + +/* +** This object is a convenience wrapper holding all information needed +** to construct WhereLoop objects for a particular query. +*/ +struct WhereLoopBuilder { + WhereInfo *pWInfo; /* Information about this WHERE */ + WhereClause *pWC; /* WHERE clause terms */ + WhereLoop *pNew; /* Template WhereLoop */ + WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ +#ifdef SQLITE_ENABLE_STAT4 + UnpackedRecord *pRec; /* Probe for stat4 (if required) */ + int nRecValid; /* Number of valid fields currently in pRec */ +#endif + unsigned char bldFlags1; /* First set of SQLITE_BLDF_* flags */ + unsigned char bldFlags2; /* Second set of SQLITE_BLDF_* flags */ + unsigned int iPlanLimit; /* Search limiter */ +}; + +/* Allowed values for WhereLoopBuider.bldFlags */ +#define SQLITE_BLDF1_INDEXED 0x0001 /* An index is used */ +#define SQLITE_BLDF1_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ + +#define SQLITE_BLDF2_2NDPASS 0x0004 /* Second builder pass needed */ + +/* The WhereLoopBuilder.iPlanLimit is used to limit the number of +** index+constraint combinations the query planner will consider for a +** particular query. If this parameter is unlimited, then certain +** pathological queries can spend excess time in the sqlite3WhereBegin() +** routine. The limit is high enough that is should not impact real-world +** queries. +** +** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is +** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM +** clause is processed, so that every table in a join is guaranteed to be +** able to propose a some index+constraint combinations even if the initial +** baseline limit was exhausted by prior tables of the join. +*/ +#ifndef SQLITE_QUERY_PLANNER_LIMIT +# define SQLITE_QUERY_PLANNER_LIMIT 20000 +#endif +#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR +# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 +#endif + +/* +** The WHERE clause processing routine has two halves. The +** first part does the start of the WHERE loop and the second +** half does the tail of the WHERE loop. An instance of +** this structure is returned by the first half and passed +** into the second half to give some continuity. +** +** An instance of this object holds the complete state of the query +** planner. +*/ +struct WhereInfo { + Parse *pParse; /* Parsing and code generating context */ + SrcList *pTabList; /* List of tables in the join */ + ExprList *pOrderBy; /* The ORDER BY clause or NULL */ + ExprList *pResultSet; /* Result set of the query */ +#if WHERETRACE_ENABLED + Expr *pWhere; /* The complete WHERE clause */ +#endif + Select *pSelect; /* The entire SELECT statement containing WHERE */ + int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ + int iContinue; /* Jump here to continue with next record */ + int iBreak; /* Jump here to break out of the loop */ + int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ + u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ + LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ + u8 nLevel; /* Number of nested loop */ + i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ + u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ + u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ + unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ + unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ + unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ + unsigned sorted :1; /* True if really sorted (not just grouped) */ + LogEst nRowOut; /* Estimated number of output rows */ + int iTop; /* The very beginning of the WHERE loop */ + int iEndWhere; /* End of the WHERE clause itself */ + WhereLoop *pLoops; /* List of all WhereLoop objects */ + WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ + Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ + WhereClause sWC; /* Decomposition of the WHERE clause */ + WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ + WhereLevel a[1]; /* Information about each nest loop in WHERE */ +}; + +/* +** Private interfaces - callable only by other where.c routines. +** +** where.c: +*/ +SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); +#ifdef WHERETRACE_ENABLED +SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC); +#endif +SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( + WhereClause *pWC, /* The WHERE clause to be searched */ + int iCur, /* Cursor number of LHS */ + int iColumn, /* Column number of LHS */ + Bitmask notReady, /* RHS must not overlap with this mask */ + u32 op, /* Mask of WO_xx values describing operator */ + Index *pIdx /* Must be compatible with this index, if not NULL */ +); +SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte); +SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte); + +/* wherecode.c: */ +#ifndef SQLITE_OMIT_EXPLAIN +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +); +#else +# define sqlite3WhereExplainOneScan(u,v,w,x) 0 +# define sqlite3WhereExplainBloomFilter(u,v,w) 0 +#endif /* SQLITE_OMIT_EXPLAIN */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +SQLITE_PRIVATE void sqlite3WhereAddScanStatus( + Vdbe *v, /* Vdbe to add scanstatus entry to */ + SrcList *pSrclist, /* FROM clause pLvl reads data from */ + WhereLevel *pLvl, /* Level to add scanstatus() entry for */ + int addrExplain /* Address of OP_Explain (or 0) */ +); +#else +# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d) +#endif +SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + Parse *pParse, /* Parsing context */ + Vdbe *v, /* Prepared statement under construction */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + WhereLevel *pLevel, /* The current level pointer */ + Bitmask notReady /* Which tables are currently available */ +); +SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( + WhereInfo *pWInfo, + int iLevel, + WhereLevel *pLevel +); + +/* whereexpr.c: */ +SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); +SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); +SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); +SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); + + + + + +/* +** Bitmasks for the operators on WhereTerm objects. These are all +** operators that are of interest to the query planner. An +** OR-ed combination of these values can be used when searching for +** particular WhereTerms within a WhereClause. +** +** Value constraints: +** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ +** WO_LT == SQLITE_INDEX_CONSTRAINT_LT +** WO_LE == SQLITE_INDEX_CONSTRAINT_LE +** WO_GT == SQLITE_INDEX_CONSTRAINT_GT +** WO_GE == SQLITE_INDEX_CONSTRAINT_GE +*/ +#define WO_IN 0x0001 +#define WO_EQ 0x0002 +#define WO_LT (WO_EQ<<(TK_LT-TK_EQ)) +#define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) +#define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) +#define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) +#define WO_AUX 0x0040 /* Op useful to virtual tables only */ +#define WO_IS 0x0080 +#define WO_ISNULL 0x0100 +#define WO_OR 0x0200 /* Two or more OR-connected terms */ +#define WO_AND 0x0400 /* Two or more AND-connected terms */ +#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */ +#define WO_NOOP 0x1000 /* This term does not restrict search space */ +#define WO_ROWVAL 0x2000 /* A row-value term */ + +#define WO_ALL 0x3fff /* Mask of all possible WO_* values */ +#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */ + +/* +** These are definitions of bits in the WhereLoop.wsFlags field. +** The particular combination of bits in each WhereLoop help to +** determine the algorithm that WhereLoop represents. +*/ +#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */ +#define WHERE_COLUMN_RANGE 0x00000002 /* xEXPR */ +#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */ +#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */ +#define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */ +#define WHERE_TOP_LIMIT 0x00000010 /* xEXPR or x>=EXPR constraint */ +#define WHERE_BOTH_LIMIT 0x00000030 /* Both x>EXPR and xaiColumn[i]; + if( i==XN_EXPR ) return ""; + if( i==XN_ROWID ) return "rowid"; + return pIdx->pTable->aCol[i].zCnName; +} + +/* +** This routine is a helper for explainIndexRange() below +** +** pStr holds the text of an expression that we are building up one term +** at a time. This routine adds a new term to the end of the expression. +** Terms are separated by AND so add the "AND" text for second and subsequent +** terms only. +*/ +static void explainAppendTerm( + StrAccum *pStr, /* The text expression being built */ + Index *pIdx, /* Index to read column names from */ + int nTerm, /* Number of terms */ + int iTerm, /* Zero-based index of first term. */ + int bAnd, /* Non-zero to append " AND " */ + const char *zOp /* Name of the operator */ +){ + int i; + + assert( nTerm>=1 ); + if( bAnd ) sqlite3_str_append(pStr, " AND ", 5); + + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); + for(i=0; i1 ) sqlite3_str_append(pStr, ")", 1); + + sqlite3_str_append(pStr, zOp, 1); + + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); + for(i=0; i1 ) sqlite3_str_append(pStr, ")", 1); +} + +/* +** Argument pLevel describes a strategy for scanning table pTab. This +** function appends text to pStr that describes the subset of table +** rows scanned by the strategy in the form of an SQL expression. +** +** For example, if the query: +** +** SELECT * FROM t1 WHERE a=1 AND b>2; +** +** is run and there is an index on (a, b), then this function returns a +** string similar to: +** +** "a=? AND b>?" +*/ +static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ + Index *pIndex = pLoop->u.btree.pIndex; + u16 nEq = pLoop->u.btree.nEq; + u16 nSkip = pLoop->nSkip; + int i, j; + + if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; + sqlite3_str_append(pStr, " (", 2); + for(i=0; i=nSkip ? "%s=?" : "ANY(%s)", z); + } + + j = i; + if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ + explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">"); + i = 1; + } + if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ + explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); + } + sqlite3_str_append(pStr, ")", 1); +} + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** was defined at compile-time. If it is not a no-op, a single OP_Explain +** opcode is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + int isSearch; /* True for a SEARCH. False for SCAN. */ + WhereLoop *pLoop; /* The controlling WhereLoop object */ + u32 flags; /* Flags that describe this loop */ + char *zMsg; /* Text to add to EQP output */ + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + pLoop = pLevel->pWLoop; + flags = pLoop->wsFlags; + if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; + + isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 + || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) + || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "%s %S", isSearch ? "SEARCH" : "SCAN", pItem); + if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ + const char *zFmt = 0; + Index *pIdx; + + assert( pLoop->u.btree.pIndex!=0 ); + pIdx = pLoop->u.btree.pIndex; + assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); + if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ + if( isSearch ){ + zFmt = "PRIMARY KEY"; + } + }else if( flags & WHERE_PARTIALIDX ){ + zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; + }else if( flags & WHERE_AUTO_INDEX ){ + zFmt = "AUTOMATIC COVERING INDEX"; + }else if( flags & WHERE_IDX_ONLY ){ + zFmt = "COVERING INDEX %s"; + }else{ + zFmt = "INDEX %s"; + } + if( zFmt ){ + sqlite3_str_append(&str, " USING ", 7); + sqlite3_str_appendf(&str, zFmt, pIdx->zName); + explainIndexRange(&str, pLoop); + } + }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ + char cRangeOp; +#if 0 /* Better output, but breaks many tests */ + const Table *pTab = pItem->pTab; + const char *zRowid = pTab->iPKey>=0 ? pTab->aCol[pTab->iPKey].zCnName: + "rowid"; +#else + const char *zRowid = "rowid"; +#endif + sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (%s", zRowid); + if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ + cRangeOp = '='; + }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ + sqlite3_str_appendf(&str, ">? AND %s", zRowid); + cRangeOp = '<'; + }else if( flags&WHERE_BTM_LIMIT ){ + cRangeOp = '>'; + }else{ + assert( flags&WHERE_TOP_LIMIT); + cRangeOp = '<'; + } + sqlite3_str_appendf(&str, "%c?)", cRangeOp); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ + sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", + pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); + } +#endif + if( pItem->fg.jointype & JT_LEFT ){ + sqlite3_str_appendf(&str, " LEFT-JOIN"); + } +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS + if( pLoop->nOut>=10 ){ + sqlite3_str_appendf(&str, " (~%llu rows)", + sqlite3LogEstToInt(pLoop->nOut)); + }else{ + sqlite3_str_append(&str, " (~1 row)", 9); + } +#endif + zMsg = sqlite3StrAccumFinish(&str); + sqlite3ExplainBreakpoint("",zMsg); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), + pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + } + return ret; +} + +/* +** Add a single OP_Explain opcode that describes a Bloom filter. +** +** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or +** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not +** required and this routine is a no-op. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +){ + int ret = 0; + SrcItem *pItem = &pWInfo->pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + char *zMsg; /* Text to add to EQP output */ + int i; /* Loop counter */ + WhereLoop *pLoop; /* The where loop */ + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); + pLoop = pLevel->pWLoop; + if( pLoop->wsFlags & WHERE_IPK ){ + const Table *pTab = pItem->pTab; + if( pTab->iPKey>=0 ){ + sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); + }else{ + sqlite3_str_appendf(&str, "rowid=?"); + } + }else{ + for(i=pLoop->nSkip; iu.btree.nEq; i++){ + const char *z = explainIndexColumnName(pLoop->u.btree.pIndex, i); + if( i>pLoop->nSkip ) sqlite3_str_append(&str, " AND ", 5); + sqlite3_str_appendf(&str, "%s=?", z); + } + } + sqlite3_str_append(&str, ")", 1); + zMsg = sqlite3StrAccumFinish(&str); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), + pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + + sqlite3VdbeScanStatus(v, sqlite3VdbeCurrentAddr(v)-1, 0, 0, 0, 0); + return ret; +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Configure the VM passed as the first argument with an +** sqlite3_stmt_scanstatus() entry corresponding to the scan used to +** implement level pLvl. Argument pSrclist is a pointer to the FROM +** clause that the scan reads data from. +** +** If argument addrExplain is not 0, it must be the address of an +** OP_Explain instruction that describes the same loop. +*/ +SQLITE_PRIVATE void sqlite3WhereAddScanStatus( + Vdbe *v, /* Vdbe to add scanstatus entry to */ + SrcList *pSrclist, /* FROM clause pLvl reads data from */ + WhereLevel *pLvl, /* Level to add scanstatus() entry for */ + int addrExplain /* Address of OP_Explain (or 0) */ +){ + if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){ + const char *zObj = 0; + WhereLoop *pLoop = pLvl->pWLoop; + int wsFlags = pLoop->wsFlags; + int viaCoroutine = 0; + + if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ + zObj = pLoop->u.btree.pIndex->zName; + }else{ + zObj = pSrclist->a[pLvl->iFrom].zName; + viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; + } + sqlite3VdbeScanStatus( + v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj + ); + + if( viaCoroutine==0 ){ + if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ + sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); + } + if( wsFlags & WHERE_INDEXED ){ + sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); + } + }else{ + int addr = pSrclist->a[pLvl->iFrom].addrFillSub; + VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); + assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); + assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); + sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); + } + } +} +#endif + + +/* +** Disable a term in the WHERE clause. Except, do not disable the term +** if it controls a LEFT OUTER JOIN and it did not originate in the ON +** or USING clause of that join. +** +** Consider the term t2.z='ok' in the following queries: +** +** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' +** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' +** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' +** +** The t2.z='ok' is disabled in the in (2) because it originates +** in the ON clause. The term is disabled in (3) because it is not part +** of a LEFT OUTER JOIN. In (1), the term is not disabled. +** +** Disabling a term causes that term to not be tested in the inner loop +** of the join. Disabling is an optimization. When terms are satisfied +** by indices, we disable them to prevent redundant tests in the inner +** loop. We would get the correct results if nothing were ever disabled, +** but joins might run a little slower. The trick is to disable as much +** as we can without disabling too much. If we disabled in (1), we'd get +** the wrong answer. See ticket #813. +** +** If all the children of a term are disabled, then that term is also +** automatically disabled. In this way, terms get disabled if derived +** virtual terms are tested first. For example: +** +** x GLOB 'abc*' AND x>='abc' AND x<'acd' +** \___________/ \______/ \_____/ +** parent child1 child2 +** +** Only the parent term was in the original WHERE clause. The child1 +** and child2 terms were added by the LIKE optimization. If both of +** the virtual child terms are valid, then testing of the parent can be +** skipped. +** +** Usually the parent term is marked as TERM_CODED. But if the parent +** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead. +** The TERM_LIKECOND marking indicates that the term should be coded inside +** a conditional such that is only evaluated on the second pass of a +** LIKE-optimization loop, when scanning BLOBs instead of strings. +*/ +static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ + int nLoop = 0; + assert( pTerm!=0 ); + while( (pTerm->wtFlags & TERM_CODED)==0 + && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_OuterON)) + && (pLevel->notReady & pTerm->prereqAll)==0 + ){ + if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ + pTerm->wtFlags |= TERM_LIKECOND; + }else{ + pTerm->wtFlags |= TERM_CODED; + } +#ifdef WHERETRACE_ENABLED + if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + sqlite3DebugPrintf("DISABLE-"); + sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); + } +#endif + if( pTerm->iParent<0 ) break; + pTerm = &pTerm->pWC->a[pTerm->iParent]; + assert( pTerm!=0 ); + pTerm->nChild--; + if( pTerm->nChild!=0 ) break; + nLoop++; + } +} + +/* +** Code an OP_Affinity opcode to apply the column affinity string zAff +** to the n registers starting at base. +** +** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which +** are no-ops) at the beginning and end of zAff are ignored. If all entries +** in zAff are SQLITE_AFF_BLOB or SQLITE_AFF_NONE, then no code gets generated. +** +** This routine makes its own copy of zAff so that the caller is free +** to modify zAff after this routine returns. +*/ +static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ + Vdbe *v = pParse->pVdbe; + if( zAff==0 ){ + assert( pParse->db->mallocFailed ); + return; + } + assert( v!=0 ); + + /* Adjust base and n to skip over SQLITE_AFF_BLOB and SQLITE_AFF_NONE + ** entries at the beginning and end of the affinity string. + */ + assert( SQLITE_AFF_NONE0 && zAff[0]<=SQLITE_AFF_BLOB ){ + n--; + base++; + zAff++; + } + while( n>1 && zAff[n-1]<=SQLITE_AFF_BLOB ){ + n--; + } + + /* Code the OP_Affinity opcode if there is anything left to do. */ + if( n>0 ){ + sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); + } +} + +/* +** Expression pRight, which is the RHS of a comparison operation, is +** either a vector of n elements or, if n==1, a scalar expression. +** Before the comparison operation, affinity zAff is to be applied +** to the pRight values. This function modifies characters within the +** affinity string to SQLITE_AFF_BLOB if either: +** +** * the comparison will be performed with no affinity, or +** * the affinity change in zAff is guaranteed not to change the value. +*/ +static void updateRangeAffinityStr( + Expr *pRight, /* RHS of comparison */ + int n, /* Number of vector elements in comparison */ + char *zAff /* Affinity string to modify */ +){ + int i; + for(i=0; idb; + Select *pSelect; /* Pointer to the SELECT on the RHS */ + Expr *pNew; + pNew = sqlite3ExprDup(db, pX, 0); + if( db->mallocFailed==0 ){ + for(pSelect=pNew->x.pSelect; pSelect; pSelect=pSelect->pPrior){ + ExprList *pOrigRhs; /* Original unmodified RHS */ + ExprList *pOrigLhs = 0; /* Original unmodified LHS */ + ExprList *pRhs = 0; /* New RHS after modifications */ + ExprList *pLhs = 0; /* New LHS after mods */ + int i; /* Loop counter */ + + assert( ExprUseXSelect(pNew) ); + pOrigRhs = pSelect->pEList; + assert( pNew->pLeft!=0 ); + assert( ExprUseXList(pNew->pLeft) ); + if( pSelect==pNew->x.pSelect ){ + pOrigLhs = pNew->pLeft->x.pList; + } + for(i=iEq; inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iField; + assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); + iField = pLoop->aLTerm[i]->u.x.iField - 1; + if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ + pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); + pOrigRhs->a[iField].pExpr = 0; + if( pOrigLhs ){ + assert( pOrigLhs->a[iField].pExpr!=0 ); + pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); + pOrigLhs->a[iField].pExpr = 0; + } + } + } + sqlite3ExprListDelete(db, pOrigRhs); + if( pOrigLhs ){ + sqlite3ExprListDelete(db, pOrigLhs); + pNew->pLeft->x.pList = pLhs; + } + pSelect->pEList = pRhs; + if( pLhs && pLhs->nExpr==1 ){ + /* Take care here not to generate a TK_VECTOR containing only a + ** single value. Since the parser never creates such a vector, some + ** of the subroutines do not handle this case. */ + Expr *p = pLhs->a[0].pExpr; + pLhs->a[0].pExpr = 0; + sqlite3ExprDelete(db, pNew->pLeft); + pNew->pLeft = p; + } + if( pSelect->pOrderBy ){ + /* If the SELECT statement has an ORDER BY clause, zero the + ** iOrderByCol variables. These are set to non-zero when an + ** ORDER BY term exactly matches one of the terms of the + ** result-set. Since the result-set of the SELECT statement may + ** have been modified or reordered, these variables are no longer + ** set correctly. Since setting them is just an optimization, + ** it's easiest just to zero them here. */ + ExprList *pOrderBy = pSelect->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } + +#if 0 + printf("For indexing, change the IN expr:\n"); + sqlite3TreeViewExpr(0, pX, 0); + printf("Into:\n"); + sqlite3TreeViewExpr(0, pNew, 0); +#endif + } + } + return pNew; +} + + +/* +** Generate code for a single equality term of the WHERE clause. An equality +** term can be either X=expr or X IN (...). pTerm is the term to be +** coded. +** +** The current value for the constraint is left in a register, the index +** of which is returned. An attempt is made store the result in iTarget but +** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the +** constraint is a TK_EQ or TK_IS, then the current value might be left in +** some other register and it is the caller's responsibility to compensate. +** +** For a constraint of the form X=expr, the expression is evaluated in +** straight-line code. For constraints of the form X IN (...) +** this routine sets up a loop that will iterate over all values of X. +*/ +static int codeEqualityTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + Vdbe *v = pParse->pVdbe; + int iReg; /* Register holding results */ + + assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); + assert( iTarget>0 ); + if( pX->op==TK_EQ || pX->op==TK_IS ){ + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); + }else if( pX->op==TK_ISNULL ){ + iReg = iTarget; + sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); +#ifndef SQLITE_OMIT_SUBQUERY + }else{ + int eType = IN_INDEX_NOOP; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; + int i; + int nEq = 0; + int *aiMap = 0; + + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] + ){ + testcase( iEq==0 ); + testcase( bRev ); + bRev = !bRev; + } + assert( pX->op==TK_IN ); + iReg = iTarget; + + for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ + disableTerm(pLevel, pTerm); + return iTarget; + } + } + for(i=iEq;inLTerm; i++){ + assert( pLoop->aLTerm[i]!=0 ); + if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; + } + + iTab = 0; + if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); + }else{ + Expr *pExpr = pTerm->pExpr; + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + pExpr->iTable = iTab; + } + sqlite3ExprDelete(db, pX); + }else{ + int n = sqlite3ExprVectorSize(pX->pLeft); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + } + pX = pExpr; + } + + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); + + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; + if( pLevel->u.in.nIn==0 ){ + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } + + i = pLevel->u.in.nIn; + pLevel->u.in.nIn += nEq; + pLevel->u.in.aInLoop = + sqlite3WhereRealloc(pTerm->pWC->pWInfo, + pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + pIn = pLevel->u.in.aInLoop; + if( pIn ){ + int iMap = 0; /* Index in aiMap[] */ + pIn += i; + for(i=iEq;inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iOut = iReg + i - iEq; + if( eType==IN_INDEX_ROWID ){ + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); + }else{ + int iCol = aiMap ? aiMap[iMap++] : 0; + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + } + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); + if( i==iEq ){ + pIn->iCur = iTab; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 ){ + pIn->iBase = iReg - i; + pIn->nPrefix = i; + }else{ + pIn->nPrefix = 0; + } + }else{ + pIn->eEndLoopOp = OP_Noop; + } + pIn++; + } + } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } + }else{ + pLevel->u.in.nIn = 0; + } + sqlite3DbFree(pParse->db, aiMap); +#endif + } + + /* As an optimization, try to disable the WHERE clause term that is + ** driving the index as it will always be true. The correct answer is + ** obtained regardless, but we might get the answer with fewer CPU cycles + ** by omitting the term. + ** + ** But do not disable the term unless we are certain that the term is + ** not a transitive constraint. For an example of where that does not + ** work, see https://sqlite.org/forum/forumpost/eb8613976a (2021-05-04) + */ + if( (pLevel->pWLoop->wsFlags & WHERE_TRANSCONS)==0 + || (pTerm->eOperator & WO_EQUIV)==0 + ){ + disableTerm(pLevel, pTerm); + } + + return iReg; +} + +/* +** Generate code that will evaluate all == and IN constraints for an +** index scan. +** +** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). +** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 +** The index has as many as three equality constraints, but in this +** example, the third "c" value is an inequality. So only two +** constraints are coded. This routine will generate code to evaluate +** a==5 and b IN (1,2,3). The current values for a and b will be stored +** in consecutive registers and the index of the first register is returned. +** +** In the example above nEq==2. But this subroutine works for any value +** of nEq including 0. If nEq==0, this routine is nearly a no-op. +** The only thing it does is allocate the pLevel->iMem memory cell and +** compute the affinity string. +** +** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints +** are == or IN and are covered by the nEq. nExtraReg is 1 if there is +** an inequality constraint (such as the "c>=5 AND c<10" in the example) that +** occurs after the nEq quality constraints. +** +** This routine allocates a range of nEq+nExtraReg memory cells and returns +** the index of the first memory cell in that range. The code that +** calls this routine will use that memory range to store keys for +** start and termination conditions of the loop. +** key value of the loop. If one or more IN operators appear, then +** this routine allocates an additional nEq memory cells for internal +** use. +** +** Before returning, *pzAff is set to point to a buffer containing a +** copy of the column affinity string of the index allocated using +** sqlite3DbMalloc(). Except, entries in the copy of the string associated +** with equality constraints that use BLOB or NONE affinity are set to +** SQLITE_AFF_BLOB. This is to deal with SQL such as the following: +** +** CREATE TABLE t1(a TEXT PRIMARY KEY, b); +** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b; +** +** In the example above, the index on t1(a) has TEXT affinity. But since +** the right hand side of the equality constraint (t2.b) has BLOB/NONE affinity, +** no conversion should be attempted before using a t2.b value as part of +** a key to search the index. Hence the first byte in the returned affinity +** string in this example would be set to SQLITE_AFF_BLOB. +*/ +static int codeAllEqualityTerms( + Parse *pParse, /* Parsing context */ + WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ + int bRev, /* Reverse the order of IN operators */ + int nExtraReg, /* Number of extra registers to allocate */ + char **pzAff /* OUT: Set to point to affinity string */ +){ + u16 nEq; /* The number of == or IN constraints to code */ + u16 nSkip; /* Number of left-most columns to skip */ + Vdbe *v = pParse->pVdbe; /* The vm under construction */ + Index *pIdx; /* The index being used for this loop */ + WhereTerm *pTerm; /* A single constraint term */ + WhereLoop *pLoop; /* The WhereLoop object */ + int j; /* Loop counter */ + int regBase; /* Base register */ + int nReg; /* Number of registers to allocate */ + char *zAff; /* Affinity string to return */ + + /* This module is only called on query plans that use an index. */ + pLoop = pLevel->pWLoop; + assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); + nEq = pLoop->u.btree.nEq; + nSkip = pLoop->nSkip; + pIdx = pLoop->u.btree.pIndex; + assert( pIdx!=0 ); + + /* Figure out how many memory cells we will need then allocate them. + */ + regBase = pParse->nMem + 1; + nReg = nEq + nExtraReg; + pParse->nMem += nReg; + + zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); + assert( zAff!=0 || pParse->db->mallocFailed ); + + if( nSkip ){ + int iIdxCur = pLevel->iIdxCur; + sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1); + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); + j = sqlite3VdbeAddOp0(v, OP_Goto); + assert( pLevel->addrSkip==0 ); + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), + iIdxCur, 0, regBase, nSkip); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + sqlite3VdbeJumpHere(v, j); + for(j=0; jaiColumn[j]==XN_EXPR ); + VdbeComment((v, "%s", explainIndexColumnName(pIdx, j))); + } + } + + /* Evaluate the equality constraints + */ + assert( zAff==0 || (int)strlen(zAff)>=nEq ); + for(j=nSkip; jaLTerm[j]; + assert( pTerm!=0 ); + /* The following testcase is true for indices with redundant columns. + ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ + testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); + if( r1!=regBase+j ){ + if( nReg==1 ){ + sqlite3ReleaseTempReg(pParse, regBase); + regBase = r1; + }else{ + sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); + } + } + if( pTerm->eOperator & WO_IN ){ + if( pTerm->pExpr->flags & EP_xIsSelect ){ + /* No affinity ever needs to be (or should be) applied to a value + ** from the RHS of an "? IN (SELECT ...)" expression. The + ** sqlite3FindInIndex() routine has already ensured that the + ** affinity of the comparison has been applied to the value. */ + if( zAff ) zAff[j] = SQLITE_AFF_BLOB; + } + }else if( (pTerm->eOperator & WO_ISNULL)==0 ){ + Expr *pRight = pTerm->pExpr->pRight; + if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + VdbeCoverage(v); + } + if( pParse->nErr==0 ){ + assert( pParse->db->mallocFailed==0 ); + if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ + zAff[j] = SQLITE_AFF_BLOB; + } + if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ + zAff[j] = SQLITE_AFF_BLOB; + } + } + } + } + *pzAff = zAff; + return regBase; +} + +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS +/* +** If the most recently coded instruction is a constant range constraint +** (a string literal) that originated from the LIKE optimization, then +** set P3 and P5 on the OP_String opcode so that the string will be cast +** to a BLOB at appropriate times. +** +** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range +** expression: "x>='ABC' AND x<'abd'". But this requires that the range +** scan loop run twice, once for strings and a second time for BLOBs. +** The OP_String opcodes on the second pass convert the upper and lower +** bound string constants to blobs. This routine makes the necessary changes +** to the OP_String opcodes for that to happen. +** +** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then +** only the one pass through the string space is required, so this routine +** becomes a no-op. +*/ +static void whereLikeOptimizationStringFixup( + Vdbe *v, /* prepared statement under construction */ + WhereLevel *pLevel, /* The loop that contains the LIKE operator */ + WhereTerm *pTerm /* The upper or lower bound just coded */ +){ + if( pTerm->wtFlags & TERM_LIKEOPT ){ + VdbeOp *pOp; + assert( pLevel->iLikeRepCntr>0 ); + pOp = sqlite3VdbeGetLastOp(v); + assert( pOp!=0 ); + assert( pOp->opcode==OP_String8 + || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); + pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ + pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ + } +} +#else +# define whereLikeOptimizationStringFixup(A,B,C) +#endif + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Information is passed from codeCursorHint() down to individual nodes of +** the expression tree (by sqlite3WalkExpr()) using an instance of this +** structure. +*/ +struct CCurHint { + int iTabCur; /* Cursor for the main table */ + int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */ + Index *pIdx; /* The index used to access the table */ +}; + +/* +** This function is called for every node of an expression that is a candidate +** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference +** the table CCurHint.iTabCur, verify that the same column can be +** accessed through the index. If it cannot, then set pWalker->eCode to 1. +*/ +static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ + struct CCurHint *pHint = pWalker->u.pCCurHint; + assert( pHint->pIdx!=0 ); + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pHint->iTabCur + && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0 + ){ + pWalker->eCode = 1; + } + return WRC_Continue; +} + +/* +** Test whether or not expression pExpr, which was part of a WHERE clause, +** should be included in the cursor-hint for a table that is on the rhs +** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the +** expression is not suitable. +** +** An expression is unsuitable if it might evaluate to non NULL even if +** a TK_COLUMN node that does affect the value of the expression is set +** to NULL. For example: +** +** col IS NULL +** col IS NOT NULL +** coalesce(col, 1) +** CASE WHEN col THEN 0 ELSE 1 END +*/ +static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_IS + || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT + || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE + ){ + pWalker->eCode = 1; + }else if( pExpr->op==TK_FUNCTION ){ + int d1; + char d2[4]; + if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ + pWalker->eCode = 1; + } + } + + return WRC_Continue; +} + + +/* +** This function is called on every node of an expression tree used as an +** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN +** that accesses any table other than the one identified by +** CCurHint.iTabCur, then do the following: +** +** 1) allocate a register and code an OP_Column instruction to read +** the specified column into the new register, and +** +** 2) transform the expression node to a TK_REGISTER node that reads +** from the newly populated register. +** +** Also, if the node is a TK_COLUMN that does access the table identified +** by pCCurHint.iTabCur, and an index is being used (which we will +** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into +** an access of the index rather than the original table. +*/ +static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ + int rc = WRC_Continue; + int reg; + struct CCurHint *pHint = pWalker->u.pCCurHint; + if( pExpr->op==TK_COLUMN ){ + if( pExpr->iTable!=pHint->iTabCur ){ + reg = ++pWalker->pParse->nMem; /* Register for column value */ + reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); + pExpr->op = TK_REGISTER; + pExpr->iTable = reg; + }else if( pHint->pIdx!=0 ){ + pExpr->iTable = pHint->iIdxCur; + pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); + assert( pExpr->iColumn>=0 ); + } + }else if( pExpr->pAggInfo ){ + rc = WRC_Prune; + reg = ++pWalker->pParse->nMem; /* Register for column value */ + reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); + pExpr->op = TK_REGISTER; + pExpr->iTable = reg; + }else if( pExpr->op==TK_TRUEFALSE ){ + /* Do not walk disabled expressions. tag-20230504-1 */ + return WRC_Prune; + } + return rc; +} + +/* +** Insert an OP_CursorHint instruction if it is appropriate to do so. +*/ +static void codeCursorHint( + SrcItem *pTabItem, /* FROM clause item */ + WhereInfo *pWInfo, /* The where clause */ + WhereLevel *pLevel, /* Which loop to provide hints for */ + WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ +){ + Parse *pParse = pWInfo->pParse; + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + Expr *pExpr = 0; + WhereLoop *pLoop = pLevel->pWLoop; + int iCur; + WhereClause *pWC; + WhereTerm *pTerm; + int i, j; + struct CCurHint sHint; + Walker sWalker; + + if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; + iCur = pLevel->iTabCur; + assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor ); + sHint.iTabCur = iCur; + sHint.iIdxCur = pLevel->iIdxCur; + sHint.pIdx = pLoop->u.btree.pIndex; + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.pParse = pParse; + sWalker.u.pCCurHint = &sHint; + pWC = &pWInfo->sWC; + for(i=0; inBase; i++){ + pTerm = &pWC->a[i]; + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( pTerm->prereqAll & pLevel->notReady ) continue; + + /* Any terms specified as part of the ON(...) clause for any LEFT + ** JOIN for which the current table is not the rhs are omitted + ** from the cursor-hint. + ** + ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms + ** that were specified as part of the WHERE clause must be excluded. + ** This is to address the following: + ** + ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL; + ** + ** Say there is a single row in t2 that matches (t1.a=t2.b), but its + ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is + ** pushed down to the cursor, this row is filtered out, causing + ** SQLite to synthesize a row of NULL values. Which does match the + ** WHERE clause, and so the query returns a row. Which is incorrect. + ** + ** For the same reason, WHERE terms such as: + ** + ** WHERE 1 = (t2.c IS NULL) + ** + ** are also excluded. See codeCursorHintIsOrFunction() for details. + */ + if( pTabItem->fg.jointype & JT_LEFT ){ + Expr *pExpr = pTerm->pExpr; + if( !ExprHasProperty(pExpr, EP_OuterON) + || pExpr->w.iJoin!=pTabItem->iCursor + ){ + sWalker.eCode = 0; + sWalker.xExprCallback = codeCursorHintIsOrFunction; + sqlite3WalkExpr(&sWalker, pTerm->pExpr); + if( sWalker.eCode ) continue; + } + }else{ + if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) continue; + } + + /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize + ** the cursor. These terms are not needed as hints for a pure range + ** scan (that has no == terms) so omit them. */ + if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){ + for(j=0; jnLTerm && pLoop->aLTerm[j]!=pTerm; j++){} + if( jnLTerm ) continue; + } + + /* No subqueries or non-deterministic functions allowed */ + if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; + + /* For an index scan, make sure referenced columns are actually in + ** the index. */ + if( sHint.pIdx!=0 ){ + sWalker.eCode = 0; + sWalker.xExprCallback = codeCursorHintCheckExpr; + sqlite3WalkExpr(&sWalker, pTerm->pExpr); + if( sWalker.eCode ) continue; + } + + /* If we survive all prior tests, that means this term is worth hinting */ + pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); + } + if( pExpr!=0 ){ + sWalker.xExprCallback = codeCursorHintFixExpr; + if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr); + sqlite3VdbeAddOp4(v, OP_CursorHint, + (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, + (const char*)pExpr, P4_EXPR); + } +} +#else +# define codeCursorHint(A,B,C,D) /* No-op */ +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + +/* +** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains +** a rowid value just read from cursor iIdxCur, open on index pIdx. This +** function generates code to do a deferred seek of cursor iCur to the +** rowid stored in register iRowid. +** +** Normally, this is just: +** +** OP_DeferredSeek $iCur $iRowid +** +** Which causes a seek on $iCur to the row with rowid $iRowid. +** +** However, if the scan currently being coded is a branch of an OR-loop and +** the statement currently being coded is a SELECT, then additional information +** is added that might allow OP_Column to omit the seek and instead do its +** lookup on the index, thus avoiding an expensive seek operation. To +** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur +** and P4 is set to an array of integers containing one entry for each column +** in the table. For each table column, if the column is the i'th +** column of the index, then the corresponding array entry is set to (i+1). +** If the column does not appear in the index at all, the array entry is set +** to 0. The OP_Column opcode can check this array to see if the column it +** wants is in the index and if it is, it will substitute the index cursor +** and column number and continue with those new values, rather than seeking +** the table cursor. +*/ +static void codeDeferredSeek( + WhereInfo *pWInfo, /* Where clause context */ + Index *pIdx, /* Index scan is using */ + int iCur, /* Cursor for IPK b-tree */ + int iIdxCur /* Index cursor */ +){ + Parse *pParse = pWInfo->pParse; /* Parse context */ + Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */ + + assert( iIdxCur>0 ); + assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); + + pWInfo->bDeferredSeek = 1; + sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); + if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) + && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) + ){ + int i; + Table *pTab = pIdx->pTable; + u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1)); + if( ai ){ + ai[0] = pTab->nCol; + for(i=0; inColumn-1; i++){ + int x1, x2; + assert( pIdx->aiColumn[i]nCol ); + x1 = pIdx->aiColumn[i]; + x2 = sqlite3TableColumnToStorage(pTab, x1); + testcase( x1!=x2 ); + if( x1>=0 ) ai[x2+1] = i+1; + } + sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); + } + } +} + +/* +** If the expression passed as the second argument is a vector, generate +** code to write the first nReg elements of the vector into an array +** of registers starting with iReg. +** +** If the expression is not a vector, then nReg must be passed 1. In +** this case, generate code to evaluate the expression and leave the +** result in register iReg. +*/ +static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ + assert( nReg>0 ); + if( p && sqlite3ExprIsVector(p) ){ +#ifndef SQLITE_OMIT_SUBQUERY + if( ExprUseXSelect(p) ){ + Vdbe *v = pParse->pVdbe; + int iSelect; + assert( p->op==TK_SELECT ); + iSelect = sqlite3CodeSubselect(pParse, p); + sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); + }else +#endif + { + int i; + const ExprList *pList; + assert( ExprUseXList(p) ); + pList = p->x.pList; + assert( nReg<=pList->nExpr ); + for(i=0; ia[i].pExpr, iReg+i); + } + } + }else{ + assert( nReg==1 || pParse->nErr ); + sqlite3ExprCode(pParse, p, iReg); + } +} + +/* +** The pTruth expression is always true because it is the WHERE clause +** a partial index that is driving a query loop. Look through all of the +** WHERE clause terms on the query, and if any of those terms must be +** true because pTruth is true, then mark those WHERE clause terms as +** coded. +*/ +static void whereApplyPartialIndexConstraints( + Expr *pTruth, + int iTabCur, + WhereClause *pWC +){ + int i; + WhereTerm *pTerm; + while( pTruth->op==TK_AND ){ + whereApplyPartialIndexConstraints(pTruth->pLeft, iTabCur, pWC); + pTruth = pTruth->pRight; + } + for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + Expr *pExpr; + if( pTerm->wtFlags & TERM_CODED ) continue; + pExpr = pTerm->pExpr; + if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){ + pTerm->wtFlags |= TERM_CODED; + } + } +} + +/* +** This routine is called right after An OP_Filter has been generated and +** before the corresponding index search has been performed. This routine +** checks to see if there are additional Bloom filters in inner loops that +** can be checked prior to doing the index lookup. If there are available +** inner-loop Bloom filters, then evaluate those filters now, before the +** index lookup. The idea is that a Bloom filter check is way faster than +** an index lookup, and the Bloom filter might return false, meaning that +** the index lookup can be skipped. +** +** We know that an inner loop uses a Bloom filter because it has the +** WhereLevel.regFilter set. If an inner-loop Bloom filter is checked, +** then clear the WhereLevel.regFilter value to prevent the Bloom filter +** from being checked a second time when the inner loop is evaluated. +*/ +static SQLITE_NOINLINE void filterPullDown( + Parse *pParse, /* Parsing context */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + int addrNxt, /* Jump here to bypass inner loops */ + Bitmask notReady /* Loops that are not ready */ +){ + while( ++iLevel < pWInfo->nLevel ){ + WhereLevel *pLevel = &pWInfo->a[iLevel]; + WhereLoop *pLoop = pLevel->pWLoop; + if( pLevel->regFilter==0 ) continue; + if( pLevel->pWLoop->nSkip ) continue; + /* ,--- Because sqlite3ConstructBloomFilter() has will not have set + ** vvvvv--' pLevel->regFilter if this were true. */ + if( NEVER(pLoop->prereq & notReady) ) continue; + assert( pLevel->addrBrk==0 ); + pLevel->addrBrk = addrNxt; + if( pLoop->wsFlags & WHERE_IPK ){ + WhereTerm *pTerm = pLoop->aLTerm[0]; + int regRowid; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + regRowid = sqlite3GetTempReg(pParse); + regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MustBeInt, regRowid, addrNxt); + VdbeCoverage(pParse->pVdbe); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, regRowid, 1); + VdbeCoverage(pParse->pVdbe); + }else{ + u16 nEq = pLoop->u.btree.nEq; + int r1; + char *zStartAff; + + assert( pLoop->wsFlags & WHERE_INDEXED ); + assert( (pLoop->wsFlags & WHERE_COLUMN_IN)==0 ); + r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff); + codeApplyAffinity(pParse, r1, nEq, zStartAff); + sqlite3DbFree(pParse->db, zStartAff); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, r1, nEq); + VdbeCoverage(pParse->pVdbe); + } + pLevel->regFilter = 0; + pLevel->addrBrk = 0; + } +} + +/* +** Generate code for the start of the iLevel-th loop in the WHERE clause +** implementation described by pWInfo. +*/ +SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + Parse *pParse, /* Parsing context */ + Vdbe *v, /* Prepared statement under construction */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + WhereLevel *pLevel, /* The current level pointer */ + Bitmask notReady /* Which tables are currently available */ +){ + int j, k; /* Loop counters */ + int iCur; /* The VDBE cursor for the table */ + int addrNxt; /* Where to jump to continue with the next IN case */ + int bRev; /* True if we need to scan in reverse order */ + WhereLoop *pLoop; /* The WhereLoop object being coded */ + WhereClause *pWC; /* Decomposition of the entire WHERE clause */ + WhereTerm *pTerm; /* A WHERE clause term */ + sqlite3 *db; /* Database connection */ + SrcItem *pTabItem; /* FROM clause term being coded */ + int addrBrk; /* Jump here to break out of the loop */ + int addrHalt; /* addrBrk for the outermost loop */ + int addrCont; /* Jump here to continue with next cycle */ + int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ + int iReleaseReg = 0; /* Temp register to free before returning */ + Index *pIdx = 0; /* Index used by loop (if any) */ + int iLoop; /* Iteration of constraint generator loop */ + + pWC = &pWInfo->sWC; + db = pParse->db; + pLoop = pLevel->pWLoop; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + iCur = pTabItem->iCursor; + pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); + bRev = (pWInfo->revMask>>iLevel)&1; + VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); +#if WHERETRACE_ENABLED /* 0x4001 */ + if( sqlite3WhereTrace & 0x1 ){ + sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", + iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); + if( sqlite3WhereTrace & 0x1000 ){ + sqlite3WhereLoopPrint(pLoop, pWC); + } + } + if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + if( iLevel==0 ){ + sqlite3DebugPrintf("WHERE clause being coded:\n"); + sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); + } + sqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); + sqlite3WhereClausePrint(pWC); + } +#endif + + /* Create labels for the "break" and "continue" instructions + ** for the current loop. Jump to addrBrk to break out of a loop. + ** Jump to cont to go immediately to the next iteration of the + ** loop. + ** + ** When there is an IN operator, we also have a "addrNxt" label that + ** means to continue with the next IN value combination. When + ** there are no IN operators in the constraints, the "addrNxt" label + ** is the same as "addrBrk". + */ + addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); + + /* If this is the right table of a LEFT OUTER JOIN, allocate and + ** initialize a memory cell that records if this table matches any + ** row of the left table of the join. + */ + assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) + || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 + ); + if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ + pLevel->iLeftJoin = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); + VdbeComment((v, "init LEFT JOIN no-match flag")); + } + + /* Compute a safe address to jump to if we discover that the table for + ** this loop is empty and can never contribute content. */ + for(j=iLevel; j>0; j--){ + if( pWInfo->a[j].iLeftJoin ) break; + if( pWInfo->a[j].pRJ ) break; + } + addrHalt = pWInfo->a[j].addrBrk; + + /* Special case of a FROM clause subquery implemented as a co-routine */ + if( pTabItem->fg.viaCoroutine ){ + int regYield = pTabItem->regReturn; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); + VdbeCoverage(v); + VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); + pLevel->op = OP_Goto; + }else + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + /* Case 1: The table is a virtual-table. Use the VFilter and VNext + ** to access the data. + */ + int iReg; /* P3 Value for OP_VFilter */ + int addrNotFound; + int nConstraint = pLoop->nLTerm; + + iReg = sqlite3GetTempRange(pParse, nConstraint+2); + addrNotFound = pLevel->addrBrk; + for(j=0; jaLTerm[j]; + if( NEVER(pTerm==0) ) continue; + if( pTerm->eOperator & WO_IN ){ + if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ + int iTab = pParse->nTab++; + int iCache = ++pParse->nMem; + sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab); + sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); + }else{ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + addrNotFound = pLevel->addrNxt; + } + }else{ + Expr *pRight = pTerm->pExpr->pRight; + codeExprOrVector(pParse, pRight, iTarget, 1); + if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET + && pLoop->u.vtab.bOmitOffset + ){ + assert( pTerm->eOperator==WO_AUX ); + assert( pWInfo->pSelect!=0 ); + assert( pWInfo->pSelect->iOffset>0 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset); + VdbeComment((v,"Zero OFFSET counter")); + } + } + } + sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); + sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); + sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, + pLoop->u.vtab.idxStr, + pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); + VdbeCoverage(v); + pLoop->u.vtab.needFree = 0; + /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed + ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */ + if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0; + pLevel->p1 = iCur; + pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + + for(j=0; jaLTerm[j]; + if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ + disableTerm(pLevel, pTerm); + continue; + } + if( (pTerm->eOperator & WO_IN)!=0 + && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 + && !db->mallocFailed + ){ + Expr *pCompare; /* The comparison operator */ + Expr *pRight; /* RHS of the comparison */ + VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ + int iIn; /* IN loop corresponding to the j-th constraint */ + + /* Reload the constraint value into reg[iReg+j+2]. The same value + ** was loaded into the same register prior to the OP_VFilter, but + ** the xFilter implementation might have changed the datatype or + ** encoding of the value in the register, so it *must* be reloaded. + */ + for(iIn=0; ALWAYS(iInu.in.nIn); iIn++){ + pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); + if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2) + || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2) + ){ + testcase( pOp->opcode==OP_Rowid ); + sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + break; + } + } + + /* Generate code that will continue to the next row if + ** the IN constraint is not satisfied + */ + pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); + if( !db->mallocFailed ){ + int iFld = pTerm->u.x.iField; + Expr *pLeft = pTerm->pExpr->pLeft; + assert( pLeft!=0 ); + if( iFld>0 ){ + assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); + assert( iFld<=pLeft->x.pList->nExpr ); + pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr; + }else{ + pCompare->pLeft = pLeft; + } + pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); + if( pRight ){ + pRight->iTable = iReg+j+2; + sqlite3ExprIfFalse( + pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL + ); + } + pCompare->pLeft = 0; + } + sqlite3ExprDelete(db, pCompare); + } + } + + /* These registers need to be preserved in case there is an IN operator + ** loop. So we could deallocate the registers here (and potentially + ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems + ** simpler and safer to simply not reuse the registers. + ** + ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); + */ + }else +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + if( (pLoop->wsFlags & WHERE_IPK)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0 + ){ + /* Case 2: We can directly reference a single row using an + ** equality comparison against the ROWID field. Or + ** we reference multiple rows using a "rowid IN (...)" + ** construct. + */ + assert( pLoop->u.btree.nEq==1 ); + pTerm = pLoop->aLTerm[0]; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + iReleaseReg = ++pParse->nMem; + iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); + if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); + addrNxt = pLevel->addrNxt; + if( pLevel->regFilter ){ + sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); + VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + iRowidReg, 1); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); + VdbeCoverage(v); + pLevel->op = OP_Noop; + }else if( (pLoop->wsFlags & WHERE_IPK)!=0 + && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 + ){ + /* Case 3: We have an inequality comparison against the ROWID field. + */ + int testOp = OP_Noop; + int start; + int memEndValue = 0; + WhereTerm *pStart, *pEnd; + + j = 0; + pStart = pEnd = 0; + if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++]; + if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++]; + assert( pStart!=0 || pEnd!=0 ); + if( bRev ){ + pTerm = pStart; + pStart = pEnd; + pEnd = pTerm; + } + codeCursorHint(pTabItem, pWInfo, pLevel, pEnd); + if( pStart ){ + Expr *pX; /* The expression that defines the start bound */ + int r1, rTemp; /* Registers for holding the start boundary */ + int op; /* Cursor seek operation */ + + /* The following constant maps TK_xx codes into corresponding + ** seek opcodes. It depends on a particular ordering of TK_xx + */ + const u8 aMoveOp[] = { + /* TK_GT */ OP_SeekGT, + /* TK_LE */ OP_SeekLE, + /* TK_LT */ OP_SeekLT, + /* TK_GE */ OP_SeekGE + }; + assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ + assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ + assert( TK_GE==TK_GT+3 ); /* ... is correct. */ + + assert( (pStart->wtFlags & TERM_VNULL)==0 ); + testcase( pStart->wtFlags & TERM_VIRTUAL ); + pX = pStart->pExpr; + assert( pX!=0 ); + testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ + if( sqlite3ExprIsVector(pX->pRight) ){ + r1 = rTemp = sqlite3GetTempReg(pParse); + codeExprOrVector(pParse, pX->pRight, r1, 1); + testcase( pX->op==TK_GT ); + testcase( pX->op==TK_GE ); + testcase( pX->op==TK_LT ); + testcase( pX->op==TK_LE ); + op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1]; + assert( pX->op!=TK_GT || op==OP_SeekGE ); + assert( pX->op!=TK_GE || op==OP_SeekGE ); + assert( pX->op!=TK_LT || op==OP_SeekLE ); + assert( pX->op!=TK_LE || op==OP_SeekLE ); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); + disableTerm(pLevel, pStart); + op = aMoveOp[(pX->op - TK_GT)]; + } + sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1); + VdbeComment((v, "pk")); + VdbeCoverageIf(v, pX->op==TK_GT); + VdbeCoverageIf(v, pX->op==TK_LE); + VdbeCoverageIf(v, pX->op==TK_LT); + VdbeCoverageIf(v, pX->op==TK_GE); + sqlite3ReleaseTempReg(pParse, rTemp); + }else{ + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + } + if( pEnd ){ + Expr *pX; + pX = pEnd->pExpr; + assert( pX!=0 ); + assert( (pEnd->wtFlags & TERM_VNULL)==0 ); + testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ + testcase( pEnd->wtFlags & TERM_VIRTUAL ); + memEndValue = ++pParse->nMem; + codeExprOrVector(pParse, pX->pRight, memEndValue, 1); + if( 0==sqlite3ExprIsVector(pX->pRight) + && (pX->op==TK_LT || pX->op==TK_GT) + ){ + testOp = bRev ? OP_Le : OP_Ge; + }else{ + testOp = bRev ? OP_Lt : OP_Gt; + } + if( 0==sqlite3ExprIsVector(pX->pRight) ){ + disableTerm(pLevel, pEnd); + } + } + start = sqlite3VdbeCurrentAddr(v); + pLevel->op = bRev ? OP_Prev : OP_Next; + pLevel->p1 = iCur; + pLevel->p2 = start; + assert( pLevel->p5==0 ); + if( testOp!=OP_Noop ){ + iRowidReg = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); + sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); + VdbeCoverageIf(v, testOp==OP_Le); + VdbeCoverageIf(v, testOp==OP_Lt); + VdbeCoverageIf(v, testOp==OP_Ge); + VdbeCoverageIf(v, testOp==OP_Gt); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); + } + }else if( pLoop->wsFlags & WHERE_INDEXED ){ + /* Case 4: A scan using an index. + ** + ** The WHERE clause may contain zero or more equality + ** terms ("==" or "IN" operators) that refer to the N + ** left-most columns of the index. It may also contain + ** inequality constraints (>, <, >= or <=) on the indexed + ** column that immediately follows the N equalities. Only + ** the right-most column can be an inequality - the rest must + ** use the "==" and "IN" operators. For example, if the + ** index is on (x,y,z), then the following clauses are all + ** optimized: + ** + ** x=5 + ** x=5 AND y=10 + ** x=5 AND y<10 + ** x=5 AND y>5 AND y<10 + ** x=5 AND y=5 AND z<=10 + ** + ** The z<10 term of the following cannot be used, only + ** the x=5 term: + ** + ** x=5 AND z<10 + ** + ** N may be zero if there are inequality constraints. + ** If there are no inequality constraints, then N is at + ** least one. + ** + ** This case is also used when there are no WHERE clause + ** constraints but an index is selected anyway, in order + ** to force the output order to conform to an ORDER BY. + */ + static const u8 aStartOp[] = { + 0, + 0, + OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ + OP_Last, /* 3: (!start_constraints && startEq && bRev) */ + OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */ + OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */ + OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */ + OP_SeekLE /* 7: (start_constraints && startEq && bRev) */ + }; + static const u8 aEndOp[] = { + OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */ + OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */ + OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */ + OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */ + }; + u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ + u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */ + u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */ + int regBase; /* Base register holding constraint values */ + WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ + WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ + int startEq; /* True if range start uses ==, >= or <= */ + int endEq; /* True if range end uses ==, >= or <= */ + int start_constraints; /* Start of range is constrained */ + int nConstraint; /* Number of constraint terms */ + int iIdxCur; /* The VDBE cursor for the index */ + int nExtraReg = 0; /* Number of extra registers needed */ + int op; /* Instruction opcode */ + char *zStartAff; /* Affinity for start of range constraint */ + char *zEndAff = 0; /* Affinity for end of range constraint */ + u8 bSeekPastNull = 0; /* True to seek past initial nulls */ + u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ + int omitTable; /* True if we use the index only */ + int regBignull = 0; /* big-null flag register */ + int addrSeekScan = 0; /* Opcode of the OP_SeekScan, if any */ + + pIdx = pLoop->u.btree.pIndex; + iIdxCur = pLevel->iIdxCur; + assert( nEq>=pLoop->nSkip ); + + /* Find any inequality constraint terms for the start and end + ** of the range. + */ + j = nEq; + if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ + pRangeStart = pLoop->aLTerm[j++]; + nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm); + /* Like optimization range constraints always occur in pairs */ + assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || + (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); + } + if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ + pRangeEnd = pLoop->aLTerm[j++]; + nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop); +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ + assert( pRangeStart!=0 ); /* LIKE opt constraints */ + assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ + pLevel->iLikeRepCntr = (u32)++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr); + VdbeComment((v, "LIKE loop counter")); + pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); + /* iLikeRepCntr actually stores 2x the counter register number. The + ** bottom bit indicates whether the search order is ASC or DESC. */ + testcase( bRev ); + testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); + assert( (bRev & ~1)==0 ); + pLevel->iLikeRepCntr <<=1; + pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC); + } +#endif + if( pRangeStart==0 ){ + j = pIdx->aiColumn[nEq]; + if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){ + bSeekPastNull = 1; + } + } + } + assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); + + /* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses + ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS + ** FIRST). In both cases separate ordered scans are made of those + ** index entries for which the column is null and for those for which + ** it is not. For an ASC sort, the non-NULL entries are scanned first. + ** For DESC, NULL entries are scanned first. + */ + if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0 + && (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0 + ){ + assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 ); + assert( pRangeEnd==0 && pRangeStart==0 ); + testcase( pLoop->nSkip>0 ); + nExtraReg = 1; + bSeekPastNull = 1; + pLevel->regBignull = regBignull = ++pParse->nMem; + if( pLevel->iLeftJoin ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull); + } + pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); + } + + /* If we are doing a reverse order scan on an ascending index, or + ** a forward order scan on a descending index, interchange the + ** start and end terms (pRangeStart and pRangeEnd). + */ + if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){ + SWAP(WhereTerm *, pRangeEnd, pRangeStart); + SWAP(u8, bSeekPastNull, bStopAtNull); + SWAP(u8, nBtm, nTop); + } + + if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){ + /* In case OP_SeekScan is used, ensure that the index cursor does not + ** point to a valid row for the first iteration of this loop. */ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + + /* Generate code to evaluate all constraint terms using == or IN + ** and store the values of those terms in an array of registers + ** starting at regBase. + */ + codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); + regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); + if( zStartAff && nTop ){ + zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); + } + addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt); + + testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); + testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); + testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 ); + testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 ); + startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE); + endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE); + start_constraints = pRangeStart || nEq>0; + + /* Seek the index cursor to the start of the range. */ + nConstraint = nEq; + if( pRangeStart ){ + Expr *pRight = pRangeStart->pExpr->pRight; + codeExprOrVector(pParse, pRight, regBase+nEq, nBtm); + whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); + if( (pRangeStart->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); + } + if( zStartAff ){ + updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]); + } + nConstraint += nBtm; + testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); + if( sqlite3ExprIsVector(pRight)==0 ){ + disableTerm(pLevel, pRangeStart); + }else{ + startEq = 1; + } + bSeekPastNull = 0; + }else if( bSeekPastNull ){ + startEq = 0; + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + start_constraints = 1; + nConstraint++; + }else if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + start_constraints = 1; + nConstraint++; + } + codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); + if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){ + /* The skip-scan logic inside the call to codeAllEqualityConstraints() + ** above has already left the cursor sitting on the correct row, + ** so no further seeking is needed */ + }else{ + if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); + VdbeComment((v, "NULL-scan pass ctr")); + } + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + regBase, nEq); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } + + op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; + assert( op!=0 ); + if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){ + assert( regBignull==0 ); + /* TUNING: The OP_SeekScan opcode seeks to reduce the number + ** of expensive seek operations by replacing a single seek with + ** 1 or more step operations. The question is, how many steps + ** should we try before giving up and going with a seek. The cost + ** of a seek is proportional to the logarithm of the of the number + ** of entries in the tree, so basing the number of steps to try + ** on the estimated number of rows in the btree seems like a good + ** guess. */ + addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, + (pIdx->aiRowLogEst[0]+9)/10); + if( pRangeStart || pRangeEnd ){ + sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1); + addrSeekScan = 0; + } + VdbeCoverage(v); + } + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); + + assert( bSeekPastNull==0 || bStopAtNull==0 ); + if( regBignull ){ + assert( bSeekPastNull==1 || bStopAtNull==1 ); + assert( bSeekPastNull==!bStopAtNull ); + assert( bStopAtNull==startEq ); + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + nConstraint-startEq); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE); + } + } + + /* Load the value for the inequality constraint at the end of the + ** range (if any). + */ + nConstraint = nEq; + assert( pLevel->p2==0 ); + if( pRangeEnd ){ + Expr *pRight = pRangeEnd->pExpr->pRight; + assert( addrSeekScan==0 ); + codeExprOrVector(pParse, pRight, regBase+nEq, nTop); + whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); + if( (pRangeEnd->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); + } + if( zEndAff ){ + updateRangeAffinityStr(pRight, nTop, zEndAff); + codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); + }else{ + assert( pParse->db->mallocFailed ); + } + nConstraint += nTop; + testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); + + if( sqlite3ExprIsVector(pRight)==0 ){ + disableTerm(pLevel, pRangeEnd); + }else{ + endEq = 1; + } + }else if( bStopAtNull ){ + if( regBignull==0 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + endEq = 0; + } + nConstraint++; + } + if( zStartAff ) sqlite3DbNNFreeNN(db, zStartAff); + if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff); + + /* Top of the loop body */ + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + + /* Check if the index cursor is past the end of the range. */ + if( nConstraint ){ + if( regBignull ){ + /* Except, skip the end-of-range check while doing the NULL-scan */ + sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); + VdbeComment((v, "If NULL-scan 2nd pass")); + VdbeCoverage(v); + } + op = aEndOp[bRev*2 + endEq]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan); + } + if( regBignull ){ + /* During a NULL-scan, check to see if we have reached the end of + ** the NULLs */ + assert( bSeekPastNull==!bStopAtNull ); + assert( bSeekPastNull+bStopAtNull==1 ); + assert( nConstraint+bSeekPastNull>0 ); + sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); + VdbeComment((v, "If NULL-scan 1st pass")); + VdbeCoverage(v); + op = aEndOp[bRev*2 + bSeekPastNull]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + nConstraint+bSeekPastNull); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + } + + if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq); + } + + /* Seek the table cursor, if required */ + omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 + && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0; + if( omitTable ){ + /* pIdx is a covering index. No need to access the main table. */ + }else if( HasRowid(pIdx->pTable) ){ + codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); + }else if( iCur!=iIdxCur ){ + Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); + iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); + for(j=0; jnKeyCol; j++){ + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); + } + sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, + iRowidReg, pPk->nKeyCol); VdbeCoverage(v); + } + + if( pLevel->iLeftJoin==0 ){ + /* If a partial index is driving the loop, try to eliminate WHERE clause + ** terms from the query that must be true due to the WHERE clause of + ** the partial index. + ** + ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work + ** for a LEFT JOIN. + */ + if( pIdx->pPartIdxWhere ){ + whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); + } + }else{ + testcase( pIdx->pPartIdxWhere ); + /* The following assert() is not a requirement, merely an observation: + ** The OR-optimization doesn't work for the right hand table of + ** a LEFT JOIN: */ + assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ); + } + + /* Record the instruction used to terminate the loop. */ + if( pLoop->wsFlags & WHERE_ONEROW ){ + pLevel->op = OP_Noop; + }else if( bRev ){ + pLevel->op = OP_Prev; + }else{ + pLevel->op = OP_Next; + } + pLevel->p1 = iIdxCur; + pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0; + if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + }else{ + assert( pLevel->p5==0 ); + } + if( omitTable ) pIdx = 0; + }else + +#ifndef SQLITE_OMIT_OR_OPTIMIZATION + if( pLoop->wsFlags & WHERE_MULTI_OR ){ + /* Case 5: Two or more separately indexed terms connected by OR + ** + ** Example: + ** + ** CREATE TABLE t1(a,b,c,d); + ** CREATE INDEX i1 ON t1(a); + ** CREATE INDEX i2 ON t1(b); + ** CREATE INDEX i3 ON t1(c); + ** + ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13) + ** + ** In the example, there are three indexed terms connected by OR. + ** The top of the loop looks like this: + ** + ** Null 1 # Zero the rowset in reg 1 + ** + ** Then, for each indexed term, the following. The arguments to + ** RowSetTest are such that the rowid of the current row is inserted + ** into the RowSet. If it is already present, control skips the + ** Gosub opcode and jumps straight to the code generated by WhereEnd(). + ** + ** sqlite3WhereBegin() + ** RowSetTest # Insert rowid into rowset + ** Gosub 2 A + ** sqlite3WhereEnd() + ** + ** Following the above, code to terminate the loop. Label A, the target + ** of the Gosub above, jumps to the instruction right after the Goto. + ** + ** Null 1 # Zero the rowset in reg 1 + ** Goto B # The loop is finished. + ** + ** A: # Return data, whatever. + ** + ** Return 2 # Jump back to the Gosub + ** + ** B: + ** + ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then + ** use an ephemeral index instead of a RowSet to record the primary + ** keys of the rows we have already seen. + ** + */ + WhereClause *pOrWc; /* The OR-clause broken out into subterms */ + SrcList *pOrTab; /* Shortened table list or OR-clause generation */ + Index *pCov = 0; /* Potential covering index (or NULL) */ + int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ + + int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ + int regRowset = 0; /* Register for RowSet object */ + int regRowid = 0; /* Register holding rowid */ + int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */ + int iRetInit; /* Address of regReturn init */ + int untestedTerms = 0; /* Some terms not completely tested */ + int ii; /* Loop counter */ + Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ + Table *pTab = pTabItem->pTab; + + pTerm = pLoop->aLTerm[0]; + assert( pTerm!=0 ); + assert( pTerm->eOperator & WO_OR ); + assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); + pOrWc = &pTerm->u.pOrInfo->wc; + pLevel->op = OP_Return; + pLevel->p1 = regReturn; + + /* Set up a new SrcList in pOrTab containing the table being scanned + ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. + ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). + */ + if( pWInfo->nLevel>1 ){ + int nNotReady; /* The number of notReady tables */ + SrcItem *origSrc; /* Original list of tables */ + nNotReady = pWInfo->nLevel - iLevel - 1; + pOrTab = sqlite3DbMallocRawNN(db, + sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); + if( pOrTab==0 ) return notReady; + pOrTab->nAlloc = (u8)(nNotReady + 1); + pOrTab->nSrc = pOrTab->nAlloc; + memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); + origSrc = pWInfo->pTabList->a; + for(k=1; k<=nNotReady; k++){ + memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); + } + }else{ + pOrTab = pWInfo->pTabList; + } + + /* Initialize the rowset register to contain NULL. An SQL NULL is + ** equivalent to an empty rowset. Or, create an ephemeral index + ** capable of holding primary keys in the case of a WITHOUT ROWID. + ** + ** Also initialize regReturn to contain the address of the instruction + ** immediately following the OP_Return at the bottom of the loop. This + ** is required in a few obscure LEFT JOIN cases where control jumps + ** over the top of the loop into the body of it. In this case the + ** correct response for the end-of-loop code (the OP_Return) is to + ** fall through to the next instruction, just as an OP_Next does if + ** called on an uninitialized cursor. + */ + if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ + if( HasRowid(pTab) ){ + regRowset = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + regRowset = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + regRowid = ++pParse->nMem; + } + iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); + + /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y + ** Then for every term xN, evaluate as the subexpression: xN AND y + ** That way, terms in y that are factored into the disjunction will + ** be picked up by the recursive calls to sqlite3WhereBegin() below. + ** + ** Actually, each subexpression is converted to "xN AND w" where w is + ** the "interesting" terms of z - terms that did not originate in the + ** ON or USING clause of a LEFT JOIN, and terms that are usable as + ** indices. + ** + ** This optimization also only applies if the (x1 OR x2 OR ...) term + ** is not contained in the ON clause of a LEFT JOIN. + ** See ticket http://www.sqlite.org/src/info/f2369304e4 + ** + ** 2022-02-04: Do not push down slices of a row-value comparison. + ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, + ** the initialization of the right-hand operand of the vector comparison + ** might not occur, or might occur only in an OR branch that is not + ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. + ** + ** 2022-03-03: Do not push down expressions that involve subqueries. + ** The subquery might get coded as a subroutine. Any table-references + ** in the subquery might be resolved to index-references for the index on + ** the OR branch in which the subroutine is coded. But if the subroutine + ** is invoked from a different OR branch that uses a different index, such + ** index-references will not work. tag-20220303a + ** https://sqlite.org/forum/forumpost/36937b197273d403 + */ + if( pWC->nTerm>1 ){ + int iTerm; + for(iTerm=0; iTermnTerm; iTerm++){ + Expr *pExpr = pWC->a[iTerm].pExpr; + if( &pWC->a[iTerm] == pTerm ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); + testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); + testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); + if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ + continue; + } + if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; + if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */ + pExpr = sqlite3ExprDup(db, pExpr, 0); + pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); + } + if( pAndExpr ){ + /* The extra 0x10000 bit on the opcode is masked off and does not + ** become part of the new Expr.op. However, it does make the + ** op==TK_AND comparison inside of sqlite3PExpr() false, and this + ** prevents sqlite3PExpr() from applying the AND short-circuit + ** optimization, which we do not want here. */ + pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr); + } + } + + /* Run a separate WHERE clause for each term of the OR clause. After + ** eliminating duplicates from other WHERE clauses, the action for each + ** sub-WHERE clause is to to invoke the main loop body as a subroutine. + */ + ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR")); + for(ii=0; iinTerm; ii++){ + WhereTerm *pOrTerm = &pOrWc->a[ii]; + if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ + WhereInfo *pSubWInfo; /* Info for single OR-term scan */ + Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ + Expr *pDelete; /* Local copy of OR clause term */ + int jmp1 = 0; /* Address of jump operation */ + testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pOrExpr, EP_OuterON) + ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */ + pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDelete); + continue; + } + if( pAndExpr ){ + pAndExpr->pLeft = pOrExpr; + pOrExpr = pAndExpr; + } + /* Loop through table entries that match term pOrTerm. */ + ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); + WHERETRACE(0xffffffff, ("Subplan for OR-clause:\n")); + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, + WHERE_OR_SUBCLAUSE, iCovCur); + assert( pSubWInfo || pParse->nErr ); + if( pSubWInfo ){ + WhereLoop *pSubLoop; + int addrExplain = sqlite3WhereExplainOneScan( + pParse, pOrTab, &pSubWInfo->a[0], 0 + ); + sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); + + /* This is the sub-WHERE clause body. First skip over + ** duplicate rows from prior sub-WHERE clauses, and record the + ** rowid (or PRIMARY KEY) for the current row so that the same + ** row will be skipped in subsequent sub-WHERE clauses. + */ + if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ + int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); + if( HasRowid(pTab) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); + jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, + regRowid, iSet); + VdbeCoverage(v); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk; + int r; + + /* Read the PK into an array of temp registers. */ + r = sqlite3GetTempRange(pParse, nPk); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + } + + /* Check if the temp table already contains this key. If so, + ** the row has already been included in the result set and + ** can be ignored (by jumping past the Gosub below). Otherwise, + ** insert the key into the temp table and proceed with processing + ** the row. + ** + ** Use some of the same optimizations as OP_RowSetTest: If iSet + ** is zero, assume that the key cannot already be present in + ** the temp table. And if iSet is -1, assume that there is no + ** need to insert the key into the temp table, as it will never + ** be tested for. */ + if( iSet ){ + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); + VdbeCoverage(v); + } + if( iSet>=0 ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid, + r, nPk); + if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + + /* Release the array of temp registers */ + sqlite3ReleaseTempRange(pParse, r, nPk); + } + } + + /* Invoke the main loop body as a subroutine */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); + + /* Jump here (skipping the main loop body subroutine) if the + ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ + if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1); + + /* The pSubWInfo->untestedTerms flag means that this OR term + ** contained one or more AND term from a notReady table. The + ** terms from the notReady table could not be tested and will + ** need to be tested later. + */ + if( pSubWInfo->untestedTerms ) untestedTerms = 1; + + /* If all of the OR-connected terms are optimized using the same + ** index, and the index is opened using the same cursor number + ** by each call to sqlite3WhereBegin() made by this loop, it may + ** be possible to use that index as a covering index. + ** + ** If the call to sqlite3WhereBegin() above resulted in a scan that + ** uses an index, and this is either the first OR-connected term + ** processed or the index is the same as that used by all previous + ** terms, set pCov to the candidate covering index. Otherwise, set + ** pCov to NULL to indicate that no candidate covering index will + ** be available. + */ + pSubLoop = pSubWInfo->a[0].pWLoop; + assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); + if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 + && (ii==0 || pSubLoop->u.btree.pIndex==pCov) + && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) + ){ + assert( pSubWInfo->a[0].iIdxCur==iCovCur ); + pCov = pSubLoop->u.btree.pIndex; + }else{ + pCov = 0; + } + if( sqlite3WhereUsesDeferredSeek(pSubWInfo) ){ + pWInfo->bDeferredSeek = 1; + } + + /* Finish the loop through table entries that match term pOrTerm. */ + sqlite3WhereEnd(pSubWInfo); + ExplainQueryPlanPop(pParse); + } + sqlite3ExprDelete(db, pDelete); + } + } + ExplainQueryPlanPop(pParse); + assert( pLevel->pWLoop==pLoop ); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)!=0 ); + assert( (pLoop->wsFlags & WHERE_IN_ABLE)==0 ); + pLevel->u.pCoveringIdx = pCov; + if( pCov ) pLevel->iIdxCur = iCovCur; + if( pAndExpr ){ + pAndExpr->pLeft = 0; + sqlite3ExprDelete(db, pAndExpr); + } + sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeGoto(v, pLevel->addrBrk); + sqlite3VdbeResolveLabel(v, iLoopBody); + + /* Set the P2 operand of the OP_Return opcode that will end the current + ** loop to point to this spot, which is the top of the next containing + ** loop. The byte-code formatter will use that P2 value as a hint to + ** indent everything in between the this point and the final OP_Return. + ** See tag-20220407a in vdbe.c and shell.c */ + assert( pLevel->op==OP_Return ); + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + + if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } + if( !untestedTerms ) disableTerm(pLevel, pTerm); + }else +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + + { + /* Case 6: There is no usable index. We must do a complete + ** scan of the entire table. + */ + static const u8 aStep[] = { OP_Next, OP_Prev }; + static const u8 aStart[] = { OP_Rewind, OP_Last }; + assert( bRev==0 || bRev==1 ); + if( pTabItem->fg.isRecursive ){ + /* Tables marked isRecursive have only a single row that is stored in + ** a pseudo-cursor. No need to Rewind or Next such cursors. */ + pLevel->op = OP_Noop; + }else{ + codeCursorHint(pTabItem, pWInfo, pLevel, 0); + pLevel->op = aStep[bRev]; + pLevel->p1 = iCur; + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + } + } + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pLevel->addrVisit = sqlite3VdbeCurrentAddr(v); +#endif + + /* Insert code to test every subexpression that can be completely + ** computed using the current set of tables. + ** + ** This loop may run between one and three times, depending on the + ** constraints to be generated. The value of stack variable iLoop + ** determines the constraints coded by each iteration, as follows: + ** + ** iLoop==1: Code only expressions that are entirely covered by pIdx. + ** iLoop==2: Code remaining expressions that do not contain correlated + ** sub-queries. + ** iLoop==3: Code all remaining expressions. + ** + ** An effort is made to skip unnecessary iterations of the loop. + */ + iLoop = (pIdx ? 1 : 2); + do{ + int iNext = 0; /* Next value for iLoop */ + for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + Expr *pE; + int skipLikeAddr = 0; + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + testcase( pWInfo->untestedTerms==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ); + pWInfo->untestedTerms = 1; + continue; + } + pE = pTerm->pExpr; + assert( pE!=0 ); + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){ + if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){ + /* Defer processing WHERE clause constraints until after outer + ** join processing. tag-20220513a */ + continue; + }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT + && !ExprHasProperty(pE,EP_OuterON) ){ + continue; + }else{ + Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin); + if( m & pLevel->notReady ){ + /* An ON clause that is not ripe */ + continue; + } + } + } + if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ + iNext = 2; + continue; + } + if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){ + if( iNext==0 ) iNext = 3; + continue; + } + + if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){ + /* If the TERM_LIKECOND flag is set, that means that the range search + ** is sufficient to guarantee that the LIKE operator is true, so we + ** can skip the call to the like(A,B) function. But this only works + ** for strings. So do not skip the call to the function on the pass + ** that compares BLOBs. */ +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + continue; +#else + u32 x = pLevel->iLikeRepCntr; + if( x>0 ){ + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); + VdbeCoverageIf(v, (x&1)==1); + VdbeCoverageIf(v, (x&1)==0); + } +#endif + } +#ifdef WHERETRACE_ENABLED /* 0xffffffff */ + if( sqlite3WhereTrace ){ + VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", + pWC->nTerm-j, pTerm, iLoop)); + } + if( sqlite3WhereTrace & 0x4000 ){ + sqlite3DebugPrintf("Coding auxiliary constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + } +#endif + sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); + pTerm->wtFlags |= TERM_CODED; + } + iLoop = iNext; + }while( iLoop>0 ); + + /* Insert code to test for implied constraints based on transitivity + ** of the "==" operator. + ** + ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123" + ** and we are coding the t1 loop and the t2 loop has not yet coded, + ** then we cannot use the "t1.a=t2.b" constraint, but we can code + ** the implied "t1.a=123" constraint. + */ + for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){ + Expr *pE, sEAlt; + WhereTerm *pAlt; + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; + if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; + if( pTerm->leftCursor!=iCur ) continue; + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue; + pE = pTerm->pExpr; +#ifdef WHERETRACE_ENABLED /* 0x4001 */ + if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + sqlite3DebugPrintf("Coding transitive constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + } +#endif + assert( !ExprHasProperty(pE, EP_OuterON) ); + assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady, + WO_EQ|WO_IN|WO_IS, 0); + if( pAlt==0 ) continue; + if( pAlt->wtFlags & (TERM_CODED) ) continue; + if( (pAlt->eOperator & WO_IN) + && ExprUseXSelect(pAlt->pExpr) + && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) + ){ + continue; + } + testcase( pAlt->eOperator & WO_EQ ); + testcase( pAlt->eOperator & WO_IS ); + testcase( pAlt->eOperator & WO_IN ); + VdbeModuleComment((v, "begin transitive constraint")); + sEAlt = *pAlt->pExpr; + sEAlt.pLeft = pE->pLeft; + sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); + pAlt->wtFlags |= TERM_CODED; + } + + /* For a RIGHT OUTER JOIN, record the fact that the current row has + ** been matched at least once. + */ + if( pLevel->pRJ ){ + Table *pTab; + int nPk; + int r; + int jmp1 = 0; + WhereRightJoin *pRJ = pLevel->pRJ; + + /* pTab is the right-hand table of the RIGHT JOIN. Generate code that + ** will record that the current row of that table has been matched at + ** least once. This is accomplished by storing the PK for the row in + ** both the iMatch index and the regBloom Bloom filter. + */ + pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; + if( HasRowid(pTab) ){ + r = sqlite3GetTempRange(pParse, 2); + sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + r = sqlite3GetTempRange(pParse, nPk+1); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk); + } + } + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk); + VdbeCoverage(v); + VdbeComment((v, "match against %s", pTab->zName)); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3VdbeJumpHere(v, jmp1); + sqlite3ReleaseTempRange(pParse, r, nPk+1); + } + + /* For a LEFT OUTER JOIN, generate code that will record the fact that + ** at least one row of the right table has matched the left table. + */ + if( pLevel->iLeftJoin ){ + pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); + VdbeComment((v, "record LEFT JOIN hit")); + if( pLevel->pRJ==0 ){ + goto code_outer_join_constraints; /* WHERE clause constraints */ + } + } + + if( pLevel->pRJ ){ + /* Create a subroutine used to process all interior loops and code + ** of the RIGHT JOIN. During normal operation, the subroutine will + ** be in-line with the rest of the code. But at the end, a separate + ** loop will run that invokes this subroutine for unmatched rows + ** of pTab, with all tables to left begin set to NULL. + */ + WhereRightJoin *pRJ = pLevel->pRJ; + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); + pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); + assert( pParse->withinRJSubrtn < 255 ); + pParse->withinRJSubrtn++; + + /* WHERE clause constraints must be deferred until after outer join + ** row elimination has completed, since WHERE clause constraints apply + ** to the results of the OUTER JOIN. The following loop generates the + ** appropriate WHERE clause constraint checks. tag-20220513a. + */ + code_outer_join_constraints: + for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + assert( pWInfo->untestedTerms ); + continue; + } + if( pTabItem->fg.jointype & JT_LTORJ ) continue; + assert( pTerm->pExpr ); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + pTerm->wtFlags |= TERM_CODED; + } + } + +#if WHERETRACE_ENABLED /* 0x4001 */ + if( sqlite3WhereTrace & 0x4000 ){ + sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", + iLevel); + sqlite3WhereClausePrint(pWC); + } + if( sqlite3WhereTrace & 0x1 ){ + sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", + iLevel, (u64)pLevel->notReady); + } +#endif + return pLevel->notReady; +} + +/* +** Generate the code for the loop that finds all non-matched terms +** for a RIGHT JOIN. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( + WhereInfo *pWInfo, + int iLevel, + WhereLevel *pLevel +){ + Parse *pParse = pWInfo->pParse; + Vdbe *v = pParse->pVdbe; + WhereRightJoin *pRJ = pLevel->pRJ; + Expr *pSubWhere = 0; + WhereClause *pWC = &pWInfo->sWC; + WhereInfo *pSubWInfo; + WhereLoop *pLoop = pLevel->pWLoop; + SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + SrcList sFrom; + Bitmask mAll = 0; + int k; + + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); + sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, + pRJ->regReturn); + for(k=0; ka[k].pWLoop->maskSelf; + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); + iIdxCur = pWInfo->a[k].iIdxCur; + if( iIdxCur ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + } + if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){ + mAll |= pLoop->maskSelf; + for(k=0; knTerm; k++){ + WhereTerm *pTerm = &pWC->a[k]; + if( (pTerm->wtFlags & (TERM_VIRTUAL|TERM_SLICE))!=0 + && pTerm->eOperator!=WO_ROWVAL + ){ + break; + } + if( pTerm->prereqAll & ~mAll ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue; + pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, + sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); + } + } + sFrom.nSrc = 1; + sFrom.nAlloc = 1; + memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); + sFrom.a[0].fg.jointype = 0; + assert( pParse->withinRJSubrtn < 100 ); + pParse->withinRJSubrtn++; + pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, + WHERE_RIGHT_JOIN, 0); + if( pSubWInfo ){ + int iCur = pLevel->iTabCur; + int r = ++pParse->nMem; + int nPk; + int jmp; + int addrCont = sqlite3WhereContinueLabel(pSubWInfo); + Table *pTab = pTabItem->pTab; + if( HasRowid(pTab) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + pParse->nMem += nPk - 1; + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + } + } + jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); + VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, jmp); + sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); + sqlite3WhereEnd(pSubWInfo); + } + sqlite3ExprDelete(pParse->db, pSubWhere); + ExplainQueryPlanPop(pParse); + assert( pParse->withinRJSubrtn>0 ); + pParse->withinRJSubrtn--; +} + +/************** End of wherecode.c *******************************************/ +/************** Begin file whereexpr.c ***************************************/ +/* +** 2015-06-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. +** +** This file was originally part of where.c but was split out to improve +** readability and editability. This file contains utility routines for +** analyzing Expr objects in the WHERE clause. +*/ +/* #include "sqliteInt.h" */ +/* #include "whereInt.h" */ + +/* Forward declarations */ +static void exprAnalyze(SrcList*, WhereClause*, int); + +/* +** Deallocate all memory associated with a WhereOrInfo object. +*/ +static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){ + sqlite3WhereClauseClear(&p->wc); + sqlite3DbFree(db, p); +} + +/* +** Deallocate all memory associated with a WhereAndInfo object. +*/ +static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){ + sqlite3WhereClauseClear(&p->wc); + sqlite3DbFree(db, p); +} + +/* +** Add a single new WhereTerm entry to the WhereClause object pWC. +** The new WhereTerm object is constructed from Expr p and with wtFlags. +** The index in pWC->a[] of the new WhereTerm is returned on success. +** 0 is returned if the new WhereTerm could not be added due to a memory +** allocation error. The memory allocation failure will be recorded in +** the db->mallocFailed flag so that higher-level functions can detect it. +** +** This routine will increase the size of the pWC->a[] array as necessary. +** +** If the wtFlags argument includes TERM_DYNAMIC, then responsibility +** for freeing the expression p is assumed by the WhereClause object pWC. +** This is true even if this routine fails to allocate a new WhereTerm. +** +** WARNING: This routine might reallocate the space used to store +** WhereTerms. All pointers to WhereTerms should be invalidated after +** calling this routine. Such pointers may be reinitialized by referencing +** the pWC->a[] array. +*/ +static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ + WhereTerm *pTerm; + int idx; + testcase( wtFlags & TERM_VIRTUAL ); + if( pWC->nTerm>=pWC->nSlot ){ + WhereTerm *pOld = pWC->a; + sqlite3 *db = pWC->pWInfo->pParse->db; + pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 ); + if( pWC->a==0 ){ + if( wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, p); + } + pWC->a = pOld; + return 0; + } + memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); + pWC->nSlot = pWC->nSlot*2; + } + pTerm = &pWC->a[idx = pWC->nTerm++]; + if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm; + if( p && ExprHasProperty(p, EP_Unlikely) ){ + pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; + }else{ + pTerm->truthProb = 1; + } + pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p); + pTerm->wtFlags = wtFlags; + pTerm->pWC = pWC; + pTerm->iParent = -1; + memset(&pTerm->eOperator, 0, + sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); + return idx; +} + +/* +** Return TRUE if the given operator is one of the operators that is +** allowed for an indexable WHERE clause term. The allowed operators are +** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL" +*/ +static int allowedOp(int op){ + assert( TK_GT>TK_EQ && TK_GTTK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; +} + +/* +** Commute a comparison operator. Expressions of the form "X op Y" +** are converted into "Y op X". +*/ +static u16 exprCommute(Parse *pParse, Expr *pExpr){ + if( pExpr->pLeft->op==TK_VECTOR + || pExpr->pRight->op==TK_VECTOR + || sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != + sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) + ){ + pExpr->flags ^= EP_Commuted; + } + SWAP(Expr*,pExpr->pRight,pExpr->pLeft); + if( pExpr->op>=TK_GT ){ + assert( TK_LT==TK_GT+2 ); + assert( TK_GE==TK_LE+2 ); + assert( TK_GT>TK_EQ ); + assert( TK_GTop>=TK_GT && pExpr->op<=TK_GE ); + pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; + } + return 0; +} + +/* +** Translate from TK_xx operator to WO_xx bitmask. +*/ +static u16 operatorMask(int op){ + u16 c; + assert( allowedOp(op) ); + if( op==TK_IN ){ + c = WO_IN; + }else if( op==TK_ISNULL ){ + c = WO_ISNULL; + }else if( op==TK_IS ){ + c = WO_IS; + }else{ + assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); + c = (u16)(WO_EQ<<(op-TK_EQ)); + } + assert( op!=TK_ISNULL || c==WO_ISNULL ); + assert( op!=TK_IN || c==WO_IN ); + assert( op!=TK_EQ || c==WO_EQ ); + assert( op!=TK_LT || c==WO_LT ); + assert( op!=TK_LE || c==WO_LE ); + assert( op!=TK_GT || c==WO_GT ); + assert( op!=TK_GE || c==WO_GE ); + assert( op!=TK_IS || c==WO_IS ); + return c; +} + + +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION +/* +** Check to see if the given expression is a LIKE or GLOB operator that +** can be optimized using inequality constraints. Return TRUE if it is +** so and false if not. +** +** In order for the operator to be optimizible, the RHS must be a string +** literal that does not begin with a wildcard. The LHS must be a column +** that may only be NULL, a string, or a BLOB, never a number. (This means +** that virtual tables cannot participate in the LIKE optimization.) The +** collating sequence for the column on the LHS must be appropriate for +** the operator. +*/ +static int isLikeOrGlob( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* Test this expression */ + Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */ + int *pisComplete, /* True if the only wildcard is % in the last character */ + int *pnoCase /* True if uppercase is equivalent to lowercase */ +){ + const u8 *z = 0; /* String on RHS of LIKE operator */ + Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ + ExprList *pList; /* List of operands to the LIKE operator */ + u8 c; /* One character in z[] */ + int cnt; /* Number of non-wildcard prefix characters */ + u8 wc[4]; /* Wildcard characters */ + sqlite3 *db = pParse->db; /* Database connection */ + sqlite3_value *pVal = 0; + int op; /* Opcode of pRight */ + int rc; /* Result code to return */ + + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ + return 0; + } +#ifdef SQLITE_EBCDIC + if( *pnoCase ) return 0; +#endif + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + pLeft = pList->a[1].pExpr; + + pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); + op = pRight->op; + if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ + Vdbe *pReprepare = pParse->pReprepare; + int iCol = pRight->iColumn; + pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB); + if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ + z = sqlite3_value_text(pVal); + } + sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); + assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); + }else if( op==TK_STRING ){ + assert( !ExprHasProperty(pRight, EP_IntValue) ); + z = (u8*)pRight->u.zToken; + } + if( z ){ + + /* Count the number of prefix characters prior to the first wildcard */ + cnt = 0; + while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ + cnt++; + if( c==wc[3] && z[cnt]!=0 ) cnt++; + } + + /* The optimization is possible only if (1) the pattern does not begin + ** with a wildcard and if (2) the non-wildcard prefix does not end with + ** an (illegal 0xff) character, or (3) the pattern does not consist of + ** a single escape character. The second condition is necessary so + ** that we can increment the prefix key to find an upper bound for the + ** range search. The third is because the caller assumes that the pattern + ** consists of at least one character after all escapes have been + ** removed. */ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ + Expr *pPrefix; + + /* A "complete" match if the pattern ends with "*" or "%" */ + *pisComplete = c==wc[0] && z[cnt+1]==0; + + /* Get the pattern prefix. Remove all escapes from the prefix. */ + pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); + if( pPrefix ){ + int iFrom, iTo; + char *zNew; + assert( !ExprHasProperty(pPrefix, EP_IntValue) ); + zNew = pPrefix->u.zToken; + zNew[cnt] = 0; + for(iFrom=iTo=0; iFrom0 ); + + /* If the LHS is not an ordinary column with TEXT affinity, then the + ** pattern prefix boundaries (both the start and end boundaries) must + ** not look like a number. Otherwise the pattern might be treated as + ** a number, which will invalidate the LIKE optimization. + ** + ** Getting this right has been a persistent source of bugs in the + ** LIKE optimization. See, for example: + ** 2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1 + ** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28 + ** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07 + ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975 + ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a + */ + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || (ALWAYS( ExprUseYTab(pLeft) ) + && ALWAYS(pLeft->y.pTab) + && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ + ){ + int isNum; + double rDummy; + isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); + if( isNum<=0 ){ + if( iTo==1 && zNew[0]=='-' ){ + isNum = +1; + }else{ + zNew[iTo-1]++; + isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); + zNew[iTo-1]--; + } + } + if( isNum>0 ){ + sqlite3ExprDelete(db, pPrefix); + sqlite3ValueFree(pVal); + return 0; + } + } + } + *ppPrefix = pPrefix; + + /* If the RHS pattern is a bound parameter, make arrangements to + ** reprepare the statement when that parameter is rebound */ + if( op==TK_VARIABLE ){ + Vdbe *v = pParse->pVdbe; + sqlite3VdbeSetVarmask(v, pRight->iColumn); + assert( !ExprHasProperty(pRight, EP_IntValue) ); + if( *pisComplete && pRight->u.zToken[1] ){ + /* If the rhs of the LIKE expression is a variable, and the current + ** value of the variable means there is no need to invoke the LIKE + ** function, then no OP_Variable will be added to the program. + ** This causes problems for the sqlite3_bind_parameter_name() + ** API. To work around them, add a dummy OP_Variable here. + */ + int r1 = sqlite3GetTempReg(pParse); + sqlite3ExprCodeTarget(pParse, pRight, r1); + sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); + sqlite3ReleaseTempReg(pParse, r1); + } + } + }else{ + z = 0; + } + } + + rc = (z!=0); + sqlite3ValueFree(pVal); + return rc; +} +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Check to see if the pExpr expression is a form that needs to be passed +** to the xBestIndex method of virtual tables. Forms of interest include: +** +** Expression Virtual Table Operator +** ----------------------- --------------------------------- +** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH +** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB +** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE +** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP +** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE +** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE +** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT +** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT +** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL +** +** In every case, "column" must be a column of a virtual table. If there +** is a match, set *ppLeft to the "column" expression, set *ppRight to the +** "expr" expression (even though in forms (6) and (8) the column is on the +** right and the expression is on the left). Also set *peOp2 to the +** appropriate virtual table operator. The return value is 1 or 2 if there +** is a match. The usual return is 1, but if the RHS is also a column +** of virtual table in forms (5) or (7) then return 2. +** +** If the expression matches none of the patterns above, return 0. +*/ +static int isAuxiliaryVtabOperator( + sqlite3 *db, /* Parsing context */ + Expr *pExpr, /* Test this expression */ + unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ + Expr **ppLeft, /* Column expression to left of MATCH/op2 */ + Expr **ppRight /* Expression to left of MATCH/op2 */ +){ + if( pExpr->op==TK_FUNCTION ){ + static const struct Op2 { + const char *zOp; + unsigned char eOp2; + } aOp[] = { + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, + { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } + }; + ExprList *pList; + Expr *pCol; /* Column reference */ + int i; + + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + if( pList==0 || pList->nExpr!=2 ){ + return 0; + } + + /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a + ** virtual table on their second argument, which is the same as + ** the left-hand side operand in their in-fix form. + ** + ** vtab_column MATCH expression + ** MATCH(expression,vtab_column) + */ + pCol = pList->a[1].pExpr; + assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + if( ExprIsVtab(pCol) ){ + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + *peOp2 = aOp[i].eOp2; + *ppRight = pList->a[0].pExpr; + *ppLeft = pCol; + return 1; + } + } + } + + /* We can also match against the first column of overloaded + ** functions where xFindFunction returns a value of at least + ** SQLITE_INDEX_CONSTRAINT_FUNCTION. + ** + ** OVERLOADED(vtab_column,expression) + ** + ** Historically, xFindFunction expected to see lower-case function + ** names. But for this use case, xFindFunction is expected to deal + ** with function names in an arbitrary case. + */ + pCol = pList->a[0].pExpr; + assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); + assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + if( ExprIsVtab(pCol) ){ + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); + void *pNotUsed; + pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction!=0 ){ + i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); + if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + *peOp2 = i; + *ppRight = pList->a[1].pExpr; + *ppLeft = pCol; + return 1; + } + } + } + }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ + int res = 0; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); + if( ExprIsVtab(pLeft) ){ + res++; + } + assert( pRight==0 || pRight->op!=TK_COLUMN + || (ExprUseYTab(pRight) && pRight->y.pTab!=0) ); + if( pRight && ExprIsVtab(pRight) ){ + res++; + SWAP(Expr*, pLeft, pRight); + } + *ppLeft = pLeft; + *ppRight = pRight; + if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE; + if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT; + if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL; + return res; + } + return 0; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** If the pBase expression originated in the ON or USING clause of +** a join, then transfer the appropriate markings over to derived. +*/ +static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ + if( pDerived && ExprHasProperty(pBase, EP_OuterON|EP_InnerON) ){ + pDerived->flags |= pBase->flags & (EP_OuterON|EP_InnerON); + pDerived->w.iJoin = pBase->w.iJoin; + } +} + +/* +** Mark term iChild as being a child of term iParent +*/ +static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ + pWC->a[iChild].iParent = iParent; + pWC->a[iChild].truthProb = pWC->a[iParent].truthProb; + pWC->a[iParent].nChild++; +} + +/* +** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not +** a conjunction, then return just pTerm when N==0. If N is exceeds +** the number of available subterms, return NULL. +*/ +static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ + if( pTerm->eOperator!=WO_AND ){ + return N==0 ? pTerm : 0; + } + if( Nu.pAndInfo->wc.nTerm ){ + return &pTerm->u.pAndInfo->wc.a[N]; + } + return 0; +} + +/* +** Subterms pOne and pTwo are contained within WHERE clause pWC. The +** two subterms are in disjunction - they are OR-ed together. +** +** If these two terms are both of the form: "A op B" with the same +** A and B values but different operators and if the operators are +** compatible (if one is = and the other is <, for example) then +** add a new virtual AND term to pWC that is the combination of the +** two. +** +** Some examples: +** +** x x<=y +** x=y OR x=y --> x=y +** x<=y OR x x<=y +** +** The following is NOT generated: +** +** xy --> x!=y +*/ +static void whereCombineDisjuncts( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* The complete WHERE clause */ + WhereTerm *pOne, /* First disjunct */ + WhereTerm *pTwo /* Second disjunct */ +){ + u16 eOp = pOne->eOperator | pTwo->eOperator; + sqlite3 *db; /* Database connection (for malloc) */ + Expr *pNew; /* New virtual expression */ + int op; /* Operator for the combined expression */ + int idxNew; /* Index in pWC of the next virtual term */ + + if( (pOne->wtFlags | pTwo->wtFlags) & TERM_VNULL ) return; + if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp + && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; + assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); + assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); + if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; + if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return; + /* If we reach this point, it means the two subterms can be combined */ + if( (eOp & (eOp-1))!=0 ){ + if( eOp & (WO_LT|WO_LE) ){ + eOp = WO_LE; + }else{ + assert( eOp & (WO_GT|WO_GE) ); + eOp = WO_GE; + } + } + db = pWC->pWInfo->pParse->db; + pNew = sqlite3ExprDup(db, pOne->pExpr, 0); + if( pNew==0 ) return; + for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); +} + +#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Analyze a term that consists of two or more OR-connected +** subterms. So in: +** +** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13) +** ^^^^^^^^^^^^^^^^^^^^ +** +** This routine analyzes terms such as the middle term in the above example. +** A WhereOrTerm object is computed and attached to the term under +** analysis, regardless of the outcome of the analysis. Hence: +** +** WhereTerm.wtFlags |= TERM_ORINFO +** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object +** +** The term being analyzed must have two or more of OR-connected subterms. +** A single subterm might be a set of AND-connected sub-subterms. +** Examples of terms under analysis: +** +** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5 +** (B) x=expr1 OR expr2=x OR x=expr3 +** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) +** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') +** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) +** (F) x>A OR (x=A AND y>=B) +** +** CASE 1: +** +** If all subterms are of the form T.C=expr for some single column of C and +** a single table T (as shown in example B above) then create a new virtual +** term that is an equivalent IN expression. In other words, if the term +** being analyzed is: +** +** x = expr1 OR expr2 = x OR x = expr3 +** +** then create a new virtual term like this: +** +** x IN (expr1,expr2,expr3) +** +** CASE 2: +** +** If there are exactly two disjuncts and one side has x>A and the other side +** has x=A (for the same x and A) then add a new virtual conjunct term to the +** WHERE clause of the form "x>=A". Example: +** +** x>A OR (x=A AND y>B) adds: x>=A +** +** The added conjunct can sometimes be helpful in query planning. +** +** CASE 3: +** +** If all subterms are indexable by a single table T, then set +** +** WhereTerm.eOperator = WO_OR +** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T +** +** A subterm is "indexable" if it is of the form +** "T.C " where C is any column of table T and +** is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". +** A subterm is also indexable if it is an AND of two or more +** subsubterms at least one of which is indexable. Indexable AND +** subterms have their eOperator set to WO_AND and they have +** u.pAndInfo set to a dynamically allocated WhereAndTerm object. +** +** From another point of view, "indexable" means that the subterm could +** potentially be used with an index if an appropriate index exists. +** This analysis does not consider whether or not the index exists; that +** is decided elsewhere. This analysis only looks at whether subterms +** appropriate for indexing exist. +** +** All examples A through E above satisfy case 3. But if a term +** also satisfies case 1 (such as B) we know that the optimizer will +** always prefer case 1, so in that case we pretend that case 3 is not +** satisfied. +** +** It might be the case that multiple tables are indexable. For example, +** (E) above is indexable on tables P, Q, and R. +** +** Terms that satisfy case 3 are candidates for lookup by using +** separate indices to find rowids for each subterm and composing +** the union of all rowids using a RowSet object. This is similar +** to "bitmap indices" in other database engines. +** +** OTHERWISE: +** +** If none of cases 1, 2, or 3 apply, then leave the eOperator set to +** zero. This term is not useful for search. +*/ +static void exprAnalyzeOrTerm( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the complete WHERE clause */ + int idxTerm /* Index of the OR-term to be analyzed */ +){ + WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ + Parse *pParse = pWInfo->pParse; /* Parser context */ + sqlite3 *db = pParse->db; /* Database connection */ + WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */ + Expr *pExpr = pTerm->pExpr; /* The expression of the term */ + int i; /* Loop counters */ + WhereClause *pOrWc; /* Breakup of pTerm into subterms */ + WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */ + WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */ + Bitmask chngToIN; /* Tables that might satisfy case 1 */ + Bitmask indexable; /* Tables that are indexable, satisfying case 2 */ + + /* + ** Break the OR clause into its separate subterms. The subterms are + ** stored in a WhereClause structure containing within the WhereOrInfo + ** object that is attached to the original OR clause term. + */ + assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 ); + assert( pExpr->op==TK_OR ); + pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo)); + if( pOrInfo==0 ) return; + pTerm->wtFlags |= TERM_ORINFO; + pOrWc = &pOrInfo->wc; + memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic)); + sqlite3WhereClauseInit(pOrWc, pWInfo); + sqlite3WhereSplit(pOrWc, pExpr, TK_OR); + sqlite3WhereExprAnalyze(pSrc, pOrWc); + if( db->mallocFailed ) return; + assert( pOrWc->nTerm>=2 ); + + /* + ** Compute the set of tables that might satisfy cases 1 or 3. + */ + indexable = ~(Bitmask)0; + chngToIN = ~(Bitmask)0; + for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ + if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ + WhereAndInfo *pAndInfo; + assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); + chngToIN = 0; + pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); + if( pAndInfo ){ + WhereClause *pAndWC; + WhereTerm *pAndTerm; + int j; + Bitmask b = 0; + pOrTerm->u.pAndInfo = pAndInfo; + pOrTerm->wtFlags |= TERM_ANDINFO; + pOrTerm->eOperator = WO_AND; + pOrTerm->leftCursor = -1; + pAndWC = &pAndInfo->wc; + memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic)); + sqlite3WhereClauseInit(pAndWC, pWC->pWInfo); + sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); + sqlite3WhereExprAnalyze(pSrc, pAndWC); + pAndWC->pOuter = pWC; + if( !db->mallocFailed ){ + for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ + assert( pAndTerm->pExpr ); + if( allowedOp(pAndTerm->pExpr->op) + || pAndTerm->eOperator==WO_AUX + ){ + b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); + } + } + } + indexable &= b; + } + }else if( pOrTerm->wtFlags & TERM_COPIED ){ + /* Skip this term for now. We revisit it when we process the + ** corresponding TERM_VIRTUAL term */ + }else{ + Bitmask b; + b = sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor); + if( pOrTerm->wtFlags & TERM_VIRTUAL ){ + WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent]; + b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor); + } + indexable &= b; + if( (pOrTerm->eOperator & WO_EQ)==0 ){ + chngToIN = 0; + }else{ + chngToIN &= b; + } + } + } + + /* + ** Record the set of tables that satisfy case 3. The set might be + ** empty. + */ + pOrInfo->indexable = indexable; + pTerm->eOperator = WO_OR; + pTerm->leftCursor = -1; + if( indexable ){ + pWC->hasOr = 1; + } + + /* For a two-way OR, attempt to implementation case 2. + */ + if( indexable && pOrWc->nTerm==2 ){ + int iOne = 0; + WhereTerm *pOne; + while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){ + int iTwo = 0; + WhereTerm *pTwo; + while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){ + whereCombineDisjuncts(pSrc, pWC, pOne, pTwo); + } + } + } + + /* + ** chngToIN holds a set of tables that *might* satisfy case 1. But + ** we have to do some additional checking to see if case 1 really + ** is satisfied. + ** + ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means + ** that there is no possibility of transforming the OR clause into an + ** IN operator because one or more terms in the OR clause contain + ** something other than == on a column in the single table. The 1-bit + ** case means that every term of the OR clause is of the form + ** "table.column=expr" for some single table. The one bit that is set + ** will correspond to the common table. We still need to check to make + ** sure the same column is used on all terms. The 2-bit case is when + ** the all terms are of the form "table1.column=table2.column". It + ** might be possible to form an IN operator with either table1.column + ** or table2.column as the LHS if either is common to every term of + ** the OR clause. + ** + ** Note that terms of the form "table.column1=table.column2" (the + ** same table on both sizes of the ==) cannot be optimized. + */ + if( chngToIN ){ + int okToChngToIN = 0; /* True if the conversion to IN is valid */ + int iColumn = -1; /* Column index on lhs of IN operator */ + int iCursor = -1; /* Table cursor common to all terms */ + int j = 0; /* Loop counter */ + + /* Search for a table and column that appears on one side or the + ** other of the == operator in every subterm. That table and column + ** will be recorded in iCursor and iColumn. There might not be any + ** such table and column. Set okToChngToIN if an appropriate table + ** and column is found but leave okToChngToIN false if not found. + */ + for(j=0; j<2 && !okToChngToIN; j++){ + Expr *pLeft = 0; + pOrTerm = pOrWc->a; + for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ + assert( pOrTerm->eOperator & WO_EQ ); + pOrTerm->wtFlags &= ~TERM_OK; + if( pOrTerm->leftCursor==iCursor ){ + /* This is the 2-bit case and we are on the second iteration and + ** current term is from the first iteration. So skip this term. */ + assert( j==1 ); + continue; + } + if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, + pOrTerm->leftCursor))==0 ){ + /* This term must be of the form t1.a==t2.b where t2 is in the + ** chngToIN set but t1 is not. This term will be either preceded + ** or followed by an inverted copy (t2.b==t1.a). Skip this term + ** and use its inversion. */ + testcase( pOrTerm->wtFlags & TERM_COPIED ); + testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); + assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); + continue; + } + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + iColumn = pOrTerm->u.x.leftColumn; + iCursor = pOrTerm->leftCursor; + pLeft = pOrTerm->pExpr->pLeft; + break; + } + if( i<0 ){ + /* No candidate table+column was found. This can only occur + ** on the second iteration */ + assert( j==1 ); + assert( IsPowerOfTwo(chngToIN) ); + assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); + break; + } + testcase( j==1 ); + + /* We have found a candidate table and column. Check to see if that + ** table and column is common to every term in the OR clause */ + okToChngToIN = 1; + for(; i>=0 && okToChngToIN; i--, pOrTerm++){ + assert( pOrTerm->eOperator & WO_EQ ); + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + if( pOrTerm->leftCursor!=iCursor ){ + pOrTerm->wtFlags &= ~TERM_OK; + }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR + && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) + )){ + okToChngToIN = 0; + }else{ + int affLeft, affRight; + /* If the right-hand side is also a column, then the affinities + ** of both right and left sides must be such that no type + ** conversions are required on the right. (Ticket #2249) + */ + affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); + affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); + if( affRight!=0 && affRight!=affLeft ){ + okToChngToIN = 0; + }else{ + pOrTerm->wtFlags |= TERM_OK; + } + } + } + } + + /* At this point, okToChngToIN is true if original pTerm satisfies + ** case 1. In that case, construct a new virtual term that is + ** pTerm converted into an IN operator. + */ + if( okToChngToIN ){ + Expr *pDup; /* A transient duplicate expression */ + ExprList *pList = 0; /* The RHS of the IN operator */ + Expr *pLeft = 0; /* The LHS of the IN operator */ + Expr *pNew; /* The complete IN operator */ + + for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ + if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue; + assert( pOrTerm->eOperator & WO_EQ ); + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pOrTerm->leftCursor==iCursor ); + assert( pOrTerm->u.x.leftColumn==iColumn ); + pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); + pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); + pLeft = pOrTerm->pExpr->pLeft; + } + assert( pLeft!=0 ); + pDup = sqlite3ExprDup(db, pLeft, 0); + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); + if( pNew ){ + int idxNew; + transferJoinMarkings(pNew, pExpr); + assert( ExprUseXList(pNew) ); + pNew->x.pList = pList; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + exprAnalyze(pSrc, pWC, idxNew); + /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */ + markTermAsChild(pWC, idxNew, idxTerm); + }else{ + sqlite3ExprListDelete(db, pList); + } + } + } +} +#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */ + +/* +** We already know that pExpr is a binary operator where both operands are +** column references. This routine checks to see if pExpr is an equivalence +** relation: +** 1. The SQLITE_Transitive optimization must be enabled +** 2. Must be either an == or an IS operator +** 3. Not originating in the ON clause of an OUTER JOIN +** 4. The affinities of A and B must be compatible +** 5a. Both operands use the same collating sequence OR +** 5b. The overall collating sequence is BINARY +** If this routine returns TRUE, that means that the RHS can be substituted +** for the LHS anyplace else in the WHERE clause where the LHS column occurs. +** This is an optimization. No harm comes from returning 0. But if 1 is +** returned when it should not be, then incorrect answers might result. +*/ +static int termIsEquivalence(Parse *pParse, Expr *pExpr){ + char aff1, aff2; + CollSeq *pColl; + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; + aff1 = sqlite3ExprAffinity(pExpr->pLeft); + aff2 = sqlite3ExprAffinity(pExpr->pRight); + if( aff1!=aff2 + && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) + ){ + return 0; + } + pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); + if( sqlite3IsBinary(pColl) ) return 1; + return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); +} + +/* +** Recursively walk the expressions of a SELECT statement and generate +** a bitmask indicating which tables are used in that expression +** tree. +*/ +static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ + Bitmask mask = 0; + while( pS ){ + SrcList *pSrc = pS->pSrc; + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pEList); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere); + mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); + if( ALWAYS(pSrc!=0) ){ + int i; + for(i=0; inSrc; i++){ + mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); + if( pSrc->a[i].fg.isUsing==0 ){ + mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); + } + if( pSrc->a[i].fg.isTabFunc ){ + mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); + } + } + } + pS = pS->pPrior; + } + return mask; +} + +/* +** Expression pExpr is one operand of a comparison operator that might +** be useful for indexing. This routine checks to see if pExpr appears +** in any index. Return TRUE (1) if pExpr is an indexed term and return +** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor +** number of the table that is indexed and aiCurCol[1] to the column number +** of the column that is indexed, or XN_EXPR (-2) if an expression is being +** indexed. +** +** If pExpr is a TK_COLUMN column reference, then this routine always returns +** true even if that particular column is not indexed, because the column +** might be added to an automatic index later. +*/ +static SQLITE_NOINLINE int exprMightBeIndexed2( + SrcList *pFrom, /* The FROM clause */ + int *aiCurCol, /* Write the referenced table cursor and column here */ + Expr *pExpr, /* An operand of a comparison operator */ + int j /* Start looking with the j-th pFrom entry */ +){ + Index *pIdx; + int i; + int iCur; + do{ + iCur = pFrom->a[j].iCursor; + for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr==0 ) continue; + for(i=0; inKeyCol; i++){ + if( pIdx->aiColumn[i]!=XN_EXPR ) continue; + assert( pIdx->bHasExpr ); + if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 + && pExpr->op!=TK_STRING + ){ + aiCurCol[0] = iCur; + aiCurCol[1] = XN_EXPR; + return 1; + } + } + } + }while( ++j < pFrom->nSrc ); + return 0; +} +static int exprMightBeIndexed( + SrcList *pFrom, /* The FROM clause */ + int *aiCurCol, /* Write the referenced table cursor & column here */ + Expr *pExpr, /* An operand of a comparison operator */ + int op /* The specific comparison operator */ +){ + int i; + + /* If this expression is a vector to the left or right of a + ** inequality constraint (>, <, >= or <=), perform the processing + ** on the first element of the vector. */ + assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); + assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ + assert( ExprUseXList(pExpr) ); + pExpr = pExpr->x.pList->a[0].pExpr; + } + + if( pExpr->op==TK_COLUMN ){ + aiCurCol[0] = pExpr->iTable; + aiCurCol[1] = pExpr->iColumn; + return 1; + } + + for(i=0; inSrc; i++){ + Index *pIdx; + for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr ){ + return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); + } + } + } + return 0; +} + + +/* +** The input to this routine is an WhereTerm structure with only the +** "pExpr" field filled in. The job of this routine is to analyze the +** subexpression and populate all the other fields of the WhereTerm +** structure. +** +** If the expression is of the form " X" it gets commuted +** to the standard form of "X ". +** +** If the expression is of the form "X Y" where both X and Y are +** columns, then the original expression is unchanged and a new virtual +** term of the form "Y X" is added to the WHERE clause and +** analyzed separately. The original term is marked with TERM_COPIED +** and the new term is marked with TERM_DYNAMIC (because it's pExpr +** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it +** is a commuted copy of a prior term.) The original term has nChild=1 +** and the copy has idxParent set to the index of the original term. +*/ +static void exprAnalyze( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ + WhereTerm *pTerm; /* The term to be analyzed */ + WhereMaskSet *pMaskSet; /* Set of table index masks */ + Expr *pExpr; /* The expression to be analyzed */ + Bitmask prereqLeft; /* Prerequisites of the pExpr->pLeft */ + Bitmask prereqAll; /* Prerequisites of pExpr */ + Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ + Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ + int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ + int noCase = 0; /* uppercase equivalent to lowercase */ + int op; /* Top-level operator. pExpr->op */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + sqlite3 *db = pParse->db; /* Database connection */ + unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */ + int nLeft; /* Number of elements on left side vector */ + + if( db->mallocFailed ){ + return; + } + assert( pWC->nTerm > idxTerm ); + pTerm = &pWC->a[idxTerm]; + pMaskSet = &pWInfo->sMaskSet; + pExpr = pTerm->pExpr; + assert( pExpr!=0 ); /* Because malloc() has not failed */ + assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); + pMaskSet->bVarSelect = 0; + prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); + op = pExpr->op; + if( op==TK_IN ){ + assert( pExpr->pRight==0 ); + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; + if( ExprUseXSelect(pExpr) ){ + pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); + }else{ + pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); + } + prereqAll = prereqLeft | pTerm->prereqRight; + }else{ + pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); + if( pExpr->pLeft==0 + || ExprHasProperty(pExpr, EP_xIsSelect|EP_IfNullRow) + || pExpr->x.pList!=0 + ){ + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); + }else{ + prereqAll = prereqLeft | pTerm->prereqRight; + } + } + if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; + +#ifdef SQLITE_DEBUG + if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){ + printf("\n*** Incorrect prereqAll computed for:\n"); + sqlite3TreeViewExpr(0,pExpr,0); + assert( 0 ); + } +#endif + + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){ + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin); + if( ExprHasProperty(pExpr, EP_OuterON) ){ + prereqAll |= x; + extraRight = x-1; /* ON clause terms may not be used with an index + ** on left table of a LEFT JOIN. Ticket #3015 */ + if( (prereqAll>>1)>=x ){ + sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); + return; + } + }else if( (prereqAll>>1)>=x ){ + /* The ON clause of an INNER JOIN references a table to its right. + ** Most other SQL database engines raise an error. But SQLite versions + ** 3.0 through 3.38 just put the ON clause constraint into the WHERE + ** clause and carried on. Beginning with 3.39, raise an error only + ** if there is a RIGHT or FULL JOIN in the query. This makes SQLite + ** more like other systems, and also preserves legacy. */ + if( ALWAYS(pSrc->nSrc>0) && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); + return; + } + ExprClearProperty(pExpr, EP_InnerON); + } + } + pTerm->prereqAll = prereqAll; + pTerm->leftCursor = -1; + pTerm->iParent = -1; + pTerm->eOperator = 0; + if( allowedOp(op) ){ + int aiCurCol[2]; + Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); + Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); + u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; + + if( pTerm->u.x.iField>0 ){ + assert( op==TK_IN ); + assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); + pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; + } + + if( exprMightBeIndexed(pSrc, aiCurCol, pLeft, op) ){ + pTerm->leftCursor = aiCurCol[0]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pTerm->u.x.leftColumn = aiCurCol[1]; + pTerm->eOperator = operatorMask(op) & opMask; + } + if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; + if( pRight + && exprMightBeIndexed(pSrc, aiCurCol, pRight, op) + && !ExprHasProperty(pRight, EP_FixedCol) + ){ + WhereTerm *pNew; + Expr *pDup; + u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ + assert( pTerm->u.x.iField==0 ); + if( pTerm->leftCursor>=0 ){ + int idxNew; + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + if( idxNew==0 ) return; + pNew = &pWC->a[idxNew]; + markTermAsChild(pWC, idxNew, idxTerm); + if( op==TK_IS ) pNew->wtFlags |= TERM_IS; + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + + if( termIsEquivalence(pParse, pDup) ){ + pTerm->eOperator |= WO_EQUIV; + eExtraOp = WO_EQUIV; + } + }else{ + pDup = pExpr; + pNew = pTerm; + } + pNew->wtFlags |= exprCommute(pParse, pDup); + pNew->leftCursor = aiCurCol[0]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pNew->u.x.leftColumn = aiCurCol[1]; + testcase( (prereqLeft | extraRight) != prereqLeft ); + pNew->prereqRight = prereqLeft | extraRight; + pNew->prereqAll = prereqAll; + pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + }else + if( op==TK_ISNULL + && !ExprHasProperty(pExpr,EP_OuterON) + && 0==sqlite3ExprCanBeNull(pLeft) + ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pExpr->op = TK_TRUEFALSE; /* See tag-20230504-1 */ + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; + } + } + +#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION + /* If a term is the BETWEEN operator, create two new virtual terms + ** that define the range that the BETWEEN implements. For example: + ** + ** a BETWEEN b AND c + ** + ** is converted into: + ** + ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c) + ** + ** The two new terms are added onto the end of the WhereClause object. + ** The new terms are "dynamic" and are children of the original BETWEEN + ** term. That means that if the BETWEEN term is coded, the children are + ** skipped. Or, if the children are satisfied by an index, the original + ** BETWEEN term is skipped. + */ + else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ + ExprList *pList; + int i; + static const u8 ops[] = {TK_GE, TK_LE}; + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + assert( pList!=0 ); + assert( pList->nExpr==2 ); + for(i=0; i<2; i++){ + Expr *pNewExpr; + int idxNew; + pNewExpr = sqlite3PExpr(pParse, ops[i], + sqlite3ExprDup(db, pExpr->pLeft, 0), + sqlite3ExprDup(db, pList->a[i].pExpr, 0)); + transferJoinMarkings(pNewExpr, pExpr); + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + exprAnalyze(pSrc, pWC, idxNew); + pTerm = &pWC->a[idxTerm]; + markTermAsChild(pWC, idxNew, idxTerm); + } + } +#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */ + +#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) + /* Analyze a term that is composed of two or more subterms connected by + ** an OR operator. + */ + else if( pExpr->op==TK_OR ){ + assert( pWC->op==TK_AND ); + exprAnalyzeOrTerm(pSrc, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; + } +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + /* The form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** The virtual term must be tagged with TERM_VNULL. + */ + else if( pExpr->op==TK_NOTNULL ){ + if( pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + && !ExprHasProperty(pExpr, EP_OuterON) + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } + } + + +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION + /* Add constraints to reduce the search space on a LIKE or GLOB + ** operator. + ** + ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints + ** + ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%' + ** + ** The last character of the prefix "abc" is incremented to form the + ** termination condition "abd". If case is not significant (the default + ** for LIKE) then the lower-bound is made all uppercase and the upper- + ** bound is made all lowercase so that the bounds also work when comparing + ** BLOBs. + */ + else if( pExpr->op==TK_FUNCTION + && pWC->op==TK_AND + && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) + ){ + Expr *pLeft; /* LHS of LIKE/GLOB operator */ + Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */ + Expr *pNewExpr1; + Expr *pNewExpr2; + int idxNew1; + int idxNew2; + const char *zCollSeqName; /* Name of collating sequence */ + const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; + + assert( ExprUseXList(pExpr) ); + pLeft = pExpr->x.pList->a[1].pExpr; + pStr2 = sqlite3ExprDup(db, pStr1, 0); + assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) ); + assert( pStr2==0 || !ExprHasProperty(pStr2, EP_IntValue) ); + + + /* Convert the lower bound to upper-case and the upper bound to + ** lower-case (upper-case is less than lower-case in ASCII) so that + ** the range constraints also work for BLOBs + */ + if( noCase && !pParse->db->mallocFailed ){ + int i; + char c; + pTerm->wtFlags |= TERM_LIKE; + for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ + pStr1->u.zToken[i] = sqlite3Toupper(c); + pStr2->u.zToken[i] = sqlite3Tolower(c); + } + } + + if( !db->mallocFailed ){ + u8 c, *pC; /* Last character before the first wildcard */ + pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; + c = *pC; + if( noCase ){ + /* The point is to increment the last character before the first + ** wildcard. But if we increment '@', that will push it into the + ** alphabetic range where case conversions will mess up the + ** inequality. To avoid this, make sure to also run the full + ** LIKE on all candidate expressions by clearing the isComplete flag + */ + if( c=='A'-1 ) isComplete = 0; + c = sqlite3UpperToLower[c]; + } + *pC = c + 1; + } + zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; + pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), + pStr1); + transferJoinMarkings(pNewExpr1, pExpr); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); + testcase( idxNew1==0 ); + pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, + sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), + pStr2); + transferJoinMarkings(pNewExpr2, pExpr); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); + testcase( idxNew2==0 ); + exprAnalyze(pSrc, pWC, idxNew1); + exprAnalyze(pSrc, pWC, idxNew2); + pTerm = &pWC->a[idxTerm]; + if( isComplete ){ + markTermAsChild(pWC, idxNew1, idxTerm); + markTermAsChild(pWC, idxNew2, idxTerm); + } + } +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + + /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create + ** new terms for each component comparison - "a = ?" and "b = ?". The + ** new terms completely replace the original vector comparison, which is + ** no longer used. + ** + ** This is only required if at least one side of the comparison operation + ** is not a sub-select. + ** + ** tag-20220128a + */ + if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) + && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 + && sqlite3ExprVectorSize(pExpr->pRight)==nLeft + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + || (pExpr->pRight->flags & EP_xIsSelect)==0) + && pWC->op==TK_AND + ){ + int i; + for(i=0; ipLeft, i, nLeft); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft); + + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); + transferJoinMarkings(pNew, pExpr); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE); + exprAnalyze(pSrc, pWC, idxNew); + } + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ + pTerm->eOperator = WO_ROWVAL; + } + + /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create + ** a virtual term for each vector component. The expression object + ** used by each such virtual term is pExpr (the full vector IN(...) + ** expression). The WhereTerm.u.x.iField variable identifies the index within + ** the vector on the LHS that the virtual term represents. + ** + ** This only works if the RHS is a simple SELECT (not a compound) that does + ** not use window functions. + */ + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 + && pExpr->pLeft->op==TK_VECTOR + && ALWAYS( ExprUseXSelect(pExpr) ) + && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values)) +#ifndef SQLITE_OMIT_WINDOWFUNC + && pExpr->x.pSelect->pWin==0 +#endif + && pWC->op==TK_AND + ){ + int i; + for(i=0; ipLeft); i++){ + int idxNew; + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); + pWC->a[idxNew].u.x.iField = i+1; + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + } + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Add a WO_AUX auxiliary term to the constraint set if the + ** current expression is of the form "column OP expr" where OP + ** is an operator that gets passed into virtual tables but which is + ** not normally optimized for ordinary tables. In other words, OP + ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. + ** This information is used by the xBestIndex methods of + ** virtual tables. The native query optimizer does not attempt + ** to do anything with MATCH functions. + */ + else if( pWC->op==TK_AND ){ + Expr *pRight = 0, *pLeft = 0; + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); + while( res-- > 0 ){ + int idxNew; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; + + prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); + prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0)); + if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){ + ExprSetProperty(pNewExpr, EP_OuterON); + pNewExpr->w.iJoin = pExpr->w.iJoin; + } + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_AUX; + pNewTerm->eMatchOp = eOp2; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + SWAP(Expr*, pLeft, pRight); + } + } +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + /* Prevent ON clause terms of a LEFT JOIN from being used to drive + ** an index for tables to the left of the join. + */ + testcase( pTerm!=&pWC->a[idxTerm] ); + pTerm = &pWC->a[idxTerm]; + pTerm->prereqRight |= extraRight; +} + +/*************************************************************************** +** Routines with file scope above. Interface to the rest of the where.c +** subsystem follows. +***************************************************************************/ + +/* +** This routine identifies subexpressions in the WHERE clause where +** each subexpression is separated by the AND operator or some other +** operator specified in the op parameter. The WhereClause structure +** is filled with pointers to subexpressions. For example: +** +** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22) +** \________/ \_______________/ \________________/ +** slot[0] slot[1] slot[2] +** +** The original WHERE clause in pExpr is unaltered. All this routine +** does is make slot[] entries point to substructure within pExpr. +** +** In the previous sentence and in the diagram, "slot[]" refers to +** the WhereClause.a[] array. The slot[] array grows as needed to contain +** all terms of the WHERE clause. +*/ +SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); + pWC->op = op; + assert( pE2!=0 || pExpr==0 ); + if( pE2==0 ) return; + if( pE2->op!=op ){ + whereClauseInsert(pWC, pExpr, 0); + }else{ + sqlite3WhereSplit(pWC, pE2->pLeft, op); + sqlite3WhereSplit(pWC, pE2->pRight, op); + } +} + +/* +** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or +** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the +** where-clause passed as the first argument. The value for the term +** is found in register iReg. +** +** In the common case where the value is a simple integer +** (example: "LIMIT 5 OFFSET 10") then the expression codes as a +** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value(). +** If not, then it codes as a TK_REGISTER expression. +*/ +static void whereAddLimitExpr( + WhereClause *pWC, /* Add the constraint to this WHERE clause */ + int iReg, /* Register that will hold value of the limit/offset */ + Expr *pExpr, /* Expression that defines the limit/offset */ + int iCsr, /* Cursor to which the constraint applies */ + int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */ +){ + Parse *pParse = pWC->pWInfo->pParse; + sqlite3 *db = pParse->db; + Expr *pNew; + int iVal = 0; + + if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ + Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); + if( pVal==0 ) return; + ExprSetProperty(pVal, EP_IntValue); + pVal->u.iValue = iVal; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + }else{ + Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0); + if( pVal==0 ) return; + pVal->iTable = iReg; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + } + if( pNew ){ + WhereTerm *pTerm; + int idx; + idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL); + pTerm = &pWC->a[idx]; + pTerm->leftCursor = iCsr; + pTerm->eOperator = WO_AUX; + pTerm->eMatchOp = eMatchOp; + } +} + +/* +** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the +** SELECT statement passed as the second argument. These terms are only +** added if: +** +** 1. The SELECT statement has a LIMIT clause, and +** 2. The SELECT statement is not an aggregate or DISTINCT query, and +** 3. The SELECT statement has exactly one object in its from clause, and +** that object is a virtual table, and +** 4. There are no terms in the WHERE clause that will not be passed +** to the virtual table xBestIndex method. +** 5. The ORDER BY clause, if any, will be made available to the xBestIndex +** method. +** +** LIMIT and OFFSET terms are ignored by most of the planner code. They +** exist only so that they may be passed to the xBestIndex method of the +** single virtual table in the FROM clause of the SELECT. +*/ +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ + assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ + if( p->pGroupBy==0 + && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ + ){ + ExprList *pOrderBy = p->pOrderBy; + int iCsr = p->pSrc->a[0].iCursor; + int ii; + + /* Check condition (4). Return early if it is not met. */ + for(ii=0; iinTerm; ii++){ + if( pWC->a[ii].wtFlags & TERM_CODED ){ + /* This term is a vector operation that has been decomposed into + ** other, subsequent terms. It can be ignored. See tag-20220128a */ + assert( pWC->a[ii].wtFlags & TERM_VIRTUAL ); + assert( pWC->a[ii].eOperator==WO_ROWVAL ); + continue; + } + if( pWC->a[ii].nChild ){ + /* If this term has child terms, then they are also part of the + ** pWC->a[] array. So this term can be ignored, as a LIMIT clause + ** will only be added if each of the child terms passes the + ** (leftCursor==iCsr) test below. */ + continue; + } + if( pWC->a[ii].leftCursor!=iCsr ) return; + } + + /* Check condition (5). Return early if it is not met. */ + if( pOrderBy ){ + for(ii=0; iinExpr; ii++){ + Expr *pExpr = pOrderBy->a[ii].pExpr; + if( pExpr->op!=TK_COLUMN ) return; + if( pExpr->iTable!=iCsr ) return; + if( pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) return; + } + } + + /* All conditions are met. Add the terms to the where-clause object. */ + assert( p->pLimit->op==TK_LIMIT ); + whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, + iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); + if( p->iOffset>0 ){ + whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, + iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); + } + } +} + +/* +** Initialize a preallocated WhereClause structure. +*/ +SQLITE_PRIVATE void sqlite3WhereClauseInit( + WhereClause *pWC, /* The WhereClause to be initialized */ + WhereInfo *pWInfo /* The WHERE processing context */ +){ + pWC->pWInfo = pWInfo; + pWC->hasOr = 0; + pWC->pOuter = 0; + pWC->nTerm = 0; + pWC->nBase = 0; + pWC->nSlot = ArraySize(pWC->aStatic); + pWC->a = pWC->aStatic; +} + +/* +** Deallocate a WhereClause structure. The WhereClause structure +** itself is not freed. This routine is the inverse of +** sqlite3WhereClauseInit(). +*/ +SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ + sqlite3 *db = pWC->pWInfo->pParse->db; + assert( pWC->nTerm>=pWC->nBase ); + if( pWC->nTerm>0 ){ + WhereTerm *a = pWC->a; + WhereTerm *aLast = &pWC->a[pWC->nTerm-1]; +#ifdef SQLITE_DEBUG + int i; + /* Verify that every term past pWC->nBase is virtual */ + for(i=pWC->nBase; inTerm; i++){ + assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 ); + } +#endif + while(1){ + assert( a->eMatchOp==0 || a->eOperator==WO_AUX ); + if( a->wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, a->pExpr); + } + if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){ + if( a->wtFlags & TERM_ORINFO ){ + assert( (a->wtFlags & TERM_ANDINFO)==0 ); + whereOrInfoDelete(db, a->u.pOrInfo); + }else{ + assert( (a->wtFlags & TERM_ANDINFO)!=0 ); + whereAndInfoDelete(db, a->u.pAndInfo); + } + } + if( a==aLast ) break; + a++; + } + } +} + + +/* +** These routines walk (recursively) an expression tree and generate +** a bitmask indicating which tables are used in that expression +** tree. +** +** sqlite3WhereExprUsage(MaskSet, Expr) -> +** +** Return a Bitmask of all tables referenced by Expr. Expr can be +** be NULL, in which case 0 is returned. +** +** sqlite3WhereExprUsageNN(MaskSet, Expr) -> +** +** Same as sqlite3WhereExprUsage() except that Expr must not be +** NULL. The "NN" suffix on the name stands for "Not Null". +** +** sqlite3WhereExprListUsage(MaskSet, ExprList) -> +** +** Return a Bitmask of all tables referenced by every expression +** in the expression list ExprList. ExprList can be NULL, in which +** case 0 is returned. +** +** sqlite3WhereExprUsageFull(MaskSet, ExprList) -> +** +** Internal use only. Called only by sqlite3WhereExprUsageNN() for +** complex expressions that require pushing register values onto +** the stack. Many calls to sqlite3WhereExprUsageNN() do not need +** the more complex analysis done by this routine. Hence, the +** computations done by this routine are broken out into a separate +** "no-inline" function to avoid the stack push overhead in the +** common case where it is not needed. +*/ +static SQLITE_NOINLINE Bitmask sqlite3WhereExprUsageFull( + WhereMaskSet *pMaskSet, + Expr *p +){ + Bitmask mask; + mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; + if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); + if( p->pRight ){ + mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); + assert( p->x.pList==0 ); + }else if( ExprUseXSelect(p) ){ + if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; + mask |= exprSelectUsage(pMaskSet, p->x.pSelect); + }else if( p->x.pList ){ + mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && ExprUseYWin(p) ){ + assert( p->y.pWin!=0 ); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); + } +#endif + return mask; +} +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ + if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return sqlite3WhereGetMask(pMaskSet, p->iTable); + }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + assert( p->op!=TK_IF_NULL_ROW ); + return 0; + } + return sqlite3WhereExprUsageFull(pMaskSet, p); +} +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ + return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; +} +SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ + int i; + Bitmask mask = 0; + if( pList ){ + for(i=0; inExpr; i++){ + mask |= sqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr); + } + } + return mask; +} + + +/* +** Call exprAnalyze on all terms in a WHERE clause. +** +** Note that exprAnalyze() might add new virtual terms onto the +** end of the WHERE clause. We do not want to analyze these new +** virtual terms, so start analyzing at the end and work forward +** so that the added virtual terms are never processed. +*/ +SQLITE_PRIVATE void sqlite3WhereExprAnalyze( + SrcList *pTabList, /* the FROM clause */ + WhereClause *pWC /* the WHERE clause to be analyzed */ +){ + int i; + for(i=pWC->nTerm-1; i>=0; i--){ + exprAnalyze(pTabList, pWC, i); + } +} + +/* +** For table-valued-functions, transform the function arguments into +** new WHERE clause terms. +** +** Each function argument translates into an equality constraint against +** a HIDDEN column in the table. +*/ +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( + Parse *pParse, /* Parsing context */ + SrcItem *pItem, /* The FROM clause term to process */ + WhereClause *pWC /* Xfer function arguments to here */ +){ + Table *pTab; + int j, k; + ExprList *pArgs; + Expr *pColRef; + Expr *pTerm; + if( pItem->fg.isTabFunc==0 ) return; + pTab = pItem->pTab; + assert( pTab!=0 ); + pArgs = pItem->u1.pFuncArg; + if( pArgs==0 ) return; + for(j=k=0; jnExpr; j++){ + Expr *pRhs; + u32 joinType; + while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} + if( k>=pTab->nCol ){ + sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", + pTab->zName, j); + return; + } + pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); + if( pColRef==0 ) return; + pColRef->iTable = pItem->iCursor; + pColRef->iColumn = k++; + assert( ExprUseYTab(pColRef) ); + pColRef->y.pTab = pTab; + pItem->colUsed |= sqlite3ExprColUsed(pColRef); + pRhs = sqlite3PExpr(pParse, TK_UPLUS, + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); + if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){ + testcase( pItem->fg.jointype & JT_LEFT ); /* testtag-20230227a */ + testcase( pItem->fg.jointype & JT_RIGHT ); /* testtag-20230227b */ + joinType = EP_OuterON; + }else{ + testcase( pItem->fg.jointype & JT_LTORJ ); /* testtag-20230227c */ + joinType = EP_InnerON; + } + sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); + whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); + } +} + +/************** End of whereexpr.c *******************************************/ +/************** Begin file where.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. This module is responsible for +** generating the code that loops through a table looking for applicable +** rows. Indices are selected and used to speed the search when doing +** so is applicable. Because this module is responsible for selecting +** indices, you might also think of this module as the "query optimizer". +*/ +/* #include "sqliteInt.h" */ +/* #include "whereInt.h" */ + +/* +** Extra information appended to the end of sqlite3_index_info but not +** visible to the xBestIndex function, at least not directly. The +** sqlite3_vtab_collation() interface knows how to reach it, however. +** +** This object is not an API and can be changed from one release to the +** next. As long as allocateIndexInfo() and sqlite3_vtab_collation() +** agree on the structure, all will be well. +*/ +typedef struct HiddenIndexInfo HiddenIndexInfo; +struct HiddenIndexInfo { + WhereClause *pWC; /* The Where clause being analyzed */ + Parse *pParse; /* The parsing context */ + int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ + u32 mIn; /* Mask of terms that are IN (...) */ + u32 mHandleIn; /* Terms that vtab will handle as IN (...) */ + sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST + ** because extra space is allocated to hold up + ** to nTerm such values */ +}; + +/* Forward declaration of methods */ +static int whereLoopResize(sqlite3*, WhereLoop*, int); + +/* +** Return the estimated number of output rows from a WHERE clause +*/ +SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ + return pWInfo->nRowOut; +} + +/* +** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this +** WHERE clause returns outputs for DISTINCT processing. +*/ +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){ + return pWInfo->eDistinct; +} + +/* +** Return the number of ORDER BY terms that are satisfied by the +** WHERE clause. A return of 0 means that the output must be +** completely sorted. A return equal to the number of ORDER BY +** terms means that no sorting is needed at all. A return that +** is positive but less than the number of ORDER BY terms means that +** block sorting is required. +*/ +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ + return pWInfo->nOBSat<0 ? 0 : pWInfo->nOBSat; +} + +/* +** In the ORDER BY LIMIT optimization, if the inner-most loop is known +** to emit rows in increasing order, and if the last row emitted by the +** inner-most loop did not fit within the sorter, then we can skip all +** subsequent rows for the current iteration of the inner loop (because they +** will not fit in the sorter either) and continue with the second inner +** loop - the loop immediately outside the inner-most. +** +** When a row does not fit in the sorter (because the sorter already +** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the +** label returned by this function. +** +** If the ORDER BY LIMIT optimization applies, the jump destination should +** be the continuation for the second-inner-most loop. If the ORDER BY +** LIMIT optimization does not apply, then the jump destination should +** be the continuation for the inner-most loop. +** +** It is always safe for this routine to return the continuation of the +** inner-most loop, in the sense that a correct answer will result. +** Returning the continuation the second inner loop is an optimization +** that might make the code run a little faster, but should not change +** the final answer. +*/ +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ + WhereLevel *pInner; + if( !pWInfo->bOrderedInnerLoop ){ + /* The ORDER BY LIMIT optimization does not apply. Jump to the + ** continuation of the inner-most loop. */ + return pWInfo->iContinue; + } + pInner = &pWInfo->a[pWInfo->nLevel-1]; + assert( pInner->addrNxt!=0 ); + return pInner->pRJ ? pWInfo->iContinue : pInner->addrNxt; +} + +/* +** While generating code for the min/max optimization, after handling +** the aggregate-step call to min() or max(), check to see if any +** additional looping is required. If the output order is such that +** we are certain that the correct answer has already been found, then +** code an OP_Goto to by pass subsequent processing. +** +** Any extra OP_Goto that is coded here is an optimization. The +** correct answer should be obtained regardless. This OP_Goto just +** makes the answer appear faster. +*/ +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){ + WhereLevel *pInner; + int i; + if( !pWInfo->bOrderedInnerLoop ) return; + if( pWInfo->nOBSat==0 ) return; + for(i=pWInfo->nLevel-1; i>=0; i--){ + pInner = &pWInfo->a[i]; + if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)!=0 ){ + sqlite3VdbeGoto(v, pInner->addrNxt); + return; + } + } + sqlite3VdbeGoto(v, pWInfo->iBreak); +} + +/* +** Return the VDBE address or label to jump to in order to continue +** immediately with the next row of a WHERE clause. +*/ +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ + assert( pWInfo->iContinue!=0 ); + return pWInfo->iContinue; +} + +/* +** Return the VDBE address or label to jump to in order to break +** out of a WHERE loop. +*/ +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ + return pWInfo->iBreak; +} + +/* +** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to +** operate directly on the rowids returned by a WHERE clause. Return +** ONEPASS_SINGLE (1) if the statement can operation directly because only +** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass +** optimization can be used on multiple +** +** If the ONEPASS optimization is used (if this routine returns true) +** then also write the indices of open cursors used by ONEPASS +** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data +** table and iaCur[1] gets the cursor used by an auxiliary index. +** Either value may be -1, indicating that cursor is not used. +** Any cursors returned will have been opened for writing. +** +** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is +** unable to use the ONEPASS optimization. +*/ +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ + memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2); +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){ + sqlite3DebugPrintf("%s cursors: %d %d\n", + pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI", + aiCur[0], aiCur[1]); + } +#endif + return pWInfo->eOnePass; +} + +/* +** Return TRUE if the WHERE loop uses the OP_DeferredSeek opcode to move +** the data cursor to the row selected by the index cursor. +*/ +SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo *pWInfo){ + return pWInfo->bDeferredSeek; +} + +/* +** Move the content of pSrc into pDest +*/ +static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){ + pDest->n = pSrc->n; + memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0])); +} + +/* +** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet. +** +** The new entry might overwrite an existing entry, or it might be +** appended, or it might be discarded. Do whatever is the right thing +** so that pSet keeps the N_OR_COST best entries seen so far. +*/ +static int whereOrInsert( + WhereOrSet *pSet, /* The WhereOrSet to be updated */ + Bitmask prereq, /* Prerequisites of the new entry */ + LogEst rRun, /* Run-cost of the new entry */ + LogEst nOut /* Number of outputs for the new entry */ +){ + u16 i; + WhereOrCost *p; + for(i=pSet->n, p=pSet->a; i>0; i--, p++){ + if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){ + goto whereOrInsert_done; + } + if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){ + return 0; + } + } + if( pSet->na[pSet->n++]; + p->nOut = nOut; + }else{ + p = pSet->a; + for(i=1; in; i++){ + if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i; + } + if( p->rRun<=rRun ) return 0; + } +whereOrInsert_done: + p->prereq = prereq; + p->rRun = rRun; + if( p->nOut>nOut ) p->nOut = nOut; + return 1; +} + +/* +** Return the bitmask for the given cursor number. Return 0 if +** iCursor is not in the set. +*/ +SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ + int i; + assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); + assert( pMaskSet->n>0 || pMaskSet->ix[0]<0 ); + assert( iCursor>=-1 ); + if( pMaskSet->ix[0]==iCursor ){ + return 1; + } + for(i=1; in; i++){ + if( pMaskSet->ix[i]==iCursor ){ + return MASKBIT(i); + } + } + return 0; +} + +/* Allocate memory that is automatically freed when pWInfo is freed. +*/ +SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){ + WhereMemBlock *pBlock; + pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock)); + if( pBlock ){ + pBlock->pNext = pWInfo->pMemToFree; + pBlock->sz = nByte; + pWInfo->pMemToFree = pBlock; + pBlock++; + } + return (void*)pBlock; +} +SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){ + void *pNew = sqlite3WhereMalloc(pWInfo, nByte); + if( pNew && pOld ){ + WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld; + pOldBlk--; + assert( pOldBlk->szsz); + } + return pNew; +} + +/* +** Create a new mask for cursor iCursor. +** +** There is one cursor per table in the FROM clause. The number of +** tables in the FROM clause is limited by a test early in the +** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[] +** array will never overflow. +*/ +static void createMask(WhereMaskSet *pMaskSet, int iCursor){ + assert( pMaskSet->n < ArraySize(pMaskSet->ix) ); + pMaskSet->ix[pMaskSet->n++] = iCursor; +} + +/* +** If the right-hand branch of the expression is a TK_COLUMN, then return +** a pointer to the right-hand branch. Otherwise, return NULL. +*/ +static Expr *whereRightSubexprIsColumn(Expr *p){ + p = sqlite3ExprSkipCollateAndLikely(p->pRight); + if( ALWAYS(p!=0) && p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return p; + } + return 0; +} + +/* +** Advance to the next WhereTerm that matches according to the criteria +** established when the pScan object was initialized by whereScanInit(). +** Return NULL if there are no more matching WhereTerms. +*/ +static WhereTerm *whereScanNext(WhereScan *pScan){ + int iCur; /* The cursor on the LHS of the term */ + i16 iColumn; /* The column on the LHS of the term. -1 for IPK */ + Expr *pX; /* An expression being tested */ + WhereClause *pWC; /* Shorthand for pScan->pWC */ + WhereTerm *pTerm; /* The term being tested */ + int k = pScan->k; /* Where to start scanning */ + + assert( pScan->iEquiv<=pScan->nEquiv ); + pWC = pScan->pWC; + while(1){ + iColumn = pScan->aiColumn[pScan->iEquiv-1]; + iCur = pScan->aiCur[pScan->iEquiv-1]; + assert( pWC!=0 ); + assert( iCur>=0 ); + do{ + for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 || pTerm->leftCursor<0 ); + if( pTerm->leftCursor==iCur + && pTerm->u.x.leftColumn==iColumn + && (iColumn!=XN_EXPR + || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, + pScan->pIdxExpr,iCur)==0) + && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_OuterON)) + ){ + if( (pTerm->eOperator & WO_EQUIV)!=0 + && pScan->nEquivaiCur) + && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0 + ){ + int j; + for(j=0; jnEquiv; j++){ + if( pScan->aiCur[j]==pX->iTable + && pScan->aiColumn[j]==pX->iColumn ){ + break; + } + } + if( j==pScan->nEquiv ){ + pScan->aiCur[j] = pX->iTable; + pScan->aiColumn[j] = pX->iColumn; + pScan->nEquiv++; + } + } + if( (pTerm->eOperator & pScan->opMask)!=0 ){ + /* Verify the affinity and collating sequence match */ + if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ + CollSeq *pColl; + Parse *pParse = pWC->pWInfo->pParse; + pX = pTerm->pExpr; + if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ + continue; + } + assert(pX->pLeft); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + if( pColl==0 ) pColl = pParse->db->pDfltColl; + if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ + continue; + } + } + if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0 + && (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0)) + && pX->op==TK_COLUMN + && pX->iTable==pScan->aiCur[0] + && pX->iColumn==pScan->aiColumn[0] + ){ + testcase( pTerm->eOperator & WO_IS ); + continue; + } + pScan->pWC = pWC; + pScan->k = k+1; +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x20000 ){ + int ii; + sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d", + pTerm, pScan->nEquiv); + for(ii=0; iinEquiv; ii++){ + sqlite3DebugPrintf(" {%d:%d}", + pScan->aiCur[ii], pScan->aiColumn[ii]); + } + sqlite3DebugPrintf("\n"); + } +#endif + return pTerm; + } + } + } + pWC = pWC->pOuter; + k = 0; + }while( pWC!=0 ); + if( pScan->iEquiv>=pScan->nEquiv ) break; + pWC = pScan->pOrigWC; + k = 0; + pScan->iEquiv++; + } + return 0; +} + +/* +** This is whereScanInit() for the case of an index on an expression. +** It is factored out into a separate tail-recursion subroutine so that +** the normal whereScanInit() routine, which is a high-runner, does not +** need to push registers onto the stack as part of its prologue. +*/ +static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){ + pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr); + return whereScanNext(pScan); +} + +/* +** Initialize a WHERE clause scanner object. Return a pointer to the +** first match. Return NULL if there are no matches. +** +** The scanner will be searching the WHERE clause pWC. It will look +** for terms of the form "X " where X is column iColumn of table +** iCur. Or if pIdx!=0 then X is column iColumn of index pIdx. pIdx +** must be one of the indexes of table iCur. +** +** The must be one of the operators described by opMask. +** +** If the search is for X and the WHERE clause contains terms of the +** form X=Y then this routine might also return terms of the form +** "Y ". The number of levels of transitivity is limited, +** but is enough to handle most commonly occurring SQL statements. +** +** If X is not the INTEGER PRIMARY KEY then X must be compatible with +** index pIdx. +*/ +static WhereTerm *whereScanInit( + WhereScan *pScan, /* The WhereScan object being initialized */ + WhereClause *pWC, /* The WHERE clause to be scanned */ + int iCur, /* Cursor to scan for */ + int iColumn, /* Column to scan for */ + u32 opMask, /* Operator(s) to scan for */ + Index *pIdx /* Must be compatible with this index */ +){ + pScan->pOrigWC = pWC; + pScan->pWC = pWC; + pScan->pIdxExpr = 0; + pScan->idxaff = 0; + pScan->zCollName = 0; + pScan->opMask = opMask; + pScan->k = 0; + pScan->aiCur[0] = iCur; + pScan->nEquiv = 1; + pScan->iEquiv = 1; + if( pIdx ){ + int j = iColumn; + iColumn = pIdx->aiColumn[j]; + if( iColumn==pIdx->pTable->iPKey ){ + iColumn = XN_ROWID; + }else if( iColumn>=0 ){ + pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; + pScan->zCollName = pIdx->azColl[j]; + }else if( iColumn==XN_EXPR ){ + pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + pScan->zCollName = pIdx->azColl[j]; + pScan->aiColumn[0] = XN_EXPR; + return whereScanInitIndexExpr(pScan); + } + }else if( iColumn==XN_EXPR ){ + return 0; + } + pScan->aiColumn[0] = iColumn; + return whereScanNext(pScan); +} + +/* +** Search for a term in the WHERE clause that is of the form "X " +** where X is a reference to the iColumn of table iCur or of index pIdx +** if pIdx!=0 and is one of the WO_xx operator codes specified by +** the op parameter. Return a pointer to the term. Return 0 if not found. +** +** If pIdx!=0 then it must be one of the indexes of table iCur. +** Search for terms matching the iColumn-th column of pIdx +** rather than the iColumn-th column of table iCur. +** +** The term returned might by Y= if there is another constraint in +** the WHERE clause that specifies that X=Y. Any such constraints will be +** identified by the WO_EQUIV bit in the pTerm->eOperator field. The +** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11 +** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10 +** other equivalent values. Hence a search for X will return if X=A1 +** and A1=A2 and A2=A3 and ... and A9=A10 and A10=. +** +** If there are multiple terms in the WHERE clause of the form "X " +** then try for the one with no dependencies on - in other words where +** is a constant expression of some kind. Only return entries of +** the form "X Y" where Y is a column in another table if no terms of +** the form "X " exist. If no terms with a constant RHS +** exist, try to return a term that does not use WO_EQUIV. +*/ +SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( + WhereClause *pWC, /* The WHERE clause to be searched */ + int iCur, /* Cursor number of LHS */ + int iColumn, /* Column number of LHS */ + Bitmask notReady, /* RHS must not overlap with this mask */ + u32 op, /* Mask of WO_xx values describing operator */ + Index *pIdx /* Must be compatible with this index, if not NULL */ +){ + WhereTerm *pResult = 0; + WhereTerm *p; + WhereScan scan; + + p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx); + op &= WO_EQ|WO_IS; + while( p ){ + if( (p->prereqRight & notReady)==0 ){ + if( p->prereqRight==0 && (p->eOperator&op)!=0 ){ + testcase( p->eOperator & WO_IS ); + return p; + } + if( pResult==0 ) pResult = p; + } + p = whereScanNext(&scan); + } + return pResult; +} + +/* +** This function searches pList for an entry that matches the iCol-th column +** of index pIdx. +** +** If such an expression is found, its index in pList->a[] is returned. If +** no expression is found, -1 is returned. +*/ +static int findIndexCol( + Parse *pParse, /* Parse context */ + ExprList *pList, /* Expression list to search */ + int iBase, /* Cursor for table associated with pIdx */ + Index *pIdx, /* Index to match column of */ + int iCol /* Column of index to match */ +){ + int i; + const char *zColl = pIdx->azColl[iCol]; + + for(i=0; inExpr; i++){ + Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); + if( ALWAYS(p!=0) + && (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) + && p->iColumn==pIdx->aiColumn[iCol] + && p->iTable==iBase + ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); + if( 0==sqlite3StrICmp(pColl->zName, zColl) ){ + return i; + } + } + } + + return -1; +} + +/* +** Return TRUE if the iCol-th column of index pIdx is NOT NULL +*/ +static int indexColumnNotNull(Index *pIdx, int iCol){ + int j; + assert( pIdx!=0 ); + assert( iCol>=0 && iColnColumn ); + j = pIdx->aiColumn[iCol]; + if( j>=0 ){ + return pIdx->pTable->aCol[j].notNull; + }else if( j==(-1) ){ + return 1; + }else{ + assert( j==(-2) ); + return 0; /* Assume an indexed expression can always yield a NULL */ + + } +} + +/* +** Return true if the DISTINCT expression-list passed as the third argument +** is redundant. +** +** A DISTINCT list is redundant if any subset of the columns in the +** DISTINCT list are collectively unique and individually non-null. +*/ +static int isDistinctRedundant( + Parse *pParse, /* Parsing context */ + SrcList *pTabList, /* The FROM clause */ + WhereClause *pWC, /* The WHERE clause */ + ExprList *pDistinct /* The result set that needs to be DISTINCT */ +){ + Table *pTab; + Index *pIdx; + int i; + int iBase; + + /* If there is more than one table or sub-select in the FROM clause of + ** this query, then it will not be possible to show that the DISTINCT + ** clause is redundant. */ + if( pTabList->nSrc!=1 ) return 0; + iBase = pTabList->a[0].iCursor; + pTab = pTabList->a[0].pTab; + + /* If any of the expressions is an IPK column on table iBase, then return + ** true. Note: The (p->iTable==iBase) part of this test may be false if the + ** current SELECT is a correlated sub-query. + */ + for(i=0; inExpr; i++){ + Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); + if( NEVER(p==0) ) continue; + if( p->op!=TK_COLUMN && p->op!=TK_AGG_COLUMN ) continue; + if( p->iTable==iBase && p->iColumn<0 ) return 1; + } + + /* Loop through all indices on the table, checking each to see if it makes + ** the DISTINCT qualifier redundant. It does so if: + ** + ** 1. The index is itself UNIQUE, and + ** + ** 2. All of the columns in the index are either part of the pDistinct + ** list, or else the WHERE clause contains a term of the form "col=X", + ** where X is a constant value. The collation sequences of the + ** comparison and select-list expressions must match those of the index. + ** + ** 3. All of those index columns for which the WHERE clause does not + ** contain a "col=X" term are subject to a NOT NULL constraint. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( !IsUniqueIndex(pIdx) ) continue; + if( pIdx->pPartIdxWhere ) continue; + for(i=0; inKeyCol; i++){ + if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){ + if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break; + if( indexColumnNotNull(pIdx, i)==0 ) break; + } + } + if( i==pIdx->nKeyCol ){ + /* This index implies that the DISTINCT qualifier is redundant. */ + return 1; + } + } + + return 0; +} + + +/* +** Estimate the logarithm of the input value to base 2. +*/ +static LogEst estLog(LogEst N){ + return N<=10 ? 0 : sqlite3LogEst(N) - 33; +} + +/* +** Convert OP_Column opcodes to OP_Copy in previously generated code. +** +** This routine runs over generated VDBE code and translates OP_Column +** opcodes into OP_Copy when the table is being accessed via co-routine +** instead of via table lookup. +** +** If the iAutoidxCur is not zero, then any OP_Rowid instructions on +** cursor iTabCur are transformed into OP_Sequence opcode for the +** iAutoidxCur cursor, in order to generate unique rowids for the +** automatic index being generated. +*/ +static void translateColumnToCopy( + Parse *pParse, /* Parsing context */ + int iStart, /* Translate from this opcode to the end */ + int iTabCur, /* OP_Column/OP_Rowid references to this table */ + int iRegister, /* The first column is in this register */ + int iAutoidxCur /* If non-zero, cursor of autoindex being generated */ +){ + Vdbe *v = pParse->pVdbe; + VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); + int iEnd = sqlite3VdbeCurrentAddr(v); + if( pParse->db->mallocFailed ) return; + for(; iStartp1!=iTabCur ) continue; + if( pOp->opcode==OP_Column ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); + } +#endif + pOp->opcode = OP_Copy; + pOp->p1 = pOp->p2 + iRegister; + pOp->p2 = pOp->p3; + pOp->p3 = 0; + pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ + }else if( pOp->opcode==OP_Rowid ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart); + } +#endif + pOp->opcode = OP_Sequence; + pOp->p1 = iAutoidxCur; +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( iAutoidxCur==0 ){ + pOp->opcode = OP_Null; + pOp->p3 = 0; + } +#endif + } + } +} + +/* +** Two routines for printing the content of an sqlite3_index_info +** structure. Used for testing and debugging only. If neither +** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines +** are no-ops. +*/ +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) +static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ + int i; + if( (sqlite3WhereTrace & 0x10)==0 ) return; + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf( + " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", + i, + p->aConstraint[i].iColumn, + p->aConstraint[i].iTermOffset, + p->aConstraint[i].op, + p->aConstraint[i].usable, + sqlite3_vtab_collation(p,i)); + } + for(i=0; inOrderBy; i++){ + sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", + i, + p->aOrderBy[i].iColumn, + p->aOrderBy[i].desc); + } +} +static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ + int i; + if( (sqlite3WhereTrace & 0x10)==0 ) return; + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", + i, + p->aConstraintUsage[i].argvIndex, + p->aConstraintUsage[i].omit); + } + sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); + sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); + sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); + sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); + sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); +} +#else +#define whereTraceIndexInfoInputs(A) +#define whereTraceIndexInfoOutputs(A) +#endif + +/* +** We know that pSrc is an operand of an outer join. Return true if +** pTerm is a constraint that is compatible with that join. +** +** pTerm must be EP_OuterON if pSrc is the right operand of an +** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc +** is the left operand of a RIGHT join. +** +** See https://sqlite.org/forum/forumpost/206d99a16dd9212f +** for an example of a WHERE clause constraints that may not be used on +** the right table of a RIGHT JOIN because the constraint implies a +** not-NULL condition on the left table of the RIGHT JOIN. +*/ +static int constraintCompatibleWithOuterJoin( + const WhereTerm *pTerm, /* WHERE clause term to check */ + const SrcItem *pSrc /* Table we are trying to access */ +){ + assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */ + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); + testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) + testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) + || pTerm->pExpr->w.iJoin != pSrc->iCursor + ){ + return 0; + } + if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 + && ExprHasProperty(pTerm->pExpr, EP_InnerON) + ){ + return 0; + } + return 1; +} + + + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return TRUE if the WHERE clause term pTerm is of a form where it +** could be used with an index to access pSrc, assuming an appropriate +** index existed. +*/ +static int termCanDriveIndex( + const WhereTerm *pTerm, /* WHERE clause term to check */ + const SrcItem *pSrc, /* Table we are trying to access */ + const Bitmask notReady /* Tables in outer loops of the join */ +){ + char aff; + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; + if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; + assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ + } + if( (pTerm->prereqRight & notReady)!=0 ) return 0; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + if( pTerm->u.x.leftColumn<0 ) return 0; + aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; + if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; + testcase( pTerm->pExpr->op==TK_IS ); + return 1; +} +#endif + + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Argument pIdx represents an automatic index that the current statement +** will create and populate. Add an OP_Explain with text of the form: +** +** CREATE AUTOMATIC INDEX ON
() [WHERE ] +** +** This is only required if sqlite3_stmt_scanstatus() is enabled, to +** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP +** values with. In order to avoid breaking legacy code and test cases, +** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command. +*/ +static void explainAutomaticIndex( + Parse *pParse, + Index *pIdx, /* Automatic index to explain */ + int bPartial, /* True if pIdx is a partial index */ + int *pAddrExplain /* OUT: Address of OP_Explain */ +){ + if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){ + Table *pTab = pIdx->pTable; + const char *zSep = ""; + char *zText = 0; + int ii = 0; + sqlite3_str *pStr = sqlite3_str_new(pParse->db); + sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName); + assert( pIdx->nColumn>1 ); + assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID ); + for(ii=0; ii<(pIdx->nColumn-1); ii++){ + const char *zName = 0; + int iCol = pIdx->aiColumn[ii]; + + zName = pTab->aCol[iCol].zCnName; + sqlite3_str_appendf(pStr, "%s%s", zSep, zName); + zSep = ", "; + } + zText = sqlite3_str_finish(pStr); + if( zText==0 ){ + sqlite3OomFault(pParse->db); + }else{ + *pAddrExplain = sqlite3VdbeExplain( + pParse, 0, "%s)%s", zText, (bPartial ? " WHERE " : "") + ); + sqlite3_free(zText); + } + } +} +#else +# define explainAutomaticIndex(a,b,c,d) +#endif + +/* +** Generate code to construct the Index object for an automatic index +** and to set up the WhereLevel object pLevel so that the code generator +** makes use of the automatic index. +*/ +static SQLITE_NOINLINE void constructAutomaticIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + const Bitmask notReady, /* Mask of cursors that are not available */ + WhereLevel *pLevel /* Write new index here */ +){ + int nKeyCol; /* Number of columns in the constructed index */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + WhereTerm *pWCEnd; /* End of pWC->a[] */ + Index *pIdx; /* Object describing the transient index */ + Vdbe *v; /* Prepared statement under construction */ + int addrInit; /* Address of the initialization bypass jump */ + Table *pTable; /* The table being indexed */ + int addrTop; /* Top of the index fill loop */ + int regRecord; /* Register holding an index record */ + int n; /* Column counter */ + int i; /* Loop counter */ + int mxBitCol; /* Maximum column in pSrc->colUsed */ + CollSeq *pColl; /* Collating sequence to on a column */ + WhereLoop *pLoop; /* The Loop object */ + char *zNotUsed; /* Extra space on the end of pIdx */ + Bitmask idxCols; /* Bitmap of columns used for indexing */ + Bitmask extraCols; /* Bitmap of additional columns */ + u8 sentWarning = 0; /* True if a warning has been issued */ + u8 useBloomFilter = 0; /* True to also add a Bloom filter */ + Expr *pPartial = 0; /* Partial Index Expression */ + int iContinue = 0; /* Jump here to skip excluded rows */ + SrcList *pTabList; /* The complete FROM clause */ + SrcItem *pSrc; /* The FROM clause term to get the next index */ + int addrCounter = 0; /* Address where integer counter is initialized */ + int regBase; /* Array of registers where record is assembled */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExp = 0; /* Address of OP_Explain */ +#endif + + /* Generate code to skip over the creation and initialization of the + ** transient index on 2nd and subsequent iterations of the loop. */ + v = pParse->pVdbe; + assert( v!=0 ); + addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + + /* Count the number of columns that will be added to the index + ** and used to match WHERE clause constraints */ + nKeyCol = 0; + pTabList = pWC->pWInfo->pTabList; + pSrc = &pTabList->a[pLevel->iFrom]; + pTable = pSrc->pTab; + pWCEnd = &pWC->a[pWC->nTerm]; + pLoop = pLevel->pWLoop; + idxCols = 0; + for(pTerm=pWC->a; pTermpExpr; + /* Make the automatic index a partial index if there are terms in the + ** WHERE clause (or the ON clause of a LEFT join) that constrain which + ** rows of the target table (pSrc) that can be used. */ + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) + ){ + pPartial = sqlite3ExprAnd(pParse, pPartial, + sqlite3ExprDup(pParse->db, pExpr, 0)); + } + if( termCanDriveIndex(pTerm, pSrc, notReady) ){ + int iCol; + Bitmask cMask; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + iCol = pTerm->u.x.leftColumn; + cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + if( !sentWarning ){ + sqlite3_log(SQLITE_WARNING_AUTOINDEX, + "automatic index on %s(%s)", pTable->zName, + pTable->aCol[iCol].zCnName); + sentWarning = 1; + } + if( (idxCols & cMask)==0 ){ + if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){ + goto end_auto_index_create; + } + pLoop->aLTerm[nKeyCol++] = pTerm; + idxCols |= cMask; + } + } + } + assert( nKeyCol>0 || pParse->db->mallocFailed ); + pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol; + pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED + | WHERE_AUTO_INDEX; + + /* Count the number of additional columns needed to create a + ** covering index. A "covering index" is an index that contains all + ** columns that are needed by the query. With a covering index, the + ** original table never needs to be accessed. Automatic indices must + ** be a covering index because the index will not be updated if the + ** original table changes and the index and table cannot both be used + ** if they go out of sync. + */ + if( IsView(pTable) ){ + extraCols = ALLBITS; + }else{ + extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); + } + mxBitCol = MIN(BMS-1,pTable->nCol); + testcase( pTable->nCol==BMS-1 ); + testcase( pTable->nCol==BMS-2 ); + for(i=0; icolUsed & MASKBIT(BMS-1) ){ + nKeyCol += pTable->nCol - BMS + 1; + } + + /* Construct the Index object to describe this index */ + pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed); + if( pIdx==0 ) goto end_auto_index_create; + pLoop->u.btree.pIndex = pIdx; + pIdx->zName = "auto-index"; + pIdx->pTable = pTable; + n = 0; + idxCols = 0; + for(pTerm=pWC->a; pTermeOperator & (WO_OR|WO_AND))==0 ); + iCol = pTerm->u.x.leftColumn; + cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + testcase( iCol==BMS-1 ); + testcase( iCol==BMS ); + if( (idxCols & cMask)==0 ){ + Expr *pX = pTerm->pExpr; + idxCols |= cMask; + pIdx->aiColumn[n] = pTerm->u.x.leftColumn; + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ + pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; + n++; + if( ALWAYS(pX->pLeft!=0) + && sqlite3ExprAffinity(pX->pLeft)!=SQLITE_AFF_TEXT + ){ + /* TUNING: only use a Bloom filter on an automatic index + ** if one or more key columns has the ability to hold numeric + ** values, since strings all have the same hash in the Bloom + ** filter implementation and hence a Bloom filter on a text column + ** is not usually helpful. */ + useBloomFilter = 1; + } + } + } + } + assert( (u32)n==pLoop->u.btree.nEq ); + + /* Add additional columns needed to make the automatic index into + ** a covering index */ + for(i=0; iaiColumn[n] = i; + pIdx->azColl[n] = sqlite3StrBINARY; + n++; + } + } + if( pSrc->colUsed & MASKBIT(BMS-1) ){ + for(i=BMS-1; inCol; i++){ + pIdx->aiColumn[n] = i; + pIdx->azColl[n] = sqlite3StrBINARY; + n++; + } + } + assert( n==nKeyCol ); + pIdx->aiColumn[n] = XN_ROWID; + pIdx->azColl[n] = sqlite3StrBINARY; + + /* Create the automatic index */ + explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp); + assert( pLevel->iIdxCur>=0 ); + pLevel->iIdxCur = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "for %s", pTable->zName)); + if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) && useBloomFilter ){ + sqlite3WhereExplainBloomFilter(pParse, pWC->pWInfo, pLevel); + pLevel->regFilter = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); + } + + /* Fill the automatic index with content */ + assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); + if( pSrc->fg.viaCoroutine ){ + int regYield = pSrc->regReturn; + addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); + VdbeCoverage(v); + VdbeComment((v, "next row of %s", pSrc->pTab->zName)); + }else{ + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); + } + if( pPartial ){ + iContinue = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); + pLoop->wsFlags |= WHERE_PARTIALIDX; + } + regRecord = sqlite3GetTempReg(pParse); + regBase = sqlite3GenerateIndexKey( + pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 + ); + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, + regBase, pLoop->u.btree.nEq); + } + sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); + if( pSrc->fg.viaCoroutine ){ + sqlite3VdbeChangeP2(v, addrCounter, regBase+n); + testcase( pParse->db->mallocFailed ); + assert( pLevel->iIdxCur>0 ); + translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, + pSrc->regResult, pLevel->iIdxCur); + sqlite3VdbeGoto(v, addrTop); + pSrc->fg.viaCoroutine = 0; + }else{ + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); + } + sqlite3VdbeJumpHere(v, addrTop); + sqlite3ReleaseTempReg(pParse, regRecord); + + /* Jump here when skipping the initialization */ + sqlite3VdbeJumpHere(v, addrInit); + sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); + +end_auto_index_create: + sqlite3ExprDelete(pParse->db, pPartial); +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + +/* +** Generate bytecode that will initialize a Bloom filter that is appropriate +** for pLevel. +** +** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER +** flag set, initialize a Bloomfilter for them as well. Except don't do +** this recursive initialization if the SQLITE_BloomPulldown optimization has +** been turned off. +** +** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared +** from the loop, but the regFilter value is set to a register that implements +** the Bloom filter. When regFilter is positive, the +** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter +** and skip the subsequence B-Tree seek if the Bloom filter indicates that +** no matching rows exist. +** +** This routine may only be called if it has previously been determined that +** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit +** is set. +*/ +static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( + WhereInfo *pWInfo, /* The WHERE clause */ + int iLevel, /* Index in pWInfo->a[] that is pLevel */ + WhereLevel *pLevel, /* Make a Bloom filter for this FROM term */ + Bitmask notReady /* Loops that are not ready */ +){ + int addrOnce; /* Address of opening OP_Once */ + int addrTop; /* Address of OP_Rewind */ + int addrCont; /* Jump here to skip a row */ + const WhereTerm *pTerm; /* For looping over WHERE clause terms */ + const WhereTerm *pWCEnd; /* Last WHERE clause term */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ + int iCur; /* Cursor for table getting the filter */ + IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ + IndexedExpr *saved_pIdxPartExpr; /* saved copy of Parse.pIdxPartExpr */ + + saved_pIdxEpr = pParse->pIdxEpr; + saved_pIdxPartExpr = pParse->pIdxPartExpr; + pParse->pIdxEpr = 0; + pParse->pIdxPartExpr = 0; + + assert( pLoop!=0 ); + assert( v!=0 ); + assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ); + + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + do{ + const SrcList *pTabList; + const SrcItem *pItem; + const Table *pTab; + u64 sz; + int iSrc; + sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); + addrCont = sqlite3VdbeMakeLabel(pParse); + iCur = pLevel->iTabCur; + pLevel->regFilter = ++pParse->nMem; + + /* The Bloom filter is a Blob held in a register. Initialize it + ** to zero-filled blob of at least 80K bits, but maybe more if the + ** estimated size of the table is larger. We could actually + ** measure the size of the table at run-time using OP_Count with + ** P3==1 and use that value to initialize the blob. But that makes + ** testing complicated. By basing the blob size on the value in the + ** sqlite_stat1 table, testing is much easier. + */ + pTabList = pWInfo->pTabList; + iSrc = pLevel->iFrom; + pItem = &pTabList->a[iSrc]; + assert( pItem!=0 ); + pTab = pItem->pTab; + assert( pTab!=0 ); + sz = sqlite3LogEstToInt(pTab->nRowLogEst); + if( sz<10000 ){ + sz = 10000; + }else if( sz>10000000 ){ + sz = 10000000; + } + sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter); + + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm]; + for(pTerm=pWInfo->sWC.a; pTermpExpr; + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) + ){ + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + } + } + if( pLoop->wsFlags & WHERE_IPK ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, 1); + sqlite3ReleaseTempReg(pParse, r1); + }else{ + Index *pIdx = pLoop->u.btree.pIndex; + int n = pLoop->u.btree.nEq; + int r1 = sqlite3GetTempRange(pParse, n); + int jj; + for(jj=0; jjpTable==pItem->pTab ); + sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); + } + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); + sqlite3ReleaseTempRange(pParse, r1, n); + } + sqlite3VdbeResolveLabel(v, addrCont); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + pLoop->wsFlags &= ~WHERE_BLOOMFILTER; + if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; + while( ++iLevel < pWInfo->nLevel ){ + const SrcItem *pTabItem; + pLevel = &pWInfo->a[iLevel]; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue; + pLoop = pLevel->pWLoop; + if( NEVER(pLoop==0) ) continue; + if( pLoop->prereq & notReady ) continue; + if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) + ==WHERE_BLOOMFILTER + ){ + /* This is a candidate for bloom-filter pull-down (early evaluation). + ** The test that WHERE_COLUMN_IN is omitted is important, as we are + ** not able to do early evaluation of bloom filters that make use of + ** the IN operator */ + break; + } + } + }while( iLevel < pWInfo->nLevel ); + sqlite3VdbeJumpHere(v, addrOnce); + pParse->pIdxEpr = saved_pIdxEpr; + pParse->pIdxPartExpr = saved_pIdxPartExpr; +} + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Allocate and populate an sqlite3_index_info structure. It is the +** responsibility of the caller to eventually release the structure +** by passing the pointer returned by this function to freeIndexInfo(). +*/ +static sqlite3_index_info *allocateIndexInfo( + WhereInfo *pWInfo, /* The WHERE clause */ + WhereClause *pWC, /* The WHERE clause being analyzed */ + Bitmask mUnusable, /* Ignore terms with these prereqs */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ + u16 *pmNoOmit /* Mask of terms not to omit */ +){ + int i, j; + int nTerm; + Parse *pParse = pWInfo->pParse; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_orderby *pIdxOrderBy; + struct sqlite3_index_constraint_usage *pUsage; + struct HiddenIndexInfo *pHidden; + WhereTerm *pTerm; + int nOrderBy; + sqlite3_index_info *pIdxInfo; + u16 mNoOmit = 0; + const Table *pTab; + int eDistinct = 0; + ExprList *pOrderBy = pWInfo->pOrderBy; + + assert( pSrc!=0 ); + pTab = pSrc->pTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); + + /* Find all WHERE clause constraints referring to this virtual table. + ** Mark each term with the TERM_OK flag. Set nTerm to the number of + ** terms found. + */ + for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->prereqRight & mUnusable ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; + + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumnnCol ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + nTerm++; + pTerm->wtFlags |= TERM_OK; + } + + /* If the ORDER BY clause contains only columns in the current + ** virtual table then allocate space for the aOrderBy part of + ** the sqlite3_index_info structure. + */ + nOrderBy = 0; + if( pOrderBy ){ + int n = pOrderBy->nExpr; + for(i=0; ia[i].pExpr; + Expr *pE2; + + /* Skip over constant terms in the ORDER BY clause */ + if( sqlite3ExprIsConstant(pExpr) ){ + continue; + } + + /* Virtual tables are unable to deal with NULLS FIRST */ + if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break; + + /* First case - a direct column references without a COLLATE operator */ + if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){ + assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumnnCol ); + continue; + } + + /* 2nd case - a column reference with a COLLATE operator. Only match + ** of the COLLATE operator matches the collation of the column. */ + if( pExpr->op==TK_COLLATE + && (pE2 = pExpr->pLeft)->op==TK_COLUMN + && pE2->iTable==pSrc->iCursor + ){ + const char *zColl; /* The collating sequence name */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pE2->iColumn>=XN_ROWID && pE2->iColumnnCol ); + pExpr->iColumn = pE2->iColumn; + if( pE2->iColumn<0 ) continue; /* Collseq does not matter for rowid */ + zColl = sqlite3ColumnColl(&pTab->aCol[pE2->iColumn]); + if( zColl==0 ) zColl = sqlite3StrBINARY; + if( sqlite3_stricmp(pExpr->u.zToken, zColl)==0 ) continue; + } + + /* No matches cause a break out of the loop */ + break; + } + if( i==n ){ + nOrderBy = n; + if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){ + eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); + }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ + eDistinct = 1; + } + } + } + + /* Allocate the sqlite3_index_info structure + */ + pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) + + sizeof(sqlite3_value*)*nTerm ); + if( pIdxInfo==0 ){ + sqlite3ErrorMsg(pParse, "out of memory"); + return 0; + } + pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; + pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; + pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; + pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; + pIdxInfo->aConstraint = pIdxCons; + pIdxInfo->aOrderBy = pIdxOrderBy; + pIdxInfo->aConstraintUsage = pUsage; + pHidden->pWC = pWC; + pHidden->pParse = pParse; + pHidden->eDistinct = eDistinct; + pHidden->mIn = 0; + for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + u16 op; + if( (pTerm->wtFlags & TERM_OK)==0 ) continue; + pIdxCons[j].iColumn = pTerm->u.x.leftColumn; + pIdxCons[j].iTermOffset = i; + op = pTerm->eOperator & WO_ALL; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; + } + if( op==WO_AUX ){ + pIdxCons[j].op = pTerm->eMatchOp; + }else if( op & (WO_ISNULL|WO_IS) ){ + if( op==WO_ISNULL ){ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + }else{ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; + } + }else{ + pIdxCons[j].op = (u8)op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); + + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + testcase( j!=i ); + if( j<16 ) mNoOmit |= (1 << j); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } + } + + j++; + } + assert( j==nTerm ); + pIdxInfo->nConstraint = j; + for(i=j=0; ia[i].pExpr; + if( sqlite3ExprIsConstant(pExpr) ) continue; + assert( pExpr->op==TK_COLUMN + || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN + && pExpr->iColumn==pExpr->pLeft->iColumn) ); + pIdxOrderBy[j].iColumn = pExpr->iColumn; + pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC; + j++; + } + pIdxInfo->nOrderBy = j; + + *pmNoOmit = mNoOmit; + return pIdxInfo; +} + +/* +** Free an sqlite3_index_info structure allocated by allocateIndexInfo() +** and possibly modified by xBestIndex methods. +*/ +static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden; + int i; + assert( pIdxInfo!=0 ); + pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->pParse!=0 ); + assert( pHidden->pParse->db==db ); + for(i=0; inConstraint; i++){ + sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ + pHidden->aRhs[i] = 0; + } + sqlite3DbFree(db, pIdxInfo); +} + +/* +** The table object reference passed as the second argument to this function +** must represent a virtual table. This function invokes the xBestIndex() +** method of the virtual table with the sqlite3_index_info object that +** comes in as the 3rd argument to this function. +** +** If an error occurs, pParse is populated with an error message and an +** appropriate error code is returned. A return of SQLITE_CONSTRAINT from +** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that +** the current configuration of "unusable" flags in sqlite3_index_info can +** not result in a valid plan. +** +** Whether or not an error is returned, it is the responsibility of the +** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates +** that this is required. +*/ +static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ + sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; + int rc; + + whereTraceIndexInfoInputs(p); + pParse->db->nSchemaLock++; + rc = pVtab->pModule->xBestIndex(pVtab, p); + pParse->db->nSchemaLock--; + whereTraceIndexInfoOutputs(p); + + if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(pParse->db); + }else if( !pVtab->zErrMsg ){ + sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); + }else{ + sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); + } + } + if( pTab->u.vtab.p->bAllSchemas ){ + sqlite3VtabUsesAllSchemas(pParse); + } + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; + return rc; +} +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Estimate the location of a particular key among all keys in an +** index. Store the results in aStat as follows: +** +** aStat[0] Est. number of rows less than pRec +** aStat[1] Est. number of rows equal to pRec +** +** Return the index of the sample that is the smallest sample that +** is greater than or equal to pRec. Note that this index is not an index +** into the aSample[] array - it is an index into a virtual set of samples +** based on the contents of aSample[] and the number of fields in record +** pRec. +*/ +static int whereKeyStats( + Parse *pParse, /* Database connection */ + Index *pIdx, /* Index to consider domain of */ + UnpackedRecord *pRec, /* Vector of values to consider */ + int roundUp, /* Round up if true. Round down if false */ + tRowcnt *aStat /* OUT: stats written here */ +){ + IndexSample *aSample = pIdx->aSample; + int iCol; /* Index of required stats in anEq[] etc. */ + int i; /* Index of first sample >= pRec */ + int iSample; /* Smallest sample larger than or equal to pRec */ + int iMin = 0; /* Smallest sample not yet tested */ + int iTest; /* Next sample to test */ + int res; /* Result of comparison operation */ + int nField; /* Number of fields in pRec */ + tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */ + +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER( pParse ); +#endif + assert( pRec!=0 ); + assert( pIdx->nSample>0 ); + assert( pRec->nField>0 ); + + + /* Do a binary search to find the first sample greater than or equal + ** to pRec. If pRec contains a single field, the set of samples to search + ** is simply the aSample[] array. If the samples in aSample[] contain more + ** than one fields, all fields following the first are ignored. + ** + ** If pRec contains N fields, where N is more than one, then as well as the + ** samples in aSample[] (truncated to N fields), the search also has to + ** consider prefixes of those samples. For example, if the set of samples + ** in aSample is: + ** + ** aSample[0] = (a, 5) + ** aSample[1] = (a, 10) + ** aSample[2] = (b, 5) + ** aSample[3] = (c, 100) + ** aSample[4] = (c, 105) + ** + ** Then the search space should ideally be the samples above and the + ** unique prefixes [a], [b] and [c]. But since that is hard to organize, + ** the code actually searches this set: + ** + ** 0: (a) + ** 1: (a, 5) + ** 2: (a, 10) + ** 3: (a, 10) + ** 4: (b) + ** 5: (b, 5) + ** 6: (c) + ** 7: (c, 100) + ** 8: (c, 105) + ** 9: (c, 105) + ** + ** For each sample in the aSample[] array, N samples are present in the + ** effective sample array. In the above, samples 0 and 1 are based on + ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. + ** + ** Often, sample i of each block of N effective samples has (i+1) fields. + ** Except, each sample may be extended to ensure that it is greater than or + ** equal to the previous sample in the array. For example, in the above, + ** sample 2 is the first sample of a block of N samples, so at first it + ** appears that it should be 1 field in size. However, that would make it + ** smaller than sample 1, so the binary search would not work. As a result, + ** it is extended to two fields. The duplicates that this creates do not + ** cause any problems. + */ + if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ + nField = pIdx->nKeyCol; + }else{ + nField = pIdx->nColumn; + } + nField = MIN(pRec->nField, nField); + iCol = 0; + iSample = pIdx->nSample * nField; + do{ + int iSamp; /* Index in aSample[] of test sample */ + int n; /* Number of fields in test sample */ + + iTest = (iMin+iSample)/2; + iSamp = iTest / nField; + if( iSamp>0 ){ + /* The proposed effective sample is a prefix of sample aSample[iSamp]. + ** Specifically, the shortest prefix of at least (1 + iTest%nField) + ** fields that is greater than the previous effective sample. */ + for(n=(iTest % nField) + 1; nnField = n; + res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); + if( res<0 ){ + iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; + iMin = iTest+1; + }else if( res==0 && ndb->mallocFailed==0 ){ + if( res==0 ){ + /* If (res==0) is true, then pRec must be equal to sample i. */ + assert( inSample ); + assert( iCol==nField-1 ); + pRec->nField = nField; + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + || pParse->db->mallocFailed + ); + }else{ + /* Unless i==pIdx->nSample, indicating that pRec is larger than + ** all samples in the aSample[] array, pRec must be smaller than the + ** (iCol+1) field prefix of sample i. */ + assert( i<=pIdx->nSample && i>=0 ); + pRec->nField = iCol+1; + assert( i==pIdx->nSample + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 + || pParse->db->mallocFailed ); + + /* if i==0 and iCol==0, then record pRec is smaller than all samples + ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must + ** be greater than or equal to the (iCol) field prefix of sample i. + ** If (i>0), then pRec must also be greater than sample (i-1). */ + if( iCol>0 ){ + pRec->nField = iCol; + assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 + || pParse->db->mallocFailed || CORRUPT_DB ); + } + if( i>0 ){ + pRec->nField = nField; + assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 + || pParse->db->mallocFailed || CORRUPT_DB ); + } + } + } +#endif /* ifdef SQLITE_DEBUG */ + + if( res==0 ){ + /* Record pRec is equal to sample i */ + assert( iCol==nField-1 ); + aStat[0] = aSample[i].anLt[iCol]; + aStat[1] = aSample[i].anEq[iCol]; + }else{ + /* At this point, the (iCol+1) field prefix of aSample[i] is the first + ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec + ** is larger than all samples in the array. */ + tRowcnt iUpper, iGap; + if( i>=pIdx->nSample ){ + iUpper = pIdx->nRowEst0; + }else{ + iUpper = aSample[i].anLt[iCol]; + } + + if( iLower>=iUpper ){ + iGap = 0; + }else{ + iGap = iUpper - iLower; + } + if( roundUp ){ + iGap = (iGap*2)/3; + }else{ + iGap = iGap/3; + } + aStat[0] = iLower + iGap; + aStat[1] = pIdx->aAvgEq[nField-1]; + } + + /* Restore the pRec->nField value before returning. */ + pRec->nField = nField; + return i; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** If it is not NULL, pTerm is a term that provides an upper or lower +** bound on a range scan. Without considering pTerm, it is estimated +** that the scan will visit nNew rows. This function returns the number +** estimated to be visited after taking pTerm into account. +** +** If the user explicitly specified a likelihood() value for this term, +** then the return value is the likelihood multiplied by the number of +** input rows. Otherwise, this function assumes that an "IS NOT NULL" term +** has a likelihood of 0.50, and any other term a likelihood of 0.25. +*/ +static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ + LogEst nRet = nNew; + if( pTerm ){ + if( pTerm->truthProb<=0 ){ + nRet += pTerm->truthProb; + }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ + nRet -= 20; assert( 20==sqlite3LogEst(4) ); + } + } + return nRet; +} + + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Return the affinity for a single column of an index. +*/ +SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ + assert( iCol>=0 && iColnColumn ); + if( !pIdx->zColAff ){ + if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; + } + assert( pIdx->zColAff[iCol]!=0 ); + return pIdx->zColAff[iCol]; +} +#endif + + +#ifdef SQLITE_ENABLE_STAT4 +/* +** This function is called to estimate the number of rows visited by a +** range-scan on a skip-scan index. For example: +** +** CREATE INDEX i1 ON t1(a, b, c); +** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; +** +** Value pLoop->nOut is currently set to the estimated number of rows +** visited for scanning (a=? AND b=?). This function reduces that estimate +** by some factor to account for the (c BETWEEN ? AND ?) expression based +** on the stat4 data for the index. this scan will be performed multiple +** times (once for each (a,b) combination that matches a=?) is dealt with +** by the caller. +** +** It does this by scanning through all stat4 samples, comparing values +** extracted from pLower and pUpper with the corresponding column in each +** sample. If L and U are the number of samples found to be less than or +** equal to the values extracted from pLower and pUpper respectively, and +** N is the total number of samples, the pLoop->nOut value is adjusted +** as follows: +** +** nOut = nOut * ( min(U - L, 1) / N ) +** +** If pLower is NULL, or a value cannot be extracted from the term, L is +** set to zero. If pUpper is NULL, or a value cannot be extracted from it, +** U is set to N. +** +** Normally, this function sets *pbDone to 1 before returning. However, +** if no value can be extracted from either pLower or pUpper (and so the +** estimate of the number of rows delivered remains unchanged), *pbDone +** is left as is. +** +** If an error occurs, an SQLite error code is returned. Otherwise, +** SQLITE_OK. +*/ +static int whereRangeSkipScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + WhereLoop *pLoop, /* Update the .nOut value of this loop */ + int *pbDone /* Set to true if at least one expr. value extracted */ +){ + Index *p = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; + sqlite3 *db = pParse->db; + int nLower = -1; + int nUpper = p->nSample+1; + int rc = SQLITE_OK; + u8 aff = sqlite3IndexColumnAffinity(db, p, nEq); + CollSeq *pColl; + + sqlite3_value *p1 = 0; /* Value extracted from pLower */ + sqlite3_value *p2 = 0; /* Value extracted from pUpper */ + sqlite3_value *pVal = 0; /* Value extracted from record */ + + pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]); + if( pLower ){ + rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1); + nLower = 0; + } + if( pUpper && rc==SQLITE_OK ){ + rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2); + nUpper = p2 ? 0 : p->nSample; + } + + if( p1 || p2 ){ + int i; + int nDiff; + for(i=0; rc==SQLITE_OK && inSample; i++){ + rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal); + if( rc==SQLITE_OK && p1 ){ + int res = sqlite3MemCompare(p1, pVal, pColl); + if( res>=0 ) nLower++; + } + if( rc==SQLITE_OK && p2 ){ + int res = sqlite3MemCompare(p2, pVal, pColl); + if( res>=0 ) nUpper++; + } + } + nDiff = (nUpper - nLower); + if( nDiff<=0 ) nDiff = 1; + + /* If there is both an upper and lower bound specified, and the + ** comparisons indicate that they are close together, use the fallback + ** method (assume that the scan visits 1/64 of the rows) for estimating + ** the number of rows visited. Otherwise, estimate the number of rows + ** using the method described in the header comment for this function. */ + if( nDiff!=1 || pUpper==0 || pLower==0 ){ + int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); + pLoop->nOut -= nAdjust; + *pbDone = 1; + WHERETRACE(0x20, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", + nLower, nUpper, nAdjust*-1, pLoop->nOut)); + } + + }else{ + assert( *pbDone==0 ); + } + + sqlite3ValueFree(p1); + sqlite3ValueFree(p2); + sqlite3ValueFree(pVal); + + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** This function is used to estimate the number of rows that will be visited +** by scanning an index for a range of values. The range may have an upper +** bound, a lower bound, or both. The WHERE clause terms that set the upper +** and lower bounds are represented by pLower and pUpper respectively. For +** example, assuming that index p is on t1(a): +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** |_____| |_____| +** | | +** pLower pUpper +** +** If either of the upper or lower bound is not present, then NULL is passed in +** place of the corresponding WhereTerm. +** +** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index +** column subject to the range constraint. Or, equivalently, the number of +** equality constraints optimized by the proposed index scan. For example, +** assuming index p is on t1(a, b), and the SQL query is: +** +** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... +** +** then nEq is set to 1 (as the range restricted column, b, is the second +** left-most column of the index). Or, if the query is: +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** +** then nEq is set to 0. +** +** When this function is called, *pnOut is set to the sqlite3LogEst() of the +** number of rows that the index scan is expected to visit without +** considering the range constraints. If nEq is 0, then *pnOut is the number of +** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) +** to account for the range constraints pLower and pUpper. +** +** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be +** used, a single range inequality reduces the search space by a factor of 4. +** and a pair of constraints (x>? AND x123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ +){ + int rc = SQLITE_OK; + int nOut = pLoop->nOut; + LogEst nNew; + +#ifdef SQLITE_ENABLE_STAT4 + Index *p = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; + + if( p->nSample>0 && ALWAYS(nEqnSampleCol) + && OptimizationEnabled(pParse->db, SQLITE_Stat4) + ){ + if( nEq==pBuilder->nRecValid ){ + UnpackedRecord *pRec = pBuilder->pRec; + tRowcnt a[2]; + int nBtm = pLoop->u.btree.nBtm; + int nTop = pLoop->u.btree.nTop; + + /* Variable iLower will be set to the estimate of the number of rows in + ** the index that are less than the lower bound of the range query. The + ** lower bound being the concatenation of $P and $L, where $P is the + ** key-prefix formed by the nEq values matched against the nEq left-most + ** columns of the index, and $L is the value in pLower. + ** + ** Or, if pLower is NULL or $L cannot be extracted from it (because it + ** is not a simple variable or literal value), the lower bound of the + ** range is $P. Due to a quirk in the way whereKeyStats() works, even + ** if $L is available, whereKeyStats() is called for both ($P) and + ** ($P:$L) and the larger of the two returned values is used. + ** + ** Similarly, iUpper is to be set to the estimate of the number of rows + ** less than the upper bound of the range query. Where the upper bound + ** is either ($P) or ($P:$U). Again, even if $U is available, both values + ** of iUpper are requested of whereKeyStats() and the smaller used. + ** + ** The number of rows between the two bounds is then just iUpper-iLower. + */ + tRowcnt iLower; /* Rows less than the lower bound */ + tRowcnt iUpper; /* Rows less than the upper bound */ + int iLwrIdx = -2; /* aSample[] for the lower bound */ + int iUprIdx = -1; /* aSample[] for the upper bound */ + + if( pRec ){ + testcase( pRec->nField!=pBuilder->nRecValid ); + pRec->nField = pBuilder->nRecValid; + } + /* Determine iLower and iUpper using ($P) only. */ + if( nEq==0 ){ + iLower = 0; + iUpper = p->nRowEst0; + }else{ + /* Note: this call could be optimized away - since the same values must + ** have been requested when testing key $P in whereEqualScanEst(). */ + whereKeyStats(pParse, p, pRec, 0, a); + iLower = a[0]; + iUpper = a[0] + a[1]; + } + + assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 ); + assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); + assert( p->aSortOrder!=0 ); + if( p->aSortOrder[nEq] ){ + /* The roles of pLower and pUpper are swapped for a DESC index */ + SWAP(WhereTerm*, pLower, pUpper); + SWAP(int, nBtm, nTop); + } + + /* If possible, improve on the iLower estimate using ($P:$L). */ + if( pLower ){ + int n; /* Values extracted from pExpr */ + Expr *pExpr = pLower->pExpr->pRight; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n); + if( rc==SQLITE_OK && n ){ + tRowcnt iNew; + u16 mask = WO_GT|WO_LE; + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); + iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a); + iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0); + if( iNew>iLower ) iLower = iNew; + nOut--; + pLower = 0; + } + } + + /* If possible, improve on the iUpper estimate using ($P:$U). */ + if( pUpper ){ + int n; /* Values extracted from pExpr */ + Expr *pExpr = pUpper->pExpr->pRight; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n); + if( rc==SQLITE_OK && n ){ + tRowcnt iNew; + u16 mask = WO_GT|WO_LE; + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); + iUprIdx = whereKeyStats(pParse, p, pRec, 1, a); + iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0); + if( iNewpRec = pRec; + if( rc==SQLITE_OK ){ + if( iUpper>iLower ){ + nNew = sqlite3LogEst(iUpper - iLower); + /* TUNING: If both iUpper and iLower are derived from the same + ** sample, then assume they are 4x more selective. This brings + ** the estimated selectivity more in line with what it would be + ** if estimated without the use of STAT4 tables. */ + if( iLwrIdx==iUprIdx ){ nNew -= 20; } + assert( 20==sqlite3LogEst(4) ); + }else{ + nNew = 10; assert( 10==sqlite3LogEst(2) ); + } + if( nNewwtFlags & TERM_VNULL)==0 || pParse->nErr>0 ); + nNew = whereRangeAdjust(pLower, nOut); + nNew = whereRangeAdjust(pUpper, nNew); + + /* TUNING: If there is both an upper and lower limit and neither limit + ** has an application-defined likelihood(), assume the range is + ** reduced by an additional 75%. This means that, by default, an open-ended + ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the + ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to + ** match 1/64 of the index. */ + if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){ + nNew -= 20; + } + + nOut -= (pLower!=0) + (pUpper!=0); + if( nNew<10 ) nNew = 10; + if( nNewnOut>nOut ){ + WHERETRACE(0x20,("Range scan lowers nOut from %d to %d\n", + pLoop->nOut, nOut)); + } +#endif + pLoop->nOut = (LogEst)nOut; + return rc; +} + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Estimate the number of rows that will be returned based on +** an equality constraint x=VALUE and where that VALUE occurs in +** the histogram data. This only works when x is the left-most +** column of an index and sqlite_stat4 histogram data is available +** for that index. When pExpr==NULL that means the constraint is +** "x IS NULL" instead of "x=VALUE". +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereEqualScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereLoopBuilder *pBuilder, + Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ + tRowcnt *pnRow /* Write the revised row estimate here */ +){ + Index *p = pBuilder->pNew->u.btree.pIndex; + int nEq = pBuilder->pNew->u.btree.nEq; + UnpackedRecord *pRec = pBuilder->pRec; + int rc; /* Subfunction return code */ + tRowcnt a[2]; /* Statistics */ + int bOk; + + assert( nEq>=1 ); + assert( nEq<=p->nColumn ); + assert( p->aSample!=0 ); + assert( p->nSample>0 ); + assert( pBuilder->nRecValidnRecValid<(nEq-1) ){ + return SQLITE_NOTFOUND; + } + + /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() + ** below would return the same value. */ + if( nEq>=p->nColumn ){ + *pnRow = 1; + return SQLITE_OK; + } + + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk); + pBuilder->pRec = pRec; + if( rc!=SQLITE_OK ) return rc; + if( bOk==0 ) return SQLITE_NOTFOUND; + pBuilder->nRecValid = nEq; + + whereKeyStats(pParse, p, pRec, 0, a); + WHERETRACE(0x20,("equality scan regions %s(%d): %d\n", + p->zName, nEq-1, (int)a[1])); + *pnRow = a[1]; + + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Estimate the number of rows that will be returned based on +** an IN constraint where the right-hand side of the IN operator +** is a list of values. Example: +** +** WHERE x IN (1,2,3,4) +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereInScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereLoopBuilder *pBuilder, + ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ + tRowcnt *pnRow /* Write the revised row estimate here */ +){ + Index *p = pBuilder->pNew->u.btree.pIndex; + i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); + int nRecValid = pBuilder->nRecValid; + int rc = SQLITE_OK; /* Subfunction return code */ + tRowcnt nEst; /* Number of rows for a single term */ + tRowcnt nRowEst = 0; /* New estimate of the number of rows */ + int i; /* Loop counter */ + + assert( p->aSample!=0 ); + for(i=0; rc==SQLITE_OK && inExpr; i++){ + nEst = nRow0; + rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); + nRowEst += nEst; + pBuilder->nRecValid = nRecValid; + } + + if( rc==SQLITE_OK ){ + if( nRowEst > (tRowcnt)nRow0 ) nRowEst = nRow0; + *pnRow = nRowEst; + WHERETRACE(0x20,("IN row estimate: est=%d\n", nRowEst)); + } + assert( pBuilder->nRecValid==nRecValid ); + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + + +#ifdef WHERETRACE_ENABLED +/* +** Print the content of a WhereTerm object +*/ +SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ + if( pTerm==0 ){ + sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); + }else{ + char zType[8]; + char zLeft[50]; + memcpy(zType, "....", 5); + if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; + if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; + if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) zType[2] = 'L'; + if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; + if( pTerm->eOperator & WO_SINGLE ){ + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", + pTerm->leftCursor, pTerm->u.x.leftColumn); + }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", + pTerm->u.pOrInfo->indexable); + }else{ + sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); + } + sqlite3DebugPrintf( + "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", + iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); + /* The 0x10000 .wheretrace flag causes extra information to be + ** shown about each Term */ + if( sqlite3WhereTrace & 0x10000 ){ + sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", + pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); + } + if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){ + sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField); + } + if( pTerm->iParent>=0 ){ + sqlite3DebugPrintf(" iParent=%d", pTerm->iParent); + } + sqlite3DebugPrintf("\n"); + sqlite3TreeViewExpr(0, pTerm->pExpr, 0); + } +} +#endif + +#ifdef WHERETRACE_ENABLED +/* +** Show the complete content of a WhereClause +*/ +SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ + int i; + for(i=0; inTerm; i++){ + sqlite3WhereTermPrint(&pWC->a[i], i); + } +} +#endif + +#ifdef WHERETRACE_ENABLED +/* +** Print a WhereLoop object for debugging purposes +** +** Format example: +** +** .--- Position in WHERE clause rSetup, rRun, nOut ---. +** | | +** | .--- selfMask nTerm ------. | +** | | | | +** | | .-- prereq Idx wsFlags----. | | +** | | | Name | | | +** | | | __|__ nEq ---. ___|__ | __|__ +** | / \ / \ / \ | / \ / \ / \ +** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 +*/ +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ + if( pWC ){ + WhereInfo *pWInfo = pWC->pWInfo; + int nb = 1+(pWInfo->pTabList->nSrc+3)/4; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; + Table *pTab = pItem->pTab; + Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); + sqlite3DebugPrintf(" %12s", + pItem->zAlias ? pItem->zAlias : pTab->zName); + }else{ + sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", + p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab); + } + if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + const char *zName; + if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ + if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ + int i = sqlite3Strlen30(zName) - 1; + while( zName[i]!='_' ) i--; + zName += i; + } + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); + }else{ + sqlite3DebugPrintf("%20s",""); + } + }else{ + char *z; + if( p->u.vtab.idxStr ){ + z = sqlite3_mprintf("(%d,\"%s\",%#x)", + p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); + }else{ + z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); + } + sqlite3DebugPrintf(" %-19s", z); + sqlite3_free(z); + } + if( p->wsFlags & WHERE_SKIPSCAN ){ + sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); + }else{ + sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); + } + sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); + if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){ + int i; + for(i=0; inLTerm; i++){ + sqlite3WhereTermPrint(p->aLTerm[i], i); + } + } +} +SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){ + if( p ) sqlite3WhereLoopPrint(p, 0); +} +SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){ + while( p ){ + sqlite3ShowWhereLoop(p); + p = p->pNextLoop; + } +} +#endif + +/* +** Convert bulk memory into a valid WhereLoop that can be passed +** to whereLoopClear harmlessly. +*/ +static void whereLoopInit(WhereLoop *p){ + p->aLTerm = p->aLTermSpace; + p->nLTerm = 0; + p->nLSlot = ArraySize(p->aLTermSpace); + p->wsFlags = 0; +} + +/* +** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. +*/ +static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ + if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ + if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ + sqlite3_free(p->u.vtab.idxStr); + p->u.vtab.needFree = 0; + p->u.vtab.idxStr = 0; + }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ + sqlite3DbFree(db, p->u.btree.pIndex->zColAff); + sqlite3DbFreeNN(db, p->u.btree.pIndex); + p->u.btree.pIndex = 0; + } + } +} + +/* +** Deallocate internal memory used by a WhereLoop object. Leave the +** object in an initialized state, as if it had been newly allocated. +*/ +static void whereLoopClear(sqlite3 *db, WhereLoop *p){ + if( p->aLTerm!=p->aLTermSpace ){ + sqlite3DbFreeNN(db, p->aLTerm); + p->aLTerm = p->aLTermSpace; + p->nLSlot = ArraySize(p->aLTermSpace); + } + whereLoopClearUnion(db, p); + p->nLTerm = 0; + p->wsFlags = 0; +} + +/* +** Increase the memory allocation for pLoop->aLTerm[] to be at least n. +*/ +static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ + WhereTerm **paNew; + if( p->nLSlot>=n ) return SQLITE_OK; + n = (n+7)&~7; + paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); + if( paNew==0 ) return SQLITE_NOMEM_BKPT; + memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); + p->aLTerm = paNew; + p->nLSlot = n; + return SQLITE_OK; +} + +/* +** Transfer content from the second pLoop into the first. +*/ +static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ + whereLoopClearUnion(db, pTo); + if( pFrom->nLTerm > pTo->nLSlot + && whereLoopResize(db, pTo, pFrom->nLTerm) + ){ + memset(pTo, 0, WHERE_LOOP_XFER_SZ); + return SQLITE_NOMEM_BKPT; + } + memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); + memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); + if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ + pFrom->u.vtab.needFree = 0; + }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ + pFrom->u.btree.pIndex = 0; + } + return SQLITE_OK; +} + +/* +** Delete a WhereLoop object +*/ +static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ + assert( db!=0 ); + whereLoopClear(db, p); + sqlite3DbNNFreeNN(db, p); +} + +/* +** Free a WhereInfo structure +*/ +static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ + assert( pWInfo!=0 ); + assert( db!=0 ); + sqlite3WhereClauseClear(&pWInfo->sWC); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + while( pWInfo->pMemToFree ){ + WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; + sqlite3DbNNFreeNN(db, pWInfo->pMemToFree); + pWInfo->pMemToFree = pNext; + } + sqlite3DbNNFreeNN(db, pWInfo); +} + +/* +** Return TRUE if X is a proper subset of Y but is of equal or less cost. +** In other words, return true if all constraints of X are also part of Y +** and Y has additional constraints that might speed the search that X lacks +** but the cost of running X is not more than the cost of running Y. +** +** In other words, return true if the cost relationwship between X and Y +** is inverted and needs to be adjusted. +** +** Case 1: +** +** (1a) X and Y use the same index. +** (1b) X has fewer == terms than Y +** (1c) Neither X nor Y use skip-scan +** (1d) X does not have a a greater cost than Y +** +** Case 2: +** +** (2a) X has the same or lower cost, or returns the same or fewer rows, +** than Y. +** (2b) X uses fewer WHERE clause terms than Y +** (2c) Every WHERE clause term used by X is also used by Y +** (2d) X skips at least as many columns as Y +** (2e) If X is a covering index, than Y is too +*/ +static int whereLoopCheaperProperSubset( + const WhereLoop *pX, /* First WhereLoop to compare */ + const WhereLoop *pY /* Compare against this WhereLoop */ +){ + int i, j; + if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */ + assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 ); + if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */ + && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */ + && pX->nSkip==0 && pY->nSkip==0 /* (1c) */ + ){ + return 1; /* Case 1 is true */ + } + if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ + return 0; /* (2b) */ + } + if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */ + for(i=pX->nLTerm-1; i>=0; i--){ + if( pX->aLTerm[i]==0 ) continue; + for(j=pY->nLTerm-1; j>=0; j--){ + if( pY->aLTerm[j]==pX->aLTerm[i] ) break; + } + if( j<0 ) return 0; /* (2c) */ + } + if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 + && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ + return 0; /* (2e) */ + } + return 1; /* Case 2 is true */ +} + +/* +** Try to adjust the cost and number of output rows of WhereLoop pTemplate +** upwards or downwards so that: +** +** (1) pTemplate costs less than any other WhereLoops that are a proper +** subset of pTemplate +** +** (2) pTemplate costs more than any other WhereLoops for which pTemplate +** is a proper subset. +** +** To say "WhereLoop X is a proper subset of Y" means that X uses fewer +** WHERE clause terms than Y and that every WHERE clause term used by X is +** also used by Y. +*/ +static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ + if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; + for(; p; p=p->pNextLoop){ + if( p->iTab!=pTemplate->iTab ) continue; + if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; + if( whereLoopCheaperProperSubset(p, pTemplate) ){ + /* Adjust pTemplate cost downward so that it is cheaper than its + ** subset p. */ + WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", + pTemplate->rRun, pTemplate->nOut, + MIN(p->rRun, pTemplate->rRun), + MIN(p->nOut - 1, pTemplate->nOut))); + pTemplate->rRun = MIN(p->rRun, pTemplate->rRun); + pTemplate->nOut = MIN(p->nOut - 1, pTemplate->nOut); + }else if( whereLoopCheaperProperSubset(pTemplate, p) ){ + /* Adjust pTemplate cost upward so that it is costlier than p since + ** pTemplate is a proper subset of p */ + WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", + pTemplate->rRun, pTemplate->nOut, + MAX(p->rRun, pTemplate->rRun), + MAX(p->nOut + 1, pTemplate->nOut))); + pTemplate->rRun = MAX(p->rRun, pTemplate->rRun); + pTemplate->nOut = MAX(p->nOut + 1, pTemplate->nOut); + } + } +} + +/* +** Search the list of WhereLoops in *ppPrev looking for one that can be +** replaced by pTemplate. +** +** Return NULL if pTemplate does not belong on the WhereLoop list. +** In other words if pTemplate ought to be dropped from further consideration. +** +** If pX is a WhereLoop that pTemplate can replace, then return the +** link that points to pX. +** +** If pTemplate cannot replace any existing element of the list but needs +** to be added to the list as a new entry, then return a pointer to the +** tail of the list. +*/ +static WhereLoop **whereLoopFindLesser( + WhereLoop **ppPrev, + const WhereLoop *pTemplate +){ + WhereLoop *p; + for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){ + if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ + /* If either the iTab or iSortIdx values for two WhereLoop are different + ** then those WhereLoops need to be considered separately. Neither is + ** a candidate to replace the other. */ + continue; + } + /* In the current implementation, the rSetup value is either zero + ** or the cost of building an automatic index (NlogN) and the NlogN + ** is the same for compatible WhereLoops. */ + assert( p->rSetup==0 || pTemplate->rSetup==0 + || p->rSetup==pTemplate->rSetup ); + + /* whereLoopAddBtree() always generates and inserts the automatic index + ** case first. Hence compatible candidate WhereLoops never have a larger + ** rSetup. Call this SETUP-INVARIANT */ + assert( p->rSetup>=pTemplate->rSetup ); + + /* Any loop using an application-defined index (or PRIMARY KEY or + ** UNIQUE constraint) with one or more == constraints is better + ** than an automatic index. Unless it is a skip-scan. */ + if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 + && (pTemplate->nSkip)==0 + && (pTemplate->wsFlags & WHERE_INDEXED)!=0 + && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0 + && (p->prereq & pTemplate->prereq)==pTemplate->prereq + ){ + break; + } + + /* If existing WhereLoop p is better than pTemplate, pTemplate can be + ** discarded. WhereLoop p is better if: + ** (1) p has no more dependencies than pTemplate, and + ** (2) p has an equal or lower cost than pTemplate + */ + if( (p->prereq & pTemplate->prereq)==p->prereq /* (1) */ + && p->rSetup<=pTemplate->rSetup /* (2a) */ + && p->rRun<=pTemplate->rRun /* (2b) */ + && p->nOut<=pTemplate->nOut /* (2c) */ + ){ + return 0; /* Discard pTemplate */ + } + + /* If pTemplate is always better than p, then cause p to be overwritten + ** with pTemplate. pTemplate is better than p if: + ** (1) pTemplate has no more dependencies than p, and + ** (2) pTemplate has an equal or lower cost than p. + */ + if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ + && p->rRun>=pTemplate->rRun /* (2a) */ + && p->nOut>=pTemplate->nOut /* (2b) */ + ){ + assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ + break; /* Cause p to be overwritten by pTemplate */ + } + } + return ppPrev; +} + +/* +** Insert or replace a WhereLoop entry using the template supplied. +** +** An existing WhereLoop entry might be overwritten if the new template +** is better and has fewer dependencies. Or the template will be ignored +** and no insert will occur if an existing WhereLoop is faster and has +** fewer dependencies than the template. Otherwise a new WhereLoop is +** added based on the template. +** +** If pBuilder->pOrSet is not NULL then we care about only the +** prerequisites and rRun and nOut costs of the N best loops. That +** information is gathered in the pBuilder->pOrSet object. This special +** processing mode is used only for OR clause processing. +** +** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we +** still might overwrite similar loops with the new template if the +** new template is better. Loops may be overwritten if the following +** conditions are met: +** +** (1) They have the same iTab. +** (2) They have the same iSortIdx. +** (3) The template has same or fewer dependencies than the current loop +** (4) The template has the same or lower cost than the current loop +*/ +static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ + WhereLoop **ppPrev, *p; + WhereInfo *pWInfo = pBuilder->pWInfo; + sqlite3 *db = pWInfo->pParse->db; + int rc; + + /* Stop the search once we hit the query planner search limit */ + if( pBuilder->iPlanLimit==0 ){ + WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n")); + if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0; + return SQLITE_DONE; + } + pBuilder->iPlanLimit--; + + whereLoopAdjustCost(pWInfo->pLoops, pTemplate); + + /* If pBuilder->pOrSet is defined, then only keep track of the costs + ** and prereqs. + */ + if( pBuilder->pOrSet!=0 ){ + if( pTemplate->nLTerm ){ +#if WHERETRACE_ENABLED + u16 n = pBuilder->pOrSet->n; + int x = +#endif + whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun, + pTemplate->nOut); +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + } + return SQLITE_OK; + } + + /* Look for an existing WhereLoop to replace with pTemplate + */ + ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate); + + if( ppPrev==0 ){ + /* There already exists a WhereLoop on the list that is better + ** than pTemplate, so just ignore pTemplate */ +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" skip: "); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + return SQLITE_OK; + }else{ + p = *ppPrev; + } + + /* If we reach this point it means that either p[] should be overwritten + ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new + ** WhereLoop and insert it. + */ +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + if( p!=0 ){ + sqlite3DebugPrintf("replace: "); + sqlite3WhereLoopPrint(p, pBuilder->pWC); + sqlite3DebugPrintf(" with: "); + }else{ + sqlite3DebugPrintf(" add: "); + } + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + if( p==0 ){ + /* Allocate a new WhereLoop to add to the end of the list */ + *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + whereLoopInit(p); + p->pNextLoop = 0; + }else{ + /* We will be overwriting WhereLoop p[]. But before we do, first + ** go through the rest of the list and delete any other entries besides + ** p[] that are also supplanted by pTemplate */ + WhereLoop **ppTail = &p->pNextLoop; + WhereLoop *pToDel; + while( *ppTail ){ + ppTail = whereLoopFindLesser(ppTail, pTemplate); + if( ppTail==0 ) break; + pToDel = *ppTail; + if( pToDel==0 ) break; + *ppTail = pToDel->pNextLoop; +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" delete: "); + sqlite3WhereLoopPrint(pToDel, pBuilder->pWC); + } +#endif + whereLoopDelete(db, pToDel); + } + } + rc = whereLoopXfer(db, p, pTemplate); + if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + Index *pIndex = p->u.btree.pIndex; + if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){ + p->u.btree.pIndex = 0; + } + } + return rc; +} + +/* +** Adjust the WhereLoop.nOut value downward to account for terms of the +** WHERE clause that reference the loop but which are not used by an +** index. +* +** For every WHERE clause term that is not used by the index +** and which has a truth probability assigned by one of the likelihood(), +** likely(), or unlikely() SQL functions, reduce the estimated number +** of output rows by the probability specified. +** +** TUNING: For every WHERE clause term that is not used by the index +** and which does not have an assigned truth probability, heuristics +** described below are used to try to estimate the truth probability. +** TODO --> Perhaps this is something that could be improved by better +** table statistics. +** +** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75% +** value corresponds to -1 in LogEst notation, so this means decrement +** the WhereLoop.nOut field for every such WHERE clause term. +** +** Heuristic 2: If there exists one or more WHERE clause terms of the +** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the +** final output row estimate is no greater than 1/4 of the total number +** of rows in the table. In other words, assume that x==EXPR will filter +** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the +** "x" column is boolean or else -1 or 0 or 1 is a common default value +** on the "x" column and so in that case only cap the output row estimate +** at 1/2 instead of 1/4. +*/ +static void whereLoopOutputAdjust( + WhereClause *pWC, /* The WHERE clause */ + WhereLoop *pLoop, /* The loop to adjust downward */ + LogEst nRow /* Number of rows in the entire table */ +){ + WhereTerm *pTerm, *pX; + Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); + int i, j; + LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ + + assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); + for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ + assert( pTerm!=0 ); + if( (pTerm->prereqAll & notAllowed)!=0 ) continue; + if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; + if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue; + for(j=pLoop->nLTerm-1; j>=0; j--){ + pX = pLoop->aLTerm[j]; + if( pX==0 ) continue; + if( pX==pTerm ) break; + if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; + } + if( j<0 ){ + sqlite3ProgressCheck(pWC->pWInfo->pParse); + if( pLoop->maskSelf==pTerm->prereqAll ){ + /* If there are extra terms in the WHERE clause not used by an index + ** that depend only on the table being scanned, and that will tend to + ** cause many rows to be omitted, then mark that table as + ** "self-culling". + ** + ** 2022-03-24: Self-culling only applies if either the extra terms + ** are straight comparison operators that are non-true with NULL + ** operand, or if the loop is not an OUTER JOIN. + */ + if( (pTerm->eOperator & 0x3f)!=0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype + & (JT_LEFT|JT_LTORJ))==0 + ){ + pLoop->wsFlags |= WHERE_SELFCULL; + } + } + if( pTerm->truthProb<=0 ){ + /* If a truth probability is specified using the likelihood() hints, + ** then use the probability provided by the application. */ + pLoop->nOut += pTerm->truthProb; + }else{ + /* In the absence of explicit truth probabilities, use heuristics to + ** guess a reasonable truth probability. */ + pLoop->nOut--; + if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 + && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ + ){ + Expr *pRight = pTerm->pExpr->pRight; + int k = 0; + testcase( pTerm->pExpr->op==TK_IS ); + if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + k = 10; + }else{ + k = 20; + } + if( iReducewtFlags |= TERM_HEURTRUTH; + iReduce = k; + } + } + } + } + } + if( pLoop->nOut > nRow-iReduce ){ + pLoop->nOut = nRow - iReduce; + } +} + +/* +** Term pTerm is a vector range comparison operation. The first comparison +** in the vector can be optimized using column nEq of the index. This +** function returns the total number of vector elements that can be used +** as part of the range comparison. +** +** For example, if the query is: +** +** WHERE a = ? AND (b, c, d) > (?, ?, ?) +** +** and the index: +** +** CREATE INDEX ... ON (a, b, c, d, e) +** +** then this function would be invoked with nEq=1. The value returned in +** this case is 3. +*/ +static int whereRangeVectorLen( + Parse *pParse, /* Parsing context */ + int iCur, /* Cursor open on pIdx */ + Index *pIdx, /* The index to be used for a inequality constraint */ + int nEq, /* Number of prior equality constraints on same index */ + WhereTerm *pTerm /* The vector inequality constraint */ +){ + int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft); + int i; + + nCmp = MIN(nCmp, (pIdx->nColumn - nEq)); + for(i=1; ipExpr->pLeft) ); + pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr; + pRhs = pTerm->pExpr->pRight; + if( ExprUseXSelect(pRhs) ){ + pRhs = pRhs->x.pSelect->pEList->a[i].pExpr; + }else{ + pRhs = pRhs->x.pList->a[i].pExpr; + } + + /* Check that the LHS of the comparison is a column reference to + ** the right column of the right source table. And that the sort + ** order of the index column is the same as the sort order of the + ** leftmost index column. */ + if( pLhs->op!=TK_COLUMN + || pLhs->iTable!=iCur + || pLhs->iColumn!=pIdx->aiColumn[i+nEq] + || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq] + ){ + break; + } + + testcase( pLhs->iColumn==XN_ROWID ); + aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); + idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); + if( aff!=idxaff ) break; + + pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + if( pColl==0 ) break; + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; + } + return i; +} + +/* +** Adjust the cost C by the costMult factor T. This only occurs if +** compiled with -DSQLITE_ENABLE_COSTMULT +*/ +#ifdef SQLITE_ENABLE_COSTMULT +# define ApplyCostMultiplier(C,T) C += T +#else +# define ApplyCostMultiplier(C,T) +#endif + +/* +** We have so far matched pBuilder->pNew->u.btree.nEq terms of the +** index pIndex. Try to match one more. +** +** When this function is called, pBuilder->pNew->nOut contains the +** number of rows expected to be visited by filtering using the nEq +** terms only. If it is modified, this value is restored before this +** function returns. +** +** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is +** a fake index used for the INTEGER PRIMARY KEY. +*/ +static int whereLoopAddBtreeIndex( + WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ + SrcItem *pSrc, /* FROM clause term being analyzed */ + Index *pProbe, /* An index on pSrc */ + LogEst nInMul /* log(Number of iterations due to IN) */ +){ + WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyze context */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + sqlite3 *db = pParse->db; /* Database connection malloc context */ + WhereLoop *pNew; /* Template WhereLoop under construction */ + WhereTerm *pTerm; /* A WhereTerm under consideration */ + int opMask; /* Valid operators for constraints */ + WhereScan scan; /* Iterator for WHERE terms */ + Bitmask saved_prereq; /* Original value of pNew->prereq */ + u16 saved_nLTerm; /* Original value of pNew->nLTerm */ + u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ + u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */ + u16 saved_nTop; /* Original value of pNew->u.btree.nTop */ + u16 saved_nSkip; /* Original value of pNew->nSkip */ + u32 saved_wsFlags; /* Original value of pNew->wsFlags */ + LogEst saved_nOut; /* Original value of pNew->nOut */ + int rc = SQLITE_OK; /* Return code */ + LogEst rSize; /* Number of rows in the table */ + LogEst rLogSize; /* Logarithm of table size */ + WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ + + pNew = pBuilder->pNew; + assert( db->mallocFailed==0 || pParse->nErr>0 ); + if( pParse->nErr ){ + return pParse->rc; + } + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", + pProbe->pTable->zName,pProbe->zName, + pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); + + assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); + if( pNew->wsFlags & WHERE_BTM_LIMIT ){ + opMask = WO_LT|WO_LE; + }else{ + assert( pNew->u.btree.nBtm==0 ); + opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; + } + if( pProbe->bUnordered || pProbe->bLowQual ){ + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bLowQual ) opMask &= ~(WO_EQ|WO_IN|WO_IS); + } + + assert( pNew->u.btree.nEqnColumn ); + assert( pNew->u.btree.nEqnKeyCol + || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY ); + + saved_nEq = pNew->u.btree.nEq; + saved_nBtm = pNew->u.btree.nBtm; + saved_nTop = pNew->u.btree.nTop; + saved_nSkip = pNew->nSkip; + saved_nLTerm = pNew->nLTerm; + saved_wsFlags = pNew->wsFlags; + saved_prereq = pNew->prereq; + saved_nOut = pNew->nOut; + pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq, + opMask, pProbe); + pNew->rSetup = 0; + rSize = pProbe->aiRowLogEst[0]; + rLogSize = estLog(rSize); + for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ + u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ + LogEst rCostIdx; + LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ + int nIn = 0; +#ifdef SQLITE_ENABLE_STAT4 + int nRecValid = pBuilder->nRecValid; +#endif + if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) + && indexColumnNotNull(pProbe, saved_nEq) + ){ + continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ + } + if( pTerm->prereqRight & pNew->maskSelf ) continue; + + /* Do not allow the upper bound of a LIKE optimization range constraint + ** to mix with a lower range bound from some other source */ + if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; + + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ + pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; + }else{ + pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED; + } + pNew->wsFlags = saved_wsFlags; + pNew->u.btree.nEq = saved_nEq; + pNew->u.btree.nBtm = saved_nBtm; + pNew->u.btree.nTop = saved_nTop; + pNew->nLTerm = saved_nLTerm; + if( pNew->nLTerm>=pNew->nLSlot + && whereLoopResize(db, pNew, pNew->nLTerm+1) + ){ + break; /* OOM while trying to enlarge the pNew->aLTerm array */ + } + pNew->aLTerm[pNew->nLTerm++] = pTerm; + pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; + + assert( nInMul==0 + || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 + || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 + || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 + ); + + if( eOp & WO_IN ){ + Expr *pExpr = pTerm->pExpr; + if( ExprUseXSelect(pExpr) ){ + /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ + int i; + nIn = 46; assert( 46==sqlite3LogEst(25) ); + + /* The expression may actually be of the form (x, y) IN (SELECT...). + ** In this case there is a separate term for each of (x) and (y). + ** However, the nIn multiplier should only be applied once, not once + ** for each such term. The following loop checks that pTerm is the + ** first such term in use, and sets nIn back to 0 if it is not. */ + for(i=0; inLTerm-1; i++){ + if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; + } + }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ + /* "x IN (value, value, ...)" */ + nIn = sqlite3LogEst(pExpr->x.pList->nExpr); + } + if( pProbe->hasStat1 && rLogSize>=10 ){ + LogEst M, logK, x; + /* Let: + ** N = the total number of rows in the table + ** K = the number of entries on the RHS of the IN operator + ** M = the number of rows in the table that match terms to the + ** to the left in the same index. If the IN operator is on + ** the left-most index column, M==N. + ** + ** Given the definitions above, it is better to omit the IN operator + ** from the index lookup and instead do a scan of the M elements, + ** testing each scanned row against the IN operator separately, if: + ** + ** M*log(K) < K*log(N) + ** + ** Our estimates for M, K, and N might be inaccurate, so we build in + ** a safety margin of 2 (LogEst: 10) that favors using the IN operator + ** with the index, as using an index has better worst-case behavior. + ** If we do not have real sqlite_stat1 data, always prefer to use + ** the index. Do not bother with this optimization on very small + ** tables (less than 2 rows) as it is pointless in that case. + */ + M = pProbe->aiRowLogEst[saved_nEq]; + logK = estLog(nIn); + /* TUNING v----- 10 to bias toward indexed IN */ + x = M + logK + 10 - (nIn + rLogSize); + if( x>=0 ){ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d) " + "prefers indexed lookup\n", + saved_nEq, M, logK, nIn, rLogSize, x)); + }else if( nInMul<2 && OptimizationEnabled(db, SQLITE_SeekScan) ){ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d" + " nInMul=%d) prefers skip-scan\n", + saved_nEq, M, logK, nIn, rLogSize, x, nInMul)); + pNew->wsFlags |= WHERE_IN_SEEKSCAN; + }else{ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d" + " nInMul=%d) prefers normal scan\n", + saved_nEq, M, logK, nIn, rLogSize, x, nInMul)); + continue; + } + } + pNew->wsFlags |= WHERE_COLUMN_IN; + }else if( eOp & (WO_EQ|WO_IS) ){ + int iCol = pProbe->aiColumn[saved_nEq]; + pNew->wsFlags |= WHERE_COLUMN_EQ; + assert( saved_nEq==pNew->u.btree.nEq ); + if( iCol==XN_ROWID + || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) + ){ + if( iCol==XN_ROWID || pProbe->uniqNotNull + || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + ){ + pNew->wsFlags |= WHERE_ONEROW; + }else{ + pNew->wsFlags |= WHERE_UNQ_WANTED; + } + } + if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; + }else if( eOp & WO_ISNULL ){ + pNew->wsFlags |= WHERE_COLUMN_NULL; + }else{ + int nVecLen = whereRangeVectorLen( + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm + ); + if( eOp & (WO_GT|WO_GE) ){ + testcase( eOp & WO_GT ); + testcase( eOp & WO_GE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; + pNew->u.btree.nBtm = nVecLen; + pBtm = pTerm; + pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Range constraints that come from the LIKE optimization are + ** always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + pNew->u.btree.nTop = 1; + } + }else{ + assert( eOp & (WO_LT|WO_LE) ); + testcase( eOp & WO_LT ); + testcase( eOp & WO_LE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; + pNew->u.btree.nTop = nVecLen; + pTop = pTerm; + pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? + pNew->aLTerm[pNew->nLTerm-2] : 0; + } + } + + /* At this point pNew->nOut is set to the number of rows expected to + ** be visited by the index scan before considering term pTerm, or the + ** values of nIn and nInMul. In other words, assuming that all + ** "x IN(...)" terms are replaced with "x = ?". This block updates + ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ + assert( pNew->nOut==saved_nOut ); + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ + /* Adjust nOut using stat4 data. Or, if there is no stat4 + ** data, using some other estimate. */ + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); + }else{ + int nEq = ++pNew->u.btree.nEq; + assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) ); + + assert( pNew->nOut==saved_nOut ); + if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){ + assert( (eOp & WO_IN) || nIn==0 ); + testcase( eOp & WO_IN ); + pNew->nOut += pTerm->truthProb; + pNew->nOut -= nIn; + }else{ +#ifdef SQLITE_ENABLE_STAT4 + tRowcnt nOut = 0; + if( nInMul==0 + && pProbe->nSample + && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol) + && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr)) + && OptimizationEnabled(db, SQLITE_Stat4) + ){ + Expr *pExpr = pTerm->pExpr; + if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ + testcase( eOp & WO_EQ ); + testcase( eOp & WO_IS ); + testcase( eOp & WO_ISNULL ); + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); + }else{ + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); + } + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ + if( nOut ){ + pNew->nOut = sqlite3LogEst(nOut); + if( nEq==1 + /* TUNING: Mark terms as "low selectivity" if they seem likely + ** to be true for half or more of the rows in the table. + ** See tag-202002240-1 */ + && pNew->nOut+10 > pProbe->aiRowLogEst[0] + ){ +#if WHERETRACE_ENABLED /* 0x01 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf( + "STAT4 determines term has low selectivity:\n"); + sqlite3WhereTermPrint(pTerm, 999); + } +#endif + pTerm->wtFlags |= TERM_HIGHTRUTH; + if( pTerm->wtFlags & TERM_HEURTRUTH ){ + /* If the term has previously been used with an assumption of + ** higher selectivity, then set the flag to rerun the + ** loop computations. */ + pBuilder->bldFlags2 |= SQLITE_BLDF2_2NDPASS; + } + } + if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; + pNew->nOut -= nIn; + } + } + if( nOut==0 ) +#endif + { + pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); + if( eOp & WO_ISNULL ){ + /* TUNING: If there is no likelihood() value, assume that a + ** "col IS NULL" expression matches twice as many rows + ** as (col=?). */ + pNew->nOut += 10; + } + } + } + } + + /* Set rCostIdx to the cost of visiting selected rows in index. Add + ** it to pNew->rRun, which is currently set to the cost of the index + ** seek only. Then, if this is a non-covering index, add the cost of + ** visiting the rows in the main table. */ + assert( pSrc->pTab->szTabRow>0 ); + if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ + /* The pProbe->szIdxRow is low for an IPK table since the interior + ** pages are small. Thus szIdxRow gives a good estimate of seek cost. + ** But the leaf pages are full-size, so pProbe->szIdxRow would badly + ** under-estimate the scanning cost. */ + rCostIdx = pNew->nOut + 16; + }else{ + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; + } + pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); + if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); + } + ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); + + nOutUnadjusted = pNew->nOut; + pNew->rRun += nInMul + nIn; + pNew->nOut += nInMul + nIn; + whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); + rc = whereLoopInsert(pBuilder, pNew); + + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ + pNew->nOut = saved_nOut; + }else{ + pNew->nOut = nOutUnadjusted; + } + + if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 + && pNew->u.btree.nEqnColumn + && (pNew->u.btree.nEqnKeyCol || + pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) + ){ + if( pNew->u.btree.nEq>3 ){ + sqlite3ProgressCheck(pParse); + } + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); + } + pNew->nOut = saved_nOut; +#ifdef SQLITE_ENABLE_STAT4 + pBuilder->nRecValid = nRecValid; +#endif + } + pNew->prereq = saved_prereq; + pNew->u.btree.nEq = saved_nEq; + pNew->u.btree.nBtm = saved_nBtm; + pNew->u.btree.nTop = saved_nTop; + pNew->nSkip = saved_nSkip; + pNew->wsFlags = saved_wsFlags; + pNew->nOut = saved_nOut; + pNew->nLTerm = saved_nLTerm; + + /* Consider using a skip-scan if there are no WHERE clause constraints + ** available for the left-most terms of the index, and if the average + ** number of repeats in the left-most terms is at least 18. + ** + ** The magic number 18 is selected on the basis that scanning 17 rows + ** is almost always quicker than an index seek (even though if the index + ** contains fewer than 2^17 rows we assume otherwise in other parts of + ** the code). And, even if it is not, it should not be too much slower. + ** On the other hand, the extra seeks could end up being significantly + ** more expensive. */ + assert( 42==sqlite3LogEst(18) ); + if( saved_nEq==saved_nSkip + && saved_nEq+1nKeyCol + && saved_nEq==pNew->nLTerm + && pProbe->noSkipScan==0 + && pProbe->hasStat1!=0 + && OptimizationEnabled(db, SQLITE_SkipScan) + && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ + && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK + ){ + LogEst nIter; + pNew->u.btree.nEq++; + pNew->nSkip++; + pNew->aLTerm[pNew->nLTerm++] = 0; + pNew->wsFlags |= WHERE_SKIPSCAN; + nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; + pNew->nOut -= nIter; + /* TUNING: Because uncertainties in the estimates for skip-scan queries, + ** add a 1.375 fudge factor to make skip-scan slightly less likely. */ + nIter += 5; + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); + pNew->nOut = saved_nOut; + pNew->u.btree.nEq = saved_nEq; + pNew->nSkip = saved_nSkip; + pNew->wsFlags = saved_wsFlags; + } + + WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n", + pProbe->pTable->zName, pProbe->zName, saved_nEq, rc)); + return rc; +} + +/* +** Return True if it is possible that pIndex might be useful in +** implementing the ORDER BY clause in pBuilder. +** +** Return False if pBuilder does not contain an ORDER BY clause or +** if there is no way for pIndex to be useful in implementing that +** ORDER BY clause. +*/ +static int indexMightHelpWithOrderBy( + WhereLoopBuilder *pBuilder, + Index *pIndex, + int iCursor +){ + ExprList *pOB; + ExprList *aColExpr; + int ii, jj; + + if( pIndex->bUnordered ) return 0; + if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; + for(ii=0; iinExpr; ii++){ + Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); + if( NEVER(pExpr==0) ) continue; + if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ + if( pExpr->iColumn<0 ) return 1; + for(jj=0; jjnKeyCol; jj++){ + if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; + } + }else if( (aColExpr = pIndex->aColExpr)!=0 ){ + for(jj=0; jjnKeyCol; jj++){ + if( pIndex->aiColumn[jj]!=XN_EXPR ) continue; + if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ + return 1; + } + } + } + } + return 0; +} + +/* Check to see if a partial index with pPartIndexWhere can be used +** in the current query. Return true if it can be and false if not. +*/ +static int whereUsablePartialIndex( + int iTab, /* The table for which we want an index */ + u8 jointype, /* The JT_* flags on the join */ + WhereClause *pWC, /* The WHERE clause of the query */ + Expr *pWhere /* The WHERE clause from the partial index */ +){ + int i; + WhereTerm *pTerm; + Parse *pParse; + + if( jointype & JT_LTORJ ) return 0; + pParse = pWC->pWInfo->pParse; + while( pWhere->op==TK_AND ){ + if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; + pWhere = pWhere->pRight; + } + if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; + for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + Expr *pExpr; + pExpr = pTerm->pExpr; + if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) + && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) + && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) + && (pTerm->wtFlags & TERM_VNULL)==0 + ){ + return 1; + } + } + return 0; +} + +/* +** pIdx is an index containing expressions. Check it see if any of the +** expressions in the index match the pExpr expression. +*/ +static int exprIsCoveredByIndex( + const Expr *pExpr, + const Index *pIdx, + int iTabCur +){ + int i; + for(i=0; inColumn; i++){ + if( pIdx->aiColumn[i]==XN_EXPR + && sqlite3ExprCompare(0, pExpr, pIdx->aColExpr->a[i].pExpr, iTabCur)==0 + ){ + return 1; + } + } + return 0; +} + +/* +** Structure passed to the whereIsCoveringIndex Walker callback. +*/ +typedef struct CoveringIndexCheck CoveringIndexCheck; +struct CoveringIndexCheck { + Index *pIdx; /* The index */ + int iTabCur; /* Cursor number for the corresponding table */ + u8 bExpr; /* Uses an indexed expression */ + u8 bUnidx; /* Uses an unindexed column not within an indexed expr */ +}; + +/* +** Information passed in is pWalk->u.pCovIdxCk. Call it pCk. +** +** If the Expr node references the table with cursor pCk->iTabCur, then +** make sure that column is covered by the index pCk->pIdx. We know that +** all columns less than 63 (really BMS-1) are covered, so we don't need +** to check them. But we do need to check any column at 63 or greater. +** +** If the index does not cover the column, then set pWalk->eCode to +** non-zero and return WRC_Abort to stop the search. +** +** If this node does not disprove that the index can be a covering index, +** then just return WRC_Continue, to continue the search. +** +** If pCk->pIdx contains indexed expressions and one of those expressions +** matches pExpr, then prune the search. +*/ +static int whereIsCoveringIndexWalkCallback(Walker *pWalk, Expr *pExpr){ + int i; /* Loop counter */ + const Index *pIdx; /* The index of interest */ + const i16 *aiColumn; /* Columns contained in the index */ + u16 nColumn; /* Number of columns in the index */ + CoveringIndexCheck *pCk; /* Info about this search */ + + pCk = pWalk->u.pCovIdxCk; + pIdx = pCk->pIdx; + if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) ){ + /* if( pExpr->iColumn<(BMS-1) && pIdx->bHasExpr==0 ) return WRC_Continue;*/ + if( pExpr->iTable!=pCk->iTabCur ) return WRC_Continue; + pIdx = pWalk->u.pCovIdxCk->pIdx; + aiColumn = pIdx->aiColumn; + nColumn = pIdx->nColumn; + for(i=0; iiColumn ) return WRC_Continue; + } + pCk->bUnidx = 1; + return WRC_Abort; + }else if( pIdx->bHasExpr + && exprIsCoveredByIndex(pExpr, pIdx, pWalk->u.pCovIdxCk->iTabCur) ){ + pCk->bExpr = 1; + return WRC_Prune; + } + return WRC_Continue; +} + + +/* +** pIdx is an index that covers all of the low-number columns used by +** pWInfo->pSelect (columns from 0 through 62) or an index that has +** expressions terms. Hence, we cannot determine whether or not it is +** a covering index by using the colUsed bitmasks. We have to do a search +** to see if the index is covering. This routine does that search. +** +** The return value is one of these: +** +** 0 The index is definitely not a covering index +** +** WHERE_IDX_ONLY The index is definitely a covering index +** +** WHERE_EXPRIDX The index is likely a covering index, but it is +** difficult to determine precisely because of the +** expressions that are indexed. Score it as a +** covering index, but still keep the main table open +** just in case we need it. +** +** This routine is an optimization. It is always safe to return zero. +** But returning one of the other two values when zero should have been +** returned can lead to incorrect bytecode and assertion faults. +*/ +static SQLITE_NOINLINE u32 whereIsCoveringIndex( + WhereInfo *pWInfo, /* The WHERE clause context */ + Index *pIdx, /* Index that is being tested */ + int iTabCur /* Cursor for the table being indexed */ +){ + int i, rc; + struct CoveringIndexCheck ck; + Walker w; + if( pWInfo->pSelect==0 ){ + /* We don't have access to the full query, so we cannot check to see + ** if pIdx is covering. Assume it is not. */ + return 0; + } + if( pIdx->bHasExpr==0 ){ + for(i=0; inColumn; i++){ + if( pIdx->aiColumn[i]>=BMS-1 ) break; + } + if( i>=pIdx->nColumn ){ + /* pIdx does not index any columns greater than 62, but we know from + ** colMask that columns greater than 62 are used, so this is not a + ** covering index */ + return 0; + } + } + ck.pIdx = pIdx; + ck.iTabCur = iTabCur; + ck.bExpr = 0; + ck.bUnidx = 0; + memset(&w, 0, sizeof(w)); + w.xExprCallback = whereIsCoveringIndexWalkCallback; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.u.pCovIdxCk = &ck; + sqlite3WalkSelect(&w, pWInfo->pSelect); + if( ck.bUnidx ){ + rc = 0; + }else if( ck.bExpr ){ + rc = WHERE_EXPRIDX; + }else{ + rc = WHERE_IDX_ONLY; + } + return rc; +} + +/* +** This is an sqlite3ParserAddCleanup() callback that is invoked to +** free the Parse->pIdxEpr list when the Parse object is destroyed. +*/ +static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ + IndexedExpr **pp = (IndexedExpr**)pObject; + while( *pp!=0 ){ + IndexedExpr *p = *pp; + *pp = p->pIENext; + sqlite3ExprDelete(db, p->pExpr); + sqlite3DbFreeNN(db, p); + } +} + +/* +** This function is called for a partial index - one with a WHERE clause - in +** two scenarios. In both cases, it determines whether or not the WHERE +** clause on the index implies that a column of the table may be safely +** replaced by a constant expression. For example, in the following +** SELECT: +** +** CREATE INDEX i1 ON t1(b, c) WHERE a=; +** SELECT a, b, c FROM t1 WHERE a= AND b=?; +** +** The "a" in the select-list may be replaced by , iff: +** +** (a) is a constant expression, and +** (b) The (a=) comparison uses the BINARY collation sequence, and +** (c) Column "a" has an affinity other than NONE or BLOB. +** +** If argument pItem is NULL, then pMask must not be NULL. In this case this +** function is being called as part of determining whether or not pIdx +** is a covering index. This function clears any bits in (*pMask) +** corresponding to columns that may be replaced by constants as described +** above. +** +** Otherwise, if pItem is not NULL, then this function is being called +** as part of coding a loop that uses index pIdx. In this case, add entries +** to the Parse.pIdxPartExpr list for each column that can be replaced +** by a constant. +*/ +static void wherePartIdxExpr( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Partial index being processed */ + Expr *pPart, /* WHERE clause being processed */ + Bitmask *pMask, /* Mask to clear bits in */ + int iIdxCur, /* Cursor number for index */ + SrcItem *pItem /* The FROM clause entry for the table */ +){ + assert( pItem==0 || (pItem->fg.jointype & JT_RIGHT)==0 ); + assert( (pItem==0 || pMask==0) && (pMask!=0 || pItem!=0) ); + + if( pPart->op==TK_AND ){ + wherePartIdxExpr(pParse, pIdx, pPart->pRight, pMask, iIdxCur, pItem); + pPart = pPart->pLeft; + } + + if( (pPart->op==TK_EQ || pPart->op==TK_IS) ){ + Expr *pLeft = pPart->pLeft; + Expr *pRight = pPart->pRight; + u8 aff; + + if( pLeft->op!=TK_COLUMN ) return; + if( !sqlite3ExprIsConstant(pRight) ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; + if( pLeft->iColumn<0 ) return; + aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; + if( aff>=SQLITE_AFF_TEXT ){ + if( pItem ){ + sqlite3 *db = pParse->db; + IndexedExpr *p = (IndexedExpr*)sqlite3DbMallocRaw(db, sizeof(*p)); + if( p ){ + int bNullRow = (pItem->fg.jointype&(JT_LEFT|JT_LTORJ))!=0; + p->pExpr = sqlite3ExprDup(db, pRight, 0); + p->iDataCur = pItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = pLeft->iColumn; + p->bMaybeNullRow = bNullRow; + p->pIENext = pParse->pIdxPartExpr; + p->aff = aff; + pParse->pIdxPartExpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxPartExpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } + }else if( pLeft->iColumn<(BMS-1) ){ + *pMask &= ~((Bitmask)1 << pLeft->iColumn); + } + } + } +} + + +/* +** Add all WhereLoop objects for a single table of the join where the table +** is identified by pBuilder->pNew->iTab. That table is guaranteed to be +** a b-tree table, not a virtual table. +** +** The costs (WhereLoop.rRun) of the b-tree loops added by this function +** are calculated as follows: +** +** For a full scan, assuming the table (or index) contains nRow rows: +** +** cost = nRow * 3.0 // full-table scan +** cost = nRow * K // scan of covering index +** cost = nRow * (K+3.0) // scan of non-covering index +** +** where K is a value between 1.1 and 3.0 set based on the relative +** estimated average size of the index and table records. +** +** For an index scan, where nVisit is the number of index rows visited +** by the scan, and nSeek is the number of seek operations required on +** the index b-tree: +** +** cost = nSeek * (log(nRow) + K * nVisit) // covering index +** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index +** +** Normally, nSeek is 1. nSeek values greater than 1 come about if the +** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when +** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. +** +** The estimated values (nRow, nVisit, nSeek) often contain a large amount +** of uncertainty. For this reason, scoring is designed to pick plans that +** "do the least harm" if the estimates are inaccurate. For example, a +** log(nRow) factor is omitted from a non-covering index scan in order to +** bias the scoring in favor of using an index, since the worst-case +** performance of using an index is far better than the worst-case performance +** of a full table scan. +*/ +static int whereLoopAddBtree( + WhereLoopBuilder *pBuilder, /* WHERE clause information */ + Bitmask mPrereq /* Extra prerequisites for using this table */ +){ + WhereInfo *pWInfo; /* WHERE analysis context */ + Index *pProbe; /* An index we are evaluating */ + Index sPk; /* A fake index object for the primary key */ + LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ + i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ + SrcList *pTabList; /* The FROM clause */ + SrcItem *pSrc; /* The FROM clause btree term to add */ + WhereLoop *pNew; /* Template WhereLoop object */ + int rc = SQLITE_OK; /* Return code */ + int iSortIdx = 1; /* Index number */ + int b; /* A boolean value */ + LogEst rSize; /* number of rows in the table */ + WhereClause *pWC; /* The parsed WHERE clause */ + Table *pTab; /* Table being queried */ + + pNew = pBuilder->pNew; + pWInfo = pBuilder->pWInfo; + pTabList = pWInfo->pTabList; + pSrc = pTabList->a + pNew->iTab; + pTab = pSrc->pTab; + pWC = pBuilder->pWC; + assert( !IsVirtual(pSrc->pTab) ); + + if( pSrc->fg.isIndexedBy ){ + assert( pSrc->fg.isCte==0 ); + /* An INDEXED BY clause specifies a particular index to use */ + pProbe = pSrc->u2.pIBIndex; + }else if( !HasRowid(pTab) ){ + pProbe = pTab->pIndex; + }else{ + /* There is no INDEXED BY clause. Create a fake Index object in local + ** variable sPk to represent the rowid primary key index. Make this + ** fake index the first in a chain of Index objects with all of the real + ** indices to follow */ + Index *pFirst; /* First of real indices on the table */ + memset(&sPk, 0, sizeof(Index)); + sPk.nKeyCol = 1; + sPk.nColumn = 1; + sPk.aiColumn = &aiColumnPk; + sPk.aiRowLogEst = aiRowEstPk; + sPk.onError = OE_Replace; + sPk.pTable = pTab; + sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ + sPk.idxType = SQLITE_IDXTYPE_IPK; + aiRowEstPk[0] = pTab->nRowLogEst; + aiRowEstPk[1] = 0; + pFirst = pSrc->pTab->pIndex; + if( pSrc->fg.notIndexed==0 ){ + /* The real indices of the table are only considered if the + ** NOT INDEXED qualifier is omitted from the FROM clause */ + sPk.pNext = pFirst; + } + pProbe = &sPk; + } + rSize = pTab->nRowLogEst; + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + /* Automatic indexes */ + if( !pBuilder->pOrSet /* Not part of an OR optimization */ + && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0 + && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 + && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ + && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ + && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ + && !pSrc->fg.isCorrelated /* Not a correlated subquery */ + && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ + && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */ + ){ + /* Generate auto-index WhereLoops */ + LogEst rLogSize; /* Logarithm of the number of rows in the table */ + WhereTerm *pTerm; + WhereTerm *pWCEnd = pWC->a + pWC->nTerm; + rLogSize = estLog(rSize); + for(pTerm=pWC->a; rc==SQLITE_OK && pTermprereqRight & pNew->maskSelf ) continue; + if( termCanDriveIndex(pTerm, pSrc, 0) ){ + pNew->u.btree.nEq = 1; + pNew->nSkip = 0; + pNew->u.btree.pIndex = 0; + pNew->nLTerm = 1; + pNew->aLTerm[0] = pTerm; + /* TUNING: One-time cost for computing the automatic index is + ** estimated to be X*N*log2(N) where N is the number of rows in + ** the table being indexed and where X is 7 (LogEst=28) for normal + ** tables or 0.5 (LogEst=-10) for views and subqueries. The value + ** of X is smaller for views and subqueries so that the query planner + ** will be more aggressive about generating automatic indexes for + ** those objects, since there is no opportunity to add schema + ** indexes on subqueries and views. */ + pNew->rSetup = rLogSize + rSize; + if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ + pNew->rSetup += 28; + }else{ + pNew->rSetup -= 25; /* Greatly reduced setup cost for auto indexes + ** on ephemeral materializations of views */ + } + ApplyCostMultiplier(pNew->rSetup, pTab->costMult); + if( pNew->rSetup<0 ) pNew->rSetup = 0; + /* TUNING: Each index lookup yields 20 rows in the table. This + ** is more than the usual guess of 10 rows, since we have no way + ** of knowing how selective the index will ultimately be. It would + ** not be unreasonable to make this value much larger. */ + pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); + pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); + pNew->wsFlags = WHERE_AUTO_INDEX; + pNew->prereq = mPrereq | pTerm->prereqRight; + rc = whereLoopInsert(pBuilder, pNew); + } + } + } +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + + /* Loop over all indices. If there was an INDEXED BY clause, then only + ** consider index pProbe. */ + for(; rc==SQLITE_OK && pProbe; + pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ + ){ + if( pProbe->pPartIdxWhere!=0 + && !whereUsablePartialIndex(pSrc->iCursor, pSrc->fg.jointype, pWC, + pProbe->pPartIdxWhere) + ){ + testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ + continue; /* Partial index inappropriate for this query */ + } + if( pProbe->bNoQuery ) continue; + rSize = pProbe->aiRowLogEst[0]; + pNew->u.btree.nEq = 0; + pNew->u.btree.nBtm = 0; + pNew->u.btree.nTop = 0; + pNew->nSkip = 0; + pNew->nLTerm = 0; + pNew->iSortIdx = 0; + pNew->rSetup = 0; + pNew->prereq = mPrereq; + pNew->nOut = rSize; + pNew->u.btree.pIndex = pProbe; + b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); + + /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ + assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); + if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ + /* Integer primary key index */ + pNew->wsFlags = WHERE_IPK; + + /* Full table scan */ + pNew->iSortIdx = b ? iSortIdx : 0; + /* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an + ** extra cost designed to discourage the use of full table scans, + ** since index lookups have better worst-case performance if our + ** stat guesses are wrong. Reduce the 3.0 penalty slightly + ** (to 2.75) if we have valid STAT4 information for the table. + ** At 2.75, a full table scan is preferred over using an index on + ** a column with just two distinct values where each value has about + ** an equal number of appearances. Without STAT4 data, we still want + ** to use an index in that case, since the constraint might be for + ** the scarcer of the two values, and in that case an index lookup is + ** better. + */ +#ifdef SQLITE_ENABLE_STAT4 + pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); +#else + pNew->rRun = rSize + 16; +#endif + ApplyCostMultiplier(pNew->rRun, pTab->costMult); + whereLoopOutputAdjust(pWC, pNew, rSize); + rc = whereLoopInsert(pBuilder, pNew); + pNew->nOut = rSize; + if( rc ) break; + }else{ + Bitmask m; + if( pProbe->isCovering ){ + m = 0; + pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + }else{ + m = pSrc->colUsed & pProbe->colNotIdxed; + if( pProbe->pPartIdxWhere ){ + wherePartIdxExpr( + pWInfo->pParse, pProbe, pProbe->pPartIdxWhere, &m, 0, 0 + ); + } + pNew->wsFlags = WHERE_INDEXED; + if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ + u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); + if( isCov==0 ){ + WHERETRACE(0x200, + ("-> %s is not a covering index" + " according to whereIsCoveringIndex()\n", pProbe->zName)); + assert( m!=0 ); + }else{ + m = 0; + pNew->wsFlags |= isCov; + if( isCov & WHERE_IDX_ONLY ){ + WHERETRACE(0x200, + ("-> %s is a covering expression index" + " according to whereIsCoveringIndex()\n", pProbe->zName)); + }else{ + assert( isCov==WHERE_EXPRIDX ); + WHERETRACE(0x200, + ("-> %s might be a covering expression index" + " according to whereIsCoveringIndex()\n", pProbe->zName)); + } + } + }else if( m==0 ){ + WHERETRACE(0x200, + ("-> %s a covering index according to bitmasks\n", + pProbe->zName, m==0 ? "is" : "is not")); + pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + } + } + + /* Full scan via index */ + if( b + || !HasRowid(pTab) + || pProbe->pPartIdxWhere!=0 + || pSrc->fg.isIndexedBy + || ( m==0 + && pProbe->bUnordered==0 + && (pProbe->szIdxRowszTabRow) + && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 + && sqlite3GlobalConfig.bUseCis + && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) + ) + ){ + pNew->iSortIdx = b ? iSortIdx : 0; + + /* The cost of visiting the index rows is N*K, where K is + ** between 1.1 and 3.0, depending on the relative sizes of the + ** index and table rows. */ + pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; + if( m!=0 ){ + /* If this is a non-covering index scan, add in the cost of + ** doing table lookups. The cost will be 3x the number of + ** lookups. Take into account WHERE clause terms that can be + ** satisfied using just the index, and that do not require a + ** table lookup. */ + LogEst nLookup = rSize + 16; /* Base cost: N*3 */ + int ii; + int iCur = pSrc->iCursor; + WhereClause *pWC2 = &pWInfo->sWC; + for(ii=0; iinTerm; ii++){ + WhereTerm *pTerm = &pWC2->a[ii]; + if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ + break; + } + /* pTerm can be evaluated using just the index. So reduce + ** the expected number of table lookups accordingly */ + if( pTerm->truthProb<=0 ){ + nLookup += pTerm->truthProb; + }else{ + nLookup--; + if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19; + } + } + + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); + } + ApplyCostMultiplier(pNew->rRun, pTab->costMult); + whereLoopOutputAdjust(pWC, pNew, rSize); + if( (pSrc->fg.jointype & JT_RIGHT)!=0 && pProbe->aColExpr ){ + /* Do not do an SCAN of a index-on-expression in a RIGHT JOIN + ** because the cursor used to access the index might not be + ** positioned to the correct row during the right-join no-match + ** loop. */ + }else{ + rc = whereLoopInsert(pBuilder, pNew); + } + pNew->nOut = rSize; + if( rc ) break; + } + } + + pBuilder->bldFlags1 = 0; + rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); + if( pBuilder->bldFlags1==SQLITE_BLDF1_INDEXED ){ + /* If a non-unique index is used, or if a prefix of the key for + ** unique index is used (making the index functionally non-unique) + ** then the sqlite_stat1 data becomes important for scoring the + ** plan */ + pTab->tabFlags |= TF_StatsUsed; + } +#ifdef SQLITE_ENABLE_STAT4 + sqlite3Stat4ProbeFree(pBuilder->pRec); + pBuilder->nRecValid = 0; + pBuilder->pRec = 0; +#endif + } + return rc; +} + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Return true if pTerm is a virtual table LIMIT or OFFSET term. +*/ +static int isLimitTerm(WhereTerm *pTerm){ + assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 ); + return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT + && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET; +} + +/* +** Argument pIdxInfo is already populated with all constraints that may +** be used by the virtual table identified by pBuilder->pNew->iTab. This +** function marks a subset of those constraints usable, invokes the +** xBestIndex method and adds the returned plan to pBuilder. +** +** A constraint is marked usable if: +** +** * Argument mUsable indicates that its prerequisites are available, and +** +** * It is not one of the operators specified in the mExclude mask passed +** as the fourth argument (which in practice is either WO_IN or 0). +** +** Argument mPrereq is a mask of tables that must be scanned before the +** virtual table in question. These are added to the plans prerequisites +** before it is added to pBuilder. +** +** Output parameter *pbIn is set to true if the plan added to pBuilder +** uses one or more WO_IN terms, or false otherwise. +*/ +static int whereLoopAddVirtualOne( + WhereLoopBuilder *pBuilder, + Bitmask mPrereq, /* Mask of tables that must be used. */ + Bitmask mUsable, /* Mask of usable tables */ + u16 mExclude, /* Exclude terms using these operators */ + sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ + u16 mNoOmit, /* Do not omit these constraints */ + int *pbIn, /* OUT: True if plan uses an IN(...) op */ + int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */ +){ + WhereClause *pWC = pBuilder->pWC; + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; + int i; + int mxTerm; + int rc = SQLITE_OK; + WhereLoop *pNew = pBuilder->pNew; + Parse *pParse = pBuilder->pWInfo->pParse; + SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; + int nConstraint = pIdxInfo->nConstraint; + + assert( (mUsable & mPrereq)==mPrereq ); + *pbIn = 0; + pNew->prereq = mPrereq; + + /* Set the usable flag on the subset of constraints identified by + ** arguments mUsable and mExclude. */ + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + for(i=0; ia[pIdxCons->iTermOffset]; + pIdxCons->usable = 0; + if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight + && (pTerm->eOperator & mExclude)==0 + && (pbRetryLimit || !isLimitTerm(pTerm)) + ){ + pIdxCons->usable = 1; + } + } + + /* Initialize the output fields of the sqlite3_index_info structure */ + memset(pUsage, 0, sizeof(pUsage[0])*nConstraint); + assert( pIdxInfo->needToFreeIdxStr==0 ); + pIdxInfo->idxStr = 0; + pIdxInfo->idxNum = 0; + pIdxInfo->orderByConsumed = 0; + pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; + pIdxInfo->estimatedRows = 25; + pIdxInfo->idxFlags = 0; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + pHidden->mHandleIn = 0; + + /* Invoke the virtual table xBestIndex() method */ + rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); + if( rc ){ + if( rc==SQLITE_CONSTRAINT ){ + /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means + ** that the particular combination of parameters provided is unusable. + ** Make no entries in the loop table. + */ + WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + return SQLITE_OK; + } + return rc; + } + + mxTerm = -1; + assert( pNew->nLSlot>=nConstraint ); + memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint ); + memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab)); + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + for(i=0; i=0 ){ + WhereTerm *pTerm; + int j = pIdxCons->iTermOffset; + if( iTerm>=nConstraint + || j<0 + || j>=pWC->nTerm + || pNew->aLTerm[iTerm]!=0 + || pIdxCons->usable==0 + ){ + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); + testcase( pIdxInfo->needToFreeIdxStr ); + return SQLITE_ERROR; + } + testcase( iTerm==nConstraint-1 ); + testcase( j==0 ); + testcase( j==pWC->nTerm-1 ); + pTerm = &pWC->a[j]; + pNew->prereq |= pTerm->prereqRight; + assert( iTermnLSlot ); + pNew->aLTerm[iTerm] = pTerm; + if( iTerm>mxTerm ) mxTerm = iTerm; + testcase( iTerm==15 ); + testcase( iTerm==16 ); + if( pUsage[i].omit ){ + if( i<16 && ((1<u.vtab.omitMask |= 1<eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){ + pNew->u.vtab.bOmitOffset = 1; + } + } + if( SMASKBIT32(i) & pHidden->mHandleIn ){ + pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm); + }else if( (pTerm->eOperator & WO_IN)!=0 ){ + /* A virtual table that is constrained by an IN clause may not + ** consume the ORDER BY clause because (1) the order of IN terms + ** is not necessarily related to the order of output terms and + ** (2) Multiple outputs from a single IN value will not merge + ** together. */ + pIdxInfo->orderByConsumed = 0; + pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE; + *pbIn = 1; assert( (mExclude & WO_IN)==0 ); + } + + assert( pbRetryLimit || !isLimitTerm(pTerm) ); + if( isLimitTerm(pTerm) && *pbIn ){ + /* If there is an IN(...) term handled as an == (separate call to + ** xFilter for each value on the RHS of the IN) and a LIMIT or + ** OFFSET term handled as well, the plan is unusable. Set output + ** variable *pbRetryLimit to true to tell the caller to retry with + ** LIMIT and OFFSET disabled. */ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } + *pbRetryLimit = 1; + return SQLITE_OK; + } + } + } + + pNew->nLTerm = mxTerm+1; + for(i=0; i<=mxTerm; i++){ + if( pNew->aLTerm[i]==0 ){ + /* The non-zero argvIdx values must be contiguous. Raise an + ** error if they are not */ + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); + testcase( pIdxInfo->needToFreeIdxStr ); + return SQLITE_ERROR; + } + } + assert( pNew->nLTerm<=pNew->nLSlot ); + pNew->u.vtab.idxNum = pIdxInfo->idxNum; + pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; + pIdxInfo->needToFreeIdxStr = 0; + pNew->u.vtab.idxStr = pIdxInfo->idxStr; + pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? + pIdxInfo->nOrderBy : 0); + pNew->rSetup = 0; + pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); + pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); + + /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated + ** that the scan will visit at most one row. Clear it otherwise. */ + if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){ + pNew->wsFlags |= WHERE_ONEROW; + }else{ + pNew->wsFlags &= ~WHERE_ONEROW; + } + rc = whereLoopInsert(pBuilder, pNew); + if( pNew->u.vtab.needFree ){ + sqlite3_free(pNew->u.vtab.idxStr); + pNew->u.vtab.needFree = 0; + } + WHERETRACE(0xffffffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", + *pbIn, (sqlite3_uint64)mPrereq, + (sqlite3_uint64)(pNew->prereq & ~mPrereq))); + + return rc; +} + +/* +** Return the collating sequence for a constraint passed into xBestIndex. +** +** pIdxInfo must be an sqlite3_index_info structure passed into xBestIndex. +** This routine depends on there being a HiddenIndexInfo structure immediately +** following the sqlite3_index_info structure. +** +** Return a pointer to the collation name: +** +** 1. If there is an explicit COLLATE operator on the constraint, return it. +** +** 2. Else, if the column has an alternative collation, return that. +** +** 3. Otherwise, return "BINARY". +*/ +SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + const char *zRet = 0; + if( iCons>=0 && iConsnConstraint ){ + CollSeq *pC = 0; + int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; + Expr *pX = pHidden->pWC->a[iTerm].pExpr; + if( pX->pLeft ){ + pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); + } + zRet = (pC ? pC->zName : sqlite3StrBINARY); + } + return zRet; +} + +/* +** Return true if constraint iCons is really an IN(...) constraint, or +** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0) +** or clear (if bHandle==0) the flag to handle it using an iterator. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + u32 m = SMASKBIT32(iCons); + if( m & pHidden->mIn ){ + if( bHandle==0 ){ + pHidden->mHandleIn &= ~m; + }else if( bHandle>0 ){ + pHidden->mHandleIn |= m; + } + return 1; + } + return 0; +} + +/* +** This interface is callable from within the xBestIndex callback only. +** +** If possible, set (*ppVal) to point to an object containing the value +** on the right-hand-side of constraint iCons. +*/ +SQLITE_API int sqlite3_vtab_rhs_value( + sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */ + int iCons, /* Constraint for which RHS is wanted */ + sqlite3_value **ppVal /* Write value extracted here */ +){ + HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1]; + sqlite3_value *pVal = 0; + int rc = SQLITE_OK; + if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ + rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ + }else{ + if( pH->aRhs[iCons]==0 ){ + WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; + rc = sqlite3ValueFromExpr( + pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), + SQLITE_AFF_BLOB, &pH->aRhs[iCons] + ); + testcase( rc!=SQLITE_OK ); + } + pVal = pH->aRhs[iCons]; + } + *ppVal = pVal; + + if( rc==SQLITE_OK && pVal==0 ){ /* IMP: R-19933-32160 */ + rc = SQLITE_NOTFOUND; /* IMP: R-36424-56542 */ + } + + return rc; +} + +/* +** Return true if ORDER BY clause may be handled as DISTINCT. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 ); + return pHidden->eDistinct; +} + +/* +** Cause the prepared statement that is associated with a call to +** xBestIndex to potentially use all schemas. If the statement being +** prepared is read-only, then just start read transactions on all +** schemas. But if this is a write operation, start writes on all +** schemas. +** +** This is used by the (built-in) sqlite_dbpage virtual table. +*/ +SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse *pParse){ + int nDb = pParse->db->nDb; + int i; + for(i=0; iwriteMask) ){ + for(i=0; ipNew->iTab. That table is guaranteed to be a virtual table. +** +** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and +** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause +** entries that occur before the virtual table in the FROM clause and are +** separated from it by at least one LEFT or CROSS JOIN. Similarly, the +** mUnusable mask contains all FROM clause entries that occur after the +** virtual table and are separated from it by at least one LEFT or +** CROSS JOIN. +** +** For example, if the query were: +** +** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6; +** +** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6). +** +** All the tables in mPrereq must be scanned before the current virtual +** table. So any terms for which all prerequisites are satisfied by +** mPrereq may be specified as "usable" in all calls to xBestIndex. +** Conversely, all tables in mUnusable must be scanned after the current +** virtual table, so any terms for which the prerequisites overlap with +** mUnusable should always be configured as "not-usable" for xBestIndex. +*/ +static int whereLoopAddVirtual( + WhereLoopBuilder *pBuilder, /* WHERE clause information */ + Bitmask mPrereq, /* Tables that must be scanned before this one */ + Bitmask mUnusable /* Tables that must be scanned after this one */ +){ + int rc = SQLITE_OK; /* Return code */ + WhereInfo *pWInfo; /* WHERE analysis context */ + Parse *pParse; /* The parsing context */ + WhereClause *pWC; /* The WHERE clause */ + SrcItem *pSrc; /* The FROM clause term to search */ + sqlite3_index_info *p; /* Object to pass to xBestIndex() */ + int nConstraint; /* Number of constraints in p */ + int bIn; /* True if plan uses IN(...) operator */ + WhereLoop *pNew; + Bitmask mBest; /* Tables used by best possible plan */ + u16 mNoOmit; + int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */ + + assert( (mPrereq & mUnusable)==0 ); + pWInfo = pBuilder->pWInfo; + pParse = pWInfo->pParse; + pWC = pBuilder->pWC; + pNew = pBuilder->pNew; + pSrc = &pWInfo->pTabList->a[pNew->iTab]; + assert( IsVirtual(pSrc->pTab) ); + p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); + if( p==0 ) return SQLITE_NOMEM_BKPT; + pNew->rSetup = 0; + pNew->wsFlags = WHERE_VIRTUALTABLE; + pNew->nLTerm = 0; + pNew->u.vtab.needFree = 0; + nConstraint = p->nConstraint; + if( whereLoopResize(pParse->db, pNew, nConstraint) ){ + freeIndexInfo(pParse->db, p); + return SQLITE_NOMEM_BKPT; + } + + /* First call xBestIndex() with all constraints usable. */ + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); + WHERETRACE(0x800, (" VirtualOne: all usable\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry + ); + if( bRetry ){ + assert( rc==SQLITE_OK ); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0 + ); + } + + /* If the call to xBestIndex() with all terms enabled produced a plan + ** that does not require any source tables (IOW: a plan with mBest==0) + ** and does not use an IN(...) operator, then there is no point in making + ** any further calls to xBestIndex() since they will all return the same + ** result (if the xBestIndex() implementation is sane). */ + if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){ + int seenZero = 0; /* True if a plan with no prereqs seen */ + int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */ + Bitmask mPrev = 0; + Bitmask mBestNoIn = 0; + + /* If the plan produced by the earlier call uses an IN(...) term, call + ** xBestIndex again, this time with IN(...) terms disabled. */ + if( bIn ){ + WHERETRACE(0x800, (" VirtualOne: all usable w/o IN\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); + assert( bIn==0 ); + mBestNoIn = pNew->prereq & ~mPrereq; + if( mBestNoIn==0 ){ + seenZero = 1; + seenZeroNoIN = 1; + } + } + + /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) + ** in the set of terms that apply to the current virtual table. */ + while( rc==SQLITE_OK ){ + int i; + Bitmask mNext = ALLBITS; + assert( mNext>0 ); + for(i=0; ia[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq + ); + if( mThis>mPrev && mThisprereq==mPrereq ){ + seenZero = 1; + if( bIn==0 ) seenZeroNoIN = 1; + } + } + + /* If the calls to xBestIndex() in the above loop did not find a plan + ** that requires no source tables at all (i.e. one guaranteed to be + ** usable), make a call here with all source tables disabled */ + if( rc==SQLITE_OK && seenZero==0 ){ + WHERETRACE(0x800, (" VirtualOne: all disabled\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); + if( bIn==0 ) seenZeroNoIN = 1; + } + + /* If the calls to xBestIndex() have so far failed to find a plan + ** that requires no source tables at all and does not use an IN(...) + ** operator, make a final call to obtain one here. */ + if( rc==SQLITE_OK && seenZeroNoIN==0 ){ + WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); + } + } + + if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); + freeIndexInfo(pParse->db, p); + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); + return rc; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** Add WhereLoop entries to handle OR terms. This works for either +** btrees or virtual tables. +*/ +static int whereLoopAddOr( + WhereLoopBuilder *pBuilder, + Bitmask mPrereq, + Bitmask mUnusable +){ + WhereInfo *pWInfo = pBuilder->pWInfo; + WhereClause *pWC; + WhereLoop *pNew; + WhereTerm *pTerm, *pWCEnd; + int rc = SQLITE_OK; + int iCur; + WhereClause tempWC; + WhereLoopBuilder sSubBuild; + WhereOrSet sSum, sCur; + SrcItem *pItem; + + pWC = pBuilder->pWC; + pWCEnd = pWC->a + pWC->nTerm; + pNew = pBuilder->pNew; + memset(&sSum, 0, sizeof(sSum)); + pItem = pWInfo->pTabList->a + pNew->iTab; + iCur = pItem->iCursor; + + /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */ + if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK; + + for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 + && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 + ){ + WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; + WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; + WhereTerm *pOrTerm; + int once = 1; + int i, j; + + sSubBuild = *pBuilder; + sSubBuild.pOrSet = &sCur; + + WHERETRACE(0x400, ("Begin processing OR-clause %p\n", pTerm)); + for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ + sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; + }else if( pOrTerm->leftCursor==iCur ){ + tempWC.pWInfo = pWC->pWInfo; + tempWC.pOuter = pWC; + tempWC.op = TK_AND; + tempWC.nTerm = 1; + tempWC.nBase = 1; + tempWC.a = pOrTerm; + sSubBuild.pWC = &tempWC; + }else{ + continue; + } + sCur.n = 0; +#ifdef WHERETRACE_ENABLED + WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", + (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); + if( sqlite3WhereTrace & 0x20000 ){ + sqlite3WhereClausePrint(sSubBuild.pWC); + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pItem->pTab) ){ + rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); + }else +#endif + { + rc = whereLoopAddBtree(&sSubBuild, mPrereq); + } + if( rc==SQLITE_OK ){ + rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); + } + testcase( rc==SQLITE_NOMEM && sCur.n>0 ); + testcase( rc==SQLITE_DONE ); + if( sCur.n==0 ){ + sSum.n = 0; + break; + }else if( once ){ + whereOrMove(&sSum, &sCur); + once = 0; + }else{ + WhereOrSet sPrev; + whereOrMove(&sPrev, &sSum); + sSum.n = 0; + for(i=0; inLTerm = 1; + pNew->aLTerm[0] = pTerm; + pNew->wsFlags = WHERE_MULTI_OR; + pNew->rSetup = 0; + pNew->iSortIdx = 0; + memset(&pNew->u, 0, sizeof(pNew->u)); + for(i=0; rc==SQLITE_OK && irRun = sSum.a[i].rRun + 1; + pNew->nOut = sSum.a[i].nOut; + pNew->prereq = sSum.a[i].prereq; + rc = whereLoopInsert(pBuilder, pNew); + } + WHERETRACE(0x400, ("End processing OR-clause %p\n", pTerm)); + } + } + return rc; +} + +/* +** Add all WhereLoop objects for all tables +*/ +static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo = pBuilder->pWInfo; + Bitmask mPrereq = 0; + Bitmask mPrior = 0; + int iTab; + SrcList *pTabList = pWInfo->pTabList; + SrcItem *pItem; + SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; + sqlite3 *db = pWInfo->pParse->db; + int rc = SQLITE_OK; + int bFirstPastRJ = 0; + int hasRightJoin = 0; + WhereLoop *pNew; + + + /* Loop over the tables in the join, from left to right */ + pNew = pBuilder->pNew; + + /* Verify that pNew has already been initialized */ + assert( pNew->nLTerm==0 ); + assert( pNew->wsFlags==0 ); + assert( pNew->nLSlot>=ArraySize(pNew->aLTermSpace) ); + assert( pNew->aLTerm!=0 ); + + pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; + for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; + pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; + pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); + if( bFirstPastRJ + || (pItem->fg.jointype & (JT_OUTER|JT_CROSS|JT_LTORJ))!=0 + ){ + /* Add prerequisites to prevent reordering of FROM clause terms + ** across CROSS joins and outer joins. The bFirstPastRJ boolean + ** prevents the right operand of a RIGHT JOIN from being swapped with + ** other elements even further to the right. + ** + ** The JT_LTORJ case and the hasRightJoin flag work together to + ** prevent FROM-clause terms from moving from the right side of + ** a LEFT JOIN over to the left side of that join if the LEFT JOIN + ** is itself on the left side of a RIGHT JOIN. + */ + if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; + mPrereq |= mPrior; + bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; + }else if( !hasRightJoin ){ + mPrereq = 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pItem->pTab) ){ + SrcItem *p; + for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){ + mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); + } + } + rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable); + }else +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + { + rc = whereLoopAddBtree(pBuilder, mPrereq); + } + if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){ + rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); + } + mPrior |= pNew->maskSelf; + if( rc || db->mallocFailed ){ + if( rc==SQLITE_DONE ){ + /* We hit the query planner search limit set by iPlanLimit */ + sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); + rc = SQLITE_OK; + }else{ + break; + } + } + } + + whereLoopClear(db, pNew); + return rc; +} + +/* +** Examine a WherePath (with the addition of the extra WhereLoop of the 6th +** parameters) to see if it outputs rows in the requested ORDER BY +** (or GROUP BY) without requiring a separate sort operation. Return N: +** +** N>0: N terms of the ORDER BY clause are satisfied +** N==0: No terms of the ORDER BY clause are satisfied +** N<0: Unknown yet how many terms of ORDER BY might be satisfied. +** +** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as +** strict. With GROUP BY and DISTINCT the only requirement is that +** equivalent rows appear immediately adjacent to one another. GROUP BY +** and DISTINCT do not require rows to appear in any particular order as long +** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT +** the pOrderBy terms can be matched in any order. With ORDER BY, the +** pOrderBy terms must be matched in strict left-to-right order. +*/ +static i8 wherePathSatisfiesOrderBy( + WhereInfo *pWInfo, /* The WHERE clause */ + ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ + WherePath *pPath, /* The WherePath to check */ + u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */ + u16 nLoop, /* Number of entries in pPath->aLoop[] */ + WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */ + Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */ +){ + u8 revSet; /* True if rev is known */ + u8 rev; /* Composite sort order */ + u8 revIdx; /* Index sort order */ + u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */ + u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */ + u8 isMatch; /* iColumn matches a term of the ORDER BY clause */ + u16 eqOpMask; /* Allowed equality operators */ + u16 nKeyCol; /* Number of key columns in pIndex */ + u16 nColumn; /* Total number of ordered columns in the index */ + u16 nOrderBy; /* Number terms in the ORDER BY clause */ + int iLoop; /* Index of WhereLoop in pPath being processed */ + int i, j; /* Loop counters */ + int iCur; /* Cursor number for current WhereLoop */ + int iColumn; /* A column number within table iCur */ + WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + Expr *pOBExpr; /* An expression from the ORDER BY clause */ + CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */ + Index *pIndex; /* The index associated with pLoop */ + sqlite3 *db = pWInfo->pParse->db; /* Database connection */ + Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */ + Bitmask obDone; /* Mask of all ORDER BY terms */ + Bitmask orderDistinctMask; /* Mask of all well-ordered loops */ + Bitmask ready; /* Mask of inner loops */ + + /* + ** We say the WhereLoop is "one-row" if it generates no more than one + ** row of output. A WhereLoop is one-row if all of the following are true: + ** (a) All index columns match with WHERE_COLUMN_EQ. + ** (b) The index is unique + ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row. + ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags. + ** + ** We say the WhereLoop is "order-distinct" if the set of columns from + ** that WhereLoop that are in the ORDER BY clause are different for every + ** row of the WhereLoop. Every one-row WhereLoop is automatically + ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause + ** is not order-distinct. To be order-distinct is not quite the same as being + ** UNIQUE since a UNIQUE column or index can have multiple rows that + ** are NULL and NULL values are equivalent for the purpose of order-distinct. + ** To be order-distinct, the columns must be UNIQUE and NOT NULL. + ** + ** The rowid for a table is always UNIQUE and NOT NULL so whenever the + ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is + ** automatically order-distinct. + */ + + assert( pOrderBy!=0 ); + if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; + + nOrderBy = pOrderBy->nExpr; + testcase( nOrderBy==BMS-1 ); + if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ + isOrderDistinct = 1; + obDone = MASKBIT(nOrderBy)-1; + orderDistinctMask = 0; + ready = 0; + eqOpMask = WO_EQ | WO_IS | WO_ISNULL; + if( wctrlFlags & (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MAX|WHERE_ORDERBY_MIN) ){ + eqOpMask |= WO_IN; + } + for(iLoop=0; isOrderDistinct && obSat0 ) ready |= pLoop->maskSelf; + if( iLoopaLoop[iLoop]; + if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; + }else{ + pLoop = pLast; + } + if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ + if( pLoop->u.vtab.isOrdered + && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) + ){ + obSat = obDone; + } + break; + }else if( wctrlFlags & WHERE_DISTINCTBY ){ + pLoop->u.btree.nDistinctCol = 0; + } + iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; + + /* Mark off any ORDER BY term X that is a column in the table of + ** the current loop for which there is term in the WHERE + ** clause of the form X IS NULL or X=? that reference only outer + ** loops. + */ + for(i=0; ia[i].pExpr); + if( NEVER(pOBExpr==0) ) continue; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; + if( pOBExpr->iTable!=iCur ) continue; + pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, + ~ready, eqOpMask, 0); + if( pTerm==0 ) continue; + if( pTerm->eOperator==WO_IN ){ + /* IN terms are only valid for sorting in the ORDER BY LIMIT + ** optimization, and then only if they are actually used + ** by the query plan */ + assert( wctrlFlags & + (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ); + for(j=0; jnLTerm && pTerm!=pLoop->aLTerm[j]; j++){} + if( j>=pLoop->nLTerm ) continue; + } + if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ + Parse *pParse = pWInfo->pParse; + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr); + CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); + assert( pColl1 ); + if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){ + continue; + } + testcase( pTerm->pExpr->op==TK_IS ); + } + obSat |= MASKBIT(i); + } + + if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ + if( pLoop->wsFlags & WHERE_IPK ){ + pIndex = 0; + nKeyCol = 0; + nColumn = 1; + }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ + return 0; + }else{ + nKeyCol = pIndex->nKeyCol; + nColumn = pIndex->nColumn; + assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); + assert( pIndex->aiColumn[nColumn-1]==XN_ROWID + || !HasRowid(pIndex->pTable)); + /* All relevant terms of the index must also be non-NULL in order + ** for isOrderDistinct to be true. So the isOrderDistint value + ** computed here might be a false positive. Corrections will be + ** made at tag-20210426-1 below */ + isOrderDistinct = IsUniqueIndex(pIndex) + && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; + } + + /* Loop through all columns of the index and deal with the ones + ** that are not constrained by == or IN. + */ + rev = revSet = 0; + distinctColumns = 0; + for(j=0; j=pLoop->u.btree.nEq + || (pLoop->aLTerm[j]==0)==(jnSkip) + ); + if( ju.btree.nEq && j>=pLoop->nSkip ){ + u16 eOp = pLoop->aLTerm[j]->eOperator; + + /* Skip over == and IS and ISNULL terms. (Also skip IN terms when + ** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL + ** terms imply that the index is not UNIQUE NOT NULL in which case + ** the loop need to be marked as not order-distinct because it can + ** have repeated NULL rows. + ** + ** If the current term is a column of an ((?,?) IN (SELECT...)) + ** expression for which the SELECT returns more than one column, + ** check that it is the only column used by this loop. Otherwise, + ** if it is one of two or more, none of the columns can be + ** considered to match an ORDER BY term. + */ + if( (eOp & eqOpMask)!=0 ){ + if( eOp & (WO_ISNULL|WO_IS) ){ + testcase( eOp & WO_ISNULL ); + testcase( eOp & WO_IS ); + testcase( isOrderDistinct ); + isOrderDistinct = 0; + } + continue; + }else if( ALWAYS(eOp & WO_IN) ){ + /* ALWAYS() justification: eOp is an equality operator due to the + ** ju.btree.nEq constraint above. Any equality other + ** than WO_IN is captured by the previous "if". So this one + ** always has to be WO_IN. */ + Expr *pX = pLoop->aLTerm[j]->pExpr; + for(i=j+1; iu.btree.nEq; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + assert( (pLoop->aLTerm[i]->eOperator & WO_IN) ); + bOnce = 0; + break; + } + } + } + } + + /* Get the column number in the table (iColumn) and sort order + ** (revIdx) for the j-th column of the index. + */ + if( pIndex ){ + iColumn = pIndex->aiColumn[j]; + revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC; + if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; + }else{ + iColumn = XN_ROWID; + revIdx = 0; + } + + /* An unconstrained column that might be NULL means that this + ** WhereLoop is not well-ordered. tag-20210426-1 + */ + if( isOrderDistinct ){ + if( iColumn>=0 + && j>=pLoop->u.btree.nEq + && pIndex->pTable->aCol[iColumn].notNull==0 + ){ + isOrderDistinct = 0; + } + if( iColumn==XN_EXPR ){ + isOrderDistinct = 0; + } + } + + /* Find the ORDER BY term that corresponds to the j-th column + ** of the index and mark that ORDER BY term off + */ + isMatch = 0; + for(i=0; bOnce && ia[i].pExpr); + testcase( wctrlFlags & WHERE_GROUPBY ); + testcase( wctrlFlags & WHERE_DISTINCTBY ); + if( NEVER(pOBExpr==0) ) continue; + if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; + if( iColumn>=XN_ROWID ){ + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; + if( pOBExpr->iTable!=iCur ) continue; + if( pOBExpr->iColumn!=iColumn ) continue; + }else{ + Expr *pIxExpr = pIndex->aColExpr->a[j].pExpr; + if( sqlite3ExprCompareSkip(pOBExpr, pIxExpr, iCur) ){ + continue; + } + } + if( iColumn!=XN_ROWID ){ + pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); + if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; + } + if( wctrlFlags & WHERE_DISTINCTBY ){ + pLoop->u.btree.nDistinctCol = j+1; + } + isMatch = 1; + break; + } + if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ + /* Make sure the sort order is compatible in an ORDER BY clause. + ** Sort order is irrelevant for a GROUP BY clause. */ + if( revSet ){ + if( (rev ^ revIdx) + != (pOrderBy->a[i].fg.sortFlags&KEYINFO_ORDER_DESC) + ){ + isMatch = 0; + } + }else{ + rev = revIdx ^ (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC); + if( rev ) *pRevMask |= MASKBIT(iLoop); + revSet = 1; + } + } + if( isMatch && (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL) ){ + if( j==pLoop->u.btree.nEq ){ + pLoop->wsFlags |= WHERE_BIGNULL_SORT; + }else{ + isMatch = 0; + } + } + if( isMatch ){ + if( iColumn==XN_ROWID ){ + testcase( distinctColumns==0 ); + distinctColumns = 1; + } + obSat |= MASKBIT(i); + }else{ + /* No match found */ + if( j==0 || jmaskSelf; + for(i=0; ia[i].pExpr; + mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); + if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; + if( (mTerm&~orderDistinctMask)==0 ){ + obSat |= MASKBIT(i); + } + } + } + } /* End the loop over all WhereLoops from outer-most down to inner-most */ + if( obSat==obDone ) return (i8)nOrderBy; + if( !isOrderDistinct ){ + for(i=nOrderBy-1; i>0; i--){ + Bitmask m = ALWAYS(iwctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) ); + assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); + return pWInfo->sorted; +} + +#ifdef WHERETRACE_ENABLED +/* For debugging use only: */ +static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ + static char zName[65]; + int i; + for(i=0; iaLoop[i]->cId; } + if( pLast ) zName[i++] = pLast->cId; + zName[i] = 0; + return zName; +} +#endif + +/* +** Return the cost of sorting nRow rows, assuming that the keys have +** nOrderby columns and that the first nSorted columns are already in +** order. +*/ +static LogEst whereSortingCost( + WhereInfo *pWInfo, /* Query planning context */ + LogEst nRow, /* Estimated number of rows to sort */ + int nOrderBy, /* Number of ORDER BY clause terms */ + int nSorted /* Number of initial ORDER BY terms naturally in order */ +){ + /* Estimated cost of a full external sort, where N is + ** the number of rows to sort is: + ** + ** cost = (K * N * log(N)). + ** + ** Or, if the order-by clause has X terms but only the last Y + ** terms are out of order, then block-sorting will reduce the + ** sorting cost to: + ** + ** cost = (K * N * log(N)) * (Y/X) + ** + ** The constant K is at least 2.0 but will be larger if there are a + ** large number of columns to be sorted, as the sorting time is + ** proportional to the amount of content to be sorted. The algorithm + ** does not currently distinguish between fat columns (BLOBs and TEXTs) + ** and skinny columns (INTs). It just uses the number of columns as + ** an approximation for the row width. + ** + ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort + ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert. + */ + LogEst rSortCost, nCol; + assert( pWInfo->pSelect!=0 ); + assert( pWInfo->pSelect->pEList!=0 ); + /* TUNING: sorting cost proportional to the number of output columns: */ + nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30); + rSortCost = nRow + nCol; + if( nSorted>0 ){ + /* Scale the result by (Y/X) */ + rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; + } + + /* Multiple by log(M) where M is the number of output rows. + ** Use the LIMIT for M if it is smaller. Or if this sort is for + ** a DISTINCT operator, M will be the number of distinct output + ** rows, so fudge it downwards a bit. + */ + if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){ + rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */ + if( nSorted!=0 ){ + rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */ + } + if( pWInfo->iLimitiLimit; + } + }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ + /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT + ** reduces the number of output rows by a factor of 2 */ + if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } + } + rSortCost += estLog(nRow); + return rSortCost; +} + +/* +** Given the list of WhereLoop objects at pWInfo->pLoops, this routine +** attempts to find the lowest cost path that visits each WhereLoop +** once. This path is then loaded into the pWInfo->a[].pWLoop fields. +** +** Assume that the total number of output rows that will need to be sorted +** will be nRowEst (in the 10*log2 representation). Or, ignore sorting +** costs if nRowEst==0. +** +** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation +** error occurs. +*/ +static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ + int mxChoice; /* Maximum number of simultaneous paths tracked */ + int nLoop; /* Number of terms in the join */ + Parse *pParse; /* Parsing context */ + int iLoop; /* Loop counter over the terms of the join */ + int ii, jj; /* Loop counters */ + int mxI = 0; /* Index of next entry to replace */ + int nOrderBy; /* Number of ORDER BY clause terms */ + LogEst mxCost = 0; /* Maximum cost of a set of paths */ + LogEst mxUnsorted = 0; /* Maximum unsorted cost of a set of path */ + int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ + WherePath *aFrom; /* All nFrom paths at the previous level */ + WherePath *aTo; /* The nTo best paths at the current level */ + WherePath *pFrom; /* An element of aFrom[] that we are working on */ + WherePath *pTo; /* An element of aTo[] that we are working on */ + WhereLoop *pWLoop; /* One of the WhereLoop objects */ + WhereLoop **pX; /* Used to divy up the pSpace memory */ + LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ + char *pSpace; /* Temporary memory used by this routine */ + int nSpace; /* Bytes of space allocated at pSpace */ + + pParse = pWInfo->pParse; + nLoop = pWInfo->nLevel; + /* TUNING: For simple queries, only the best path is tracked. + ** For 2-way joins, the 5 best paths are followed. + ** For joins of 3 or more tables, track the 10 best paths */ + mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); + assert( nLoop<=pWInfo->pTabList->nSrc ); + WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", + nRowEst, pParse->nQueryLoop)); + + /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this + ** case the purpose of this call is to estimate the number of rows returned + ** by the overall query. Once this estimate has been obtained, the caller + ** will invoke this function a second time, passing the estimate as the + ** nRowEst parameter. */ + if( pWInfo->pOrderBy==0 || nRowEst==0 ){ + nOrderBy = 0; + }else{ + nOrderBy = pWInfo->pOrderBy->nExpr; + } + + /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ + nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; + nSpace += sizeof(LogEst) * nOrderBy; + pSpace = sqlite3StackAllocRawNN(pParse->db, nSpace); + if( pSpace==0 ) return SQLITE_NOMEM_BKPT; + aTo = (WherePath*)pSpace; + aFrom = aTo+mxChoice; + memset(aFrom, 0, sizeof(aFrom[0])); + pX = (WhereLoop**)(aFrom+mxChoice); + for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){ + pFrom->aLoop = pX; + } + if( nOrderBy ){ + /* If there is an ORDER BY clause and it is not being ignored, set up + ** space for the aSortCost[] array. Each element of the aSortCost array + ** is either zero - meaning it has not yet been initialized - or the + ** cost of sorting nRowEst rows of data where the first X terms of + ** the ORDER BY clause are already in order, where X is the array + ** index. */ + aSortCost = (LogEst*)pX; + memset(aSortCost, 0, sizeof(LogEst) * nOrderBy); + } + assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] ); + assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX ); + + /* Seed the search with a single WherePath containing zero WhereLoops. + ** + ** TUNING: Do not let the number of iterations go above 28. If the cost + ** of computing an automatic index is not paid back within the first 28 + ** rows, then do not use the automatic index. */ + aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); + nFrom = 1; + assert( aFrom[0].isOrdered==0 ); + if( nOrderBy ){ + /* If nLoop is zero, then there are no FROM terms in the query. Since + ** in this case the query may return a maximum of one row, the results + ** are already in the requested order. Set isOrdered to nOrderBy to + ** indicate this. Or, if nLoop is greater than zero, set isOrdered to + ** -1, indicating that the result set may or may not be ordered, + ** depending on the loops added to the current plan. */ + aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy; + } + + /* Compute successively longer WherePaths using the previous generation + ** of WherePaths as the basis for the next. Keep track of the mxChoice + ** best paths at each generation */ + for(iLoop=0; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ + LogEst rCost; /* Cost of path (pFrom+pWLoop) */ + LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ + i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */ + Bitmask maskNew; /* Mask of src visited by (..) */ + Bitmask revMask; /* Mask of rev-order loops for (..) */ + + if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; + if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; + if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ + /* Do not use an automatic index if the this loop is expected + ** to run less than 1.25 times. It is tempting to also exclude + ** automatic index usage on an outer loop, but sometimes an automatic + ** index is useful in the outer loop of a correlated subquery. */ + assert( 10==sqlite3LogEst(2) ); + continue; + } + + /* At this point, pWLoop is a candidate to be the next loop. + ** Compute its cost */ + rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); + rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); + nOut = pFrom->nRow + pWLoop->nOut; + maskNew = pFrom->maskLoop | pWLoop->maskSelf; + isOrdered = pFrom->isOrdered; + if( isOrdered<0 ){ + revMask = 0; + isOrdered = wherePathSatisfiesOrderBy(pWInfo, + pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, + iLoop, pWLoop, &revMask); + }else{ + revMask = pFrom->revLoop; + } + if( isOrdered>=0 && isOrderedisOrdered^isOrdered)&0x80)==0" is equivalent + ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range + ** of legal values for isOrdered, -1..64. + */ + for(jj=0, pTo=aTo; jjmaskLoop==maskNew + && ((pTo->isOrdered^isOrdered)&0x80)==0 + ){ + testcase( jj==nTo-1 ); + break; + } + } + if( jj>=nTo ){ + /* None of the existing best-so-far paths match the candidate. */ + if( nTo>=mxChoice + && (rCost>mxCost || (rCost==mxCost && rUnsorted>=mxUnsorted)) + ){ + /* The current candidate is no better than any of the mxChoice + ** paths currently in the best-so-far buffer. So discard + ** this candidate as not viable. */ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, + isOrdered>=0 ? isOrdered+'0' : '?'); + } +#endif + continue; + } + /* If we reach this points it means that the new candidate path + ** needs to be added to the set of best-so-far paths. */ + if( nTo=0 ? isOrdered+'0' : '?'); + } +#endif + }else{ + /* Control reaches here if best-so-far path pTo=aTo[jj] covers the + ** same set of loops and has the same isOrdered setting as the + ** candidate path. Check to see if the candidate should replace + ** pTo or if the candidate should be skipped. + ** + ** The conditional is an expanded vector comparison equivalent to: + ** (pTo->rCost,pTo->nRow,pTo->rUnsorted) <= (rCost,nOut,rUnsorted) + */ + if( pTo->rCostrCost==rCost + && (pTo->nRownRow==nOut && pTo->rUnsorted<=rUnsorted) + ) + ) + ){ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( + "Skip %s cost=%-3d,%3d,%3d order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, + isOrdered>=0 ? isOrdered+'0' : '?'); + sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); + } +#endif + /* Discard the candidate path from further consideration */ + testcase( pTo->rCost==rCost ); + continue; + } + testcase( pTo->rCost==rCost+1 ); + /* Control reaches here if the candidate path is better than the + ** pTo path. Replace pTo with the candidate. */ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( + "Update %s cost=%-3d,%3d,%3d order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, + isOrdered>=0 ? isOrdered+'0' : '?'); + sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); + } +#endif + } + /* pWLoop is a winner. Add it to the set of best so far */ + pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; + pTo->revLoop = revMask; + pTo->nRow = nOut; + pTo->rCost = rCost; + pTo->rUnsorted = rUnsorted; + pTo->isOrdered = isOrdered; + memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); + pTo->aLoop[iLoop] = pWLoop; + if( nTo>=mxChoice ){ + mxI = 0; + mxCost = aTo[0].rCost; + mxUnsorted = aTo[0].nRow; + for(jj=1, pTo=&aTo[1]; jjrCost>mxCost + || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted) + ){ + mxCost = pTo->rCost; + mxUnsorted = pTo->rUnsorted; + mxI = jj; + } + } + } + } + } + +#ifdef WHERETRACE_ENABLED /* >=2 */ + if( sqlite3WhereTrace & 0x02 ){ + sqlite3DebugPrintf("---- after round %d ----\n", iLoop); + for(ii=0, pTo=aTo; iirCost, pTo->nRow, + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); + if( pTo->isOrdered>0 ){ + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + }else{ + sqlite3DebugPrintf("\n"); + } + } + } +#endif + + /* Swap the roles of aFrom and aTo for the next generation */ + pFrom = aTo; + aTo = aFrom; + aFrom = pFrom; + nFrom = nTo; + } + + if( nFrom==0 ){ + sqlite3ErrorMsg(pParse, "no query solution"); + sqlite3StackFreeNN(pParse->db, pSpace); + return SQLITE_ERROR; + } + + /* Find the lowest cost path. pFrom will be left pointing to that path */ + pFrom = aFrom; + for(ii=1; iirCost>aFrom[ii].rCost ) pFrom = &aFrom[ii]; + } + assert( pWInfo->nLevel==nLoop ); + /* Load the lowest cost path into pWInfo */ + for(iLoop=0; iLoopa + iLoop; + pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; + pLevel->iFrom = pWLoop->iTab; + pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; + } + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 + && pWInfo->eDistinct==WHERE_DISTINCT_NOOP + && nRowEst + ){ + Bitmask notUsed; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, + WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); + if( rc==pWInfo->pResultSet->nExpr ){ + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } + } + pWInfo->bOrderedInnerLoop = 0; + if( pWInfo->pOrderBy ){ + pWInfo->nOBSat = pFrom->isOrdered; + if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ + if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } + if( pWInfo->pSelect->pOrderBy + && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){ + pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr; + } + }else{ + pWInfo->revMask = pFrom->revLoop; + if( pWInfo->nOBSat<=0 ){ + pWInfo->nOBSat = 0; + if( nLoop>0 ){ + u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; + if( (wsFlags & WHERE_ONEROW)==0 + && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) + ){ + Bitmask m = 0; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, + WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); + testcase( wsFlags & WHERE_IPK ); + testcase( wsFlags & WHERE_COLUMN_IN ); + if( rc==pWInfo->pOrderBy->nExpr ){ + pWInfo->bOrderedInnerLoop = 1; + pWInfo->revMask = m; + } + } + } + }else if( nLoop + && pWInfo->nOBSat==1 + && (pWInfo->wctrlFlags & (WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX))!=0 + ){ + pWInfo->bOrderedInnerLoop = 1; + } + } + if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) + && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 + ){ + Bitmask revMask = 0; + int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, + pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask + ); + assert( pWInfo->sorted==0 ); + if( nOrder==pWInfo->pOrderBy->nExpr ){ + pWInfo->sorted = 1; + pWInfo->revMask = revMask; + } + } + } + + + pWInfo->nRowOut = pFrom->nRow; + + /* Free temporary memory and return success */ + sqlite3StackFreeNN(pParse->db, pSpace); + return SQLITE_OK; +} + +/* +** Most queries use only a single table (they are not joins) and have +** simple == constraints against indexed fields. This routine attempts +** to plan those simple cases using much less ceremony than the +** general-purpose query planner, and thereby yield faster sqlite3_prepare() +** times for the common case. +** +** Return non-zero on success, if this query can be handled by this +** no-frills query planner. Return zero if this query needs the +** general-purpose query planner. +*/ +static int whereShortCut(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo; + SrcItem *pItem; + WhereClause *pWC; + WhereTerm *pTerm; + WhereLoop *pLoop; + int iCur; + int j; + Table *pTab; + Index *pIdx; + WhereScan scan; + + pWInfo = pBuilder->pWInfo; + if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; + assert( pWInfo->pTabList->nSrc>=1 ); + pItem = pWInfo->pTabList->a; + pTab = pItem->pTab; + if( IsVirtual(pTab) ) return 0; + if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ + testcase( pItem->fg.isIndexedBy ); + testcase( pItem->fg.notIndexed ); + return 0; + } + iCur = pItem->iCursor; + pWC = &pWInfo->sWC; + pLoop = pBuilder->pNew; + pLoop->wsFlags = 0; + pLoop->nSkip = 0; + pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0); + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); + if( pTerm ){ + testcase( pTerm->eOperator & WO_IS ); + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; + pLoop->aLTerm[0] = pTerm; + pLoop->nLTerm = 1; + pLoop->u.btree.nEq = 1; + /* TUNING: Cost of a rowid lookup is 10 */ + pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ + }else{ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int opMask; + assert( pLoop->aLTermSpace==pLoop->aLTerm ); + if( !IsUniqueIndex(pIdx) + || pIdx->pPartIdxWhere!=0 + || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) + ) continue; + opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ; + for(j=0; jnKeyCol; j++){ + pTerm = whereScanInit(&scan, pWC, iCur, j, opMask, pIdx); + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); + if( pTerm==0 ) break; + testcase( pTerm->eOperator & WO_IS ); + pLoop->aLTerm[j] = pTerm; + } + if( j!=pIdx->nKeyCol ) continue; + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; + if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){ + pLoop->wsFlags |= WHERE_IDX_ONLY; + } + pLoop->nLTerm = j; + pLoop->u.btree.nEq = j; + pLoop->u.btree.pIndex = pIdx; + /* TUNING: Cost of a unique index lookup is 15 */ + pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */ + break; + } + } + if( pLoop->wsFlags ){ + pLoop->nOut = (LogEst)1; + pWInfo->a[0].pWLoop = pLoop; + assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] ); + pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */ + pWInfo->a[0].iTabCur = iCur; + pWInfo->nRowOut = 1; + if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } + if( scan.iEquiv>1 ) pLoop->wsFlags |= WHERE_TRANSCONS; +#ifdef SQLITE_DEBUG + pLoop->cId = '0'; +#endif +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x02 ){ + sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); + } +#endif + return 1; + } + return 0; +} + +/* +** Helper function for exprIsDeterministic(). +*/ +static int exprNodeIsDeterministic(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_ConstFunc)==0 ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Continue; +} + +/* +** Return true if the expression contains no non-deterministic SQL +** functions. Do not consider non-deterministic SQL functions that are +** part of sub-select statements. +*/ +static int exprIsDeterministic(Expr *p){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = 1; + w.xExprCallback = exprNodeIsDeterministic; + w.xSelectCallback = sqlite3SelectWalkFail; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + + +#ifdef WHERETRACE_ENABLED +/* +** Display all WhereLoops in pWInfo +*/ +static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ + if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ + WhereLoop *p; + int i; + static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" + "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; + for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ + p->cId = zLabel[i%(sizeof(zLabel)-1)]; + sqlite3WhereLoopPrint(p, pWC); + } + } +} +# define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C) +#else +# define WHERETRACE_ALL_LOOPS(W,C) +#endif + +/* Attempt to omit tables from a join that do not affect the result. +** For a table to not affect the result, the following must be true: +** +** 1) The query must not be an aggregate. +** 2) The table must be the RHS of a LEFT JOIN. +** 3) Either the query must be DISTINCT, or else the ON or USING clause +** must contain a constraint that limits the scan of the table to +** at most a single row. +** 4) The table must not be referenced by any part of the query apart +** from its own USING or ON clause. +** 5) The table must not have an inner-join ON or USING clause if there is +** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause +** might move from the right side to the left side of the RIGHT JOIN. +** Note: Due to (2), this condition can only arise if the table is +** the right-most table of a subquery that was flattened into the +** main query and that subquery was the right-hand operand of an +** inner join that held an ON or USING clause. +** +** For example, given: +** +** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); +** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); +** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); +** +** then table t2 can be omitted from the following: +** +** SELECT v1, v3 FROM t1 +** LEFT JOIN t2 ON (t1.ipk=t2.ipk) +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +** +** or from: +** +** SELECT DISTINCT v1, v3 FROM t1 +** LEFT JOIN t2 +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +*/ +static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( + WhereInfo *pWInfo, + Bitmask notReady +){ + int i; + Bitmask tabUsed; + int hasRightJoin; + + /* Preconditions checked by the caller */ + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_OmitNoopJoin) ); + + /* These two preconditions checked by the caller combine to guarantee + ** condition (1) of the header comment */ + assert( pWInfo->pResultSet!=0 ); + assert( 0==(pWInfo->wctrlFlags & WHERE_AGG_DISTINCT) ); + + tabUsed = sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pResultSet); + if( pWInfo->pOrderBy ){ + tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); + } + hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; + for(i=pWInfo->nLevel-1; i>=1; i--){ + WhereTerm *pTerm, *pEnd; + SrcItem *pItem; + WhereLoop *pLoop; + pLoop = pWInfo->a[i].pWLoop; + pItem = &pWInfo->pTabList->a[pLoop->iTab]; + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 + && (pLoop->wsFlags & WHERE_ONEROW)==0 + ){ + continue; + } + if( (tabUsed & pLoop->maskSelf)!=0 ) continue; + pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON) + || pTerm->pExpr->w.iJoin!=pItem->iCursor + ){ + break; + } + } + if( hasRightJoin + && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && pTerm->pExpr->w.iJoin==pItem->iCursor + ){ + break; /* restriction (5) */ + } + } + if( pTerm drop loop %c not used\n", pLoop->cId)); + notReady &= ~pLoop->maskSelf; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + pTerm->wtFlags |= TERM_CODED; + } + } + if( i!=pWInfo->nLevel-1 ){ + int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); + memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); + } + pWInfo->nLevel--; + assert( pWInfo->nLevel>0 ); + } + return notReady; +} + +/* +** Check to see if there are any SEARCH loops that might benefit from +** using a Bloom filter. Consider a Bloom filter if: +** +** (1) The SEARCH happens more than N times where N is the number +** of rows in the table that is being considered for the Bloom +** filter. +** (2) Some searches are expected to find zero rows. (This is determined +** by the WHERE_SELFCULL flag on the term.) +** (3) Bloom-filter processing is not disabled. (Checked by the +** caller.) +** (4) The size of the table being searched is known by ANALYZE. +** +** This block of code merely checks to see if a Bloom filter would be +** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the +** WhereLoop. The implementation of the Bloom filter comes further +** down where the code for each WhereLoop is generated. +*/ +static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( + const WhereInfo *pWInfo +){ + int i; + LogEst nSearch = 0; + + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); + for(i=0; inLevel; i++){ + WhereLoop *pLoop = pWInfo->a[i].pWLoop; + const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); + SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; + Table *pTab = pItem->pTab; + if( (pTab->tabFlags & TF_HasStat1)==0 ) break; + pTab->tabFlags |= TF_StatsUsed; + if( i>=1 + && (pLoop->wsFlags & reqFlags)==reqFlags + /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ + && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) + ){ + if( nSearch > pTab->nRowLogEst ){ + testcase( pItem->fg.jointype & JT_LEFT ); + pLoop->wsFlags |= WHERE_BLOOMFILTER; + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + WHERETRACE(0xffffffff, ( + "-> use Bloom-filter on loop %c because there are ~%.1e " + "lookups into %s which has only ~%.1e rows\n", + pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, + (double)sqlite3LogEstToInt(pTab->nRowLogEst))); + } + } + nSearch += pLoop->nOut; + } +} + +/* +** The index pIdx is used by a query and contains one or more expressions. +** In other words pIdx is an index on an expression. iIdxCur is the cursor +** number for the index and iDataCur is the cursor number for the corresponding +** table. +** +** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for +** each of the expressions in the index so that the expression code generator +** will know to replace occurrences of the indexed expression with +** references to the corresponding column of the index. +*/ +static SQLITE_NOINLINE void whereAddIndexedExpr( + Parse *pParse, /* Add IndexedExpr entries to pParse->pIdxEpr */ + Index *pIdx, /* The index-on-expression that contains the expressions */ + int iIdxCur, /* Cursor number for pIdx */ + SrcItem *pTabItem /* The FROM clause entry for the table */ +){ + int i; + IndexedExpr *p; + Table *pTab; + assert( pIdx->bHasExpr ); + pTab = pIdx->pTable; + for(i=0; inColumn; i++){ + Expr *pExpr; + int j = pIdx->aiColumn[i]; + if( j==XN_EXPR ){ + pExpr = pIdx->aColExpr->a[i].pExpr; + }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ + pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); + }else{ + continue; + } + if( sqlite3ExprIsConstant(pExpr) ) continue; + if( pExpr->op==TK_FUNCTION ){ + /* Functions that might set a subtype should not be replaced by the + ** value taken from an expression index since the index omits the + ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ + int n; + FuncDef *pDef; + sqlite3 *db = pParse->db; + assert( ExprUseXList(pExpr) ); + n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + continue; + } + } + p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); + if( p==0 ) break; + p->pIENext = pParse->pIdxEpr; +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x200 ){ + sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i); + if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr); + } +#endif + p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + p->iDataCur = pTabItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = i; + p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; + if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ + p->aff = pIdx->zColAff[i]; + } +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + p->zIdxName = pIdx->zName; +#endif + pParse->pIdxEpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxEpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } +} + +/* +** Set the reverse-scan order mask to one for all tables in the query +** with the exception of MATERIALIZED common table expressions that have +** their own internal ORDER BY clauses. +** +** This implements the PRAGMA reverse_unordered_selects=ON setting. +** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER). +*/ +static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ + int ii; + for(ii=0; iipTabList->nSrc; ii++){ + SrcItem *pItem = &pWInfo->pTabList->a[ii]; + if( !pItem->fg.isCte + || pItem->u2.pCteUse->eM10d!=M10d_Yes + || NEVER(pItem->pSelect==0) + || pItem->pSelect->pOrderBy==0 + ){ + pWInfo->revMask |= MASKBIT(ii); + } + } +} + +/* +** Generate the beginning of the loop used for WHERE clause processing. +** The return value is a pointer to an opaque structure that contains +** information needed to terminate the loop. Later, the calling routine +** should invoke sqlite3WhereEnd() with the return value of this function +** in order to complete the WHERE clause processing. +** +** If an error occurs, this routine returns NULL. +** +** The basic idea is to do a nested loop, one loop for each table in +** the FROM clause of a select. (INSERT and UPDATE statements are the +** same as a SELECT with only a single table in the FROM clause.) For +** example, if the SQL is this: +** +** SELECT * FROM t1, t2, t3 WHERE ...; +** +** Then the code generated is conceptually like the following: +** +** foreach row1 in t1 do \ Code generated +** foreach row2 in t2 do |-- by sqlite3WhereBegin() +** foreach row3 in t3 do / +** ... +** end \ Code generated +** end |-- by sqlite3WhereEnd() +** end / +** +** Note that the loops might not be nested in the order in which they +** appear in the FROM clause if a different order is better able to make +** use of indices. Note also that when the IN operator appears in +** the WHERE clause, it might result in additional nested loops for +** scanning through all values on the right-hand side of the IN. +** +** There are Btree cursors associated with each table. t1 uses cursor +** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. +** And so forth. This routine generates code to open those VDBE cursors +** and sqlite3WhereEnd() generates the code to close them. +** +** The code that sqlite3WhereBegin() generates leaves the cursors named +** in pTabList pointing at their appropriate entries. The [...] code +** can use OP_Column and OP_Rowid opcodes on these cursors to extract +** data from the various tables of the loop. +** +** If the WHERE clause is empty, the foreach loops must each scan their +** entire tables. Thus a three-way join is an O(N^3) operation. But if +** the tables have indices and there are terms in the WHERE clause that +** refer to those indices, a complete table scan can be avoided and the +** code will run much faster. Most of the work of this routine is checking +** to see if there are indices that can be used to speed up the loop. +** +** Terms of the WHERE clause are also used to limit which rows actually +** make it to the "..." in the middle of the loop. After each "foreach", +** terms of the WHERE clause that use only terms in that loop and outer +** loops are evaluated and if false a jump is made around all subsequent +** inner loops (or around the "..." if the test occurs within the inner- +** most loop) +** +** OUTER JOINS +** +** An outer join of tables t1 and t2 is conceptually coded as follows: +** +** foreach row1 in t1 do +** flag = 0 +** foreach row2 in t2 do +** start: +** ... +** flag = 1 +** end +** if flag==0 then +** move the row2 cursor to a null row +** goto start +** fi +** end +** +** ORDER BY CLAUSE PROCESSING +** +** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause +** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement +** if there is one. If there is no ORDER BY clause or if this routine +** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. +** +** The iIdxCur parameter is the cursor number of an index. If +** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index +** to use for OR clause processing. The WHERE clause should use this +** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is +** the first cursor in an array of cursors for all indices. iIdxCur should +** be used to compute the appropriate cursor depending on which index is +** used. +*/ +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ + Expr *pWhere, /* The WHERE clause */ + ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ + ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ + Select *pSelect, /* The entire SELECT statement */ + u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ + int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number + ** If WHERE_USE_LIMIT, then the limit amount */ +){ + int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ + int nTabList; /* Number of elements in pTabList */ + WhereInfo *pWInfo; /* Will become the return value of this function */ + Vdbe *v = pParse->pVdbe; /* The virtual database engine */ + Bitmask notReady; /* Cursors that are not yet positioned */ + WhereLoopBuilder sWLB; /* The WhereLoop builder */ + WhereMaskSet *pMaskSet; /* The expression mask set */ + WhereLevel *pLevel; /* A single level in pWInfo->a[] */ + WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ + int ii; /* Loop counter */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code */ + u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */ + + assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( + (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + )); + + /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */ + assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + || (wctrlFlags & WHERE_USE_LIMIT)==0 ); + + /* Variable initialization */ + db = pParse->db; + memset(&sWLB, 0, sizeof(sWLB)); + + /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ + testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); + if( pOrderBy && pOrderBy->nExpr>=BMS ){ + pOrderBy = 0; + wctrlFlags &= ~WHERE_WANT_DISTINCT; + } + + /* The number of tables in the FROM clause is limited by the number of + ** bits in a Bitmask + */ + testcase( pTabList->nSrc==BMS ); + if( pTabList->nSrc>BMS ){ + sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); + return 0; + } + + /* This function normally generates a nested loop for all tables in + ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should + ** only generate code for the first table in pTabList and assume that + ** any cursors associated with subsequent tables are uninitialized. + */ + nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc; + + /* Allocate and initialize the WhereInfo structure that will become the + ** return value. A single allocation is used to store the WhereInfo + ** struct, the contents of WhereInfo.a[], the WhereClause structure + ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte + ** field (type Bitmask) it must be aligned on an 8-byte boundary on + ** some architectures. Hence the ROUND8() below. + */ + nByteWInfo = ROUND8P(sizeof(WhereInfo)); + if( nTabList>1 ){ + nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); + } + pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); + if( db->mallocFailed ){ + sqlite3DbFree(db, pWInfo); + pWInfo = 0; + goto whereBeginError; + } + pWInfo->pParse = pParse; + pWInfo->pTabList = pTabList; + pWInfo->pOrderBy = pOrderBy; +#if WHERETRACE_ENABLED + pWInfo->pWhere = pWhere; +#endif + pWInfo->pResultSet = pResultSet; + pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; + pWInfo->nLevel = nTabList; + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse); + pWInfo->wctrlFlags = wctrlFlags; + pWInfo->iLimit = iAuxArg; + pWInfo->savedNQueryLoop = pParse->nQueryLoop; + pWInfo->pSelect = pSelect; + memset(&pWInfo->nOBSat, 0, + offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); + memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); + assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ + pMaskSet = &pWInfo->sMaskSet; + pMaskSet->n = 0; + pMaskSet->ix[0] = -99; /* Initialize ix[0] to a value that can never be + ** a valid cursor number, to avoid an initial + ** test for pMaskSet->n==0 in sqlite3WhereGetMask() */ + sWLB.pWInfo = pWInfo; + sWLB.pWC = &pWInfo->sWC; + sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); + assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) ); + whereLoopInit(sWLB.pNew); +#ifdef SQLITE_DEBUG + sWLB.pNew->cId = '*'; +#endif + + /* Split the WHERE clause into separate subexpressions where each + ** subexpression is separated by an AND operator. + */ + sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); + sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); + + /* Special case: No FROM clause + */ + if( nTabList==0 ){ + if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; + if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && OptimizationEnabled(db, SQLITE_DistinctOpt) + ){ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } + ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + }else{ + /* Assign a bit from the bitmask to every term in the FROM clause. + ** + ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in + ** pTabList, not just the first nTabList tables. nTabList is normally + ** equal to pTabList->nSrc but might be shortened to 1 if the + ** WHERE_OR_SUBCLAUSE flag is set. + */ + ii = 0; + do{ + createMask(pMaskSet, pTabList->a[ii].iCursor); + sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); + }while( (++ii)nSrc ); + #ifdef SQLITE_DEBUG + { + Bitmask mx = 0; + for(ii=0; iinSrc; ii++){ + Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); + assert( m>=mx ); + mx = m; + } + } + #endif + } + + /* Analyze all of the subexpressions. */ + sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); + if( pSelect && pSelect->pLimit ){ + sqlite3WhereAddLimit(&pWInfo->sWC, pSelect); + } + if( pParse->nErr ) goto whereBeginError; + + /* The False-WHERE-Term-Bypass optimization: + ** + ** If there are WHERE terms that are false, then no rows will be output, + ** so skip over all of the code generated here. + ** + ** Conditions: + ** + ** (1) The WHERE term must not refer to any tables in the join. + ** (2) The term must not come from an ON clause on the + ** right-hand side of a LEFT or FULL JOIN. + ** (3) The term must not come from an ON clause, or there must be + ** no RIGHT or FULL OUTER joins in pTabList. + ** (4) If the expression contains non-deterministic functions + ** that are not within a sub-select. This is not required + ** for correctness but rather to preserves SQLite's legacy + ** behaviour in the following two cases: + ** + ** WHERE random()>0; -- eval random() once per row + ** WHERE (SELECT random())>0; -- eval random() just once overall + ** + ** Note that the Where term need not be a constant in order for this + ** optimization to apply, though it does need to be constant relative to + ** the current subquery (condition 1). The term might include variables + ** from outer queries so that the value of the term changes from one + ** invocation of the current subquery to the next. + */ + for(ii=0; iinBase; ii++){ + WhereTerm *pT = &sWLB.pWC->a[ii]; /* A term of the WHERE clause */ + Expr *pX; /* The expression of pT */ + if( pT->wtFlags & TERM_VIRTUAL ) continue; + pX = pT->pExpr; + assert( pX!=0 ); + assert( pT->prereqAll!=0 || !ExprHasProperty(pX, EP_OuterON) ); + if( pT->prereqAll==0 /* Conditions (1) and (2) */ + && (nTabList==0 || exprIsDeterministic(pX)) /* Condition (4) */ + && !(ExprHasProperty(pX, EP_InnerON) /* Condition (3) */ + && (pTabList->a[0].fg.jointype & JT_LTORJ)!=0 ) + ){ + sqlite3ExprIfFalse(pParse, pX, pWInfo->iBreak, SQLITE_JUMPIFNULL); + pT->wtFlags |= TERM_CODED; + } + } + + if( wctrlFlags & WHERE_WANT_DISTINCT ){ + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + wctrlFlags &= ~WHERE_WANT_DISTINCT; + pWInfo->wctrlFlags &= ~WHERE_WANT_DISTINCT; + }else if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ + /* The DISTINCT marking is pointless. Ignore it. */ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + }else if( pOrderBy==0 ){ + /* Try to ORDER BY the result set to make distinct processing easier */ + pWInfo->wctrlFlags |= WHERE_DISTINCTBY; + pWInfo->pOrderBy = pResultSet; + } + } + + /* Construct the WhereLoop objects */ +#if defined(WHERETRACE_ENABLED) + if( sqlite3WhereTrace & 0xffffffff ){ + sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); + if( wctrlFlags & WHERE_USE_LIMIT ){ + sqlite3DebugPrintf(", limit: %d", iAuxArg); + } + sqlite3DebugPrintf(")\n"); + if( sqlite3WhereTrace & 0x8000 ){ + Select sSelect; + memset(&sSelect, 0, sizeof(sSelect)); + sSelect.selFlags = SF_WhereBegin; + sSelect.pSrc = pTabList; + sSelect.pWhere = pWhere; + sSelect.pOrderBy = pOrderBy; + sSelect.pEList = pResultSet; + sqlite3TreeViewSelect(0, &sSelect, 0); + } + if( sqlite3WhereTrace & 0x4000 ){ /* Display all WHERE clause terms */ + sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); + } + } +#endif + + if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + +#ifdef SQLITE_ENABLE_STAT4 + /* If one or more WhereTerm.truthProb values were used in estimating + ** loop parameters, but then those truthProb values were subsequently + ** changed based on STAT4 information while computing subsequent loops, + ** then we need to rerun the whole loop building process so that all + ** loops will be built using the revised truthProb values. */ + if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ + WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); + WHERETRACE(0xffffffff, + ("**** Redo all loop computations due to" + " TERM_HIGHTRUTH changes ****\n")); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + } +#endif + WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); + + wherePathSolver(pWInfo, 0); + if( db->mallocFailed ) goto whereBeginError; + if( pWInfo->pOrderBy ){ + wherePathSolver(pWInfo, pWInfo->nRowOut+1); + if( db->mallocFailed ) goto whereBeginError; + } + + /* TUNING: Assume that a DISTINCT clause on a subquery reduces + ** the output size by a factor of 8 (LogEst -30). + */ + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ + WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", + pWInfo->nRowOut, pWInfo->nRowOut-30)); + pWInfo->nRowOut -= 30; + } + + } + assert( pWInfo->pTabList!=0 ); + if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ + whereReverseScanOrder(pWInfo); + } + if( pParse->nErr ){ + goto whereBeginError; + } + assert( db->mallocFailed==0 ); +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace ){ + sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); + if( pWInfo->nOBSat>0 ){ + sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); + } + switch( pWInfo->eDistinct ){ + case WHERE_DISTINCT_UNIQUE: { + sqlite3DebugPrintf(" DISTINCT=unique"); + break; + } + case WHERE_DISTINCT_ORDERED: { + sqlite3DebugPrintf(" DISTINCT=ordered"); + break; + } + case WHERE_DISTINCT_UNORDERED: { + sqlite3DebugPrintf(" DISTINCT=unordered"); + break; + } + } + sqlite3DebugPrintf("\n"); + for(ii=0; iinLevel; ii++){ + sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); + } + } +#endif + + /* Attempt to omit tables from a join that do not affect the result. + ** See the comment on whereOmitNoopJoin() for further information. + ** + ** This query optimization is factored out into a separate "no-inline" + ** procedure to keep the sqlite3WhereBegin() procedure from becoming + ** too large. If sqlite3WhereBegin() becomes too large, that prevents + ** some C-compiler optimizers from in-lining the + ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to + ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. + */ + notReady = ~(Bitmask)0; + if( pWInfo->nLevel>=2 + && pResultSet!=0 /* these two combine to guarantee */ + && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */ + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) + ){ + notReady = whereOmitNoopJoin(pWInfo, notReady); + nTabList = pWInfo->nLevel; + assert( nTabList>0 ); + } + + /* Check to see if there are any SEARCH loops that might benefit from + ** using a Bloom filter. + */ + if( pWInfo->nLevel>=2 + && OptimizationEnabled(db, SQLITE_BloomFilter) + ){ + whereCheckIfBloomFilterIsUseful(pWInfo); + } + +#if defined(WHERETRACE_ENABLED) + if( sqlite3WhereTrace & 0x4000 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); + } + WHERETRACE(0xffffffff,("*** Optimizer Finished ***\n")); +#endif + pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; + + /* If the caller is an UPDATE or DELETE statement that is requesting + ** to use a one-pass algorithm, determine if this is appropriate. + ** + ** A one-pass approach can be used if the caller has requested one + ** and either (a) the scan visits at most one row or (b) each + ** of the following are true: + ** + ** * the caller has indicated that a one-pass approach can be used + ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and + ** * the table is not a virtual table, and + ** * either the scan does not use the OR optimization or the caller + ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified + ** for DELETE). + ** + ** The last qualification is because an UPDATE statement uses + ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can + ** use a one-pass approach, and this is not set accurately for scans + ** that use the OR optimization. + */ + assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); + if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ + int wsFlags = pWInfo->a[0].pWLoop->wsFlags; + int bOnerow = (wsFlags & WHERE_ONEROW)!=0; + assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) ); + if( bOnerow || ( + 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) + && !IsVirtual(pTabList->a[0].pTab) + && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) + && OptimizationEnabled(db, SQLITE_OnePass) + )){ + pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; + if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ + if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ + bFordelete = OPFLAG_FORDELETE; + } + pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY); + } + } + } + + /* Open all tables in the pTabList and any indices selected for + ** searching those tables. + */ + for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; + pTab = pTabItem->pTab; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pLoop = pLevel->pWLoop; + if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ + /* Do nothing */ + }else +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + int iCur = pTabItem->iCursor; + sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); + }else if( IsVirtual(pTab) ){ + /* noop */ + }else +#endif + if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0) + || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0 + ){ + int op = OP_OpenRead; + if( pWInfo->eOnePass!=ONEPASS_OFF ){ + op = OP_OpenWrite; + pWInfo->aiCurOnePass[0] = pTabItem->iCursor; + }; + sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + assert( pTabItem->iCursor==pLevel->iTabCur ); + testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); + testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); + if( pWInfo->eOnePass==ONEPASS_OFF + && pTab->nColtabFlags & (TF_HasGenerated|TF_WithoutRowid))==0 + && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0 + ){ + /* If we know that only a prefix of the record will be used, + ** it is advantageous to reduce the "column count" field in + ** the P4 operand of the OP_OpenRead/Write opcode. */ + Bitmask b = pTabItem->colUsed; + int n = 0; + for(; b; b=b>>1, n++){} + sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32); + assert( n<=pTab->nCol ); + } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + if( pLoop->u.btree.pIndex!=0 && (pTab->tabFlags & TF_WithoutRowid)==0 ){ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); + }else +#endif + { + sqlite3VdbeChangeP5(v, bFordelete); + } +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, + (const u8*)&pTabItem->colUsed, P4_INT64); +#endif + }else{ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + } + if( pLoop->wsFlags & WHERE_INDEXED ){ + Index *pIx = pLoop->u.btree.pIndex; + int iIndexCur; + int op = OP_OpenRead; + /* iAuxArg is always set to a positive value if ONEPASS is possible */ + assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) + && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 + ){ + /* This is one term of an OR-optimization using the PRIMARY KEY of a + ** WITHOUT ROWID table. No need for a separate index */ + iIndexCur = pLevel->iTabCur; + op = 0; + }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ + Index *pJ = pTabItem->pTab->pIndex; + iIndexCur = iAuxArg; + assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); + while( ALWAYS(pJ) && pJ!=pIx ){ + iIndexCur++; + pJ = pJ->pNext; + } + op = OP_OpenWrite; + pWInfo->aiCurOnePass[1] = iIndexCur; + }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ + iIndexCur = iAuxArg; + op = OP_ReopenIdx; + }else{ + iIndexCur = pParse->nTab++; + if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ + whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); + } + if( pIx->pPartIdxWhere && (pTabItem->fg.jointype & JT_RIGHT)==0 ){ + wherePartIdxExpr( + pParse, pIx, pIx->pPartIdxWhere, 0, iIndexCur, pTabItem + ); + } + } + pLevel->iIdxCur = iIndexCur; + assert( pIx!=0 ); + assert( pIx->pSchema==pTab->pSchema ); + assert( iIndexCur>=0 ); + if( op ){ + sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 + && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 + && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED + ){ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); + } + VdbeComment((v, "%s", pIx->zName)); +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + { + u64 colUsed = 0; + int ii, jj; + for(ii=0; iinColumn; ii++){ + jj = pIx->aiColumn[ii]; + if( jj<0 ) continue; + if( jj>63 ) jj = 63; + if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; + colUsed |= ((u64)1)<<(ii<63 ? ii : 63); + } + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, + (u8*)&colUsed, P4_INT64); + } +#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ + } + } + if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); + if( (pTabItem->fg.jointype & JT_RIGHT)!=0 + && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 + ){ + WhereRightJoin *pRJ = pLevel->pRJ; + pRJ->iMatch = pParse->nTab++; + pRJ->regBloom = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); + pRJ->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); + assert( pTab==pTabItem->pTab ); + if( HasRowid(pTab) ){ + KeyInfo *pInfo; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); + pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); + if( pInfo ){ + pInfo->aColl[0] = 0; + pInfo->aSortFlags[0] = 0; + sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO); + } + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + /* The nature of RIGHT JOIN processing is such that it messes up + ** the output order. So omit any ORDER BY/GROUP BY elimination + ** optimizations. We need to do an actual sort for RIGHT JOIN. */ + pWInfo->nOBSat = 0; + pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED; + } + } + pWInfo->iTop = sqlite3VdbeCurrentAddr(v); + if( db->mallocFailed ) goto whereBeginError; + + /* Generate the code to do the search. Each iteration of the for + ** loop below generates code for a single nested loop of the VM + ** program. + */ + for(ii=0; iinErr ) goto whereBeginError; + pLevel = &pWInfo->a[ii]; + wsFlags = pLevel->pWLoop->wsFlags; + pSrc = &pTabList->a[pLevel->iFrom]; + if( pSrc->fg.isMaterialized ){ + if( pSrc->fg.isCorrelated ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); + }else{ + int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); + sqlite3VdbeJumpHere(v, iOnce); + } + } + assert( pTabList == pWInfo->pTabList ); + if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ + if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel); +#endif + }else{ + sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); + } + if( db->mallocFailed ) goto whereBeginError; + } + addrExplain = sqlite3WhereExplainOneScan( + pParse, pTabList, pLevel, wctrlFlags + ); + pLevel->addrBody = sqlite3VdbeCurrentAddr(v); + notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady); + pWInfo->iContinue = pLevel->addrCont; + if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){ + sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); + } + } + + /* Done. */ + VdbeModuleComment((v, "Begin WHERE-core")); + pWInfo->iEndWhere = sqlite3VdbeCurrentAddr(v); + return pWInfo; + + /* Jump here if malloc fails */ +whereBeginError: + if( pWInfo ){ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + } +#ifdef WHERETRACE_ENABLED + /* Prevent harmless compiler warnings about debugging routines + ** being declared but never used */ + sqlite3ShowWhereLoopList(0); +#endif /* WHERETRACE_ENABLED */ + return 0; +} + +/* +** Part of sqlite3WhereEnd() will rewrite opcodes to reference the +** index rather than the main table. In SQLITE_DEBUG mode, we want +** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine +** does that. +*/ +#ifndef SQLITE_DEBUG +# define OpcodeRewriteTrace(D,K,P) /* no-op */ +#else +# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P) + static void sqlite3WhereOpcodeRewriteTrace( + sqlite3 *db, + int pc, + VdbeOp *pOp + ){ + if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; + sqlite3VdbePrintOp(0, pc, pOp); + } +#endif + +#ifdef SQLITE_DEBUG +/* +** Return true if cursor iCur is opened by instruction k of the +** bytecode. Used inside of assert() only. +*/ +static int cursorIsOpen(Vdbe *v, int iCur, int k){ + while( k>=0 ){ + VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); + if( pOp->p1!=iCur ) continue; + if( pOp->opcode==OP_Close ) return 0; + if( pOp->opcode==OP_OpenRead ) return 1; + if( pOp->opcode==OP_OpenWrite ) return 1; + if( pOp->opcode==OP_OpenDup ) return 1; + if( pOp->opcode==OP_OpenAutoindex ) return 1; + if( pOp->opcode==OP_OpenEphemeral ) return 1; + } + return 0; +} +#endif /* SQLITE_DEBUG */ + +/* +** Generate the end of the WHERE loop. See comments on +** sqlite3WhereBegin() for additional information. +*/ +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ + Parse *pParse = pWInfo->pParse; + Vdbe *v = pParse->pVdbe; + int i; + WhereLevel *pLevel; + WhereLoop *pLoop; + SrcList *pTabList = pWInfo->pTabList; + sqlite3 *db = pParse->db; + int iEnd = sqlite3VdbeCurrentAddr(v); + int nRJ = 0; + + /* Generate loop termination code. + */ + VdbeModuleComment((v, "End WHERE-core")); + for(i=pWInfo->nLevel-1; i>=0; i--){ + int addr; + pLevel = &pWInfo->a[i]; + if( pLevel->pRJ ){ + /* Terminate the subroutine that forms the interior of the loop of + ** the RIGHT JOIN table */ + WhereRightJoin *pRJ = pLevel->pRJ; + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + pLevel->addrCont = 0; + pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1); + VdbeCoverage(v); + nRJ++; + } + pLoop = pLevel->pWLoop; + if( pLevel->op!=OP_Noop ){ +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + int addrSeek = 0; + Index *pIdx; + int n; + if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED + && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */ + && (pLoop->wsFlags & WHERE_INDEXED)!=0 + && (pIdx = pLoop->u.btree.pIndex)->hasStat1 + && (n = pLoop->u.btree.nDistinctCol)>0 + && pIdx->aiRowLogEst[n]>=36 + ){ + int r1 = pParse->nMem+1; + int j, op; + for(j=0; jiIdxCur, j, r1+j); + } + pParse->nMem += n+1; + op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT; + addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n); + VdbeCoverageIf(v, op==OP_SeekLT); + VdbeCoverageIf(v, op==OP_SeekGT); + sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); + } +#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ + /* The common case: Advance to the next row */ + if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont); + sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); + sqlite3VdbeChangeP5(v, pLevel->p5); + VdbeCoverage(v); + VdbeCoverageIf(v, pLevel->op==OP_Next); + VdbeCoverageIf(v, pLevel->op==OP_Prev); + VdbeCoverageIf(v, pLevel->op==OP_VNext); + if( pLevel->regBignull ){ + sqlite3VdbeResolveLabel(v, pLevel->addrBignull); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); + VdbeCoverage(v); + } +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); +#endif + }else if( pLevel->addrCont ){ + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + } + if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ + struct InLoop *pIn; + int j; + sqlite3VdbeResolveLabel(v, pLevel->addrNxt); + for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ + assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull + || pParse->db->mallocFailed ); + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); + if( pIn->eEndLoopOp!=OP_Noop ){ + if( pIn->nPrefix ){ + int bEarlyOut = + (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0; + if( pLevel->iLeftJoin ){ + /* For LEFT JOIN queries, cursor pIn->iCur may not have been + ** opened yet. This occurs for WHERE clauses such as + ** "a = ? AND b IN (...)", where the index is on (a, b). If + ** the RHS of the (a=?) is NULL, then the "b IN (...)" may + ** never have been coded, but the body of the loop run to + ** return the null-row. So, if the cursor is not open yet, + ** jump over the OP_Next or OP_Prev instruction about to + ** be coded. */ + sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, + sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut); + VdbeCoverage(v); + } + if( bEarlyOut ){ + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2, + pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); + /* Retarget the OP_IsNull against the left operand of IN so + ** it jumps past the OP_IfNoHope. This is because the + ** OP_IsNull also bypasses the OP_Affinity opcode that is + ** required by OP_IfNoHope. */ + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); + } + } + sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); + VdbeCoverage(v); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); + } + sqlite3VdbeJumpHere(v, pIn->addrInTop-1); + } + } + sqlite3VdbeResolveLabel(v, pLevel->addrBrk); + if( pLevel->pRJ ){ + sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1); + VdbeCoverage(v); + } + if( pLevel->addrSkip ){ + sqlite3VdbeGoto(v, pLevel->addrSkip); + VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); + sqlite3VdbeJumpHere(v, pLevel->addrSkip); + sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); + } +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( pLevel->addrLikeRep ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1), + pLevel->addrLikeRep); + VdbeCoverage(v); + } +#endif + if( pLevel->iLeftJoin ){ + int ws = pLoop->wsFlags; + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); + assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); + if( (ws & WHERE_IDX_ONLY)==0 ){ + assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); + } + if( (ws & WHERE_INDEXED) + || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx) + ){ + if( ws & WHERE_MULTI_OR ){ + Index *pIx = pLevel->u.pCoveringIdx; + int iDb = sqlite3SchemaToIndex(db, pIx->pSchema); + sqlite3VdbeAddOp3(v, OP_ReopenIdx, pLevel->iIdxCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + } + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); + } + if( pLevel->op==OP_Return ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); + }else{ + sqlite3VdbeGoto(v, pLevel->addrFirst); + } + sqlite3VdbeJumpHere(v, addr); + } + VdbeModuleComment((v, "End WHERE-loop%d: %s", i, + pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); + } + + assert( pWInfo->nLevel<=pTabList->nSrc ); + for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ + int k, last; + VdbeOp *pOp, *pLastOp; + Index *pIdx = 0; + SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; + Table *pTab = pTabItem->pTab; + assert( pTab!=0 ); + pLoop = pLevel->pWLoop; + + /* Do RIGHT JOIN processing. Generate code that will output the + ** unmatched rows of the right operand of the RIGHT JOIN with + ** all of the columns of the left operand set to NULL. + */ + if( pLevel->pRJ ){ + sqlite3WhereRightJoinLoop(pWInfo, i, pLevel); + continue; + } + + /* For a co-routine, change all OP_Column references to the table of + ** the co-routine into OP_Copy of result contained in a register. + ** OP_Rowid becomes OP_Null. + */ + if( pTabItem->fg.viaCoroutine ){ + testcase( pParse->db->mallocFailed ); + translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, + pTabItem->regResult, 0); + continue; + } + + /* If this scan uses an index, make VDBE code substitutions to read data + ** from the index instead of from the table where possible. In some cases + ** this optimization prevents the table from ever being read, which can + ** yield a significant performance boost. + ** + ** Calls to the code generator in between sqlite3WhereBegin and + ** sqlite3WhereEnd will have created code that references the table + ** directly. This loop scans all that code looking for opcodes + ** that reference the table and converts them into opcodes that + ** reference the index. + */ + if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){ + pIdx = pLoop->u.btree.pIndex; + }else if( pLoop->wsFlags & WHERE_MULTI_OR ){ + pIdx = pLevel->u.pCoveringIdx; + } + if( pIdx + && !db->mallocFailed + ){ + if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){ + last = iEnd; + }else{ + last = pWInfo->iEndWhere; + } + if( pIdx->bHasExpr ){ + IndexedExpr *p = pParse->pIdxEpr; + while( p ){ + if( p->iIdxCur==pLevel->iIdxCur ){ +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x200 ){ + sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n", + p->iIdxCur, p->iIdxCol); + if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr); + } +#endif + p->iDataCur = -1; + p->iIdxCur = -1; + } + p = p->pIENext; + } + } + k = pLevel->addrBody + 1; +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE cursor %d->%d in opcode range %d..%d\n", + pLevel->iTabCur, pLevel->iIdxCur, k, last-1); + } + /* Proof that the "+1" on the k value above is safe */ + pOp = sqlite3VdbeGetOp(v, k - 1); + assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_Rowid || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_IfNullRow || pOp->p1!=pLevel->iTabCur ); +#endif + pOp = sqlite3VdbeGetOp(v, k); + pLastOp = pOp + (last - k); + assert( pOp<=pLastOp ); + do{ + if( pOp->p1!=pLevel->iTabCur ){ + /* no-op */ + }else if( pOp->opcode==OP_Column +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + || pOp->opcode==OP_Offset +#endif + ){ + int x = pOp->p2; + assert( pIdx->pTable==pTab ); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( pOp->opcode==OP_Offset ){ + /* Do not need to translate the column number */ + }else +#endif + if( !HasRowid(pTab) ){ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + x = pPk->aiColumn[x]; + assert( x>=0 ); + }else{ + testcase( x!=sqlite3StorageColumnToTable(pTab,x) ); + x = sqlite3StorageColumnToTable(pTab,x); + } + x = sqlite3TableColumnToIndex(pIdx, x); + if( x>=0 ){ + pOp->p2 = x; + pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); + }else{ + /* Unable to translate the table reference into an index + ** reference. Verify that this is harmless - that the + ** table being referenced really is open. + */ +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + || pOp->opcode==OP_Offset + ); +#else + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + ); +#endif + } + }else if( pOp->opcode==OP_Rowid ){ + pOp->p1 = pLevel->iIdxCur; + pOp->opcode = OP_IdxRowid; + OpcodeRewriteTrace(db, k, pOp); + }else if( pOp->opcode==OP_IfNullRow ){ + pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); + } +#ifdef SQLITE_DEBUG + k++; +#endif + }while( (++pOp)flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); +#endif + } + } + + /* The "break" point is here, just past the end of the outer loop. + ** Set it. + */ + sqlite3VdbeResolveLabel(v, pWInfo->iBreak); + + /* Final cleanup + */ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + pParse->withinRJSubrtn -= nRJ; + return; +} + +/************** End of where.c ***********************************************/ +/************** Begin file window.c ******************************************/ +/* +** 2018 May 08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + +/* +** SELECT REWRITING +** +** Any SELECT statement that contains one or more window functions in +** either the select list or ORDER BY clause (the only two places window +** functions may be used) is transformed by function sqlite3WindowRewrite() +** in order to support window function processing. For example, with the +** schema: +** +** CREATE TABLE t1(a, b, c, d, e, f, g); +** +** the statement: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e; +** +** is transformed to: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT a, e, c, d, b FROM t1 ORDER BY c, d +** ) ORDER BY e; +** +** The flattening optimization is disabled when processing this transformed +** SELECT statement. This allows the implementation of the window function +** (in this case max()) to process rows sorted in order of (c, d), which +** makes things easier for obvious reasons. More generally: +** +** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to +** the sub-query. +** +** * ORDER BY, LIMIT and OFFSET remain part of the parent query. +** +** * Terminals from each of the expression trees that make up the +** select-list and ORDER BY expressions in the parent query are +** selected by the sub-query. For the purposes of the transformation, +** terminals are column references and aggregate functions. +** +** If there is more than one window function in the SELECT that uses +** the same window declaration (the OVER bit), then a single scan may +** be used to process more than one window function. For example: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY c ORDER BY d) +** FROM t1; +** +** is transformed in the same way as the example above. However: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY a ORDER BY b) +** FROM t1; +** +** Must be transformed to: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM +** SELECT a, e, c, d, b FROM t1 ORDER BY a, b +** ) ORDER BY c, d +** ) ORDER BY e; +** +** so that both min() and max() may process rows in the order defined by +** their respective window declarations. +** +** INTERFACE WITH SELECT.C +** +** When processing the rewritten SELECT statement, code in select.c calls +** sqlite3WhereBegin() to begin iterating through the results of the +** sub-query, which is always implemented as a co-routine. It then calls +** sqlite3WindowCodeStep() to process rows and finish the scan by calling +** sqlite3WhereEnd(). +** +** sqlite3WindowCodeStep() generates VM code so that, for each row returned +** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked. +** When the sub-routine is invoked: +** +** * The results of all window-functions for the row are stored +** in the associated Window.regResult registers. +** +** * The required terminal values are stored in the current row of +** temp table Window.iEphCsr. +** +** In some cases, depending on the window frame and the specific window +** functions invoked, sqlite3WindowCodeStep() caches each entire partition +** in a temp table before returning any rows. In other cases it does not. +** This detail is encapsulated within this file, the code generated by +** select.c is the same in either case. +** +** BUILT-IN WINDOW FUNCTIONS +** +** This implementation features the following built-in window functions: +** +** row_number() +** rank() +** dense_rank() +** percent_rank() +** cume_dist() +** ntile(N) +** lead(expr [, offset [, default]]) +** lag(expr [, offset [, default]]) +** first_value(expr) +** last_value(expr) +** nth_value(expr, N) +** +** These are the same built-in window functions supported by Postgres. +** Although the behaviour of aggregate window functions (functions that +** can be used as either aggregates or window functions) allows them to +** be implemented using an API, built-in window functions are much more +** esoteric. Additionally, some window functions (e.g. nth_value()) +** may only be implemented by caching the entire partition in memory. +** As such, some built-in window functions use the same API as aggregate +** window functions and some are implemented directly using VDBE +** instructions. Additionally, for those functions that use the API, the +** window frame is sometimes modified before the SELECT statement is +** rewritten. For example, regardless of the specified window frame, the +** row_number() function always uses: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** See sqlite3WindowUpdate() for details. +** +** As well as some of the built-in window functions, aggregate window +** functions min() and max() are implemented using VDBE instructions if +** the start of the window frame is declared as anything other than +** UNBOUNDED PRECEDING. +*/ + +/* +** Implementation of built-in window function row_number(). Assumes that the +** window frame has been coerced to: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void row_numberStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) (*p)++; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void row_numberValueFunc(sqlite3_context *pCtx){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + sqlite3_result_int64(pCtx, (p ? *p : 0)); +} + +/* +** Context object type used by rank(), dense_rank(), percent_rank() and +** cume_dist(). +*/ +struct CallCount { + i64 nValue; + i64 nStep; + i64 nTotal; +}; + +/* +** Implementation of built-in window function dense_rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void dense_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) p->nStep = 1; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void dense_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nStep ){ + p->nValue++; + p->nStep = 0; + } + sqlite3_result_int64(pCtx, p->nValue); + } +} + +/* +** Implementation of built-in window function nth_value(). This +** implementation is used in "slow mode" only - when the EXCLUDE clause +** is not set to the default value "NO OTHERS". +*/ +struct NthValueCtx { + i64 nStep; + sqlite3_value *pValue; +}; +static void nth_valueStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + i64 iVal; + switch( sqlite3_value_numeric_type(apArg[1]) ){ + case SQLITE_INTEGER: + iVal = sqlite3_value_int64(apArg[1]); + break; + case SQLITE_FLOAT: { + double fVal = sqlite3_value_double(apArg[1]); + if( ((i64)fVal)!=fVal ) goto error_out; + iVal = (i64)fVal; + break; + } + default: + goto error_out; + } + if( iVal<=0 ) goto error_out; + + p->nStep++; + if( iVal==p->nStep ){ + p->pValue = sqlite3_value_dup(apArg[0]); + if( !p->pValue ){ + sqlite3_result_error_nomem(pCtx); + } + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + return; + + error_out: + sqlite3_result_error( + pCtx, "second argument to nth_value must be a positive integer", -1 + ); +} +static void nth_valueFinalizeFunc(sqlite3_context *pCtx){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0); + if( p && p->pValue ){ + sqlite3_result_value(pCtx, p->pValue); + sqlite3_value_free(p->pValue); + p->pValue = 0; + } +} +#define nth_valueInvFunc noopStepFunc +#define nth_valueValueFunc noopValueFunc + +static void first_valueStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pValue==0 ){ + p->pValue = sqlite3_value_dup(apArg[0]); + if( !p->pValue ){ + sqlite3_result_error_nomem(pCtx); + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void first_valueFinalizeFunc(sqlite3_context *pCtx){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pValue ){ + sqlite3_result_value(pCtx, p->pValue); + sqlite3_value_free(p->pValue); + p->pValue = 0; + } +} +#define first_valueInvFunc noopStepFunc +#define first_valueValueFunc noopValueFunc + +/* +** Implementation of built-in window function rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nStep++; + if( p->nValue==0 ){ + p->nValue = p->nStep; + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + sqlite3_result_int64(pCtx, p->nValue); + p->nValue = 0; + } +} + +/* +** Implementation of built-in window function percent_rank(). Assumes that +** the window frame has been set to: +** +** GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +*/ +static void percent_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nTotal++; + } +} +static void percent_rankInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + p->nStep++; +} +static void percent_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nValue = p->nStep; + if( p->nTotal>1 ){ + double r = (double)p->nValue / (double)(p->nTotal-1); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_double(pCtx, 0.0); + } + } +} +#define percent_rankFinalizeFunc percent_rankValueFunc + +/* +** Implementation of built-in window function cume_dist(). Assumes that +** the window frame has been set to: +** +** GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING +*/ +static void cume_distStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nTotal++; + } +} +static void cume_distInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + p->nStep++; +} +static void cume_distValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0); + if( p ){ + double r = (double)(p->nStep) / (double)(p->nTotal); + sqlite3_result_double(pCtx, r); + } +} +#define cume_distFinalizeFunc cume_distValueFunc + +/* +** Context object for ntile() window function. +*/ +struct NtileCtx { + i64 nTotal; /* Total rows in partition */ + i64 nParam; /* Parameter passed to ntile(N) */ + i64 iRow; /* Current row */ +}; + +/* +** Implementation of ntile(). This assumes that the window frame has +** been coerced to: +** +** ROWS CURRENT ROW AND UNBOUNDED FOLLOWING +*/ +static void ntileStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NtileCtx *p; + assert( nArg==1 ); UNUSED_PARAMETER(nArg); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nParam = sqlite3_value_int64(apArg[0]); + if( p->nParam<=0 ){ + sqlite3_result_error( + pCtx, "argument of ntile must be a positive integer", -1 + ); + } + } + p->nTotal++; + } +} +static void ntileInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NtileCtx *p; + assert( nArg==1 ); UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + p->iRow++; +} +static void ntileValueFunc(sqlite3_context *pCtx){ + struct NtileCtx *p; + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->nParam>0 ){ + int nSize = (p->nTotal / p->nParam); + if( nSize==0 ){ + sqlite3_result_int64(pCtx, p->iRow+1); + }else{ + i64 nLarge = p->nTotal - p->nParam*nSize; + i64 iSmall = nLarge*(nSize+1); + i64 iRow = p->iRow; + + assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal ); + + if( iRowpVal); + p->pVal = sqlite3_value_dup(apArg[0]); + if( p->pVal==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + p->nVal++; + } + } +} +static void last_valueInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct LastValueCtx *p; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( ALWAYS(p) ){ + p->nVal--; + if( p->nVal==0 ){ + sqlite3_value_free(p->pVal); + p->pVal = 0; + } + } +} +static void last_valueValueFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + } +} +static void last_valueFinalizeFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + sqlite3_value_free(p->pVal); + p->pVal = 0; + } +} + +/* +** Static names for the built-in window function names. These static +** names are used, rather than string literals, so that FuncDef objects +** can be associated with a particular window function by direct +** comparison of the zName pointer. Example: +** +** if( pFuncDef->zName==row_valueName ){ ... } +*/ +static const char row_numberName[] = "row_number"; +static const char dense_rankName[] = "dense_rank"; +static const char rankName[] = "rank"; +static const char percent_rankName[] = "percent_rank"; +static const char cume_distName[] = "cume_dist"; +static const char ntileName[] = "ntile"; +static const char last_valueName[] = "last_value"; +static const char nth_valueName[] = "nth_value"; +static const char first_valueName[] = "first_value"; +static const char leadName[] = "lead"; +static const char lagName[] = "lag"; + +/* +** No-op implementations of xStep() and xFinalize(). Used as place-holders +** for built-in window functions that never call those interfaces. +** +** The noopValueFunc() is called but is expected to do nothing. The +** noopStepFunc() is never called, and so it is marked with NO_TEST to +** let the test coverage routine know not to expect this function to be +** invoked. +*/ +static void noopStepFunc( /*NO_TEST*/ + sqlite3_context *p, /*NO_TEST*/ + int n, /*NO_TEST*/ + sqlite3_value **a /*NO_TEST*/ +){ /*NO_TEST*/ + UNUSED_PARAMETER(p); /*NO_TEST*/ + UNUSED_PARAMETER(n); /*NO_TEST*/ + UNUSED_PARAMETER(a); /*NO_TEST*/ + assert(0); /*NO_TEST*/ +} /*NO_TEST*/ +static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } + +/* Window functions that use all window interfaces: xStep, xFinal, +** xValue, and xInverse */ +#define WINDOWFUNCALL(name,nArg,extra) { \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \ + name ## InvFunc, name ## Name, {0} \ +} + +/* Window functions that are implemented using bytecode and thus have +** no-op routines for their methods */ +#define WINDOWFUNCNOOP(name,nArg,extra) { \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + noopStepFunc, noopValueFunc, noopValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + +/* Window functions that use all window interfaces: xStep, the +** same routine for xFinalize and xValue and which never call +** xInverse. */ +#define WINDOWFUNCX(name,nArg,extra) { \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + + +/* +** Register those built-in window functions that are not also aggregates. +*/ +SQLITE_PRIVATE void sqlite3WindowFunctions(void){ + static FuncDef aWindowFuncs[] = { + WINDOWFUNCX(row_number, 0, 0), + WINDOWFUNCX(dense_rank, 0, 0), + WINDOWFUNCX(rank, 0, 0), + WINDOWFUNCALL(percent_rank, 0, 0), + WINDOWFUNCALL(cume_dist, 0, 0), + WINDOWFUNCALL(ntile, 1, 0), + WINDOWFUNCALL(last_value, 1, 0), + WINDOWFUNCALL(nth_value, 2, 0), + WINDOWFUNCALL(first_value, 1, 0), + WINDOWFUNCNOOP(lead, 1, 0), + WINDOWFUNCNOOP(lead, 2, 0), + WINDOWFUNCNOOP(lead, 3, 0), + WINDOWFUNCNOOP(lag, 1, 0), + WINDOWFUNCNOOP(lag, 2, 0), + WINDOWFUNCNOOP(lag, 3, 0), + }; + sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); +} + +static Window *windowFind(Parse *pParse, Window *pList, const char *zName){ + Window *p; + for(p=pList; p; p=p->pNextWin){ + if( sqlite3StrICmp(p->zName, zName)==0 ) break; + } + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such window: %s", zName); + } + return p; +} + +/* +** This function is called immediately after resolving the function name +** for a window function within a SELECT statement. Argument pList is a +** linked list of WINDOW definitions for the current SELECT statement. +** Argument pFunc is the function definition just resolved and pWin +** is the Window object representing the associated OVER clause. This +** function updates the contents of pWin as follows: +** +** * If the OVER clause referred to a named window (as in "max(x) OVER win"), +** search list pList for a matching WINDOW definition, and update pWin +** accordingly. If no such WINDOW clause can be found, leave an error +** in pParse. +** +** * If the function is a built-in window function that requires the +** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top +** of this file), pWin is updated here. +*/ +SQLITE_PRIVATE void sqlite3WindowUpdate( + Parse *pParse, + Window *pList, /* List of named windows for this SELECT */ + Window *pWin, /* Window frame to update */ + FuncDef *pFunc /* Window function definition */ +){ + if( pWin->zName && pWin->eFrmType==0 ){ + Window *p = windowFind(pParse, pList, pWin->zName); + if( p==0 ) return; + pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); + pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0); + pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0); + pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); + pWin->eStart = p->eStart; + pWin->eEnd = p->eEnd; + pWin->eFrmType = p->eFrmType; + pWin->eExclude = p->eExclude; + }else{ + sqlite3WindowChain(pParse, pWin, pList); + } + if( (pWin->eFrmType==TK_RANGE) + && (pWin->pStart || pWin->pEnd) + && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1) + ){ + sqlite3ErrorMsg(pParse, + "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression" + ); + }else + if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ + sqlite3 *db = pParse->db; + if( pWin->pFilter ){ + sqlite3ErrorMsg(pParse, + "FILTER clause may only be used with aggregate window functions" + ); + }else{ + struct WindowUpdate { + const char *zFunc; + int eFrmType; + int eStart; + int eEnd; + } aUp[] = { + { row_numberName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, + { dense_rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, + { rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, + { percent_rankName, TK_GROUPS, TK_CURRENT, TK_UNBOUNDED }, + { cume_distName, TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, + { ntileName, TK_ROWS, TK_CURRENT, TK_UNBOUNDED }, + { leadName, TK_ROWS, TK_UNBOUNDED, TK_UNBOUNDED }, + { lagName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, + }; + int i; + for(i=0; izName==aUp[i].zFunc ){ + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); + pWin->pEnd = pWin->pStart = 0; + pWin->eFrmType = aUp[i].eFrmType; + pWin->eStart = aUp[i].eStart; + pWin->eEnd = aUp[i].eEnd; + pWin->eExclude = 0; + if( pWin->eStart==TK_FOLLOWING ){ + pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1"); + } + break; + } + } + } + } + pWin->pWFunc = pFunc; +} + +/* +** Context object passed through sqlite3WalkExprList() to +** selectWindowRewriteExprCb() by selectWindowRewriteEList(). +*/ +typedef struct WindowRewrite WindowRewrite; +struct WindowRewrite { + Window *pWin; + SrcList *pSrc; + ExprList *pSub; + Table *pTab; + Select *pSubSelect; /* Current sub-select, if any */ +}; + +/* +** Callback function used by selectWindowRewriteEList(). If necessary, +** this function appends to the output expression-list and updates +** expression (*ppExpr) in place. +*/ +static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Parse *pParse = pWalker->pParse; + assert( p!=0 ); + assert( p->pWin!=0 ); + + /* If this function is being called from within a scalar sub-select + ** that used by the SELECT statement being processed, only process + ** TK_COLUMN expressions that refer to it (the outer SELECT). Do + ** not process aggregates or window functions at all, as they belong + ** to the scalar sub-select. */ + if( p->pSubSelect ){ + if( pExpr->op!=TK_COLUMN ){ + return WRC_Continue; + }else{ + int nSrc = p->pSrc->nSrc; + int i; + for(i=0; iiTable==p->pSrc->a[i].iCursor ) break; + } + if( i==nSrc ) return WRC_Continue; + } + } + + switch( pExpr->op ){ + + case TK_FUNCTION: + if( !ExprHasProperty(pExpr, EP_WinFunc) ){ + break; + }else{ + Window *pWin; + for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){ + if( pExpr->y.pWin==pWin ){ + assert( pWin->pOwner==pExpr ); + return WRC_Prune; + } + } + } + /* no break */ deliberate_fall_through + + case TK_IF_NULL_ROW: + case TK_AGG_FUNCTION: + case TK_COLUMN: { + int iCol = -1; + if( pParse->db->mallocFailed ) return WRC_Abort; + if( p->pSub ){ + int i; + for(i=0; ipSub->nExpr; i++){ + if( 0==sqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){ + iCol = i; + break; + } + } + } + if( iCol<0 ){ + Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); + if( pDup && pDup->op==TK_AGG_FUNCTION ) pDup->op = TK_FUNCTION; + p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); + } + if( p->pSub ){ + int f = pExpr->flags & EP_Collate; + assert( ExprHasProperty(pExpr, EP_Static)==0 ); + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(pParse->db, pExpr); + ExprClearProperty(pExpr, EP_Static); + memset(pExpr, 0, sizeof(Expr)); + + pExpr->op = TK_COLUMN; + pExpr->iColumn = (iCol<0 ? p->pSub->nExpr-1: iCol); + pExpr->iTable = p->pWin->iEphCsr; + pExpr->y.pTab = p->pTab; + pExpr->flags = f; + } + if( pParse->db->mallocFailed ) return WRC_Abort; + break; + } + + default: /* no-op */ + break; + } + + return WRC_Continue; +} +static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Select *pSave = p->pSubSelect; + if( pSave==pSelect ){ + return WRC_Continue; + }else{ + p->pSubSelect = pSelect; + sqlite3WalkSelect(pWalker, pSelect); + p->pSubSelect = pSave; + } + return WRC_Prune; +} + + +/* +** Iterate through each expression in expression-list pEList. For each: +** +** * TK_COLUMN, +** * aggregate function, or +** * window function with a Window object that is not a member of the +** Window list passed as the second argument (pWin). +** +** Append the node to output expression-list (*ppSub). And replace it +** with a TK_COLUMN that reads the (N-1)th element of table +** pWin->iEphCsr, where N is the number of elements in (*ppSub) after +** appending the new one. +*/ +static void selectWindowRewriteEList( + Parse *pParse, + Window *pWin, + SrcList *pSrc, + ExprList *pEList, /* Rewrite expressions in this list */ + Table *pTab, + ExprList **ppSub /* IN/OUT: Sub-select expression-list */ +){ + Walker sWalker; + WindowRewrite sRewrite; + + assert( pWin!=0 ); + memset(&sWalker, 0, sizeof(Walker)); + memset(&sRewrite, 0, sizeof(WindowRewrite)); + + sRewrite.pSub = *ppSub; + sRewrite.pWin = pWin; + sRewrite.pSrc = pSrc; + sRewrite.pTab = pTab; + + sWalker.pParse = pParse; + sWalker.xExprCallback = selectWindowRewriteExprCb; + sWalker.xSelectCallback = selectWindowRewriteSelectCb; + sWalker.u.pRewrite = &sRewrite; + + (void)sqlite3WalkExprList(&sWalker, pEList); + + *ppSub = sRewrite.pSub; +} + +/* +** Append a copy of each expression in expression-list pAppend to +** expression list pList. Return a pointer to the result list. +*/ +static ExprList *exprListAppendList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + ExprList *pAppend, /* List of values to append. Might be NULL */ + int bIntToNull +){ + if( pAppend ){ + int i; + int nInit = pList ? pList->nExpr : 0; + for(i=0; inExpr; i++){ + sqlite3 *db = pParse->db; + Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + break; + } + if( bIntToNull ){ + int iDummy; + Expr *pSub; + pSub = sqlite3ExprSkipCollateAndLikely(pDup); + if( sqlite3ExprIsInteger(pSub, &iDummy) ){ + pSub->op = TK_NULL; + pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); + pSub->u.zToken = 0; + } + } + pList = sqlite3ExprListAppend(pParse, pList, pDup); + if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags; + } + } + return pList; +} + +/* +** When rewriting a query, if the new subquery in the FROM clause +** contains TK_AGG_FUNCTION nodes that refer to an outer query, +** then we have to increase the Expr->op2 values of those nodes +** due to the extra subquery layer that was added. +** +** See also the incrAggDepth() routine in resolve.c +*/ +static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION + && pExpr->op2>=pWalker->walkerDepth + ){ + pExpr->op2++; + } + return WRC_Continue; +} + +static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pWalker->pParse, + "misuse of aggregate: %s()", pExpr->u.zToken); + } + return WRC_Continue; +} + +/* +** If the SELECT statement passed as the second argument does not invoke +** any SQL window functions, this function is a no-op. Otherwise, it +** rewrites the SELECT statement so that window function xStep functions +** are invoked in the correct order as described under "SELECT REWRITING" +** at the top of this file. +*/ +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ + int rc = SQLITE_OK; + if( p->pWin + && p->pPrior==0 + && ALWAYS((p->selFlags & SF_WinRewrite)==0) + && ALWAYS(!IN_RENAME_OBJECT) + ){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3 *db = pParse->db; + Select *pSub = 0; /* The subquery */ + SrcList *pSrc = p->pSrc; + Expr *pWhere = p->pWhere; + ExprList *pGroupBy = p->pGroupBy; + Expr *pHaving = p->pHaving; + ExprList *pSort = 0; + + ExprList *pSublist = 0; /* Expression list for sub-query */ + Window *pMWin = p->pWin; /* Main window object */ + Window *pWin; /* Window object iterator */ + Table *pTab; + Walker w; + + u32 selFlags = p->selFlags; + + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ){ + return sqlite3ErrorToParser(db, SQLITE_NOMEM); + } + sqlite3AggInfoPersistWalkerInit(&w, pParse); + sqlite3WalkSelect(&w, p); + if( (p->selFlags & SF_Aggregate)==0 ){ + w.xExprCallback = disallowAggregatesInOrderByCb; + w.xSelectCallback = 0; + sqlite3WalkExprList(&w, p->pOrderBy); + } + + p->pSrc = 0; + p->pWhere = 0; + p->pGroupBy = 0; + p->pHaving = 0; + p->selFlags &= ~SF_Aggregate; + p->selFlags |= SF_WinRewrite; + + /* Create the ORDER BY clause for the sub-select. This is the concatenation + ** of the window PARTITION and ORDER BY clauses. Then, if this makes it + ** redundant, remove the ORDER BY from the parent SELECT. */ + pSort = exprListAppendList(pParse, 0, pMWin->pPartition, 1); + pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1); + if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){ + int nSave = pSort->nExpr; + pSort->nExpr = p->pOrderBy->nExpr; + if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + } + pSort->nExpr = nSave; + } + + /* Assign a cursor number for the ephemeral table used to buffer rows. + ** The OpenEphemeral instruction is coded later, after it is known how + ** many columns the table will have. */ + pMWin->iEphCsr = pParse->nTab++; + pParse->nTab += 3; + + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist); + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist); + pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0); + + /* Append the PARTITION BY and ORDER BY expressions to the to the + ** sub-select expression list. They are required to figure out where + ** boundaries for partitions and sets of peer rows lie. */ + pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0); + pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0); + + /* Append the arguments passed to each window function to the + ** sub-select expression list. Also allocate two registers for each + ** window function - one for the accumulator, another for interim + ** results. */ + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + ExprList *pArgs; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->pWFunc!=0 ); + pArgs = pWin->pOwner->x.pList; + if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){ + selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pWin->bExprArgs = 1; + }else{ + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pSublist = exprListAppendList(pParse, pSublist, pArgs, 0); + } + if( pWin->pFilter ){ + Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); + pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); + } + pWin->regAccum = ++pParse->nMem; + pWin->regResult = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + } + + /* If there is no ORDER BY or PARTITION BY clause, and the window + ** function accepts zero arguments, and there are no other columns + ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible + ** that pSublist is still NULL here. Add a constant expression here to + ** keep everything legal in this case. + */ + if( pSublist==0 ){ + pSublist = sqlite3ExprListAppend(pParse, 0, + sqlite3Expr(db, TK_INTEGER, "0") + ); + } + + pSub = sqlite3SelectNew( + pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 + ); + TREETRACE(0x40,pParse,pSub, + ("New window-function subquery in FROM clause of (%u/%p)\n", + p->selId, p)); + p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside + ** of sqlite3DbMallocRawNN() called from + ** sqlite3SrcListAppend() */ + if( p->pSrc ){ + Table *pTab2; + p->pSrc->a[0].pSelect = pSub; + p->pSrc->a[0].fg.isCorrelated = 1; + sqlite3SrcListAssignCursors(pParse, p->pSrc); + pSub->selFlags |= SF_Expanded|SF_OrderByReqd; + pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); + pSub->selFlags |= (selFlags & SF_Aggregate); + if( pTab2==0 ){ + /* Might actually be some other kind of error, but in that case + ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get + ** the correct error message regardless. */ + rc = SQLITE_NOMEM; + }else{ + memcpy(pTab, pTab2, sizeof(Table)); + pTab->tabFlags |= TF_Ephemeral; + p->pSrc->a[0].pTab = pTab; + pTab = pTab2; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3WindowExtraAggFuncDepth; + w.xSelectCallback = sqlite3WalkerDepthIncrease; + w.xSelectCallback2 = sqlite3WalkerDepthDecrease; + sqlite3WalkSelect(&w, pSub); + } + }else{ + sqlite3SelectDelete(db, pSub); + } + if( db->mallocFailed ) rc = SQLITE_NOMEM; + + /* Defer deleting the temporary table pTab because if an error occurred, + ** there could still be references to that table embedded in the + ** result-set or ORDER BY clause of the SELECT statement p. */ + sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab); + } + + assert( rc==SQLITE_OK || pParse->nErr!=0 ); + return rc; +} + +/* +** Unlink the Window object from the Select to which it is attached, +** if it is attached. +*/ +SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window *p){ + if( p->ppThis ){ + *p->ppThis = p->pNextWin; + if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis; + p->ppThis = 0; + } +} + +/* +** Free the Window object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){ + if( p ){ + sqlite3WindowUnlinkFromSelect(p); + sqlite3ExprDelete(db, p->pFilter); + sqlite3ExprListDelete(db, p->pPartition); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pEnd); + sqlite3ExprDelete(db, p->pStart); + sqlite3DbFree(db, p->zName); + sqlite3DbFree(db, p->zBase); + sqlite3DbFree(db, p); + } +} + +/* +** Free the linked list of Window objects starting at the second argument. +*/ +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ + while( p ){ + Window *pNext = p->pNextWin; + sqlite3WindowDelete(db, p); + p = pNext; + } +} + +/* +** The argument expression is an PRECEDING or FOLLOWING offset. The +** value should be a non-negative integer. If the value is not a +** constant, change it to NULL. The fact that it is then a non-negative +** integer will be caught later. But it is important not to leave +** variable values in the expression tree. +*/ +static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ + if( 0==sqlite3ExprIsConstant(pExpr) ){ + if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); + sqlite3ExprDelete(pParse->db, pExpr); + pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); + } + return pExpr; +} + +/* +** Allocate and return a new Window object describing a Window Definition. +*/ +SQLITE_PRIVATE Window *sqlite3WindowAlloc( + Parse *pParse, /* Parsing context */ + int eType, /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */ + int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */ + Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */ + int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */ + Expr *pEnd, /* End window size if TK_FOLLOWING or PRECEDING */ + u8 eExclude /* EXCLUDE clause */ +){ + Window *pWin = 0; + int bImplicitFrame = 0; + + /* Parser assures the following: */ + assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS ); + assert( eStart==TK_CURRENT || eStart==TK_PRECEDING + || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING ); + assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING + || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING ); + assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) ); + assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) ); + + if( eType==0 ){ + bImplicitFrame = 1; + eType = TK_RANGE; + } + + /* Additionally, the + ** starting boundary type may not occur earlier in the following list than + ** the ending boundary type: + ** + ** UNBOUNDED PRECEDING + ** PRECEDING + ** CURRENT ROW + ** FOLLOWING + ** UNBOUNDED FOLLOWING + ** + ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending + ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting + ** frame boundary. + */ + if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING) + || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT)) + ){ + sqlite3ErrorMsg(pParse, "unsupported frame specification"); + goto windowAllocErr; + } + + pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( pWin==0 ) goto windowAllocErr; + pWin->eFrmType = eType; + pWin->eStart = eStart; + pWin->eEnd = eEnd; + if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_WindowFunc) ){ + eExclude = TK_NO; + } + pWin->eExclude = eExclude; + pWin->bImplicitFrame = bImplicitFrame; + pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd); + pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart); + return pWin; + +windowAllocErr: + sqlite3ExprDelete(pParse->db, pEnd); + sqlite3ExprDelete(pParse->db, pStart); + return 0; +} + +/* +** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window +** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the +** equivalent nul-terminated string. +*/ +SQLITE_PRIVATE Window *sqlite3WindowAssemble( + Parse *pParse, + Window *pWin, + ExprList *pPartition, + ExprList *pOrderBy, + Token *pBase +){ + if( pWin ){ + pWin->pPartition = pPartition; + pWin->pOrderBy = pOrderBy; + if( pBase ){ + pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n); + } + }else{ + sqlite3ExprListDelete(pParse->db, pPartition); + sqlite3ExprListDelete(pParse->db, pOrderBy); + } + return pWin; +} + +/* +** Window *pWin has just been created from a WINDOW clause. Token pBase +** is the base window. Earlier windows from the same WINDOW clause are +** stored in the linked list starting at pWin->pNextWin. This function +** either updates *pWin according to the base specification, or else +** leaves an error in pParse. +*/ +SQLITE_PRIVATE void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){ + if( pWin->zBase ){ + sqlite3 *db = pParse->db; + Window *pExist = windowFind(pParse, pList, pWin->zBase); + if( pExist ){ + const char *zErr = 0; + /* Check for errors */ + if( pWin->pPartition ){ + zErr = "PARTITION clause"; + }else if( pExist->pOrderBy && pWin->pOrderBy ){ + zErr = "ORDER BY clause"; + }else if( pExist->bImplicitFrame==0 ){ + zErr = "frame specification"; + } + if( zErr ){ + sqlite3ErrorMsg(pParse, + "cannot override %s of window: %s", zErr, pWin->zBase + ); + }else{ + pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0); + if( pExist->pOrderBy ){ + assert( pWin->pOrderBy==0 ); + pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0); + } + sqlite3DbFree(db, pWin->zBase); + pWin->zBase = 0; + } + } + } +} + +/* +** Attach window object pWin to expression p. +*/ +SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ + if( p ){ + assert( p->op==TK_FUNCTION ); + assert( pWin ); + assert( ExprIsFullSize(p) ); + p->y.pWin = pWin; + ExprSetProperty(p, EP_WinFunc|EP_FullSize); + pWin->pOwner = p; + if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ + sqlite3ErrorMsg(pParse, + "DISTINCT is not supported for window functions" + ); + } + }else{ + sqlite3WindowDelete(pParse->db, pWin); + } +} + +/* +** Possibly link window pWin into the list at pSel->pWin (window functions +** to be processed as part of SELECT statement pSel). The window is linked +** in if either (a) there are no other windows already linked to this +** SELECT, or (b) the windows already linked use a compatible window frame. +*/ +SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin){ + if( pSel ){ + if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + }else{ + if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){ + pSel->selFlags |= SF_MultiPart; + } + } + } +} + +/* +** Return 0 if the two window objects are identical, 1 if they are +** different, or 2 if it cannot be determined if the objects are identical +** or not. Identical window objects can be processed in a single scan. +*/ +SQLITE_PRIVATE int sqlite3WindowCompare( + const Parse *pParse, + const Window *p1, + const Window *p2, + int bFilter +){ + int res; + if( NEVER(p1==0) || NEVER(p2==0) ) return 1; + if( p1->eFrmType!=p2->eFrmType ) return 1; + if( p1->eStart!=p2->eStart ) return 1; + if( p1->eEnd!=p2->eEnd ) return 1; + if( p1->eExclude!=p2->eExclude ) return 1; + if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; + if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; + if( (res = sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){ + return res; + } + if( (res = sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){ + return res; + } + if( bFilter ){ + if( (res = sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){ + return res; + } + } + return 0; +} + + +/* +** This is called by code in select.c before it calls sqlite3WhereBegin() +** to begin iterating through the sub-query results. It is used to allocate +** and initialize registers and cursors used by sqlite3WindowCodeStep(). +*/ +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ + int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; + Window *pMWin = pSelect->pWin; + Window *pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); + + /* Allocate registers to use for PARTITION BY values, if any. Initialize + ** said registers to NULL. */ + if( pMWin->pPartition ){ + int nExpr = pMWin->pPartition->nExpr; + pMWin->regPart = pParse->nMem+1; + pParse->nMem += nExpr; + sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1); + } + + pMWin->regOne = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne); + + if( pMWin->eExclude ){ + pMWin->regStartRowid = ++pParse->nMem; + pMWin->regEndRowid = ++pParse->nMem; + pMWin->csrApp = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr); + return; + } + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *p = pWin->pWFunc; + if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){ + /* The inline versions of min() and max() require a single ephemeral + ** table and 3 registers. The registers are used as follows: + ** + ** regApp+0: slot to copy min()/max() argument to for MakeRecord + ** regApp+1: integer value used to ensure keys are unique + ** regApp+2: output of MakeRecord + */ + ExprList *pList; + KeyInfo *pKeyInfo; + assert( ExprUseXList(pWin->pOwner) ); + pList = pWin->pOwner->x.pList; + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); + pWin->csrApp = pParse->nTab++; + pWin->regApp = pParse->nMem+1; + pParse->nMem += 3; + if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){ + assert( pKeyInfo->aSortFlags[0]==0 ); + pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC; + } + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + else if( p->zName==nth_valueName || p->zName==first_valueName ){ + /* Allocate two registers at pWin->regApp. These will be used to + ** store the start and end index of the current frame. */ + pWin->regApp = pParse->nMem+1; + pWin->csrApp = pParse->nTab++; + pParse->nMem += 2; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + else if( p->zName==leadName || p->zName==lagName ){ + pWin->csrApp = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + } +} + +#define WINDOW_STARTING_INT 0 +#define WINDOW_ENDING_INT 1 +#define WINDOW_NTH_VALUE_INT 2 +#define WINDOW_STARTING_NUM 3 +#define WINDOW_ENDING_NUM 4 + +/* +** A "PRECEDING " (eCond==0) or "FOLLOWING " (eCond==1) or the +** value of the second argument to nth_value() (eCond==2) has just been +** evaluated and the result left in register reg. This function generates VM +** code to check that the value is a non-negative integer and throws an +** exception if it is not. +*/ +static void windowCheckValue(Parse *pParse, int reg, int eCond){ + static const char *azErr[] = { + "frame starting offset must be a non-negative integer", + "frame ending offset must be a non-negative integer", + "second argument to nth_value must be a positive integer", + "frame starting offset must be a non-negative number", + "frame ending offset must be a non-negative number", + }; + static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge }; + Vdbe *v = sqlite3GetVdbe(pParse); + int regZero = sqlite3GetTempReg(pParse); + assert( eCond>=0 && eCond=WINDOW_STARTING_NUM ){ + int regString = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL); + VdbeCoverage(v); + assert( eCond==3 || eCond==4 ); + VdbeCoverageIf(v, eCond==3); + VdbeCoverageIf(v, eCond==4); + }else{ + sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + assert( eCond==0 || eCond==1 || eCond==2 ); + VdbeCoverageIf(v, eCond==0); + VdbeCoverageIf(v, eCond==1); + VdbeCoverageIf(v, eCond==2); + } + sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC); + VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */ + VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */ + VdbeCoverageNeverNullIf(v, eCond==2); + VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */ + VdbeCoverageNeverNullIf(v, eCond==4); /* the OP_Ge */ + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); + sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); + sqlite3ReleaseTempReg(pParse, regZero); +} + +/* +** Return the number of arguments passed to the window-function associated +** with the object passed as the only argument to this function. +*/ +static int windowArgCount(Window *pWin){ + const ExprList *pList; + assert( ExprUseXList(pWin->pOwner) ); + pList = pWin->pOwner->x.pList; + return (pList ? pList->nExpr : 0); +} + +typedef struct WindowCodeArg WindowCodeArg; +typedef struct WindowCsrAndReg WindowCsrAndReg; + +/* +** See comments above struct WindowCodeArg. +*/ +struct WindowCsrAndReg { + int csr; /* Cursor number */ + int reg; /* First in array of peer values */ +}; + +/* +** A single instance of this structure is allocated on the stack by +** sqlite3WindowCodeStep() and a pointer to it passed to the various helper +** routines. This is to reduce the number of arguments required by each +** helper function. +** +** regArg: +** Each window function requires an accumulator register (just as an +** ordinary aggregate function does). This variable is set to the first +** in an array of accumulator registers - one for each window function +** in the WindowCodeArg.pMWin list. +** +** eDelete: +** The window functions implementation sometimes caches the input rows +** that it processes in a temporary table. If it is not zero, this +** variable indicates when rows may be removed from the temp table (in +** order to reduce memory requirements - it would always be safe just +** to leave them there). Possible values for eDelete are: +** +** WINDOW_RETURN_ROW: +** An input row can be discarded after it is returned to the caller. +** +** WINDOW_AGGINVERSE: +** An input row can be discarded after the window functions xInverse() +** callbacks have been invoked in it. +** +** WINDOW_AGGSTEP: +** An input row can be discarded after the window functions xStep() +** callbacks have been invoked in it. +** +** start,current,end +** Consider a window-frame similar to the following: +** +** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) +** +** The windows functions implementation caches the input rows in a temp +** table, sorted by "a, b" (it actually populates the cache lazily, and +** aggressively removes rows once they are no longer required, but that's +** a mere detail). It keeps three cursors open on the temp table. One +** (current) that points to the next row to return to the query engine +** once its window function values have been calculated. Another (end) +** points to the next row to call the xStep() method of each window function +** on (so that it is 2 groups ahead of current). And a third (start) that +** points to the next row to call the xInverse() method of each window +** function on. +** +** Each cursor (start, current and end) consists of a VDBE cursor +** (WindowCsrAndReg.csr) and an array of registers (starting at +** WindowCodeArg.reg) that always contains a copy of the peer values +** read from the corresponding cursor. +** +** Depending on the window-frame in question, all three cursors may not +** be required. In this case both WindowCodeArg.csr and reg are set to +** 0. +*/ +struct WindowCodeArg { + Parse *pParse; /* Parse context */ + Window *pMWin; /* First in list of functions being processed */ + Vdbe *pVdbe; /* VDBE object */ + int addrGosub; /* OP_Gosub to this address to return one row */ + int regGosub; /* Register used with OP_Gosub(addrGosub) */ + int regArg; /* First in array of accumulator registers */ + int eDelete; /* See above */ + int regRowid; + + WindowCsrAndReg start; + WindowCsrAndReg current; + WindowCsrAndReg end; +}; + +/* +** Generate VM code to read the window frames peer values from cursor csr into +** an array of registers starting at reg. +*/ +static void windowReadPeerValues( + WindowCodeArg *p, + int csr, + int reg +){ + Window *pMWin = p->pMWin; + ExprList *pOrderBy = pMWin->pOrderBy; + if( pOrderBy ){ + Vdbe *v = sqlite3GetVdbe(p->pParse); + ExprList *pPart = pMWin->pPartition; + int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0); + int i; + for(i=0; inExpr; i++){ + sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i); + } + } +} + +/* +** Generate VM code to invoke either xStep() (if bInverse is 0) or +** xInverse (if bInverse is non-zero) for each window function in the +** linked list starting at pMWin. Or, for built-in window functions +** that do not use the standard function API, generate the required +** inline VM code. +** +** If argument csr is greater than or equal to 0, then argument reg is +** the first register in an array of registers guaranteed to be large +** enough to hold the array of arguments for each function. In this case +** the arguments are extracted from the current row of csr into the +** array of registers before invoking OP_AggStep or OP_AggInverse +** +** Or, if csr is less than zero, then the array of registers at reg is +** already populated with all columns from the current row of the sub-query. +** +** If argument regPartSize is non-zero, then it is a register containing the +** number of rows in the current partition. +*/ +static void windowAggStep( + WindowCodeArg *p, + Window *pMWin, /* Linked list of window functions */ + int csr, /* Read arguments from this cursor */ + int bInverse, /* True to invoke xInverse instead of xStep */ + int reg /* Array of registers */ +){ + Parse *pParse = p->pParse; + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + int regArg; + int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); + int i; + + assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); + + /* All OVER clauses in the same window function aggregate step must + ** be the same. */ + assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 ); + + for(i=0; izName!=nth_valueName ){ + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i); + } + } + regArg = reg; + + if( pMWin->regStartRowid==0 + && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pWin->eStart!=TK_UNBOUNDED) + ){ + int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); + VdbeCoverage(v); + if( bInverse==0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); + }else{ + sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + } + sqlite3VdbeJumpHere(v, addrIsNull); + }else if( pWin->regApp ){ + assert( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ); + assert( bInverse==0 || bInverse==1 ); + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); + }else if( pFunc->xSFunc!=noopStepFunc ){ + int addrIf = 0; + if( pWin->pFilter ){ + int regTmp; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regTmp); + } + + if( pWin->bExprArgs ){ + int iOp = sqlite3VdbeCurrentAddr(v); + int iEnd; + + assert( ExprUseXList(pWin->pOwner) ); + nArg = pWin->pOwner->x.pList->nExpr; + regArg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); + + for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pMWin->iEphCsr ){ + pOp->p1 = csr; + } + } + } + if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl; + assert( nArg>0 ); + assert( ExprUseXList(pWin->pOwner) ); + pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); + sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, + bInverse, regArg, pWin->regAccum); + sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + if( pWin->bExprArgs ){ + sqlite3ReleaseTempRange(pParse, regArg, nArg); + } + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); + } + } +} + +/* +** Values that may be passed as the second argument to windowCodeOp(). +*/ +#define WINDOW_RETURN_ROW 1 +#define WINDOW_AGGINVERSE 2 +#define WINDOW_AGGSTEP 3 + +/* +** Generate VM code to invoke either xValue() (bFin==0) or xFinalize() +** (bFin==1) for each window function in the linked list starting at +** pMWin. Or, for built-in window-functions that do not use the standard +** API, generate the equivalent VM code. +*/ +static void windowAggFinal(WindowCodeArg *p, int bFin){ + Parse *pParse = p->pParse; + Window *pMWin = p->pMWin; + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + if( pMWin->regStartRowid==0 + && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pWin->eStart!=TK_UNBOUNDED) + ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + }else if( pWin->regApp ){ + assert( pMWin->regStartRowid==0 ); + }else{ + int nArg = windowArgCount(pWin); + if( bFin ){ + sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg); + sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + }else{ + sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult); + sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF); + } + } + } +} + +/* +** Generate code to calculate the current values of all window functions in the +** p->pMWin list by doing a full scan of the current window frame. Store the +** results in the Window.regResult registers, ready to return the upper +** layer. +*/ +static void windowFullScan(WindowCodeArg *p){ + Window *pWin; + Parse *pParse = p->pParse; + Window *pMWin = p->pMWin; + Vdbe *v = p->pVdbe; + + int regCRowid = 0; /* Current rowid value */ + int regCPeer = 0; /* Current peer values */ + int regRowid = 0; /* AggStep rowid value */ + int regPeer = 0; /* AggStep peer values */ + + int nPeer; + int lblNext; + int lblBrk; + int addrNext; + int csr; + + VdbeModuleComment((v, "windowFullScan begin")); + + assert( pMWin!=0 ); + csr = pMWin->csrApp; + nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); + + lblNext = sqlite3VdbeMakeLabel(pParse); + lblBrk = sqlite3VdbeMakeLabel(pParse); + + regCRowid = sqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); + if( nPeer ){ + regCPeer = sqlite3GetTempRange(pParse, nPeer); + regPeer = sqlite3GetTempRange(pParse, nPeer); + } + + sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid); + windowReadPeerValues(p, pMWin->iEphCsr, regCPeer); + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + } + + sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid); + VdbeCoverage(v); + addrNext = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid); + sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid); + VdbeCoverageNeverNull(v); + + if( pMWin->eExclude==TK_CURRENT ){ + sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid); + VdbeCoverageNeverNull(v); + }else if( pMWin->eExclude!=TK_NO ){ + int addr; + int addrEq = 0; + KeyInfo *pKeyInfo = 0; + + if( pMWin->pOrderBy ){ + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0); + } + if( pMWin->eExclude==TK_TIES ){ + addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid); + VdbeCoverageNeverNull(v); + } + if( pKeyInfo ){ + windowReadPeerValues(p, csr, regPeer); + sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addr = sqlite3VdbeCurrentAddr(v)+1; + sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr); + VdbeCoverageEqNe(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext); + } + if( addrEq ) sqlite3VdbeJumpHere(v, addrEq); + } + + windowAggStep(p, pMWin, csr, 0, p->regArg); + + sqlite3VdbeResolveLabel(v, lblNext); + sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrNext-1); + sqlite3VdbeJumpHere(v, addrNext+1); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regCRowid); + if( nPeer ){ + sqlite3ReleaseTempRange(pParse, regPeer, nPeer); + sqlite3ReleaseTempRange(pParse, regCPeer, nPeer); + } + + windowAggFinal(p, 1); + VdbeModuleComment((v, "windowFullScan end")); +} + +/* +** Invoke the sub-routine at regGosub (generated by code in select.c) to +** return the current row of Window.iEphCsr. If all window functions are +** aggregate window functions that use the standard API, a single +** OP_Gosub instruction is all that this routine generates. Extra VM code +** for per-row processing is only generated for the following built-in window +** functions: +** +** nth_value() +** first_value() +** lag() +** lead() +*/ +static void windowReturnOneRow(WindowCodeArg *p){ + Window *pMWin = p->pMWin; + Vdbe *v = p->pVdbe; + + if( pMWin->regStartRowid ){ + windowFullScan(p); + }else{ + Parse *pParse = p->pParse; + Window *pWin; + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + assert( ExprUseXList(pWin->pOwner) ); + if( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ){ + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(pParse); + int tmpReg = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + + if( pFunc->zName==nth_valueName ){ + sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg); + windowCheckValue(pParse, tmpReg, 2); + }else{ + sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); + } + sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); + sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + else if( pFunc->zName==leadName || pFunc->zName==lagName ){ + int nArg = pWin->pOwner->x.pList->nExpr; + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(pParse); + int tmpReg = sqlite3GetTempReg(pParse); + int iEph = pMWin->iEphCsr; + + if( nArg<3 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult); + } + sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); + if( nArg<2 ){ + int val = (pFunc->zName==leadName ? 1 : -1); + sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); + }else{ + int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract); + int tmpReg2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); + sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); + sqlite3ReleaseTempReg(pParse, tmpReg2); + } + + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + } + } + sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub); +} + +/* +** Generate code to set the accumulator register for each window function +** in the linked list passed as the second argument to NULL. And perform +** any equivalent initialization required by any built-in window functions +** in the list. +*/ +static int windowInitAccum(Parse *pParse, Window *pMWin){ + Vdbe *v = sqlite3GetVdbe(pParse); + int regArg; + int nArg = 0; + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + assert( pWin->regAccum ); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + nArg = MAX(nArg, windowArgCount(pWin)); + if( pMWin->regStartRowid==0 ){ + if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + + if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){ + assert( pWin->eStart!=TK_UNBOUNDED ); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + } + } + regArg = pParse->nMem+1; + pParse->nMem += nArg; + return regArg; +} + +/* +** Return true if the current frame should be cached in the ephemeral table, +** even if there are no xInverse() calls required. +*/ +static int windowCacheFrame(Window *pMWin){ + Window *pWin; + if( pMWin->regStartRowid ) return 1; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + if( (pFunc->zName==nth_valueName) + || (pFunc->zName==first_valueName) + || (pFunc->zName==leadName) + || (pFunc->zName==lagName) + ){ + return 1; + } + } + return 0; +} + +/* +** regOld and regNew are each the first register in an array of size +** pOrderBy->nExpr. This function generates code to compare the two +** arrays of registers using the collation sequences and other comparison +** parameters specified by pOrderBy. +** +** If the two arrays are not equal, the contents of regNew is copied to +** regOld and control falls through. Otherwise, if the contents of the arrays +** are equal, an OP_Goto is executed. The address of the OP_Goto is returned. +*/ +static void windowIfNewPeer( + Parse *pParse, + ExprList *pOrderBy, + int regNew, /* First in array of new values */ + int regOld, /* First in array of old values */ + int addr /* Jump here */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( pOrderBy ){ + int nVal = pOrderBy->nExpr; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, + sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1 + ); + VdbeCoverageEqNe(v); + sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + } +} + +/* +** This function is called as part of generating VM programs for RANGE +** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for +** the ORDER BY term in the window, and that argument op is OP_Ge, it generates +** code equivalent to: +** +** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl; +** +** The value of parameter op may also be OP_Gt or OP_Le. In these cases the +** operator in the above pseudo-code is replaced with ">" or "<=", respectively. +** +** If the sort-order for the ORDER BY term in the window is DESC, then the +** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is +** subtracted. And the comparison operator is inverted to - ">=" becomes "<=", +** ">" becomes "<", and so on. So, with DESC sort order, if the argument op +** is OP_Ge, the generated code is equivalent to: +** +** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl; +** +** A special type of arithmetic is used such that if csr1.peerVal is not +** a numeric type (real or integer), then the result of the addition +** or subtraction is a a copy of csr1.peerVal. +*/ +static void windowCodeRangeTest( + WindowCodeArg *p, + int op, /* OP_Ge, OP_Gt, or OP_Le */ + int csr1, /* Cursor number for cursor 1 */ + int regVal, /* Register containing non-negative number */ + int csr2, /* Cursor number for cursor 2 */ + int lbl /* Jump destination if condition is true */ +){ + Parse *pParse = p->pParse; + Vdbe *v = sqlite3GetVdbe(pParse); + ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */ + int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */ + int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */ + int regString = ++pParse->nMem; /* Reg. for constant value '' */ + int arith = OP_Add; /* OP_Add or OP_Subtract */ + int addrGe; /* Jump destination */ + int addrDone = sqlite3VdbeMakeLabel(pParse); /* Address past OP_Ge */ + CollSeq *pColl; + + /* Read the peer-value from each cursor into a register */ + windowReadPeerValues(p, csr1, reg1); + windowReadPeerValues(p, csr2, reg2); + + assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); + assert( pOrderBy && pOrderBy->nExpr==1 ); + if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){ + switch( op ){ + case OP_Ge: op = OP_Le; break; + case OP_Gt: op = OP_Lt; break; + default: assert( op==OP_Le ); op = OP_Ge; break; + } + arith = OP_Subtract; + } + + VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl", + reg1, (arith==OP_Add ? "+" : "-"), regVal, + ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2 + )); + + /* If the BIGNULL flag is set for the ORDER BY, then it is required to + ** consider NULL values to be larger than all other values, instead of + ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this + ** (and adding that capability causes a performance regression), so + ** instead if the BIGNULL flag is set then cases where either reg1 or + ** reg2 are NULL are handled separately in the following block. The code + ** generated is equivalent to: + ** + ** if( reg1 IS NULL ){ + ** if( op==OP_Ge ) goto lbl; + ** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl; + ** if( op==OP_Le && reg2 IS NULL ) goto lbl; + ** }else if( reg2 IS NULL ){ + ** if( op==OP_Le ) goto lbl; + ** } + ** + ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is + ** not taken, control jumps over the comparison operator coded below this + ** block. */ + if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){ + /* This block runs if reg1 contains a NULL. */ + int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); + switch( op ){ + case OP_Ge: + sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); + break; + case OP_Gt: + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); + VdbeCoverage(v); + break; + case OP_Le: + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); + VdbeCoverage(v); + break; + default: assert( op==OP_Lt ); /* no-op */ break; + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone); + + /* This block runs if reg1 is not NULL, but reg2 is. */ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, + (op==OP_Gt || op==OP_Ge) ? addrDone : lbl); + VdbeCoverage(v); + } + + /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). + ** This block adds (or subtracts for DESC) the numeric value in regVal + ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), + ** then leave reg1 as it is. In pseudo-code, this is implemented as: + ** + ** if( reg1>='' ) goto addrGe; + ** reg1 = reg1 +/- regVal + ** addrGe: + ** + ** Since all strings and blobs are greater-than-or-equal-to an empty string, + ** the add/subtract is skipped for these, as required. If reg1 is a NULL, + ** then the arithmetic is performed, but since adding or subtracting from + ** NULL is always NULL anyway, this case is handled as required too. */ + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); + VdbeCoverage(v); + if( (op==OP_Ge && arith==OP_Add) || (op==OP_Le && arith==OP_Subtract) ){ + sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); + sqlite3VdbeJumpHere(v, addrGe); + + /* Compare registers reg2 and reg1, taking the jump if required. Note that + ** control skips over this test if the BIGNULL flag is set and either + ** reg1 or reg2 contain a NULL value. */ + sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr); + sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + sqlite3VdbeResolveLabel(v, addrDone); + + assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); + testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge); + testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt); + testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le); + testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt); + sqlite3ReleaseTempReg(pParse, reg1); + sqlite3ReleaseTempReg(pParse, reg2); + + VdbeModuleComment((v, "CodeRangeTest: end")); +} + +/* +** Helper function for sqlite3WindowCodeStep(). Each call to this function +** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE +** operation. Refer to the header comment for sqlite3WindowCodeStep() for +** details. +*/ +static int windowCodeOp( + WindowCodeArg *p, /* Context object */ + int op, /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */ + int regCountdown, /* Register for OP_IfPos countdown */ + int jumpOnEof /* Jump here if stepped cursor reaches EOF */ +){ + int csr, reg; + Parse *pParse = p->pParse; + Window *pMWin = p->pMWin; + int ret = 0; + Vdbe *v = p->pVdbe; + int addrContinue = 0; + int bPeer = (pMWin->eFrmType!=TK_ROWS); + + int lblDone = sqlite3VdbeMakeLabel(pParse); + int addrNextRange = 0; + + /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame + ** starts with UNBOUNDED PRECEDING. */ + if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){ + assert( regCountdown==0 && jumpOnEof==0 ); + return 0; + } + + if( regCountdown>0 ){ + if( pMWin->eFrmType==TK_RANGE ){ + addrNextRange = sqlite3VdbeCurrentAddr(v); + assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP ); + if( op==WINDOW_AGGINVERSE ){ + if( pMWin->eStart==TK_FOLLOWING ){ + windowCodeRangeTest( + p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone + ); + }else{ + windowCodeRangeTest( + p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone + ); + } + }else{ + windowCodeRangeTest( + p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone + ); + } + }else{ + sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1); + VdbeCoverage(v); + } + } + + if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){ + windowAggFinal(p, 0); + } + addrContinue = sqlite3VdbeCurrentAddr(v); + + /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or + ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the + ** start cursor does not advance past the end cursor within the + ** temporary table. It otherwise might, if (a>b). Also ensure that, + ** if the input cursor is still finding new rows, that the end + ** cursor does not go past it to EOF. */ + if( pMWin->eStart==pMWin->eEnd && regCountdown + && pMWin->eFrmType==TK_RANGE + ){ + int regRowid1 = sqlite3GetTempReg(pParse); + int regRowid2 = sqlite3GetTempReg(pParse); + if( op==WINDOW_AGGINVERSE ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); + sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); + VdbeCoverage(v); + }else if( p->regRowid ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1); + sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1); + VdbeCoverageNeverNull(v); + } + sqlite3ReleaseTempReg(pParse, regRowid1); + sqlite3ReleaseTempReg(pParse, regRowid2); + assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ); + } + + switch( op ){ + case WINDOW_RETURN_ROW: + csr = p->current.csr; + reg = p->current.reg; + windowReturnOneRow(p); + break; + + case WINDOW_AGGINVERSE: + csr = p->start.csr; + reg = p->start.reg; + if( pMWin->regStartRowid ){ + assert( pMWin->regEndRowid ); + sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1); + }else{ + windowAggStep(p, pMWin, csr, 1, p->regArg); + } + break; + + default: + assert( op==WINDOW_AGGSTEP ); + csr = p->end.csr; + reg = p->end.reg; + if( pMWin->regStartRowid ){ + assert( pMWin->regEndRowid ); + sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1); + }else{ + windowAggStep(p, pMWin, csr, 0, p->regArg); + } + break; + } + + if( op==p->eDelete ){ + sqlite3VdbeAddOp1(v, OP_Delete, csr); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + } + + if( jumpOnEof ){ + sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + ret = sqlite3VdbeAddOp0(v, OP_Goto); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer); + VdbeCoverage(v); + if( bPeer ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone); + } + } + + if( bPeer ){ + int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); + int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0); + windowReadPeerValues(p, csr, regTmp); + windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue); + sqlite3ReleaseTempRange(pParse, regTmp, nReg); + } + + if( addrNextRange ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange); + } + sqlite3VdbeResolveLabel(v, lblDone); + return ret; +} + + +/* +** Allocate and return a duplicate of the Window object indicated by the +** third argument. Set the Window.pOwner field of the new object to +** pOwner. +*/ +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ + Window *pNew = 0; + if( ALWAYS(p) ){ + pNew = sqlite3DbMallocZero(db, sizeof(Window)); + if( pNew ){ + pNew->zName = sqlite3DbStrDup(db, p->zName); + pNew->zBase = sqlite3DbStrDup(db, p->zBase); + pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); + pNew->pWFunc = p->pWFunc; + pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); + pNew->eFrmType = p->eFrmType; + pNew->eEnd = p->eEnd; + pNew->eStart = p->eStart; + pNew->eExclude = p->eExclude; + pNew->regResult = p->regResult; + pNew->regAccum = p->regAccum; + pNew->iArgCol = p->iArgCol; + pNew->iEphCsr = p->iEphCsr; + pNew->bExprArgs = p->bExprArgs; + pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); + pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); + pNew->pOwner = pOwner; + pNew->bImplicitFrame = p->bImplicitFrame; + } + } + return pNew; +} + +/* +** Return a copy of the linked list of Window objects passed as the +** second argument. +*/ +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ + Window *pWin; + Window *pRet = 0; + Window **pp = &pRet; + + for(pWin=p; pWin; pWin=pWin->pNextWin){ + *pp = sqlite3WindowDup(db, 0, pWin); + if( *pp==0 ) break; + pp = &((*pp)->pNextWin); + } + + return pRet; +} + +/* +** Return true if it can be determined at compile time that expression +** pExpr evaluates to a value that, when cast to an integer, is greater +** than zero. False otherwise. +** +** If an OOM error occurs, this function sets the Parse.db.mallocFailed +** flag and returns zero. +*/ +static int windowExprGtZero(Parse *pParse, Expr *pExpr){ + int ret = 0; + sqlite3 *db = pParse->db; + sqlite3_value *pVal = 0; + sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal); + if( pVal && sqlite3_value_int(pVal)>0 ){ + ret = 1; + } + sqlite3ValueFree(pVal); + return ret; +} + +/* +** sqlite3WhereBegin() has already been called for the SELECT statement +** passed as the second argument when this function is invoked. It generates +** code to populate the Window.regResult register for each window function +** and invoke the sub-routine at instruction addrGosub once for each row. +** sqlite3WhereEnd() is always called before returning. +** +** This function handles several different types of window frames, which +** require slightly different processing. The following pseudo code is +** used to implement window frames of the form: +** +** ROWS BETWEEN PRECEDING AND FOLLOWING +** +** Other window frame types use variants of the following: +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** +** if( first row of partition ){ +** // Rewind three cursors, all open on the eph table. +** Rewind(csrEnd); +** Rewind(csrStart); +** Rewind(csrCurrent); +** +** regEnd = // FOLLOWING expression +** regStart = // PRECEDING expression +** }else{ +** // First time this branch is taken, the eph table contains two +** // rows. The first row in the partition, which all three cursors +** // currently point to, and the following row. +** AGGSTEP +** if( (regEnd--)<=0 ){ +** RETURN_ROW +** if( (regStart--)<=0 ){ +** AGGINVERSE +** } +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** RETURN ROW +** if( csrCurrent is EOF ) break; +** if( (regStart--)<=0 ){ +** AggInverse(csrStart) +** Next(csrStart) +** } +** } +** +** The pseudo-code above uses the following shorthand: +** +** AGGSTEP: invoke the aggregate xStep() function for each window function +** with arguments read from the current row of cursor csrEnd, then +** step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()). +** +** RETURN_ROW: return a row to the caller based on the contents of the +** current row of csrCurrent and the current state of all +** aggregates. Then step cursor csrCurrent forward one row. +** +** AGGINVERSE: invoke the aggregate xInverse() function for each window +** functions with arguments read from the current row of cursor +** csrStart. Then step csrStart forward one row. +** +** There are two other ROWS window frames that are handled significantly +** differently from the above - "BETWEEN PRECEDING AND PRECEDING" +** and "BETWEEN FOLLOWING AND FOLLOWING". These are special +** cases because they change the order in which the three cursors (csrStart, +** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that +** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these +** three. +** +** ROWS BETWEEN PRECEDING AND PRECEDING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** if( (regEnd--)<=0 ){ +** AGGSTEP +** } +** RETURN_ROW +** if( (regStart--)<=0 ){ +** AGGINVERSE +** } +** } +** } +** flush: +** if( (regEnd--)<=0 ){ +** AGGSTEP +** } +** RETURN_ROW +** +** +** ROWS BETWEEN FOLLOWING AND FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = regEnd - +** }else{ +** AGGSTEP +** if( (regEnd--)<=0 ){ +** RETURN_ROW +** } +** if( (regStart--)<=0 ){ +** AGGINVERSE +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** if( (regEnd--)<=0 ){ +** RETURN_ROW +** if( eof ) break; +** } +** if( (regStart--)<=0 ){ +** AGGINVERSE +** if( eof ) break +** } +** } +** while( !eof csrCurrent ){ +** RETURN_ROW +** } +** +** For the most part, the patterns above are adapted to support UNBOUNDED by +** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and +** CURRENT ROW by assuming that it is equivalent to "0 PRECEDING/FOLLOWING". +** This is optimized of course - branches that will never be taken and +** conditions that are always true are omitted from the VM code. The only +** exceptional case is: +** +** ROWS BETWEEN FOLLOWING AND UNBOUNDED FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regStart = +** }else{ +** AGGSTEP +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** if( (regStart--)<=0 ){ +** AGGINVERSE +** if( eof ) break +** } +** RETURN_ROW +** } +** while( !eof csrCurrent ){ +** RETURN_ROW +** } +** +** Also requiring special handling are the cases: +** +** ROWS BETWEEN PRECEDING AND PRECEDING +** ROWS BETWEEN FOLLOWING AND FOLLOWING +** +** when (expr1 < expr2). This is detected at runtime, not by this function. +** To handle this case, the pseudo-code programs depicted above are modified +** slightly to be: +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** if( regEnd < regStart ){ +** RETURN_ROW +** delete eph table contents +** continue +** } +** ... +** +** The new "continue" statement in the above jumps to the next iteration +** of the outer loop - the one started by sqlite3WhereBegin(). +** +** The various GROUPS cases are implemented using the same patterns as +** ROWS. The VM code is modified slightly so that: +** +** 1. The else branch in the main loop is only taken if the row just +** added to the ephemeral table is the start of a new group. In +** other words, it becomes: +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else if( new group ){ +** ... +** } +** } +** +** 2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or +** AGGINVERSE step processes the current row of the relevant cursor and +** all subsequent rows belonging to the same group. +** +** RANGE window frames are a little different again. As for GROUPS, the +** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE +** deal in groups instead of rows. As for ROWS and GROUPS, there are three +** basic cases: +** +** RANGE BETWEEN PRECEDING AND FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** AGGSTEP +** while( (csrCurrent.key + regEnd) < csrEnd.key ){ +** RETURN_ROW +** while( csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** RETURN ROW +** if( csrCurrent is EOF ) break; +** while( csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** } +** } +** +** In the above notation, "csr.key" means the current value of the ORDER BY +** expression (there is only ever 1 for a RANGE that uses an FOLLOWING +** or PRECEDING AND PRECEDING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** while( (csrEnd.key + regEnd) <= csrCurrent.key ){ +** AGGSTEP +** } +** while( (csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** RETURN_ROW +** } +** } +** flush: +** while( (csrEnd.key + regEnd) <= csrCurrent.key ){ +** AGGSTEP +** } +** while( (csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** RETURN_ROW +** +** RANGE BETWEEN FOLLOWING AND FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** AGGSTEP +** while( (csrCurrent.key + regEnd) < csrEnd.key ){ +** while( (csrCurrent.key + regStart) > csrStart.key ){ +** AGGINVERSE +** } +** RETURN_ROW +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** while( (csrCurrent.key + regStart) > csrStart.key ){ +** AGGINVERSE +** if( eof ) break "while( 1 )" loop. +** } +** RETURN_ROW +** } +** while( !eof csrCurrent ){ +** RETURN_ROW +** } +** +** The text above leaves out many details. Refer to the code and comments +** below for a more complete picture. +*/ +SQLITE_PRIVATE void sqlite3WindowCodeStep( + Parse *pParse, /* Parse context */ + Select *p, /* Rewritten SELECT statement */ + WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */ + int regGosub, /* Register for OP_Gosub */ + int addrGosub /* OP_Gosub here to return each row */ +){ + Window *pMWin = p->pWin; + ExprList *pOrderBy = pMWin->pOrderBy; + Vdbe *v = sqlite3GetVdbe(pParse); + int csrWrite; /* Cursor used to write to eph. table */ + int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ + int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ + int iInput; /* To iterate through sub cols */ + int addrNe; /* Address of OP_Ne */ + int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ + int addrInteger = 0; /* Address of OP_Integer */ + int addrEmpty; /* Address of OP_Rewind in flush: */ + int regNew; /* Array of registers holding new input row */ + int regRecord; /* regNew array in record form */ + int regNewPeer = 0; /* Peer values for new row (part of regNew) */ + int regPeer = 0; /* Peer values for current row */ + int regFlushPart = 0; /* Register for "Gosub flush_partition" */ + WindowCodeArg s; /* Context object for sub-routines */ + int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */ + int regStart = 0; /* Value of PRECEDING */ + int regEnd = 0; /* Value of FOLLOWING */ + + assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED + ); + assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT + || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING + ); + assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT + || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES + || pMWin->eExclude==TK_NO + ); + + lblWhereEnd = sqlite3VdbeMakeLabel(pParse); + + /* Fill in the context object */ + memset(&s, 0, sizeof(WindowCodeArg)); + s.pParse = pParse; + s.pMWin = pMWin; + s.pVdbe = v; + s.regGosub = regGosub; + s.addrGosub = addrGosub; + s.current.csr = pMWin->iEphCsr; + csrWrite = s.current.csr+1; + s.start.csr = s.current.csr+2; + s.end.csr = s.current.csr+3; + + /* Figure out when rows may be deleted from the ephemeral table. There + ** are four options - they may never be deleted (eDelete==0), they may + ** be deleted as soon as they are no longer part of the window frame + ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row + ** has been returned to the caller (WINDOW_RETURN_ROW), or they may + ** be deleted after they enter the frame (WINDOW_AGGSTEP). */ + switch( pMWin->eStart ){ + case TK_FOLLOWING: + if( pMWin->eFrmType!=TK_RANGE + && windowExprGtZero(pParse, pMWin->pStart) + ){ + s.eDelete = WINDOW_RETURN_ROW; + } + break; + case TK_UNBOUNDED: + if( windowCacheFrame(pMWin)==0 ){ + if( pMWin->eEnd==TK_PRECEDING ){ + if( pMWin->eFrmType!=TK_RANGE + && windowExprGtZero(pParse, pMWin->pEnd) + ){ + s.eDelete = WINDOW_AGGSTEP; + } + }else{ + s.eDelete = WINDOW_RETURN_ROW; + } + } + break; + default: + s.eDelete = WINDOW_AGGINVERSE; + break; + } + + /* Allocate registers for the array of values from the sub-query, the + ** same values in record form, and the rowid used to insert said record + ** into the ephemeral table. */ + regNew = pParse->nMem+1; + pParse->nMem += nInput; + regRecord = ++pParse->nMem; + s.regRowid = ++pParse->nMem; + + /* If the window frame contains an " PRECEDING" or " FOLLOWING" + ** clause, allocate registers to store the results of evaluating each + ** . */ + if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){ + regStart = ++pParse->nMem; + } + if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){ + regEnd = ++pParse->nMem; + } + + /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of + ** registers to store copies of the ORDER BY expressions (peer values) + ** for the main loop, and for each cursor (start, current and end). */ + if( pMWin->eFrmType!=TK_ROWS ){ + int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); + regNewPeer = regNew + pMWin->nBufferCol; + if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr; + regPeer = pParse->nMem+1; pParse->nMem += nPeer; + s.start.reg = pParse->nMem+1; pParse->nMem += nPeer; + s.current.reg = pParse->nMem+1; pParse->nMem += nPeer; + s.end.reg = pParse->nMem+1; pParse->nMem += nPeer; + } + + /* Load the column values for the row returned by the sub-select + ** into an array of registers starting at regNew. Assemble them into + ** a record in register regRecord. */ + for(iInput=0; iInputpPartition ){ + int addr; + ExprList *pPart = pMWin->pPartition; + int nPart = pPart->nExpr; + int regNewPart = regNew + pMWin->nBufferCol; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + + regFlushPart = ++pParse->nMem; + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); + VdbeCoverageEqNe(v); + addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart); + VdbeComment((v, "call flush_partition")); + sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); + } + + /* Insert the new row into the ephemeral table */ + sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid); + addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid); + VdbeCoverageNeverNull(v); + + /* This block is run for the first row of each partition */ + s.regArg = windowInitAccum(pParse, pMWin); + + if( regStart ){ + sqlite3ExprCode(pParse, pMWin->pStart, regStart); + windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0)); + } + if( regEnd ){ + sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); + windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0)); + } + + if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){ + int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); + int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); + VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */ + VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ + windowAggFinal(&s, 0); + sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); + windowReturnOneRow(&s); + sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); + sqlite3VdbeJumpHere(v, addrGe); + } + if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){ + assert( pMWin->eEnd==TK_FOLLOWING ); + sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); + } + + if( pMWin->eStart!=TK_UNBOUNDED ){ + sqlite3VdbeAddOp1(v, OP_Rewind, s.start.csr); + } + sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); + sqlite3VdbeAddOp1(v, OP_Rewind, s.end.csr); + if( regPeer && pOrderBy ){ + sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1); + } + + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); + + sqlite3VdbeJumpHere(v, addrNe); + + /* Beginning of the block executed for the second and subsequent rows. */ + if( regPeer ){ + windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd); + } + if( pMWin->eStart==TK_FOLLOWING ){ + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + if( pMWin->eEnd!=TK_UNBOUNDED ){ + if( pMWin->eFrmType==TK_RANGE ){ + int lbl = sqlite3VdbeMakeLabel(pParse); + int addrNext = sqlite3VdbeCurrentAddr(v); + windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); + sqlite3VdbeResolveLabel(v, lbl); + }else{ + windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + } + } + }else + if( pMWin->eEnd==TK_PRECEDING ){ + int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE); + windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0); + if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + if( !bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + }else{ + int addr = 0; + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + if( pMWin->eEnd!=TK_UNBOUNDED ){ + if( pMWin->eFrmType==TK_RANGE ){ + int lbl = 0; + addr = sqlite3VdbeCurrentAddr(v); + if( regEnd ){ + lbl = sqlite3VdbeMakeLabel(pParse); + windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); + } + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + if( regEnd ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + sqlite3VdbeResolveLabel(v, lbl); + } + }else{ + if( regEnd ){ + addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1); + VdbeCoverage(v); + } + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + if( regEnd ) sqlite3VdbeJumpHere(v, addr); + } + } + } + + /* End of the main input loop */ + sqlite3VdbeResolveLabel(v, lblWhereEnd); + sqlite3WhereEnd(pWInfo); + + /* Fall through */ + if( pMWin->pPartition ){ + addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart); + sqlite3VdbeJumpHere(v, addrGosubFlush); + } + + s.regRowid = 0; + addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite); + VdbeCoverage(v); + if( pMWin->eEnd==TK_PRECEDING ){ + int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE); + windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0); + if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + }else if( pMWin->eStart==TK_FOLLOWING ){ + int addrStart; + int addrBreak1; + int addrBreak2; + int addrBreak3; + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + if( pMWin->eFrmType==TK_RANGE ){ + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); + }else + if( pMWin->eEnd==TK_UNBOUNDED ){ + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1); + }else{ + assert( pMWin->eEnd==TK_FOLLOWING ); + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak2); + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak1); + sqlite3VdbeJumpHere(v, addrBreak3); + }else{ + int addrBreak; + int addrStart; + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak); + } + sqlite3VdbeJumpHere(v, addrEmpty); + + sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); + if( pMWin->pPartition ){ + if( pMWin->regStartRowid ){ + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); + } + sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + } +} + +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/************** End of window.c **********************************************/ +/************** Begin file parse.c *******************************************/ +/* This file is automatically generated by Lemon from input grammar +** source file "parse.y" with these options: +** +** -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT +*/ +/* +** 2001-09-15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains SQLite's SQL parser. +** +** The canonical source code to this file ("parse.y") is a Lemon grammar +** file that specifies the input grammar and actions to take while parsing. +** That input file is processed by Lemon to generate a C-language +** implementation of a parser for the given grammar. You might be reading +** this comment as part of the translated C-code. Edits should be made +** to the original parse.y sources. +*/ + +/* #include "sqliteInt.h" */ + +/* +** Disable all error recovery processing in the parser push-down +** automaton. +*/ +#define YYNOERRORRECOVERY 1 + +/* +** Make yytestcase() the same as testcase() +*/ +#define yytestcase(X) testcase(X) + +/* +** Indicate that sqlite3ParserFree() will never be called with a null +** pointer. +*/ +#define YYPARSEFREENEVERNULL 1 + +/* +** In the amalgamation, the parse.c file generated by lemon and the +** tokenize.c file are concatenated. In that case, sqlite3RunParser() +** has access to the the size of the yyParser object and so the parser +** engine can be allocated from stack. In that case, only the +** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked +** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be +** omitted. +*/ +#ifdef SQLITE_AMALGAMATION +# define sqlite3Parser_ENGINEALWAYSONSTACK 1 +#endif + +/* +** Alternative datatype for the argument to the malloc() routine passed +** into sqlite3ParserAlloc(). The default is size_t. +*/ +#define YYMALLOCARGTYPE u64 + +/* +** An instance of the following structure describes the event of a +** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, +** TK_DELETE, or TK_INSTEAD. If the event is of the form +** +** UPDATE ON (a,b,c) +** +** Then the "b" IdList records the list "a,b,c". +*/ +struct TrigEvent { int a; IdList * b; }; + +struct FrameBound { int eType; Expr *pExpr; }; + +/* +** Disable lookaside memory allocation for objects that might be +** shared across database connections. +*/ +static void disableLookaside(Parse *pParse){ + sqlite3 *db = pParse->db; + pParse->disableLookaside++; + DisableLookaside; +} + +#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \ + && defined(SQLITE_UDL_CAPABLE_PARSER) +/* +** Issue an error message if an ORDER BY or LIMIT clause occurs on an +** UPDATE or DELETE statement. +*/ +static void updateDeleteLimitError( + Parse *pParse, + ExprList *pOrderBy, + Expr *pLimit +){ + if( pOrderBy ){ + sqlite3ErrorMsg(pParse, "syntax error near \"ORDER BY\""); + }else{ + sqlite3ErrorMsg(pParse, "syntax error near \"LIMIT\""); + } + sqlite3ExprListDelete(pParse->db, pOrderBy); + sqlite3ExprDelete(pParse->db, pLimit); +} +#endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */ + + + /* + ** For a compound SELECT statement, make sure p->pPrior->pNext==p for + ** all elements in the list. And make sure list length does not exceed + ** SQLITE_LIMIT_COMPOUND_SELECT. + */ + static void parserDoubleLinkSelect(Parse *pParse, Select *p){ + assert( p!=0 ); + if( p->pPrior ){ + Select *pNext = 0, *pLoop = p; + int mxSelect, cnt = 1; + while(1){ + pLoop->pNext = pNext; + pLoop->selFlags |= SF_Compound; + pNext = pLoop; + pLoop = pLoop->pPrior; + if( pLoop==0 ) break; + cnt++; + if( pLoop->pOrderBy || pLoop->pLimit ){ + sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", + pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", + sqlite3SelectOpName(pNext->op)); + break; + } + } + if( (p->selFlags & SF_MultiValue)==0 && + (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && + cnt>mxSelect + ){ + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + } + } + } + + /* Attach a With object describing the WITH clause to a Select + ** object describing the query for which the WITH clause is a prefix. + */ + static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){ + if( pSelect ){ + pSelect->pWith = pWith; + parserDoubleLinkSelect(pParse, pSelect); + }else{ + sqlite3WithDelete(pParse->db, pWith); + } + return pSelect; + } + + + /* Construct a new Expr object from a single token */ + static Expr *tokenExpr(Parse *pParse, int op, Token t){ + Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); + if( p ){ + /* memset(p, 0, sizeof(Expr)); */ + p->op = (u8)op; + p->affExpr = 0; + p->flags = EP_Leaf; + ExprClearVVAProperties(p); + /* p->iAgg = -1; // Not required */ + p->pLeft = p->pRight = 0; + p->pAggInfo = 0; + memset(&p->x, 0, sizeof(p->x)); + memset(&p->y, 0, sizeof(p->y)); + p->op2 = 0; + p->iTable = 0; + p->iColumn = 0; + p->u.zToken = (char*)&p[1]; + memcpy(p->u.zToken, t.z, t.n); + p->u.zToken[t.n] = 0; + p->w.iOfst = (int)(t.z - pParse->zTail); + if( sqlite3Isquote(p->u.zToken[0]) ){ + sqlite3DequoteExpr(p); + } +#if SQLITE_MAX_EXPR_DEPTH>0 + p->nHeight = 1; +#endif + if( IN_RENAME_OBJECT ){ + return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t); + } + } + return p; + } + + + /* A routine to convert a binary TK_IS or TK_ISNOT expression into a + ** unary TK_ISNULL or TK_NOTNULL expression. */ + static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ + sqlite3 *db = pParse->db; + if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){ + pA->op = (u8)op; + sqlite3ExprDelete(db, pA->pRight); + pA->pRight = 0; + } + } + + /* Add a single new term to an ExprList that is used to store a + ** list of identifiers. Report an error if the ID list contains + ** a COLLATE clause or an ASC or DESC keyword, except ignore the + ** error while parsing a legacy schema. + */ + static ExprList *parserAddExprIdListTerm( + Parse *pParse, + ExprList *pPrior, + Token *pIdToken, + int hasCollate, + int sortOrder + ){ + ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0); + if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED) + && pParse->db->init.busy==0 + ){ + sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"", + pIdToken->n, pIdToken->z); + } + sqlite3ExprListSetName(pParse, p, pIdToken, 1); + return p; + } + +#if TK_SPAN>255 +# error too many tokens in the grammar +#endif +/**************** End of %include directives **********************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef TK_SEMI +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_COMMA 25 +#define TK_WITHOUT 26 +#define TK_ABORT 27 +#define TK_ACTION 28 +#define TK_AFTER 29 +#define TK_ANALYZE 30 +#define TK_ASC 31 +#define TK_ATTACH 32 +#define TK_BEFORE 33 +#define TK_BY 34 +#define TK_CASCADE 35 +#define TK_CAST 36 +#define TK_CONFLICT 37 +#define TK_DATABASE 38 +#define TK_DESC 39 +#define TK_DETACH 40 +#define TK_EACH 41 +#define TK_FAIL 42 +#define TK_OR 43 +#define TK_AND 44 +#define TK_IS 45 +#define TK_MATCH 46 +#define TK_LIKE_KW 47 +#define TK_BETWEEN 48 +#define TK_IN 49 +#define TK_ISNULL 50 +#define TK_NOTNULL 51 +#define TK_NE 52 +#define TK_EQ 53 +#define TK_GT 54 +#define TK_LE 55 +#define TK_LT 56 +#define TK_GE 57 +#define TK_ESCAPE 58 +#define TK_ID 59 +#define TK_COLUMNKW 60 +#define TK_DO 61 +#define TK_FOR 62 +#define TK_IGNORE 63 +#define TK_INITIALLY 64 +#define TK_INSTEAD 65 +#define TK_NO 66 +#define TK_KEY 67 +#define TK_OF 68 +#define TK_OFFSET 69 +#define TK_PRAGMA 70 +#define TK_RAISE 71 +#define TK_RECURSIVE 72 +#define TK_REPLACE 73 +#define TK_RESTRICT 74 +#define TK_ROW 75 +#define TK_ROWS 76 +#define TK_TRIGGER 77 +#define TK_VACUUM 78 +#define TK_VIEW 79 +#define TK_VIRTUAL 80 +#define TK_WITH 81 +#define TK_NULLS 82 +#define TK_FIRST 83 +#define TK_LAST 84 +#define TK_CURRENT 85 +#define TK_FOLLOWING 86 +#define TK_PARTITION 87 +#define TK_PRECEDING 88 +#define TK_RANGE 89 +#define TK_UNBOUNDED 90 +#define TK_EXCLUDE 91 +#define TK_GROUPS 92 +#define TK_OTHERS 93 +#define TK_TIES 94 +#define TK_GENERATED 95 +#define TK_ALWAYS 96 +#define TK_MATERIALIZED 97 +#define TK_REINDEX 98 +#define TK_RENAME 99 +#define TK_CTIME_KW 100 +#define TK_ANY 101 +#define TK_BITAND 102 +#define TK_BITOR 103 +#define TK_LSHIFT 104 +#define TK_RSHIFT 105 +#define TK_PLUS 106 +#define TK_MINUS 107 +#define TK_STAR 108 +#define TK_SLASH 109 +#define TK_REM 110 +#define TK_CONCAT 111 +#define TK_PTR 112 +#define TK_COLLATE 113 +#define TK_BITNOT 114 +#define TK_ON 115 +#define TK_INDEXED 116 +#define TK_STRING 117 +#define TK_JOIN_KW 118 +#define TK_CONSTRAINT 119 +#define TK_DEFAULT 120 +#define TK_NULL 121 +#define TK_PRIMARY 122 +#define TK_UNIQUE 123 +#define TK_CHECK 124 +#define TK_REFERENCES 125 +#define TK_AUTOINCR 126 +#define TK_INSERT 127 +#define TK_DELETE 128 +#define TK_UPDATE 129 +#define TK_SET 130 +#define TK_DEFERRABLE 131 +#define TK_FOREIGN 132 +#define TK_DROP 133 +#define TK_UNION 134 +#define TK_ALL 135 +#define TK_EXCEPT 136 +#define TK_INTERSECT 137 +#define TK_SELECT 138 +#define TK_VALUES 139 +#define TK_DISTINCT 140 +#define TK_DOT 141 +#define TK_FROM 142 +#define TK_JOIN 143 +#define TK_USING 144 +#define TK_ORDER 145 +#define TK_GROUP 146 +#define TK_HAVING 147 +#define TK_LIMIT 148 +#define TK_WHERE 149 +#define TK_RETURNING 150 +#define TK_INTO 151 +#define TK_NOTHING 152 +#define TK_FLOAT 153 +#define TK_BLOB 154 +#define TK_INTEGER 155 +#define TK_VARIABLE 156 +#define TK_CASE 157 +#define TK_WHEN 158 +#define TK_THEN 159 +#define TK_ELSE 160 +#define TK_INDEX 161 +#define TK_ALTER 162 +#define TK_ADD 163 +#define TK_WINDOW 164 +#define TK_OVER 165 +#define TK_FILTER 166 +#define TK_COLUMN 167 +#define TK_AGG_FUNCTION 168 +#define TK_AGG_COLUMN 169 +#define TK_TRUEFALSE 170 +#define TK_ISNOT 171 +#define TK_FUNCTION 172 +#define TK_UMINUS 173 +#define TK_UPLUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_SPACE 183 +#define TK_ILLEGAL 184 +#endif +/**************** End token definitions ***************************************/ + +/* The next sections is a series of control #defines. +** various aspects of the generated parser. +** YYCODETYPE is the data type used to store the integer codes +** that represent terminal and non-terminal symbols. +** "unsigned char" is used if there are fewer than +** 256 symbols. Larger types otherwise. +** YYNOCODE is a number of type YYCODETYPE that is not used for +** any terminal or nonterminal symbol. +** YYFALLBACK If defined, this indicates that one or more tokens +** (also known as: "terminal symbols") have fall-back +** values which should be used if the original symbol +** would not parse. This permits keywords to sometimes +** be used as identifiers, for example. +** YYACTIONTYPE is the data type used for "action codes" - numbers +** that indicate what to do in response to the next +** token. +** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal +** symbols. Background: A "minor type" is a semantic +** value associated with a terminal or non-terminal +** symbols. For example, for an "ID" terminal symbol, +** the minor type might be the name of the identifier. +** Each non-terminal can have a different minor type. +** Terminal symbols all have the same minor type, though. +** This macros defines the minor type for terminal +** symbols. +** YYMINORTYPE is the data type used for all minor types. +** This is typically a union of many types, one of +** which is sqlite3ParserTOKENTYPE. The entry in the union +** for terminal symbols is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument +** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument +** sqlite3ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter +** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser +** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser +** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYNTOKEN Number of terminal symbols +** YY_MAX_SHIFT Maximum value for shift actions +** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions +** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions +** YY_ERROR_ACTION The yy_action[] code for syntax error +** YY_ACCEPT_ACTION The yy_action[] code for accept +** YY_NO_ACTION The yy_action[] code for no-op +** YY_MIN_REDUCE Minimum value for reduce actions +** YY_MAX_REDUCE Maximum value for reduce actions +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/************* Begin control #defines *****************************************/ +#define YYCODETYPE unsigned short int +#define YYNOCODE 319 +#define YYACTIONTYPE unsigned short int +#define YYWILDCARD 101 +#define sqlite3ParserTOKENTYPE Token +typedef union { + int yyinit; + sqlite3ParserTOKENTYPE yy0; + TriggerStep* yy33; + Window* yy41; + Select* yy47; + SrcList* yy131; + struct TrigEvent yy180; + struct {int value; int mask;} yy231; + IdList* yy254; + u32 yy285; + ExprList* yy322; + Cte* yy385; + int yy394; + Upsert* yy444; + u8 yy516; + With* yy521; + const char* yy522; + Expr* yy528; + OnOrUsing yy561; + struct FrameBound yy595; +} YYMINORTYPE; +#ifndef YYSTACKDEPTH +#define YYSTACKDEPTH 100 +#endif +#define sqlite3ParserARG_SDECL +#define sqlite3ParserARG_PDECL +#define sqlite3ParserARG_PARAM +#define sqlite3ParserARG_FETCH +#define sqlite3ParserARG_STORE +#define sqlite3ParserCTX_SDECL Parse *pParse; +#define sqlite3ParserCTX_PDECL ,Parse *pParse +#define sqlite3ParserCTX_PARAM ,pParse +#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; +#define sqlite3ParserCTX_STORE yypParser->pParse=pParse; +#define YYFALLBACK 1 +#define YYNSTATE 583 +#define YYNRULE 405 +#define YYNRULE_WITH_ACTION 340 +#define YYNTOKEN 185 +#define YY_MAX_SHIFT 582 +#define YY_MIN_SHIFTREDUCE 842 +#define YY_MAX_SHIFTREDUCE 1246 +#define YY_ERROR_ACTION 1247 +#define YY_ACCEPT_ACTION 1248 +#define YY_NO_ACTION 1249 +#define YY_MIN_REDUCE 1250 +#define YY_MAX_REDUCE 1654 +/************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) + +/* Define the yytestcase() macro to be a no-op if is not already defined +** otherwise. +** +** Applications can choose to define yytestcase() in the %include section +** to a macro that can assist in verifying code coverage. For production +** code the yytestcase() macro should be turned off. But it is useful +** for testing. +*/ +#ifndef yytestcase +# define yytestcase(X) +#endif + + +/* Next are the tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then +** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. +** +** N == YY_ERROR_ACTION A syntax error has occurred. +** +** N == YY_ACCEPT_ACTION The parser accepts its input. +** +** N == YY_NO_ACTION No such action. Denotes unused +** slots in the yy_action[] table. +** +** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE +** and YY_MAX_REDUCE +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as either: +** +** (A) N = yy_action[ yy_shift_ofst[S] + X ] +** (B) N = yy_default[S] +** +** The (A) formula is preferred. The B formula is used instead if +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X. +** +** The formulas above are for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +** +*********** Begin parsing tables **********************************************/ +#define YY_ACTTAB_COUNT (2112) +static const YYACTIONTYPE yy_action[] = { + /* 0 */ 576, 210, 576, 119, 116, 231, 576, 119, 116, 231, + /* 10 */ 576, 1321, 383, 1300, 414, 570, 570, 570, 576, 415, + /* 20 */ 384, 1321, 1283, 42, 42, 42, 42, 210, 1533, 72, + /* 30 */ 72, 978, 425, 42, 42, 499, 305, 281, 305, 979, + /* 40 */ 403, 72, 72, 126, 127, 81, 1221, 1221, 1058, 1061, + /* 50 */ 1048, 1048, 124, 124, 125, 125, 125, 125, 484, 415, + /* 60 */ 1248, 1, 1, 582, 2, 1252, 558, 119, 116, 231, + /* 70 */ 319, 488, 147, 488, 532, 119, 116, 231, 537, 1334, + /* 80 */ 423, 531, 143, 126, 127, 81, 1221, 1221, 1058, 1061, + /* 90 */ 1048, 1048, 124, 124, 125, 125, 125, 125, 119, 116, + /* 100 */ 231, 329, 123, 123, 123, 123, 122, 122, 121, 121, + /* 110 */ 121, 120, 117, 452, 286, 286, 286, 286, 450, 450, + /* 120 */ 450, 1572, 382, 1574, 1197, 381, 1168, 573, 1168, 573, + /* 130 */ 415, 1572, 545, 261, 228, 452, 102, 146, 457, 318, + /* 140 */ 567, 242, 123, 123, 123, 123, 122, 122, 121, 121, + /* 150 */ 121, 120, 117, 452, 126, 127, 81, 1221, 1221, 1058, + /* 160 */ 1061, 1048, 1048, 124, 124, 125, 125, 125, 125, 143, + /* 170 */ 296, 1197, 345, 456, 121, 121, 121, 120, 117, 452, + /* 180 */ 128, 1197, 1198, 1197, 149, 449, 448, 576, 120, 117, + /* 190 */ 452, 125, 125, 125, 125, 118, 123, 123, 123, 123, + /* 200 */ 122, 122, 121, 121, 121, 120, 117, 452, 462, 114, + /* 210 */ 13, 13, 554, 123, 123, 123, 123, 122, 122, 121, + /* 220 */ 121, 121, 120, 117, 452, 428, 318, 567, 1197, 1198, + /* 230 */ 1197, 150, 1229, 415, 1229, 125, 125, 125, 125, 123, + /* 240 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, + /* 250 */ 452, 473, 348, 1045, 1045, 1059, 1062, 126, 127, 81, + /* 260 */ 1221, 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, + /* 270 */ 125, 125, 1286, 530, 224, 1197, 576, 415, 226, 523, + /* 280 */ 177, 83, 84, 123, 123, 123, 123, 122, 122, 121, + /* 290 */ 121, 121, 120, 117, 452, 1014, 16, 16, 1197, 134, + /* 300 */ 134, 126, 127, 81, 1221, 1221, 1058, 1061, 1048, 1048, + /* 310 */ 124, 124, 125, 125, 125, 125, 123, 123, 123, 123, + /* 320 */ 122, 122, 121, 121, 121, 120, 117, 452, 1049, 554, + /* 330 */ 1197, 379, 1197, 1198, 1197, 254, 1442, 405, 512, 509, + /* 340 */ 508, 112, 568, 574, 4, 933, 933, 439, 507, 346, + /* 350 */ 468, 332, 366, 400, 1242, 1197, 1198, 1197, 571, 576, + /* 360 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120, + /* 370 */ 117, 452, 286, 286, 375, 1585, 1611, 449, 448, 155, + /* 380 */ 415, 453, 72, 72, 1293, 573, 1226, 1197, 1198, 1197, + /* 390 */ 86, 1228, 273, 565, 551, 524, 524, 576, 99, 1227, + /* 400 */ 6, 1285, 480, 143, 126, 127, 81, 1221, 1221, 1058, + /* 410 */ 1061, 1048, 1048, 124, 124, 125, 125, 125, 125, 558, + /* 420 */ 13, 13, 1035, 515, 1229, 1197, 1229, 557, 110, 110, + /* 430 */ 224, 576, 1243, 177, 576, 433, 111, 199, 453, 577, + /* 440 */ 453, 436, 1559, 1023, 327, 559, 1197, 272, 289, 374, + /* 450 */ 518, 369, 517, 259, 72, 72, 551, 72, 72, 365, + /* 460 */ 318, 567, 1617, 123, 123, 123, 123, 122, 122, 121, + /* 470 */ 121, 121, 120, 117, 452, 1023, 1023, 1025, 1026, 28, + /* 480 */ 286, 286, 1197, 1198, 1197, 1163, 576, 1616, 415, 908, + /* 490 */ 192, 558, 362, 573, 558, 944, 541, 525, 1163, 441, + /* 500 */ 419, 1163, 560, 1197, 1198, 1197, 576, 552, 552, 52, + /* 510 */ 52, 216, 126, 127, 81, 1221, 1221, 1058, 1061, 1048, + /* 520 */ 1048, 124, 124, 125, 125, 125, 125, 1197, 482, 136, + /* 530 */ 136, 415, 286, 286, 1497, 513, 122, 122, 121, 121, + /* 540 */ 121, 120, 117, 452, 1014, 573, 526, 219, 549, 549, + /* 550 */ 318, 567, 143, 6, 540, 126, 127, 81, 1221, 1221, + /* 560 */ 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, 125, + /* 570 */ 1561, 123, 123, 123, 123, 122, 122, 121, 121, 121, + /* 580 */ 120, 117, 452, 493, 1197, 1198, 1197, 490, 283, 1274, + /* 590 */ 964, 254, 1197, 379, 512, 509, 508, 1197, 346, 578, + /* 600 */ 1197, 578, 415, 294, 507, 964, 883, 193, 488, 318, + /* 610 */ 567, 390, 292, 386, 123, 123, 123, 123, 122, 122, + /* 620 */ 121, 121, 121, 120, 117, 452, 126, 127, 81, 1221, + /* 630 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 640 */ 125, 415, 400, 1143, 1197, 876, 101, 286, 286, 1197, + /* 650 */ 1198, 1197, 379, 1100, 1197, 1198, 1197, 1197, 1198, 1197, + /* 660 */ 573, 463, 33, 379, 235, 126, 127, 81, 1221, 1221, + /* 670 */ 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, 125, + /* 680 */ 1441, 966, 576, 230, 965, 123, 123, 123, 123, 122, + /* 690 */ 122, 121, 121, 121, 120, 117, 452, 1163, 230, 1197, + /* 700 */ 158, 1197, 1198, 1197, 1560, 13, 13, 303, 964, 1237, + /* 710 */ 1163, 154, 415, 1163, 379, 1588, 1181, 5, 375, 1585, + /* 720 */ 435, 1243, 3, 964, 123, 123, 123, 123, 122, 122, + /* 730 */ 121, 121, 121, 120, 117, 452, 126, 127, 81, 1221, + /* 740 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 750 */ 125, 415, 210, 575, 1197, 1036, 1197, 1198, 1197, 1197, + /* 760 */ 394, 859, 156, 1559, 380, 408, 1105, 1105, 496, 576, + /* 770 */ 473, 348, 1326, 1326, 1559, 126, 127, 81, 1221, 1221, + /* 780 */ 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, 125, + /* 790 */ 130, 576, 13, 13, 536, 123, 123, 123, 123, 122, + /* 800 */ 122, 121, 121, 121, 120, 117, 452, 304, 576, 461, + /* 810 */ 229, 1197, 1198, 1197, 13, 13, 1197, 1198, 1197, 1304, + /* 820 */ 471, 1274, 415, 1324, 1324, 1559, 1019, 461, 460, 440, + /* 830 */ 301, 72, 72, 1272, 123, 123, 123, 123, 122, 122, + /* 840 */ 121, 121, 121, 120, 117, 452, 126, 127, 81, 1221, + /* 850 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 860 */ 125, 415, 388, 1080, 1163, 286, 286, 425, 314, 280, + /* 870 */ 280, 287, 287, 465, 412, 411, 1543, 1163, 573, 576, + /* 880 */ 1163, 1200, 573, 413, 573, 126, 127, 81, 1221, 1221, + /* 890 */ 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, 125, + /* 900 */ 461, 1489, 13, 13, 1545, 123, 123, 123, 123, 122, + /* 910 */ 122, 121, 121, 121, 120, 117, 452, 202, 576, 466, + /* 920 */ 1591, 582, 2, 1252, 847, 848, 849, 1567, 319, 413, + /* 930 */ 147, 6, 415, 257, 256, 255, 208, 1334, 9, 1200, + /* 940 */ 264, 72, 72, 1440, 123, 123, 123, 123, 122, 122, + /* 950 */ 121, 121, 121, 120, 117, 452, 126, 127, 81, 1221, + /* 960 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 970 */ 125, 576, 286, 286, 576, 1217, 415, 581, 315, 1252, + /* 980 */ 425, 375, 1585, 360, 319, 573, 147, 499, 533, 1648, + /* 990 */ 401, 939, 499, 1334, 71, 71, 938, 72, 72, 242, + /* 1000 */ 1332, 105, 81, 1221, 1221, 1058, 1061, 1048, 1048, 124, + /* 1010 */ 124, 125, 125, 125, 125, 123, 123, 123, 123, 122, + /* 1020 */ 122, 121, 121, 121, 120, 117, 452, 1121, 286, 286, + /* 1030 */ 1426, 456, 1532, 1217, 447, 286, 286, 1496, 1359, 313, + /* 1040 */ 482, 573, 1122, 458, 355, 499, 358, 1270, 573, 209, + /* 1050 */ 576, 422, 179, 576, 1035, 242, 389, 1123, 527, 123, + /* 1060 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, + /* 1070 */ 452, 1024, 108, 72, 72, 1023, 13, 13, 919, 576, + /* 1080 */ 1502, 576, 286, 286, 98, 534, 1541, 456, 920, 1338, + /* 1090 */ 1333, 203, 415, 286, 286, 573, 152, 211, 1502, 1504, + /* 1100 */ 430, 573, 56, 56, 57, 57, 573, 1023, 1023, 1025, + /* 1110 */ 451, 576, 415, 535, 12, 297, 126, 127, 81, 1221, + /* 1120 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 1130 */ 125, 576, 415, 871, 15, 15, 126, 127, 81, 1221, + /* 1140 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 1150 */ 125, 377, 533, 264, 44, 44, 126, 115, 81, 1221, + /* 1160 */ 1221, 1058, 1061, 1048, 1048, 124, 124, 125, 125, 125, + /* 1170 */ 125, 1502, 482, 1275, 421, 123, 123, 123, 123, 122, + /* 1180 */ 122, 121, 121, 121, 120, 117, 452, 205, 1217, 499, + /* 1190 */ 434, 871, 472, 322, 499, 123, 123, 123, 123, 122, + /* 1200 */ 122, 121, 121, 121, 120, 117, 452, 576, 561, 1144, + /* 1210 */ 1646, 1426, 1646, 547, 576, 123, 123, 123, 123, 122, + /* 1220 */ 122, 121, 121, 121, 120, 117, 452, 576, 1426, 576, + /* 1230 */ 13, 13, 546, 323, 1329, 415, 338, 58, 58, 353, + /* 1240 */ 1426, 1174, 326, 286, 286, 553, 1217, 300, 899, 534, + /* 1250 */ 45, 45, 59, 59, 1144, 1647, 573, 1647, 569, 421, + /* 1260 */ 127, 81, 1221, 1221, 1058, 1061, 1048, 1048, 124, 124, + /* 1270 */ 125, 125, 125, 125, 1371, 377, 504, 290, 1197, 516, + /* 1280 */ 1370, 431, 398, 398, 397, 275, 395, 900, 1142, 856, + /* 1290 */ 482, 258, 1426, 1174, 467, 1163, 12, 335, 432, 337, + /* 1300 */ 1121, 464, 236, 258, 325, 464, 548, 1548, 1163, 1102, + /* 1310 */ 495, 1163, 324, 1102, 444, 1122, 339, 520, 123, 123, + /* 1320 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 452, + /* 1330 */ 1123, 318, 567, 1142, 576, 1197, 1198, 1197, 112, 568, + /* 1340 */ 201, 4, 238, 437, 939, 494, 285, 228, 1521, 938, + /* 1350 */ 170, 564, 576, 142, 1520, 571, 576, 60, 60, 576, + /* 1360 */ 420, 576, 445, 576, 539, 302, 879, 8, 491, 576, + /* 1370 */ 237, 576, 420, 576, 489, 61, 61, 576, 453, 62, + /* 1380 */ 62, 336, 63, 63, 46, 46, 47, 47, 365, 576, + /* 1390 */ 565, 576, 48, 48, 50, 50, 51, 51, 576, 295, + /* 1400 */ 64, 64, 486, 295, 543, 416, 475, 1035, 576, 542, + /* 1410 */ 318, 567, 65, 65, 66, 66, 413, 479, 576, 1035, + /* 1420 */ 576, 14, 14, 879, 1024, 110, 110, 413, 1023, 576, + /* 1430 */ 478, 67, 67, 111, 459, 453, 577, 453, 98, 317, + /* 1440 */ 1023, 132, 132, 133, 133, 576, 1565, 576, 978, 413, + /* 1450 */ 6, 1566, 68, 68, 1564, 6, 979, 576, 6, 1563, + /* 1460 */ 1023, 1023, 1025, 6, 350, 218, 101, 535, 53, 53, + /* 1470 */ 69, 69, 1023, 1023, 1025, 1026, 28, 1590, 1185, 455, + /* 1480 */ 70, 70, 290, 87, 215, 31, 1367, 398, 398, 397, + /* 1490 */ 275, 395, 354, 109, 856, 107, 576, 112, 568, 487, + /* 1500 */ 4, 1216, 576, 239, 153, 576, 39, 236, 1303, 325, + /* 1510 */ 112, 568, 1302, 4, 571, 576, 32, 324, 576, 54, + /* 1520 */ 54, 576, 1139, 357, 402, 165, 165, 571, 166, 166, + /* 1530 */ 576, 291, 359, 576, 17, 361, 576, 453, 77, 77, + /* 1540 */ 1317, 55, 55, 1301, 73, 73, 576, 238, 474, 565, + /* 1550 */ 453, 476, 368, 135, 135, 170, 74, 74, 142, 163, + /* 1560 */ 163, 378, 565, 543, 576, 321, 576, 890, 544, 137, + /* 1570 */ 137, 343, 1357, 426, 298, 237, 543, 576, 1035, 576, + /* 1580 */ 344, 542, 101, 373, 110, 110, 162, 131, 131, 164, + /* 1590 */ 164, 1035, 111, 372, 453, 577, 453, 110, 110, 1023, + /* 1600 */ 157, 157, 141, 141, 576, 111, 576, 453, 577, 453, + /* 1610 */ 416, 288, 1023, 576, 886, 318, 567, 576, 219, 576, + /* 1620 */ 241, 1016, 481, 263, 263, 898, 897, 140, 140, 138, + /* 1630 */ 138, 1023, 1023, 1025, 1026, 28, 139, 139, 529, 459, + /* 1640 */ 76, 76, 78, 78, 1023, 1023, 1025, 1026, 28, 1185, + /* 1650 */ 455, 576, 1087, 290, 112, 568, 1579, 4, 398, 398, + /* 1660 */ 397, 275, 395, 576, 1027, 856, 576, 483, 349, 263, + /* 1670 */ 101, 571, 886, 1380, 75, 75, 1425, 505, 236, 260, + /* 1680 */ 325, 112, 568, 363, 4, 101, 43, 43, 324, 49, + /* 1690 */ 49, 905, 906, 161, 453, 101, 981, 982, 571, 1083, + /* 1700 */ 1353, 260, 969, 936, 263, 114, 565, 1099, 521, 1099, + /* 1710 */ 1087, 1098, 869, 1098, 151, 937, 1148, 114, 238, 1365, + /* 1720 */ 562, 453, 1027, 563, 1430, 1282, 170, 1273, 1261, 142, + /* 1730 */ 1605, 1260, 1262, 565, 1598, 1035, 500, 278, 213, 1350, + /* 1740 */ 310, 110, 110, 943, 311, 312, 237, 11, 234, 111, + /* 1750 */ 221, 453, 577, 453, 293, 399, 1023, 1412, 341, 331, + /* 1760 */ 334, 342, 1035, 299, 347, 1417, 1416, 485, 110, 110, + /* 1770 */ 510, 406, 225, 1300, 206, 371, 111, 1362, 453, 577, + /* 1780 */ 453, 416, 1363, 1023, 1493, 1492, 318, 567, 1023, 1023, + /* 1790 */ 1025, 1026, 28, 566, 207, 220, 80, 568, 393, 4, + /* 1800 */ 1601, 1361, 556, 1360, 1237, 181, 267, 232, 1540, 1538, + /* 1810 */ 459, 1234, 424, 571, 82, 1023, 1023, 1025, 1026, 28, + /* 1820 */ 86, 217, 85, 1498, 190, 129, 1407, 554, 330, 175, + /* 1830 */ 36, 1413, 1400, 333, 183, 469, 453, 470, 185, 186, + /* 1840 */ 187, 503, 244, 188, 99, 1419, 1418, 37, 565, 1421, + /* 1850 */ 492, 194, 248, 404, 92, 498, 112, 568, 1509, 4, + /* 1860 */ 477, 352, 407, 279, 1487, 250, 198, 501, 356, 519, + /* 1870 */ 409, 251, 252, 571, 1263, 1320, 1319, 1035, 438, 1318, + /* 1880 */ 94, 890, 1311, 110, 110, 1290, 1310, 226, 1615, 442, + /* 1890 */ 1584, 111, 528, 453, 577, 453, 453, 443, 1023, 1614, + /* 1900 */ 265, 266, 410, 1289, 370, 1288, 1613, 308, 565, 309, + /* 1910 */ 446, 376, 1570, 1569, 10, 1474, 1385, 555, 387, 106, + /* 1920 */ 316, 1384, 100, 35, 538, 579, 1191, 274, 1343, 276, + /* 1930 */ 1023, 1023, 1025, 1026, 28, 1342, 277, 1035, 580, 1258, + /* 1940 */ 385, 212, 1253, 110, 110, 391, 167, 392, 168, 1525, + /* 1950 */ 417, 111, 180, 453, 577, 453, 1526, 843, 1023, 148, + /* 1960 */ 306, 1524, 1523, 454, 169, 222, 223, 214, 320, 79, + /* 1970 */ 233, 1097, 145, 1095, 328, 182, 171, 1216, 240, 922, + /* 1980 */ 184, 340, 1111, 243, 189, 172, 173, 427, 429, 88, + /* 1990 */ 1023, 1023, 1025, 1026, 28, 89, 191, 418, 174, 90, + /* 2000 */ 91, 1114, 245, 246, 1110, 159, 18, 1103, 247, 351, + /* 2010 */ 263, 195, 1231, 497, 249, 196, 38, 858, 502, 372, + /* 2020 */ 253, 364, 888, 197, 506, 511, 93, 19, 20, 514, + /* 2030 */ 901, 367, 95, 307, 160, 96, 522, 97, 1179, 1064, + /* 2040 */ 1150, 40, 227, 21, 282, 176, 1149, 284, 973, 200, + /* 2050 */ 967, 114, 262, 1169, 22, 1165, 23, 24, 1173, 25, + /* 2060 */ 1167, 1154, 1172, 26, 34, 550, 27, 103, 204, 101, + /* 2070 */ 104, 1078, 7, 1065, 1063, 1067, 1120, 1068, 1119, 268, + /* 2080 */ 269, 29, 41, 1187, 1028, 870, 113, 30, 572, 396, + /* 2090 */ 1186, 144, 178, 1249, 1249, 1249, 932, 1249, 1249, 1249, + /* 2100 */ 1249, 1249, 1249, 270, 1249, 271, 1249, 1249, 1249, 1249, + /* 2110 */ 1249, 1606, +}; +static const YYCODETYPE yy_lookahead[] = { + /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, + /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19, + /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216, + /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39, + /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, + /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, + /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204, + /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275, + /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, + /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, + /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138, + /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, + /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, + /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113, + /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112, + /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, + /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25, + /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108, + /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, + /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102, + /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45, + /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166, + /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108, + /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216, + /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, + /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145, + /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123, + /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127, + /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193, + /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241, + /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, + /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128, + /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48, + /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253, + /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107, + /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117, + /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121, + /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131, + /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108, + /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, + /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25, + /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261, + /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216, + /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, + /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216, + /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109, + /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309, + /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47, + /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193, + /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203, + /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138, + /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107, + /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116, + /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118, + /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47, + /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106, + /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, + /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60, + /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312, + /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107, + /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59, + /* 760 */ 201, 21, 241, 304, 193, 206, 127, 128, 129, 193, + /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47, + /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106, + /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193, + /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226, + /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231, + /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107, + /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239, + /* 870 */ 240, 239, 240, 244, 106, 107, 193, 89, 252, 193, + /* 880 */ 92, 59, 252, 254, 252, 43, 44, 45, 46, 47, + /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106, + /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 244, + /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 254, + /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117, + /* 940 */ 24, 216, 217, 273, 102, 103, 104, 105, 106, 107, + /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190, + /* 980 */ 193, 311, 312, 16, 195, 252, 197, 193, 19, 301, + /* 990 */ 302, 135, 193, 204, 216, 217, 140, 216, 217, 266, + /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, + /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, + /* 1030 */ 193, 298, 238, 117, 253, 239, 240, 238, 259, 260, + /* 1040 */ 193, 252, 27, 193, 77, 193, 79, 204, 252, 262, + /* 1050 */ 193, 299, 300, 193, 100, 266, 278, 42, 204, 102, + /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193, + /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 240, + /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212, + /* 1100 */ 263, 252, 216, 217, 216, 217, 252, 153, 154, 155, + /* 1110 */ 253, 193, 19, 144, 213, 268, 43, 44, 45, 46, + /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1130 */ 57, 193, 19, 59, 216, 217, 43, 44, 45, 46, + /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1150 */ 57, 193, 19, 24, 216, 217, 43, 44, 45, 46, + /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1170 */ 57, 284, 193, 208, 209, 102, 103, 104, 105, 106, + /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 59, 193, + /* 1190 */ 232, 117, 291, 193, 193, 102, 103, 104, 105, 106, + /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 193, 204, 22, + /* 1210 */ 23, 193, 25, 66, 193, 102, 103, 104, 105, 106, + /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 193, 193, + /* 1230 */ 216, 217, 85, 193, 238, 19, 16, 216, 217, 238, + /* 1240 */ 193, 94, 193, 239, 240, 231, 117, 268, 35, 116, + /* 1250 */ 216, 217, 216, 217, 22, 23, 252, 25, 208, 209, + /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 1270 */ 54, 55, 56, 57, 193, 193, 19, 5, 59, 66, + /* 1280 */ 193, 263, 10, 11, 12, 13, 14, 74, 101, 17, + /* 1290 */ 193, 46, 193, 146, 193, 76, 213, 77, 263, 79, + /* 1300 */ 12, 260, 30, 46, 32, 264, 87, 193, 89, 29, + /* 1310 */ 263, 92, 40, 33, 232, 27, 193, 108, 102, 103, + /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 1330 */ 42, 138, 139, 101, 193, 116, 117, 118, 19, 20, + /* 1340 */ 255, 22, 70, 130, 135, 65, 256, 257, 193, 140, + /* 1350 */ 78, 63, 193, 81, 193, 36, 193, 216, 217, 193, + /* 1360 */ 115, 193, 263, 193, 145, 268, 59, 48, 193, 193, + /* 1370 */ 98, 193, 115, 193, 291, 216, 217, 193, 59, 216, + /* 1380 */ 217, 161, 216, 217, 216, 217, 216, 217, 131, 193, + /* 1390 */ 71, 193, 216, 217, 216, 217, 216, 217, 193, 260, + /* 1400 */ 216, 217, 19, 264, 85, 133, 244, 100, 193, 90, + /* 1410 */ 138, 139, 216, 217, 216, 217, 254, 244, 193, 100, + /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 254, 121, 193, + /* 1430 */ 115, 216, 217, 114, 162, 116, 117, 118, 115, 244, + /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 193, 31, 254, + /* 1450 */ 313, 309, 216, 217, 309, 313, 39, 193, 313, 309, + /* 1460 */ 153, 154, 155, 313, 193, 150, 25, 144, 216, 217, + /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2, + /* 1480 */ 216, 217, 5, 149, 150, 22, 193, 10, 11, 12, + /* 1490 */ 13, 14, 193, 158, 17, 160, 193, 19, 20, 116, + /* 1500 */ 22, 25, 193, 24, 22, 193, 24, 30, 226, 32, + /* 1510 */ 19, 20, 226, 22, 36, 193, 53, 40, 193, 216, + /* 1520 */ 217, 193, 23, 193, 25, 216, 217, 36, 216, 217, + /* 1530 */ 193, 99, 193, 193, 22, 193, 193, 59, 216, 217, + /* 1540 */ 193, 216, 217, 193, 216, 217, 193, 70, 129, 71, + /* 1550 */ 59, 129, 193, 216, 217, 78, 216, 217, 81, 216, + /* 1560 */ 217, 193, 71, 85, 193, 133, 193, 126, 90, 216, + /* 1570 */ 217, 152, 258, 61, 152, 98, 85, 193, 100, 193, + /* 1580 */ 23, 90, 25, 121, 106, 107, 23, 216, 217, 216, + /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121, + /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, + /* 1610 */ 133, 22, 121, 193, 59, 138, 139, 193, 142, 193, + /* 1620 */ 141, 23, 23, 25, 25, 120, 121, 216, 217, 216, + /* 1630 */ 217, 153, 154, 155, 156, 157, 216, 217, 19, 162, + /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1, + /* 1650 */ 2, 193, 59, 5, 19, 20, 318, 22, 10, 11, + /* 1660 */ 12, 13, 14, 193, 59, 17, 193, 23, 23, 25, + /* 1670 */ 25, 36, 117, 193, 216, 217, 193, 23, 30, 25, + /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216, + /* 1690 */ 217, 7, 8, 23, 59, 25, 83, 84, 36, 23, + /* 1700 */ 193, 25, 23, 23, 25, 25, 71, 153, 145, 155, + /* 1710 */ 117, 153, 23, 155, 25, 23, 97, 25, 70, 193, + /* 1720 */ 193, 59, 117, 236, 193, 193, 78, 193, 193, 81, + /* 1730 */ 141, 193, 193, 71, 193, 100, 288, 287, 242, 255, + /* 1740 */ 255, 106, 107, 108, 255, 255, 98, 243, 297, 114, + /* 1750 */ 214, 116, 117, 118, 245, 191, 121, 271, 293, 267, + /* 1760 */ 267, 246, 100, 246, 245, 271, 271, 293, 106, 107, + /* 1770 */ 220, 271, 229, 225, 249, 219, 114, 259, 116, 117, + /* 1780 */ 118, 133, 259, 121, 219, 219, 138, 139, 153, 154, + /* 1790 */ 155, 156, 157, 280, 249, 243, 19, 20, 245, 22, + /* 1800 */ 196, 259, 140, 259, 60, 297, 141, 297, 200, 200, + /* 1810 */ 162, 38, 200, 36, 294, 153, 154, 155, 156, 157, + /* 1820 */ 151, 150, 294, 283, 22, 148, 250, 145, 249, 43, + /* 1830 */ 270, 272, 250, 249, 234, 18, 59, 200, 237, 237, + /* 1840 */ 237, 18, 199, 237, 149, 272, 272, 270, 71, 234, + /* 1850 */ 200, 234, 199, 246, 158, 62, 19, 20, 290, 22, + /* 1860 */ 246, 289, 246, 200, 246, 199, 22, 221, 200, 115, + /* 1870 */ 221, 199, 199, 36, 200, 218, 218, 100, 64, 218, + /* 1880 */ 22, 126, 227, 106, 107, 218, 227, 165, 224, 24, + /* 1890 */ 312, 114, 305, 116, 117, 118, 59, 113, 121, 224, + /* 1900 */ 200, 91, 221, 220, 218, 218, 218, 282, 71, 282, + /* 1910 */ 82, 221, 317, 317, 22, 277, 265, 140, 200, 158, + /* 1920 */ 279, 265, 147, 25, 146, 202, 13, 194, 250, 194, + /* 1930 */ 153, 154, 155, 156, 157, 250, 6, 100, 192, 192, + /* 1940 */ 249, 248, 192, 106, 107, 247, 207, 246, 207, 213, + /* 1950 */ 303, 114, 300, 116, 117, 118, 213, 4, 121, 222, + /* 1960 */ 222, 213, 213, 3, 207, 214, 214, 22, 163, 213, + /* 1970 */ 15, 23, 16, 23, 139, 151, 130, 25, 24, 20, + /* 1980 */ 142, 16, 1, 144, 142, 130, 130, 61, 37, 53, + /* 1990 */ 153, 154, 155, 156, 157, 53, 151, 303, 130, 53, + /* 2000 */ 53, 116, 34, 141, 1, 5, 22, 68, 115, 161, + /* 2010 */ 25, 68, 75, 41, 141, 115, 24, 20, 19, 131, + /* 2020 */ 125, 23, 59, 22, 67, 67, 22, 22, 22, 96, + /* 2030 */ 28, 24, 22, 67, 23, 149, 22, 25, 23, 23, + /* 2040 */ 23, 22, 141, 34, 23, 37, 97, 23, 116, 22, + /* 2050 */ 143, 25, 34, 75, 34, 88, 34, 34, 75, 34, + /* 2060 */ 86, 23, 93, 34, 22, 24, 34, 142, 25, 25, + /* 2070 */ 142, 23, 44, 23, 23, 23, 23, 11, 23, 25, + /* 2080 */ 22, 22, 22, 1, 23, 23, 22, 22, 25, 15, + /* 2090 */ 1, 23, 25, 319, 319, 319, 135, 319, 319, 319, + /* 2100 */ 319, 319, 319, 141, 319, 141, 319, 319, 319, 319, + /* 2110 */ 319, 141, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2280 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2290 */ 319, 319, 319, 319, 319, 319, 319, +}; +#define YY_SHIFT_COUNT (582) +#define YY_SHIFT_MIN (0) +#define YY_SHIFT_MAX (2089) +static const unsigned short int yy_shift_ofst[] = { + /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837, + /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837, + /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 30 */ 1837, 271, 271, 1219, 1219, 216, 88, 1, 1, 1, + /* 40 */ 1, 1, 40, 111, 258, 361, 469, 512, 583, 622, + /* 50 */ 693, 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, + /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /* 70 */ 1093, 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, + /* 80 */ 1662, 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 130 */ 1837, 137, 181, 181, 181, 181, 181, 181, 181, 94, + /* 140 */ 430, 66, 65, 112, 366, 533, 533, 740, 1257, 533, + /* 150 */ 533, 79, 79, 533, 412, 412, 412, 77, 412, 123, + /* 160 */ 113, 113, 113, 22, 22, 2112, 2112, 328, 328, 328, + /* 170 */ 239, 468, 468, 468, 468, 1015, 1015, 409, 366, 1187, + /* 180 */ 1232, 533, 533, 533, 533, 533, 533, 533, 533, 533, + /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, + /* 200 */ 533, 969, 621, 621, 533, 642, 788, 788, 1133, 1133, + /* 210 */ 822, 822, 67, 1193, 2112, 2112, 2112, 2112, 2112, 2112, + /* 220 */ 2112, 1307, 954, 954, 585, 472, 640, 387, 695, 538, + /* 230 */ 541, 700, 533, 533, 533, 533, 533, 533, 533, 533, + /* 240 */ 533, 533, 222, 533, 533, 533, 533, 533, 533, 533, + /* 250 */ 533, 533, 533, 533, 533, 1213, 1213, 1213, 533, 533, + /* 260 */ 533, 565, 533, 533, 533, 916, 1147, 533, 533, 1288, + /* 270 */ 533, 533, 533, 533, 533, 533, 533, 533, 639, 1280, + /* 280 */ 209, 1129, 1129, 1129, 1129, 580, 209, 209, 1209, 768, + /* 290 */ 917, 649, 1315, 1334, 405, 1334, 1383, 249, 1315, 1315, + /* 300 */ 249, 1315, 405, 1383, 1441, 464, 1245, 1417, 1417, 1417, + /* 310 */ 1323, 1323, 1323, 1323, 184, 184, 1335, 1476, 856, 1482, + /* 320 */ 1744, 1744, 1665, 1665, 1773, 1773, 1665, 1669, 1671, 1802, + /* 330 */ 1677, 1682, 1786, 1677, 1682, 1817, 1817, 1817, 1817, 1665, + /* 340 */ 1823, 1695, 1671, 1671, 1695, 1802, 1786, 1695, 1786, 1695, + /* 350 */ 1665, 1823, 1696, 1793, 1665, 1823, 1844, 1665, 1823, 1665, + /* 360 */ 1823, 1844, 1754, 1754, 1754, 1814, 1858, 1858, 1844, 1754, + /* 370 */ 1755, 1754, 1814, 1754, 1754, 1722, 1865, 1784, 1784, 1844, + /* 380 */ 1665, 1810, 1810, 1828, 1828, 1677, 1682, 1892, 1665, 1761, + /* 390 */ 1677, 1775, 1778, 1695, 1898, 1913, 1913, 1930, 1930, 1930, + /* 400 */ 2112, 2112, 2112, 2112, 2112, 2112, 2112, 2112, 2112, 2112, + /* 410 */ 2112, 2112, 2112, 2112, 2112, 207, 1220, 331, 620, 967, + /* 420 */ 806, 1074, 1499, 1432, 1463, 1479, 1419, 1422, 1557, 1512, + /* 430 */ 1598, 1599, 1644, 1645, 1654, 1660, 1555, 1505, 1684, 1462, + /* 440 */ 1670, 1563, 1619, 1593, 1676, 1679, 1613, 1680, 1554, 1558, + /* 450 */ 1689, 1692, 1605, 1589, 1953, 1960, 1945, 1805, 1955, 1956, + /* 460 */ 1948, 1950, 1835, 1824, 1846, 1952, 1952, 1954, 1838, 1959, + /* 470 */ 1839, 1965, 1981, 1842, 1855, 1952, 1856, 1926, 1951, 1952, + /* 480 */ 1845, 1936, 1942, 1946, 1947, 1868, 1885, 1968, 1862, 2003, + /* 490 */ 2000, 1984, 1893, 1848, 1939, 1985, 1943, 1937, 1972, 1873, + /* 500 */ 1900, 1992, 1997, 1999, 1888, 1895, 2001, 1957, 2004, 2005, + /* 510 */ 1998, 2006, 1958, 1963, 2007, 1933, 2002, 2010, 1966, 2008, + /* 520 */ 2011, 2009, 1886, 2014, 2015, 2016, 2012, 2017, 2019, 1949, + /* 530 */ 1901, 2021, 2024, 1932, 2018, 2027, 1907, 2026, 2020, 2022, + /* 540 */ 2023, 2025, 1967, 1978, 1974, 2028, 1983, 1969, 2029, 2038, + /* 550 */ 2042, 2041, 2043, 2044, 2032, 1925, 1928, 2048, 2026, 2050, + /* 560 */ 2051, 2052, 2053, 2054, 2055, 2058, 2066, 2059, 2060, 2061, + /* 570 */ 2062, 2064, 2065, 2063, 1961, 1962, 1964, 1970, 2067, 2068, + /* 580 */ 2074, 2082, 2089, +}; +#define YY_REDUCE_COUNT (414) +#define YY_REDUCE_MIN (-271) +#define YY_REDUCE_MAX (1757) +static const short yy_reduce_ofst[] = { + /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, + /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489, + /* 20 */ 576, 598, -175, 686, 860, 615, 725, 1014, 778, 781, + /* 30 */ 857, 616, 887, 87, 240, -192, 408, 626, 796, 843, + /* 40 */ 854, 1004, -271, -271, -271, -271, -271, -271, -271, -271, + /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, + /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, + /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, 80, + /* 80 */ 83, 313, 886, 888, 918, 938, 1021, 1034, 1036, 1141, + /* 90 */ 1159, 1163, 1166, 1168, 1170, 1176, 1178, 1180, 1184, 1196, + /* 100 */ 1198, 1205, 1215, 1225, 1227, 1236, 1252, 1254, 1264, 1303, + /* 110 */ 1309, 1312, 1322, 1325, 1328, 1337, 1340, 1343, 1353, 1371, + /* 120 */ 1373, 1384, 1386, 1411, 1413, 1420, 1424, 1426, 1458, 1470, + /* 130 */ 1473, -271, -271, -271, -271, -271, -271, -271, -271, -271, + /* 140 */ -271, -271, 138, 459, 396, -158, 470, 302, -212, 521, + /* 150 */ 201, -195, -92, 559, 630, 632, 630, -271, 632, 901, + /* 160 */ 63, 407, 670, -271, -271, -271, -271, 161, 161, 161, + /* 170 */ 251, 335, 847, 979, 1097, 537, 588, 618, 628, 688, + /* 180 */ 688, -166, -161, 674, 787, 794, 799, 852, 996, -122, + /* 190 */ 837, -120, 1018, 1035, 415, 1047, 1001, 958, 1082, 400, + /* 200 */ 1099, 779, 1137, 1142, 263, 1083, 1145, 1150, 1041, 1139, + /* 210 */ 965, 1050, 362, 849, 752, 629, 675, 1162, 1173, 1090, + /* 220 */ 1195, -194, 56, 185, -135, 232, 522, 560, 571, 601, + /* 230 */ 617, 669, 683, 711, 850, 893, 1000, 1040, 1049, 1081, + /* 240 */ 1087, 1101, 392, 1114, 1123, 1155, 1161, 1175, 1271, 1293, + /* 250 */ 1299, 1330, 1339, 1342, 1347, 593, 1282, 1286, 1350, 1359, + /* 260 */ 1368, 1314, 1480, 1483, 1507, 1085, 1338, 1526, 1527, 1487, + /* 270 */ 1531, 560, 1532, 1534, 1535, 1538, 1539, 1541, 1448, 1450, + /* 280 */ 1496, 1484, 1485, 1489, 1490, 1314, 1496, 1496, 1504, 1536, + /* 290 */ 1564, 1451, 1486, 1492, 1509, 1493, 1465, 1515, 1494, 1495, + /* 300 */ 1517, 1500, 1519, 1474, 1550, 1543, 1548, 1556, 1565, 1566, + /* 310 */ 1518, 1523, 1542, 1544, 1525, 1545, 1513, 1553, 1552, 1604, + /* 320 */ 1508, 1510, 1608, 1609, 1520, 1528, 1612, 1540, 1559, 1560, + /* 330 */ 1576, 1579, 1600, 1582, 1584, 1601, 1602, 1603, 1606, 1637, + /* 340 */ 1643, 1607, 1573, 1574, 1614, 1577, 1615, 1616, 1617, 1618, + /* 350 */ 1650, 1653, 1568, 1572, 1663, 1666, 1646, 1668, 1672, 1674, + /* 360 */ 1673, 1649, 1657, 1658, 1661, 1655, 1664, 1675, 1681, 1667, + /* 370 */ 1683, 1686, 1659, 1687, 1688, 1578, 1587, 1625, 1627, 1690, + /* 380 */ 1700, 1595, 1596, 1651, 1656, 1678, 1691, 1638, 1718, 1641, + /* 390 */ 1685, 1693, 1698, 1701, 1723, 1733, 1735, 1746, 1747, 1750, + /* 400 */ 1647, 1694, 1652, 1739, 1736, 1743, 1748, 1749, 1741, 1737, + /* 410 */ 1738, 1751, 1752, 1756, 1757, +}; +static const YYACTIONTYPE yy_default[] = { + /* 0 */ 1652, 1652, 1652, 1482, 1247, 1358, 1247, 1247, 1247, 1482, + /* 10 */ 1482, 1482, 1247, 1388, 1388, 1535, 1280, 1247, 1247, 1247, + /* 20 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1481, 1247, + /* 30 */ 1247, 1247, 1247, 1568, 1568, 1247, 1247, 1247, 1247, 1247, + /* 40 */ 1247, 1247, 1247, 1397, 1247, 1404, 1247, 1247, 1247, 1247, + /* 50 */ 1247, 1483, 1484, 1247, 1247, 1247, 1534, 1536, 1499, 1411, + /* 60 */ 1410, 1409, 1408, 1517, 1376, 1402, 1395, 1399, 1478, 1479, + /* 70 */ 1477, 1630, 1484, 1483, 1247, 1398, 1446, 1462, 1445, 1247, + /* 80 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 90 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 100 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 110 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 120 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 130 */ 1247, 1454, 1461, 1460, 1459, 1468, 1458, 1455, 1448, 1447, + /* 140 */ 1449, 1450, 1247, 1247, 1271, 1247, 1247, 1268, 1322, 1247, + /* 150 */ 1247, 1247, 1247, 1247, 1554, 1553, 1247, 1451, 1247, 1280, + /* 160 */ 1439, 1438, 1437, 1465, 1452, 1464, 1463, 1542, 1604, 1603, + /* 170 */ 1500, 1247, 1247, 1247, 1247, 1247, 1247, 1568, 1247, 1247, + /* 180 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 190 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 200 */ 1247, 1378, 1568, 1568, 1247, 1280, 1568, 1568, 1379, 1379, + /* 210 */ 1276, 1276, 1382, 1247, 1549, 1349, 1349, 1349, 1349, 1358, + /* 220 */ 1349, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 230 */ 1247, 1247, 1247, 1247, 1247, 1247, 1539, 1537, 1247, 1247, + /* 240 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 250 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 260 */ 1247, 1247, 1247, 1247, 1247, 1354, 1247, 1247, 1247, 1247, + /* 270 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1597, 1247, 1512, + /* 280 */ 1336, 1354, 1354, 1354, 1354, 1356, 1337, 1335, 1348, 1281, + /* 290 */ 1254, 1644, 1414, 1403, 1355, 1403, 1641, 1401, 1414, 1414, + /* 300 */ 1401, 1414, 1355, 1641, 1297, 1619, 1292, 1388, 1388, 1388, + /* 310 */ 1378, 1378, 1378, 1378, 1382, 1382, 1480, 1355, 1348, 1247, + /* 320 */ 1644, 1644, 1364, 1364, 1643, 1643, 1364, 1500, 1627, 1423, + /* 330 */ 1396, 1382, 1325, 1396, 1382, 1331, 1331, 1331, 1331, 1364, + /* 340 */ 1265, 1401, 1627, 1627, 1401, 1423, 1325, 1401, 1325, 1401, + /* 350 */ 1364, 1265, 1516, 1638, 1364, 1265, 1490, 1364, 1265, 1364, + /* 360 */ 1265, 1490, 1323, 1323, 1323, 1312, 1247, 1247, 1490, 1323, + /* 370 */ 1297, 1323, 1312, 1323, 1323, 1586, 1247, 1494, 1494, 1490, + /* 380 */ 1364, 1578, 1578, 1391, 1391, 1396, 1382, 1485, 1364, 1247, + /* 390 */ 1396, 1394, 1392, 1401, 1315, 1600, 1600, 1596, 1596, 1596, + /* 400 */ 1649, 1649, 1549, 1612, 1280, 1280, 1280, 1280, 1612, 1299, + /* 410 */ 1299, 1281, 1281, 1280, 1612, 1247, 1247, 1247, 1247, 1247, + /* 420 */ 1247, 1607, 1247, 1544, 1501, 1368, 1247, 1247, 1247, 1247, + /* 430 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 440 */ 1247, 1247, 1555, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 450 */ 1247, 1247, 1247, 1428, 1247, 1250, 1546, 1247, 1247, 1247, + /* 460 */ 1247, 1247, 1247, 1247, 1247, 1405, 1406, 1369, 1247, 1247, + /* 470 */ 1247, 1247, 1247, 1247, 1247, 1420, 1247, 1247, 1247, 1415, + /* 480 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1640, 1247, + /* 490 */ 1247, 1247, 1247, 1247, 1247, 1515, 1514, 1247, 1247, 1366, + /* 500 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 510 */ 1247, 1247, 1247, 1295, 1247, 1247, 1247, 1247, 1247, 1247, + /* 520 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 530 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1393, 1247, 1247, + /* 540 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 550 */ 1247, 1247, 1583, 1383, 1247, 1247, 1247, 1247, 1631, 1247, + /* 560 */ 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + /* 570 */ 1247, 1247, 1247, 1623, 1339, 1429, 1247, 1432, 1269, 1247, + /* 580 */ 1259, 1247, 1247, +}; +/********** End of lemon-generated parsing tables *****************************/ + +/* The next table maps tokens (terminal symbols) into fallback tokens. +** If a construct like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammar, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +** +** This feature can be used, for example, to cause some keywords in a language +** to revert to identifiers if they keyword does not apply in the context where +** it appears. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { + 0, /* $ => nothing */ + 0, /* SEMI => nothing */ + 59, /* EXPLAIN => ID */ + 59, /* QUERY => ID */ + 59, /* PLAN => ID */ + 59, /* BEGIN => ID */ + 0, /* TRANSACTION => nothing */ + 59, /* DEFERRED => ID */ + 59, /* IMMEDIATE => ID */ + 59, /* EXCLUSIVE => ID */ + 0, /* COMMIT => nothing */ + 59, /* END => ID */ + 59, /* ROLLBACK => ID */ + 59, /* SAVEPOINT => ID */ + 59, /* RELEASE => ID */ + 0, /* TO => nothing */ + 0, /* TABLE => nothing */ + 0, /* CREATE => nothing */ + 59, /* IF => ID */ + 0, /* NOT => nothing */ + 0, /* EXISTS => nothing */ + 59, /* TEMP => ID */ + 0, /* LP => nothing */ + 0, /* RP => nothing */ + 0, /* AS => nothing */ + 0, /* COMMA => nothing */ + 59, /* WITHOUT => ID */ + 59, /* ABORT => ID */ + 59, /* ACTION => ID */ + 59, /* AFTER => ID */ + 59, /* ANALYZE => ID */ + 59, /* ASC => ID */ + 59, /* ATTACH => ID */ + 59, /* BEFORE => ID */ + 59, /* BY => ID */ + 59, /* CASCADE => ID */ + 59, /* CAST => ID */ + 59, /* CONFLICT => ID */ + 59, /* DATABASE => ID */ + 59, /* DESC => ID */ + 59, /* DETACH => ID */ + 59, /* EACH => ID */ + 59, /* FAIL => ID */ + 0, /* OR => nothing */ + 0, /* AND => nothing */ + 0, /* IS => nothing */ + 59, /* MATCH => ID */ + 59, /* LIKE_KW => ID */ + 0, /* BETWEEN => nothing */ + 0, /* IN => nothing */ + 0, /* ISNULL => nothing */ + 0, /* NOTNULL => nothing */ + 0, /* NE => nothing */ + 0, /* EQ => nothing */ + 0, /* GT => nothing */ + 0, /* LE => nothing */ + 0, /* LT => nothing */ + 0, /* GE => nothing */ + 0, /* ESCAPE => nothing */ + 0, /* ID => nothing */ + 59, /* COLUMNKW => ID */ + 59, /* DO => ID */ + 59, /* FOR => ID */ + 59, /* IGNORE => ID */ + 59, /* INITIALLY => ID */ + 59, /* INSTEAD => ID */ + 59, /* NO => ID */ + 59, /* KEY => ID */ + 59, /* OF => ID */ + 59, /* OFFSET => ID */ + 59, /* PRAGMA => ID */ + 59, /* RAISE => ID */ + 59, /* RECURSIVE => ID */ + 59, /* REPLACE => ID */ + 59, /* RESTRICT => ID */ + 59, /* ROW => ID */ + 59, /* ROWS => ID */ + 59, /* TRIGGER => ID */ + 59, /* VACUUM => ID */ + 59, /* VIEW => ID */ + 59, /* VIRTUAL => ID */ + 59, /* WITH => ID */ + 59, /* NULLS => ID */ + 59, /* FIRST => ID */ + 59, /* LAST => ID */ + 59, /* CURRENT => ID */ + 59, /* FOLLOWING => ID */ + 59, /* PARTITION => ID */ + 59, /* PRECEDING => ID */ + 59, /* RANGE => ID */ + 59, /* UNBOUNDED => ID */ + 59, /* EXCLUDE => ID */ + 59, /* GROUPS => ID */ + 59, /* OTHERS => ID */ + 59, /* TIES => ID */ + 59, /* GENERATED => ID */ + 59, /* ALWAYS => ID */ + 59, /* MATERIALIZED => ID */ + 59, /* REINDEX => ID */ + 59, /* RENAME => ID */ + 59, /* CTIME_KW => ID */ + 0, /* ANY => nothing */ + 0, /* BITAND => nothing */ + 0, /* BITOR => nothing */ + 0, /* LSHIFT => nothing */ + 0, /* RSHIFT => nothing */ + 0, /* PLUS => nothing */ + 0, /* MINUS => nothing */ + 0, /* STAR => nothing */ + 0, /* SLASH => nothing */ + 0, /* REM => nothing */ + 0, /* CONCAT => nothing */ + 0, /* PTR => nothing */ + 0, /* COLLATE => nothing */ + 0, /* BITNOT => nothing */ + 0, /* ON => nothing */ + 0, /* INDEXED => nothing */ + 0, /* STRING => nothing */ + 0, /* JOIN_KW => nothing */ + 0, /* CONSTRAINT => nothing */ + 0, /* DEFAULT => nothing */ + 0, /* NULL => nothing */ + 0, /* PRIMARY => nothing */ + 0, /* UNIQUE => nothing */ + 0, /* CHECK => nothing */ + 0, /* REFERENCES => nothing */ + 0, /* AUTOINCR => nothing */ + 0, /* INSERT => nothing */ + 0, /* DELETE => nothing */ + 0, /* UPDATE => nothing */ + 0, /* SET => nothing */ + 0, /* DEFERRABLE => nothing */ + 0, /* FOREIGN => nothing */ + 0, /* DROP => nothing */ + 0, /* UNION => nothing */ + 0, /* ALL => nothing */ + 0, /* EXCEPT => nothing */ + 0, /* INTERSECT => nothing */ + 0, /* SELECT => nothing */ + 0, /* VALUES => nothing */ + 0, /* DISTINCT => nothing */ + 0, /* DOT => nothing */ + 0, /* FROM => nothing */ + 0, /* JOIN => nothing */ + 0, /* USING => nothing */ + 0, /* ORDER => nothing */ + 0, /* GROUP => nothing */ + 0, /* HAVING => nothing */ + 0, /* LIMIT => nothing */ + 0, /* WHERE => nothing */ + 0, /* RETURNING => nothing */ + 0, /* INTO => nothing */ + 0, /* NOTHING => nothing */ + 0, /* FLOAT => nothing */ + 0, /* BLOB => nothing */ + 0, /* INTEGER => nothing */ + 0, /* VARIABLE => nothing */ + 0, /* CASE => nothing */ + 0, /* WHEN => nothing */ + 0, /* THEN => nothing */ + 0, /* ELSE => nothing */ + 0, /* INDEX => nothing */ + 0, /* ALTER => nothing */ + 0, /* ADD => nothing */ + 0, /* WINDOW => nothing */ + 0, /* OVER => nothing */ + 0, /* FILTER => nothing */ + 0, /* COLUMN => nothing */ + 0, /* AGG_FUNCTION => nothing */ + 0, /* AGG_COLUMN => nothing */ + 0, /* TRUEFALSE => nothing */ + 0, /* ISNOT => nothing */ + 0, /* FUNCTION => nothing */ + 0, /* UMINUS => nothing */ + 0, /* UPLUS => nothing */ + 0, /* TRUTH => nothing */ + 0, /* REGISTER => nothing */ + 0, /* VECTOR => nothing */ + 0, /* SELECT_COLUMN => nothing */ + 0, /* IF_NULL_ROW => nothing */ + 0, /* ASTERISK => nothing */ + 0, /* SPAN => nothing */ + 0, /* ERROR => nothing */ + 0, /* SPACE => nothing */ + 0, /* ILLEGAL => nothing */ +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +** +** After the "shift" half of a SHIFTREDUCE action, the stateno field +** actually contains the reduce action for the second half of the +** SHIFTREDUCE. +*/ +struct yyStackEntry { + YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */ + YYCODETYPE major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + yyStackEntry *yytos; /* Pointer to top element of the stack */ +#ifdef YYTRACKMAXSTACKDEPTH + int yyhwm; /* High-water mark of the stack */ +#endif +#ifndef YYNOERRORRECOVERY + int yyerrcnt; /* Shifts left before out of the error */ +#endif + sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ + sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ + yyStackEntry yystk0; /* First stack entry */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ + yyStackEntry *yystackEnd; /* Last entry in the stack */ +#endif +}; +typedef struct yyParser yyParser; + +/* #include */ +#ifndef NDEBUG +/* #include */ +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
    +**
  • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
  • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
+** +** Outputs: +** None. +*/ +SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#if defined(YYCOVERAGE) || !defined(NDEBUG) +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { + /* 0 */ "$", + /* 1 */ "SEMI", + /* 2 */ "EXPLAIN", + /* 3 */ "QUERY", + /* 4 */ "PLAN", + /* 5 */ "BEGIN", + /* 6 */ "TRANSACTION", + /* 7 */ "DEFERRED", + /* 8 */ "IMMEDIATE", + /* 9 */ "EXCLUSIVE", + /* 10 */ "COMMIT", + /* 11 */ "END", + /* 12 */ "ROLLBACK", + /* 13 */ "SAVEPOINT", + /* 14 */ "RELEASE", + /* 15 */ "TO", + /* 16 */ "TABLE", + /* 17 */ "CREATE", + /* 18 */ "IF", + /* 19 */ "NOT", + /* 20 */ "EXISTS", + /* 21 */ "TEMP", + /* 22 */ "LP", + /* 23 */ "RP", + /* 24 */ "AS", + /* 25 */ "COMMA", + /* 26 */ "WITHOUT", + /* 27 */ "ABORT", + /* 28 */ "ACTION", + /* 29 */ "AFTER", + /* 30 */ "ANALYZE", + /* 31 */ "ASC", + /* 32 */ "ATTACH", + /* 33 */ "BEFORE", + /* 34 */ "BY", + /* 35 */ "CASCADE", + /* 36 */ "CAST", + /* 37 */ "CONFLICT", + /* 38 */ "DATABASE", + /* 39 */ "DESC", + /* 40 */ "DETACH", + /* 41 */ "EACH", + /* 42 */ "FAIL", + /* 43 */ "OR", + /* 44 */ "AND", + /* 45 */ "IS", + /* 46 */ "MATCH", + /* 47 */ "LIKE_KW", + /* 48 */ "BETWEEN", + /* 49 */ "IN", + /* 50 */ "ISNULL", + /* 51 */ "NOTNULL", + /* 52 */ "NE", + /* 53 */ "EQ", + /* 54 */ "GT", + /* 55 */ "LE", + /* 56 */ "LT", + /* 57 */ "GE", + /* 58 */ "ESCAPE", + /* 59 */ "ID", + /* 60 */ "COLUMNKW", + /* 61 */ "DO", + /* 62 */ "FOR", + /* 63 */ "IGNORE", + /* 64 */ "INITIALLY", + /* 65 */ "INSTEAD", + /* 66 */ "NO", + /* 67 */ "KEY", + /* 68 */ "OF", + /* 69 */ "OFFSET", + /* 70 */ "PRAGMA", + /* 71 */ "RAISE", + /* 72 */ "RECURSIVE", + /* 73 */ "REPLACE", + /* 74 */ "RESTRICT", + /* 75 */ "ROW", + /* 76 */ "ROWS", + /* 77 */ "TRIGGER", + /* 78 */ "VACUUM", + /* 79 */ "VIEW", + /* 80 */ "VIRTUAL", + /* 81 */ "WITH", + /* 82 */ "NULLS", + /* 83 */ "FIRST", + /* 84 */ "LAST", + /* 85 */ "CURRENT", + /* 86 */ "FOLLOWING", + /* 87 */ "PARTITION", + /* 88 */ "PRECEDING", + /* 89 */ "RANGE", + /* 90 */ "UNBOUNDED", + /* 91 */ "EXCLUDE", + /* 92 */ "GROUPS", + /* 93 */ "OTHERS", + /* 94 */ "TIES", + /* 95 */ "GENERATED", + /* 96 */ "ALWAYS", + /* 97 */ "MATERIALIZED", + /* 98 */ "REINDEX", + /* 99 */ "RENAME", + /* 100 */ "CTIME_KW", + /* 101 */ "ANY", + /* 102 */ "BITAND", + /* 103 */ "BITOR", + /* 104 */ "LSHIFT", + /* 105 */ "RSHIFT", + /* 106 */ "PLUS", + /* 107 */ "MINUS", + /* 108 */ "STAR", + /* 109 */ "SLASH", + /* 110 */ "REM", + /* 111 */ "CONCAT", + /* 112 */ "PTR", + /* 113 */ "COLLATE", + /* 114 */ "BITNOT", + /* 115 */ "ON", + /* 116 */ "INDEXED", + /* 117 */ "STRING", + /* 118 */ "JOIN_KW", + /* 119 */ "CONSTRAINT", + /* 120 */ "DEFAULT", + /* 121 */ "NULL", + /* 122 */ "PRIMARY", + /* 123 */ "UNIQUE", + /* 124 */ "CHECK", + /* 125 */ "REFERENCES", + /* 126 */ "AUTOINCR", + /* 127 */ "INSERT", + /* 128 */ "DELETE", + /* 129 */ "UPDATE", + /* 130 */ "SET", + /* 131 */ "DEFERRABLE", + /* 132 */ "FOREIGN", + /* 133 */ "DROP", + /* 134 */ "UNION", + /* 135 */ "ALL", + /* 136 */ "EXCEPT", + /* 137 */ "INTERSECT", + /* 138 */ "SELECT", + /* 139 */ "VALUES", + /* 140 */ "DISTINCT", + /* 141 */ "DOT", + /* 142 */ "FROM", + /* 143 */ "JOIN", + /* 144 */ "USING", + /* 145 */ "ORDER", + /* 146 */ "GROUP", + /* 147 */ "HAVING", + /* 148 */ "LIMIT", + /* 149 */ "WHERE", + /* 150 */ "RETURNING", + /* 151 */ "INTO", + /* 152 */ "NOTHING", + /* 153 */ "FLOAT", + /* 154 */ "BLOB", + /* 155 */ "INTEGER", + /* 156 */ "VARIABLE", + /* 157 */ "CASE", + /* 158 */ "WHEN", + /* 159 */ "THEN", + /* 160 */ "ELSE", + /* 161 */ "INDEX", + /* 162 */ "ALTER", + /* 163 */ "ADD", + /* 164 */ "WINDOW", + /* 165 */ "OVER", + /* 166 */ "FILTER", + /* 167 */ "COLUMN", + /* 168 */ "AGG_FUNCTION", + /* 169 */ "AGG_COLUMN", + /* 170 */ "TRUEFALSE", + /* 171 */ "ISNOT", + /* 172 */ "FUNCTION", + /* 173 */ "UMINUS", + /* 174 */ "UPLUS", + /* 175 */ "TRUTH", + /* 176 */ "REGISTER", + /* 177 */ "VECTOR", + /* 178 */ "SELECT_COLUMN", + /* 179 */ "IF_NULL_ROW", + /* 180 */ "ASTERISK", + /* 181 */ "SPAN", + /* 182 */ "ERROR", + /* 183 */ "SPACE", + /* 184 */ "ILLEGAL", + /* 185 */ "input", + /* 186 */ "cmdlist", + /* 187 */ "ecmd", + /* 188 */ "cmdx", + /* 189 */ "explain", + /* 190 */ "cmd", + /* 191 */ "transtype", + /* 192 */ "trans_opt", + /* 193 */ "nm", + /* 194 */ "savepoint_opt", + /* 195 */ "create_table", + /* 196 */ "create_table_args", + /* 197 */ "createkw", + /* 198 */ "temp", + /* 199 */ "ifnotexists", + /* 200 */ "dbnm", + /* 201 */ "columnlist", + /* 202 */ "conslist_opt", + /* 203 */ "table_option_set", + /* 204 */ "select", + /* 205 */ "table_option", + /* 206 */ "columnname", + /* 207 */ "carglist", + /* 208 */ "typetoken", + /* 209 */ "typename", + /* 210 */ "signed", + /* 211 */ "plus_num", + /* 212 */ "minus_num", + /* 213 */ "scanpt", + /* 214 */ "scantok", + /* 215 */ "ccons", + /* 216 */ "term", + /* 217 */ "expr", + /* 218 */ "onconf", + /* 219 */ "sortorder", + /* 220 */ "autoinc", + /* 221 */ "eidlist_opt", + /* 222 */ "refargs", + /* 223 */ "defer_subclause", + /* 224 */ "generated", + /* 225 */ "refarg", + /* 226 */ "refact", + /* 227 */ "init_deferred_pred_opt", + /* 228 */ "conslist", + /* 229 */ "tconscomma", + /* 230 */ "tcons", + /* 231 */ "sortlist", + /* 232 */ "eidlist", + /* 233 */ "defer_subclause_opt", + /* 234 */ "orconf", + /* 235 */ "resolvetype", + /* 236 */ "raisetype", + /* 237 */ "ifexists", + /* 238 */ "fullname", + /* 239 */ "selectnowith", + /* 240 */ "oneselect", + /* 241 */ "wqlist", + /* 242 */ "multiselect_op", + /* 243 */ "distinct", + /* 244 */ "selcollist", + /* 245 */ "from", + /* 246 */ "where_opt", + /* 247 */ "groupby_opt", + /* 248 */ "having_opt", + /* 249 */ "orderby_opt", + /* 250 */ "limit_opt", + /* 251 */ "window_clause", + /* 252 */ "values", + /* 253 */ "nexprlist", + /* 254 */ "sclp", + /* 255 */ "as", + /* 256 */ "seltablist", + /* 257 */ "stl_prefix", + /* 258 */ "joinop", + /* 259 */ "on_using", + /* 260 */ "indexed_by", + /* 261 */ "exprlist", + /* 262 */ "xfullname", + /* 263 */ "idlist", + /* 264 */ "indexed_opt", + /* 265 */ "nulls", + /* 266 */ "with", + /* 267 */ "where_opt_ret", + /* 268 */ "setlist", + /* 269 */ "insert_cmd", + /* 270 */ "idlist_opt", + /* 271 */ "upsert", + /* 272 */ "returning", + /* 273 */ "filter_over", + /* 274 */ "likeop", + /* 275 */ "between_op", + /* 276 */ "in_op", + /* 277 */ "paren_exprlist", + /* 278 */ "case_operand", + /* 279 */ "case_exprlist", + /* 280 */ "case_else", + /* 281 */ "uniqueflag", + /* 282 */ "collate", + /* 283 */ "vinto", + /* 284 */ "nmnum", + /* 285 */ "trigger_decl", + /* 286 */ "trigger_cmd_list", + /* 287 */ "trigger_time", + /* 288 */ "trigger_event", + /* 289 */ "foreach_clause", + /* 290 */ "when_clause", + /* 291 */ "trigger_cmd", + /* 292 */ "trnm", + /* 293 */ "tridxby", + /* 294 */ "database_kw_opt", + /* 295 */ "key_opt", + /* 296 */ "add_column_fullname", + /* 297 */ "kwcolumn_opt", + /* 298 */ "create_vtab", + /* 299 */ "vtabarglist", + /* 300 */ "vtabarg", + /* 301 */ "vtabargtoken", + /* 302 */ "lp", + /* 303 */ "anylist", + /* 304 */ "wqitem", + /* 305 */ "wqas", + /* 306 */ "windowdefn_list", + /* 307 */ "windowdefn", + /* 308 */ "window", + /* 309 */ "frame_opt", + /* 310 */ "part_opt", + /* 311 */ "filter_clause", + /* 312 */ "over_clause", + /* 313 */ "range_or_rows", + /* 314 */ "frame_bound", + /* 315 */ "frame_bound_s", + /* 316 */ "frame_bound_e", + /* 317 */ "frame_exclude_opt", + /* 318 */ "frame_exclude", +}; +#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { + /* 0 */ "explain ::= EXPLAIN", + /* 1 */ "explain ::= EXPLAIN QUERY PLAN", + /* 2 */ "cmdx ::= cmd", + /* 3 */ "cmd ::= BEGIN transtype trans_opt", + /* 4 */ "transtype ::=", + /* 5 */ "transtype ::= DEFERRED", + /* 6 */ "transtype ::= IMMEDIATE", + /* 7 */ "transtype ::= EXCLUSIVE", + /* 8 */ "cmd ::= COMMIT|END trans_opt", + /* 9 */ "cmd ::= ROLLBACK trans_opt", + /* 10 */ "cmd ::= SAVEPOINT nm", + /* 11 */ "cmd ::= RELEASE savepoint_opt nm", + /* 12 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm", + /* 13 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm", + /* 14 */ "createkw ::= CREATE", + /* 15 */ "ifnotexists ::=", + /* 16 */ "ifnotexists ::= IF NOT EXISTS", + /* 17 */ "temp ::= TEMP", + /* 18 */ "temp ::=", + /* 19 */ "create_table_args ::= LP columnlist conslist_opt RP table_option_set", + /* 20 */ "create_table_args ::= AS select", + /* 21 */ "table_option_set ::=", + /* 22 */ "table_option_set ::= table_option_set COMMA table_option", + /* 23 */ "table_option ::= WITHOUT nm", + /* 24 */ "table_option ::= nm", + /* 25 */ "columnname ::= nm typetoken", + /* 26 */ "typetoken ::=", + /* 27 */ "typetoken ::= typename LP signed RP", + /* 28 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 29 */ "typename ::= typename ID|STRING", + /* 30 */ "scanpt ::=", + /* 31 */ "scantok ::=", + /* 32 */ "ccons ::= CONSTRAINT nm", + /* 33 */ "ccons ::= DEFAULT scantok term", + /* 34 */ "ccons ::= DEFAULT LP expr RP", + /* 35 */ "ccons ::= DEFAULT PLUS scantok term", + /* 36 */ "ccons ::= DEFAULT MINUS scantok term", + /* 37 */ "ccons ::= DEFAULT scantok ID|INDEXED", + /* 38 */ "ccons ::= NOT NULL onconf", + /* 39 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 40 */ "ccons ::= UNIQUE onconf", + /* 41 */ "ccons ::= CHECK LP expr RP", + /* 42 */ "ccons ::= REFERENCES nm eidlist_opt refargs", + /* 43 */ "ccons ::= defer_subclause", + /* 44 */ "ccons ::= COLLATE ID|STRING", + /* 45 */ "generated ::= LP expr RP", + /* 46 */ "generated ::= LP expr RP ID", + /* 47 */ "autoinc ::=", + /* 48 */ "autoinc ::= AUTOINCR", + /* 49 */ "refargs ::=", + /* 50 */ "refargs ::= refargs refarg", + /* 51 */ "refarg ::= MATCH nm", + /* 52 */ "refarg ::= ON INSERT refact", + /* 53 */ "refarg ::= ON DELETE refact", + /* 54 */ "refarg ::= ON UPDATE refact", + /* 55 */ "refact ::= SET NULL", + /* 56 */ "refact ::= SET DEFAULT", + /* 57 */ "refact ::= CASCADE", + /* 58 */ "refact ::= RESTRICT", + /* 59 */ "refact ::= NO ACTION", + /* 60 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 61 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 62 */ "init_deferred_pred_opt ::=", + /* 63 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 64 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 65 */ "conslist_opt ::=", + /* 66 */ "tconscomma ::= COMMA", + /* 67 */ "tcons ::= CONSTRAINT nm", + /* 68 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", + /* 69 */ "tcons ::= UNIQUE LP sortlist RP onconf", + /* 70 */ "tcons ::= CHECK LP expr RP onconf", + /* 71 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", + /* 72 */ "defer_subclause_opt ::=", + /* 73 */ "onconf ::=", + /* 74 */ "onconf ::= ON CONFLICT resolvetype", + /* 75 */ "orconf ::=", + /* 76 */ "orconf ::= OR resolvetype", + /* 77 */ "resolvetype ::= IGNORE", + /* 78 */ "resolvetype ::= REPLACE", + /* 79 */ "cmd ::= DROP TABLE ifexists fullname", + /* 80 */ "ifexists ::= IF EXISTS", + /* 81 */ "ifexists ::=", + /* 82 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", + /* 83 */ "cmd ::= DROP VIEW ifexists fullname", + /* 84 */ "cmd ::= select", + /* 85 */ "select ::= WITH wqlist selectnowith", + /* 86 */ "select ::= WITH RECURSIVE wqlist selectnowith", + /* 87 */ "select ::= selectnowith", + /* 88 */ "selectnowith ::= selectnowith multiselect_op oneselect", + /* 89 */ "multiselect_op ::= UNION", + /* 90 */ "multiselect_op ::= UNION ALL", + /* 91 */ "multiselect_op ::= EXCEPT|INTERSECT", + /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", + /* 94 */ "values ::= VALUES LP nexprlist RP", + /* 95 */ "values ::= values COMMA LP nexprlist RP", + /* 96 */ "distinct ::= DISTINCT", + /* 97 */ "distinct ::= ALL", + /* 98 */ "distinct ::=", + /* 99 */ "sclp ::=", + /* 100 */ "selcollist ::= sclp scanpt expr scanpt as", + /* 101 */ "selcollist ::= sclp scanpt STAR", + /* 102 */ "selcollist ::= sclp scanpt nm DOT STAR", + /* 103 */ "as ::= AS nm", + /* 104 */ "as ::=", + /* 105 */ "from ::=", + /* 106 */ "from ::= FROM seltablist", + /* 107 */ "stl_prefix ::= seltablist joinop", + /* 108 */ "stl_prefix ::=", + /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using", + /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", + /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", + /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using", + /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", + /* 114 */ "dbnm ::=", + /* 115 */ "dbnm ::= DOT nm", + /* 116 */ "fullname ::= nm", + /* 117 */ "fullname ::= nm DOT nm", + /* 118 */ "xfullname ::= nm", + /* 119 */ "xfullname ::= nm DOT nm", + /* 120 */ "xfullname ::= nm DOT nm AS nm", + /* 121 */ "xfullname ::= nm AS nm", + /* 122 */ "joinop ::= COMMA|JOIN", + /* 123 */ "joinop ::= JOIN_KW JOIN", + /* 124 */ "joinop ::= JOIN_KW nm JOIN", + /* 125 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 126 */ "on_using ::= ON expr", + /* 127 */ "on_using ::= USING LP idlist RP", + /* 128 */ "on_using ::=", + /* 129 */ "indexed_opt ::=", + /* 130 */ "indexed_by ::= INDEXED BY nm", + /* 131 */ "indexed_by ::= NOT INDEXED", + /* 132 */ "orderby_opt ::=", + /* 133 */ "orderby_opt ::= ORDER BY sortlist", + /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls", + /* 135 */ "sortlist ::= expr sortorder nulls", + /* 136 */ "sortorder ::= ASC", + /* 137 */ "sortorder ::= DESC", + /* 138 */ "sortorder ::=", + /* 139 */ "nulls ::= NULLS FIRST", + /* 140 */ "nulls ::= NULLS LAST", + /* 141 */ "nulls ::=", + /* 142 */ "groupby_opt ::=", + /* 143 */ "groupby_opt ::= GROUP BY nexprlist", + /* 144 */ "having_opt ::=", + /* 145 */ "having_opt ::= HAVING expr", + /* 146 */ "limit_opt ::=", + /* 147 */ "limit_opt ::= LIMIT expr", + /* 148 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 149 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 150 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret orderby_opt limit_opt", + /* 151 */ "where_opt ::=", + /* 152 */ "where_opt ::= WHERE expr", + /* 153 */ "where_opt_ret ::=", + /* 154 */ "where_opt_ret ::= WHERE expr", + /* 155 */ "where_opt_ret ::= RETURNING selcollist", + /* 156 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 157 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret orderby_opt limit_opt", + /* 158 */ "setlist ::= setlist COMMA nm EQ expr", + /* 159 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 160 */ "setlist ::= nm EQ expr", + /* 161 */ "setlist ::= LP idlist RP EQ expr", + /* 162 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 163 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 164 */ "upsert ::=", + /* 165 */ "upsert ::= RETURNING selcollist", + /* 166 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 167 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 168 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 169 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 170 */ "returning ::= RETURNING selcollist", + /* 171 */ "insert_cmd ::= INSERT orconf", + /* 172 */ "insert_cmd ::= REPLACE", + /* 173 */ "idlist_opt ::=", + /* 174 */ "idlist_opt ::= LP idlist RP", + /* 175 */ "idlist ::= idlist COMMA nm", + /* 176 */ "idlist ::= nm", + /* 177 */ "expr ::= LP expr RP", + /* 178 */ "expr ::= ID|INDEXED|JOIN_KW", + /* 179 */ "expr ::= nm DOT nm", + /* 180 */ "expr ::= nm DOT nm DOT nm", + /* 181 */ "term ::= NULL|FLOAT|BLOB", + /* 182 */ "term ::= STRING", + /* 183 */ "term ::= INTEGER", + /* 184 */ "expr ::= VARIABLE", + /* 185 */ "expr ::= expr COLLATE ID|STRING", + /* 186 */ "expr ::= CAST LP expr AS typetoken RP", + /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", + /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", + /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", + /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", + /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", + /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", + /* 193 */ "term ::= CTIME_KW", + /* 194 */ "expr ::= LP nexprlist COMMA expr RP", + /* 195 */ "expr ::= expr AND expr", + /* 196 */ "expr ::= expr OR expr", + /* 197 */ "expr ::= expr LT|GT|GE|LE expr", + /* 198 */ "expr ::= expr EQ|NE expr", + /* 199 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 200 */ "expr ::= expr PLUS|MINUS expr", + /* 201 */ "expr ::= expr STAR|SLASH|REM expr", + /* 202 */ "expr ::= expr CONCAT expr", + /* 203 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 204 */ "expr ::= expr likeop expr", + /* 205 */ "expr ::= expr likeop expr ESCAPE expr", + /* 206 */ "expr ::= expr ISNULL|NOTNULL", + /* 207 */ "expr ::= expr NOT NULL", + /* 208 */ "expr ::= expr IS expr", + /* 209 */ "expr ::= expr IS NOT expr", + /* 210 */ "expr ::= expr IS NOT DISTINCT FROM expr", + /* 211 */ "expr ::= expr IS DISTINCT FROM expr", + /* 212 */ "expr ::= NOT expr", + /* 213 */ "expr ::= BITNOT expr", + /* 214 */ "expr ::= PLUS|MINUS expr", + /* 215 */ "expr ::= expr PTR expr", + /* 216 */ "between_op ::= BETWEEN", + /* 217 */ "between_op ::= NOT BETWEEN", + /* 218 */ "expr ::= expr between_op expr AND expr", + /* 219 */ "in_op ::= IN", + /* 220 */ "in_op ::= NOT IN", + /* 221 */ "expr ::= expr in_op LP exprlist RP", + /* 222 */ "expr ::= LP select RP", + /* 223 */ "expr ::= expr in_op LP select RP", + /* 224 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 225 */ "expr ::= EXISTS LP select RP", + /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 228 */ "case_exprlist ::= WHEN expr THEN expr", + /* 229 */ "case_else ::= ELSE expr", + /* 230 */ "case_else ::=", + /* 231 */ "case_operand ::=", + /* 232 */ "exprlist ::=", + /* 233 */ "nexprlist ::= nexprlist COMMA expr", + /* 234 */ "nexprlist ::= expr", + /* 235 */ "paren_exprlist ::=", + /* 236 */ "paren_exprlist ::= LP exprlist RP", + /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 238 */ "uniqueflag ::= UNIQUE", + /* 239 */ "uniqueflag ::=", + /* 240 */ "eidlist_opt ::=", + /* 241 */ "eidlist_opt ::= LP eidlist RP", + /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 243 */ "eidlist ::= nm collate sortorder", + /* 244 */ "collate ::=", + /* 245 */ "collate ::= COLLATE ID|STRING", + /* 246 */ "cmd ::= DROP INDEX ifexists fullname", + /* 247 */ "cmd ::= VACUUM vinto", + /* 248 */ "cmd ::= VACUUM nm vinto", + /* 249 */ "vinto ::= INTO expr", + /* 250 */ "vinto ::=", + /* 251 */ "cmd ::= PRAGMA nm dbnm", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 260 */ "trigger_time ::= BEFORE|AFTER", + /* 261 */ "trigger_time ::= INSTEAD OF", + /* 262 */ "trigger_time ::=", + /* 263 */ "trigger_event ::= DELETE|INSERT", + /* 264 */ "trigger_event ::= UPDATE", + /* 265 */ "trigger_event ::= UPDATE OF idlist", + /* 266 */ "when_clause ::=", + /* 267 */ "when_clause ::= WHEN expr", + /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 270 */ "trnm ::= nm DOT nm", + /* 271 */ "tridxby ::= INDEXED BY nm", + /* 272 */ "tridxby ::= NOT INDEXED", + /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 276 */ "trigger_cmd ::= scanpt select scanpt", + /* 277 */ "expr ::= RAISE LP IGNORE RP", + /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 279 */ "raisetype ::= ROLLBACK", + /* 280 */ "raisetype ::= ABORT", + /* 281 */ "raisetype ::= FAIL", + /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 284 */ "cmd ::= DETACH database_kw_opt expr", + /* 285 */ "key_opt ::=", + /* 286 */ "key_opt ::= KEY expr", + /* 287 */ "cmd ::= REINDEX", + /* 288 */ "cmd ::= REINDEX nm dbnm", + /* 289 */ "cmd ::= ANALYZE", + /* 290 */ "cmd ::= ANALYZE nm dbnm", + /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 294 */ "add_column_fullname ::= fullname", + /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 296 */ "cmd ::= create_vtab", + /* 297 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 299 */ "vtabarg ::=", + /* 300 */ "vtabargtoken ::= ANY", + /* 301 */ "vtabargtoken ::= lp anylist RP", + /* 302 */ "lp ::= LP", + /* 303 */ "with ::= WITH wqlist", + /* 304 */ "with ::= WITH RECURSIVE wqlist", + /* 305 */ "wqas ::= AS", + /* 306 */ "wqas ::= AS MATERIALIZED", + /* 307 */ "wqas ::= AS NOT MATERIALIZED", + /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 309 */ "wqlist ::= wqitem", + /* 310 */ "wqlist ::= wqlist COMMA wqitem", + /* 311 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 312 */ "windowdefn ::= nm AS LP window RP", + /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 315 */ "window ::= ORDER BY sortlist frame_opt", + /* 316 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 317 */ "window ::= nm frame_opt", + /* 318 */ "frame_opt ::=", + /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 322 */ "frame_bound_s ::= frame_bound", + /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 324 */ "frame_bound_e ::= frame_bound", + /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 327 */ "frame_bound ::= CURRENT ROW", + /* 328 */ "frame_exclude_opt ::=", + /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 330 */ "frame_exclude ::= NO OTHERS", + /* 331 */ "frame_exclude ::= CURRENT ROW", + /* 332 */ "frame_exclude ::= GROUP|TIES", + /* 333 */ "window_clause ::= WINDOW windowdefn_list", + /* 334 */ "filter_over ::= filter_clause over_clause", + /* 335 */ "filter_over ::= over_clause", + /* 336 */ "filter_over ::= filter_clause", + /* 337 */ "over_clause ::= OVER LP window RP", + /* 338 */ "over_clause ::= OVER nm", + /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 340 */ "input ::= cmdlist", + /* 341 */ "cmdlist ::= cmdlist ecmd", + /* 342 */ "cmdlist ::= ecmd", + /* 343 */ "ecmd ::= SEMI", + /* 344 */ "ecmd ::= cmdx SEMI", + /* 345 */ "ecmd ::= explain cmdx SEMI", + /* 346 */ "trans_opt ::=", + /* 347 */ "trans_opt ::= TRANSACTION", + /* 348 */ "trans_opt ::= TRANSACTION nm", + /* 349 */ "savepoint_opt ::= SAVEPOINT", + /* 350 */ "savepoint_opt ::=", + /* 351 */ "cmd ::= create_table create_table_args", + /* 352 */ "table_option_set ::= table_option", + /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 354 */ "columnlist ::= columnname carglist", + /* 355 */ "nm ::= ID|INDEXED|JOIN_KW", + /* 356 */ "nm ::= STRING", + /* 357 */ "typetoken ::= typename", + /* 358 */ "typename ::= ID|STRING", + /* 359 */ "signed ::= plus_num", + /* 360 */ "signed ::= minus_num", + /* 361 */ "carglist ::= carglist ccons", + /* 362 */ "carglist ::=", + /* 363 */ "ccons ::= NULL onconf", + /* 364 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 365 */ "ccons ::= AS generated", + /* 366 */ "conslist_opt ::= COMMA conslist", + /* 367 */ "conslist ::= conslist tconscomma tcons", + /* 368 */ "conslist ::= tcons", + /* 369 */ "tconscomma ::=", + /* 370 */ "defer_subclause_opt ::= defer_subclause", + /* 371 */ "resolvetype ::= raisetype", + /* 372 */ "selectnowith ::= oneselect", + /* 373 */ "oneselect ::= values", + /* 374 */ "sclp ::= selcollist COMMA", + /* 375 */ "as ::= ID|STRING", + /* 376 */ "indexed_opt ::= indexed_by", + /* 377 */ "returning ::=", + /* 378 */ "expr ::= term", + /* 379 */ "likeop ::= LIKE_KW|MATCH", + /* 380 */ "case_operand ::= expr", + /* 381 */ "exprlist ::= nexprlist", + /* 382 */ "nmnum ::= plus_num", + /* 383 */ "nmnum ::= nm", + /* 384 */ "nmnum ::= ON", + /* 385 */ "nmnum ::= DELETE", + /* 386 */ "nmnum ::= DEFAULT", + /* 387 */ "plus_num ::= INTEGER|FLOAT", + /* 388 */ "foreach_clause ::=", + /* 389 */ "foreach_clause ::= FOR EACH ROW", + /* 390 */ "trnm ::= nm", + /* 391 */ "tridxby ::=", + /* 392 */ "database_kw_opt ::= DATABASE", + /* 393 */ "database_kw_opt ::=", + /* 394 */ "kwcolumn_opt ::=", + /* 395 */ "kwcolumn_opt ::= COLUMNKW", + /* 396 */ "vtabarglist ::= vtabarg", + /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 398 */ "vtabarg ::= vtabarg vtabargtoken", + /* 399 */ "anylist ::=", + /* 400 */ "anylist ::= anylist LP anylist RP", + /* 401 */ "anylist ::= anylist ANY", + /* 402 */ "with ::=", + /* 403 */ "windowdefn_list ::= windowdefn", + /* 404 */ "window ::= frame_opt", +}; +#endif /* NDEBUG */ + + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. Return the number +** of errors. Return 0 on success. +*/ +static int yyGrowStack(yyParser *p){ + int newSize; + int idx; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; + if( p->yystack==&p->yystk0 ){ + pNew = malloc(newSize*sizeof(pNew[0])); + if( pNew ) pNew[0] = p->yystk0; + }else{ + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + } + if( pNew ){ + p->yystack = pNew; + p->yytos = &p->yystack[idx]; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, p->yystksz, newSize); + } +#endif + p->yystksz = newSize; + } + return pNew==0; +} +#endif + +/* Datatype of the argument to the memory allocated passed as the +** second argument to sqlite3ParserAlloc() below. This can be changed by +** putting an appropriate #define in the %include section of the input +** grammar. +*/ +#ifndef YYMALLOCARGTYPE +# define YYMALLOCARGTYPE size_t +#endif + +/* Initialize a new parser that has already been allocated. +*/ +SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){ + yyParser *yypParser = (yyParser*)yypRawParser; + sqlite3ParserCTX_STORE +#ifdef YYTRACKMAXSTACKDEPTH + yypParser->yyhwm = 0; +#endif +#if YYSTACKDEPTH<=0 + yypParser->yytos = NULL; + yypParser->yystack = NULL; + yypParser->yystksz = 0; + if( yyGrowStack(yypParser) ){ + yypParser->yystack = &yypParser->yystk0; + yypParser->yystksz = 1; + } +#endif +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + yypParser->yytos = yypParser->yystack; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; +#if YYSTACKDEPTH>0 + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; +#endif +} + +#ifndef sqlite3Parser_ENGINEALWAYSONSTACK +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to sqlite3Parser and sqlite3ParserFree. +*/ +SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){ + yyParser *yypParser; + yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( yypParser ){ + sqlite3ParserCTX_STORE + sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM); + } + return (void*)yypParser; +} +#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ + + +/* The following function deletes the "minor type" or semantic value +** associated with a symbol. The symbol can be either a terminal +** or nonterminal. "yymajor" is the symbol code, and "yypminor" is +** a pointer to the value to be deleted. The code used to do the +** deletions is derived from the %destructor and/or %token_destructor +** directives of the input grammar. +*/ +static void yy_destructor( + yyParser *yypParser, /* The parser */ + YYCODETYPE yymajor, /* Type code for object to destroy */ + YYMINORTYPE *yypminor /* The object to be destroyed */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are *not* used + ** inside the C code. + */ +/********* Begin destructor definitions ***************************************/ + case 204: /* select */ + case 239: /* selectnowith */ + case 240: /* oneselect */ + case 252: /* values */ +{ +sqlite3SelectDelete(pParse->db, (yypminor->yy47)); +} + break; + case 216: /* term */ + case 217: /* expr */ + case 246: /* where_opt */ + case 248: /* having_opt */ + case 267: /* where_opt_ret */ + case 278: /* case_operand */ + case 280: /* case_else */ + case 283: /* vinto */ + case 290: /* when_clause */ + case 295: /* key_opt */ + case 311: /* filter_clause */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy528)); +} + break; + case 221: /* eidlist_opt */ + case 231: /* sortlist */ + case 232: /* eidlist */ + case 244: /* selcollist */ + case 247: /* groupby_opt */ + case 249: /* orderby_opt */ + case 253: /* nexprlist */ + case 254: /* sclp */ + case 261: /* exprlist */ + case 268: /* setlist */ + case 277: /* paren_exprlist */ + case 279: /* case_exprlist */ + case 310: /* part_opt */ +{ +sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); +} + break; + case 238: /* fullname */ + case 245: /* from */ + case 256: /* seltablist */ + case 257: /* stl_prefix */ + case 262: /* xfullname */ +{ +sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); +} + break; + case 241: /* wqlist */ +{ +sqlite3WithDelete(pParse->db, (yypminor->yy521)); +} + break; + case 251: /* window_clause */ + case 306: /* windowdefn_list */ +{ +sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); +} + break; + case 263: /* idlist */ + case 270: /* idlist_opt */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy254)); +} + break; + case 273: /* filter_over */ + case 307: /* windowdefn */ + case 308: /* window */ + case 309: /* frame_opt */ + case 312: /* over_clause */ +{ +sqlite3WindowDelete(pParse->db, (yypminor->yy41)); +} + break; + case 286: /* trigger_cmd_list */ + case 291: /* trigger_cmd */ +{ +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); +} + break; + case 288: /* trigger_event */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); +} + break; + case 314: /* frame_bound */ + case 315: /* frame_bound_s */ + case 316: /* frame_bound_e */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); +} + break; +/********* End destructor definitions *****************************************/ + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +*/ +static void yy_pop_parser_stack(yyParser *pParser){ + yyStackEntry *yytos; + assert( pParser->yytos!=0 ); + assert( pParser->yytos > pParser->yystack ); + yytos = pParser->yytos--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yy_destructor(pParser, yytos->major, &yytos->minor); +} + +/* +** Clear all secondary memory allocations from the parser +*/ +SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ + yyParser *pParser = (yyParser*)p; + while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); +#endif +} + +#ifndef sqlite3Parser_ENGINEALWAYSONSTACK +/* +** Deallocate and destroy a parser. Destructors are called for +** all stack elements before shutting the parser down. +** +** If the YYPARSEFREENEVERNULL macro exists (for example because it +** is defined in a %include section of the input grammar) then it is +** assumed that the input pointer is never NULL. +*/ +SQLITE_PRIVATE void sqlite3ParserFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ +#ifndef YYPARSEFREENEVERNULL + if( p==0 ) return; +#endif + sqlite3ParserFinalize(p); + (*freeProc)(p); +} +#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ + +/* +** Return the peak depth of the stack for a parser. +*/ +#ifdef YYTRACKMAXSTACKDEPTH +SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){ + yyParser *pParser = (yyParser*)p; + return pParser->yyhwm; +} +#endif + +/* This array of booleans keeps track of the parser statement +** coverage. The element yycoverage[X][Y] is set when the parser +** is in state X and has a lookahead token Y. In a well-tested +** systems, every element of this matrix should end up being set. +*/ +#if defined(YYCOVERAGE) +static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; +#endif + +/* +** Write into out a description of every state/lookahead combination that +** +** (1) has not been used by the parser, and +** (2) is not a syntax error. +** +** Return the number of missed state/lookahead combinations. +*/ +#if defined(YYCOVERAGE) +SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){ + int stateno, iLookAhead, i; + int nMissed = 0; + for(stateno=0; statenoYY_MAX_SHIFT ) return stateno; + assert( stateno <= YY_SHIFT_COUNT ); +#if defined(YYCOVERAGE) + yycoverage[stateno][iLookAhead] = 1; +#endif + do{ + i = yy_shift_ofst[stateno]; + assert( i>=0 ); + assert( i<=YY_ACTTAB_COUNT ); + assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); + assert( iLookAhead!=YYNOCODE ); + assert( iLookAhead < YYNTOKEN ); + i += iLookAhead; + assert( i<(int)YY_NLOOKAHEAD ); + if( yy_lookahead[i]!=iLookAhead ){ +#ifdef YYFALLBACK + YYCODETYPE iFallback; /* Fallback token */ + assert( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ + iLookAhead = iFallback; + continue; + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); + if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], + yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + return yy_default[stateno]; + }else{ + assert( i>=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); + return yy_action[i]; + } + }while(1); +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +*/ +static YYACTIONTYPE yy_find_reduce_action( + YYACTIONTYPE stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; +#ifdef YYERRORSYMBOL + if( stateno>YY_REDUCE_COUNT ){ + return yy_default[stateno]; + } +#else + assert( stateno<=YY_REDUCE_COUNT ); +#endif + i = yy_reduce_ofst[stateno]; + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; +#ifdef YYERRORSYMBOL + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + } +#else + assert( i>=0 && iyytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ +/******** Begin %stack_overflow code ******************************************/ + + sqlite3ErrorMsg(pParse, "parser stack overflow"); +/******** End %stack_overflow code ********************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ + sqlite3ParserCTX_STORE +} + +/* +** Print tracing information for a SHIFT action +*/ +#ifndef NDEBUG +static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){ + if( yyTraceFILE ){ + if( yyNewStateyytos->major], + yyNewState); + }else{ + fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n", + yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], + yyNewState - YY_MIN_REDUCE); + } + } +} +#else +# define yyTraceShift(X,Y,Z) +#endif + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + YYACTIONTYPE yyNewState, /* The new state to shift in */ + YYCODETYPE yyMajor, /* The major token to shift in */ + sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yytos++; +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>yypParser->yystackEnd ){ + yypParser->yytos--; + yyStackOverflow(yypParser); + return; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ + if( yyGrowStack(yypParser) ){ + yypParser->yytos--; + yyStackOverflow(yypParser); + return; + } + } +#endif + if( yyNewState > YY_MAX_SHIFT ){ + yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } + yytos = yypParser->yytos; + yytos->stateno = yyNewState; + yytos->major = yyMajor; + yytos->minor.yy0 = yyMinor; + yyTraceShift(yypParser, yyNewState, "Shift"); +} + +/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side +** of that rule */ +static const YYCODETYPE yyRuleInfoLhs[] = { + 189, /* (0) explain ::= EXPLAIN */ + 189, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 188, /* (2) cmdx ::= cmd */ + 190, /* (3) cmd ::= BEGIN transtype trans_opt */ + 191, /* (4) transtype ::= */ + 191, /* (5) transtype ::= DEFERRED */ + 191, /* (6) transtype ::= IMMEDIATE */ + 191, /* (7) transtype ::= EXCLUSIVE */ + 190, /* (8) cmd ::= COMMIT|END trans_opt */ + 190, /* (9) cmd ::= ROLLBACK trans_opt */ + 190, /* (10) cmd ::= SAVEPOINT nm */ + 190, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 197, /* (14) createkw ::= CREATE */ + 199, /* (15) ifnotexists ::= */ + 199, /* (16) ifnotexists ::= IF NOT EXISTS */ + 198, /* (17) temp ::= TEMP */ + 198, /* (18) temp ::= */ + 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + 196, /* (20) create_table_args ::= AS select */ + 203, /* (21) table_option_set ::= */ + 203, /* (22) table_option_set ::= table_option_set COMMA table_option */ + 205, /* (23) table_option ::= WITHOUT nm */ + 205, /* (24) table_option ::= nm */ + 206, /* (25) columnname ::= nm typetoken */ + 208, /* (26) typetoken ::= */ + 208, /* (27) typetoken ::= typename LP signed RP */ + 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + 209, /* (29) typename ::= typename ID|STRING */ + 213, /* (30) scanpt ::= */ + 214, /* (31) scantok ::= */ + 215, /* (32) ccons ::= CONSTRAINT nm */ + 215, /* (33) ccons ::= DEFAULT scantok term */ + 215, /* (34) ccons ::= DEFAULT LP expr RP */ + 215, /* (35) ccons ::= DEFAULT PLUS scantok term */ + 215, /* (36) ccons ::= DEFAULT MINUS scantok term */ + 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + 215, /* (38) ccons ::= NOT NULL onconf */ + 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 215, /* (40) ccons ::= UNIQUE onconf */ + 215, /* (41) ccons ::= CHECK LP expr RP */ + 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + 215, /* (43) ccons ::= defer_subclause */ + 215, /* (44) ccons ::= COLLATE ID|STRING */ + 224, /* (45) generated ::= LP expr RP */ + 224, /* (46) generated ::= LP expr RP ID */ + 220, /* (47) autoinc ::= */ + 220, /* (48) autoinc ::= AUTOINCR */ + 222, /* (49) refargs ::= */ + 222, /* (50) refargs ::= refargs refarg */ + 225, /* (51) refarg ::= MATCH nm */ + 225, /* (52) refarg ::= ON INSERT refact */ + 225, /* (53) refarg ::= ON DELETE refact */ + 225, /* (54) refarg ::= ON UPDATE refact */ + 226, /* (55) refact ::= SET NULL */ + 226, /* (56) refact ::= SET DEFAULT */ + 226, /* (57) refact ::= CASCADE */ + 226, /* (58) refact ::= RESTRICT */ + 226, /* (59) refact ::= NO ACTION */ + 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 227, /* (62) init_deferred_pred_opt ::= */ + 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 202, /* (65) conslist_opt ::= */ + 229, /* (66) tconscomma ::= COMMA */ + 230, /* (67) tcons ::= CONSTRAINT nm */ + 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + 230, /* (70) tcons ::= CHECK LP expr RP onconf */ + 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 233, /* (72) defer_subclause_opt ::= */ + 218, /* (73) onconf ::= */ + 218, /* (74) onconf ::= ON CONFLICT resolvetype */ + 234, /* (75) orconf ::= */ + 234, /* (76) orconf ::= OR resolvetype */ + 235, /* (77) resolvetype ::= IGNORE */ + 235, /* (78) resolvetype ::= REPLACE */ + 190, /* (79) cmd ::= DROP TABLE ifexists fullname */ + 237, /* (80) ifexists ::= IF EXISTS */ + 237, /* (81) ifexists ::= */ + 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 190, /* (83) cmd ::= DROP VIEW ifexists fullname */ + 190, /* (84) cmd ::= select */ + 204, /* (85) select ::= WITH wqlist selectnowith */ + 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + 204, /* (87) select ::= selectnowith */ + 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + 242, /* (89) multiselect_op ::= UNION */ + 242, /* (90) multiselect_op ::= UNION ALL */ + 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 252, /* (94) values ::= VALUES LP nexprlist RP */ + 252, /* (95) values ::= values COMMA LP nexprlist RP */ + 243, /* (96) distinct ::= DISTINCT */ + 243, /* (97) distinct ::= ALL */ + 243, /* (98) distinct ::= */ + 254, /* (99) sclp ::= */ + 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */ + 244, /* (101) selcollist ::= sclp scanpt STAR */ + 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ + 255, /* (103) as ::= AS nm */ + 255, /* (104) as ::= */ + 245, /* (105) from ::= */ + 245, /* (106) from ::= FROM seltablist */ + 257, /* (107) stl_prefix ::= seltablist joinop */ + 257, /* (108) stl_prefix ::= */ + 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ + 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ + 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 200, /* (114) dbnm ::= */ + 200, /* (115) dbnm ::= DOT nm */ + 238, /* (116) fullname ::= nm */ + 238, /* (117) fullname ::= nm DOT nm */ + 262, /* (118) xfullname ::= nm */ + 262, /* (119) xfullname ::= nm DOT nm */ + 262, /* (120) xfullname ::= nm DOT nm AS nm */ + 262, /* (121) xfullname ::= nm AS nm */ + 258, /* (122) joinop ::= COMMA|JOIN */ + 258, /* (123) joinop ::= JOIN_KW JOIN */ + 258, /* (124) joinop ::= JOIN_KW nm JOIN */ + 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */ + 259, /* (126) on_using ::= ON expr */ + 259, /* (127) on_using ::= USING LP idlist RP */ + 259, /* (128) on_using ::= */ + 264, /* (129) indexed_opt ::= */ + 260, /* (130) indexed_by ::= INDEXED BY nm */ + 260, /* (131) indexed_by ::= NOT INDEXED */ + 249, /* (132) orderby_opt ::= */ + 249, /* (133) orderby_opt ::= ORDER BY sortlist */ + 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ + 231, /* (135) sortlist ::= expr sortorder nulls */ + 219, /* (136) sortorder ::= ASC */ + 219, /* (137) sortorder ::= DESC */ + 219, /* (138) sortorder ::= */ + 265, /* (139) nulls ::= NULLS FIRST */ + 265, /* (140) nulls ::= NULLS LAST */ + 265, /* (141) nulls ::= */ + 247, /* (142) groupby_opt ::= */ + 247, /* (143) groupby_opt ::= GROUP BY nexprlist */ + 248, /* (144) having_opt ::= */ + 248, /* (145) having_opt ::= HAVING expr */ + 250, /* (146) limit_opt ::= */ + 250, /* (147) limit_opt ::= LIMIT expr */ + 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ + 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */ + 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret orderby_opt limit_opt */ + 246, /* (151) where_opt ::= */ + 246, /* (152) where_opt ::= WHERE expr */ + 267, /* (153) where_opt_ret ::= */ + 267, /* (154) where_opt_ret ::= WHERE expr */ + 267, /* (155) where_opt_ret ::= RETURNING selcollist */ + 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret orderby_opt limit_opt */ + 268, /* (158) setlist ::= setlist COMMA nm EQ expr */ + 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 268, /* (160) setlist ::= nm EQ expr */ + 268, /* (161) setlist ::= LP idlist RP EQ expr */ + 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 271, /* (164) upsert ::= */ + 271, /* (165) upsert ::= RETURNING selcollist */ + 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ + 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 272, /* (170) returning ::= RETURNING selcollist */ + 269, /* (171) insert_cmd ::= INSERT orconf */ + 269, /* (172) insert_cmd ::= REPLACE */ + 270, /* (173) idlist_opt ::= */ + 270, /* (174) idlist_opt ::= LP idlist RP */ + 263, /* (175) idlist ::= idlist COMMA nm */ + 263, /* (176) idlist ::= nm */ + 217, /* (177) expr ::= LP expr RP */ + 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */ + 217, /* (179) expr ::= nm DOT nm */ + 217, /* (180) expr ::= nm DOT nm DOT nm */ + 216, /* (181) term ::= NULL|FLOAT|BLOB */ + 216, /* (182) term ::= STRING */ + 216, /* (183) term ::= INTEGER */ + 217, /* (184) expr ::= VARIABLE */ + 217, /* (185) expr ::= expr COLLATE ID|STRING */ + 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ + 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + 217, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + 217, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + 216, /* (193) term ::= CTIME_KW */ + 217, /* (194) expr ::= LP nexprlist COMMA expr RP */ + 217, /* (195) expr ::= expr AND expr */ + 217, /* (196) expr ::= expr OR expr */ + 217, /* (197) expr ::= expr LT|GT|GE|LE expr */ + 217, /* (198) expr ::= expr EQ|NE expr */ + 217, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 217, /* (200) expr ::= expr PLUS|MINUS expr */ + 217, /* (201) expr ::= expr STAR|SLASH|REM expr */ + 217, /* (202) expr ::= expr CONCAT expr */ + 274, /* (203) likeop ::= NOT LIKE_KW|MATCH */ + 217, /* (204) expr ::= expr likeop expr */ + 217, /* (205) expr ::= expr likeop expr ESCAPE expr */ + 217, /* (206) expr ::= expr ISNULL|NOTNULL */ + 217, /* (207) expr ::= expr NOT NULL */ + 217, /* (208) expr ::= expr IS expr */ + 217, /* (209) expr ::= expr IS NOT expr */ + 217, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ + 217, /* (211) expr ::= expr IS DISTINCT FROM expr */ + 217, /* (212) expr ::= NOT expr */ + 217, /* (213) expr ::= BITNOT expr */ + 217, /* (214) expr ::= PLUS|MINUS expr */ + 217, /* (215) expr ::= expr PTR expr */ + 275, /* (216) between_op ::= BETWEEN */ + 275, /* (217) between_op ::= NOT BETWEEN */ + 217, /* (218) expr ::= expr between_op expr AND expr */ + 276, /* (219) in_op ::= IN */ + 276, /* (220) in_op ::= NOT IN */ + 217, /* (221) expr ::= expr in_op LP exprlist RP */ + 217, /* (222) expr ::= LP select RP */ + 217, /* (223) expr ::= expr in_op LP select RP */ + 217, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ + 217, /* (225) expr ::= EXISTS LP select RP */ + 217, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ + 279, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 279, /* (228) case_exprlist ::= WHEN expr THEN expr */ + 280, /* (229) case_else ::= ELSE expr */ + 280, /* (230) case_else ::= */ + 278, /* (231) case_operand ::= */ + 261, /* (232) exprlist ::= */ + 253, /* (233) nexprlist ::= nexprlist COMMA expr */ + 253, /* (234) nexprlist ::= expr */ + 277, /* (235) paren_exprlist ::= */ + 277, /* (236) paren_exprlist ::= LP exprlist RP */ + 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 281, /* (238) uniqueflag ::= UNIQUE */ + 281, /* (239) uniqueflag ::= */ + 221, /* (240) eidlist_opt ::= */ + 221, /* (241) eidlist_opt ::= LP eidlist RP */ + 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ + 232, /* (243) eidlist ::= nm collate sortorder */ + 282, /* (244) collate ::= */ + 282, /* (245) collate ::= COLLATE ID|STRING */ + 190, /* (246) cmd ::= DROP INDEX ifexists fullname */ + 190, /* (247) cmd ::= VACUUM vinto */ + 190, /* (248) cmd ::= VACUUM nm vinto */ + 283, /* (249) vinto ::= INTO expr */ + 283, /* (250) vinto ::= */ + 190, /* (251) cmd ::= PRAGMA nm dbnm */ + 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ + 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ + 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 287, /* (260) trigger_time ::= BEFORE|AFTER */ + 287, /* (261) trigger_time ::= INSTEAD OF */ + 287, /* (262) trigger_time ::= */ + 288, /* (263) trigger_event ::= DELETE|INSERT */ + 288, /* (264) trigger_event ::= UPDATE */ + 288, /* (265) trigger_event ::= UPDATE OF idlist */ + 290, /* (266) when_clause ::= */ + 290, /* (267) when_clause ::= WHEN expr */ + 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ + 292, /* (270) trnm ::= nm DOT nm */ + 293, /* (271) tridxby ::= INDEXED BY nm */ + 293, /* (272) tridxby ::= NOT INDEXED */ + 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 291, /* (276) trigger_cmd ::= scanpt select scanpt */ + 217, /* (277) expr ::= RAISE LP IGNORE RP */ + 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ + 236, /* (279) raisetype ::= ROLLBACK */ + 236, /* (280) raisetype ::= ABORT */ + 236, /* (281) raisetype ::= FAIL */ + 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ + 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 190, /* (284) cmd ::= DETACH database_kw_opt expr */ + 295, /* (285) key_opt ::= */ + 295, /* (286) key_opt ::= KEY expr */ + 190, /* (287) cmd ::= REINDEX */ + 190, /* (288) cmd ::= REINDEX nm dbnm */ + 190, /* (289) cmd ::= ANALYZE */ + 190, /* (290) cmd ::= ANALYZE nm dbnm */ + 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 296, /* (294) add_column_fullname ::= fullname */ + 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 190, /* (296) cmd ::= create_vtab */ + 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */ + 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 300, /* (299) vtabarg ::= */ + 301, /* (300) vtabargtoken ::= ANY */ + 301, /* (301) vtabargtoken ::= lp anylist RP */ + 302, /* (302) lp ::= LP */ + 266, /* (303) with ::= WITH wqlist */ + 266, /* (304) with ::= WITH RECURSIVE wqlist */ + 305, /* (305) wqas ::= AS */ + 305, /* (306) wqas ::= AS MATERIALIZED */ + 305, /* (307) wqas ::= AS NOT MATERIALIZED */ + 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ + 241, /* (309) wqlist ::= wqitem */ + 241, /* (310) wqlist ::= wqlist COMMA wqitem */ + 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 307, /* (312) windowdefn ::= nm AS LP window RP */ + 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (315) window ::= ORDER BY sortlist frame_opt */ + 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */ + 308, /* (317) window ::= nm frame_opt */ + 309, /* (318) frame_opt ::= */ + 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + 315, /* (322) frame_bound_s ::= frame_bound */ + 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + 316, /* (324) frame_bound_e ::= frame_bound */ + 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + 314, /* (327) frame_bound ::= CURRENT ROW */ + 317, /* (328) frame_exclude_opt ::= */ + 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 318, /* (330) frame_exclude ::= NO OTHERS */ + 318, /* (331) frame_exclude ::= CURRENT ROW */ + 318, /* (332) frame_exclude ::= GROUP|TIES */ + 251, /* (333) window_clause ::= WINDOW windowdefn_list */ + 273, /* (334) filter_over ::= filter_clause over_clause */ + 273, /* (335) filter_over ::= over_clause */ + 273, /* (336) filter_over ::= filter_clause */ + 312, /* (337) over_clause ::= OVER LP window RP */ + 312, /* (338) over_clause ::= OVER nm */ + 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + 185, /* (340) input ::= cmdlist */ + 186, /* (341) cmdlist ::= cmdlist ecmd */ + 186, /* (342) cmdlist ::= ecmd */ + 187, /* (343) ecmd ::= SEMI */ + 187, /* (344) ecmd ::= cmdx SEMI */ + 187, /* (345) ecmd ::= explain cmdx SEMI */ + 192, /* (346) trans_opt ::= */ + 192, /* (347) trans_opt ::= TRANSACTION */ + 192, /* (348) trans_opt ::= TRANSACTION nm */ + 194, /* (349) savepoint_opt ::= SAVEPOINT */ + 194, /* (350) savepoint_opt ::= */ + 190, /* (351) cmd ::= create_table create_table_args */ + 203, /* (352) table_option_set ::= table_option */ + 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + 201, /* (354) columnlist ::= columnname carglist */ + 193, /* (355) nm ::= ID|INDEXED|JOIN_KW */ + 193, /* (356) nm ::= STRING */ + 208, /* (357) typetoken ::= typename */ + 209, /* (358) typename ::= ID|STRING */ + 210, /* (359) signed ::= plus_num */ + 210, /* (360) signed ::= minus_num */ + 207, /* (361) carglist ::= carglist ccons */ + 207, /* (362) carglist ::= */ + 215, /* (363) ccons ::= NULL onconf */ + 215, /* (364) ccons ::= GENERATED ALWAYS AS generated */ + 215, /* (365) ccons ::= AS generated */ + 202, /* (366) conslist_opt ::= COMMA conslist */ + 228, /* (367) conslist ::= conslist tconscomma tcons */ + 228, /* (368) conslist ::= tcons */ + 229, /* (369) tconscomma ::= */ + 233, /* (370) defer_subclause_opt ::= defer_subclause */ + 235, /* (371) resolvetype ::= raisetype */ + 239, /* (372) selectnowith ::= oneselect */ + 240, /* (373) oneselect ::= values */ + 254, /* (374) sclp ::= selcollist COMMA */ + 255, /* (375) as ::= ID|STRING */ + 264, /* (376) indexed_opt ::= indexed_by */ + 272, /* (377) returning ::= */ + 217, /* (378) expr ::= term */ + 274, /* (379) likeop ::= LIKE_KW|MATCH */ + 278, /* (380) case_operand ::= expr */ + 261, /* (381) exprlist ::= nexprlist */ + 284, /* (382) nmnum ::= plus_num */ + 284, /* (383) nmnum ::= nm */ + 284, /* (384) nmnum ::= ON */ + 284, /* (385) nmnum ::= DELETE */ + 284, /* (386) nmnum ::= DEFAULT */ + 211, /* (387) plus_num ::= INTEGER|FLOAT */ + 289, /* (388) foreach_clause ::= */ + 289, /* (389) foreach_clause ::= FOR EACH ROW */ + 292, /* (390) trnm ::= nm */ + 293, /* (391) tridxby ::= */ + 294, /* (392) database_kw_opt ::= DATABASE */ + 294, /* (393) database_kw_opt ::= */ + 297, /* (394) kwcolumn_opt ::= */ + 297, /* (395) kwcolumn_opt ::= COLUMNKW */ + 299, /* (396) vtabarglist ::= vtabarg */ + 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ + 300, /* (398) vtabarg ::= vtabarg vtabargtoken */ + 303, /* (399) anylist ::= */ + 303, /* (400) anylist ::= anylist LP anylist RP */ + 303, /* (401) anylist ::= anylist ANY */ + 266, /* (402) with ::= */ + 306, /* (403) windowdefn_list ::= windowdefn */ + 308, /* (404) window ::= frame_opt */ +}; + +/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number +** of symbols on the right-hand side of that rule. */ +static const signed char yyRuleInfoNRhs[] = { + -1, /* (0) explain ::= EXPLAIN */ + -3, /* (1) explain ::= EXPLAIN QUERY PLAN */ + -1, /* (2) cmdx ::= cmd */ + -3, /* (3) cmd ::= BEGIN transtype trans_opt */ + 0, /* (4) transtype ::= */ + -1, /* (5) transtype ::= DEFERRED */ + -1, /* (6) transtype ::= IMMEDIATE */ + -1, /* (7) transtype ::= EXCLUSIVE */ + -2, /* (8) cmd ::= COMMIT|END trans_opt */ + -2, /* (9) cmd ::= ROLLBACK trans_opt */ + -2, /* (10) cmd ::= SAVEPOINT nm */ + -3, /* (11) cmd ::= RELEASE savepoint_opt nm */ + -5, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + -6, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + -1, /* (14) createkw ::= CREATE */ + 0, /* (15) ifnotexists ::= */ + -3, /* (16) ifnotexists ::= IF NOT EXISTS */ + -1, /* (17) temp ::= TEMP */ + 0, /* (18) temp ::= */ + -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + -2, /* (20) create_table_args ::= AS select */ + 0, /* (21) table_option_set ::= */ + -3, /* (22) table_option_set ::= table_option_set COMMA table_option */ + -2, /* (23) table_option ::= WITHOUT nm */ + -1, /* (24) table_option ::= nm */ + -2, /* (25) columnname ::= nm typetoken */ + 0, /* (26) typetoken ::= */ + -4, /* (27) typetoken ::= typename LP signed RP */ + -6, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + -2, /* (29) typename ::= typename ID|STRING */ + 0, /* (30) scanpt ::= */ + 0, /* (31) scantok ::= */ + -2, /* (32) ccons ::= CONSTRAINT nm */ + -3, /* (33) ccons ::= DEFAULT scantok term */ + -4, /* (34) ccons ::= DEFAULT LP expr RP */ + -4, /* (35) ccons ::= DEFAULT PLUS scantok term */ + -4, /* (36) ccons ::= DEFAULT MINUS scantok term */ + -3, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + -3, /* (38) ccons ::= NOT NULL onconf */ + -5, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + -2, /* (40) ccons ::= UNIQUE onconf */ + -4, /* (41) ccons ::= CHECK LP expr RP */ + -4, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + -1, /* (43) ccons ::= defer_subclause */ + -2, /* (44) ccons ::= COLLATE ID|STRING */ + -3, /* (45) generated ::= LP expr RP */ + -4, /* (46) generated ::= LP expr RP ID */ + 0, /* (47) autoinc ::= */ + -1, /* (48) autoinc ::= AUTOINCR */ + 0, /* (49) refargs ::= */ + -2, /* (50) refargs ::= refargs refarg */ + -2, /* (51) refarg ::= MATCH nm */ + -3, /* (52) refarg ::= ON INSERT refact */ + -3, /* (53) refarg ::= ON DELETE refact */ + -3, /* (54) refarg ::= ON UPDATE refact */ + -2, /* (55) refact ::= SET NULL */ + -2, /* (56) refact ::= SET DEFAULT */ + -1, /* (57) refact ::= CASCADE */ + -1, /* (58) refact ::= RESTRICT */ + -2, /* (59) refact ::= NO ACTION */ + -3, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + -2, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 0, /* (62) init_deferred_pred_opt ::= */ + -2, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + -2, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 0, /* (65) conslist_opt ::= */ + -1, /* (66) tconscomma ::= COMMA */ + -2, /* (67) tcons ::= CONSTRAINT nm */ + -7, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + -5, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + -5, /* (70) tcons ::= CHECK LP expr RP onconf */ + -10, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 0, /* (72) defer_subclause_opt ::= */ + 0, /* (73) onconf ::= */ + -3, /* (74) onconf ::= ON CONFLICT resolvetype */ + 0, /* (75) orconf ::= */ + -2, /* (76) orconf ::= OR resolvetype */ + -1, /* (77) resolvetype ::= IGNORE */ + -1, /* (78) resolvetype ::= REPLACE */ + -4, /* (79) cmd ::= DROP TABLE ifexists fullname */ + -2, /* (80) ifexists ::= IF EXISTS */ + 0, /* (81) ifexists ::= */ + -9, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + -4, /* (83) cmd ::= DROP VIEW ifexists fullname */ + -1, /* (84) cmd ::= select */ + -3, /* (85) select ::= WITH wqlist selectnowith */ + -4, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + -1, /* (87) select ::= selectnowith */ + -3, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + -1, /* (89) multiselect_op ::= UNION */ + -2, /* (90) multiselect_op ::= UNION ALL */ + -1, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + -4, /* (94) values ::= VALUES LP nexprlist RP */ + -5, /* (95) values ::= values COMMA LP nexprlist RP */ + -1, /* (96) distinct ::= DISTINCT */ + -1, /* (97) distinct ::= ALL */ + 0, /* (98) distinct ::= */ + 0, /* (99) sclp ::= */ + -5, /* (100) selcollist ::= sclp scanpt expr scanpt as */ + -3, /* (101) selcollist ::= sclp scanpt STAR */ + -5, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ + -2, /* (103) as ::= AS nm */ + 0, /* (104) as ::= */ + 0, /* (105) from ::= */ + -2, /* (106) from ::= FROM seltablist */ + -2, /* (107) stl_prefix ::= seltablist joinop */ + 0, /* (108) stl_prefix ::= */ + -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ + -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ + -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 0, /* (114) dbnm ::= */ + -2, /* (115) dbnm ::= DOT nm */ + -1, /* (116) fullname ::= nm */ + -3, /* (117) fullname ::= nm DOT nm */ + -1, /* (118) xfullname ::= nm */ + -3, /* (119) xfullname ::= nm DOT nm */ + -5, /* (120) xfullname ::= nm DOT nm AS nm */ + -3, /* (121) xfullname ::= nm AS nm */ + -1, /* (122) joinop ::= COMMA|JOIN */ + -2, /* (123) joinop ::= JOIN_KW JOIN */ + -3, /* (124) joinop ::= JOIN_KW nm JOIN */ + -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (126) on_using ::= ON expr */ + -4, /* (127) on_using ::= USING LP idlist RP */ + 0, /* (128) on_using ::= */ + 0, /* (129) indexed_opt ::= */ + -3, /* (130) indexed_by ::= INDEXED BY nm */ + -2, /* (131) indexed_by ::= NOT INDEXED */ + 0, /* (132) orderby_opt ::= */ + -3, /* (133) orderby_opt ::= ORDER BY sortlist */ + -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ + -3, /* (135) sortlist ::= expr sortorder nulls */ + -1, /* (136) sortorder ::= ASC */ + -1, /* (137) sortorder ::= DESC */ + 0, /* (138) sortorder ::= */ + -2, /* (139) nulls ::= NULLS FIRST */ + -2, /* (140) nulls ::= NULLS LAST */ + 0, /* (141) nulls ::= */ + 0, /* (142) groupby_opt ::= */ + -3, /* (143) groupby_opt ::= GROUP BY nexprlist */ + 0, /* (144) having_opt ::= */ + -2, /* (145) having_opt ::= HAVING expr */ + 0, /* (146) limit_opt ::= */ + -2, /* (147) limit_opt ::= LIMIT expr */ + -4, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ + -4, /* (149) limit_opt ::= LIMIT expr COMMA expr */ + -8, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret orderby_opt limit_opt */ + 0, /* (151) where_opt ::= */ + -2, /* (152) where_opt ::= WHERE expr */ + 0, /* (153) where_opt_ret ::= */ + -2, /* (154) where_opt_ret ::= WHERE expr */ + -2, /* (155) where_opt_ret ::= RETURNING selcollist */ + -4, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -11, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret orderby_opt limit_opt */ + -5, /* (158) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (160) setlist ::= nm EQ expr */ + -5, /* (161) setlist ::= LP idlist RP EQ expr */ + -7, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (164) upsert ::= */ + -2, /* (165) upsert ::= RETURNING selcollist */ + -12, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (170) returning ::= RETURNING selcollist */ + -2, /* (171) insert_cmd ::= INSERT orconf */ + -1, /* (172) insert_cmd ::= REPLACE */ + 0, /* (173) idlist_opt ::= */ + -3, /* (174) idlist_opt ::= LP idlist RP */ + -3, /* (175) idlist ::= idlist COMMA nm */ + -1, /* (176) idlist ::= nm */ + -3, /* (177) expr ::= LP expr RP */ + -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */ + -3, /* (179) expr ::= nm DOT nm */ + -5, /* (180) expr ::= nm DOT nm DOT nm */ + -1, /* (181) term ::= NULL|FLOAT|BLOB */ + -1, /* (182) term ::= STRING */ + -1, /* (183) term ::= INTEGER */ + -1, /* (184) expr ::= VARIABLE */ + -3, /* (185) expr ::= expr COLLATE ID|STRING */ + -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + -8, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + -4, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + -6, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + -9, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + -1, /* (193) term ::= CTIME_KW */ + -5, /* (194) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (195) expr ::= expr AND expr */ + -3, /* (196) expr ::= expr OR expr */ + -3, /* (197) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (198) expr ::= expr EQ|NE expr */ + -3, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (200) expr ::= expr PLUS|MINUS expr */ + -3, /* (201) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (202) expr ::= expr CONCAT expr */ + -2, /* (203) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (204) expr ::= expr likeop expr */ + -5, /* (205) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (206) expr ::= expr ISNULL|NOTNULL */ + -3, /* (207) expr ::= expr NOT NULL */ + -3, /* (208) expr ::= expr IS expr */ + -4, /* (209) expr ::= expr IS NOT expr */ + -6, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ + -5, /* (211) expr ::= expr IS DISTINCT FROM expr */ + -2, /* (212) expr ::= NOT expr */ + -2, /* (213) expr ::= BITNOT expr */ + -2, /* (214) expr ::= PLUS|MINUS expr */ + -3, /* (215) expr ::= expr PTR expr */ + -1, /* (216) between_op ::= BETWEEN */ + -2, /* (217) between_op ::= NOT BETWEEN */ + -5, /* (218) expr ::= expr between_op expr AND expr */ + -1, /* (219) in_op ::= IN */ + -2, /* (220) in_op ::= NOT IN */ + -5, /* (221) expr ::= expr in_op LP exprlist RP */ + -3, /* (222) expr ::= LP select RP */ + -5, /* (223) expr ::= expr in_op LP select RP */ + -5, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (225) expr ::= EXISTS LP select RP */ + -5, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (228) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (229) case_else ::= ELSE expr */ + 0, /* (230) case_else ::= */ + 0, /* (231) case_operand ::= */ + 0, /* (232) exprlist ::= */ + -3, /* (233) nexprlist ::= nexprlist COMMA expr */ + -1, /* (234) nexprlist ::= expr */ + 0, /* (235) paren_exprlist ::= */ + -3, /* (236) paren_exprlist ::= LP exprlist RP */ + -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (238) uniqueflag ::= UNIQUE */ + 0, /* (239) uniqueflag ::= */ + 0, /* (240) eidlist_opt ::= */ + -3, /* (241) eidlist_opt ::= LP eidlist RP */ + -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (243) eidlist ::= nm collate sortorder */ + 0, /* (244) collate ::= */ + -2, /* (245) collate ::= COLLATE ID|STRING */ + -4, /* (246) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (247) cmd ::= VACUUM vinto */ + -3, /* (248) cmd ::= VACUUM nm vinto */ + -2, /* (249) vinto ::= INTO expr */ + 0, /* (250) vinto ::= */ + -3, /* (251) cmd ::= PRAGMA nm dbnm */ + -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (260) trigger_time ::= BEFORE|AFTER */ + -2, /* (261) trigger_time ::= INSTEAD OF */ + 0, /* (262) trigger_time ::= */ + -1, /* (263) trigger_event ::= DELETE|INSERT */ + -1, /* (264) trigger_event ::= UPDATE */ + -3, /* (265) trigger_event ::= UPDATE OF idlist */ + 0, /* (266) when_clause ::= */ + -2, /* (267) when_clause ::= WHEN expr */ + -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (270) trnm ::= nm DOT nm */ + -3, /* (271) tridxby ::= INDEXED BY nm */ + -2, /* (272) tridxby ::= NOT INDEXED */ + -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (276) trigger_cmd ::= scanpt select scanpt */ + -4, /* (277) expr ::= RAISE LP IGNORE RP */ + -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (279) raisetype ::= ROLLBACK */ + -1, /* (280) raisetype ::= ABORT */ + -1, /* (281) raisetype ::= FAIL */ + -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (284) cmd ::= DETACH database_kw_opt expr */ + 0, /* (285) key_opt ::= */ + -2, /* (286) key_opt ::= KEY expr */ + -1, /* (287) cmd ::= REINDEX */ + -3, /* (288) cmd ::= REINDEX nm dbnm */ + -1, /* (289) cmd ::= ANALYZE */ + -3, /* (290) cmd ::= ANALYZE nm dbnm */ + -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (294) add_column_fullname ::= fullname */ + -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (296) cmd ::= create_vtab */ + -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (299) vtabarg ::= */ + -1, /* (300) vtabargtoken ::= ANY */ + -3, /* (301) vtabargtoken ::= lp anylist RP */ + -1, /* (302) lp ::= LP */ + -2, /* (303) with ::= WITH wqlist */ + -3, /* (304) with ::= WITH RECURSIVE wqlist */ + -1, /* (305) wqas ::= AS */ + -2, /* (306) wqas ::= AS MATERIALIZED */ + -3, /* (307) wqas ::= AS NOT MATERIALIZED */ + -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (309) wqlist ::= wqitem */ + -3, /* (310) wqlist ::= wqlist COMMA wqitem */ + -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (312) windowdefn ::= nm AS LP window RP */ + -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (315) window ::= ORDER BY sortlist frame_opt */ + -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */ + -2, /* (317) window ::= nm frame_opt */ + 0, /* (318) frame_opt ::= */ + -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (322) frame_bound_s ::= frame_bound */ + -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (324) frame_bound_e ::= frame_bound */ + -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (327) frame_bound ::= CURRENT ROW */ + 0, /* (328) frame_exclude_opt ::= */ + -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (330) frame_exclude ::= NO OTHERS */ + -2, /* (331) frame_exclude ::= CURRENT ROW */ + -1, /* (332) frame_exclude ::= GROUP|TIES */ + -2, /* (333) window_clause ::= WINDOW windowdefn_list */ + -2, /* (334) filter_over ::= filter_clause over_clause */ + -1, /* (335) filter_over ::= over_clause */ + -1, /* (336) filter_over ::= filter_clause */ + -4, /* (337) over_clause ::= OVER LP window RP */ + -2, /* (338) over_clause ::= OVER nm */ + -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (340) input ::= cmdlist */ + -2, /* (341) cmdlist ::= cmdlist ecmd */ + -1, /* (342) cmdlist ::= ecmd */ + -1, /* (343) ecmd ::= SEMI */ + -2, /* (344) ecmd ::= cmdx SEMI */ + -3, /* (345) ecmd ::= explain cmdx SEMI */ + 0, /* (346) trans_opt ::= */ + -1, /* (347) trans_opt ::= TRANSACTION */ + -2, /* (348) trans_opt ::= TRANSACTION nm */ + -1, /* (349) savepoint_opt ::= SAVEPOINT */ + 0, /* (350) savepoint_opt ::= */ + -2, /* (351) cmd ::= create_table create_table_args */ + -1, /* (352) table_option_set ::= table_option */ + -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (354) columnlist ::= columnname carglist */ + -1, /* (355) nm ::= ID|INDEXED|JOIN_KW */ + -1, /* (356) nm ::= STRING */ + -1, /* (357) typetoken ::= typename */ + -1, /* (358) typename ::= ID|STRING */ + -1, /* (359) signed ::= plus_num */ + -1, /* (360) signed ::= minus_num */ + -2, /* (361) carglist ::= carglist ccons */ + 0, /* (362) carglist ::= */ + -2, /* (363) ccons ::= NULL onconf */ + -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (365) ccons ::= AS generated */ + -2, /* (366) conslist_opt ::= COMMA conslist */ + -3, /* (367) conslist ::= conslist tconscomma tcons */ + -1, /* (368) conslist ::= tcons */ + 0, /* (369) tconscomma ::= */ + -1, /* (370) defer_subclause_opt ::= defer_subclause */ + -1, /* (371) resolvetype ::= raisetype */ + -1, /* (372) selectnowith ::= oneselect */ + -1, /* (373) oneselect ::= values */ + -2, /* (374) sclp ::= selcollist COMMA */ + -1, /* (375) as ::= ID|STRING */ + -1, /* (376) indexed_opt ::= indexed_by */ + 0, /* (377) returning ::= */ + -1, /* (378) expr ::= term */ + -1, /* (379) likeop ::= LIKE_KW|MATCH */ + -1, /* (380) case_operand ::= expr */ + -1, /* (381) exprlist ::= nexprlist */ + -1, /* (382) nmnum ::= plus_num */ + -1, /* (383) nmnum ::= nm */ + -1, /* (384) nmnum ::= ON */ + -1, /* (385) nmnum ::= DELETE */ + -1, /* (386) nmnum ::= DEFAULT */ + -1, /* (387) plus_num ::= INTEGER|FLOAT */ + 0, /* (388) foreach_clause ::= */ + -3, /* (389) foreach_clause ::= FOR EACH ROW */ + -1, /* (390) trnm ::= nm */ + 0, /* (391) tridxby ::= */ + -1, /* (392) database_kw_opt ::= DATABASE */ + 0, /* (393) database_kw_opt ::= */ + 0, /* (394) kwcolumn_opt ::= */ + -1, /* (395) kwcolumn_opt ::= COLUMNKW */ + -1, /* (396) vtabarglist ::= vtabarg */ + -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (398) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (399) anylist ::= */ + -4, /* (400) anylist ::= anylist LP anylist RP */ + -2, /* (401) anylist ::= anylist ANY */ + 0, /* (402) with ::= */ + -1, /* (403) windowdefn_list ::= windowdefn */ + -1, /* (404) window ::= frame_opt */ +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +** +** The yyLookahead and yyLookaheadToken parameters provide reduce actions +** access to the lookahead token (if any). The yyLookahead will be YYNOCODE +** if the lookahead token has already been consumed. As this procedure is +** only called from one place, optimizing compilers will in-line it, which +** means that the extra parameters have no performance impact. +*/ +static YYACTIONTYPE yy_reduce( + yyParser *yypParser, /* The parser */ + unsigned int yyruleno, /* Number of the rule by which to reduce */ + int yyLookahead, /* Lookahead token, or YYNOCODE if none */ + sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + sqlite3ParserCTX_PDECL /* %extra_context */ +){ + int yygoto; /* The next state */ + YYACTIONTYPE yyact; /* The next action */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + sqlite3ParserARG_FETCH + (void)yyLookahead; + (void)yyLookaheadToken; + yymsp = yypParser->yytos; + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ +/********** Begin reduce actions **********************************************/ + YYMINORTYPE yylhsminor; + case 0: /* explain ::= EXPLAIN */ +{ if( pParse->pReprepare==0 ) pParse->explain = 1; } + break; + case 1: /* explain ::= EXPLAIN QUERY PLAN */ +{ if( pParse->pReprepare==0 ) pParse->explain = 2; } + break; + case 2: /* cmdx ::= cmd */ +{ sqlite3FinishCoding(pParse); } + break; + case 3: /* cmd ::= BEGIN transtype trans_opt */ +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} + break; + case 4: /* transtype ::= */ +{yymsp[1].minor.yy394 = TK_DEFERRED;} + break; + case 5: /* transtype ::= DEFERRED */ + case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); + case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); + case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); +{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} + break; + case 8: /* cmd ::= COMMIT|END trans_opt */ + case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); +{sqlite3EndTransaction(pParse,yymsp[-1].major);} + break; + case 10: /* cmd ::= SAVEPOINT nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); +} + break; + case 11: /* cmd ::= RELEASE savepoint_opt nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); +} + break; + case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); +} + break; + case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ +{ + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394); +} + break; + case 14: /* createkw ::= CREATE */ +{disableLookaside(pParse);} + break; + case 15: /* ifnotexists ::= */ + case 18: /* temp ::= */ yytestcase(yyruleno==18); + case 47: /* autoinc ::= */ yytestcase(yyruleno==47); + case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); + case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); + case 81: /* ifexists ::= */ yytestcase(yyruleno==81); + case 98: /* distinct ::= */ yytestcase(yyruleno==98); + case 244: /* collate ::= */ yytestcase(yyruleno==244); +{yymsp[1].minor.yy394 = 0;} + break; + case 16: /* ifnotexists ::= IF NOT EXISTS */ +{yymsp[-2].minor.yy394 = 1;} + break; + case 17: /* temp ::= TEMP */ +{yymsp[0].minor.yy394 = pParse->db->init.busy==0;} + break; + case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ +{ + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0); +} + break; + case 20: /* create_table_args ::= AS select */ +{ + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); +} + break; + case 21: /* table_option_set ::= */ +{yymsp[1].minor.yy285 = 0;} + break; + case 22: /* table_option_set ::= table_option_set COMMA table_option */ +{yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;} + yymsp[-2].minor.yy285 = yylhsminor.yy285; + break; + case 23: /* table_option ::= WITHOUT nm */ +{ + if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ + yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; + }else{ + yymsp[-1].minor.yy285 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + break; + case 24: /* table_option ::= nm */ +{ + if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ + yylhsminor.yy285 = TF_Strict; + }else{ + yylhsminor.yy285 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + yymsp[0].minor.yy285 = yylhsminor.yy285; + break; + case 25: /* columnname ::= nm typetoken */ +{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} + break; + case 26: /* typetoken ::= */ + case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); + case 104: /* as ::= */ yytestcase(yyruleno==104); +{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} + break; + case 27: /* typetoken ::= typename LP signed RP */ +{ + yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); +} + break; + case 28: /* typetoken ::= typename LP signed COMMA signed RP */ +{ + yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); +} + break; + case 29: /* typename ::= typename ID|STRING */ +{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} + break; + case 30: /* scanpt ::= */ +{ + assert( yyLookahead!=YYNOCODE ); + yymsp[1].minor.yy522 = yyLookaheadToken.z; +} + break; + case 31: /* scantok ::= */ +{ + assert( yyLookahead!=YYNOCODE ); + yymsp[1].minor.yy0 = yyLookaheadToken; +} + break; + case 32: /* ccons ::= CONSTRAINT nm */ + case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67); +{pParse->constraintName = yymsp[0].minor.yy0;} + break; + case 33: /* ccons ::= DEFAULT scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + break; + case 34: /* ccons ::= DEFAULT LP expr RP */ +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} + break; + case 35: /* ccons ::= DEFAULT PLUS scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + break; + case 36: /* ccons ::= DEFAULT MINUS scantok term */ +{ + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0); + sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); +} + break; + case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */ +{ + Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0); + if( p ){ + sqlite3ExprIdToTrueFalse(p); + testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) ); + } + sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); +} + break; + case 38: /* ccons ::= NOT NULL onconf */ +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);} + break; + case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);} + break; + case 40: /* ccons ::= UNIQUE onconf */ +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} + break; + case 41: /* ccons ::= CHECK LP expr RP */ +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} + break; + case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);} + break; + case 43: /* ccons ::= defer_subclause */ +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);} + break; + case 44: /* ccons ::= COLLATE ID|STRING */ +{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} + break; + case 45: /* generated ::= LP expr RP */ +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);} + break; + case 46: /* generated ::= LP expr RP ID */ +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} + break; + case 48: /* autoinc ::= AUTOINCR */ +{yymsp[0].minor.yy394 = 1;} + break; + case 49: /* refargs ::= */ +{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} + break; + case 50: /* refargs ::= refargs refarg */ +{ yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; } + break; + case 51: /* refarg ::= MATCH nm */ +{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } + break; + case 52: /* refarg ::= ON INSERT refact */ +{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } + break; + case 53: /* refarg ::= ON DELETE refact */ +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } + break; + case 54: /* refarg ::= ON UPDATE refact */ +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } + break; + case 55: /* refact ::= SET NULL */ +{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} + break; + case 56: /* refact ::= SET DEFAULT */ +{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} + break; + case 57: /* refact ::= CASCADE */ +{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} + break; + case 58: /* refact ::= RESTRICT */ +{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} + break; + case 59: /* refact ::= NO ACTION */ +{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} + break; + case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ +{yymsp[-2].minor.yy394 = 0;} + break; + case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); + case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); +{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} + break; + case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ + case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); + case 217: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==217); + case 220: /* in_op ::= NOT IN */ yytestcase(yyruleno==220); + case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); +{yymsp[-1].minor.yy394 = 1;} + break; + case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ +{yymsp[-1].minor.yy394 = 0;} + break; + case 66: /* tconscomma ::= COMMA */ +{pParse->constraintName.n = 0;} + break; + case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);} + break; + case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} + break; + case 70: /* tcons ::= CHECK LP expr RP onconf */ +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} + break; + case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ +{ + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394); +} + break; + case 73: /* onconf ::= */ + case 75: /* orconf ::= */ yytestcase(yyruleno==75); +{yymsp[1].minor.yy394 = OE_Default;} + break; + case 74: /* onconf ::= ON CONFLICT resolvetype */ +{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} + break; + case 77: /* resolvetype ::= IGNORE */ +{yymsp[0].minor.yy394 = OE_Ignore;} + break; + case 78: /* resolvetype ::= REPLACE */ + case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172); +{yymsp[0].minor.yy394 = OE_Replace;} + break; + case 79: /* cmd ::= DROP TABLE ifexists fullname */ +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394); +} + break; + case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ +{ + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394); +} + break; + case 83: /* cmd ::= DROP VIEW ifexists fullname */ +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394); +} + break; + case 84: /* cmd ::= select */ +{ + SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; + sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); +} + break; + case 85: /* select ::= WITH wqlist selectnowith */ +{yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} + break; + case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ +{yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} + break; + case 87: /* select ::= selectnowith */ +{ + Select *p = yymsp[0].minor.yy47; + if( p ){ + parserDoubleLinkSelect(pParse, p); + } +} + break; + case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ +{ + Select *pRhs = yymsp[0].minor.yy47; + Select *pLhs = yymsp[-2].minor.yy47; + if( pRhs && pRhs->pPrior ){ + SrcList *pFrom; + Token x; + x.n = 0; + parserDoubleLinkSelect(pParse, pRhs); + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); + } + if( pRhs ){ + pRhs->op = (u8)yymsp[-1].minor.yy394; + pRhs->pPrior = pLhs; + if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; + pRhs->selFlags &= ~SF_MultiValue; + if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; + }else{ + sqlite3SelectDelete(pParse->db, pLhs); + } + yymsp[-2].minor.yy47 = pRhs; +} + break; + case 89: /* multiselect_op ::= UNION */ + case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); +{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/} + break; + case 90: /* multiselect_op ::= UNION ALL */ +{yymsp[-1].minor.yy394 = TK_ALL;} + break; + case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ +{ + yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528); +} + break; + case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ +{ + yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528); + if( yymsp[-9].minor.yy47 ){ + yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41; + }else{ + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41); + } +} + break; + case 94: /* values ::= VALUES LP nexprlist RP */ +{ + yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0); +} + break; + case 95: /* values ::= values COMMA LP nexprlist RP */ +{ + Select *pRight, *pLeft = yymsp[-4].minor.yy47; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0); + if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; + if( pRight ){ + pRight->op = TK_ALL; + pRight->pPrior = pLeft; + yymsp[-4].minor.yy47 = pRight; + }else{ + yymsp[-4].minor.yy47 = pLeft; + } +} + break; + case 96: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy394 = SF_Distinct;} + break; + case 97: /* distinct ::= ALL */ +{yymsp[0].minor.yy394 = SF_All;} + break; + case 99: /* sclp ::= */ + case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); + case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); + case 232: /* exprlist ::= */ yytestcase(yyruleno==232); + case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); + case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); +{yymsp[1].minor.yy322 = 0;} + break; + case 100: /* selcollist ::= sclp scanpt expr scanpt as */ +{ + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522); +} + break; + case 101: /* selcollist ::= sclp scanpt STAR */ +{ + Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); + sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); + yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); +} + break; + case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ +{ + Expr *pRight, *pLeft, *pDot; + pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); + pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); + pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); +} + break; + case 103: /* as ::= AS nm */ + case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); + case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); + case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); +{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} + break; + case 105: /* from ::= */ + case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); +{yymsp[1].minor.yy131 = 0;} + break; + case 106: /* from ::= FROM seltablist */ +{ + yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; + sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131); +} + break; + case 107: /* stl_prefix ::= seltablist joinop */ +{ + if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; +} + break; + case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */ +{ + yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); +} + break; + case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ +{ + yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0); +} + break; + case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ +{ + yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); + sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322); +} + break; + case 112: /* seltablist ::= stl_prefix LP select RP as on_using */ +{ + yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561); + } + break; + case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ +{ + if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ + yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; + }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && yymsp[-3].minor.yy131->nSrc==1 ){ + yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); + if( yymsp[-5].minor.yy131 ){ + SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; + SrcItem *pOld = yymsp[-3].minor.yy131->a; + pNew->zName = pOld->zName; + pNew->zDatabase = pOld->zDatabase; + pNew->pSelect = pOld->pSelect; + if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ + pNew->fg.isNestedFrom = 1; + } + if( pOld->fg.isTabFunc ){ + pNew->u1.pFuncArg = pOld->u1.pFuncArg; + pOld->u1.pFuncArg = 0; + pOld->fg.isTabFunc = 0; + pNew->fg.isTabFunc = 1; + } + pOld->zName = pOld->zDatabase = 0; + pOld->pSelect = 0; + } + sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131); + }else{ + Select *pSubquery; + sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0); + yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561); + } + } + break; + case 114: /* dbnm ::= */ + case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129); +{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} + break; + case 116: /* fullname ::= nm */ +{ + yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); +} + yymsp[0].minor.yy131 = yylhsminor.yy131; + break; + case 117: /* fullname ::= nm DOT nm */ +{ + yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); +} + yymsp[-2].minor.yy131 = yylhsminor.yy131; + break; + case 118: /* xfullname ::= nm */ +{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} + break; + case 119: /* xfullname ::= nm DOT nm */ +{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 120: /* xfullname ::= nm DOT nm AS nm */ +{ + yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); +} + break; + case 121: /* xfullname ::= nm AS nm */ +{ + yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); +} + break; + case 122: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy394 = JT_INNER; } + break; + case 123: /* joinop ::= JOIN_KW JOIN */ +{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + break; + case 124: /* joinop ::= JOIN_KW nm JOIN */ +{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + break; + case 125: /* joinop ::= JOIN_KW nm nm JOIN */ +{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + break; + case 126: /* on_using ::= ON expr */ +{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;} + break; + case 127: /* on_using ::= USING LP idlist RP */ +{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;} + break; + case 128: /* on_using ::= */ +{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;} + break; + case 130: /* indexed_by ::= INDEXED BY nm */ +{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} + break; + case 131: /* indexed_by ::= NOT INDEXED */ +{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} + break; + case 133: /* orderby_opt ::= ORDER BY sortlist */ + case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); +{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} + break; + case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */ +{ + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); +} + break; + case 135: /* sortlist ::= expr sortorder nulls */ +{ + yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); +} + break; + case 136: /* sortorder ::= ASC */ +{yymsp[0].minor.yy394 = SQLITE_SO_ASC;} + break; + case 137: /* sortorder ::= DESC */ +{yymsp[0].minor.yy394 = SQLITE_SO_DESC;} + break; + case 138: /* sortorder ::= */ + case 141: /* nulls ::= */ yytestcase(yyruleno==141); +{yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;} + break; + case 139: /* nulls ::= NULLS FIRST */ +{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} + break; + case 140: /* nulls ::= NULLS LAST */ +{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} + break; + case 144: /* having_opt ::= */ + case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); + case 151: /* where_opt ::= */ yytestcase(yyruleno==151); + case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); + case 230: /* case_else ::= */ yytestcase(yyruleno==230); + case 231: /* case_operand ::= */ yytestcase(yyruleno==231); + case 250: /* vinto ::= */ yytestcase(yyruleno==250); +{yymsp[1].minor.yy528 = 0;} + break; + case 145: /* having_opt ::= HAVING expr */ + case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); + case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); + case 229: /* case_else ::= ELSE expr */ yytestcase(yyruleno==229); + case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); +{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} + break; + case 147: /* limit_opt ::= LIMIT expr */ +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} + break; + case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + break; + case 149: /* limit_opt ::= LIMIT expr COMMA expr */ +{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);} + break; + case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret orderby_opt limit_opt */ +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy131, &yymsp[-3].minor.yy0); +#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( yymsp[-1].minor.yy322 || yymsp[0].minor.yy528 ){ + updateDeleteLimitError(pParse,yymsp[-1].minor.yy322,yymsp[0].minor.yy528); + yymsp[-1].minor.yy322 = 0; + yymsp[0].minor.yy528 = 0; + } +#endif + sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy131,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[0].minor.yy528); +} + break; + case 155: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} + break; + case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;} + break; + case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret orderby_opt limit_opt */ +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-7].minor.yy131, &yymsp[-6].minor.yy0); + if( yymsp[-3].minor.yy131 ){ + SrcList *pFromClause = yymsp[-3].minor.yy131; + if( pFromClause->nSrc>1 ){ + Select *pSubquery; + Token as; + pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0); + as.n = 0; + as.z = 0; + pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); + } + yymsp[-7].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-7].minor.yy131, pFromClause); + } + sqlite3ExprListCheckLength(pParse,yymsp[-4].minor.yy322,"set list"); +#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( yymsp[-1].minor.yy322 || yymsp[0].minor.yy528 ){ + updateDeleteLimitError(pParse,yymsp[-1].minor.yy322,yymsp[0].minor.yy528); + yymsp[-1].minor.yy322 = 0; + yymsp[0].minor.yy528 = 0; + } +#endif + sqlite3Update(pParse,yymsp[-7].minor.yy131,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528,yymsp[-8].minor.yy394,yymsp[-1].minor.yy322,yymsp[0].minor.yy528,0); +} + break; + case 158: /* setlist ::= setlist COMMA nm EQ expr */ +{ + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1); +} + break; + case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ +{ + yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); +} + break; + case 160: /* setlist ::= nm EQ expr */ +{ + yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528); + sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1); +} + yymsp[-2].minor.yy322 = yylhsminor.yy322; + break; + case 161: /* setlist ::= LP idlist RP EQ expr */ +{ + yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); +} + break; + case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ +{ + sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); +} + break; + case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ +{ + sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); +} + break; + case 164: /* upsert ::= */ +{ yymsp[1].minor.yy444 = 0; } + break; + case 165: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } + break; + case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);} + break; + case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); } + break; + case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } + break; + case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} + break; + case 170: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} + break; + case 173: /* idlist_opt ::= */ +{yymsp[1].minor.yy254 = 0;} + break; + case 174: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} + break; + case 175: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} + break; + case 176: /* idlist ::= nm */ +{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + break; + case 177: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} + break; + case 178: /* expr ::= ID|INDEXED|JOIN_KW */ +{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 179: /* expr ::= nm DOT nm */ +{ + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); +} + yymsp[-2].minor.yy528 = yylhsminor.yy528; + break; + case 180: /* expr ::= nm DOT nm DOT nm */ +{ + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); + Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, temp1); + } + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); +} + yymsp[-4].minor.yy528 = yylhsminor.yy528; + break; + case 181: /* term ::= NULL|FLOAT|BLOB */ + case 182: /* term ::= STRING */ yytestcase(yyruleno==182); +{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 183: /* term ::= INTEGER */ +{ + yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); +} + yymsp[0].minor.yy528 = yylhsminor.yy528; + break; + case 184: /* expr ::= VARIABLE */ +{ + if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ + u32 n = yymsp[0].minor.yy0.n; + yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); + }else{ + /* When doing a nested parse, one can include terms in an expression + ** that look like this: #1 #2 ... These terms refer to registers + ** in the virtual machine. #N is the N-th register. */ + Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ + assert( t.n>=2 ); + if( pParse->nested==0 ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); + yymsp[0].minor.yy528 = 0; + }else{ + yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); + } + } +} + break; + case 185: /* expr ::= expr COLLATE ID|STRING */ +{ + yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); +} + break; + case 186: /* expr ::= CAST LP expr AS typetoken RP */ +{ + yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); +} + break; + case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); +} + yymsp[-4].minor.yy528 = yylhsminor.yy528; + break; + case 188: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy322, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy394); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-1].minor.yy322); +} + yymsp[-7].minor.yy528 = yylhsminor.yy528; + break; + case 189: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); +} + yymsp[-3].minor.yy528 = yylhsminor.yy528; + break; + case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); +} + yymsp[-5].minor.yy528 = yylhsminor.yy528; + break; + case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy322, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy394); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-2].minor.yy322); +} + yymsp[-8].minor.yy528 = yylhsminor.yy528; + break; + case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); +} + yymsp[-4].minor.yy528 = yylhsminor.yy528; + break; + case 193: /* term ::= CTIME_KW */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); +} + yymsp[0].minor.yy528 = yylhsminor.yy528; + break; + case 194: /* expr ::= LP nexprlist COMMA expr RP */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = pList; + if( ALWAYS(pList->nExpr) ){ + yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate; + } + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } +} + break; + case 195: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + break; + case 196: /* expr ::= expr OR expr */ + case 197: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==202); +{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + break; + case 203: /* likeop ::= NOT LIKE_KW|MATCH */ +{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} + break; + case 204: /* expr ::= expr likeop expr */ +{ + ExprList *pList; + int bNot = yymsp[-1].minor.yy0.n & 0x80000000; + yymsp[-1].minor.yy0.n &= 0x7fffffff; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528); + yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); + if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; +} + break; + case 205: /* expr ::= expr likeop expr ESCAPE expr */ +{ + ExprList *pList; + int bNot = yymsp[-3].minor.yy0.n & 0x80000000; + yymsp[-3].minor.yy0.n &= 0x7fffffff; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; +} + break; + case 206: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} + break; + case 207: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} + break; + case 208: /* expr ::= expr IS expr */ +{ + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); +} + break; + case 209: /* expr ::= expr IS NOT expr */ +{ + yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); +} + break; + case 210: /* expr ::= expr IS NOT DISTINCT FROM expr */ +{ + yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); +} + break; + case 211: /* expr ::= expr IS DISTINCT FROM expr */ +{ + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); +} + break; + case 212: /* expr ::= NOT expr */ + case 213: /* expr ::= BITNOT expr */ yytestcase(yyruleno==213); +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} + break; + case 214: /* expr ::= PLUS|MINUS expr */ +{ + yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); + /*A-overwrites-B*/ +} + break; + case 215: /* expr ::= expr PTR expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); +} + yymsp[-2].minor.yy528 = yylhsminor.yy528; + break; + case 216: /* between_op ::= BETWEEN */ + case 219: /* in_op ::= IN */ yytestcase(yyruleno==219); +{yymsp[0].minor.yy394 = 0;} + break; + case 218: /* expr ::= expr between_op expr AND expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = pList; + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); +} + break; + case 221: /* expr ::= expr in_op LP exprlist RP */ +{ + if( yymsp[-1].minor.yy322==0 ){ + /* Expressions of the form + ** + ** expr1 IN () + ** expr1 NOT IN () + ** + ** simplify to constants 0 (false) and 1 (true), respectively, + ** regardless of the value of expr1. + */ + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false"); + if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528); + }else{ + Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; + if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ + yymsp[-1].minor.yy322->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); + }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){ + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect); + pRHS->x.pSelect = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + }else{ + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322); + if( pSelectRHS ){ + parserDoubleLinkSelect(pParse, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS); + } + }else{ + yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + } + } + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + } + } + break; + case 222: /* expr ::= LP select RP */ +{ + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); + } + break; + case 223: /* expr ::= expr in_op LP select RP */ +{ + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + } + break; + case 224: /* expr ::= expr in_op nm dbnm paren_exprlist */ +{ + SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); + if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + } + break; + case 225: /* expr ::= EXISTS LP select RP */ +{ + Expr *p; + p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); + } + break; + case 226: /* expr ::= CASE case_operand case_exprlist case_else END */ +{ + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + } +} + break; + case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ +{ + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); +} + break; + case 228: /* case_exprlist ::= WHEN expr THEN expr */ +{ + yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); +} + break; + case 233: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} + break; + case 234: /* nexprlist ::= expr */ +{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} + break; + case 236: /* paren_exprlist ::= LP exprlist RP */ + case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); +{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} + break; + case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ +{ + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); + if( IN_RENAME_OBJECT && pParse->pNewIndex ){ + sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); + } +} + break; + case 238: /* uniqueflag ::= UNIQUE */ + case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); +{yymsp[0].minor.yy394 = OE_Abort;} + break; + case 239: /* uniqueflag ::= */ +{yymsp[1].minor.yy394 = OE_None;} + break; + case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ +{ + yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); +} + break; + case 243: /* eidlist ::= nm collate sortorder */ +{ + yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ +} + break; + case 246: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} + break; + case 247: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} + break; + case 248: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} + break; + case 251: /* cmd ::= PRAGMA nm dbnm */ +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} + break; + case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} + break; + case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} + break; + case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} + break; + case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} + break; + case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ +{ + Token all; + all.z = yymsp[-3].minor.yy0.z; + all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); +} + break; + case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ +{ + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); + yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ +} + break; + case 260: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } + break; + case 261: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy394 = TK_INSTEAD;} + break; + case 262: /* trigger_time ::= */ +{ yymsp[1].minor.yy394 = TK_BEFORE; } + break; + case 263: /* trigger_event ::= DELETE|INSERT */ + case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); +{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} + break; + case 265: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} + break; + case 266: /* when_clause ::= */ + case 285: /* key_opt ::= */ yytestcase(yyruleno==285); +{ yymsp[1].minor.yy528 = 0; } + break; + case 267: /* when_clause ::= WHEN expr */ + case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); +{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } + break; + case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ +{ + assert( yymsp[-2].minor.yy33!=0 ); + yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; + yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; +} + break; + case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ +{ + assert( yymsp[-1].minor.yy33!=0 ); + yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; +} + break; + case 270: /* trnm ::= nm DOT nm */ +{ + yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; + sqlite3ErrorMsg(pParse, + "qualified table names are not allowed on INSERT, UPDATE, and DELETE " + "statements within triggers"); +} + break; + case 271: /* tridxby ::= INDEXED BY nm */ +{ + sqlite3ErrorMsg(pParse, + "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 272: /* tridxby ::= NOT INDEXED */ +{ + sqlite3ErrorMsg(pParse, + "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} + yymsp[-8].minor.yy33 = yylhsminor.yy33; + break; + case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ +{ + yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ +} + yymsp[-7].minor.yy33 = yylhsminor.yy33; + break; + case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} + yymsp[-5].minor.yy33 = yylhsminor.yy33; + break; + case 276: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} + yymsp[-2].minor.yy33 = yylhsminor.yy33; + break; + case 277: /* expr ::= RAISE LP IGNORE RP */ +{ + yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy528 ){ + yymsp[-3].minor.yy528->affExpr = OE_Ignore; + } +} + break; + case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ +{ + yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy528 ) { + yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; + } +} + break; + case 279: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy394 = OE_Rollback;} + break; + case 281: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy394 = OE_Fail;} + break; + case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); +} + break; + case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +{ + sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); +} + break; + case 284: /* cmd ::= DETACH database_kw_opt expr */ +{ + sqlite3Detach(pParse, yymsp[0].minor.yy528); +} + break; + case 287: /* cmd ::= REINDEX */ +{sqlite3Reindex(pParse, 0, 0);} + break; + case 288: /* cmd ::= REINDEX nm dbnm */ +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; + case 289: /* cmd ::= ANALYZE */ +{sqlite3Analyze(pParse, 0, 0);} + break; + case 290: /* cmd ::= ANALYZE nm dbnm */ +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; + case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ +{ + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); +} + break; + case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ +{ + yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; + sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); +} + break; + case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +{ + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); +} + break; + case 294: /* add_column_fullname ::= fullname */ +{ + disableLookaside(pParse); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); +} + break; + case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ +{ + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 296: /* cmd ::= create_vtab */ +{sqlite3VtabFinishParse(pParse,0);} + break; + case 297: /* cmd ::= create_vtab LP vtabarglist RP */ +{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} + break; + case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ +{ + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); +} + break; + case 299: /* vtabarg ::= */ +{sqlite3VtabArgInit(pParse);} + break; + case 300: /* vtabargtoken ::= ANY */ + case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); + case 302: /* lp ::= LP */ yytestcase(yyruleno==302); +{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} + break; + case 303: /* with ::= WITH wqlist */ + case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } + break; + case 305: /* wqas ::= AS */ +{yymsp[0].minor.yy516 = M10d_Any;} + break; + case 306: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy516 = M10d_Yes;} + break; + case 307: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy516 = M10d_No;} + break; + case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ +{ + yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ +} + break; + case 309: /* wqlist ::= wqitem */ +{ + yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ +} + break; + case 310: /* wqlist ::= wqlist COMMA wqitem */ +{ + yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); +} + break; + case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ +{ + assert( yymsp[0].minor.yy41!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); + yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; + yylhsminor.yy41 = yymsp[0].minor.yy41; +} + yymsp[-2].minor.yy41 = yylhsminor.yy41; + break; + case 312: /* windowdefn ::= nm AS LP window RP */ +{ + if( ALWAYS(yymsp[-1].minor.yy41) ){ + yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + } + yylhsminor.yy41 = yymsp[-1].minor.yy41; +} + yymsp[-4].minor.yy41 = yylhsminor.yy41; + break; + case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ +{ + yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); +} + break; + case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ +{ + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); +} + yymsp[-5].minor.yy41 = yylhsminor.yy41; + break; + case 315: /* window ::= ORDER BY sortlist frame_opt */ +{ + yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); +} + break; + case 316: /* window ::= nm ORDER BY sortlist frame_opt */ +{ + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); +} + yymsp[-4].minor.yy41 = yylhsminor.yy41; + break; + case 317: /* window ::= nm frame_opt */ +{ + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); +} + yymsp[-1].minor.yy41 = yylhsminor.yy41; + break; + case 318: /* frame_opt ::= */ +{ + yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); +} + break; + case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ +{ + yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); +} + yymsp[-2].minor.yy41 = yylhsminor.yy41; + break; + case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ +{ + yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); +} + yymsp[-5].minor.yy41 = yylhsminor.yy41; + break; + case 322: /* frame_bound_s ::= frame_bound */ + case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); +{yylhsminor.yy595 = yymsp[0].minor.yy595;} + yymsp[0].minor.yy595 = yylhsminor.yy595; + break; + case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); + case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); +{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} + yymsp[-1].minor.yy595 = yylhsminor.yy595; + break; + case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} + yymsp[-1].minor.yy595 = yylhsminor.yy595; + break; + case 328: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy516 = 0;} + break; + case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} + break; + case 330: /* frame_exclude ::= NO OTHERS */ + case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); +{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} + break; + case 332: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} + break; + case 333: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } + break; + case 334: /* filter_over ::= filter_clause over_clause */ +{ + if( yymsp[0].minor.yy41 ){ + yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; + }else{ + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + } + yylhsminor.yy41 = yymsp[0].minor.yy41; +} + yymsp[-1].minor.yy41 = yylhsminor.yy41; + break; + case 335: /* filter_over ::= over_clause */ +{ + yylhsminor.yy41 = yymsp[0].minor.yy41; +} + yymsp[0].minor.yy41 = yylhsminor.yy41; + break; + case 336: /* filter_over ::= filter_clause */ +{ + yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy41 ){ + yylhsminor.yy41->eFrmType = TK_FILTER; + yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; + }else{ + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); + } +} + yymsp[0].minor.yy41 = yylhsminor.yy41; + break; + case 337: /* over_clause ::= OVER LP window RP */ +{ + yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; + assert( yymsp[-3].minor.yy41!=0 ); +} + break; + case 338: /* over_clause ::= OVER nm */ +{ + yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy41 ){ + yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + } +} + break; + case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } + break; + default: + /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); + /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); + /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); + /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); + /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); + /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); + /* (346) trans_opt ::= */ yytestcase(yyruleno==346); + /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); + /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); + /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); + /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); + /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); + /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); + /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); + /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); + /* (355) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==355); + /* (356) nm ::= STRING */ yytestcase(yyruleno==356); + /* (357) typetoken ::= typename */ yytestcase(yyruleno==357); + /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358); + /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359); + /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); + /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361); + /* (362) carglist ::= */ yytestcase(yyruleno==362); + /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363); + /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364); + /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365); + /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366); + /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367); + /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368); + /* (369) tconscomma ::= */ yytestcase(yyruleno==369); + /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370); + /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371); + /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372); + /* (373) oneselect ::= values */ yytestcase(yyruleno==373); + /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374); + /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375); + /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376); + /* (377) returning ::= */ yytestcase(yyruleno==377); + /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); + /* (380) case_operand ::= expr */ yytestcase(yyruleno==380); + /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381); + /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382); + /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383); + /* (384) nmnum ::= ON */ yytestcase(yyruleno==384); + /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385); + /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386); + /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387); + /* (388) foreach_clause ::= */ yytestcase(yyruleno==388); + /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389); + /* (390) trnm ::= nm */ yytestcase(yyruleno==390); + /* (391) tridxby ::= */ yytestcase(yyruleno==391); + /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392); + /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393); + /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394); + /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395); + /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396); + /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397); + /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398); + /* (399) anylist ::= */ yytestcase(yyruleno==399); + /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400); + /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401); + /* (402) with ::= */ yytestcase(yyruleno==402); + /* (403) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=403); + /* (404) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=404); + break; +/********** End reduce actions ************************************************/ + }; + assert( yyrulenoYY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) ); + + /* It is not possible for a REDUCE to be followed by an error */ + assert( yyact!=YY_ERROR_ACTION ); + + yymsp += yysize+1; + yypParser->yytos = yymsp; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yyTraceShift(yypParser, yyact, "... then shift"); + return yyact; +} + +/* +** The following code executes when the parse fails +*/ +#ifndef YYNOERRORRECOVERY +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ +/************ Begin %parse_failure code ***************************************/ +/************ End %parse_failure code *****************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE +} +#endif /* YYNOERRORRECOVERY */ + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH +#define TOKEN yyminor +/************ Begin %syntax_error code ****************************************/ + + UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ + if( TOKEN.z[0] ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + }else{ + sqlite3ErrorMsg(pParse, "incomplete input"); + } +/************ End %syntax_error code ******************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + assert( yypParser->yytos==yypParser->yystack ); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ +/*********** Begin %parse_accept code *****************************************/ +/*********** End %parse_accept code *******************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "sqlite3ParserAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
    +**
  • A pointer to the parser (an opaque structure.) +**
  • The major token number. +**
  • The minor token number. +**
  • An option argument of a grammar-specified type. +**
+** +** Outputs: +** None. +*/ +SQLITE_PRIVATE void sqlite3Parser( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + sqlite3ParserTOKENTYPE yyminor /* The value for the token */ + sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + YYACTIONTYPE yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + int yyendofinput; /* True if we are at the end of input */ +#endif +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser = (yyParser*)yyp; /* The parser */ + sqlite3ParserCTX_FETCH + sqlite3ParserARG_STORE + + assert( yypParser->yytos!=0 ); +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + yyendofinput = (yymajor==0); +#endif + + yyact = yypParser->yytos->stateno; +#ifndef NDEBUG + if( yyTraceFILE ){ + if( yyact < YY_MIN_REDUCE ){ + fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact); + }else{ + fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); + } + } +#endif + + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); + assert( yyact==yypParser->yytos->stateno ); + yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); + if( yyact >= YY_MIN_REDUCE ){ + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ +#ifndef NDEBUG + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); + }else if( yyact <= YY_MAX_SHIFTREDUCE ){ + yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt--; +#endif + break; + }else if( yyact==YY_ACCEPT_ACTION ){ + yypParser->yytos--; + yy_accept(yypParser); + return; + }else{ + assert( yyact == YY_ERROR_ACTION ); + yyminorunion.yy0 = yyminor; +#ifdef YYERRORSYMBOL + int yymx; +#endif +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminor); + } + yymx = yypParser->yytos->major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); + yymajor = YYNOCODE; + }else{ + while( yypParser->yytos > yypParser->yystack ){ + yyact = yy_find_reduce_action(yypParser->yytos->stateno, + YYERRORSYMBOL); + if( yyact<=YY_MAX_SHIFTREDUCE ) break; + yy_pop_parser_stack(yypParser); + } + if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){ + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; + if( yymajor==YYNOCODE ) break; + yyact = yypParser->yytos->stateno; +#elif defined(YYNOERRORRECOVERY) + /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to + ** do any kind of error recovery. Instead, simply invoke the syntax + ** error routine and continue going as if nothing had happened. + ** + ** Applications can set this macro (for example inside %include) if + ** they intend to abandon the parse upon the first syntax error seen. + */ + yy_syntax_error(yypParser,yymajor, yyminor); + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + break; +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor, yyminor); + } + yypParser->yyerrcnt = 3; + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + } + break; +#endif + } + } +#ifndef NDEBUG + if( yyTraceFILE ){ + yyStackEntry *i; + char cDiv = '['; + fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); + for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ + fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); + cDiv = ' '; + } + fprintf(yyTraceFILE,"]\n"); + } +#endif + return; +} + +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ +#ifdef YYFALLBACK + assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); + return yyFallback[iToken]; +#else + (void)iToken; + return 0; +#endif +} + +/************** End of parse.c ***********************************************/ +/************** Begin file tokenize.c ****************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** An tokenizer for SQL +** +** This file contains C code that splits an SQL input string up into +** individual tokens and sends those tokens one-by-one over to the +** parser for analysis. +*/ +/* #include "sqliteInt.h" */ +/* #include */ + +/* Character classes for tokenizing +** +** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented +** using a lookup table, whereas a switch() directly on c uses a binary search. +** The lookup table is much faster. To maximize speed, and to ensure that +** a lookup table is used, all of the classes need to be small integers and +** all of them need to be used within the switch. +*/ +#define CC_X 0 /* The letter 'x', or start of BLOB literal */ +#define CC_KYWD0 1 /* First letter of a keyword */ +#define CC_KYWD 2 /* Alphabetics or '_'. Usable in a keyword */ +#define CC_DIGIT 3 /* Digits */ +#define CC_DOLLAR 4 /* '$' */ +#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ +#define CC_VARNUM 6 /* '?'. Numeric SQL variables */ +#define CC_SPACE 7 /* Space characters */ +#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */ +#define CC_QUOTE2 9 /* '['. [...] style quoted ids */ +#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */ +#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */ +#define CC_LT 12 /* '<'. Part of < or <= or <> */ +#define CC_GT 13 /* '>'. Part of > or >= */ +#define CC_EQ 14 /* '='. Part of = or == */ +#define CC_BANG 15 /* '!'. Part of != */ +#define CC_SLASH 16 /* '/'. / or c-style comment */ +#define CC_LP 17 /* '(' */ +#define CC_RP 18 /* ')' */ +#define CC_SEMI 19 /* ';' */ +#define CC_PLUS 20 /* '+' */ +#define CC_STAR 21 /* '*' */ +#define CC_PERCENT 22 /* '%' */ +#define CC_COMMA 23 /* ',' */ +#define CC_AND 24 /* '&' */ +#define CC_TILDA 25 /* '~' */ +#define CC_DOT 26 /* '.' */ +#define CC_ID 27 /* unicode characters usable in IDs */ +#define CC_ILLEGAL 28 /* Illegal character */ +#define CC_NUL 29 /* 0x00 */ +#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */ + +static const unsigned char aiClass[] = { +#ifdef SQLITE_ASCII +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 29, 28, 28, 28, 28, 28, 28, 28, 28, 7, 7, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, +/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, +/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2, +/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, +/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ax */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Cx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30, +/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27 +#endif +#ifdef SQLITE_EBCDIC +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 3x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 4x */ 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10, +/* 5x */ 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 15, 4, 21, 18, 19, 28, +/* 6x */ 11, 16, 28, 28, 28, 28, 28, 28, 28, 28, 28, 23, 22, 2, 13, 6, +/* 7x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 8, 5, 5, 5, 8, 14, 8, +/* 8x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* 9x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ax */ 28, 25, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Bx */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 9, 28, 28, 28, 28, 28, +/* Cx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Dx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ex */ 28, 28, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28, 28, 28, 28, 28, 28, +#endif +}; + +/* +** The charMap() macro maps alphabetic characters (only) into their +** lower-case ASCII equivalent. On ASCII machines, this is just +** an upper-to-lower case map. On EBCDIC machines we also need +** to adjust the encoding. The mapping is only valid for alphabetics +** which are the only characters for which this feature is used. +** +** Used by keywordhash.h +*/ +#ifdef SQLITE_ASCII +# define charMap(X) sqlite3UpperToLower[(unsigned char)X] +#endif +#ifdef SQLITE_EBCDIC +# define charMap(X) ebcdicToAscii[(unsigned char)X] +const unsigned char ebcdicToAscii[] = { +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */ + 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */ + 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */ + 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ + 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */ + 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */ + 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */ +}; +#endif + +/* +** The sqlite3KeywordCode function looks up an identifier to determine if +** it is a keyword. If it is a keyword, the token code of that keyword is +** returned. If the input is not a keyword, TK_ID is returned. +** +** The implementation of this routine was generated by a program, +** mkkeywordhash.c, located in the tool subdirectory of the distribution. +** The output of the mkkeywordhash.c program is written into a file +** named keywordhash.h and then included into this source file by +** the #include below. +*/ +/************** Include keywordhash.h in the middle of tokenize.c ************/ +/************** Begin file keywordhash.h *************************************/ +/***** This file contains automatically generated code ****** +** +** The code in this file has been automatically generated by +** +** sqlite/tool/mkkeywordhash.c +** +** The code in this file implements a function that determines whether +** or not a given identifier is really an SQL keyword. The same thing +** might be implemented more directly using a hand-written hash table. +** But by using this automatically generated code, the size of the code +** is substantially reduced. This is important for embedded applications +** on platforms with limited memory. +*/ +/* Hash score: 231 */ +/* zKWText[] encodes 1007 bytes of keyword text in 667 bytes */ +/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ +/* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYISNULLSAVEPOINTERSECT */ +/* IESNOTNULLIKEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTS */ +/* CONSTRAINTOFFSETRIGGERANGENERATEDETACHAVINGLOBEGINNEREFERENCES */ +/* UNIQUERYWITHOUTERELEASEATTACHBETWEENOTHINGROUPSCASCADEFAULT */ +/* CASECOLLATECREATECURRENT_DATEIMMEDIATEJOINSERTMATCHPLANALYZE */ +/* PRAGMATERIALIZEDEFERREDISTINCTUPDATEVALUESVIRTUALWAYSWHENWHERE */ +/* CURSIVEABORTAFTERENAMEANDROPARTITIONAUTOINCREMENTCASTCOLUMN */ +/* COMMITCONFLICTCROSSCURRENT_TIMESTAMPRECEDINGFAILASTFILTER */ +/* EPLACEFIRSTFOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVER */ +/* ETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBY */ +/* INITIALLYPRIMARY */ +static const char zKWText[666] = { + 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', + 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', + 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', + 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F', + 'E','R','R','A','B','L','E','L','S','E','X','C','L','U','D','E','L','E', + 'T','E','M','P','O','R','A','R','Y','I','S','N','U','L','L','S','A','V', + 'E','P','O','I','N','T','E','R','S','E','C','T','I','E','S','N','O','T', + 'N','U','L','L','I','K','E','X','C','E','P','T','R','A','N','S','A','C', + 'T','I','O','N','A','T','U','R','A','L','T','E','R','A','I','S','E','X', + 'C','L','U','S','I','V','E','X','I','S','T','S','C','O','N','S','T','R', + 'A','I','N','T','O','F','F','S','E','T','R','I','G','G','E','R','A','N', + 'G','E','N','E','R','A','T','E','D','E','T','A','C','H','A','V','I','N', + 'G','L','O','B','E','G','I','N','N','E','R','E','F','E','R','E','N','C', + 'E','S','U','N','I','Q','U','E','R','Y','W','I','T','H','O','U','T','E', + 'R','E','L','E','A','S','E','A','T','T','A','C','H','B','E','T','W','E', + 'E','N','O','T','H','I','N','G','R','O','U','P','S','C','A','S','C','A', + 'D','E','F','A','U','L','T','C','A','S','E','C','O','L','L','A','T','E', + 'C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E', + 'I','M','M','E','D','I','A','T','E','J','O','I','N','S','E','R','T','M', + 'A','T','C','H','P','L','A','N','A','L','Y','Z','E','P','R','A','G','M', + 'A','T','E','R','I','A','L','I','Z','E','D','E','F','E','R','R','E','D', + 'I','S','T','I','N','C','T','U','P','D','A','T','E','V','A','L','U','E', + 'S','V','I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H', + 'E','R','E','C','U','R','S','I','V','E','A','B','O','R','T','A','F','T', + 'E','R','E','N','A','M','E','A','N','D','R','O','P','A','R','T','I','T', + 'I','O','N','A','U','T','O','I','N','C','R','E','M','E','N','T','C','A', + 'S','T','C','O','L','U','M','N','C','O','M','M','I','T','C','O','N','F', + 'L','I','C','T','C','R','O','S','S','C','U','R','R','E','N','T','_','T', + 'I','M','E','S','T','A','M','P','R','E','C','E','D','I','N','G','F','A', + 'I','L','A','S','T','F','I','L','T','E','R','E','P','L','A','C','E','F', + 'I','R','S','T','F','O','L','L','O','W','I','N','G','F','R','O','M','F', + 'U','L','L','I','M','I','T','I','F','O','R','D','E','R','E','S','T','R', + 'I','C','T','O','T','H','E','R','S','O','V','E','R','E','T','U','R','N', + 'I','N','G','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O', + 'W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S', + 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W', + 'B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', +}; +/* aKWHash[i] is the hash value for the i-th keyword */ +static const unsigned char aKWHash[127] = { + 84, 92, 134, 82, 105, 29, 0, 0, 94, 0, 85, 72, 0, + 53, 35, 86, 15, 0, 42, 97, 54, 89, 135, 19, 0, 0, + 140, 0, 40, 129, 0, 22, 107, 0, 9, 0, 0, 123, 80, + 0, 78, 6, 0, 65, 103, 147, 0, 136, 115, 0, 0, 48, + 0, 90, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 142, + 110, 122, 0, 73, 91, 71, 145, 61, 120, 74, 0, 49, 0, + 11, 41, 0, 113, 0, 0, 0, 109, 10, 111, 116, 125, 14, + 50, 124, 0, 100, 0, 18, 121, 144, 56, 130, 139, 88, 83, + 37, 30, 126, 0, 0, 108, 51, 131, 128, 0, 34, 0, 0, + 132, 0, 98, 38, 39, 0, 20, 45, 117, 93, +}; +/* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 +** then the i-th keyword has no more hash collisions. Otherwise, +** the next keyword with the same hash is aKWHash[i]-1. */ +static const unsigned char aKWNext[148] = {0, + 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, + 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, + 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, + 138, 0, 133, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, + 0, 59, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 69, 0, 0, 0, 0, 0, 146, 3, 0, 58, 0, 1, + 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 127, 0, 104, + 0, 64, 66, 63, 0, 0, 0, 0, 0, 46, 0, 16, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 101, 0, + 112, 21, 7, 67, 0, 79, 96, 118, 0, 0, 68, 0, 0, + 99, 44, 0, 55, 0, 76, 0, 95, 32, 33, 57, 25, 0, + 102, 0, 0, 87, +}; +/* aKWLen[i] is the length (in bytes) of the i-th keyword */ +static const unsigned char aKWLen[148] = {0, + 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, + 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, + 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, + 4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6, + 2, 3, 7, 5, 9, 6, 6, 4, 5, 5, 10, 6, 5, + 7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, 7, 4, + 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 12, 8, 8, + 2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, 4, + 9, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, + 4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, + 4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, + 2, 9, 3, 7, +}; +/* aKWOffset[i] is the index into zKWText[] of the start of +** the text for the i-th keyword. */ +static const unsigned short int aKWOffset[148] = {0, + 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, + 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, + 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, + 129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184, + 184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239, + 244, 244, 248, 252, 259, 265, 271, 277, 277, 283, 284, 288, 295, + 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 359, 370, 377, + 378, 385, 391, 397, 402, 408, 412, 415, 424, 429, 433, 439, 441, + 444, 453, 455, 457, 466, 470, 476, 482, 490, 495, 495, 495, 511, + 520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579, + 585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645, + 648, 650, 655, 659, +}; +/* aKWCode[i] is the parser symbol code for the i-th keyword */ +static const unsigned char aKWCode[148] = {0, + TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, + TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, + TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, + TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, + TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, + TK_EXCLUDE, TK_DELETE, TK_TEMP, TK_TEMP, TK_OR, + TK_ISNULL, TK_NULLS, TK_SAVEPOINT, TK_INTERSECT, TK_TIES, + TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, + TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, + TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_CONSTRAINT, + TK_INTO, TK_OFFSET, TK_OF, TK_SET, TK_TRIGGER, + TK_RANGE, TK_GENERATED, TK_DETACH, TK_HAVING, TK_LIKE_KW, + TK_BEGIN, TK_JOIN_KW, TK_REFERENCES, TK_UNIQUE, TK_QUERY, + TK_WITHOUT, TK_WITH, TK_JOIN_KW, TK_RELEASE, TK_ATTACH, + TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP, TK_CASCADE, + TK_ASC, TK_DEFAULT, TK_CASE, TK_COLLATE, TK_CREATE, + TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH, + TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_MATERIALIZED, TK_DEFERRED, + TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, TK_VIRTUAL, + TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, TK_ABORT, + TK_AFTER, TK_RENAME, TK_AND, TK_DROP, TK_PARTITION, + TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, + TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, + TK_CURRENT, TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, + TK_REPLACE, TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, + TK_LIMIT, TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, + TK_OVER, TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, + TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, + TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY, + TK_ALL, TK_PRIMARY, +}; +/* Hash table decoded: +** 0: INSERT +** 1: IS +** 2: ROLLBACK TRIGGER +** 3: IMMEDIATE +** 4: PARTITION +** 5: TEMP +** 6: +** 7: +** 8: VALUES WITHOUT +** 9: +** 10: MATCH +** 11: NOTHING +** 12: +** 13: OF +** 14: TIES IGNORE +** 15: PLAN +** 16: INSTEAD INDEXED +** 17: +** 18: TRANSACTION RIGHT +** 19: WHEN +** 20: SET HAVING +** 21: MATERIALIZED IF +** 22: ROWS +** 23: SELECT +** 24: +** 25: +** 26: VACUUM SAVEPOINT +** 27: +** 28: LIKE UNION VIRTUAL REFERENCES +** 29: RESTRICT +** 30: +** 31: THEN REGEXP +** 32: TO +** 33: +** 34: BEFORE +** 35: +** 36: +** 37: FOLLOWING COLLATE CASCADE +** 38: CREATE +** 39: +** 40: CASE REINDEX +** 41: EACH +** 42: +** 43: QUERY +** 44: AND ADD +** 45: PRIMARY ANALYZE +** 46: +** 47: ROW ASC DETACH +** 48: CURRENT_TIME CURRENT_DATE +** 49: +** 50: +** 51: EXCLUSIVE TEMPORARY +** 52: +** 53: DEFERRED +** 54: DEFERRABLE +** 55: +** 56: DATABASE +** 57: +** 58: DELETE VIEW GENERATED +** 59: ATTACH +** 60: END +** 61: EXCLUDE +** 62: ESCAPE DESC +** 63: GLOB +** 64: WINDOW ELSE +** 65: COLUMN +** 66: FIRST +** 67: +** 68: GROUPS ALL +** 69: DISTINCT DROP KEY +** 70: BETWEEN +** 71: INITIALLY +** 72: BEGIN +** 73: FILTER CHECK ACTION +** 74: GROUP INDEX +** 75: +** 76: EXISTS DEFAULT +** 77: +** 78: FOR CURRENT_TIMESTAMP +** 79: EXCEPT +** 80: +** 81: CROSS +** 82: +** 83: +** 84: +** 85: CAST +** 86: FOREIGN AUTOINCREMENT +** 87: COMMIT +** 88: CURRENT AFTER ALTER +** 89: FULL FAIL CONFLICT +** 90: EXPLAIN +** 91: CONSTRAINT +** 92: FROM ALWAYS +** 93: +** 94: ABORT +** 95: +** 96: AS DO +** 97: REPLACE WITH RELEASE +** 98: BY RENAME +** 99: RANGE RAISE +** 100: OTHERS +** 101: USING NULLS +** 102: PRAGMA +** 103: JOIN ISNULL OFFSET +** 104: NOT +** 105: OR LAST LEFT +** 106: LIMIT +** 107: +** 108: +** 109: IN +** 110: INTO +** 111: OVER RECURSIVE +** 112: ORDER OUTER +** 113: +** 114: INTERSECT UNBOUNDED +** 115: +** 116: +** 117: RETURNING ON +** 118: +** 119: WHERE +** 120: NO INNER +** 121: NULL +** 122: +** 123: TABLE +** 124: NATURAL NOTNULL +** 125: PRECEDING +** 126: UPDATE UNIQUE +*/ +/* Check to see if z[0..n-1] is a keyword. If it is, write the +** parser symbol code for that keyword into *pType. Always +** return the integer n (the length of the token). */ +static int keywordCode(const char *z, int n, int *pType){ + int i, j; + const char *zKW; + assert( n>=2 ); + i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; + for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){ + if( aKWLen[i]!=n ) continue; + zKW = &zKWText[aKWOffset[i]]; +#ifdef SQLITE_ASCII + if( (z[0]&~0x20)!=zKW[0] ) continue; + if( (z[1]&~0x20)!=zKW[1] ) continue; + j = 2; + while( j=2 ) keywordCode((char*)z, n, &id); + return id; +} +#define SQLITE_N_KEYWORD 147 +SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ + if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; + i++; + *pzName = zKWText + aKWOffset[i]; + *pnName = aKWLen[i]; + return SQLITE_OK; +} +SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; } +SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){ + return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName); +} + +/************** End of keywordhash.h *****************************************/ +/************** Continuing where we left off in tokenize.c *******************/ + + +/* +** If X is a character that can be used in an identifier then +** IdChar(X) will be true. Otherwise it is false. +** +** For ASCII, any character with the high-order bit set is +** allowed in an identifier. For 7-bit characters, +** sqlite3IsIdChar[X] must be 1. +** +** For EBCDIC, the rules are more complex but have the same +** end result. +** +** Ticket #1066. the SQL standard does not allow '$' in the +** middle of identifiers. But many SQL implementations do. +** SQLite will allow '$' in identifiers for compatibility. +** But the feature is undocumented. +*/ +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */ + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */ +}; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif + +/* Make the IdChar function accessible from ctime.c and alter.c */ +SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Return the id of the next token in string (*pz). Before returning, set +** (*pz) to point to the byte following the parsed token. +*/ +static int getToken(const unsigned char **pz){ + const unsigned char *z = *pz; + int t; /* Token type to return */ + do { + z += sqlite3GetToken(z, &t); + }while( t==TK_SPACE ); + if( t==TK_ID + || t==TK_STRING + || t==TK_JOIN_KW + || t==TK_WINDOW + || t==TK_OVER + || sqlite3ParserFallback(t)==TK_ID + ){ + t = TK_ID; + } + *pz = z; + return t; +} + +/* +** The following three functions are called immediately after the tokenizer +** reads the keywords WINDOW, OVER and FILTER, respectively, to determine +** whether the token should be treated as a keyword or an SQL identifier. +** This cannot be handled by the usual lemon %fallback method, due to +** the ambiguity in some constructions. e.g. +** +** SELECT sum(x) OVER ... +** +** In the above, "OVER" might be a keyword, or it might be an alias for the +** sum(x) expression. If a "%fallback ID OVER" directive were added to +** grammar, then SQLite would always treat "OVER" as an alias, making it +** impossible to call a window-function without a FILTER clause. +** +** WINDOW is treated as a keyword if: +** +** * the following token is an identifier, or a keyword that can fallback +** to being an identifier, and +** * the token after than one is TK_AS. +** +** OVER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is either TK_LP or an identifier. +** +** FILTER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is TK_LP. +*/ +static int analyzeWindowKeyword(const unsigned char *z){ + int t; + t = getToken(&z); + if( t!=TK_ID ) return TK_ID; + t = getToken(&z); + if( t!=TK_AS ) return TK_ID; + return TK_WINDOW; +} +static int analyzeOverKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP ){ + int t = getToken(&z); + if( t==TK_LP || t==TK_ID ) return TK_OVER; + } + return TK_ID; +} +static int analyzeFilterKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP && getToken(&z)==TK_LP ){ + return TK_FILTER; + } + return TK_ID; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** Return the length (in bytes) of the token that begins at z[0]. +** Store the token type in *tokenType before returning. +*/ +SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ + int i, c; + switch( aiClass[*z] ){ /* Switch on the character-class of the first byte + ** of the token. See the comment on the CC_ defines + ** above. */ + case CC_SPACE: { + testcase( z[0]==' ' ); + testcase( z[0]=='\t' ); + testcase( z[0]=='\n' ); + testcase( z[0]=='\f' ); + testcase( z[0]=='\r' ); + for(i=1; sqlite3Isspace(z[i]); i++){} + *tokenType = TK_SPACE; + return i; + } + case CC_MINUS: { + if( z[1]=='-' ){ + for(i=2; (c=z[i])!=0 && c!='\n'; i++){} + *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ + return i; + }else if( z[1]=='>' ){ + *tokenType = TK_PTR; + return 2 + (z[2]=='>'); + } + *tokenType = TK_MINUS; + return 1; + } + case CC_LP: { + *tokenType = TK_LP; + return 1; + } + case CC_RP: { + *tokenType = TK_RP; + return 1; + } + case CC_SEMI: { + *tokenType = TK_SEMI; + return 1; + } + case CC_PLUS: { + *tokenType = TK_PLUS; + return 1; + } + case CC_STAR: { + *tokenType = TK_STAR; + return 1; + } + case CC_SLASH: { + if( z[1]!='*' || z[2]==0 ){ + *tokenType = TK_SLASH; + return 1; + } + for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} + if( c ) i++; + *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ + return i; + } + case CC_PERCENT: { + *tokenType = TK_REM; + return 1; + } + case CC_EQ: { + *tokenType = TK_EQ; + return 1 + (z[1]=='='); + } + case CC_LT: { + if( (c=z[1])=='=' ){ + *tokenType = TK_LE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_NE; + return 2; + }else if( c=='<' ){ + *tokenType = TK_LSHIFT; + return 2; + }else{ + *tokenType = TK_LT; + return 1; + } + } + case CC_GT: { + if( (c=z[1])=='=' ){ + *tokenType = TK_GE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_RSHIFT; + return 2; + }else{ + *tokenType = TK_GT; + return 1; + } + } + case CC_BANG: { + if( z[1]!='=' ){ + *tokenType = TK_ILLEGAL; + return 1; + }else{ + *tokenType = TK_NE; + return 2; + } + } + case CC_PIPE: { + if( z[1]!='|' ){ + *tokenType = TK_BITOR; + return 1; + }else{ + *tokenType = TK_CONCAT; + return 2; + } + } + case CC_COMMA: { + *tokenType = TK_COMMA; + return 1; + } + case CC_AND: { + *tokenType = TK_BITAND; + return 1; + } + case CC_TILDA: { + *tokenType = TK_BITNOT; + return 1; + } + case CC_QUOTE: { + int delim = z[0]; + testcase( delim=='`' ); + testcase( delim=='\'' ); + testcase( delim=='"' ); + for(i=1; (c=z[i])!=0; i++){ + if( c==delim ){ + if( z[i+1]==delim ){ + i++; + }else{ + break; + } + } + } + if( c=='\'' ){ + *tokenType = TK_STRING; + return i+1; + }else if( c!=0 ){ + *tokenType = TK_ID; + return i+1; + }else{ + *tokenType = TK_ILLEGAL; + return i; + } + } + case CC_DOT: { +#ifndef SQLITE_OMIT_FLOATING_POINT + if( !sqlite3Isdigit(z[1]) ) +#endif + { + *tokenType = TK_DOT; + return 1; + } + /* If the next character is a digit, this is a floating point + ** number that begins with ".". Fall thru into the next case */ + /* no break */ deliberate_fall_through + } + case CC_DIGIT: { + testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); + testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); + testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); + testcase( z[0]=='9' ); testcase( z[0]=='.' ); + *tokenType = TK_INTEGER; +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ + for(i=3; sqlite3Isxdigit(z[i]); i++){} + return i; + } +#endif + for(i=0; sqlite3Isdigit(z[i]); i++){} +#ifndef SQLITE_OMIT_FLOATING_POINT + if( z[i]=='.' ){ + i++; + while( sqlite3Isdigit(z[i]) ){ i++; } + *tokenType = TK_FLOAT; + } + if( (z[i]=='e' || z[i]=='E') && + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) + ) + ){ + i += 2; + while( sqlite3Isdigit(z[i]) ){ i++; } + *tokenType = TK_FLOAT; + } +#endif + while( IdChar(z[i]) ){ + *tokenType = TK_ILLEGAL; + i++; + } + return i; + } + case CC_QUOTE2: { + for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} + *tokenType = c==']' ? TK_ID : TK_ILLEGAL; + return i; + } + case CC_VARNUM: { + *tokenType = TK_VARIABLE; + for(i=1; sqlite3Isdigit(z[i]); i++){} + return i; + } + case CC_DOLLAR: + case CC_VARALPHA: { + int n = 0; + testcase( z[0]=='$' ); testcase( z[0]=='@' ); + testcase( z[0]==':' ); testcase( z[0]=='#' ); + *tokenType = TK_VARIABLE; + for(i=1; (c=z[i])!=0; i++){ + if( IdChar(c) ){ + n++; +#ifndef SQLITE_OMIT_TCL_VARIABLE + }else if( c=='(' && n>0 ){ + do{ + i++; + }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' ); + if( c==')' ){ + i++; + }else{ + *tokenType = TK_ILLEGAL; + } + break; + }else if( c==':' && z[i+1]==':' ){ + i++; +#endif + }else{ + break; + } + } + if( n==0 ) *tokenType = TK_ILLEGAL; + return i; + } + case CC_KYWD0: { + if( aiClass[z[1]]>CC_KYWD ){ i = 1; break; } + for(i=2; aiClass[z[i]]<=CC_KYWD; i++){} + if( IdChar(z[i]) ){ + /* This token started out using characters that can appear in keywords, + ** but z[i] is a character not allowed within keywords, so this must + ** be an identifier instead */ + i++; + break; + } + *tokenType = TK_ID; + return keywordCode((char*)z, i, tokenType); + } + case CC_X: { +#ifndef SQLITE_OMIT_BLOB_LITERAL + testcase( z[0]=='x' ); testcase( z[0]=='X' ); + if( z[1]=='\'' ){ + *tokenType = TK_BLOB; + for(i=2; sqlite3Isxdigit(z[i]); i++){} + if( z[i]!='\'' || i%2 ){ + *tokenType = TK_ILLEGAL; + while( z[i] && z[i]!='\'' ){ i++; } + } + if( z[i] ) i++; + return i; + } +#endif + /* If it is not a BLOB literal, then it must be an ID, since no + ** SQL keywords start with the letter 'x'. Fall through */ + /* no break */ deliberate_fall_through + } + case CC_KYWD: + case CC_ID: { + i = 1; + break; + } + case CC_BOM: { + if( z[1]==0xbb && z[2]==0xbf ){ + *tokenType = TK_SPACE; + return 3; + } + i = 1; + break; + } + case CC_NUL: { + *tokenType = TK_ILLEGAL; + return 0; + } + default: { + *tokenType = TK_ILLEGAL; + return 1; + } + } + while( IdChar(z[i]) ){ i++; } + *tokenType = TK_ID; + return i; +} + +/* +** Run the parser on the given SQL string. +*/ +SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ + int nErr = 0; /* Number of errors encountered */ + void *pEngine; /* The LEMON-generated LALR(1) parser */ + int n = 0; /* Length of the next token token */ + int tokenType; /* type of the next token */ + int lastTokenParsed = -1; /* type of the previous token */ + sqlite3 *db = pParse->db; /* The database connection */ + int mxSqlLen; /* Max length of an SQL string */ + Parse *pParentParse = 0; /* Outer parse context, if any */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ +#endif + VVA_ONLY( u8 startedWithOom = db->mallocFailed ); + + assert( zSql!=0 ); + mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + pParse->rc = SQLITE_OK; + pParse->zTail = zSql; +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_ParserTrace ){ + printf("parser: [[[%s]]]\n", zSql); + sqlite3ParserTrace(stdout, "parser: "); + }else{ + sqlite3ParserTrace(0, 0); + } +#endif +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + pEngine = &sEngine; + sqlite3ParserInit(pEngine, pParse); +#else + pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse); + if( pEngine==0 ){ + sqlite3OomFault(db); + return SQLITE_NOMEM_BKPT; + } +#endif + assert( pParse->pNewTable==0 ); + assert( pParse->pNewTrigger==0 ); + assert( pParse->nVar==0 ); + assert( pParse->pVList==0 ); + pParentParse = db->pParse; + db->pParse = pParse; + while( 1 ){ + n = sqlite3GetToken((u8*)zSql, &tokenType); + mxSqlLen -= n; + if( mxSqlLen<0 ){ + pParse->rc = SQLITE_TOOBIG; + pParse->nErr++; + break; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( tokenType>=TK_WINDOW ){ + assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER + || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW + ); +#else + if( tokenType>=TK_SPACE ){ + assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); +#endif /* SQLITE_OMIT_WINDOWFUNC */ + if( AtomicLoad(&db->u1.isInterrupted) ){ + pParse->rc = SQLITE_INTERRUPT; + pParse->nErr++; + break; + } + if( tokenType==TK_SPACE ){ + zSql += n; + continue; + } + if( zSql[0]==0 ){ + /* Upon reaching the end of input, call the parser two more times + ** with tokens TK_SEMI and 0, in that order. */ + if( lastTokenParsed==TK_SEMI ){ + tokenType = 0; + }else if( lastTokenParsed==0 ){ + break; + }else{ + tokenType = TK_SEMI; + } + n = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + }else if( tokenType==TK_WINDOW ){ + assert( n==6 ); + tokenType = analyzeWindowKeyword((const u8*)&zSql[6]); + }else if( tokenType==TK_OVER ){ + assert( n==4 ); + tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); + }else if( tokenType==TK_FILTER ){ + assert( n==6 ); + tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); +#endif /* SQLITE_OMIT_WINDOWFUNC */ + }else{ + Token x; + x.z = zSql; + x.n = n; + sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x); + break; + } + } + pParse->sLastToken.z = zSql; + pParse->sLastToken.n = n; + sqlite3Parser(pEngine, tokenType, pParse->sLastToken); + lastTokenParsed = tokenType; + zSql += n; + assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom ); + if( pParse->rc!=SQLITE_OK ) break; + } + assert( nErr==0 ); +#ifdef YYTRACKMAXSTACKDEPTH + sqlite3_mutex_enter(sqlite3MallocMutex()); + sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, + sqlite3ParserStackPeak(pEngine) + ); + sqlite3_mutex_leave(sqlite3MallocMutex()); +#endif /* YYDEBUG */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + sqlite3ParserFinalize(pEngine); +#else + sqlite3ParserFree(pEngine, sqlite3_free); +#endif + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM_BKPT; + } + if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){ + if( pParse->zErrMsg==0 ){ + pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); + } + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + nErr++; + } + pParse->zTail = zSql; +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_free(pParse->apVtabLock); +#endif + + if( pParse->pNewTable && !IN_SPECIAL_PARSE ){ + /* If the pParse->declareVtab flag is set, do not delete any table + ** structure built up in pParse->pNewTable. The calling code (see vtab.c) + ** will take responsibility for freeing the Table structure. + */ + sqlite3DeleteTable(db, pParse->pNewTable); + } + if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + } + if( pParse->pVList ) sqlite3DbNNFreeNN(db, pParse->pVList); + db->pParse = pParentParse; + assert( nErr==0 || pParse->rc!=SQLITE_OK ); + return nErr; +} + + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Insert a single space character into pStr if the current string +** ends with an identifier +*/ +static void addSpaceSeparator(sqlite3_str *pStr){ + if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){ + sqlite3_str_append(pStr, " ", 1); + } +} + +/* +** Compute a normalization of the SQL given by zSql[0..nSql-1]. Return +** the normalization in space obtained from sqlite3DbMalloc(). Or return +** NULL if anything goes wrong or if zSql is NULL. +*/ +SQLITE_PRIVATE char *sqlite3Normalize( + Vdbe *pVdbe, /* VM being reprepared */ + const char *zSql /* The original SQL string */ +){ + sqlite3 *db; /* The database connection */ + int i; /* Next unread byte of zSql[] */ + int n; /* length of current token */ + int tokenType; /* type of current token */ + int prevType = 0; /* Previous non-whitespace token */ + int nParen; /* Number of nested levels of parentheses */ + int iStartIN; /* Start of RHS of IN operator in z[] */ + int nParenAtIN; /* Value of nParent at start of RHS of IN operator */ + u32 j; /* Bytes of normalized SQL generated so far */ + sqlite3_str *pStr; /* The normalized SQL string under construction */ + + db = sqlite3VdbeDb(pVdbe); + tokenType = -1; + nParen = iStartIN = nParenAtIN = 0; + pStr = sqlite3_str_new(db); + assert( pStr!=0 ); /* sqlite3_str_new() never returns NULL */ + for(i=0; zSql[i] && pStr->accError==0; i+=n){ + if( tokenType!=TK_SPACE ){ + prevType = tokenType; + } + n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType); + if( NEVER(n<=0) ) break; + switch( tokenType ){ + case TK_SPACE: { + break; + } + case TK_NULL: { + if( prevType==TK_IS || prevType==TK_NOT ){ + sqlite3_str_append(pStr, " NULL", 5); + break; + } + /* Fall through */ + } + case TK_STRING: + case TK_INTEGER: + case TK_FLOAT: + case TK_VARIABLE: + case TK_BLOB: { + sqlite3_str_append(pStr, "?", 1); + break; + } + case TK_LP: { + nParen++; + if( prevType==TK_IN ){ + iStartIN = pStr->nChar; + nParenAtIN = nParen; + } + sqlite3_str_append(pStr, "(", 1); + break; + } + case TK_RP: { + if( iStartIN>0 && nParen==nParenAtIN ){ + assert( pStr->nChar>=(u32)iStartIN ); + pStr->nChar = iStartIN+1; + sqlite3_str_append(pStr, "?,?,?", 5); + iStartIN = 0; + } + nParen--; + sqlite3_str_append(pStr, ")", 1); + break; + } + case TK_ID: { + iStartIN = 0; + j = pStr->nChar; + if( sqlite3Isquote(zSql[i]) ){ + char *zId = sqlite3DbStrNDup(db, zSql+i, n); + int nId; + int eType = 0; + if( zId==0 ) break; + sqlite3Dequote(zId); + if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){ + sqlite3_str_append(pStr, "?", 1); + sqlite3DbFree(db, zId); + break; + } + nId = sqlite3Strlen30(zId); + if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){ + addSpaceSeparator(pStr); + sqlite3_str_append(pStr, zId, nId); + }else{ + sqlite3_str_appendf(pStr, "\"%w\"", zId); + } + sqlite3DbFree(db, zId); + }else{ + addSpaceSeparator(pStr); + sqlite3_str_append(pStr, zSql+i, n); + } + while( jnChar ){ + pStr->zText[j] = sqlite3Tolower(pStr->zText[j]); + j++; + } + break; + } + case TK_SELECT: { + iStartIN = 0; + /* fall through */ + } + default: { + if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); + j = pStr->nChar; + sqlite3_str_append(pStr, zSql+i, n); + while( jnChar ){ + pStr->zText[j] = sqlite3Toupper(pStr->zText[j]); + j++; + } + break; + } + } + } + if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1); + return sqlite3_str_finish(pStr); +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + +/************** End of tokenize.c ********************************************/ +/************** Begin file complete.c ****************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** An tokenizer for SQL +** +** This file contains C code that implements the sqlite3_complete() API. +** This code used to be part of the tokenizer.c source file. But by +** separating it out, the code will be automatically omitted from +** static links that do not use it. +*/ +/* #include "sqliteInt.h" */ +#ifndef SQLITE_OMIT_COMPLETE + +/* +** This is defined in tokenize.c. We just have to import the definition. +*/ +#ifndef SQLITE_AMALGAMATION +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif +#endif /* SQLITE_AMALGAMATION */ + + +/* +** Token types used by the sqlite3_complete() routine. See the header +** comments on that procedure for additional information. +*/ +#define tkSEMI 0 +#define tkWS 1 +#define tkOTHER 2 +#ifndef SQLITE_OMIT_TRIGGER +#define tkEXPLAIN 3 +#define tkCREATE 4 +#define tkTEMP 5 +#define tkTRIGGER 6 +#define tkEND 7 +#endif + +/* +** Return TRUE if the given SQL string ends in a semicolon. +** +** Special handling is require for CREATE TRIGGER statements. +** Whenever the CREATE TRIGGER keywords are seen, the statement +** must end with ";END;". +** +** This implementation uses a state machine with 8 states: +** +** (0) INVALID We have not yet seen a non-whitespace character. +** +** (1) START At the beginning or end of an SQL statement. This routine +** returns 1 if it ends in the START state and 0 if it ends +** in any other state. +** +** (2) NORMAL We are in the middle of statement which ends with a single +** semicolon. +** +** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** a statement. +** +** (4) CREATE The keyword CREATE has been seen at the beginning of a +** statement, possibly preceded by EXPLAIN and/or followed by +** TEMP or TEMPORARY +** +** (5) TRIGGER We are in the middle of a trigger definition that must be +** ended by a semicolon, the keyword END, and another semicolon. +** +** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at +** the end of a trigger definition. +** +** (7) END We've seen the ";END" of the ";END;" that occurs at the end +** of a trigger definition. +** +** Transitions between states above are determined by tokens extracted +** from the input. The following tokens are significant: +** +** (0) tkSEMI A semicolon. +** (1) tkWS Whitespace. +** (2) tkOTHER Any other SQL token. +** (3) tkEXPLAIN The "explain" keyword. +** (4) tkCREATE The "create" keyword. +** (5) tkTEMP The "temp" or "temporary" keyword. +** (6) tkTRIGGER The "trigger" keyword. +** (7) tkEND The "end" keyword. +** +** Whitespace never causes a state transition and is always ignored. +** This means that a SQL string of all whitespace is invalid. +** +** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed +** to recognize the end of a trigger can be omitted. All we have to do +** is look for a semicolon that is not part of an string or comment. +*/ +SQLITE_API int sqlite3_complete(const char *zSql){ + u8 state = 0; /* Current state, using numbers defined in header comment */ + u8 token; /* Value of the next token */ + +#ifndef SQLITE_OMIT_TRIGGER + /* A complex statement machine used to detect the end of a CREATE TRIGGER + ** statement. This is the normal case. + */ + static const u8 trans[8][8] = { + /* Token: */ + /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ + /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, + /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, }, + /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, }, + /* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, }, + /* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, }, + /* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, }, + /* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, }, + }; +#else + /* If triggers are not supported by this compile then the statement machine + ** used to detect the end of a statement is much simpler + */ + static const u8 trans[3][3] = { + /* Token: */ + /* State: ** SEMI WS OTHER */ + /* 0 INVALID: */ { 1, 0, 2, }, + /* 1 START: */ { 1, 1, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, }, + }; +#endif /* SQLITE_OMIT_TRIGGER */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zSql==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + while( *zSql ){ + switch( *zSql ){ + case ';': { /* A semicolon */ + token = tkSEMI; + break; + } + case ' ': + case '\r': + case '\t': + case '\n': + case '\f': { /* White space is ignored */ + token = tkWS; + break; + } + case '/': { /* C-style comments */ + if( zSql[1]!='*' ){ + token = tkOTHER; + break; + } + zSql += 2; + while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } + if( zSql[0]==0 ) return 0; + zSql++; + token = tkWS; + break; + } + case '-': { /* SQL-style comments from "--" to end of line */ + if( zSql[1]!='-' ){ + token = tkOTHER; + break; + } + while( *zSql && *zSql!='\n' ){ zSql++; } + if( *zSql==0 ) return state==1; + token = tkWS; + break; + } + case '[': { /* Microsoft-style identifiers in [...] */ + zSql++; + while( *zSql && *zSql!=']' ){ zSql++; } + if( *zSql==0 ) return 0; + token = tkOTHER; + break; + } + case '`': /* Grave-accent quoted symbols used by MySQL */ + case '"': /* single- and double-quoted strings */ + case '\'': { + int c = *zSql; + zSql++; + while( *zSql && *zSql!=c ){ zSql++; } + if( *zSql==0 ) return 0; + token = tkOTHER; + break; + } + default: { +#ifdef SQLITE_EBCDIC + unsigned char c; +#endif + if( IdChar((u8)*zSql) ){ + /* Keywords and unquoted identifiers */ + int nId; + for(nId=1; IdChar(zSql[nId]); nId++){} +#ifdef SQLITE_OMIT_TRIGGER + token = tkOTHER; +#else + switch( *zSql ){ + case 'c': case 'C': { + if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ + token = tkCREATE; + }else{ + token = tkOTHER; + } + break; + } + case 't': case 'T': { + if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ + token = tkTRIGGER; + }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ + token = tkTEMP; + }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ + token = tkTEMP; + }else{ + token = tkOTHER; + } + break; + } + case 'e': case 'E': { + if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ + token = tkEND; + }else +#ifndef SQLITE_OMIT_EXPLAIN + if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ + token = tkEXPLAIN; + }else +#endif + { + token = tkOTHER; + } + break; + } + default: { + token = tkOTHER; + break; + } + } +#endif /* SQLITE_OMIT_TRIGGER */ + zSql += nId-1; + }else{ + /* Operators and special symbols */ + token = tkOTHER; + } + break; + } + } + state = trans[state][token]; + zSql++; + } + return state==1; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** This routine is the same as the sqlite3_complete() routine described +** above, except that the parameter is required to be UTF-16 encoded, not +** UTF-8. +*/ +SQLITE_API int sqlite3_complete16(const void *zSql){ + sqlite3_value *pVal; + char const *zSql8; + int rc; + +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zSql8 ){ + rc = sqlite3_complete(zSql8); + }else{ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3ValueFree(pVal); + return rc & 0xff; +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_COMPLETE */ + +/************** End of complete.c ********************************************/ +/************** Begin file main.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Main file for the SQLite library. The routines in this file +** implement the programmer interface to the library. Routines in +** other files are for internal use by SQLite and should not be +** accessed by users of the library. +*/ +/* #include "sqliteInt.h" */ + +#ifdef SQLITE_ENABLE_FTS3 +/************** Include fts3.h in the middle of main.c ***********************/ +/************** Begin file fts3.h ********************************************/ +/* +** 2006 Oct 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file is used by programs that want to link against the +** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. +*/ +/* #include "sqlite3.h" */ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of fts3.h ************************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif +#ifdef SQLITE_ENABLE_RTREE +/************** Include rtree.h in the middle of main.c **********************/ +/************** Begin file rtree.h *******************************************/ +/* +** 2008 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file is used by programs that want to link against the +** RTREE library. All it does is declare the sqlite3RtreeInit() interface. +*/ +/* #include "sqlite3.h" */ + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# undef SQLITE_ENABLE_RTREE +#endif + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of rtree.h ***********************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif +#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) +/************** Include sqliteicu.h in the middle of main.c ******************/ +/************** Begin file sqliteicu.h ***************************************/ +/* +** 2008 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file is used by programs that want to link against the +** ICU extension. All it does is declare the sqlite3IcuInit() interface. +*/ +/* #include "sqlite3.h" */ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of sqliteicu.h *******************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif + +/* +** This is an extension initializer that is a no-op and always +** succeeds, except that it fails if the fault-simulation is set +** to 500. +*/ +static int sqlite3TestExtInit(sqlite3 *db){ + (void)db; + return sqlite3FaultSim(500); +} + + +/* +** Forward declarations of external module initializer functions +** for modules that need them. +*/ +#ifdef SQLITE_ENABLE_FTS5 +SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); +#endif +#ifdef SQLITE_ENABLE_STMTVTAB +SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); +#endif +#ifdef SQLITE_EXTRA_AUTOEXT +int SQLITE_EXTRA_AUTOEXT(sqlite3*); +#endif +/* +** An array of pointers to extension initializer functions for +** built-in extensions. +*/ +static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { +#ifdef SQLITE_ENABLE_FTS3 + sqlite3Fts3Init, +#endif +#ifdef SQLITE_ENABLE_FTS5 + sqlite3Fts5Init, +#endif +#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) + sqlite3IcuInit, +#endif +#ifdef SQLITE_ENABLE_RTREE + sqlite3RtreeInit, +#endif +#ifdef SQLITE_ENABLE_DBPAGE_VTAB + sqlite3DbpageRegister, +#endif +#ifdef SQLITE_ENABLE_DBSTAT_VTAB + sqlite3DbstatRegister, +#endif + sqlite3TestExtInit, +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) + sqlite3JsonTableFunctions, +#endif +#ifdef SQLITE_ENABLE_STMTVTAB + sqlite3StmtVtabInit, +#endif +#ifdef SQLITE_ENABLE_BYTECODE_VTAB + sqlite3VdbeBytecodeVtabInit, +#endif +#ifdef SQLITE_EXTRA_AUTOEXT + SQLITE_EXTRA_AUTOEXT, +#endif +}; + +#ifndef SQLITE_AMALGAMATION +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant +** contains the text of SQLITE_VERSION macro. +*/ +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +#endif + +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns +** a pointer to the to the sqlite3_version[] string constant. +*/ +SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } + +/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a +** pointer to a string constant whose value is the same as the +** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using +** an edited copy of the amalgamation, then the last four characters of +** the hash might be different from SQLITE_SOURCE_ID. +*/ +/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ + +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function +** returns an integer equal to SQLITE_VERSION_NUMBER. +*/ +SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } + +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns +** zero if and only if SQLite was compiled with mutexing code omitted due to +** the SQLITE_THREADSAFE compile-time option being set to 0. +*/ +SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } + +/* +** When compiling the test fixture or with debugging enabled (on Win32), +** this variable being set to non-zero will cause OSTRACE macros to emit +** extra diagnostic information. +*/ +#ifdef SQLITE_HAVE_OS_TRACE +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +#endif + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** If the following function pointer is not NULL and if +** SQLITE_ENABLE_IOTRACE is enabled, then messages describing +** I/O active are written using this function. These messages +** are intended for debugging activity only. +*/ +SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0; +#endif + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** temporary files. +** +** See also the "PRAGMA temp_store_directory" SQL command. +*/ +SQLITE_API char *sqlite3_temp_directory = 0; + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** all database files specified with a relative pathname. +** +** See also the "PRAGMA data_store_directory" SQL command. +*/ +SQLITE_API char *sqlite3_data_directory = 0; + +/* +** Determine whether or not high-precision (long double) floating point +** math works correctly on CPU currently running. +*/ +static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ + if( sizeof(LONGDOUBLE_TYPE)<=8 ){ + /* If the size of "long double" is not more than 8, then + ** high-precision math is not possible. */ + return 0; + }else{ + /* Just because sizeof(long double)>8 does not mean that the underlying + ** hardware actually supports high-precision floating point. For example, + ** clearing the 0x100 bit in the floating-point control word on Intel + ** processors will make long double work like double, even though long + ** double takes up more space. The only way to determine if long double + ** actually works is to run an experiment. */ + LONGDOUBLE_TYPE a, b, c; + rc++; + a = 1.0+rc*0.1; + b = 1.0e+18+rc*25.0; + c = a+b; + return b!=c; + } +} + + +/* +** Initialize SQLite. +** +** This routine must be called to initialize the memory allocation, +** VFS, and mutex subsystems prior to doing any serious work with +** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT +** this routine will be called automatically by key routines such as +** sqlite3_open(). +** +** This routine is a no-op except on its very first call for the process, +** or for the first call after a call to sqlite3_shutdown. +** +** The first thread to call this routine runs the initialization to +** completion. If subsequent threads call this routine before the first +** thread has finished the initialization process, then the subsequent +** threads must block until the first thread finishes with the initialization. +** +** The first thread might call this routine recursively. Recursive +** calls to this routine should not block, of course. Otherwise the +** initialization process would never complete. +** +** Let X be the first thread to enter this routine. Let Y be some other +** thread. Then while the initial invocation of this routine by X is +** incomplete, it is required that: +** +** * Calls to this routine from Y must block until the outer-most +** call by X completes. +** +** * Recursive calls to this routine from thread X return immediately +** without blocking. +*/ +SQLITE_API int sqlite3_initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */ + int rc; /* Result code */ +#ifdef SQLITE_EXTRA_INIT + int bRunExtraInit = 0; /* Extra initialization needed */ +#endif + +#ifdef SQLITE_OMIT_WSD + rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + /* If the following assert() fails on some obscure processor/compiler + ** combination, the work-around is to set the correct pointer + ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ + assert( SQLITE_PTRSIZE==sizeof(char*) ); + + /* If SQLite is already completely initialized, then this call + ** to sqlite3_initialize() should be a no-op. But the initialization + ** must be complete. So isInit must not be set until the very end + ** of this routine. + */ + if( sqlite3GlobalConfig.isInit ){ + sqlite3MemoryBarrier(); + return SQLITE_OK; + } + + /* Make sure the mutex subsystem is initialized. If unable to + ** initialize the mutex subsystem, return early with the error. + ** If the system is so sick that we are unable to allocate a mutex, + ** there is not much SQLite is going to be able to do. + ** + ** The mutex subsystem must take care of serializing its own + ** initialization. + */ + rc = sqlite3MutexInit(); + if( rc ) return rc; + + /* Initialize the malloc() system and the recursive pInitMutex mutex. + ** This operation is protected by the STATIC_MAIN mutex. Note that + ** MutexAlloc() is called for a static mutex prior to initializing the + ** malloc subsystem - this implies that the allocation of a static + ** mutex must not require support from the malloc subsystem. + */ + MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(pMainMtx); + sqlite3GlobalConfig.isMutexInit = 1; + if( !sqlite3GlobalConfig.isMallocInit ){ + rc = sqlite3MallocInit(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isMallocInit = 1; + if( !sqlite3GlobalConfig.pInitMutex ){ + sqlite3GlobalConfig.pInitMutex = + sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ + rc = SQLITE_NOMEM_BKPT; + } + } + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.nRefInitMutex++; + } + sqlite3_mutex_leave(pMainMtx); + + /* If rc is not SQLITE_OK at this point, then either the malloc + ** subsystem could not be initialized or the system failed to allocate + ** the pInitMutex mutex. Return an error in either case. */ + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Do the rest of the initialization under the recursive mutex so + ** that we will be able to handle recursive calls into + ** sqlite3_initialize(). The recursive calls normally come through + ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other + ** recursive calls might also be possible. + ** + ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls + ** to the xInit method, so the xInit method need not be threadsafe. + ** + ** The following mutex is what serializes access to the appdef pcache xInit + ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the + ** call to sqlite3PcacheInitialize(). + */ + sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); + if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ + sqlite3GlobalConfig.inProgress = 1; +#ifdef SQLITE_ENABLE_SQLLOG + { + extern void sqlite3_init_sqllog(void); + sqlite3_init_sqllog(); + } +#endif + memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions)); + sqlite3RegisterBuiltinFunctions(); + if( sqlite3GlobalConfig.isPCacheInit==0 ){ + rc = sqlite3PcacheInitialize(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isPCacheInit = 1; + rc = sqlite3OsInit(); + } +#ifndef SQLITE_OMIT_DESERIALIZE + if( rc==SQLITE_OK ){ + rc = sqlite3MemdbInit(); + } +#endif + if( rc==SQLITE_OK ){ + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); + sqlite3MemoryBarrier(); + sqlite3GlobalConfig.isInit = 1; +#ifdef SQLITE_EXTRA_INIT + bRunExtraInit = 1; +#endif + } + sqlite3GlobalConfig.inProgress = 0; + } + sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex); + + /* Go back under the static mutex and clean up the recursive + ** mutex to prevent a resource leak. + */ + sqlite3_mutex_enter(pMainMtx); + sqlite3GlobalConfig.nRefInitMutex--; + if( sqlite3GlobalConfig.nRefInitMutex<=0 ){ + assert( sqlite3GlobalConfig.nRefInitMutex==0 ); + sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex); + sqlite3GlobalConfig.pInitMutex = 0; + } + sqlite3_mutex_leave(pMainMtx); + + /* The following is just a sanity check to make sure SQLite has + ** been compiled correctly. It is important to run this code, but + ** we don't want to run it too often and soak up CPU cycles for no + ** reason. So we run it once during initialization. + */ +#ifndef NDEBUG +#ifndef SQLITE_OMIT_FLOATING_POINT + /* This section of code's only "output" is via assert() statements. */ + if( rc==SQLITE_OK ){ + u64 x = (((u64)1)<<63)-1; + double y; + assert(sizeof(x)==8); + assert(sizeof(x)==sizeof(y)); + memcpy(&y, &x, 8); + assert( sqlite3IsNaN(y) ); + } +#endif +#endif + + /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT + ** compile-time option. + */ +#ifdef SQLITE_EXTRA_INIT + if( bRunExtraInit ){ + int SQLITE_EXTRA_INIT(const char*); + rc = SQLITE_EXTRA_INIT(0); + } +#endif + + /* Experimentally determine if high-precision floating point is + ** available. */ +#ifndef SQLITE_OMIT_WSD + sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); +#endif + + return rc; +} + +/* +** Undo the effects of sqlite3_initialize(). Must not be called while +** there are outstanding database connections or memory allocations or +** while any part of SQLite is otherwise in use in any thread. This +** routine is not threadsafe. But it is safe to invoke this routine +** on when SQLite is already shut down. If SQLite is already shut down +** when this routine is invoked, then this routine is a harmless no-op. +*/ +SQLITE_API int sqlite3_shutdown(void){ +#ifdef SQLITE_OMIT_WSD + int rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + if( sqlite3GlobalConfig.isInit ){ +#ifdef SQLITE_EXTRA_SHUTDOWN + void SQLITE_EXTRA_SHUTDOWN(void); + SQLITE_EXTRA_SHUTDOWN(); +#endif + sqlite3_os_end(); + sqlite3_reset_auto_extension(); + sqlite3GlobalConfig.isInit = 0; + } + if( sqlite3GlobalConfig.isPCacheInit ){ + sqlite3PcacheShutdown(); + sqlite3GlobalConfig.isPCacheInit = 0; + } + if( sqlite3GlobalConfig.isMallocInit ){ + sqlite3MallocEnd(); + sqlite3GlobalConfig.isMallocInit = 0; + +#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES + /* The heap subsystem has now been shutdown and these values are supposed + ** to be NULL or point to memory that was obtained from sqlite3_malloc(), + ** which would rely on that heap subsystem; therefore, make sure these + ** values cannot refer to heap memory that was just invalidated when the + ** heap subsystem was shutdown. This is only done if the current call to + ** this function resulted in the heap subsystem actually being shutdown. + */ + sqlite3_data_directory = 0; + sqlite3_temp_directory = 0; +#endif + } + if( sqlite3GlobalConfig.isMutexInit ){ + sqlite3MutexEnd(); + sqlite3GlobalConfig.isMutexInit = 0; + } + + return SQLITE_OK; +} + +/* +** This API allows applications to modify the global configuration of +** the SQLite library at run-time. +** +** This routine should only be called when there are no outstanding +** database connections or memory allocations. This routine is not +** threadsafe. Failure to heed these warnings can lead to unpredictable +** behavior. +*/ +SQLITE_API int sqlite3_config(int op, ...){ + va_list ap; + int rc = SQLITE_OK; + + /* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. Except, a few selected opcodes + ** are allowed. + */ + if( sqlite3GlobalConfig.isInit ){ + static const u64 mAnytimeConfigOption = 0 + | MASKBIT64( SQLITE_CONFIG_LOG ) + | MASKBIT64( SQLITE_CONFIG_PCACHE_HDRSZ ) + ; + if( op<0 || op>63 || (MASKBIT64(op) & mAnytimeConfigOption)==0 ){ + return SQLITE_MISUSE_BKPT; + } + testcase( op==SQLITE_CONFIG_LOG ); + testcase( op==SQLITE_CONFIG_PCACHE_HDRSZ ); + } + + va_start(ap, op); + switch( op ){ + + /* Mutex configuration options are only available in a threadsafe + ** compile. + */ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */ + case SQLITE_CONFIG_SINGLETHREAD: { + /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to + ** Single-thread. */ + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ + case SQLITE_CONFIG_MULTITHREAD: { + /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to + ** Multi-thread. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ + case SQLITE_CONFIG_SERIALIZED: { + /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to + ** Serialized. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */ + case SQLITE_CONFIG_MUTEX: { + /* Specify an alternative mutex implementation */ + sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*); + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */ + case SQLITE_CONFIG_GETMUTEX: { + /* Retrieve the current mutex implementation */ + *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex; + break; + } +#endif + + case SQLITE_CONFIG_MALLOC: { + /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a + ** single argument which is a pointer to an instance of the + ** sqlite3_mem_methods structure. The argument specifies alternative + ** low-level memory allocation routines to be used in place of the memory + ** allocation routines built into SQLite. */ + sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*); + break; + } + case SQLITE_CONFIG_GETMALLOC: { + /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a + ** single argument which is a pointer to an instance of the + ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is + ** filled with the currently defined memory allocation routines. */ + if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); + *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; + break; + } + case SQLITE_CONFIG_MEMSTATUS: { + assert( !sqlite3GlobalConfig.isInit ); /* Cannot change at runtime */ + /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes + ** single argument of type int, interpreted as a boolean, which enables + ** or disables the collection of memory allocation statistics. */ + sqlite3GlobalConfig.bMemstat = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_SMALL_MALLOC: { + sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PAGECACHE: { + /* EVIDENCE-OF: R-18761-36601 There are three arguments to + ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem), + ** the size of each page cache line (sz), and the number of cache lines + ** (N). */ + sqlite3GlobalConfig.pPage = va_arg(ap, void*); + sqlite3GlobalConfig.szPage = va_arg(ap, int); + sqlite3GlobalConfig.nPage = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PCACHE_HDRSZ: { + /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes + ** a single parameter which is a pointer to an integer and writes into + ** that integer the number of extra bytes per page required for each page + ** in SQLITE_CONFIG_PAGECACHE. */ + *va_arg(ap, int*) = + sqlite3HeaderSizeBtree() + + sqlite3HeaderSizePcache() + + sqlite3HeaderSizePcache1(); + break; + } + + case SQLITE_CONFIG_PCACHE: { + /* no-op */ + break; + } + case SQLITE_CONFIG_GETPCACHE: { + /* now an error */ + rc = SQLITE_ERROR; + break; + } + + case SQLITE_CONFIG_PCACHE2: { + /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a + ** single argument which is a pointer to an sqlite3_pcache_methods2 + ** object. This object specifies the interface to a custom page cache + ** implementation. */ + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); + break; + } + case SQLITE_CONFIG_GETPCACHE2: { + /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a + ** single argument which is a pointer to an sqlite3_pcache_methods2 + ** object. SQLite copies of the current page cache implementation into + ** that object. */ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + sqlite3PCacheSetDefault(); + } + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; + break; + } + +/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only +** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or +** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */ +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) + case SQLITE_CONFIG_HEAP: { + /* EVIDENCE-OF: R-19854-42126 There are three arguments to + ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the + ** number of bytes in the memory buffer, and the minimum allocation size. + */ + sqlite3GlobalConfig.pHeap = va_arg(ap, void*); + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + sqlite3GlobalConfig.mnReq = va_arg(ap, int); + + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ + /* cap min request size at 2^12 */ + sqlite3GlobalConfig.mnReq = (1<<12); + } + + if( sqlite3GlobalConfig.pHeap==0 ){ + /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer) + ** is NULL, then SQLite reverts to using its default memory allocator + ** (the system malloc() implementation), undoing any prior invocation of + ** SQLITE_CONFIG_MALLOC. + ** + ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to + ** revert to its default implementation when sqlite3_initialize() is run + */ + memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); + }else{ + /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the + ** alternative memory allocator is engaged to handle all of SQLites + ** memory allocation needs. */ +#ifdef SQLITE_ENABLE_MEMSYS3 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5(); +#endif + } + break; + } +#endif + + case SQLITE_CONFIG_LOOKASIDE: { + sqlite3GlobalConfig.szLookaside = va_arg(ap, int); + sqlite3GlobalConfig.nLookaside = va_arg(ap, int); + break; + } + + /* Record a pointer to the logger function and its first argument. + ** The default is NULL. Logging is disabled if the function pointer is + ** NULL. + */ + case SQLITE_CONFIG_LOG: { + /* MSVC is picky about pulling func ptrs from va lists. + ** http://support.microsoft.com/kb/47961 + ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); + */ + typedef void(*LOGFUNC_t)(void*,int,const char*); + LOGFUNC_t xLog = va_arg(ap, LOGFUNC_t); + void *pLogArg = va_arg(ap, void*); + AtomicStore(&sqlite3GlobalConfig.xLog, xLog); + AtomicStore(&sqlite3GlobalConfig.pLogArg, pLogArg); + break; + } + + /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames + ** can be changed at start-time using the + ** sqlite3_config(SQLITE_CONFIG_URI,1) or + ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. + */ + case SQLITE_CONFIG_URI: { + /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single + ** argument of type int. If non-zero, then URI handling is globally + ** enabled. If the parameter is zero, then URI handling is globally + ** disabled. */ + int bOpenUri = va_arg(ap, int); + AtomicStore(&sqlite3GlobalConfig.bOpenUri, bOpenUri); + break; + } + + case SQLITE_CONFIG_COVERING_INDEX_SCAN: { + /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN + ** option takes a single integer argument which is interpreted as a + ** boolean in order to enable or disable the use of covering indices for + ** full table scans in the query optimizer. */ + sqlite3GlobalConfig.bUseCis = va_arg(ap, int); + break; + } + +#ifdef SQLITE_ENABLE_SQLLOG + case SQLITE_CONFIG_SQLLOG: { + typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int); + sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); + sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); + break; + } +#endif + + case SQLITE_CONFIG_MMAP_SIZE: { + /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit + ** integer (sqlite3_int64) values that are the default mmap size limit + ** (the default setting for PRAGMA mmap_size) and the maximum allowed + ** mmap size limit. */ + sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); + sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); + /* EVIDENCE-OF: R-53367-43190 If either argument to this option is + ** negative, then that argument is changed to its compile-time default. + ** + ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be + ** silently truncated if necessary so that it does not exceed the + ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE + ** compile-time option. + */ + if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ + mxMmap = SQLITE_MAX_MMAP_SIZE; + } + if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; + if( szMmap>mxMmap) szMmap = mxMmap; + sqlite3GlobalConfig.mxMmap = mxMmap; + sqlite3GlobalConfig.szMmap = szMmap; + break; + } + +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */ + case SQLITE_CONFIG_WIN32_HEAPSIZE: { + /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit + ** unsigned integer value that specifies the maximum size of the created + ** heap. */ + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + break; + } +#endif + + case SQLITE_CONFIG_PMASZ: { + sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int); + break; + } + + case SQLITE_CONFIG_STMTJRNL_SPILL: { + sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int); + break; + } + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + case SQLITE_CONFIG_SORTERREF_SIZE: { + int iVal = va_arg(ap, int); + if( iVal<0 ){ + iVal = SQLITE_DEFAULT_SORTERREF_SIZE; + } + sqlite3GlobalConfig.szSorterRef = (u32)iVal; + break; + } +#endif /* SQLITE_ENABLE_SORTER_REFERENCES */ + +#ifndef SQLITE_OMIT_DESERIALIZE + case SQLITE_CONFIG_MEMDB_MAXSIZE: { + sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64); + break; + } +#endif /* SQLITE_OMIT_DESERIALIZE */ + + case SQLITE_CONFIG_ROWID_IN_VIEW: { + int *pVal = va_arg(ap,int*); +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid; + if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0; + *pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0); +#else + *pVal = 0; +#endif + break; + } + + default: { + rc = SQLITE_ERROR; + break; + } + } + va_end(ap); + return rc; +} + +/* +** Set up the lookaside buffers for a database connection. +** Return SQLITE_OK on success. +** If lookaside is already active, return SQLITE_BUSY. +** +** The sz parameter is the number of bytes in each lookaside slot. +** The cnt parameter is the number of slots. If pStart is NULL the +** space for the lookaside memory is obtained from sqlite3_malloc(). +** If pStart is not NULL then it is sz*cnt bytes of memory to use for +** the lookaside memory. +*/ +static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ +#ifndef SQLITE_OMIT_LOOKASIDE + void *pStart; + sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt; + int nBig; /* Number of full-size slots */ + int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ + + if( sqlite3LookasideUsed(db,0)>0 ){ + return SQLITE_BUSY; + } + /* Free any existing lookaside buffer for this handle before + ** allocating a new one so we don't have to have space for + ** both at the same time. + */ + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger + ** than a pointer to be useful. + */ + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ + if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; + if( cnt<0 ) cnt = 0; + if( sz==0 || cnt==0 ){ + sz = 0; + pStart = 0; + }else if( pBuf==0 ){ + sqlite3BeginBenignMalloc(); + pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */ + sqlite3EndBenignMalloc(); + if( pStart ) szAlloc = sqlite3MallocSize(pStart); + }else{ + pStart = pBuf; + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( sz>=LOOKASIDE_SMALL*3 ){ + nBig = szAlloc/(3*LOOKASIDE_SMALL+sz); + nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL; + }else if( sz>=LOOKASIDE_SMALL*2 ){ + nBig = szAlloc/(LOOKASIDE_SMALL+sz); + nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL; + }else +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( sz>0 ){ + nBig = szAlloc/sz; + nSm = 0; + }else{ + nBig = nSm = 0; + } + db->lookaside.pStart = pStart; + db->lookaside.pInit = 0; + db->lookaside.pFree = 0; + db->lookaside.sz = (u16)sz; + db->lookaside.szTrue = (u16)sz; + if( pStart ){ + int i; + LookasideSlot *p; + assert( sz > (int)sizeof(LookasideSlot*) ); + p = (LookasideSlot*)pStart; + for(i=0; ipNext = db->lookaside.pInit; + db->lookaside.pInit = p; + p = (LookasideSlot*)&((u8*)p)[sz]; + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + db->lookaside.pSmallInit = 0; + db->lookaside.pSmallFree = 0; + db->lookaside.pMiddle = p; + for(i=0; ipNext = db->lookaside.pSmallInit; + db->lookaside.pSmallInit = p; + p = (LookasideSlot*)&((u8*)p)[LOOKASIDE_SMALL]; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + assert( ((uptr)p)<=szAlloc + (uptr)pStart ); + db->lookaside.pEnd = p; + db->lookaside.bDisable = 0; + db->lookaside.bMalloced = pBuf==0 ?1:0; + db->lookaside.nSlot = nBig+nSm; + }else{ + db->lookaside.pStart = 0; +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + db->lookaside.pSmallInit = 0; + db->lookaside.pSmallFree = 0; + db->lookaside.pMiddle = 0; +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + db->lookaside.pEnd = 0; + db->lookaside.bDisable = 1; + db->lookaside.sz = 0; + db->lookaside.bMalloced = 0; + db->lookaside.nSlot = 0; + } + db->lookaside.pTrueEnd = db->lookaside.pEnd; + assert( sqlite3LookasideUsed(db,0)==0 ); +#endif /* SQLITE_OMIT_LOOKASIDE */ + return SQLITE_OK; +} + +/* +** Return the mutex associated with a database connection. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->mutex; +} + +/* +** Free up as much memory as we can from the given database +** connection. +*/ +SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){ + int i; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Flush any dirty pages in the pager-cache for any attached database +** to disk. +*/ +SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ + int i; + int rc = SQLITE_OK; + int bSeenBusy = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ + Pager *pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerFlush(pPager); + if( rc==SQLITE_BUSY ){ + bSeenBusy = 1; + rc = SQLITE_OK; + } + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); +} + +/* +** Configuration settings for an individual database connection +*/ +SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + va_start(ap, op); + switch( op ){ + case SQLITE_DBCONFIG_MAINDBNAME: { + /* IMP: R-06824-28531 */ + /* IMP: R-36257-52125 */ + db->aDb[0].zDbSName = va_arg(ap,char*); + rc = SQLITE_OK; + break; + } + case SQLITE_DBCONFIG_LOOKASIDE: { + void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ + int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ + int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ + rc = setupLookaside(db, pBuf, sz, cnt); + break; + } + default: { + static const struct { + int op; /* The opcode */ + u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ + } aFlagOp[] = { + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + { SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView }, + { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, + { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, + { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, + { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, + { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, + { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, + { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, + { SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema| + SQLITE_NoSchemaError }, + { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter }, + { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, + { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, + { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, + { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, + { SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus }, + { SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder }, + }; + unsigned int i; + rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ + for(i=0; iflags; + if( onoff>0 ){ + db->flags |= aFlagOp[i].mask; + }else if( onoff==0 ){ + db->flags &= ~(u64)aFlagOp[i].mask; + } + if( oldFlags!=db->flags ){ + sqlite3ExpirePreparedStatements(db, 0); + } + if( pRes ){ + *pRes = (db->flags & aFlagOp[i].mask)!=0; + } + rc = SQLITE_OK; + break; + } + } + break; + } + } + va_end(ap); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This is the default collating function named "BINARY" which is always +** available. +*/ +static int binCollFunc( + void *NotUsed, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + int rc, n; + UNUSED_PARAMETER(NotUsed); + n = nKey1xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 ); + return p==0 || p->xCmp==binCollFunc; +} + +/* +** Another built-in collating sequence: NOCASE. +** +** This collating sequence is intended to be used for "case independent +** comparison". SQLite's knowledge of upper and lower case equivalents +** extends only to the 26 characters used in the English language. +** +** At the moment there is only a UTF-8 implementation. +*/ +static int nocaseCollatingFunc( + void *NotUsed, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + int r = sqlite3StrNICmp( + (const char *)pKey1, (const char *)pKey2, (nKey1lastRowid; +} + +/* +** Set the value returned by the sqlite3_last_insert_rowid() API function. +*/ +SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + sqlite3_mutex_enter(db->mutex); + db->lastRowid = iRowid; + sqlite3_mutex_leave(db->mutex); +} + +/* +** Return the number of changes in the most recent call to sqlite3_exec(). +*/ +SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->nChange; +} +SQLITE_API int sqlite3_changes(sqlite3 *db){ + return (int)sqlite3_changes64(db); +} + +/* +** Return the number of changes since the database handle was opened. +*/ +SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->nTotalChange; +} +SQLITE_API int sqlite3_total_changes(sqlite3 *db){ + return (int)sqlite3_total_changes64(db); +} + +/* +** Close all open savepoints. This function only manipulates fields of the +** database handle object, it does not close any savepoints that may be open +** at the b-tree/pager level. +*/ +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ + while( db->pSavepoint ){ + Savepoint *pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + } + db->nSavepoint = 0; + db->nStatement = 0; + db->isTransactionSavepoint = 0; +} + +/* +** Invoke the destructor function associated with FuncDef p, if any. Except, +** if this is not the last copy of the function, do not invoke it. Multiple +** copies of a single function are created when create_function() is called +** with SQLITE_ANY as the encoding. +*/ +static void functionDestroy(sqlite3 *db, FuncDef *p){ + FuncDestructor *pDestructor; + assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); + pDestructor = p->u.pDestructor; + if( pDestructor ){ + pDestructor->nRef--; + if( pDestructor->nRef==0 ){ + pDestructor->xDestroy(pDestructor->pUserData); + sqlite3DbFree(db, pDestructor); + } + } +} + +/* +** Disconnect all sqlite3_vtab objects that belong to database connection +** db. This is called when db is being closed. +*/ +static void disconnectAllVtab(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int i; + HashElem *p; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Schema *pSchema = db->aDb[i].pSchema; + if( pSchema ){ + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ + Table *pTab = (Table *)sqliteHashData(p); + if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); + } + } + } + for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ + Module *pMod = (Module *)sqliteHashData(p); + if( pMod->pEpoTab ){ + sqlite3VtabDisconnect(db, pMod->pEpoTab); + } + } + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); +#else + UNUSED_PARAMETER(db); +#endif +} + +/* +** Return TRUE if database connection db has unfinalized prepared +** statements or unfinished sqlite3_backup objects. +*/ +static int connectionIsBusy(sqlite3 *db){ + int j; + assert( sqlite3_mutex_held(db->mutex) ); + if( db->pVdbe ) return 1; + for(j=0; jnDb; j++){ + Btree *pBt = db->aDb[j].pBt; + if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; + } + return 0; +} + +/* +** Close an existing SQLite database +*/ +static int sqlite3Close(sqlite3 *db, int forceZombie){ + if( !db ){ + /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or + ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ + return SQLITE_OK; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + if( db->mTrace & SQLITE_TRACE_CLOSE ){ + db->trace.xV2(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); + } + + /* Force xDisconnect calls on all virtual tables */ + disconnectAllVtab(db); + + /* If a transaction is open, the disconnectAllVtab() call above + ** will not have called the xDisconnect() method on any virtual + ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() + ** call will do so. We need to do this before the check for active + ** SQL statements below, as the v-table implementation may be storing + ** some prepared statements internally. + */ + sqlite3VtabRollback(db); + + /* Legacy behavior (sqlite3_close() behavior) is to return + ** SQLITE_BUSY if the connection can not be closed immediately. + */ + if( !forceZombie && connectionIsBusy(db) ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " + "statements or unfinished backups"); + sqlite3_mutex_leave(db->mutex); + return SQLITE_BUSY; + } + +#ifdef SQLITE_ENABLE_SQLLOG + if( sqlite3GlobalConfig.xSqllog ){ + /* Closing the handle. Fourth parameter is passed the value 2. */ + sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); + } +#endif + + while( db->pDbData ){ + DbClientData *p = db->pDbData; + db->pDbData = p->pNext; + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + sqlite3_free(p); + } + + /* Convert the connection into a zombie and then close it. + */ + db->eOpenState = SQLITE_STATE_ZOMBIE; + sqlite3LeaveMutexAndCloseZombie(db); + return SQLITE_OK; +} + +/* +** Return the transaction state for a single databse, or the maximum +** transaction state over all attached databases if zSchema is null. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3 *db, const char *zSchema){ + int iDb, nDb; + int iTxn = -1; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( zSchema ){ + nDb = iDb = sqlite3FindDbName(db, zSchema); + if( iDb<0 ) nDb--; + }else{ + iDb = 0; + nDb = db->nDb-1; + } + for(; iDb<=nDb; iDb++){ + Btree *pBt = db->aDb[iDb].pBt; + int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE; + if( x>iTxn ) iTxn = x; + } + sqlite3_mutex_leave(db->mutex); + return iTxn; +} + +/* +** Two variations on the public interface for closing a database +** connection. The sqlite3_close() version returns SQLITE_BUSY and +** leaves the connection open if there are unfinalized prepared +** statements or unfinished sqlite3_backups. The sqlite3_close_v2() +** version forces the connection to become a zombie if there are +** unclosed resources, and arranges for deallocation when the last +** prepare statement or sqlite3_backup closes. +*/ +SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } +SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } + + +/* +** Close the mutex on database connection db. +** +** Furthermore, if database connection db is a zombie (meaning that there +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and +** every sqlite3_stmt has now been finalized and every sqlite3_backup has +** finished, then free all resources. +*/ +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ + HashElem *i; /* Hash table iterator */ + int j; + + /* If there are outstanding sqlite3_stmt or sqlite3_backup objects + ** or if the connection has not yet been closed by sqlite3_close_v2(), + ** then just leave the mutex and return. + */ + if( db->eOpenState!=SQLITE_STATE_ZOMBIE || connectionIsBusy(db) ){ + sqlite3_mutex_leave(db->mutex); + return; + } + + /* If we reach this point, it means that the database connection has + ** closed all sqlite3_stmt and sqlite3_backup objects and has been + ** passed to sqlite3_close (meaning that it is a zombie). Therefore, + ** go ahead and free all resources. + */ + + /* If a transaction is open, roll it back. This also ensures that if + ** any database schemas have been modified by an uncommitted transaction + ** they are reset. And that the required b-tree mutex is held to make + ** the pager rollback and schema reset an atomic operation. */ + sqlite3RollbackAll(db, SQLITE_OK); + + /* Free any outstanding Savepoint structures. */ + sqlite3CloseSavepoints(db); + + /* Close all database connections */ + for(j=0; jnDb; j++){ + struct Db *pDb = &db->aDb[j]; + if( pDb->pBt ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + if( j!=1 ){ + pDb->pSchema = 0; + } + } + } + /* Clear the TEMP schema separately and last */ + if( db->aDb[1].pSchema ){ + sqlite3SchemaClear(db->aDb[1].pSchema); + } + sqlite3VtabUnlockList(db); + + /* Free up the array of auxiliary databases */ + sqlite3CollapseDatabaseArray(db); + assert( db->nDb<=2 ); + assert( db->aDb==db->aDbStatic ); + + /* Tell the code in notify.c that the connection no longer holds any + ** locks and does not require any further unlock-notify callbacks. + */ + sqlite3ConnectionClosed(db); + + for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ + FuncDef *pNext, *p; + p = sqliteHashData(i); + do{ + functionDestroy(db, p); + pNext = p->pNext; + sqlite3DbFree(db, p); + p = pNext; + }while( p ); + } + sqlite3HashClear(&db->aFunc); + for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(i); + /* Invoke any destructors registered for collation sequence user data. */ + for(j=0; j<3; j++){ + if( pColl[j].xDel ){ + pColl[j].xDel(pColl[j].pUser); + } + } + sqlite3DbFree(db, pColl); + } + sqlite3HashClear(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ + Module *pMod = (Module *)sqliteHashData(i); + sqlite3VtabEponymousTableClear(db, pMod); + sqlite3VtabModuleUnref(db, pMod); + } + sqlite3HashClear(&db->aModule); +#endif + + sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ + sqlite3ValueFree(db->pErr); + sqlite3CloseExtensions(db); +#if SQLITE_USER_AUTHENTICATION + sqlite3_free(db->auth.zAuthUser); + sqlite3_free(db->auth.zAuthPW); +#endif + + db->eOpenState = SQLITE_STATE_ERROR; + + /* The temp-database schema is allocated differently from the other schema + ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). + ** So it needs to be freed here. Todo: Why not roll the temp schema into + ** the same sqliteMalloc() as the one that allocates the database + ** structure? + */ + sqlite3DbFree(db, db->aDb[1].pSchema); + if( db->xAutovacDestr ){ + db->xAutovacDestr(db->pAutovacPagesArg); + } + sqlite3_mutex_leave(db->mutex); + db->eOpenState = SQLITE_STATE_CLOSED; + sqlite3_mutex_free(db->mutex); + assert( sqlite3LookasideUsed(db,0)==0 ); + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + sqlite3_free(db); +} + +/* +** Rollback all database files. If tripCode is not SQLITE_OK, then +** any write cursors are invalidated ("tripped" - as in "tripping a circuit +** breaker") and made to return tripCode if there are any further +** attempts to use that cursor. Read cursors remain open and valid +** but are "saved" in case the table pages are moved around. +*/ +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ + int i; + int inTrans = 0; + int schemaChange; + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3BeginBenignMalloc(); + + /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). + ** This is important in case the transaction being rolled back has + ** modified the database schema. If the b-tree mutexes are not taken + ** here, then another shared-cache connection might sneak in between + ** the database rollback and schema reset, which can cause false + ** corruption reports in some cases. */ + sqlite3BtreeEnterAll(db); + schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0; + + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){ + inTrans = 1; + } + sqlite3BtreeRollback(p, tripCode, !schemaChange); + } + } + sqlite3VtabRollback(db); + sqlite3EndBenignMalloc(); + + if( schemaChange ){ + sqlite3ExpirePreparedStatements(db, 0); + sqlite3ResetAllSchemasOfConnection(db); + } + sqlite3BtreeLeaveAll(db); + + /* Any deferred constraint violations have now been resolved. */ + db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly); + + /* If one has been configured, invoke the rollback-hook callback */ + if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ + db->xRollbackCallback(db->pRollbackArg); + } +} + +/* +** Return a static string containing the name corresponding to the error code +** specified in the argument. +*/ +#if defined(SQLITE_NEED_ERR_NAME) +SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ + const char *zName = 0; + int i, origRc = rc; + for(i=0; i<2 && zName==0; i++, rc &= 0xff){ + switch( rc ){ + case SQLITE_OK: zName = "SQLITE_OK"; break; + case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; + case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break; + case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; + case SQLITE_PERM: zName = "SQLITE_PERM"; break; + case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; + case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; + case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; + case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; + case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break; + case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; + case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; + case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; + case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; + case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; + case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break; + case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; + case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; + case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break; + case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; + case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; + case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; + case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; + case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; + case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break; + case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break; + case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break; + case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break; + case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break; + case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break; + case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; + case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; + case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; + case SQLITE_IOERR_CHECKRESERVEDLOCK: + zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; + case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; + case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break; + case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break; + case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break; + case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break; + case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break; + case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; + case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; + case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; + case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; + case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; + case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; + case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; + case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; + case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; + case SQLITE_FULL: zName = "SQLITE_FULL"; break; + case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; + case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; + case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; + case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; + case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; + case SQLITE_CANTOPEN_SYMLINK: zName = "SQLITE_CANTOPEN_SYMLINK"; break; + case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; + case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; + case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; + case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; + case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; + case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; + case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; + case SQLITE_CONSTRAINT_FOREIGNKEY: + zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; + case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; + case SQLITE_CONSTRAINT_PRIMARYKEY: + zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; + case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; + case SQLITE_CONSTRAINT_COMMITHOOK: + zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; + case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; + case SQLITE_CONSTRAINT_FUNCTION: + zName = "SQLITE_CONSTRAINT_FUNCTION"; break; + case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break; + case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; + case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; + case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; + case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; + case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; + case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; + case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; + case SQLITE_ROW: zName = "SQLITE_ROW"; break; + case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; + case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; + case SQLITE_NOTICE_RECOVER_ROLLBACK: + zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; + case SQLITE_NOTICE_RBU: zName = "SQLITE_NOTICE_RBU"; break; + case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; + case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; + case SQLITE_DONE: zName = "SQLITE_DONE"; break; + } + } + if( zName==0 ){ + static char zBuf[50]; + sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); + zName = zBuf; + } + return zName; +} +#endif + +/* +** Return a static string that describes the kind of error specified in the +** argument. +*/ +SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ + static const char* const aMsg[] = { + /* SQLITE_OK */ "not an error", + /* SQLITE_ERROR */ "SQL logic error", + /* SQLITE_INTERNAL */ 0, + /* SQLITE_PERM */ "access permission denied", + /* SQLITE_ABORT */ "query aborted", + /* SQLITE_BUSY */ "database is locked", + /* SQLITE_LOCKED */ "database table is locked", + /* SQLITE_NOMEM */ "out of memory", + /* SQLITE_READONLY */ "attempt to write a readonly database", + /* SQLITE_INTERRUPT */ "interrupted", + /* SQLITE_IOERR */ "disk I/O error", + /* SQLITE_CORRUPT */ "database disk image is malformed", + /* SQLITE_NOTFOUND */ "unknown operation", + /* SQLITE_FULL */ "database or disk is full", + /* SQLITE_CANTOPEN */ "unable to open database file", + /* SQLITE_PROTOCOL */ "locking protocol", + /* SQLITE_EMPTY */ 0, + /* SQLITE_SCHEMA */ "database schema has changed", + /* SQLITE_TOOBIG */ "string or blob too big", + /* SQLITE_CONSTRAINT */ "constraint failed", + /* SQLITE_MISMATCH */ "datatype mismatch", + /* SQLITE_MISUSE */ "bad parameter or other API misuse", +#ifdef SQLITE_DISABLE_LFS + /* SQLITE_NOLFS */ "large file support is disabled", +#else + /* SQLITE_NOLFS */ 0, +#endif + /* SQLITE_AUTH */ "authorization denied", + /* SQLITE_FORMAT */ 0, + /* SQLITE_RANGE */ "column index out of range", + /* SQLITE_NOTADB */ "file is not a database", + /* SQLITE_NOTICE */ "notification message", + /* SQLITE_WARNING */ "warning message", + }; + const char *zErr = "unknown error"; + switch( rc ){ + case SQLITE_ABORT_ROLLBACK: { + zErr = "abort due to ROLLBACK"; + break; + } + case SQLITE_ROW: { + zErr = "another row available"; + break; + } + case SQLITE_DONE: { + zErr = "no more rows available"; + break; + } + default: { + rc &= 0xff; + if( ALWAYS(rc>=0) && rcbusyTimeout; + int delay, prior; + + assert( count>=0 ); + if( count < NDELAY ){ + delay = delays[count]; + prior = totals[count]; + }else{ + delay = delays[NDELAY-1]; + prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); + } + if( prior + delay > tmout ){ + delay = tmout - prior; + if( delay<=0 ) return 0; + } + sqlite3OsSleep(db->pVfs, delay*1000); + return 1; +#else + /* This case for unix systems that lack usleep() support. Sleeping + ** must be done in increments of whole seconds */ + sqlite3 *db = (sqlite3 *)ptr; + int tmout = ((sqlite3 *)ptr)->busyTimeout; + if( (count+1)*1000 > tmout ){ + return 0; + } + sqlite3OsSleep(db->pVfs, 1000000); + return 1; +#endif +} + +/* +** Invoke the given busy handler. +** +** This routine is called when an operation failed to acquire a +** lock on VFS file pFile. +** +** If this routine returns non-zero, the lock is retried. If it +** returns 0, the operation aborts with an SQLITE_BUSY error. +*/ +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ + int rc; + if( p->xBusyHandler==0 || p->nBusy<0 ) return 0; + rc = p->xBusyHandler(p->pBusyArg, p->nBusy); + if( rc==0 ){ + p->nBusy = -1; + }else{ + p->nBusy++; + } + return rc; +} + +/* +** This routine sets the busy callback for an Sqlite database to the +** given callback function with the given argument. +*/ +SQLITE_API int sqlite3_busy_handler( + sqlite3 *db, + int (*xBusy)(void*,int), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->busyHandler.xBusyHandler = xBusy; + db->busyHandler.pBusyArg = pArg; + db->busyHandler.nBusy = 0; + db->busyTimeout = 0; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK +/* +** This routine sets the progress callback for an Sqlite database to the +** given callback function with the given argument. The progress callback will +** be invoked every nOps opcodes. +*/ +SQLITE_API void sqlite3_progress_handler( + sqlite3 *db, + int nOps, + int (*xProgress)(void*), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( nOps>0 ){ + db->xProgress = xProgress; + db->nProgressOps = (unsigned)nOps; + db->pProgressArg = pArg; + }else{ + db->xProgress = 0; + db->nProgressOps = 0; + db->pProgressArg = 0; + } + sqlite3_mutex_leave(db->mutex); +} +#endif + + +/* +** This routine installs a default busy handler that waits for the +** specified number of milliseconds before returning 0. +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + if( ms>0 ){ + sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, + (void*)db); + db->busyTimeout = ms; + }else{ + sqlite3_busy_handler(db, 0, 0); + } + return SQLITE_OK; +} + +/* +** Cause any pending operation to stop at its earliest opportunity. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) + && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) + ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + AtomicStore(&db->u1.isInterrupted, 1); +} + +/* +** Return true or false depending on whether or not an interrupt is +** pending on connection db. +*/ +SQLITE_API int sqlite3_is_interrupted(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) + && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) + ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return AtomicLoad(&db->u1.isInterrupted)!=0; +} + +/* +** This function is exactly the same as sqlite3_create_function(), except +** that it is designed to be called by internal code. The difference is +** that if a malloc() fails in sqlite3_create_function(), an error code +** is returned and the mallocFailed flag cleared. +*/ +SQLITE_PRIVATE int sqlite3CreateFunc( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int enc, + void *pUserData, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), + FuncDestructor *pDestructor +){ + FuncDef *p; + int extraFlags; + + assert( sqlite3_mutex_held(db->mutex) ); + assert( xValue==0 || xSFunc==0 ); + if( zFunctionName==0 /* Must have a valid name */ + || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ + || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ + || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ + || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) + || (255funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ + if( db->nVdbeActive ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, + "unable to delete/modify user-function due to active statements"); + assert( !db->mallocFailed ); + return SQLITE_BUSY; + }else{ + sqlite3ExpirePreparedStatements(db, 0); + } + }else if( xSFunc==0 && xFinal==0 ){ + /* Trying to delete a function that does not exist. This is a no-op. + ** https://sqlite.org/forum/forumpost/726219164b */ + return SQLITE_OK; + } + + p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1); + assert(p || db->mallocFailed); + if( !p ){ + return SQLITE_NOMEM_BKPT; + } + + /* If an older version of the function with a configured destructor is + ** being replaced invoke the destructor function here. */ + functionDestroy(db, p); + + if( pDestructor ){ + pDestructor->nRef++; + } + p->u.pDestructor = pDestructor; + p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; + testcase( p->funcFlags & SQLITE_DETERMINISTIC ); + testcase( p->funcFlags & SQLITE_DIRECTONLY ); + p->xSFunc = xSFunc ? xSFunc : xStep; + p->xFinalize = xFinal; + p->xValue = xValue; + p->xInverse = xInverse; + p->pUserData = pUserData; + p->nArg = (u16)nArg; + return SQLITE_OK; +} + +/* +** Worker function used by utf-8 APIs that create new functions: +** +** sqlite3_create_function() +** sqlite3_create_function_v2() +** sqlite3_create_window_function() +*/ +static int createFunctionApi( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +){ + int rc = SQLITE_ERROR; + FuncDestructor *pArg = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( xDestroy ){ + pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor)); + if( !pArg ){ + sqlite3OomFault(db); + xDestroy(p); + goto out; + } + pArg->nRef = 0; + pArg->xDestroy = xDestroy; + pArg->pUserData = p; + } + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, + xSFunc, xStep, xFinal, xValue, xInverse, pArg + ); + if( pArg && pArg->nRef==0 ){ + assert( rc!=SQLITE_OK || (xStep==0 && xFinal==0) ); + xDestroy(p); + sqlite3_free(pArg); + } + + out: + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Create new user functions. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, 0); +} +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, xDestroy); +} +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep, + xFinal, xValue, xInverse, xDestroy); +} + +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +){ + int rc; + char *zFunc8; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); + sqlite3DbFree(db, zFunc8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif + + +/* +** The following is the implementation of an SQL function that always +** fails with an error message stating that the function is used in the +** wrong context. The sqlite3_overload_function() API might construct +** SQL function that use this routine so that the functions will exist +** for name resolution but are actually overloaded by the xFindFunction +** method of virtual tables. +*/ +static void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ + int NotUsed, /* Number of arguments to the function */ + sqlite3_value **NotUsed2 /* Value of each argument */ +){ + const char *zName = (const char*)sqlite3_user_data(context); + char *zErr; + UNUSED_PARAMETER2(NotUsed, NotUsed2); + zErr = sqlite3_mprintf( + "unable to use function %s in the requested context", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); +} + +/* +** Declare that a function has been overloaded by a virtual table. +** +** If the function already exists as a regular global function, then +** this routine is a no-op. If the function does not exist, then create +** a new one that always throws a run-time error. +** +** When virtual tables intend to provide an overloaded function, they +** should call this routine to make sure the global function exists. +** A global function must exist in order for name resolution to work +** properly. +*/ +SQLITE_API int sqlite3_overload_function( + sqlite3 *db, + const char *zName, + int nArg +){ + int rc; + char *zCopy; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; + sqlite3_mutex_leave(db->mutex); + if( rc ) return SQLITE_OK; + zCopy = sqlite3_mprintf("%s", zName); + if( zCopy==0 ) return SQLITE_NOMEM; + return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, + zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); +} + +#ifndef SQLITE_OMIT_TRACE +/* +** Register a trace function. The pArg from the previously registered trace +** is returned. +** +** A NULL trace function means that no tracing is executes. A non-NULL +** trace is a pointer to a function that is invoked at the start of each +** SQL statement. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pTraceArg; + db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0; + db->trace.xLegacy = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +#endif /* SQLITE_OMIT_DEPRECATED */ + +/* Register a trace callback using the version-2 interface. +*/ +SQLITE_API int sqlite3_trace_v2( + sqlite3 *db, /* Trace this connection */ + unsigned mTrace, /* Mask of events to be traced */ + int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */ + void *pArg /* Context */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( mTrace==0 ) xTrace = 0; + if( xTrace==0 ) mTrace = 0; + db->mTrace = mTrace; + db->trace.xV2 = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Register a profile function. The pArg from the previously registered +** profile function is returned. +** +** A NULL profile function means that no profiling is executes. A non-NULL +** profile is a pointer to a function that is invoked at the conclusion of +** each SQL statement that is run. +*/ +SQLITE_API void *sqlite3_profile( + sqlite3 *db, + void (*xProfile)(void*,const char*,sqlite_uint64), + void *pArg +){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pProfileArg; + db->xProfile = xProfile; + db->pProfileArg = pArg; + db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK; + if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +#endif /* SQLITE_OMIT_DEPRECATED */ +#endif /* SQLITE_OMIT_TRACE */ + +/* +** Register a function to be invoked when a transaction commits. +** If the invoked function returns non-zero, then the commit becomes a +** rollback. +*/ +SQLITE_API void *sqlite3_commit_hook( + sqlite3 *db, /* Attach the hook to this database */ + int (*xCallback)(void*), /* Function to invoke on each commit */ + void *pArg /* Argument to the function */ +){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pCommitArg; + db->xCommitCallback = xCallback; + db->pCommitArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} + +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), + void *pArg /* Argument to the function */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pUpdateArg; + db->xUpdateCallback = xCallback; + db->pUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +/* +** Register a callback to be invoked each time a transaction is rolled +** back by this database connection. +*/ +SQLITE_API void *sqlite3_rollback_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*), /* Callback function */ + void *pArg /* Argument to the function */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pRollbackArg; + db->xRollbackCallback = xCallback; + db->pRollbackArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +SQLITE_API void *sqlite3_preupdate_hook( + sqlite3 *db, /* Attach the hook to this database */ + void(*xCallback)( /* Callback function */ + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64), + void *pArg /* First callback argument */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 ){ + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pPreUpdateArg; + db->xPreUpdateCallback = xCallback; + db->pPreUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +/* +** Register a function to be invoked prior to each autovacuum that +** determines the number of pages to vacuum. +*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, /* Attach the hook to this database */ + unsigned int (*xCallback)(void*,const char*,u32,u32,u32), + void *pArg, /* Argument to the function */ + void (*xDestructor)(void*) /* Destructor for pArg */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + if( xDestructor ) xDestructor(pArg); + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( db->xAutovacDestr ){ + db->xAutovacDestr(db->pAutovacPagesArg); + } + db->xAutovacPages = xCallback; + db->pAutovacPagesArg = pArg; + db->xAutovacDestr = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_WAL +/* +** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). +** Invoke sqlite3_wal_checkpoint if the number of frames in the log file +** is greater than sqlite3.pWalArg cast to an integer (the value configured by +** wal_autocheckpoint()). +*/ +SQLITE_PRIVATE int sqlite3WalDefaultHook( + void *pClientData, /* Argument */ + sqlite3 *db, /* Connection */ + const char *zDb, /* Database */ + int nFrame /* Size of WAL */ +){ + if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ + sqlite3BeginBenignMalloc(); + sqlite3_wal_checkpoint(db, zDb); + sqlite3EndBenignMalloc(); + } + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** Configure an sqlite3_wal_hook() callback to automatically checkpoint +** a database after committing a transaction if there are nFrame or +** more frames in the log file. Passing zero or a negative value as the +** nFrame parameter disables automatic checkpoints entirely. +** +** The callback registered by this function replaces any existing callback +** registered using sqlite3_wal_hook(). Likewise, registering a callback +** using sqlite3_wal_hook() disables the automatic checkpoint mechanism +** configured by this function. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(nFrame); +#else +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + if( nFrame>0 ){ + sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); + }else{ + sqlite3_wal_hook(db, 0, 0); + } +#endif + return SQLITE_OK; +} + +/* +** Register a callback to be invoked each time a transaction is written +** into the write-ahead-log by this database connection. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3 *db, /* Attach the hook to this db handle */ + int(*xCallback)(void *, sqlite3*, const char*, int), + void *pArg /* First argument passed to xCallback() */ +){ +#ifndef SQLITE_OMIT_WAL + void *pRet; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pWalArg; + db->xWalCallback = xCallback; + db->pWalArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +#else + return 0; +#endif +} + +/* +** Checkpoint database zDb. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +){ +#ifdef SQLITE_OMIT_WAL + return SQLITE_OK; +#else + int rc; /* Return code */ + int iDb; /* Schema to checkpoint */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + + /* Initialize the output variables to -1 in case an error occurs. */ + if( pnLog ) *pnLog = -1; + if( pnCkpt ) *pnCkpt = -1; + + assert( SQLITE_CHECKPOINT_PASSIVE==0 ); + assert( SQLITE_CHECKPOINT_FULL==1 ); + assert( SQLITE_CHECKPOINT_RESTART==2 ); + assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); + if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ + /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint + ** mode: */ + return SQLITE_MISUSE_BKPT; + } + + sqlite3_mutex_enter(db->mutex); + if( zDb && zDb[0] ){ + iDb = sqlite3FindDbName(db, zDb); + }else{ + iDb = SQLITE_MAX_DB; /* This means process all schemas */ + } + if( iDb<0 ){ + rc = SQLITE_ERROR; + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); + }else{ + db->busyHandler.nBusy = 0; + rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); + sqlite3Error(db, rc); + } + rc = sqlite3ApiExit(db, rc); + + /* If there are no active statements, clear the interrupt flag at this + ** point. */ + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + + sqlite3_mutex_leave(db->mutex); + return rc; +#endif +} + + +/* +** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points +** to contains a zero-length string, all attached databases are +** checkpointed. +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ + /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to + ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ + return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on database iDb. This is a no-op if database iDb is +** not currently open in WAL mode. +** +** If a transaction is open on the database being checkpointed, this +** function returns SQLITE_LOCKED and a checkpoint is not attempted. If +** an error occurs while running the checkpoint, an SQLite error code is +** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. +** +** The mutex on database handle db should be held by the caller. The mutex +** associated with the specific b-tree being checkpointed is taken by +** this function while the checkpoint is running. +** +** If iDb is passed SQLITE_MAX_DB then all attached databases are +** checkpointed. If an error is encountered it is returned immediately - +** no attempt is made to checkpoint any remaining databases. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART +** or TRUNCATE. +*/ +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterate through attached dbs */ + int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ + + assert( sqlite3_mutex_held(db->mutex) ); + assert( !pnLog || *pnLog==-1 ); + assert( !pnCkpt || *pnCkpt==-1 ); + testcase( iDb==SQLITE_MAX_ATTACHED ); /* See forum post a006d86f72 */ + testcase( iDb==SQLITE_MAX_DB ); + + for(i=0; inDb && rc==SQLITE_OK; i++){ + if( i==iDb || iDb==SQLITE_MAX_DB ){ + rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); + pnLog = 0; + pnCkpt = 0; + if( rc==SQLITE_BUSY ){ + bBusy = 1; + rc = SQLITE_OK; + } + } + } + + return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** This function returns true if main-memory should be used instead of +** a temporary file for transient pager files and statement journals. +** The value returned depends on the value of db->temp_store (runtime +** parameter) and the compile time value of SQLITE_TEMP_STORE. The +** following table describes the relationship between these two values +** and this functions return value. +** +** SQLITE_TEMP_STORE db->temp_store Location of temporary database +** ----------------- -------------- ------------------------------ +** 0 any file (return 0) +** 1 1 file (return 0) +** 1 2 memory (return 1) +** 1 0 file (return 0) +** 2 1 file (return 0) +** 2 2 memory (return 1) +** 2 0 memory (return 1) +** 3 any memory (return 1) +*/ +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ +#if SQLITE_TEMP_STORE==1 + return ( db->temp_store==2 ); +#endif +#if SQLITE_TEMP_STORE==2 + return ( db->temp_store!=1 ); +#endif +#if SQLITE_TEMP_STORE==3 + UNUSED_PARAMETER(db); + return 1; +#endif +#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3 + UNUSED_PARAMETER(db); + return 0; +#endif +} + +/* +** Return UTF-8 encoded English language explanation of the most recent +** error. +*/ +SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ + const char *z; + if( !db ){ + return sqlite3ErrStr(SQLITE_NOMEM_BKPT); + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return sqlite3ErrStr(SQLITE_MISUSE_BKPT); + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = sqlite3ErrStr(SQLITE_NOMEM_BKPT); + }else{ + testcase( db->pErr==0 ); + z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0; + assert( !db->mallocFailed ); + if( z==0 ){ + z = sqlite3ErrStr(db->errCode); + } + } + sqlite3_mutex_leave(db->mutex); + return z; +} + +/* +** Return the byte offset of the most recent error +*/ +SQLITE_API int sqlite3_error_offset(sqlite3 *db){ + int iOffset = -1; + if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){ + sqlite3_mutex_enter(db->mutex); + iOffset = db->errByteOffset; + sqlite3_mutex_leave(db->mutex); + } + return iOffset; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Return UTF-16 encoded English language explanation of the most recent +** error. +*/ +SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ + static const u16 outOfMem[] = { + 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 + }; + static const u16 misuse[] = { + 'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ', + 'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ', + 'm', 'i', 's', 'u', 's', 'e', 0 + }; + + const void *z; + if( !db ){ + return (void *)outOfMem; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return (void *)misuse; + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = (void *)outOfMem; + }else{ + z = sqlite3_value_text16(db->pErr); + if( z==0 ){ + sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); + z = sqlite3_value_text16(db->pErr); + } + /* A malloc() may have failed within the call to sqlite3_value_text16() + ** above. If this is the case, then the db->mallocFailed flag needs to + ** be cleared before returning. Do this directly, instead of via + ** sqlite3ApiExit(), to avoid setting the database handle error message. + */ + sqlite3OomClear(db); + } + sqlite3_mutex_leave(db->mutex); + return z; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the most recent error code generated by an SQLite routine. If NULL is +** passed to this function, we assume a malloc() failed during sqlite3_open(). +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( !db || db->mallocFailed ){ + return SQLITE_NOMEM_BKPT; + } + return db->errCode & db->errMask; +} +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( !db || db->mallocFailed ){ + return SQLITE_NOMEM_BKPT; + } + return db->errCode; +} +SQLITE_API int sqlite3_system_errno(sqlite3 *db){ + return db ? db->iSysErrno : 0; +} + +/* +** Return a string that describes the kind of error specified in the +** argument. For now, this simply calls the internal sqlite3ErrStr() +** function. +*/ +SQLITE_API const char *sqlite3_errstr(int rc){ + return sqlite3ErrStr(rc); +} + +/* +** Create a new collating function for database "db". The name is zName +** and the encoding is enc. +*/ +static int createCollation( + sqlite3* db, + const char *zName, + u8 enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + CollSeq *pColl; + int enc2; + + assert( sqlite3_mutex_held(db->mutex) ); + + /* If SQLITE_UTF16 is specified as the encoding type, transform this + ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the + ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. + */ + enc2 = enc; + testcase( enc2==SQLITE_UTF16 ); + testcase( enc2==SQLITE_UTF16_ALIGNED ); + if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){ + enc2 = SQLITE_UTF16NATIVE; + } + if( enc2SQLITE_UTF16BE ){ + return SQLITE_MISUSE_BKPT; + } + + /* Check if this call is removing or replacing an existing collation + ** sequence. If so, and there are active VMs, return busy. If there + ** are no active VMs, invalidate any pre-compiled statements. + */ + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); + if( pColl && pColl->xCmp ){ + if( db->nVdbeActive ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, + "unable to delete/modify collation sequence due to active statements"); + return SQLITE_BUSY; + } + sqlite3ExpirePreparedStatements(db, 0); + + /* If collation sequence pColl was created directly by a call to + ** sqlite3_create_collation, and not generated by synthCollSeq(), + ** then any copies made by synthCollSeq() need to be invalidated. + ** Also, collation destructor - CollSeq.xDel() - function may need + ** to be called. + */ + if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ + CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); + int j; + for(j=0; j<3; j++){ + CollSeq *p = &aColl[j]; + if( p->enc==pColl->enc ){ + if( p->xDel ){ + p->xDel(p->pUser); + } + p->xCmp = 0; + } + } + } + } + + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); + if( pColl==0 ) return SQLITE_NOMEM_BKPT; + pColl->xCmp = xCompare; + pColl->pUser = pCtx; + pColl->xDel = xDel; + pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); + sqlite3Error(db, SQLITE_OK); + return SQLITE_OK; +} + + +/* +** This array defines hard upper bounds on limit values. The +** initializer must be kept in sync with the SQLITE_LIMIT_* +** #defines in sqlite3.h. +*/ +static const int aHardLimit[] = { + SQLITE_MAX_LENGTH, + SQLITE_MAX_SQL_LENGTH, + SQLITE_MAX_COLUMN, + SQLITE_MAX_EXPR_DEPTH, + SQLITE_MAX_COMPOUND_SELECT, + SQLITE_MAX_VDBE_OP, + SQLITE_MAX_FUNCTION_ARG, + SQLITE_MAX_ATTACHED, + SQLITE_MAX_LIKE_PATTERN_LENGTH, + SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ + SQLITE_MAX_TRIGGER_DEPTH, + SQLITE_MAX_WORKER_THREADS, +}; + +/* +** Make sure the hard limits are set to reasonable values +*/ +#if SQLITE_MAX_LENGTH<100 +# error SQLITE_MAX_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH<100 +# error SQLITE_MAX_SQL_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH +# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH +#endif +#if SQLITE_MAX_COMPOUND_SELECT<2 +# error SQLITE_MAX_COMPOUND_SELECT must be at least 2 +#endif +#if SQLITE_MAX_VDBE_OP<40 +# error SQLITE_MAX_VDBE_OP must be at least 40 +#endif +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127 +#endif +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 +# error SQLITE_MAX_ATTACHED must be between 0 and 125 +#endif +#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 +# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 +#endif +#if SQLITE_MAX_COLUMN>32767 +# error SQLITE_MAX_COLUMN must not exceed 32767 +#endif +#if SQLITE_MAX_TRIGGER_DEPTH<1 +# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 +#endif +#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 +# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 +#endif + + +/* +** Change the value of a limit. Report the old value. +** If an invalid limit index is supplied, report -1. +** Make no changes but still report the old value if the +** new limit is negative. +** +** A new lower limit does not shrink existing constructs. +** It merely prevents new constructs that exceed the limit +** from forming. +*/ +SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + int oldLimit; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + + /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME + ** there is a hard upper bound set at compile-time by a C preprocessor + ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to + ** "_MAX_".) + */ + assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); + assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); + assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); + assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); + assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); + assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== + SQLITE_MAX_LIKE_PATTERN_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); + assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) ); + + + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ + return -1; + } + oldLimit = db->aLimit[limitId]; + if( newLimit>=0 ){ /* IMP: R-52476-28732 */ + if( newLimit>aHardLimit[limitId] ){ + newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ + }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ + newLimit = 1; + } + db->aLimit[limitId] = newLimit; + } + return oldLimit; /* IMP: R-53341-35419 */ +} + +/* +** This function is used to parse both URIs and non-URI filenames passed by the +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database +** URIs specified as part of ATTACH statements. +** +** The first argument to this function is the name of the VFS to use (or +** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" +** query parameter. The second argument contains the URI (or non-URI filename) +** itself. When this function is called the *pFlags variable should contain +** the default flags to open the database handle with. The value stored in +** *pFlags may be updated before returning if the URI filename contains +** "cache=xxx" or "mode=xxx" query parameters. +** +** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to +** the VFS that should be used to open the database file. *pzFile is set to +** point to a buffer containing the name of the file to open. The value +** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter() +** and is in the same format as names created using sqlite3_create_filename(). +** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on +** the value returned in *pzFile to avoid a memory leak. +** +** If an error occurs, then an SQLite error code is returned and *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to eventually release +** this buffer by calling sqlite3_free(). +*/ +SQLITE_PRIVATE int sqlite3ParseUri( + const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ + const char *zUri, /* Nul-terminated URI to parse */ + unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + char **pzFile, /* OUT: Filename component of URI */ + char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ +){ + int rc = SQLITE_OK; + unsigned int flags = *pFlags; + const char *zVfs = zDefaultVfs; + char *zFile; + char c; + int nUri = sqlite3Strlen30(zUri); + + assert( *pzErrMsg==0 ); + + if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ + || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */ + && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ + ){ + char *zOpt; + int eState; /* Parser state when parsing URI */ + int iIn; /* Input character index */ + int iOut = 0; /* Output character index */ + u64 nByte = nUri+8; /* Bytes of space to allocate */ + + /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen + ** method that there may be extra parameters following the file-name. */ + flags |= SQLITE_OPEN_URI; + + for(iIn=0; iIn=0 && octet<256 ); + if( octet==0 ){ +#ifndef SQLITE_ENABLE_URI_00_ERROR + /* This branch is taken when "%00" appears within the URI. In this + ** case we ignore all text in the remainder of the path, name or + ** value currently being parsed. So ignore the current character + ** and skip to the next "?", "=" or "&", as appropriate. */ + while( (c = zUri[iIn])!=0 && c!='#' + && (eState!=0 || c!='?') + && (eState!=1 || (c!='=' && c!='&')) + && (eState!=2 || c!='&') + ){ + iIn++; + } + continue; +#else + /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */ + *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri"); + rc = SQLITE_ERROR; + goto parse_uri_out; +#endif + } + c = octet; + }else if( eState==1 && (c=='&' || c=='=') ){ + if( zFile[iOut-1]==0 ){ + /* An empty option name. Ignore this option altogether. */ + while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; + continue; + } + if( c=='&' ){ + zFile[iOut++] = '\0'; + }else{ + eState = 2; + } + c = 0; + }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ + c = 0; + eState = 1; + } + zFile[iOut++] = c; + } + if( eState==1 ) zFile[iOut++] = '\0'; + memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */ + + /* Check if there were any options specified that should be interpreted + ** here. Options that are interpreted here include "vfs" and those that + ** correspond to flags that may be passed to the sqlite3_open_v2() + ** method. */ + zOpt = &zFile[sqlite3Strlen30(zFile)+1]; + while( zOpt[0] ){ + int nOpt = sqlite3Strlen30(zOpt); + char *zVal = &zOpt[nOpt+1]; + int nVal = sqlite3Strlen30(zVal); + + if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ + zVfs = zVal; + }else{ + struct OpenMode { + const char *z; + int mode; + } *aMode = 0; + char *zModeType = 0; + int mask = 0; + int limit = 0; + + if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ + static struct OpenMode aCacheMode[] = { + { "shared", SQLITE_OPEN_SHAREDCACHE }, + { "private", SQLITE_OPEN_PRIVATECACHE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; + aMode = aCacheMode; + limit = mask; + zModeType = "cache"; + } + if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ + static struct OpenMode aOpenMode[] = { + { "ro", SQLITE_OPEN_READONLY }, + { "rw", SQLITE_OPEN_READWRITE }, + { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, + { "memory", SQLITE_OPEN_MEMORY }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; + aMode = aOpenMode; + limit = mask & flags; + zModeType = "access"; + } + + if( aMode ){ + int i; + int mode = 0; + for(i=0; aMode[i].z; i++){ + const char *z = aMode[i].z; + if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ + mode = aMode[i].mode; + break; + } + } + if( mode==0 ){ + *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); + rc = SQLITE_ERROR; + goto parse_uri_out; + } + if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ + *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", + zModeType, zVal); + rc = SQLITE_PERM; + goto parse_uri_out; + } + flags = (flags & ~mask) | mode; + } + } + + zOpt = &zVal[nVal+1]; + } + + }else{ + zFile = sqlite3_malloc64(nUri+8); + if( !zFile ) return SQLITE_NOMEM_BKPT; + memset(zFile, 0, 4); + zFile += 4; + if( nUri ){ + memcpy(zFile, zUri, nUri); + } + memset(zFile+nUri, 0, 4); + flags &= ~SQLITE_OPEN_URI; + } + + *ppVfs = sqlite3_vfs_find(zVfs); + if( *ppVfs==0 ){ + *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); + rc = SQLITE_ERROR; + } + parse_uri_out: + if( rc!=SQLITE_OK ){ + sqlite3_free_filename(zFile); + zFile = 0; + } + *pFlags = flags; + *pzFile = zFile; + return rc; +} + +/* +** This routine does the core work of extracting URI parameters from a +** database filename for the sqlite3_uri_parameter() interface. +*/ +static const char *uriParameter(const char *zFilename, const char *zParam){ + zFilename += sqlite3Strlen30(zFilename) + 1; + while( ALWAYS(zFilename!=0) && zFilename[0] ){ + int x = strcmp(zFilename, zParam); + zFilename += sqlite3Strlen30(zFilename) + 1; + if( x==0 ) return zFilename; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return 0; +} + + + +/* +** This routine does the work of opening a database on behalf of +** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" +** is UTF-8 encoded. +*/ +static int openDatabase( + const char *zFilename, /* Database filename UTF-8 encoded */ + sqlite3 **ppDb, /* OUT: Returned database handle */ + unsigned int flags, /* Operational flags */ + const char *zVfs /* Name of the VFS to use */ +){ + sqlite3 *db; /* Store allocated handle here */ + int rc; /* Return code */ + int isThreadsafe; /* True for threadsafe connections */ + char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ + char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ + int i; /* Loop counter */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppDb==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + + if( sqlite3GlobalConfig.bCoreMutex==0 ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_NOMUTEX ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_FULLMUTEX ){ + isThreadsafe = 1; + }else{ + isThreadsafe = sqlite3GlobalConfig.bFullMutex; + } + + if( flags & SQLITE_OPEN_PRIVATECACHE ){ + flags &= ~SQLITE_OPEN_SHAREDCACHE; + }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ + flags |= SQLITE_OPEN_SHAREDCACHE; + } + + /* Remove harmful bits from the flags parameter + ** + ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were + ** dealt with in the previous code block. Besides these, the only + ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, + ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, + ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved + ** bits. Silently mask off all other flags. + */ + flags &= ~( SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_MAIN_DB | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_SUPER_JOURNAL | + SQLITE_OPEN_NOMUTEX | + SQLITE_OPEN_FULLMUTEX | + SQLITE_OPEN_WAL + ); + + /* Allocate the sqlite data structure */ + db = sqlite3MallocZero( sizeof(sqlite3) ); + if( db==0 ) goto opendb_out; + if( isThreadsafe +#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS + || sqlite3GlobalConfig.bCoreMutex +#endif + ){ + db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( db->mutex==0 ){ + sqlite3_free(db); + db = 0; + goto opendb_out; + } + if( isThreadsafe==0 ){ + sqlite3MutexWarnOnContention(db->mutex); + } + } + sqlite3_mutex_enter(db->mutex); + db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff; + db->nDb = 2; + db->eOpenState = SQLITE_STATE_BUSY; + db->aDb = db->aDbStatic; + db->lookaside.bDisable = 1; + db->lookaside.sz = 0; + + assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); + memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); + db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; + db->autoCommit = 1; + db->nextAutovac = -1; + db->szMmap = sqlite3GlobalConfig.szMmap; + db->nextPagesize = 0; + db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ +#ifdef SQLITE_ENABLE_SORTER_MMAP + /* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map + ** the temporary files used to do external sorts (see code in vdbesort.c) + ** is disabled. It can still be used either by defining + ** SQLITE_ENABLE_SORTER_MMAP at compile time or by using the + ** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */ + db->nMaxSorterMmap = 0x7FFFFFFF; +#endif + db->flags |= SQLITE_ShortColNames + | SQLITE_EnableTrigger + | SQLITE_EnableView + | SQLITE_CacheSpill +#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0 + | SQLITE_TrustedSchema +#endif +/* The SQLITE_DQS compile-time option determines the default settings +** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. +** +** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML +** ---------- ----------------------- ----------------------- +** undefined on on +** 3 on on +** 2 on off +** 1 off on +** 0 off off +** +** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) +** and so that is the default. But developers are encouraged to use +** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible. +*/ +#if !defined(SQLITE_DQS) +# define SQLITE_DQS 3 +#endif +#if (SQLITE_DQS&1)==1 + | SQLITE_DqsDML +#endif +#if (SQLITE_DQS&2)==2 + | SQLITE_DqsDDL +#endif + +#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX + | SQLITE_AutoIndex +#endif +#if SQLITE_DEFAULT_CKPTFULLFSYNC + | SQLITE_CkptFullFSync +#endif +#if SQLITE_DEFAULT_FILE_FORMAT<4 + | SQLITE_LegacyFileFmt +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + | SQLITE_LoadExtension +#endif +#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS + | SQLITE_RecTriggers +#endif +#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS + | SQLITE_ForeignKeys +#endif +#if defined(SQLITE_REVERSE_UNORDERED_SELECTS) + | SQLITE_ReverseOrder +#endif +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + | SQLITE_CellSizeCk +#endif +#if defined(SQLITE_ENABLE_FTS3_TOKENIZER) + | SQLITE_Fts3Tokenizer +#endif +#if defined(SQLITE_ENABLE_QPSG) + | SQLITE_EnableQPSG +#endif +#if defined(SQLITE_DEFAULT_DEFENSIVE) + | SQLITE_Defensive +#endif +#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE) + | SQLITE_LegacyAlter +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) + | SQLITE_StmtScanStatus +#endif + ; + sqlite3HashInit(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3HashInit(&db->aModule); +#endif + + /* Add the default collation sequence BINARY. BINARY works for both UTF-8 + ** and UTF-16, so add a version for each to avoid any unnecessary + ** conversions. The only error that can occur here is a malloc() failure. + ** + ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating + ** functions: + */ + createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); + if( db->mallocFailed ){ + goto opendb_out; + } + +#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) + /* Process magic filenames ":localStorage:" and ":sessionStorage:" */ + if( zFilename && zFilename[0]==':' ){ + if( strcmp(zFilename, ":localStorage:")==0 ){ + zFilename = "file:local?vfs=kvvfs"; + flags |= SQLITE_OPEN_URI; + }else if( strcmp(zFilename, ":sessionStorage:")==0 ){ + zFilename = "file:session?vfs=kvvfs"; + flags |= SQLITE_OPEN_URI; + } + } +#endif /* SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) */ + + /* Parse the filename/URI argument + ** + ** Only allow sensible combinations of bits in the flags argument. + ** Throw an error if any non-sense combination is used. If we + ** do not block illegal combinations here, it could trigger + ** assert() statements in deeper layers. Sensible combinations + ** are: + ** + ** 1: SQLITE_OPEN_READONLY + ** 2: SQLITE_OPEN_READWRITE + ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + */ + db->openFlags = flags; + assert( SQLITE_OPEN_READONLY == 0x01 ); + assert( SQLITE_OPEN_READWRITE == 0x02 ); + assert( SQLITE_OPEN_CREATE == 0x04 ); + testcase( (1<<(flags&7))==0x02 ); /* READONLY */ + testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ + testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ + if( ((1<<(flags&7)) & 0x46)==0 ){ + rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ + }else{ + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + } + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); + sqlite3_free(zErrMsg); + goto opendb_out; + } + assert( db->pVfs!=0 ); +#if SQLITE_OS_KV || defined(SQLITE_OS_KV_OPTIONAL) + if( sqlite3_stricmp(db->pVfs->zName, "kvvfs")==0 ){ + db->temp_store = 2; + } +#endif + + /* Open the backend database driver */ + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + flags | SQLITE_OPEN_MAIN_DB); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3Error(db, rc); + goto opendb_out; + } + sqlite3BtreeEnter(db->aDb[0].pBt); + db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); + if( !db->mallocFailed ){ + sqlite3SetTextEncoding(db, SCHEMA_ENC(db)); + } + sqlite3BtreeLeave(db->aDb[0].pBt); + db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); + + /* The default safety_level for the main database is FULL; for the temp + ** database it is OFF. This matches the pager layer defaults. + */ + db->aDb[0].zDbSName = "main"; + db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; + db->aDb[1].zDbSName = "temp"; + db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; + + db->eOpenState = SQLITE_STATE_OPEN; + if( db->mallocFailed ){ + goto opendb_out; + } + + /* Register all built-in functions, but do not attempt to read the + ** database schema yet. This is delayed until the first time the database + ** is accessed. + */ + sqlite3Error(db, SQLITE_OK); + sqlite3RegisterPerConnectionBuiltinFunctions(db); + rc = sqlite3_errcode(db); + + + /* Load compiled-in extensions */ + for(i=0; rc==SQLITE_OK && imDbFlags |= DBFLAG_InternalFunc; +#endif + + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking + ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking + ** mode. Doing nothing at all also makes NORMAL the default. + */ +#ifdef SQLITE_DEFAULT_LOCKING_MODE + db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), + SQLITE_DEFAULT_LOCKING_MODE); +#endif + + if( rc ) sqlite3Error(db, rc); + + /* Enable the lookaside-malloc subsystem */ + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); + + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + +opendb_out: + if( db ){ + assert( db->mutex!=0 || isThreadsafe==0 + || sqlite3GlobalConfig.bFullMutex==0 ); + sqlite3_mutex_leave(db->mutex); + } + rc = sqlite3_errcode(db); + assert( db!=0 || (rc&0xff)==SQLITE_NOMEM ); + if( (rc&0xff)==SQLITE_NOMEM ){ + sqlite3_close(db); + db = 0; + }else if( rc!=SQLITE_OK ){ + db->eOpenState = SQLITE_STATE_SICK; + } + *ppDb = db; +#ifdef SQLITE_ENABLE_SQLLOG + if( sqlite3GlobalConfig.xSqllog ){ + /* Opening a db handle. Fourth parameter is passed 0. */ + void *pArg = sqlite3GlobalConfig.pSqllogArg; + sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); + } +#endif + sqlite3_free_filename(zOpen); + return rc; +} + + +/* +** Open a new database handle. +*/ +SQLITE_API int sqlite3_open( + const char *zFilename, + sqlite3 **ppDb +){ + return openDatabase(zFilename, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); +} +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +){ + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Open a new database handle. +*/ +SQLITE_API int sqlite3_open16( + const void *zFilename, + sqlite3 **ppDb +){ + char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ + sqlite3_value *pVal; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppDb==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + if( zFilename==0 ) zFilename = "\000\000"; + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zFilename8 ){ + rc = openDatabase(zFilename8, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + assert( *ppDb || rc==SQLITE_NOMEM ); + if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){ + SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE; + } + }else{ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3ValueFree(pVal); + + return rc & 0xff; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0); +} + +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int sqlite3_create_collation_v2( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int sqlite3_create_collation16( + sqlite3* db, + const void *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + int rc = SQLITE_OK; + char *zName8; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); + if( zName8 ){ + rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); + sqlite3DbFree(db, zName8); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = xCollNeeded; + db->xCollNeeded16 = 0; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +SQLITE_API int sqlite3_collation_needed16( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = 0; + db->xCollNeeded16 = xCollNeeded16; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Find existing client data. +*/ +SQLITE_API void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ + DbClientData *p; + sqlite3_mutex_enter(db->mutex); + for(p=db->pDbData; p; p=p->pNext){ + if( strcmp(p->zName, zName)==0 ){ + void *pResult = p->pData; + sqlite3_mutex_leave(db->mutex); + return pResult; + } + } + sqlite3_mutex_leave(db->mutex); + return 0; +} + +/* +** Add new client data to a database connection. +*/ +SQLITE_API int sqlite3_set_clientdata( + sqlite3 *db, /* Attach client data to this connection */ + const char *zName, /* Name of the client data */ + void *pData, /* The client data itself */ + void (*xDestructor)(void*) /* Destructor */ +){ + DbClientData *p, **pp; + sqlite3_mutex_enter(db->mutex); + pp = &db->pDbData; + for(p=db->pDbData; p && strcmp(p->zName,zName); p=p->pNext){ + pp = &p->pNext; + } + if( p ){ + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + if( pData==0 ){ + *pp = p->pNext; + sqlite3_free(p); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } + }else if( pData==0 ){ + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + }else{ + size_t n = strlen(zName); + p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); + if( p==0 ){ + if( xDestructor ) xDestructor(pData); + sqlite3_mutex_leave(db->mutex); + return SQLITE_NOMEM; + } + memcpy(p->zName, zName, n+1); + p->pNext = db->pDbData; + db->pDbData = p; + } + p->pData = pData; + p->xDestructor = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This function is now an anachronism. It used to be used to recover from a +** malloc() failure, but SQLite now does this automatically. +*/ +SQLITE_API int sqlite3_global_recover(void){ + return SQLITE_OK; +} +#endif + +/* +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->autoCommit; +} + +/* +** The following routines are substitutes for constants SQLITE_CORRUPT, +** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error +** constants. They serve two purposes: +** +** 1. Serve as a convenient place to set a breakpoint in a debugger +** to detect when version error conditions occurs. +** +** 2. Invoke sqlite3_log() to provide the source code location where +** a low-level error is first detected. +*/ +SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){ + sqlite3_log(iErr, "%s at line %d of [%.10s]", + zType, lineno, 20+sqlite3_sourceid()); + return iErr; +} +SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption"); +} +SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse"); +} +SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file"); +} +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO) +SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){ + char zMsg[100]; + sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno); + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); +} +#endif +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3NomemError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM"); +} +SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); +} +#endif + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This is a convenience routine that makes sure that all thread-specific +** data for this thread has been deallocated. +** +** SQLite no longer uses thread-specific data so this routine is now a +** no-op. It is retained for historical compatibility. +*/ +SQLITE_API void sqlite3_thread_cleanup(void){ +} +#endif + +/* +** Return meta information about a specific column of a database table. +** See comment in sqlite3.h (sqlite.h.in) for details. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +){ + int rc; + char *zErrMsg = 0; + Table *pTab = 0; + Column *pCol = 0; + int iCol = 0; + char const *zDataType = 0; + char const *zCollSeq = 0; + int notnull = 0; + int primarykey = 0; + int autoinc = 0; + + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + /* Ensure the database schema has been loaded */ + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrMsg); + if( SQLITE_OK!=rc ){ + goto error_out; + } + + /* Locate the table in question */ + pTab = sqlite3FindTable(db, zTableName, zDbName); + if( !pTab || IsView(pTab) ){ + pTab = 0; + goto error_out; + } + + /* Find the column for which info is requested */ + if( zColumnName==0 ){ + /* Query for existence of table only */ + }else{ + for(iCol=0; iColnCol; iCol++){ + pCol = &pTab->aCol[iCol]; + if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){ + break; + } + } + if( iCol==pTab->nCol ){ + if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ + iCol = pTab->iPKey; + pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; + }else{ + pTab = 0; + goto error_out; + } + } + } + + /* The following block stores the meta information that will be returned + ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey + ** and autoinc. At this point there are two possibilities: + ** + ** 1. The specified column name was rowid", "oid" or "_rowid_" + ** and there is no explicitly declared IPK column. + ** + ** 2. The table is not a view and the column name identified an + ** explicitly declared column. Copy meta information from *pCol. + */ + if( pCol ){ + zDataType = sqlite3ColumnType(pCol,0); + zCollSeq = sqlite3ColumnColl(pCol); + notnull = pCol->notNull!=0; + primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; + autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; + }else{ + zDataType = "INTEGER"; + primarykey = 1; + } + if( !zCollSeq ){ + zCollSeq = sqlite3StrBINARY; + } + +error_out: + sqlite3BtreeLeaveAll(db); + + /* Whether the function call succeeded or failed, set the output parameters + ** to whatever their local counterparts contain. If an error did occur, + ** this has the effect of zeroing all output parameters. + */ + if( pzDataType ) *pzDataType = zDataType; + if( pzCollSeq ) *pzCollSeq = zCollSeq; + if( pNotNull ) *pNotNull = notnull; + if( pPrimaryKey ) *pPrimaryKey = primarykey; + if( pAutoinc ) *pAutoinc = autoinc; + + if( SQLITE_OK==rc && !pTab ){ + sqlite3DbFree(db, zErrMsg); + zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, + zColumnName); + rc = SQLITE_ERROR; + } + sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); + sqlite3DbFree(db, zErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +SQLITE_API int sqlite3_sleep(int ms){ + sqlite3_vfs *pVfs; + int rc; + pVfs = sqlite3_vfs_find(0); + if( pVfs==0 ) return 0; + + /* This function works in milliseconds, but the underlying OsSleep() + ** API uses microseconds. Hence the 1000's. + */ + rc = (sqlite3OsSleep(pVfs, ms<0 ? 0 : 1000*ms)/1000); + return rc; +} + +/* +** Enable or disable the extended result codes. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->errMask = onoff ? 0xffffffff : 0xff; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Invoke the xFileControl method on a particular database. +*/ +SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ + int rc = SQLITE_ERROR; + Btree *pBtree; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + pBtree = sqlite3DbNameToBtree(db, zDbName); + if( pBtree ){ + Pager *pPager; + sqlite3_file *fd; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + fd = sqlite3PagerFile(pPager); + assert( fd!=0 ); + if( op==SQLITE_FCNTL_FILE_POINTER ){ + *(sqlite3_file**)pArg = fd; + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_VFS_POINTER ){ + *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager); + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ + *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_DATA_VERSION ){ + *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){ + int iNew = *(int*)pArg; + *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree); + if( iNew>=0 && iNew<=255 ){ + sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0); + } + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_RESET_CACHE ){ + sqlite3BtreeClearCache(pBtree); + rc = SQLITE_OK; + }else{ + int nSave = db->busyHandler.nBusy; + rc = sqlite3OsFileControl(fd, op, pArg); + db->busyHandler.nBusy = nSave; + } + sqlite3BtreeLeave(pBtree); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Interface to the testing logic. +*/ +SQLITE_API int sqlite3_test_control(int op, ...){ + int rc = 0; +#ifdef SQLITE_UNTESTABLE + UNUSED_PARAMETER(op); +#else + va_list ap; + va_start(ap, op); + switch( op ){ + + /* + ** Save the current state of the PRNG. + */ + case SQLITE_TESTCTRL_PRNG_SAVE: { + sqlite3PrngSaveState(); + break; + } + + /* + ** Restore the state of the PRNG to the last state saved using + ** PRNG_SAVE. If PRNG_SAVE has never before been called, then + ** this verb acts like PRNG_RESET. + */ + case SQLITE_TESTCTRL_PRNG_RESTORE: { + sqlite3PrngRestoreState(); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db); + ** + ** Control the seed for the pseudo-random number generator (PRNG) that + ** is built into SQLite. Cases: + ** + ** x!=0 && db!=0 Seed the PRNG to the current value of the + ** schema cookie in the main database for db, or + ** x if the schema cookie is zero. This case + ** is convenient to use with database fuzzers + ** as it allows the fuzzer some control over the + ** the PRNG seed. + ** + ** x!=0 && db==0 Seed the PRNG to the value of x. + ** + ** x==0 && db==0 Revert to default behavior of using the + ** xRandomness method on the primary VFS. + ** + ** This test-control also resets the PRNG so that the new seed will + ** be used for the next call to sqlite3_randomness(). + */ +#ifndef SQLITE_OMIT_WSD + case SQLITE_TESTCTRL_PRNG_SEED: { + int x = va_arg(ap, int); + int y; + sqlite3 *db = va_arg(ap, sqlite3*); + assert( db==0 || db->aDb[0].pSchema!=0 ); + if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; } + sqlite3Config.iPrngSeed = x; + sqlite3_randomness(0,0); + break; + } +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); + ** + ** If b is true, then activate the SQLITE_FkNoAction setting. If b is + ** false then clearn that setting. If the SQLITE_FkNoAction setting is + ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if + ** they were NO ACTION, regardless of how they are defined. + ** + ** NB: One must usually run "PRAGMA writable_schema=RESET" after + ** using this test-control, before it will take full effect. failing + ** to reset the schema can result in some unexpected behavior. + */ + case SQLITE_TESTCTRL_FK_NO_ACTION: { + sqlite3 *db = va_arg(ap, sqlite3*); + int b = va_arg(ap, int); + if( b ){ + db->flags |= SQLITE_FkNoAction; + }else{ + db->flags &= ~SQLITE_FkNoAction; + } + break; + } + + /* + ** sqlite3_test_control(BITVEC_TEST, size, program) + ** + ** Run a test against a Bitvec object of size. The program argument + ** is an array of integers that defines the test. Return -1 on a + ** memory allocation error, 0 on success, or non-zero for an error. + ** See the sqlite3BitvecBuiltinTest() for additional information. + */ + case SQLITE_TESTCTRL_BITVEC_TEST: { + int sz = va_arg(ap, int); + int *aProg = va_arg(ap, int*); + rc = sqlite3BitvecBuiltinTest(sz, aProg); + break; + } + + /* + ** sqlite3_test_control(FAULT_INSTALL, xCallback) + ** + ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, + ** if xCallback is not NULL. + ** + ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) + ** is called immediately after installing the new callback and the return + ** value from sqlite3FaultSim(0) becomes the return from + ** sqlite3_test_control(). + */ + case SQLITE_TESTCTRL_FAULT_INSTALL: { + /* A bug in MSVC prevents it from understanding pointers to functions + ** types in the second argument to va_arg(). Work around the problem + ** using a typedef. + ** http://support.microsoft.com/kb/47961 <-- dead hyperlink + ** Search at http://web.archive.org/ to find the 2015-03-16 archive + ** of the link above to see the original text. + ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); + */ + typedef int(*sqlite3FaultFuncType)(int); + sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType); + rc = sqlite3FaultSim(0); + break; + } + + /* + ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) + ** + ** Register hooks to call to indicate which malloc() failures + ** are benign. + */ + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { + typedef void (*void_function)(void); + void_function xBenignBegin; + void_function xBenignEnd; + xBenignBegin = va_arg(ap, void_function); + xBenignEnd = va_arg(ap, void_function); + sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) + ** + ** Set the PENDING byte to the value in the argument, if X>0. + ** Make no changes if X==0. Return the value of the pending byte + ** as it existing before this routine was called. + ** + ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in + ** an incompatible database file format. Changing the PENDING byte + ** while any database connection is open results in undefined and + ** deleterious behavior. + */ + case SQLITE_TESTCTRL_PENDING_BYTE: { + rc = PENDING_BYTE; +#ifndef SQLITE_OMIT_WSD + { + unsigned int newVal = va_arg(ap, unsigned int); + if( newVal ) sqlite3PendingByte = newVal; + } +#endif + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) + ** + ** This action provides a run-time test to see whether or not + ** assert() was enabled at compile-time. If X is true and assert() + ** is enabled, then the return value is true. If X is true and + ** assert() is disabled, then the return value is zero. If X is + ** false and assert() is enabled, then the assertion fires and the + ** process aborts. If X is false and assert() is disabled, then the + ** return value is zero. + */ + case SQLITE_TESTCTRL_ASSERT: { + volatile int x = 0; + assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); + rc = x; +#if defined(SQLITE_DEBUG) + /* Invoke these debugging routines so that the compiler does not + ** issue "defined but not used" warnings. */ + if( x==9999 ){ + sqlite3ShowExpr(0); + sqlite3ShowExpr(0); + sqlite3ShowExprList(0); + sqlite3ShowIdList(0); + sqlite3ShowSrcList(0); + sqlite3ShowWith(0); + sqlite3ShowUpsert(0); +#ifndef SQLITE_OMIT_TRIGGER + sqlite3ShowTriggerStep(0); + sqlite3ShowTriggerStepList(0); + sqlite3ShowTrigger(0); + sqlite3ShowTriggerList(0); +#endif +#ifndef SQLITE_OMIT_WINDOWFUNC + sqlite3ShowWindow(0); + sqlite3ShowWinFunc(0); +#endif + sqlite3ShowSelect(0); + } +#endif + break; + } + + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) + ** + ** This action provides a run-time test to see how the ALWAYS and + ** NEVER macros were defined at compile-time. + ** + ** The return value is ALWAYS(X) if X is true, or 0 if X is false. + ** + ** The recommended test is X==2. If the return value is 2, that means + ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the + ** default setting. If the return value is 1, then ALWAYS() is either + ** hard-coded to true or else it asserts if its argument is false. + ** The first behavior (hard-coded to true) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second + ** behavior (assert if the argument to ALWAYS() is false) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled. + ** + ** The run-time test procedure might look something like this: + ** + ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ + ** // ALWAYS() and NEVER() are no-op pass-through macros + ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ + ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false. + ** }else{ + ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0. + ** } + */ + case SQLITE_TESTCTRL_ALWAYS: { + int x = va_arg(ap,int); + rc = x ? ALWAYS(x) : 0; + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); + ** + ** The integer returned reveals the byte-order of the computer on which + ** SQLite is running: + ** + ** 1 big-endian, determined at run-time + ** 10 little-endian, determined at run-time + ** 432101 big-endian, determined at compile-time + ** 123410 little-endian, determined at compile-time + */ + case SQLITE_TESTCTRL_BYTEORDER: { + rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) + ** + ** Enable or disable various optimizations for testing purposes. The + ** argument N is a bitmask of optimizations to be disabled. For normal + ** operation N should be 0. The idea is that a test program (like the + ** SQL Logic Test or SLT test module) can run the same SQL multiple times + ** with various optimizations disabled to verify that the same answer + ** is obtained in every case. + */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->dbOptFlags = va_arg(ap, u32); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); + ** + ** If parameter onoff is 1, subsequent calls to localtime() fail. + ** If 2, then invoke xAlt() instead of localtime(). If 0, normal + ** processing. + ** + ** xAlt arguments are void pointers, but they really want to be: + ** + ** int xAlt(const time_t*, struct tm*); + ** + ** xAlt should write results in to struct tm object of its 2nd argument + ** and return zero on success, or return non-zero on failure. + */ + case SQLITE_TESTCTRL_LOCALTIME_FAULT: { + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + if( sqlite3GlobalConfig.bLocaltimeFault==2 ){ + typedef int(*sqlite3LocaltimeType)(const void*,void*); + sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType); + }else{ + sqlite3GlobalConfig.xAltLocaltime = 0; + } + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*); + ** + ** Toggle the ability to use internal functions on or off for + ** the database connection given in the argument. + */ + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->mDbFlags ^= DBFLAG_InternalFunc; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); + ** + ** Set or clear a flag that indicates that the database file is always well- + ** formed and never corrupt. This flag is clear by default, indicating that + ** database files might have arbitrary corruption. Setting the flag during + ** testing causes certain assert() statements in the code to be activated + ** that demonstrate invariants on well-formed database files. + */ + case SQLITE_TESTCTRL_NEVER_CORRUPT: { + sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int); + ** + ** Set or clear a flag that causes SQLite to verify that type, name, + ** and tbl_name fields of the sqlite_schema table. This is normally + ** on, but it is sometimes useful to turn it off for testing. + ** + ** 2020-07-22: Disabling EXTRA_SCHEMA_CHECKS also disables the + ** verification of rootpage numbers when parsing the schema. This + ** is useful to make it easier to reach strange internal error states + ** during testing. The EXTRA_SCHEMA_CHECKS setting is always enabled + ** in production. + */ + case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: { + sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int); + break; + } + + /* Set the threshold at which OP_Once counters reset back to zero. + ** By default this is 0x7ffffffe (over 2 billion), but that value is + ** too big to test in a reasonable amount of time, so this control is + ** provided to set a small and easily reachable reset value. + */ + case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { + sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); + ** + ** Set the VDBE coverage callback function to xCallback with context + ** pointer ptr. + */ + case SQLITE_TESTCTRL_VDBE_COVERAGE: { +#ifdef SQLITE_VDBE_COVERAGE + typedef void (*branch_callback)(void*,unsigned int, + unsigned char,unsigned char); + sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); + sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); +#endif + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ + case SQLITE_TESTCTRL_SORTER_MMAP: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->nMaxSorterMmap = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); + ** + ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if + ** not. + */ + case SQLITE_TESTCTRL_ISINIT: { + if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); + ** + ** This test control is used to create imposter tables. "db" is a pointer + ** to the database connection. dbName is the database name (ex: "main" or + ** "temp") which will receive the imposter. "onOff" turns imposter mode on + ** or off. "tnum" is the root page of the b-tree to which the imposter + ** table should connect. + ** + ** Enable imposter mode only when the schema has already been parsed. Then + ** run a single CREATE TABLE statement to construct the imposter table in + ** the parsed schema. Then turn imposter mode back off again. + ** + ** If onOff==0 and tnum>0 then reset the schema for all databases, causing + ** the schema to be reparsed the next time it is needed. This has the + ** effect of erasing all imposter tables. + */ + case SQLITE_TESTCTRL_IMPOSTER: { + sqlite3 *db = va_arg(ap, sqlite3*); + int iDb; + sqlite3_mutex_enter(db->mutex); + iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); + if( iDb>=0 ){ + db->init.iDb = iDb; + db->init.busy = db->init.imposterTable = va_arg(ap,int); + db->init.newTnum = va_arg(ap,int); + if( db->init.busy==0 && db->init.newTnum>0 ){ + sqlite3ResetAllSchemasOfConnection(db); + } + } + sqlite3_mutex_leave(db->mutex); + break; + } + +#if defined(YYCOVERAGE) + /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out) + ** + ** This test control (only available when SQLite is compiled with + ** -DYYCOVERAGE) writes a report onto "out" that shows all + ** state/lookahead combinations in the parser state machine + ** which are never exercised. If any state is missed, make the + ** return code SQLITE_ERROR. + */ + case SQLITE_TESTCTRL_PARSER_COVERAGE: { + FILE *out = va_arg(ap, FILE*); + if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; + break; + } +#endif /* defined(YYCOVERAGE) */ + + /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*); + ** + ** This test-control causes the most recent sqlite3_result_int64() value + ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally, + ** MEM_IntReal values only arise during an INSERT operation of integer + ** values into a REAL column, so they can be challenging to test. This + ** test-control enables us to write an intreal() SQL function that can + ** inject an intreal() value at arbitrary places in an SQL statement, + ** for testing purposes. + */ + case SQLITE_TESTCTRL_RESULT_INTREAL: { + sqlite3_context *pCtx = va_arg(ap, sqlite3_context*); + sqlite3ResultIntReal(pCtx); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT, + ** sqlite3 *db, // Database connection + ** u64 *pnSeek // Write seek count here + ** ); + ** + ** This test-control queries the seek-counter on the "main" database + ** file. The seek-counter is written into *pnSeek and is then reset. + ** The seek-count is only available if compiled with SQLITE_DEBUG. + */ + case SQLITE_TESTCTRL_SEEK_COUNT: { + sqlite3 *db = va_arg(ap, sqlite3*); + u64 *pn = va_arg(ap, sqlite3_uint64*); + *pn = sqlite3BtreeSeekCount(db->aDb->pBt); + (void)db; /* Silence harmless unused variable warning */ + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) + ** + ** "ptr" is a pointer to a u32. + ** + ** op==0 Store the current sqlite3TreeTrace in *ptr + ** op==1 Set sqlite3TreeTrace to the value *ptr + ** op==2 Store the current sqlite3WhereTrace in *ptr + ** op==3 Set sqlite3WhereTrace to the value *ptr + */ + case SQLITE_TESTCTRL_TRACEFLAGS: { + int opTrace = va_arg(ap, int); + u32 *ptr = va_arg(ap, u32*); + switch( opTrace ){ + case 0: *ptr = sqlite3TreeTrace; break; + case 1: sqlite3TreeTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; + } + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST, + ** double fIn, // Input value + ** int *pLogEst, // sqlite3LogEstFromDouble(fIn) + ** u64 *pInt, // sqlite3LogEstToInt(*pLogEst) + ** int *pLogEst2 // sqlite3LogEst(*pInt) + ** ); + ** + ** Test access for the LogEst conversion routines. + */ + case SQLITE_TESTCTRL_LOGEST: { + double rIn = va_arg(ap, double); + LogEst rLogEst = sqlite3LogEstFromDouble(rIn); + int *pI1 = va_arg(ap,int*); + u64 *pU64 = va_arg(ap,u64*); + int *pI2 = va_arg(ap,int*); + *pI1 = rLogEst; + *pU64 = sqlite3LogEstToInt(rLogEst); + *pI2 = sqlite3LogEst(*pU64); + break; + } + +#if !defined(SQLITE_OMIT_WSD) + /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); + ** + ** X<0 Make no changes to the bUseLongDouble. Just report value. + ** X==0 Disable bUseLongDouble + ** X==1 Enable bUseLongDouble + ** X>=2 Set bUseLongDouble to its default value for this platform + */ + case SQLITE_TESTCTRL_USELONGDOUBLE: { + int b = va_arg(ap, int); + if( b>=2 ) b = hasHighPrecisionDouble(b); + if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; + rc = sqlite3Config.bUseLongDouble!=0; + break; + } +#endif + + +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) + ** + ** If "id" is an integer between 1 and SQLITE_NTUNE then set the value + ** of the id-th tuning parameter to *piValue. If "id" is between -1 + ** and -SQLITE_NTUNE, then write the current value of the (-id)-th + ** tuning parameter into *piValue. + ** + ** Tuning parameters are for use during transient development builds, + ** to help find the best values for constants in the query planner. + ** Access tuning parameters using the Tuning(ID) macro. Set the + ** parameters in the CLI using ".testctrl tune ID VALUE". + ** + ** Transient use only. Tuning parameters should not be used in + ** checked-in code. + */ + case SQLITE_TESTCTRL_TUNE: { + int id = va_arg(ap, int); + int *piValue = va_arg(ap, int*); + if( id>0 && id<=SQLITE_NTUNE ){ + Tuning(id) = *piValue; + }else if( id<0 && id>=-SQLITE_NTUNE ){ + *piValue = Tuning(-id); + }else{ + rc = SQLITE_NOTFOUND; + } + break; + } +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff); + ** + ** Activate or deactivate validation of JSONB that is generated from + ** text. Off by default, as the validation is slow. Validation is + ** only available if compiled using SQLITE_DEBUG. + ** + ** If onOff is initially 1, then turn it on. If onOff is initially + ** off, turn it off. If onOff is initially -1, then change onOff + ** to be the current setting. + */ + case SQLITE_TESTCTRL_JSON_SELFCHECK: { +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + int *pOnOff = va_arg(ap, int*); + if( *pOnOff<0 ){ + *pOnOff = sqlite3Config.bJsonSelfcheck; + }else{ + sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff); + } +#endif + break; + } + } + va_end(ap); +#endif /* SQLITE_UNTESTABLE */ + return rc; +} + +/* +** The Pager stores the Database filename, Journal filename, and WAL filename +** consecutively in memory, in that order. The database filename is prefixed +** by four zero bytes. Locate the start of the database filename by searching +** backwards for the first byte following four consecutive zero bytes. +** +** This only works if the filename passed in was obtained from the Pager. +*/ +static const char *databaseName(const char *zName){ + while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ + zName--; + } + return zName; +} + +/* +** Append text z[] to the end of p[]. Return a pointer to the first +** character after then zero terminator on the new text in p[]. +*/ +static char *appendText(char *p, const char *z){ + size_t n = strlen(z); + memcpy(p, z, n+1); + return p+n+1; +} + +/* +** Allocate memory to hold names for a database, journal file, WAL file, +** and query parameters. The pointer returned is valid for use by +** sqlite3_filename_database() and sqlite3_uri_parameter() and related +** functions. +** +** Memory layout must be compatible with that generated by the pager +** and expected by sqlite3_uri_parameter() and databaseName(). +*/ +SQLITE_API const char *sqlite3_create_filename( + const char *zDatabase, + const char *zJournal, + const char *zWal, + int nParam, + const char **azParam +){ + sqlite3_int64 nByte; + int i; + char *pResult, *p; + nByte = strlen(zDatabase) + strlen(zJournal) + strlen(zWal) + 10; + for(i=0; i0 ){ + zFilename += sqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return zFilename[0] ? zFilename : 0; +} + +/* +** Return a boolean value for a query parameter. +*/ +SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + bDflt = bDflt!=0; + return z ? sqlite3GetBoolean(z, bDflt) : bDflt; +} + +/* +** Return a 64-bit integer value for a query parameter. +*/ +SQLITE_API sqlite3_int64 sqlite3_uri_int64( + const char *zFilename, /* Filename as passed to xOpen */ + const char *zParam, /* URI parameter sought */ + sqlite3_int64 bDflt /* return if parameter is missing */ +){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3DecOrHexToI64(z, &v)==0 ){ + bDflt = v; + } + return bDflt; +} + +/* +** Translate a filename that was handed to a VFS routine into the corresponding +** database, journal, or WAL file. +** +** It is an error to pass this routine a filename string that was not +** passed into the VFS from the SQLite core. Doing so is similar to +** passing free() a pointer that was not obtained from malloc() - it is +** an error that we cannot easily detect but that will likely cause memory +** corruption. +*/ +SQLITE_API const char *sqlite3_filename_database(const char *zFilename){ + if( zFilename==0 ) return 0; + return databaseName(zFilename); +} +SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ + if( zFilename==0 ) return 0; + zFilename = databaseName(zFilename); + zFilename += sqlite3Strlen30(zFilename) + 1; + while( ALWAYS(zFilename) && zFilename[0] ){ + zFilename += sqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return zFilename + 1; +} +SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){ +#ifdef SQLITE_OMIT_WAL + return 0; +#else + zFilename = sqlite3_filename_journal(zFilename); + if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1; + return zFilename; +#endif +} + +/* +** Return the Btree pointer identified by zDbName. Return NULL if not found. +*/ +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ + int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0; + return iDb<0 ? 0 : db->aDb[iDb].pBt; +} + +/* +** Return the name of the N-th database schema. Return NULL if N is out +** of range. +*/ +SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + if( N<0 || N>=db->nDb ){ + return 0; + }else{ + return db->aDb[N].zDbSName; + } +} + +/* +** Return the filename of the database associated with a database +** connection. +*/ +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ + Btree *pBt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeGetFilename(pBt) : 0; +} + +/* +** Return 1 if database is read-only or 0 if read/write. Return -1 if +** no such database exists. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ + Btree *pBt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; +} + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** Obtain a snapshot handle for the snapshot of database zDb currently +** being read by handle db. +*/ +SQLITE_API int sqlite3_snapshot_get( + sqlite3 *db, + const char *zDb, + sqlite3_snapshot **ppSnapshot +){ + int rc = SQLITE_ERROR; +#ifndef SQLITE_OMIT_WAL + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + + if( db->autoCommit==0 ){ + int iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); + } + } + } + } + + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + +/* +** Open a read-transaction on the snapshot identified by pSnapshot. +*/ +SQLITE_API int sqlite3_snapshot_open( + sqlite3 *db, + const char *zDb, + sqlite3_snapshot *pSnapshot +){ + int rc = SQLITE_ERROR; +#ifndef SQLITE_OMIT_WAL + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( db->autoCommit==0 ){ + int iDb; + iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){ + Pager *pPager = sqlite3BtreePager(pBt); + int bUnlock = 0; + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){ + if( db->nVdbeActive==0 ){ + rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); + if( rc==SQLITE_OK ){ + bUnlock = 1; + rc = sqlite3BtreeCommit(pBt); + } + } + }else{ + rc = SQLITE_OK; + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot); + } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); + } + if( bUnlock ){ + sqlite3PagerSnapshotUnlock(pPager); + } + } + } + } + + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + +/* +** Recover as many snapshots as possible from the wal file associated with +** schema zDb of database db. +*/ +SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ + int rc = SQLITE_ERROR; +#ifndef SQLITE_OMIT_WAL + int iDb; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + sqlite3_mutex_enter(db->mutex); + iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); + sqlite3BtreeCommit(pBt); + } + } + } + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + +/* +** Free a snapshot handle obtained from sqlite3_snapshot_get(). +*/ +SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){ + sqlite3_free(pSnapshot); +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +/* +** Given the name of a compile-time option, return true if that option +** was used and false if not. +** +** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix +** is not required for a match. +*/ +SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ + int i, n; + int nOpt; + const char **azCompileOpt; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zOptName==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + azCompileOpt = sqlite3CompileOptions(&nOpt); + + if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; + n = sqlite3Strlen30(zOptName); + + /* Since nOpt is normally in single digits, a linear search is + ** adequate. No need for a binary search. */ + for(i=0; i=0 && NpNextBlocked){ + int seen = 0; + sqlite3 *p2; + + /* Verify property (1) */ + assert( p->pUnlockConnection || p->pBlockingConnection ); + + /* Verify property (2) */ + for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ + if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; + assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); + assert( db==0 || p->pUnlockConnection!=db ); + assert( db==0 || p->pBlockingConnection!=db ); + } + } +} +#else +# define checkListProperties(x) +#endif + +/* +** Remove connection db from the blocked connections list. If connection +** db is not currently a part of the list, this function is a no-op. +*/ +static void removeFromBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ + if( *pp==db ){ + *pp = (*pp)->pNextBlocked; + break; + } + } +} + +/* +** Add connection db to the blocked connections list. It is assumed +** that it is not already a part of the list. +*/ +static void addToBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for( + pp=&sqlite3BlockedList; + *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; + pp=&(*pp)->pNextBlocked + ); + db->pNextBlocked = *pp; + *pp = db; +} + +/* +** Obtain the STATIC_MAIN mutex. +*/ +static void enterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)); + checkListProperties(0); +} + +/* +** Release the STATIC_MAIN mutex. +*/ +static void leaveMutex(void){ + assertMutexHeld(); + checkListProperties(0); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)); +} + +/* +** Register an unlock-notify callback. +** +** This is called after connection "db" has attempted some operation +** but has received an SQLITE_LOCKED error because another connection +** (call it pOther) in the same process was busy using the same shared +** cache. pOther is found by looking at db->pBlockingConnection. +** +** If there is no blocking connection, the callback is invoked immediately, +** before this routine returns. +** +** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate +** a deadlock. +** +** Otherwise, make arrangements to invoke xNotify when pOther drops +** its locks. +** +** Each call to this routine overrides any prior callbacks registered +** on the same "db". If xNotify==0 then any prior callbacks are immediately +** cancelled. +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *db, + void (*xNotify)(void **, int), + void *pArg +){ + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + enterMutex(); + + if( xNotify==0 ){ + removeFromBlockedList(db); + db->pBlockingConnection = 0; + db->pUnlockConnection = 0; + db->xUnlockNotify = 0; + db->pUnlockArg = 0; + }else if( 0==db->pBlockingConnection ){ + /* The blocking transaction has been concluded. Or there never was a + ** blocking transaction. In either case, invoke the notify callback + ** immediately. + */ + xNotify(&pArg, 1); + }else{ + sqlite3 *p; + + for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){} + if( p ){ + rc = SQLITE_LOCKED; /* Deadlock detected. */ + }else{ + db->pUnlockConnection = db->pBlockingConnection; + db->xUnlockNotify = xNotify; + db->pUnlockArg = pArg; + removeFromBlockedList(db); + addToBlockedList(db); + } + } + + leaveMutex(); + assert( !db->mallocFailed ); + sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is called while stepping or preparing a statement +** associated with connection db. The operation will return SQLITE_LOCKED +** to the user because it requires a lock that will not be available +** until connection pBlocker concludes its current transaction. +*/ +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ + enterMutex(); + if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){ + addToBlockedList(db); + } + db->pBlockingConnection = pBlocker; + leaveMutex(); +} + +/* +** This function is called when +** the transaction opened by database db has just finished. Locks held +** by database connection db have been released. +** +** This function loops through each entry in the blocked connections +** list and does the following: +** +** 1) If the sqlite3.pBlockingConnection member of a list entry is +** set to db, then set pBlockingConnection=0. +** +** 2) If the sqlite3.pUnlockConnection member of a list entry is +** set to db, then invoke the configured unlock-notify callback and +** set pUnlockConnection=0. +** +** 3) If the two steps above mean that pBlockingConnection==0 and +** pUnlockConnection==0, remove the entry from the blocked connections +** list. +*/ +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ + void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */ + int nArg = 0; /* Number of entries in aArg[] */ + sqlite3 **pp; /* Iterator variable */ + void **aArg; /* Arguments to the unlock callback */ + void **aDyn = 0; /* Dynamically allocated space for aArg[] */ + void *aStatic[16]; /* Starter space for aArg[]. No malloc required */ + + aArg = aStatic; + enterMutex(); /* Enter STATIC_MAIN mutex */ + + /* This loop runs once for each entry in the blocked-connections list. */ + for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){ + sqlite3 *p = *pp; + + /* Step 1. */ + if( p->pBlockingConnection==db ){ + p->pBlockingConnection = 0; + } + + /* Step 2. */ + if( p->pUnlockConnection==db ){ + assert( p->xUnlockNotify ); + if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + + sqlite3BeginBenignMalloc(); + assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); + assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); + if( (!aDyn && nArg==(int)ArraySize(aStatic)) + || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) + ){ + /* The aArg[] array needs to grow. */ + void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); + if( pNew ){ + memcpy(pNew, aArg, nArg*sizeof(void *)); + sqlite3_free(aDyn); + aDyn = aArg = pNew; + }else{ + /* This occurs when the array of context pointers that need to + ** be passed to the unlock-notify callback is larger than the + ** aStatic[] array allocated on the stack and the attempt to + ** allocate a larger array from the heap has failed. + ** + ** This is a difficult situation to handle. Returning an error + ** code to the caller is insufficient, as even if an error code + ** is returned the transaction on connection db will still be + ** closed and the unlock-notify callbacks on blocked connections + ** will go unissued. This might cause the application to wait + ** indefinitely for an unlock-notify callback that will never + ** arrive. + ** + ** Instead, invoke the unlock-notify callback with the context + ** array already accumulated. We can then clear the array and + ** begin accumulating any further context pointers without + ** requiring any dynamic allocation. This is sub-optimal because + ** it means that instead of one callback with a large array of + ** context pointers the application will receive two or more + ** callbacks with smaller arrays of context pointers, which will + ** reduce the applications ability to prioritize multiple + ** connections. But it is the best that can be done under the + ** circumstances. + */ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + } + sqlite3EndBenignMalloc(); + + aArg[nArg++] = p->pUnlockArg; + xUnlockNotify = p->xUnlockNotify; + p->pUnlockConnection = 0; + p->xUnlockNotify = 0; + p->pUnlockArg = 0; + } + + /* Step 3. */ + if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){ + /* Remove connection p from the blocked connections list. */ + *pp = p->pNextBlocked; + p->pNextBlocked = 0; + }else{ + pp = &p->pNextBlocked; + } + } + + if( nArg!=0 ){ + xUnlockNotify(aArg, nArg); + } + sqlite3_free(aDyn); + leaveMutex(); /* Leave STATIC_MAIN mutex */ +} + +/* +** This is called when the database connection passed as an argument is +** being closed. The connection is removed from the blocked list. +*/ +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ + sqlite3ConnectionUnlocked(db); + enterMutex(); + removeFromBlockedList(db); + checkListProperties(db); + leaveMutex(); +} +#endif + +/************** End of notify.c **********************************************/ +/************** Begin file fts3.c ********************************************/ +/* +** 2006 Oct 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This is an SQLite module implementing full-text search. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ + +/* The full-text index is stored in a series of b+tree (-like) +** structures called segments which map terms to doclists. The +** structures are like b+trees in layout, but are constructed from the +** bottom up in optimal fashion and are not updatable. Since trees +** are built from the bottom up, things will be described from the +** bottom up. +** +** +**** Varints **** +** The basic unit of encoding is a variable-length integer called a +** varint. We encode variable-length integers in little-endian order +** using seven bits * per byte as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** and so on. +** +** This is similar in concept to how sqlite encodes "varints" but +** the encoding is not the same. SQLite varints are big-endian +** are are limited to 9 bytes in length whereas FTS3 varints are +** little-endian and can be up to 10 bytes in length (in theory). +** +** Example encodings: +** +** 1: 0x01 +** 127: 0x7f +** 128: 0x81 0x00 +** +** +**** Document lists **** +** A doclist (document list) holds a docid-sorted list of hits for a +** given term. Doclists hold docids and associated token positions. +** A docid is the unique integer identifier for a single document. +** A position is the index of a word within the document. The first +** word of the document has a position of 0. +** +** FTS3 used to optionally store character offsets using a compile-time +** option. But that functionality is no longer supported. +** +** A doclist is stored like this: +** +** array { +** varint docid; (delta from previous doclist) +** array { (position list for column 0) +** varint position; (2 more than the delta from previous position) +** } +** array { +** varint POS_COLUMN; (marks start of position list for new column) +** varint column; (index of new column) +** array { +** varint position; (2 more than the delta from previous position) +** } +** } +** varint POS_END; (marks end of positions for this document. +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. A "position" is an index of a token in the token stream +** generated by the tokenizer. Note that POS_END and POS_COLUMN occur +** in the same logical place as the position element, and act as sentinals +** ending a position list array. POS_END is 0. POS_COLUMN is 1. +** The positions numbers are not stored literally but rather as two more +** than the difference from the prior position, or the just the position plus +** 2 for the first position. Example: +** +** label: A B C D E F G H I J K +** value: 123 5 9 1 1 14 35 0 234 72 0 +** +** The 123 value is the first docid. For column zero in this document +** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1 +** at D signals the start of a new column; the 1 at E indicates that the +** new column is column number 1. There are two positions at 12 and 45 +** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The +** 234 at I is the delta to next docid (357). It has one position 70 +** (72-2) and then terminates with the 0 at K. +** +** A "position-list" is the list of positions for multiple columns for +** a single docid. A "column-list" is the set of positions for a single +** column. Hence, a position-list consists of one or more column-lists, +** a document record consists of a docid followed by a position-list and +** a doclist consists of one or more document records. +** +** A bare doclist omits the position information, becoming an +** array of varint-encoded docids. +** +**** Segment leaf nodes **** +** Segment leaf nodes store terms and doclists, ordered by term. Leaf +** nodes are written using LeafWriter, and read using LeafReader (to +** iterate through a single leaf node's data) and LeavesReader (to +** iterate through a segment's entire leaf layer). Leaf nodes have +** the format: +** +** varint iHeight; (height from leaf level, always 0) +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of prefix shared with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix];(unshared suffix of next term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. +** +** Leaf nodes are broken into blocks which are stored contiguously in +** the %_segments table in sorted order. This means that when the end +** of a node is reached, the next term is in the node with the next +** greater node id. +** +** New data is spilled to a new leaf node when the current node +** exceeds LEAF_MAX bytes (default 2048). New data which itself is +** larger than STANDALONE_MIN (default 1024) is placed in a standalone +** node (a leaf node with a single term and doclist). The goal of +** these settings is to pack together groups of small doclists while +** making it efficient to directly access large doclists. The +** assumption is that large doclists represent terms which are more +** likely to be query targets. +** +** TODO(shess) It may be useful for blocking decisions to be more +** dynamic. For instance, it may make more sense to have a 2.5k leaf +** node rather than splitting into 2k and .5k nodes. My intuition is +** that this might extend through 2x or 4x the pagesize. +** +** +**** Segment interior nodes **** +** Segment interior nodes store blockids for subtree nodes and terms +** to describe what data is stored by the each subtree. Interior +** nodes are written using InteriorWriter, and read using +** InteriorReader. InteriorWriters are created as needed when +** SegmentWriter creates new leaf nodes, or when an interior node +** itself grows too big and must be split. The format of interior +** nodes: +** +** varint iHeight; (height from leaf level, always >0) +** varint iBlockid; (block id of node's leftmost subtree) +** optional { +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of shared prefix with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix]; (unshared suffix of next term) +** } +** } +** +** Here, optional { X } means an optional element, while array { X } +** means zero or more occurrences of X, adjacent in memory. +** +** An interior node encodes n terms separating n+1 subtrees. The +** subtree blocks are contiguous, so only the first subtree's blockid +** is encoded. The subtree at iBlockid will contain all terms less +** than the first term encoded (or all terms if no term is encoded). +** Otherwise, for terms greater than or equal to pTerm[i] but less +** than pTerm[i+1], the subtree for that term will be rooted at +** iBlockid+i. Interior nodes only store enough term data to +** distinguish adjacent children (if the rightmost term of the left +** child is "something", and the leftmost term of the right child is +** "wicked", only "w" is stored). +** +** New data is spilled to a new interior node at the same height when +** the current node exceeds INTERIOR_MAX bytes (default 2048). +** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing +** interior nodes and making the tree too skinny. The interior nodes +** at a given height are naturally tracked by interior nodes at +** height+1, and so on. +** +** +**** Segment directory **** +** The segment directory in table %_segdir stores meta-information for +** merging and deleting segments, and also the root node of the +** segment's tree. +** +** The root node is the top node of the segment's tree after encoding +** the entire segment, restricted to ROOT_MAX bytes (default 1024). +** This could be either a leaf node or an interior node. If the top +** node requires more than ROOT_MAX bytes, it is flushed to %_segments +** and a new root interior node is generated (which should always fit +** within ROOT_MAX because it only needs space for 2 varints, the +** height and the blockid of the previous root). +** +** The meta-information in the segment directory is: +** level - segment level (see below) +** idx - index within level +** - (level,idx uniquely identify a segment) +** start_block - first leaf node +** leaves_end_block - last leaf node +** end_block - last block (including interior nodes) +** root - contents of root node +** +** If the root node is a leaf node, then start_block, +** leaves_end_block, and end_block are all 0. +** +** +**** Segment merging **** +** To amortize update costs, segments are grouped into levels and +** merged in batches. Each increase in level represents exponentially +** more documents. +** +** New documents (actually, document updates) are tokenized and +** written individually (using LeafWriter) to a level 0 segment, with +** incrementing idx. When idx reaches MERGE_COUNT (default 16), all +** level 0 segments are merged into a single level 1 segment. Level 1 +** is populated like level 0, and eventually MERGE_COUNT level 1 +** segments are merged to a single level 2 segment (representing +** MERGE_COUNT^2 updates), and so on. +** +** A segment merge traverses all segments at a given level in +** parallel, performing a straightforward sorted merge. Since segment +** leaf nodes are written in to the %_segments table in order, this +** merge traverses the underlying sqlite disk structures efficiently. +** After the merge, all segment blocks from the merged level are +** deleted. +** +** MERGE_COUNT controls how often we merge segments. 16 seems to be +** somewhat of a sweet spot for insertion performance. 32 and 64 show +** very similar performance numbers to 16 on insertion, though they're +** a tiny bit slower (perhaps due to more overhead in merge-time +** sorting). 8 is about 20% slower than 16, 4 about 50% slower than +** 16, 2 about 66% slower than 16. +** +** At query time, high MERGE_COUNT increases the number of segments +** which need to be scanned and merged. For instance, with 100k docs +** inserted: +** +** MERGE_COUNT segments +** 16 25 +** 8 12 +** 4 10 +** 2 6 +** +** This appears to have only a moderate impact on queries for very +** frequent terms (which are somewhat dominated by segment merge +** costs), and infrequent and non-existent terms still seem to be fast +** even with many segments. +** +** TODO(shess) That said, it would be nice to have a better query-side +** argument for MERGE_COUNT of 16. Also, it is possible/likely that +** optimizations to things like doclist merging will swing the sweet +** spot around. +** +** +** +**** Handling of deletions and updates **** +** Since we're using a segmented structure, with no docid-oriented +** index into the term index, we clearly cannot simply update the term +** index when a document is deleted or updated. For deletions, we +** write an empty doclist (varint(docid) varint(POS_END)), for updates +** we simply write the new doclist. Segment merges overwrite older +** data for a particular docid with newer data, so deletes or updates +** will eventually overtake the earlier data and knock it out. The +** query logic likewise merges doclists so that newer data knocks out +** older data. +*/ + +/************** Include fts3Int.h in the middle of fts3.c ********************/ +/************** Begin file fts3Int.h *****************************************/ +/* +** 2009 Nov 12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +*/ +#ifndef _FTSINT_H +#define _FTSINT_H + +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* FTS3/FTS4 require virtual tables */ +#ifdef SQLITE_OMIT_VIRTUALTABLE +# undef SQLITE_ENABLE_FTS3 +# undef SQLITE_ENABLE_FTS4 +#endif + +/* +** FTS4 is really an extension for FTS3. It is enabled using the +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all +** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. +*/ +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) +# define SQLITE_ENABLE_FTS3 +#endif + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* If not building as part of the core, include sqlite3ext.h. */ +#ifndef SQLITE_CORE +/* # include "sqlite3ext.h" */ +SQLITE_EXTENSION_INIT3 +#endif + +/* #include "sqlite3.h" */ +/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/* #include "sqlite3.h" */ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0 or 1. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialized by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. *piStartOffset should be set to the index of the first + ** byte of the token in the input buffer. *piEndOffset should be set + ** to the index of the first byte just past the end of the token in + ** the input buffer. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); + + /*********************************************************************** + ** Methods below this point are only available if iVersion>=1. + */ + + /* + ** Configure the language id of a tokenizer cursor. + */ + int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +int fts3_global_term_cnt(int iTerm, int iCol); +int fts3_term_cnt(int iTerm, int iCol); + + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3Int.h ********************/ +/************** Include fts3_hash.h in the middle of fts3Int.h ***************/ +/************** Begin file fts3_hash.h ***************************************/ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the header file for the generic hash-table implementation +** used in SQLite. We've modified it slightly to serve as a standalone +** hash table implementation for the full-text indexing module. +** +*/ +#ifndef _FTS3_HASH_H_ +#define _FTS3_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct Fts3Hash Fts3Hash; +typedef struct Fts3HashElem Fts3HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, many of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +*/ +struct Fts3Hash { + char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ + char copyKey; /* True if copy of key made on insert */ + int count; /* Number of entries in this table */ + Fts3HashElem *first; /* The first element of the array */ + int htsize; /* Number of buckets in the hash table */ + struct _fts3ht { /* the hash table */ + int count; /* Number of entries with this hash */ + Fts3HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct Fts3HashElem { + Fts3HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + void *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** There are 2 different modes of operation for a hash table: +** +** FTS3_HASH_STRING pKey points to a string that is nKey bytes long +** (including the null-terminator, if any). Case +** is respected in comparisons. +** +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** memcmp() is used to compare keys. +** +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +*/ +#define FTS3_HASH_STRING 1 +#define FTS3_HASH_BINARY 2 + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey); +SQLITE_PRIVATE void *sqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData); +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey); +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash*); +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int); + +/* +** Shorthand for the functions above +*/ +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear +#define fts3HashFindElem sqlite3Fts3HashFindElem + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Fts3Hash h; +** Fts3HashElem *p; +** ... +** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ +** SomeStructure *pData = fts3HashData(p); +** // do something with pData +** } +*/ +#define fts3HashFirst(H) ((H)->first) +#define fts3HashNext(E) ((E)->next) +#define fts3HashData(E) ((E)->data) +#define fts3HashKey(E) ((E)->pKey) +#define fts3HashKeysize(E) ((E)->nKey) + +/* +** Number of entries in a hash table +*/ +#define fts3HashCount(H) ((H)->count) + +#endif /* _FTS3_HASH_H_ */ + +/************** End of fts3_hash.h *******************************************/ +/************** Continuing where we left off in fts3Int.h ********************/ + +/* +** This constant determines the maximum depth of an FTS expression tree +** that the library will create and use. FTS uses recursion to perform +** various operations on the query tree, so the disadvantage of a large +** limit is that it may allow very large queries to use large amounts +** of stack space (perhaps causing a stack overflow). +*/ +#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH +# define SQLITE_FTS3_MAX_EXPR_DEPTH 12 +#endif + + +/* +** This constant controls how often segments are merged. Once there are +** FTS3_MERGE_COUNT segments of level N, they are merged into a single +** segment of level N+1. +*/ +#define FTS3_MERGE_COUNT 16 + +/* +** This is the maximum amount of data (in bytes) to store in the +** Fts3Table.pendingTerms hash table. Normally, the hash table is +** populated as documents are inserted/updated/deleted in a transaction +** and used to create a new segment when the transaction is committed. +** However if this limit is reached midway through a transaction, a new +** segment is created and the hash table cleared immediately. +*/ +#define FTS3_MAX_PENDING_DATA (1*1024*1024) + +/* +** Macro to return the number of elements in an array. SQLite has a +** similar macro called ArraySize(). Use a different name to avoid +** a collision when building an amalgamation with built-in FTS3. +*/ +#define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) + + +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif +#ifndef MAX +# define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +/* +** Maximum length of a varint encoded integer. The varint format is different +** from that used by SQLite, so the maximum length is 10, not 9. +*/ +#define FTS3_VARINT_MAX 10 + +#define FTS3_BUFFER_PADDING 8 + +/* +** FTS4 virtual tables may maintain multiple indexes - one index of all terms +** in the document set and zero or more prefix indexes. All indexes are stored +** as one or more b+-trees in the %_segments and %_segdir tables. +** +** It is possible to determine which index a b+-tree belongs to based on the +** value stored in the "%_segdir.level" column. Given this value L, the index +** that the b+-tree belongs to is (L<<10). In other words, all b+-trees with +** level values between 0 and 1023 (inclusive) belong to index 0, all levels +** between 1024 and 2047 to index 1, and so on. +** +** It is considered impossible for an index to use more than 1024 levels. In +** theory though this may happen, but only after at least +** (FTS3_MERGE_COUNT^1024) separate flushes of the pending-terms tables. +*/ +#define FTS3_SEGDIR_MAXLEVEL 1024 +#define FTS3_SEGDIR_MAXLEVEL_STR "1024" + +/* +** The testcase() macro is only used by the amalgamation. If undefined, +** make it a no-op. +*/ +#ifndef testcase +# define testcase(X) +#endif + +/* +** Terminator values for position-lists and column-lists. +*/ +#define POS_COLUMN (1) /* Column-list terminator */ +#define POS_END (0) /* Position-list terminator */ + +/* +** The assert_fts3_nc() macro is similar to the assert() macro, except that it +** is used for assert() conditions that are true only if it can be +** guranteed that the database is not corrupt. +*/ +#ifdef SQLITE_DEBUG +SQLITE_API extern int sqlite3_fts3_may_be_corrupt; +# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x)) +#else +# define assert_fts3_nc(x) assert(x) +#endif + +/* +** This section provides definitions to allow the +** FTS3 extension to be compiled outside of the +** amalgamation. +*/ +#ifndef SQLITE_AMALGAMATION +/* +** Macros indicating that conditional expressions are always true or +** false. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +/* +** Internal types used by SQLite. +*/ +typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ +typedef short int i16; /* 2-byte (or larger) signed integer */ +typedef unsigned int u32; /* 4-byte unsigned integer */ +typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ +typedef sqlite3_int64 i64; /* 8-byte signed integer */ + +/* +** Macro used to suppress compiler warnings for unused parameters. +*/ +#define UNUSED_PARAMETER(x) (void)(x) + +/* +** Activate assert() only if SQLITE_TEST is enabled. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +#define deliberate_fall_through + +#endif /* SQLITE_AMALGAMATION */ + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); +# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() +#else +# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB +#endif + +typedef struct Fts3Table Fts3Table; +typedef struct Fts3Cursor Fts3Cursor; +typedef struct Fts3Expr Fts3Expr; +typedef struct Fts3Phrase Fts3Phrase; +typedef struct Fts3PhraseToken Fts3PhraseToken; + +typedef struct Fts3Doclist Fts3Doclist; +typedef struct Fts3SegFilter Fts3SegFilter; +typedef struct Fts3DeferredToken Fts3DeferredToken; +typedef struct Fts3SegReader Fts3SegReader; +typedef struct Fts3MultiSegReader Fts3MultiSegReader; + +typedef struct MatchinfoBuffer MatchinfoBuffer; + +/* +** A connection to a fulltext index is an instance of the following +** structure. The xCreate and xConnect methods create an instance +** of this structure and xDestroy and xDisconnect free that instance. +** All other methods receive a pointer to the structure as one of their +** arguments. +*/ +struct Fts3Table { + sqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3 *db; /* The database connection */ + const char *zDb; /* logical database name */ + const char *zName; /* virtual table name */ + int nColumn; /* number of named columns in virtual table */ + char **azColumn; /* column names. malloced */ + u8 *abNotindexed; /* True for 'notindexed' columns */ + sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ + char *zContentTbl; /* content=xxx option, or NULL */ + char *zLanguageid; /* languageid=xxx option, or NULL */ + int nAutoincrmerge; /* Value configured by 'automerge' */ + u32 nLeafAdd; /* Number of leaf blocks added this trans */ + int bLock; /* Used to prevent recursive content= tbls */ + + /* Precompiled statements used by the implementation. Each of these + ** statements is run and reset within a single virtual table API call. + */ + sqlite3_stmt *aStmt[40]; + sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */ + + char *zReadExprlist; + char *zWriteExprlist; + + int nNodeSize; /* Soft limit for node size */ + u8 bFts4; /* True for FTS4, false for FTS3 */ + u8 bHasStat; /* True if %_stat table exists (2==unknown) */ + u8 bHasDocsize; /* True if %_docsize table exists */ + u8 bDescIdx; /* True if doclists are in reverse order */ + u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ + int nPgsz; /* Page size for host database */ + char *zSegmentsTbl; /* Name of %_segments table */ + sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + int iSavepoint; + + /* + ** The following array of hash tables is used to buffer pending index + ** updates during transactions. All pending updates buffered at any one + ** time must share a common language-id (see the FTS4 langid= feature). + ** The current language id is stored in variable iPrevLangid. + ** + ** A single FTS4 table may have multiple full-text indexes. For each index + ** there is an entry in the aIndex[] array. Index 0 is an index of all the + ** terms that appear in the document set. Each subsequent index in aIndex[] + ** is an index of prefixes of a specific length. + ** + ** Variable nPendingData contains an estimate the memory consumed by the + ** pending data structures, including hash table overhead, but not including + ** malloc overhead. When nPendingData exceeds nMaxPendingData, all hash + ** tables are flushed to disk. Variable iPrevDocid is the docid of the most + ** recently inserted record. + */ + int nIndex; /* Size of aIndex[] */ + struct Fts3Index { + int nPrefix; /* Prefix length (0 for main terms index) */ + Fts3Hash hPending; /* Pending terms table for this index */ + } *aIndex; + int nMaxPendingData; /* Max pending data before flush to disk */ + int nPendingData; /* Current bytes of pending data */ + sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ + int iPrevLangid; /* Langid of recently inserted document */ + int bPrevDelete; /* True if last operation was a delete */ + +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + /* State variables used for validating that the transaction control + ** methods of the virtual table are called at appropriate times. These + ** values do not contribute to FTS functionality; they are used for + ** verifying the operation of the SQLite core. + */ + int inTransaction; /* True after xBegin but before xCommit/xRollback */ + int mxSavepoint; /* Largest valid xSavepoint integer */ +#endif + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* True to disable the incremental doclist optimization. This is controled + ** by special insert command 'test-no-incr-doclist'. */ + int bNoIncrDoclist; + + /* Number of segments in a level */ + int nMergeCount; +#endif +}; + +/* Macro to find the number of segments to merge */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) +# define MergeCount(P) ((P)->nMergeCount) +#else +# define MergeCount(P) FTS3_MERGE_COUNT +#endif + +/* +** When the core wants to read from the virtual table, it creates a +** virtual table cursor (an instance of the following structure) using +** the xOpen method. Cursors are destroyed using the xClose method. +*/ +struct Fts3Cursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + i16 eSearch; /* Search strategy (see below) */ + u8 isEof; /* True if at End Of Results */ + u8 isRequireSeek; /* True if must seek pStmt to %_content row */ + u8 bSeekStmt; /* True if pStmt is a seek */ + sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ + Fts3Expr *pExpr; /* Parsed MATCH query string */ + int iLangid; /* Language being queried for */ + int nPhrase; /* Number of matchable phrases in query */ + Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ + sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ + char *pNextId; /* Pointer into the body of aDoclist */ + char *aDoclist; /* List of docids for full-text queries */ + int nDoclist; /* Size of buffer at aDoclist */ + u8 bDesc; /* True to sort in descending order */ + int eEvalmode; /* An FTS3_EVAL_XX constant */ + int nRowAvg; /* Average size of database rows, in pages */ + sqlite3_int64 nDoc; /* Documents in table */ + i64 iMinDocid; /* Minimum docid to return */ + i64 iMaxDocid; /* Maximum docid to return */ + int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ + MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */ +}; + +#define FTS3_EVAL_FILTER 0 +#define FTS3_EVAL_NEXT 1 +#define FTS3_EVAL_MATCHINFO 2 + +/* +** The Fts3Cursor.eSearch member is always set to one of the following. +** Actualy, Fts3Cursor.eSearch can be greater than or equal to +** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index +** of the column to be searched. For example, in +** +** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); +** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; +** +** Because the LHS of the MATCH operator is 2nd column "b", +** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1. (+0 for a, +** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1" +** indicating that all columns should be searched, +** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4. +*/ +#define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */ +#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ +#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ + +/* +** The lower 16-bits of the sqlite3_index_info.idxNum value set by +** the xBestIndex() method contains the Fts3Cursor.eSearch value described +** above. The upper 16-bits contain a combination of the following +** bits, used to describe extra constraints on full-text searches. +*/ +#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */ +#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */ +#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */ + +struct Fts3Doclist { + char *aAll; /* Array containing doclist (or NULL) */ + int nAll; /* Size of a[] in bytes */ + char *pNextDocid; /* Pointer to next docid */ + + sqlite3_int64 iDocid; /* Current docid (if pList!=0) */ + int bFreeList; /* True if pList should be sqlite3_free()d */ + char *pList; /* Pointer to position list following iDocid */ + int nList; /* Length of position list */ +}; + +/* +** A "phrase" is a sequence of one or more tokens that must match in +** sequence. A single token is the base case and the most common case. +** For a sequence of tokens contained in double-quotes (i.e. "one two three") +** nToken will be the number of tokens in the string. +*/ +struct Fts3PhraseToken { + char *z; /* Text of the token */ + int n; /* Number of bytes in buffer z */ + int isPrefix; /* True if token ends with a "*" character */ + int bFirst; /* True if token must appear at position 0 */ + + /* Variables above this point are populated when the expression is + ** parsed (by code in fts3_expr.c). Below this point the variables are + ** used when evaluating the expression. */ + Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ + Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ +}; + +struct Fts3Phrase { + /* Cache of doclist for this phrase. */ + Fts3Doclist doclist; + int bIncr; /* True if doclist is loaded incrementally */ + int iDoclistToken; + + /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an + ** OR condition. */ + char *pOrPoslist; + i64 iOrDocid; + + /* Variables below this point are populated by fts3_expr.c when parsing + ** a MATCH expression. Everything above is part of the evaluation phase. + */ + int nToken; /* Number of tokens in the phrase */ + int iColumn; /* Index of column this phrase must match */ + Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ +}; + +/* +** A tree of these objects forms the RHS of a MATCH operator. +** +** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist +** points to a malloced buffer, size nDoclist bytes, containing the results +** of this phrase query in FTS3 doclist format. As usual, the initial +** "Length" field found in doclists stored on disk is omitted from this +** buffer. +** +** Variable aMI is used only for FTSQUERY_NEAR nodes to store the global +** matchinfo data. If it is not NULL, it points to an array of size nCol*3, +** where nCol is the number of columns in the queried FTS table. The array +** is populated as follows: +** +** aMI[iCol*3 + 0] = Undefined +** aMI[iCol*3 + 1] = Number of occurrences +** aMI[iCol*3 + 2] = Number of rows containing at least one instance +** +** The aMI array is allocated using sqlite3_malloc(). It should be freed +** when the expression node is. +*/ +struct Fts3Expr { + int eType; /* One of the FTSQUERY_XXX values defined below */ + int nNear; /* Valid if eType==FTSQUERY_NEAR */ + Fts3Expr *pParent; /* pParent->pLeft==this or pParent->pRight==this */ + Fts3Expr *pLeft; /* Left operand */ + Fts3Expr *pRight; /* Right operand */ + Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */ + + /* The following are used by the fts3_eval.c module. */ + sqlite3_int64 iDocid; /* Current docid */ + u8 bEof; /* True this expression is at EOF already */ + u8 bStart; /* True if iDocid is valid */ + u8 bDeferred; /* True if this expression is entirely deferred */ + + /* The following are used by the fts3_snippet.c module. */ + int iPhrase; /* Index of this phrase in matchinfo() results */ + u32 *aMI; /* See above */ +}; + +/* +** Candidate values for Fts3Query.eType. Note that the order of the first +** four values is in order of precedence when parsing expressions. For +** example, the following: +** +** "a OR b AND c NOT d NEAR e" +** +** is equivalent to: +** +** "a OR (b AND (c NOT (d NEAR e)))" +*/ +#define FTSQUERY_NEAR 1 +#define FTSQUERY_NOT 2 +#define FTSQUERY_AND 3 +#define FTSQUERY_OR 4 +#define FTSQUERY_PHRASE 5 + + +/* fts3_write.c */ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64, + sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); +SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( + Fts3Table*,int,const char*,int,int,Fts3SegReader**); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); + +SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); +#else +# define sqlite3Fts3FreeDeferredTokens(x) +# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK +# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK +# define sqlite3Fts3FreeDeferredDoclists(x) +# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK +#endif + +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); + +/* Special values interpreted by sqlite3SegReaderCursor() */ +#define FTS3_SEGCURSOR_PENDING -1 +#define FTS3_SEGCURSOR_ALL -2 + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); + +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *, + int, int, int, const char *, int, int, int, Fts3MultiSegReader *); + +/* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ +#define FTS3_SEGMENT_REQUIRE_POS 0x00000001 +#define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002 +#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004 +#define FTS3_SEGMENT_PREFIX 0x00000008 +#define FTS3_SEGMENT_SCAN 0x00000010 +#define FTS3_SEGMENT_FIRST 0x00000020 + +/* Type passed as 4th argument to SegmentReaderIterate() */ +struct Fts3SegFilter { + const char *zTerm; + int nTerm; + int iCol; + int flags; +}; + +struct Fts3MultiSegReader { + /* Used internally by sqlite3Fts3SegReaderXXX() calls */ + Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ + int nSegment; /* Size of apSegment array */ + int nAdvance; /* How many seg-readers to advance */ + Fts3SegFilter *pFilter; /* Pointer to filter object */ + char *aBuffer; /* Buffer to merge doclists in */ + i64 nBuffer; /* Allocated size of aBuffer[] in bytes */ + + int iColFilter; /* If >=0, filter for this column */ + int bRestart; + + /* Used by fts3.c only. */ + int nCost; /* Cost of running iterator */ + int bLookup; /* True if a lookup of a single entry. */ + + /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ + char *zTerm; /* Pointer to term buffer */ + int nTerm; /* Size of zTerm in bytes */ + char *aDoclist; /* Pointer to doclist buffer */ + int nDoclist; /* Size of aDoclist[] in bytes */ +}; + +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); + +#define fts3GetVarint32(p, piVal) ( \ + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ +) + +/* fts3.c */ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); +SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*); +SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc); +SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut); + +/* fts3_tokenizer.c */ +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, + sqlite3_tokenizer **, char ** +); +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char); + +/* fts3_snippet.c */ +SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); +SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, + const char *, const char *, int, int +); +SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); +SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p); + +/* fts3_expr.c */ +SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, + char **, int, int, int, const char *, int, Fts3Expr **, char ** +); +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); +SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); +#endif +SQLITE_PRIVATE void *sqlite3Fts3MallocZero(i64 nByte); + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, + sqlite3_tokenizer_cursor ** +); + +/* fts3_aux.c */ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); + +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table*, Fts3MultiSegReader*, int, const char*, int); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); + +/* fts3_tokenize_vtab.c */ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*)); + +/* fts3_unicode2.c (functions generated by parsing unicode text files) */ +#ifndef SQLITE_DISABLE_FTS3_UNICODE +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); +#endif + +SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); + +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); + +#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ +#endif /* _FTSINT_H */ + +/************** End of fts3Int.h *********************************************/ +/************** Continuing where we left off in fts3.c ***********************/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) +# define SQLITE_CORE 1 +#endif + +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3.h" */ +#ifndef SQLITE_CORE +/* # include "sqlite3ext.h" */ + SQLITE_EXTENSION_INIT1 +#endif + +typedef struct Fts3HashWrapper Fts3HashWrapper; +struct Fts3HashWrapper { + Fts3Hash hash; /* Hash table */ + int nRef; /* Number of pointers to this object */ +}; + +static int fts3EvalNext(Fts3Cursor *pCsr); +static int fts3EvalStart(Fts3Cursor *pCsr); +static int fts3TermSegReaderCursor( + Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); + +/* +** This variable is set to false when running tests for which the on disk +** structures should not be corrupt. Otherwise, true. If it is false, extra +** assert() conditions in the fts3 code are activated - conditions that are +** only true if it is guaranteed that the fts3 database is not corrupt. +*/ +#ifdef SQLITE_DEBUG +SQLITE_API int sqlite3_fts3_may_be_corrupt = 1; +#endif + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. +** The number of bytes written is returned. +*/ +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ + unsigned char *q = (unsigned char *) p; + sqlite_uint64 vu = v; + do{ + *q++ = (unsigned char) ((vu & 0x7f) | 0x80); + vu >>= 7; + }while( vu!=0 ); + q[-1] &= 0x7f; /* turn off high bit in final byte */ + assert( q - (unsigned char *)p <= FTS3_VARINT_MAX ); + return (int) (q - (unsigned char *)p); +} + +#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ + v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift ); \ + if( (v & mask2)==0 ){ var = v; return ret; } +#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ + v = (*ptr++); \ + if( (v & mask2)==0 ){ var = v; return ret; } + +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ + const unsigned char *p = (const unsigned char*)pBuf; + const unsigned char *pStart = p; + u32 a; + u64 b; + int shift; + + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1); + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); + b = (a & 0x0FFFFFFF ); + + for(shift=28; shift<=63; shift+=7){ + u64 c = *p++; + b += (c&0x7F) << shift; + if( (c & 0x80)==0 ) break; + } + *v = b; + return (int)(p - pStart); +} + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + return sqlite3Fts3GetVarintU(pBuf, (sqlite3_uint64*)v); +} + +/* +** Read a 64-bit variable-length integer from memory starting at p[0] and +** not extending past pEnd[-1]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded( + const char *pBuf, + const char *pEnd, + sqlite_int64 *v +){ + const unsigned char *p = (const unsigned char*)pBuf; + const unsigned char *pStart = p; + const unsigned char *pX = (const unsigned char*)pEnd; + u64 b = 0; + int shift; + for(shift=0; shift<=63; shift+=7){ + u64 c = p=0 ); + return 5; +} + +/* +** Return the number of bytes required to encode v as a varint +*/ +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){ + int i = 0; + do{ + i++; + v >>= 7; + }while( v!=0 ); + return i; +} + +/* +** Convert an SQL-style quoted string into a normal string by removing +** the quote characters. The conversion is done in-place. If the +** input does not begin with a quote character, then this routine +** is a no-op. +** +** Examples: +** +** "abc" becomes abc +** 'xyz' becomes xyz +** [pqr] becomes pqr +** `mno` becomes mno +** +*/ +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ + char quote; /* Quote character (if any ) */ + + quote = z[0]; + if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){ + int iIn = 1; /* Index of next byte to read from input */ + int iOut = 0; /* Index of next byte to write to output */ + + /* If the first byte was a '[', then the close-quote character is a ']' */ + if( quote=='[' ) quote = ']'; + + while( z[iIn] ){ + if( z[iIn]==quote ){ + if( z[iIn+1]!=quote ) break; + z[iOut++] = quote; + iIn += 2; + }else{ + z[iOut++] = z[iIn++]; + } + } + z[iOut] = '\0'; + } +} + +/* +** Read a single varint from the doclist at *pp and advance *pp to point +** to the first byte past the end of the varint. Add the value of the varint +** to *pVal. +*/ +static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ + sqlite3_int64 iVal; + *pp += sqlite3Fts3GetVarint(*pp, &iVal); + *pVal += iVal; +} + +/* +** When this function is called, *pp points to the first byte following a +** varint that is part of a doclist (or position-list, or any other list +** of varints). This function moves *pp to point to the start of that varint, +** and sets *pVal by the varint value. +** +** Argument pStart points to the first byte of the doclist that the +** varint is part of. +*/ +static void fts3GetReverseVarint( + char **pp, + char *pStart, + sqlite3_int64 *pVal +){ + sqlite3_int64 iVal; + char *p; + + /* Pointer p now points at the first byte past the varint we are + ** interested in. So, unless the doclist is corrupt, the 0x80 bit is + ** clear on character p[-1]. */ + for(p = (*pp)-2; p>=pStart && *p&0x80; p--); + p++; + *pp = p; + + sqlite3Fts3GetVarint(p, &iVal); + *pVal = iVal; +} + +/* +** The xDisconnect() virtual table method. +*/ +static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table *)pVtab; + int i; + + assert( p->nPendingData==0 ); + assert( p->pSegments==0 ); + + /* Free any prepared statements held */ + sqlite3_finalize(p->pSeekStmt); + for(i=0; iaStmt); i++){ + sqlite3_finalize(p->aStmt[i]); + } + sqlite3_free(p->zSegmentsTbl); + sqlite3_free(p->zReadExprlist); + sqlite3_free(p->zWriteExprlist); + sqlite3_free(p->zContentTbl); + sqlite3_free(p->zLanguageid); + + /* Invoke the tokenizer destructor to free the tokenizer. */ + p->pTokenizer->pModule->xDestroy(p->pTokenizer); + + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Write an error message into *pzErr +*/ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ + va_list ap; + sqlite3_free(*pzErr); + va_start(ap, zFormat); + *pzErr = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + +/* +** Construct one or more SQL statements from the format string given +** and then evaluate those statements. The success code is written +** into *pRc. +** +** If *pRc is initially non-zero then this routine is a no-op. +*/ +static void fts3DbExec( + int *pRc, /* Success code */ + sqlite3 *db, /* Database in which to run SQL */ + const char *zFormat, /* Format string for SQL */ + ... /* Arguments to the format string */ +){ + va_list ap; + char *zSql; + if( *pRc ) return; + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + *pRc = sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } +} + +/* +** The xDestroy() virtual table method. +*/ +static int fts3DestroyMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table *)pVtab; + int rc = SQLITE_OK; /* Return code */ + const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */ + sqlite3 *db = p->db; /* Database handle */ + + /* Drop the shadow tables */ + fts3DbExec(&rc, db, + "DROP TABLE IF EXISTS %Q.'%q_segments';" + "DROP TABLE IF EXISTS %Q.'%q_segdir';" + "DROP TABLE IF EXISTS %Q.'%q_docsize';" + "DROP TABLE IF EXISTS %Q.'%q_stat';" + "%s DROP TABLE IF EXISTS %Q.'%q_content';", + zDb, p->zName, + zDb, p->zName, + zDb, p->zName, + zDb, p->zName, + (p->zContentTbl ? "--" : ""), zDb,p->zName + ); + + /* If everything has worked, invoke fts3DisconnectMethod() to free the + ** memory associated with the Fts3Table structure and return SQLITE_OK. + ** Otherwise, return an SQLite error code. + */ + return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc); +} + + +/* +** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table +** passed as the first argument. This is done as part of the xConnect() +** and xCreate() methods. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. +*/ +static void fts3DeclareVtab(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int i; /* Iterator variable */ + int rc; /* Return code */ + char *zSql; /* SQL statement passed to declare_vtab() */ + char *zCols; /* List of user defined columns */ + const char *zLanguageid; + + zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); + sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(p->db, SQLITE_VTAB_INNOCUOUS); + + /* Create a list of user columns for the virtual table */ + zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); + for(i=1; zCols && inColumn; i++){ + zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); + } + + /* Create the whole "CREATE TABLE" statement to pass to SQLite */ + zSql = sqlite3_mprintf( + "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)", + zCols, p->zName, zLanguageid + ); + if( !zCols || !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_declare_vtab(p->db, zSql); + } + + sqlite3_free(zSql); + sqlite3_free(zCols); + *pRc = rc; + } +} + +/* +** Create the %_stat table if it does not already exist. +*/ +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ + fts3DbExec(pRc, p->db, + "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'" + "(id INTEGER PRIMARY KEY, value BLOB);", + p->zDb, p->zName + ); + if( (*pRc)==SQLITE_OK ) p->bHasStat = 1; +} + +/* +** Create the backing store tables (%_content, %_segments and %_segdir) +** required by the FTS3 table passed as the only argument. This is done +** as part of the vtab xCreate() method. +** +** If the p->bHasDocsize boolean is true (indicating that this is an +** FTS4 table, not an FTS3 table) then also create the %_docsize and +** %_stat tables required by FTS4. +*/ +static int fts3CreateTables(Fts3Table *p){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Iterator variable */ + sqlite3 *db = p->db; /* The database connection */ + + if( p->zContentTbl==0 ){ + const char *zLanguageid = p->zLanguageid; + char *zContentCols; /* Columns of %_content table */ + + /* Create a list of user columns for the content table */ + zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); + for(i=0; zContentCols && inColumn; i++){ + char *z = p->azColumn[i]; + zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); + } + if( zLanguageid && zContentCols ){ + zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid); + } + if( zContentCols==0 ) rc = SQLITE_NOMEM; + + /* Create the content table */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_content'(%s)", + p->zDb, p->zName, zContentCols + ); + sqlite3_free(zContentCols); + } + + /* Create other tables */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + p->zDb, p->zName + ); + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_segdir'(" + "level INTEGER," + "idx INTEGER," + "start_block INTEGER," + "leaves_end_block INTEGER," + "end_block INTEGER," + "root BLOB," + "PRIMARY KEY(level, idx)" + ");", + p->zDb, p->zName + ); + if( p->bHasDocsize ){ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + p->zDb, p->zName + ); + } + assert( p->bHasStat==p->bFts4 ); + if( p->bHasStat ){ + sqlite3Fts3CreateStatTable(&rc, p); + } + return rc; +} + +/* +** Store the current database page-size in bytes in p->nPgsz. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. +*/ +static void fts3DatabasePageSize(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int rc; /* Return code */ + char *zSql; /* SQL text "PRAGMA %Q.page_size" */ + sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ + + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_step(pStmt); + p->nPgsz = sqlite3_column_int(pStmt, 0); + rc = sqlite3_finalize(pStmt); + }else if( rc==SQLITE_AUTH ){ + p->nPgsz = 1024; + rc = SQLITE_OK; + } + } + assert( p->nPgsz>0 || rc!=SQLITE_OK ); + sqlite3_free(zSql); + *pRc = rc; + } +} + +/* +** "Special" FTS4 arguments are column specifications of the following form: +** +** = +** +** There may not be whitespace surrounding the "=" character. The +** term may be quoted, but the may not. +*/ +static int fts3IsSpecialColumn( + const char *z, + int *pnKey, + char **pzValue +){ + char *zValue; + const char *zCsr = z; + + while( *zCsr!='=' ){ + if( *zCsr=='\0' ) return 0; + zCsr++; + } + + *pnKey = (int)(zCsr-z); + zValue = sqlite3_mprintf("%s", &zCsr[1]); + if( zValue ){ + sqlite3Fts3Dequote(zValue); + } + *pzValue = zValue; + return 1; +} + +/* +** Append the output of a printf() style formatting to an existing string. +*/ +static void fts3Appendf( + int *pRc, /* IN/OUT: Error code */ + char **pz, /* IN/OUT: Pointer to string buffer */ + const char *zFormat, /* Printf format string to append */ + ... /* Arguments for printf format string */ +){ + if( *pRc==SQLITE_OK ){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( z && *pz ){ + char *z2 = sqlite3_mprintf("%s%s", *pz, z); + sqlite3_free(z); + z = z2; + } + if( z==0 ) *pRc = SQLITE_NOMEM; + sqlite3_free(*pz); + *pz = z; + } +} + +/* +** Return a copy of input string zInput enclosed in double-quotes (") and +** with all double quote characters escaped. For example: +** +** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\"" +** +** The pointer returned points to memory obtained from sqlite3_malloc(). It +** is the callers responsibility to call sqlite3_free() to release this +** memory. +*/ +static char *fts3QuoteId(char const *zInput){ + sqlite3_int64 nRet; + char *zRet; + nRet = 2 + (int)strlen(zInput)*2 + 1; + zRet = sqlite3_malloc64(nRet); + if( zRet ){ + int i; + char *z = zRet; + *(z++) = '"'; + for(i=0; zInput[i]; i++){ + if( zInput[i]=='"' ) *(z++) = '"'; + *(z++) = zInput[i]; + } + *(z++) = '"'; + *(z++) = '\0'; + } + return zRet; +} + +/* +** Return a list of comma separated SQL expressions and a FROM clause that +** could be used in a SELECT statement such as the following: +** +** SELECT FROM %_content AS x ... +** +** to return the docid, followed by each column of text data in order +** from left to write. If parameter zFunc is not NULL, then instead of +** being returned directly each column of text data is passed to an SQL +** function named zFunc first. For example, if zFunc is "unzip" and the +** table has the three user-defined columns "a", "b", and "c", the following +** string is returned: +** +** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( p->zContentTbl==0 ){ + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "docid"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", "langid"); + } + sqlite3_free(zFree); + }else{ + fts3Appendf(pRc, &zRet, "rowid"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", p->zLanguageid); + } + } + fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x", + p->zDb, + (p->zContentTbl ? p->zContentTbl : p->zName), + (p->zContentTbl ? "" : "_content") + ); + return zRet; +} + +/* +** Return a list of N comma separated question marks, where N is the number +** of columns in the %_content table (one for the docid plus one for each +** user-defined text column). +** +** If argument zFunc is not NULL, then all but the first question mark +** is preceded by zFunc and an open bracket, and followed by a closed +** bracket. For example, if zFunc is "zip" and the FTS3 table has three +** user-defined text columns, the following string is returned: +** +** "?, zip(?), zip(?), zip(?)" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "?"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(?)", zFunction); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", ?"); + } + sqlite3_free(zFree); + return zRet; +} + +/* +** Buffer z contains a positive integer value encoded as utf-8 text. +** Decode this value and store it in *pnOut, returning the number of bytes +** consumed. If an overflow error occurs return a negative value. +*/ +SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut){ + u64 iVal = 0; + int i; + for(i=0; z[i]>='0' && z[i]<='9'; i++){ + iVal = iVal*10 + (z[i] - '0'); + if( iVal>0x7FFFFFFF ) return -1; + } + *pnOut = (int)iVal; + return i; +} + +/* +** This function interprets the string at (*pp) as a non-negative integer +** value. It reads the integer and sets *pnOut to the value read, then +** sets *pp to point to the byte immediately following the last byte of +** the integer value. +** +** Only decimal digits ('0'..'9') may be part of an integer value. +** +** If *pp does not being with a decimal digit SQLITE_ERROR is returned and +** the output value undefined. Otherwise SQLITE_OK is returned. +** +** This function is used when parsing the "prefix=" FTS4 parameter. +*/ +static int fts3GobbleInt(const char **pp, int *pnOut){ + const int MAX_NPREFIX = 10000000; + int nInt = 0; /* Output value */ + int nByte; + nByte = sqlite3Fts3ReadInt(*pp, &nInt); + if( nInt>MAX_NPREFIX ){ + nInt = 0; + } + if( nByte==0 ){ + return SQLITE_ERROR; + } + *pnOut = nInt; + *pp += nByte; + return SQLITE_OK; +} + +/* +** This function is called to allocate an array of Fts3Index structures +** representing the indexes maintained by the current FTS table. FTS tables +** always maintain the main "terms" index, but may also maintain one or +** more "prefix" indexes, depending on the value of the "prefix=" parameter +** (if any) specified as part of the CREATE VIRTUAL TABLE statement. +** +** Argument zParam is passed the value of the "prefix=" option if one was +** specified, or NULL otherwise. +** +** If no error occurs, SQLITE_OK is returned and *apIndex set to point to +** the allocated array. *pnIndex is set to the number of elements in the +** array. If an error does occur, an SQLite error code is returned. +** +** Regardless of whether or not an error is returned, it is the responsibility +** of the caller to call sqlite3_free() on the output array to free it. +*/ +static int fts3PrefixParameter( + const char *zParam, /* ABC in prefix=ABC parameter to parse */ + int *pnIndex, /* OUT: size of *apIndex[] array */ + struct Fts3Index **apIndex /* OUT: Array of indexes for this table */ +){ + struct Fts3Index *aIndex; /* Allocated array */ + int nIndex = 1; /* Number of entries in array */ + + if( zParam && zParam[0] ){ + const char *p; + nIndex++; + for(p=zParam; *p; p++){ + if( *p==',' ) nIndex++; + } + } + + aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex); + *apIndex = aIndex; + if( !aIndex ){ + return SQLITE_NOMEM; + } + + memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex); + if( zParam ){ + const char *p = zParam; + int i; + for(i=1; i=0 ); + if( nPrefix==0 ){ + nIndex--; + i--; + }else{ + aIndex[i].nPrefix = nPrefix; + } + p++; + } + } + + *pnIndex = nIndex; + return SQLITE_OK; +} + +/* +** This function is called when initializing an FTS4 table that uses the +** content=xxx option. It determines the number of and names of the columns +** of the new FTS4 table. +** +** The third argument passed to this function is the value passed to the +** config=xxx option (i.e. "xxx"). This function queries the database for +** a table of that name. If found, the output variables are populated +** as follows: +** +** *pnCol: Set to the number of columns table xxx has, +** +** *pnStr: Set to the total amount of space required to store a copy +** of each columns name, including the nul-terminator. +** +** *pazCol: Set to point to an array of *pnCol strings. Each string is +** the name of the corresponding column in table xxx. The array +** and its contents are allocated using a single allocation. It +** is the responsibility of the caller to free this allocation +** by eventually passing the *pazCol value to sqlite3_free(). +** +** If the table cannot be found, an error code is returned and the output +** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is +** returned (and the output variables are undefined). +*/ +static int fts3ContentColumns( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */ + const char *zTbl, /* Name of content table */ + const char ***pazCol, /* OUT: Malloc'd array of column names */ + int *pnCol, /* OUT: Size of array *pazCol */ + int *pnStr, /* OUT: Bytes of string content */ + char **pzErr /* OUT: error message */ +){ + int rc = SQLITE_OK; /* Return code */ + char *zSql; /* "SELECT *" statement on zTbl */ + sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */ + + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db)); + } + } + sqlite3_free(zSql); + + if( rc==SQLITE_OK ){ + const char **azCol; /* Output array */ + sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */ + int nCol; /* Number of table columns */ + int i; /* Used to iterate through columns */ + + /* Loop through the returned columns. Set nStr to the number of bytes of + ** space required to store a copy of each column name, including the + ** nul-terminator byte. */ + nCol = sqlite3_column_count(pStmt); + for(i=0; i module name ("fts3" or "fts4") +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> "column name" and other module argument fields. +*/ +static int fts3InitVtab( + int isCreate, /* True for xCreate, false for xConnect */ + sqlite3 *db, /* The SQLite database connection */ + void *pAux, /* Hash table containing tokenizers */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ + char **pzErr /* Write any error message here */ +){ + Fts3Hash *pHash = &((Fts3HashWrapper*)pAux)->hash; + Fts3Table *p = 0; /* Pointer to allocated vtab */ + int rc = SQLITE_OK; /* Return code */ + int i; /* Iterator variable */ + sqlite3_int64 nByte; /* Size of allocation used for *p */ + int iCol; /* Column index */ + int nString = 0; /* Bytes required to hold all column names */ + int nCol = 0; /* Number of columns in the FTS table */ + char *zCsr; /* Space for holding column names */ + int nDb; /* Bytes required to hold database name */ + int nName; /* Bytes required to hold table name */ + int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ + const char **aCol; /* Array of column names */ + sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ + + int nIndex = 0; /* Size of aIndex[] array */ + struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ + + /* The results of parsing supported FTS4 key=value options: */ + int bNoDocsize = 0; /* True to omit %_docsize table */ + int bDescIdx = 0; /* True to store descending indexes */ + char *zPrefix = 0; /* Prefix parameter value (or NULL) */ + char *zCompress = 0; /* compress=? parameter (or NULL) */ + char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ + char *zContent = 0; /* content=? parameter (or NULL) */ + char *zLanguageid = 0; /* languageid=? parameter (or NULL) */ + char **azNotindexed = 0; /* The set of notindexed= columns */ + int nNotindexed = 0; /* Size of azNotindexed[] array */ + + assert( strlen(argv[0])==4 ); + assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) + || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) + ); + + nDb = (int)strlen(argv[1]) + 1; + nName = (int)strlen(argv[2]) + 1; + + nByte = sizeof(const char *) * (argc-2); + aCol = (const char **)sqlite3_malloc64(nByte); + if( aCol ){ + memset((void*)aCol, 0, nByte); + azNotindexed = (char **)sqlite3_malloc64(nByte); + } + if( azNotindexed ){ + memset(azNotindexed, 0, nByte); + } + if( !aCol || !azNotindexed ){ + rc = SQLITE_NOMEM; + goto fts3_init_out; + } + + /* Loop through all of the arguments passed by the user to the FTS3/4 + ** module (i.e. all the column names and special arguments). This loop + ** does the following: + ** + ** + Figures out the number of columns the FTSX table will have, and + ** the number of bytes of space that must be allocated to store copies + ** of the column names. + ** + ** + If there is a tokenizer specification included in the arguments, + ** initializes the tokenizer pTokenizer. + */ + for(i=3; rc==SQLITE_OK && i8 + && 0==sqlite3_strnicmp(z, "tokenize", 8) + && 0==sqlite3Fts3IsIdChar(z[8]) + ){ + rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); + } + + /* Check if it is an FTS4 special argument. */ + else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){ + struct Fts4Option { + const char *zOpt; + int nOpt; + } aFts4Opt[] = { + { "matchinfo", 9 }, /* 0 -> MATCHINFO */ + { "prefix", 6 }, /* 1 -> PREFIX */ + { "compress", 8 }, /* 2 -> COMPRESS */ + { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ + { "order", 5 }, /* 4 -> ORDER */ + { "content", 7 }, /* 5 -> CONTENT */ + { "languageid", 10 }, /* 6 -> LANGUAGEID */ + { "notindexed", 10 } /* 7 -> NOTINDEXED */ + }; + + int iOpt; + if( !zVal ){ + rc = SQLITE_NOMEM; + }else{ + for(iOpt=0; iOptnOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ + break; + } + } + switch( iOpt ){ + case 0: /* MATCHINFO */ + if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); + rc = SQLITE_ERROR; + } + bNoDocsize = 1; + break; + + case 1: /* PREFIX */ + sqlite3_free(zPrefix); + zPrefix = zVal; + zVal = 0; + break; + + case 2: /* COMPRESS */ + sqlite3_free(zCompress); + zCompress = zVal; + zVal = 0; + break; + + case 3: /* UNCOMPRESS */ + sqlite3_free(zUncompress); + zUncompress = zVal; + zVal = 0; + break; + + case 4: /* ORDER */ + if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) + && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) + ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); + rc = SQLITE_ERROR; + } + bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); + break; + + case 5: /* CONTENT */ + sqlite3_free(zContent); + zContent = zVal; + zVal = 0; + break; + + case 6: /* LANGUAGEID */ + assert( iOpt==6 ); + sqlite3_free(zLanguageid); + zLanguageid = zVal; + zVal = 0; + break; + + case 7: /* NOTINDEXED */ + azNotindexed[nNotindexed++] = zVal; + zVal = 0; + break; + + default: + assert( iOpt==SizeofArray(aFts4Opt) ); + sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); + rc = SQLITE_ERROR; + break; + } + sqlite3_free(zVal); + } + } + + /* Otherwise, the argument is a column name. */ + else { + nString += (int)(strlen(z) + 1); + aCol[nCol++] = z; + } + } + + /* If a content=xxx option was specified, the following: + ** + ** 1. Ignore any compress= and uncompress= options. + ** + ** 2. If no column names were specified as part of the CREATE VIRTUAL + ** TABLE statement, use all columns from the content table. + */ + if( rc==SQLITE_OK && zContent ){ + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + zCompress = 0; + zUncompress = 0; + if( nCol==0 ){ + sqlite3_free((void*)aCol); + aCol = 0; + rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr); + + /* If a languageid= option was specified, remove the language id + ** column from the aCol[] array. */ + if( rc==SQLITE_OK && zLanguageid ){ + int j; + for(j=0; jdb = db; + p->nColumn = nCol; + p->nPendingData = 0; + p->azColumn = (char **)&p[1]; + p->pTokenizer = pTokenizer; + p->nMaxPendingData = FTS3_MAX_PENDING_DATA; + p->bHasDocsize = (isFts4 && bNoDocsize==0); + p->bHasStat = (u8)isFts4; + p->bFts4 = (u8)isFts4; + p->bDescIdx = (u8)bDescIdx; + p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ + p->zContentTbl = zContent; + p->zLanguageid = zLanguageid; + zContent = 0; + zLanguageid = 0; + TESTONLY( p->inTransaction = -1 ); + TESTONLY( p->mxSavepoint = -1 ); + + p->aIndex = (struct Fts3Index *)&p->azColumn[nCol]; + memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); + p->nIndex = nIndex; + for(i=0; iaIndex[i].hPending, FTS3_HASH_STRING, 1); + } + p->abNotindexed = (u8 *)&p->aIndex[nIndex]; + + /* Fill in the zName and zDb fields of the vtab structure. */ + zCsr = (char *)&p->abNotindexed[nCol]; + p->zName = zCsr; + memcpy(zCsr, argv[2], nName); + zCsr += nName; + p->zDb = zCsr; + memcpy(zCsr, argv[1], nDb); + zCsr += nDb; + + /* Fill in the azColumn array */ + for(iCol=0; iCol0 ){ + memcpy(zCsr, z, n); + } + zCsr[n] = '\0'; + sqlite3Fts3Dequote(zCsr); + p->azColumn[iCol] = zCsr; + zCsr += n+1; + assert( zCsr <= &((char *)p)[nByte] ); + } + + /* Fill in the abNotindexed array */ + for(iCol=0; iColazColumn[iCol]); + for(i=0; iazColumn[iCol], zNot, n) + ){ + p->abNotindexed[iCol] = 1; + sqlite3_free(zNot); + azNotindexed[i] = 0; + } + } + } + for(i=0; izReadExprlist = fts3ReadExprList(p, zUncompress, &rc); + p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); + if( rc!=SQLITE_OK ) goto fts3_init_out; + + /* If this is an xCreate call, create the underlying tables in the + ** database. TODO: For xConnect(), it could verify that said tables exist. + */ + if( isCreate ){ + rc = fts3CreateTables(p); + } + + /* Check to see if a legacy fts3 table has been "upgraded" by the + ** addition of a %_stat table so that it can use incremental merge. + */ + if( !isFts4 && !isCreate ){ + p->bHasStat = 2; + } + + /* Figure out the page-size for the database. This is required in order to + ** estimate the cost of loading large doclists from the database. */ + fts3DatabasePageSize(&rc, p); + p->nNodeSize = p->nPgsz-35; + +#if defined(SQLITE_DEBUG)||defined(SQLITE_TEST) + p->nMergeCount = FTS3_MERGE_COUNT; +#endif + + /* Declare the table schema to SQLite. */ + fts3DeclareVtab(&rc, p); + +fts3_init_out: + sqlite3_free(zPrefix); + sqlite3_free(aIndex); + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + sqlite3_free(zContent); + sqlite3_free(zLanguageid); + for(i=0; ipModule->xDestroy(pTokenizer); + } + }else{ + assert( p->pSegments==0 ); + *ppVTab = &p->base; + } + return rc; +} + +/* +** The xConnect() and xCreate() methods for the virtual table. All the +** work is done in function fts3InitVtab(). +*/ +static int fts3ConnectMethod( + sqlite3 *db, /* Database connection */ + void *pAux, /* Pointer to tokenizer hash table */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + return fts3InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr); +} +static int fts3CreateMethod( + sqlite3 *db, /* Database connection */ + void *pAux, /* Pointer to tokenizer hash table */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); +} + +/* +** Set the pIdxInfo->estimatedRows variable to nRow. Unless this +** extension is currently being used by a version of SQLite too old to +** support estimatedRows. In that case this function is a no-op. +*/ +static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ +#if SQLITE_VERSION_NUMBER>=3008002 + if( sqlite3_libversion_number()>=3008002 ){ + pIdxInfo->estimatedRows = nRow; + } +#endif +} + +/* +** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this +** extension is currently being used by a version of SQLite too old to +** support index-info flags. In that case this function is a no-op. +*/ +static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){ +#if SQLITE_VERSION_NUMBER>=3008012 + if( sqlite3_libversion_number()>=3008012 ){ + pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; + } +#endif +} + +/* +** Implementation of the xBestIndex method for FTS3 tables. There +** are three possible strategies, in order of preference: +** +** 1. Direct lookup by rowid or docid. +** 2. Full-text search using a MATCH operator on a non-docid column. +** 3. Linear scan of %_content table. +*/ +static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + Fts3Table *p = (Fts3Table *)pVTab; + int i; /* Iterator variable */ + int iCons = -1; /* Index of constraint to use */ + + int iLangidCons = -1; /* Index of langid=x constraint, if present */ + int iDocidGe = -1; /* Index of docid>=x constraint, if present */ + int iDocidLe = -1; /* Index of docid<=x constraint, if present */ + int iIdx; + + if( p->bLock ){ + return SQLITE_ERROR; + } + + /* By default use a full table scan. This is an expensive option, + ** so search through the constraints to see if a more efficient + ** strategy is possible. + */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 5000000; + for(i=0; inConstraint; i++){ + int bDocid; /* True if this constraint is on docid */ + struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; + if( pCons->usable==0 ){ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + /* There exists an unusable MATCH constraint. This means that if + ** the planner does elect to use the results of this call as part + ** of the overall query plan the user will see an "unable to use + ** function MATCH in the requested context" error. To discourage + ** this, return a very high cost here. */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 1e50; + fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); + return SQLITE_OK; + } + continue; + } + + bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); + + /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ + if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){ + pInfo->idxNum = FTS3_DOCID_SEARCH; + pInfo->estimatedCost = 1.0; + iCons = i; + } + + /* A MATCH constraint. Use a full-text search. + ** + ** If there is more than one MATCH constraint available, use the first + ** one encountered. If there is both a MATCH constraint and a direct + ** rowid/docid lookup, prefer the MATCH strategy. This is done even + ** though the rowid/docid lookup is faster than a MATCH query, selecting + ** it would lead to an "unable to use function MATCH in the requested + ** context" error. + */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH + && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn + ){ + pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn; + pInfo->estimatedCost = 2.0; + iCons = i; + } + + /* Equality constraint on the langid column */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ + && pCons->iColumn==p->nColumn + 2 + ){ + iLangidCons = i; + } + + if( bDocid ){ + switch( pCons->op ){ + case SQLITE_INDEX_CONSTRAINT_GE: + case SQLITE_INDEX_CONSTRAINT_GT: + iDocidGe = i; + break; + + case SQLITE_INDEX_CONSTRAINT_LE: + case SQLITE_INDEX_CONSTRAINT_LT: + iDocidLe = i; + break; + } + } + } + + /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */ + if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo); + + iIdx = 1; + if( iCons>=0 ){ + pInfo->aConstraintUsage[iCons].argvIndex = iIdx++; + pInfo->aConstraintUsage[iCons].omit = 1; + } + if( iLangidCons>=0 ){ + pInfo->idxNum |= FTS3_HAVE_LANGID; + pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++; + } + if( iDocidGe>=0 ){ + pInfo->idxNum |= FTS3_HAVE_DOCID_GE; + pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++; + } + if( iDocidLe>=0 ){ + pInfo->idxNum |= FTS3_HAVE_DOCID_LE; + pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++; + } + + /* Regardless of the strategy selected, FTS can deliver rows in rowid (or + ** docid) order. Both ascending and descending are possible. + */ + if( pInfo->nOrderBy==1 ){ + struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; + if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){ + if( pOrder->desc ){ + pInfo->idxStr = "DESC"; + }else{ + pInfo->idxStr = "ASC"; + } + pInfo->orderByConsumed = 1; + } + } + + assert( p->pSegments==0 ); + return SQLITE_OK; +} + +/* +** Implementation of xOpen method. +*/ +static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + sqlite3_vtab_cursor *pCsr; /* Allocated cursor */ + + UNUSED_PARAMETER(pVTab); + + /* Allocate a buffer large enough for an Fts3Cursor structure. If the + ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, + ** if the allocation fails, return SQLITE_NOMEM. + */ + *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor)); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts3Cursor)); + return SQLITE_OK; +} + +/* +** Finalize the statement handle at pCsr->pStmt. +** +** Or, if that statement handle is one created by fts3CursorSeekStmt(), +** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement +** pointer there instead of finalizing it. +*/ +static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){ + if( pCsr->bSeekStmt ){ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + if( p->pSeekStmt==0 ){ + p->pSeekStmt = pCsr->pStmt; + sqlite3_reset(pCsr->pStmt); + pCsr->pStmt = 0; + } + pCsr->bSeekStmt = 0; + } + sqlite3_finalize(pCsr->pStmt); +} + +/* +** Free all resources currently held by the cursor passed as the only +** argument. +*/ +static void fts3ClearCursor(Fts3Cursor *pCsr){ + fts3CursorFinalizeStmt(pCsr); + sqlite3Fts3FreeDeferredTokens(pCsr); + sqlite3_free(pCsr->aDoclist); + sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); + sqlite3Fts3ExprFree(pCsr->pExpr); + memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); +} + +/* +** Close the cursor. For additional information see the documentation +** on the xClose method of the virtual table interface. +*/ +static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + fts3ClearCursor(pCsr); + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then +** compose and prepare an SQL statement of the form: +** +** "SELECT FROM %_content WHERE rowid = ?" +** +** (or the equivalent for a content=xxx table) and set pCsr->pStmt to +** it. If an error occurs, return an SQLite error code. +*/ +static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; + if( pCsr->pStmt==0 ){ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + char *zSql; + if( p->pSeekStmt ){ + pCsr->pStmt = p->pSeekStmt; + p->pSeekStmt = 0; + }else{ + zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); + if( !zSql ) return SQLITE_NOMEM; + p->bLock++; + rc = sqlite3_prepare_v3( + p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 + ); + p->bLock--; + sqlite3_free(zSql); + } + if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1; + } + return rc; +} + +/* +** Position the pCsr->pStmt statement so that it is on the row +** of the %_content table that contains the last match. Return +** SQLITE_OK on success. +*/ +static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ + int rc = SQLITE_OK; + if( pCsr->isRequireSeek ){ + rc = fts3CursorSeekStmt(pCsr); + if( rc==SQLITE_OK ){ + Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab; + pTab->bLock++; + sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); + pCsr->isRequireSeek = 0; + if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ + pTab->bLock--; + return SQLITE_OK; + }else{ + pTab->bLock--; + rc = sqlite3_reset(pCsr->pStmt); + if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){ + /* If no row was found and no error has occurred, then the %_content + ** table is missing a row that is present in the full-text index. + ** The data structures are corrupt. */ + rc = FTS_CORRUPT_VTAB; + pCsr->isEof = 1; + } + } + } + } + + if( rc!=SQLITE_OK && pContext ){ + sqlite3_result_error_code(pContext, rc); + } + return rc; +} + +/* +** This function is used to process a single interior node when searching +** a b-tree for a term or term prefix. The node data is passed to this +** function via the zNode/nNode parameters. The term to search for is +** passed in zTerm/nTerm. +** +** If piFirst is not NULL, then this function sets *piFirst to the blockid +** of the child node that heads the sub-tree that may contain the term. +** +** If piLast is not NULL, then *piLast is set to the right-most child node +** that heads a sub-tree that may contain a term for which zTerm/nTerm is +** a prefix. +** +** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. +*/ +static int fts3ScanInteriorNode( + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piFirst, /* OUT: Selected child node */ + sqlite3_int64 *piLast /* OUT: Selected child node */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zCsr = zNode; /* Cursor to iterate through node */ + const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ + char *zBuffer = 0; /* Buffer to load terms into */ + i64 nAlloc = 0; /* Size of allocated buffer */ + int isFirstTerm = 1; /* True when processing first term on page */ + u64 iChild; /* Block id of child node to descend to */ + int nBuffer = 0; /* Total term size */ + + /* Skip over the 'height' varint that occurs at the start of every + ** interior node. Then load the blockid of the left-child of the b-tree + ** node into variable iChild. + ** + ** Even if the data structure on disk is corrupted, this (reading two + ** varints from the buffer) does not risk an overread. If zNode is a + ** root node, then the buffer comes from a SELECT statement. SQLite does + ** not make this guarantee explicitly, but in practice there are always + ** either more than 20 bytes of allocated space following the nNode bytes of + ** contents, or two zero bytes. Or, if the node is read from the %_segments + ** table, then there are always 20 bytes of zeroed padding following the + ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). + */ + zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild); + if( zCsr>zEnd ){ + return FTS_CORRUPT_VTAB; + } + + while( zCsrnBuffer ){ + rc = FTS_CORRUPT_VTAB; + goto finish_scan; + } + } + isFirstTerm = 0; + zCsr += fts3GetVarint32(zCsr, &nSuffix); + + assert( nPrefix>=0 && nSuffix>=0 ); + if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr || nSuffix==0 ){ + rc = FTS_CORRUPT_VTAB; + goto finish_scan; + } + if( (i64)nPrefix+nSuffix>nAlloc ){ + char *zNew; + nAlloc = ((i64)nPrefix+nSuffix) * 2; + zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc); + if( !zNew ){ + rc = SQLITE_NOMEM; + goto finish_scan; + } + zBuffer = zNew; + } + assert( zBuffer ); + memcpy(&zBuffer[nPrefix], zCsr, nSuffix); + nBuffer = nPrefix + nSuffix; + zCsr += nSuffix; + + /* Compare the term we are searching for with the term just loaded from + ** the interior node. If the specified term is greater than or equal + ** to the term from the interior node, then all terms on the sub-tree + ** headed by node iChild are smaller than zTerm. No need to search + ** iChild. + ** + ** If the interior node term is larger than the specified term, then + ** the tree headed by iChild may contain the specified term. + */ + cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); + if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){ + *piFirst = (i64)iChild; + piFirst = 0; + } + + if( piLast && cmp<0 ){ + *piLast = (i64)iChild; + piLast = 0; + } + + iChild++; + }; + + if( piFirst ) *piFirst = (i64)iChild; + if( piLast ) *piLast = (i64)iChild; + + finish_scan: + sqlite3_free(zBuffer); + return rc; +} + + +/* +** The buffer pointed to by argument zNode (size nNode bytes) contains an +** interior node of a b-tree segment. The zTerm buffer (size nTerm bytes) +** contains a term. This function searches the sub-tree headed by the zNode +** node for the range of leaf nodes that may contain the specified term +** or terms for which the specified term is a prefix. +** +** If piLeaf is not NULL, then *piLeaf is set to the blockid of the +** left-most leaf node in the tree that may contain the specified term. +** If piLeaf2 is not NULL, then *piLeaf2 is set to the blockid of the +** right-most leaf node that may contain a term for which the specified +** term is a prefix. +** +** It is possible that the range of returned leaf nodes does not contain +** the specified term or any terms for which it is a prefix. However, if the +** segment does contain any such terms, they are stored within the identified +** range. Because this function only inspects interior segment nodes (and +** never loads leaf nodes into memory), it is not possible to be sure. +** +** If an error occurs, an error code other than SQLITE_OK is returned. +*/ +static int fts3SelectLeaf( + Fts3Table *p, /* Virtual table handle */ + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piLeaf, /* Selected leaf node */ + sqlite3_int64 *piLeaf2 /* Selected leaf node */ +){ + int rc = SQLITE_OK; /* Return code */ + int iHeight; /* Height of this node in tree */ + + assert( piLeaf || piLeaf2 ); + + fts3GetVarint32(zNode, &iHeight); + rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); + assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); + + if( rc==SQLITE_OK && iHeight>1 ){ + char *zBlob = 0; /* Blob read from %_segments table */ + int nBlob = 0; /* Size of zBlob in bytes */ + + if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ + rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); + if( rc==SQLITE_OK ){ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); + } + sqlite3_free(zBlob); + piLeaf = 0; + zBlob = 0; + } + + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); + } + if( rc==SQLITE_OK ){ + int iNewHeight = 0; + fts3GetVarint32(zBlob, &iNewHeight); + if( iNewHeight>=iHeight ){ + rc = FTS_CORRUPT_VTAB; + }else{ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); + } + } + sqlite3_free(zBlob); + } + + return rc; +} + +/* +** This function is used to create delta-encoded serialized lists of FTS3 +** varints. Each call to this function appends a single varint to a list. +*/ +static void fts3PutDeltaVarint( + char **pp, /* IN/OUT: Output pointer */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + assert_fts3_nc( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); + *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); + *piPrev = iVal; +} + +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a position-list. After it returns, *ppPoslist points to the +** first byte after the position-list. +** +** A position list is list of positions (delta encoded) and columns for +** a single document record of a doclist. So, in other words, this +** routine advances *ppPoslist so that it points to the next docid in +** the doclist, or to the first byte past the end of the doclist. +** +** If pp is not NULL, then the contents of the position list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. +*/ +static void fts3PoslistCopy(char **pp, char **ppPoslist){ + char *pEnd = *ppPoslist; + char c = 0; + + /* The end of a position list is marked by a zero encoded as an FTS3 + ** varint. A single POS_END (0) byte. Except, if the 0 byte is preceded by + ** a byte with the 0x80 bit set, then it is not a varint 0, but the tail + ** of some other, multi-byte, value. + ** + ** The following while-loop moves pEnd to point to the first byte that is not + ** immediately preceded by a byte with the 0x80 bit set. Then increments + ** pEnd once more so that it points to the byte immediately following the + ** last byte in the position-list. + */ + while( *pEnd | c ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && (*pEnd)==0 ); + } + pEnd++; /* Advance past the POS_END terminator byte */ + + if( pp ){ + int n = (int)(pEnd - *ppPoslist); + char *p = *pp; + memcpy(p, *ppPoslist, n); + p += n; + *pp = p; + } + *ppPoslist = pEnd; +} + +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a column-list. After it returns, *ppPoslist points to the +** to the terminator (POS_COLUMN or POS_END) byte of the column-list. +** +** A column-list is list of delta-encoded positions for a single column +** within a single document within a doclist. +** +** The column-list is terminated either by a POS_COLUMN varint (1) or +** a POS_END varint (0). This routine leaves *ppPoslist pointing to +** the POS_COLUMN or POS_END that terminates the column-list. +** +** If pp is not NULL, then the contents of the column-list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. The POS_COLUMN or POS_END terminator +** is not copied into *pp. +*/ +static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ + char *pEnd = *ppPoslist; + char c = 0; + + /* A column-list is terminated by either a 0x01 or 0x00 byte that is + ** not part of a multi-byte varint. + */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && ((*pEnd)&0xfe)==0 ); + } + if( pp ){ + int n = (int)(pEnd - *ppPoslist); + char *p = *pp; + memcpy(p, *ppPoslist, n); + p += n; + *pp = p; + } + *ppPoslist = pEnd; +} + +/* +** Value used to signify the end of an position-list. This must be +** as large or larger than any value that might appear on the +** position-list, even a position list that has been corrupted. +*/ +#define POSITION_LIST_END LARGEST_INT64 + +/* +** This function is used to help parse position-lists. When this function is +** called, *pp may point to the start of the next varint in the position-list +** being parsed, or it may point to 1 byte past the end of the position-list +** (in which case **pp will be a terminator bytes POS_END (0) or +** (1)). +** +** If *pp points past the end of the current position-list, set *pi to +** POSITION_LIST_END and return. Otherwise, read the next varint from *pp, +** increment the current value of *pi by the value read, and set *pp to +** point to the next value before returning. +** +** Before calling this routine *pi must be initialized to the value of +** the previous position, or zero if we are reading the first position +** in the position-list. Because positions are delta-encoded, the value +** of the previous position is needed in order to compute the value of +** the next position. +*/ +static void fts3ReadNextPos( + char **pp, /* IN/OUT: Pointer into position-list buffer */ + sqlite3_int64 *pi /* IN/OUT: Value read from position-list */ +){ + if( (**pp)&0xFE ){ + int iVal; + *pp += fts3GetVarint32((*pp), &iVal); + *pi += iVal; + *pi -= 2; + }else{ + *pi = POSITION_LIST_END; + } +} + +/* +** If parameter iCol is not 0, write an POS_COLUMN (1) byte followed by +** the value of iCol encoded as a varint to *pp. This will start a new +** column list. +** +** Set *pp to point to the byte just after the last byte written before +** returning (do not modify it if iCol==0). Return the total number of bytes +** written (0 if iCol==0). +*/ +static int fts3PutColNumber(char **pp, int iCol){ + int n = 0; /* Number of bytes written */ + if( iCol ){ + char *p = *pp; /* Output pointer */ + n = 1 + sqlite3Fts3PutVarint(&p[1], iCol); + *p = 0x01; + *pp = &p[n]; + } + return n; +} + +/* +** Compute the union of two position lists. The output written +** into *pp contains all positions of both *pp1 and *pp2 in sorted +** order and with any duplicates removed. All pointers are +** updated appropriately. The caller is responsible for insuring +** that there is enough space in *pp to hold the complete output. +*/ +static int fts3PoslistMerge( + char **pp, /* Output buffer */ + char **pp1, /* Left input list */ + char **pp2 /* Right input list */ +){ + char *p = *pp; + char *p1 = *pp1; + char *p2 = *pp2; + + while( *p1 || *p2 ){ + int iCol1; /* The current column index in pp1 */ + int iCol2; /* The current column index in pp2 */ + + if( *p1==POS_COLUMN ){ + fts3GetVarint32(&p1[1], &iCol1); + if( iCol1==0 ) return FTS_CORRUPT_VTAB; + } + else if( *p1==POS_END ) iCol1 = 0x7fffffff; + else iCol1 = 0; + + if( *p2==POS_COLUMN ){ + fts3GetVarint32(&p2[1], &iCol2); + if( iCol2==0 ) return FTS_CORRUPT_VTAB; + } + else if( *p2==POS_END ) iCol2 = 0x7fffffff; + else iCol2 = 0; + + if( iCol1==iCol2 ){ + sqlite3_int64 i1 = 0; /* Last position from pp1 */ + sqlite3_int64 i2 = 0; /* Last position from pp2 */ + sqlite3_int64 iPrev = 0; + int n = fts3PutColNumber(&p, iCol1); + p1 += n; + p2 += n; + + /* At this point, both p1 and p2 point to the start of column-lists + ** for the same column (the column with index iCol1 and iCol2). + ** A column-list is a list of non-negative delta-encoded varints, each + ** incremented by 2 before being stored. Each list is terminated by a + ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists + ** and writes the results to buffer p. p is left pointing to the byte + ** after the list written. No terminator (POS_END or POS_COLUMN) is + ** written to the output. + */ + fts3GetDeltaVarint(&p1, &i1); + fts3GetDeltaVarint(&p2, &i2); + if( i1<2 || i2<2 ){ + break; + } + do { + fts3PutDeltaVarint(&p, &iPrev, (i1pos(*pp1) && pos(*pp2)-pos(*pp1)<=nToken). i.e. +** when the *pp1 token appears before the *pp2 token, but not more than nToken +** slots before it. +** +** e.g. nToken==1 searches for adjacent positions. +*/ +static int fts3PoslistPhraseMerge( + char **pp, /* IN/OUT: Preallocated output buffer */ + int nToken, /* Maximum difference in token positions */ + int isSaveLeft, /* Save the left position */ + int isExact, /* If *pp1 is exactly nTokens before *pp2 */ + char **pp1, /* IN/OUT: Left input list */ + char **pp2 /* IN/OUT: Right input list */ +){ + char *p = *pp; + char *p1 = *pp1; + char *p2 = *pp2; + int iCol1 = 0; + int iCol2 = 0; + + /* Never set both isSaveLeft and isExact for the same invocation. */ + assert( isSaveLeft==0 || isExact==0 ); + + assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 ); + if( *p1==POS_COLUMN ){ + p1++; + p1 += fts3GetVarint32(p1, &iCol1); + } + if( *p2==POS_COLUMN ){ + p2++; + p2 += fts3GetVarint32(p2, &iCol2); + } + + while( 1 ){ + if( iCol1==iCol2 ){ + char *pSave = p; + sqlite3_int64 iPrev = 0; + sqlite3_int64 iPos1 = 0; + sqlite3_int64 iPos2 = 0; + + if( iCol1 ){ + *p++ = POS_COLUMN; + p += sqlite3Fts3PutVarint(p, iCol1); + } + + fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; + fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + if( iPos1<0 || iPos2<0 ) break; + + while( 1 ){ + if( iPos2==iPos1+nToken + || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) + ){ + sqlite3_int64 iSave; + iSave = isSaveLeft ? iPos1 : iPos2; + fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2; + pSave = 0; + assert( p ); + } + if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){ + if( (*p2&0xFE)==0 ) break; + fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + }else{ + if( (*p1&0xFE)==0 ) break; + fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; + } + } + + if( pSave ){ + assert( pp && p ); + p = pSave; + } + + fts3ColumnlistCopy(0, &p1); + fts3ColumnlistCopy(0, &p2); + assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 ); + if( 0==*p1 || 0==*p2 ) break; + + p1++; + p1 += fts3GetVarint32(p1, &iCol1); + p2++; + p2 += fts3GetVarint32(p2, &iCol2); + } + + /* Advance pointer p1 or p2 (whichever corresponds to the smaller of + ** iCol1 and iCol2) so that it points to either the 0x00 that marks the + ** end of the position list, or the 0x01 that precedes the next + ** column-number in the position list. + */ + else if( iCol1=pEnd ){ + *pp = 0; + }else{ + u64 iVal; + *pp += sqlite3Fts3GetVarintU(*pp, &iVal); + if( bDescIdx ){ + *pVal = (i64)((u64)*pVal - iVal); + }else{ + *pVal = (i64)((u64)*pVal + iVal); + } + } +} + +/* +** This function is used to write a single varint to a buffer. The varint +** is written to *pp. Before returning, *pp is set to point 1 byte past the +** end of the value written. +** +** If *pbFirst is zero when this function is called, the value written to +** the buffer is that of parameter iVal. +** +** If *pbFirst is non-zero when this function is called, then the value +** written is either (iVal-*piPrev) (if bDescIdx is zero) or (*piPrev-iVal) +** (if bDescIdx is non-zero). +** +** Before returning, this function always sets *pbFirst to 1 and *piPrev +** to the value of parameter iVal. +*/ +static void fts3PutDeltaVarint3( + char **pp, /* IN/OUT: Output pointer */ + int bDescIdx, /* True for descending docids */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + int *pbFirst, /* IN/OUT: True after first int written */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + sqlite3_uint64 iWrite; + if( bDescIdx==0 || *pbFirst==0 ){ + assert_fts3_nc( *pbFirst==0 || iVal>=*piPrev ); + iWrite = (u64)iVal - (u64)*piPrev; + }else{ + assert_fts3_nc( *piPrev>=iVal ); + iWrite = (u64)*piPrev - (u64)iVal; + } + assert( *pbFirst || *piPrev==0 ); + assert_fts3_nc( *pbFirst==0 || iWrite>0 ); + *pp += sqlite3Fts3PutVarint(*pp, iWrite); + *piPrev = iVal; + *pbFirst = 1; +} + + +/* +** This macro is used by various functions that merge doclists. The two +** arguments are 64-bit docid values. If the value of the stack variable +** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2). +** Otherwise, (i2-i1). +** +** Using this makes it easier to write code that can merge doclists that are +** sorted in either ascending or descending order. +*/ +/* #define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i64)((u64)i1-i2)) */ +#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1>i2?1:((i1==i2)?0:-1))) + +/* +** This function does an "OR" merge of two doclists (output contains all +** positions contained in either argument doclist). If the docids in the +** input doclists are sorted in ascending order, parameter bDescDoclist +** should be false. If they are sorted in ascending order, it should be +** passed a non-zero value. +** +** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer +** containing the output doclist and SQLITE_OK is returned. In this case +** *pnOut is set to the number of bytes in the output doclist. +** +** If an error occurs, an SQLite error code is returned. The output values +** are undefined in this case. +*/ +static int fts3DoclistOrMerge( + int bDescDoclist, /* True if arguments are desc */ + char *a1, int n1, /* First doclist */ + char *a2, int n2, /* Second doclist */ + char **paOut, int *pnOut /* OUT: Malloc'd doclist */ +){ + int rc = SQLITE_OK; + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *pEnd1 = &a1[n1]; + char *pEnd2 = &a2[n2]; + char *p1 = a1; + char *p2 = a2; + char *p; + char *aOut; + int bFirstOut = 0; + + *paOut = 0; + *pnOut = 0; + + /* Allocate space for the output. Both the input and output doclists + ** are delta encoded. If they are in ascending order (bDescDoclist==0), + ** then the first docid in each list is simply encoded as a varint. For + ** each subsequent docid, the varint stored is the difference between the + ** current and previous docid (a positive number - since the list is in + ** ascending order). + ** + ** The first docid written to the output is therefore encoded using the + ** same number of bytes as it is in whichever of the input lists it is + ** read from. And each subsequent docid read from the same input list + ** consumes either the same or less bytes as it did in the input (since + ** the difference between it and the previous value in the output must + ** be a positive value less than or equal to the delta value read from + ** the input list). The same argument applies to all but the first docid + ** read from the 'other' list. And to the contents of all position lists + ** that will be copied and merged from the input to the output. + ** + ** However, if the first docid copied to the output is a negative number, + ** then the encoding of the first docid from the 'other' input list may + ** be larger in the output than it was in the input (since the delta value + ** may be a larger positive integer than the actual docid). + ** + ** The space required to store the output is therefore the sum of the + ** sizes of the two inputs, plus enough space for exactly one of the input + ** docids to grow. + ** + ** A symetric argument may be made if the doclists are in descending + ** order. + */ + aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); + if( !aOut ) return SQLITE_NOMEM; + + p = aOut; + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + while( p1 || p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + + if( p2 && p1 && iDiff==0 ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + rc = fts3PoslistMerge(&p, &p1, &p2); + if( rc ) break; + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( !p2 || (p1 && iDiff<0) ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + fts3PoslistCopy(&p, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2); + fts3PoslistCopy(&p, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } + + assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) ); + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + p = aOut = 0; + }else{ + assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 ); + memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING); + } + *paOut = aOut; + *pnOut = (int)(p-aOut); + return rc; +} + +/* +** This function does a "phrase" merge of two doclists. In a phrase merge, +** the output contains a copy of each position from the right-hand input +** doclist for which there is a position in the left-hand input doclist +** exactly nDist tokens before it. +** +** If the docids in the input doclists are sorted in ascending order, +** parameter bDescDoclist should be false. If they are sorted in ascending +** order, it should be passed a non-zero value. +** +** The right-hand input doclist is overwritten by this function. +*/ +static int fts3DoclistPhraseMerge( + int bDescDoclist, /* True if arguments are desc */ + int nDist, /* Distance from left to right (1=adjacent) */ + char *aLeft, int nLeft, /* Left doclist */ + char **paRight, int *pnRight /* IN/OUT: Right/output doclist */ +){ + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *aRight = *paRight; + char *pEnd1 = &aLeft[nLeft]; + char *pEnd2 = &aRight[*pnRight]; + char *p1 = aLeft; + char *p2 = aRight; + char *p; + int bFirstOut = 0; + char *aOut; + + assert( nDist>0 ); + if( bDescDoclist ){ + aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX); + if( aOut==0 ) return SQLITE_NOMEM; + }else{ + aOut = aRight; + } + p = aOut; + + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + + while( p1 && p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + if( iDiff==0 ){ + char *pSave = p; + sqlite3_int64 iPrevSave = iPrev; + int bFirstOutSave = bFirstOut; + + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + if( 0==fts3PoslistPhraseMerge(&p, nDist, 0, 1, &p1, &p2) ){ + p = pSave; + iPrev = iPrevSave; + bFirstOut = bFirstOutSave; + } + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( iDiff<0 ){ + fts3PoslistCopy(0, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PoslistCopy(0, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } + } + + *pnRight = (int)(p - aOut); + if( bDescDoclist ){ + sqlite3_free(aRight); + *paRight = aOut; + } + + return SQLITE_OK; +} + +/* +** Argument pList points to a position list nList bytes in size. This +** function checks to see if the position list contains any entries for +** a token in position 0 (of any column). If so, it writes argument iDelta +** to the output buffer pOut, followed by a position list consisting only +** of the entries from pList at position 0, and terminated by an 0x00 byte. +** The value returned is the number of bytes written to pOut (if any). +*/ +SQLITE_PRIVATE int sqlite3Fts3FirstFilter( + sqlite3_int64 iDelta, /* Varint that may be written to pOut */ + char *pList, /* Position list (no 0x00 term) */ + int nList, /* Size of pList in bytes */ + char *pOut /* Write output here */ +){ + int nOut = 0; + int bWritten = 0; /* True once iDelta has been written */ + char *p = pList; + char *pEnd = &pList[nList]; + + if( *p!=0x01 ){ + if( *p==0x02 ){ + nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta); + pOut[nOut++] = 0x02; + bWritten = 1; + } + fts3ColumnlistCopy(0, &p); + } + + while( paaOutput); i++){ + if( pTS->aaOutput[i] ){ + if( !aOut ){ + aOut = pTS->aaOutput[i]; + nOut = pTS->anOutput[i]; + pTS->aaOutput[i] = 0; + }else{ + int nNew; + char *aNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, + pTS->aaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + return rc; + } + + sqlite3_free(pTS->aaOutput[i]); + sqlite3_free(aOut); + pTS->aaOutput[i] = 0; + aOut = aNew; + nOut = nNew; + } + } + } + + pTS->aaOutput[0] = aOut; + pTS->anOutput[0] = nOut; + return SQLITE_OK; +} + +/* +** Merge the doclist aDoclist/nDoclist into the TermSelect object passed +** as the first argument. The merge is an "OR" merge (see function +** fts3DoclistOrMerge() for details). +** +** This function is called with the doclist for each term that matches +** a queried prefix. It merges all these doclists into one, the doclist +** for the specified prefix. Since there can be a very large number of +** doclists to merge, the merging is done pair-wise using the TermSelect +** object. +** +** This function returns SQLITE_OK if the merge is successful, or an +** SQLite error code (SQLITE_NOMEM) if an error occurs. +*/ +static int fts3TermSelectMerge( + Fts3Table *p, /* FTS table handle */ + TermSelect *pTS, /* TermSelect object to merge into */ + char *aDoclist, /* Pointer to doclist */ + int nDoclist /* Size of aDoclist in bytes */ +){ + if( pTS->aaOutput[0]==0 ){ + /* If this is the first term selected, copy the doclist to the output + ** buffer using memcpy(). + ** + ** Add FTS3_VARINT_MAX bytes of unused space to the end of the + ** allocation. This is so as to ensure that the buffer is big enough + ** to hold the current doclist AND'd with any other doclist. If the + ** doclists are stored in order=ASC order, this padding would not be + ** required (since the size of [doclistA AND doclistB] is always less + ** than or equal to the size of [doclistA] in that case). But this is + ** not true for order=DESC. For example, a doclist containing (1, -1) + ** may be smaller than (-1), as in the first example the -1 may be stored + ** as a single-byte delta, whereas in the second it must be stored as a + ** FTS3_VARINT_MAX byte varint. + ** + ** Similar padding is added in the fts3DoclistOrMerge() function. + */ + pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1); + pTS->anOutput[0] = nDoclist; + if( pTS->aaOutput[0] ){ + memcpy(pTS->aaOutput[0], aDoclist, nDoclist); + memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX); + }else{ + return SQLITE_NOMEM; + } + }else{ + char *aMerge = aDoclist; + int nMerge = nDoclist; + int iOut; + + for(iOut=0; iOutaaOutput); iOut++){ + if( pTS->aaOutput[iOut]==0 ){ + assert( iOut>0 ); + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + break; + }else{ + char *aNew; + int nNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, aMerge, nMerge, + pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + return rc; + } + + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + sqlite3_free(pTS->aaOutput[iOut]); + pTS->aaOutput[iOut] = 0; + + aMerge = aNew; + nMerge = nNew; + if( (iOut+1)==SizeofArray(pTS->aaOutput) ){ + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + } + } + } + } + return SQLITE_OK; +} + +/* +** Append SegReader object pNew to the end of the pCsr->apSegment[] array. +*/ +static int fts3SegReaderCursorAppend( + Fts3MultiSegReader *pCsr, + Fts3SegReader *pNew +){ + if( (pCsr->nSegment%16)==0 ){ + Fts3SegReader **apNew; + sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); + apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte); + if( !apNew ){ + sqlite3Fts3SegReaderFree(pNew); + return SQLITE_NOMEM; + } + pCsr->apSegment = apNew; + } + pCsr->apSegment[pCsr->nSegment++] = pNew; + return SQLITE_OK; +} + +/* +** Add seg-reader objects to the Fts3MultiSegReader object passed as the +** 8th argument. +** +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. +*/ +static int fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + int rc = SQLITE_OK; /* Error code */ + sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ + int rc2; /* Result of sqlite3_reset() */ + + /* If iLevel is less than 0 and this is not a scan, include a seg-reader + ** for the pending-terms. If this is a scan, then this call must be being + ** made by an fts4aux module, not an FTS table. In this case calling + ** Fts3SegReaderPending might segfault, as the data structures used by + ** fts4aux are not completely populated. So it's easiest to filter these + ** calls out here. */ + if( iLevel<0 && p->aIndex && p->iPrevLangid==iLangid ){ + Fts3SegReader *pSeg = 0; + rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); + if( rc==SQLITE_OK && pSeg ){ + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } + } + + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); + } + + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + Fts3SegReader *pSeg = 0; + + /* Read the values returned by the SELECT into local variables. */ + sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1); + sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2); + sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3); + int nRoot = sqlite3_column_bytes(pStmt, 4); + char const *zRoot = sqlite3_column_blob(pStmt, 4); + + /* If zTerm is not NULL, and this segment is not stored entirely on its + ** root node, the range of leaves scanned can be reduced. Do this. */ + if( iStartBlock && zTerm && zRoot ){ + sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); + rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); + if( rc!=SQLITE_OK ) goto finished; + if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; + } + + rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, + (isPrefix==0 && isScan==0), + iStartBlock, iLeavesEndBlock, + iEndBlock, zRoot, nRoot, &pSeg + ); + if( rc!=SQLITE_OK ) goto finished; + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } + } + + finished: + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_DONE ) rc = rc2; + + return rc; +} + +/* +** Set up a cursor object for iterating through a full-text index or a +** single level therein. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language-id to search */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + assert( iIndex>=0 && iIndexnIndex ); + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevelbase.pVtab; + + if( isPrefix ){ + for(i=1; bFound==0 && inIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr + ); + pSegcsr->bLookup = 1; + } + } + + for(i=1; bFound==0 && inIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm+1 ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr + ); + if( rc==SQLITE_OK ){ + rc = fts3SegReaderCursorAddZero( + p, pCsr->iLangid, zTerm, nTerm, pSegcsr + ); + } + } + } + } + + if( bFound==0 ){ + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr + ); + pSegcsr->bLookup = !isPrefix; + } + } + + *ppSegcsr = pSegcsr; + return rc; +} + +/* +** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor(). +*/ +static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){ + sqlite3Fts3SegReaderFinish(pSegcsr); + sqlite3_free(pSegcsr); +} + +/* +** This function retrieves the doclist for the specified term (or term +** prefix) from the database. +*/ +static int fts3TermSelect( + Fts3Table *p, /* Virtual table handle */ + Fts3PhraseToken *pTok, /* Token to query for */ + int iColumn, /* Column to query (or -ve for all columns) */ + int *pnOut, /* OUT: Size of buffer at *ppOut */ + char **ppOut /* OUT: Malloced result buffer */ +){ + int rc; /* Return code */ + Fts3MultiSegReader *pSegcsr; /* Seg-reader cursor for this term */ + TermSelect tsc; /* Object for pair-wise doclist merging */ + Fts3SegFilter filter; /* Segment term filter configuration */ + + pSegcsr = pTok->pSegcsr; + memset(&tsc, 0, sizeof(TermSelect)); + + filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS + | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0) + | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0) + | (iColumnnColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0); + filter.iCol = iColumn; + filter.zTerm = pTok->z; + filter.nTerm = pTok->n; + + rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter); + while( SQLITE_OK==rc + && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr)) + ){ + rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist); + } + + if( rc==SQLITE_OK ){ + rc = fts3TermSelectFinishMerge(p, &tsc); + } + if( rc==SQLITE_OK ){ + *ppOut = tsc.aaOutput[0]; + *pnOut = tsc.anOutput[0]; + }else{ + int i; + for(i=0; ipSegcsr = 0; + return rc; +} + +/* +** This function counts the total number of docids in the doclist stored +** in buffer aList[], size nList bytes. +** +** If the isPoslist argument is true, then it is assumed that the doclist +** contains a position-list following each docid. Otherwise, it is assumed +** that the doclist is simply a list of docids stored as delta encoded +** varints. +*/ +static int fts3DoclistCountDocids(char *aList, int nList){ + int nDoc = 0; /* Return value */ + if( aList ){ + char *aEnd = &aList[nList]; /* Pointer to one byte after EOF */ + char *p = aList; /* Cursor */ + while( peSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ + Fts3Table *pTab = (Fts3Table*)pCursor->pVtab; + pTab->bLock++; + if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ + pCsr->isEof = 1; + rc = sqlite3_reset(pCsr->pStmt); + }else{ + pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); + rc = SQLITE_OK; + } + pTab->bLock--; + }else{ + rc = fts3EvalNext((Fts3Cursor *)pCursor); + } + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + return rc; +} + +/* +** If the numeric type of argument pVal is "integer", then return it +** converted to a 64-bit signed integer. Otherwise, return a copy of +** the second parameter, iDefault. +*/ +static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ + if( pVal ){ + int eType = sqlite3_value_numeric_type(pVal); + if( eType==SQLITE_INTEGER ){ + return sqlite3_value_int64(pVal); + } + } + return iDefault; +} + +/* +** This is the xFilter interface for the virtual table. See +** the virtual table xFilter method documentation for additional +** information. +** +** If idxNum==FTS3_FULLSCAN_SEARCH then do a full table scan against +** the %_content table. +** +** If idxNum==FTS3_DOCID_SEARCH then do a docid lookup for a single entry +** in the %_content table. +** +** If idxNum>=FTS3_FULLTEXT_SEARCH then use the full text index. The +** column on the left-hand side of the MATCH operator is column +** number idxNum-FTS3_FULLTEXT_SEARCH, 0 indexed. argv[0] is the right-hand +** side of the MATCH operator. +*/ +static int fts3FilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_OK; + char *zSql; /* SQL statement used to access %_content */ + int eSearch; + Fts3Table *p = (Fts3Table *)pCursor->pVtab; + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + + sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ + sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ + sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ + sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ + int iIdx; + + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(nVal); + + if( p->bLock ){ + return SQLITE_ERROR; + } + + eSearch = (idxNum & 0x0000FFFF); + assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); + assert( p->pSegments==0 ); + + /* Collect arguments into local variables */ + iIdx = 0; + if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++]; + assert( iIdx==nVal ); + + /* In case the cursor has been used before, clear it now. */ + fts3ClearCursor(pCsr); + + /* Set the lower and upper bounds on docids to return */ + pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); + pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64); + + if( idxStr ){ + pCsr->bDesc = (idxStr[0]=='D'); + }else{ + pCsr->bDesc = p->bDescIdx; + } + pCsr->eSearch = (i16)eSearch; + + if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ + int iCol = eSearch-FTS3_FULLTEXT_SEARCH; + const char *zQuery = (const char *)sqlite3_value_text(pCons); + + if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ + return SQLITE_NOMEM; + } + + pCsr->iLangid = 0; + if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); + + assert( p->base.zErrMsg==0 ); + rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, + p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, + &p->base.zErrMsg + ); + if( rc!=SQLITE_OK ){ + return rc; + } + + rc = fts3EvalStart(pCsr); + sqlite3Fts3SegmentsClose(p); + if( rc!=SQLITE_OK ) return rc; + pCsr->pNextId = pCsr->aDoclist; + pCsr->iPrevId = 0; + } + + /* Compile a SELECT statement for this cursor. For a full-table-scan, the + ** statement loops through all rows of the %_content table. For a + ** full-text query or docid lookup, the statement retrieves a single + ** row by docid. + */ + if( eSearch==FTS3_FULLSCAN_SEARCH ){ + if( pDocidGe || pDocidLe ){ + zSql = sqlite3_mprintf( + "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", + p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, + (pCsr->bDesc ? "DESC" : "ASC") + ); + }else{ + zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", + p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") + ); + } + if( zSql ){ + p->bLock++; + rc = sqlite3_prepare_v3( + p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 + ); + p->bLock--; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + }else if( eSearch==FTS3_DOCID_SEARCH ){ + rc = fts3CursorSeekStmt(pCsr); + if( rc==SQLITE_OK ){ + rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); + } + } + if( rc!=SQLITE_OK ) return rc; + + return fts3NextMethod(pCursor); +} + +/* +** This is the xEof method of the virtual table. SQLite calls this +** routine to find out if it has reached the end of a result set. +*/ +static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Cursor *pCsr = (Fts3Cursor*)pCursor; + if( pCsr->isEof ){ + fts3ClearCursor(pCsr); + pCsr->isEof = 1; + } + return pCsr->isEof; +} + +/* +** This is the xRowid method. The SQLite core calls this routine to +** retrieve the rowid for the current row of the result set. fts3 +** exposes %_content.docid as the rowid for the virtual table. The +** rowid should be written to *pRowid. +*/ +static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; + *pRowid = pCsr->iPrevId; + return SQLITE_OK; +} + +/* +** This is the xColumn method, called by SQLite to request a value from +** the row that the supplied cursor currently points to. +** +** If: +** +** (iCol < p->nColumn) -> The value of the iCol'th user column. +** (iCol == p->nColumn) -> Magic column with the same name as the table. +** (iCol == p->nColumn+1) -> Docid column +** (iCol == p->nColumn+2) -> Langid column +*/ +static int fts3ColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; + Fts3Table *p = (Fts3Table *)pCursor->pVtab; + + /* The column value supplied by SQLite must be in range. */ + assert( iCol>=0 && iCol<=p->nColumn+2 ); + + switch( iCol-p->nColumn ){ + case 0: + /* The special 'table-name' column */ + sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0); + break; + + case 1: + /* The docid column */ + sqlite3_result_int64(pCtx, pCsr->iPrevId); + break; + + case 2: + if( pCsr->pExpr ){ + sqlite3_result_int64(pCtx, pCsr->iLangid); + break; + }else if( p->zLanguageid==0 ){ + sqlite3_result_int(pCtx, 0); + break; + }else{ + iCol = p->nColumn; + /* no break */ deliberate_fall_through + } + + default: + /* A user column. Or, if this is a full-table scan, possibly the + ** language-id column. Seek the cursor. */ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){ + sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + } + break; + } + + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + return rc; +} + +/* +** This function is the implementation of the xUpdate callback used by +** FTS3 virtual tables. It is invoked by SQLite each time a row is to be +** inserted, updated or deleted. +*/ +static int fts3UpdateMethod( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Size of argument array */ + sqlite3_value **apVal, /* Array of arguments */ + sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ +){ + return sqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid); +} + +/* +** Implementation of xSync() method. Flush the contents of the pending-terms +** hash-table to the database. +*/ +static int fts3SyncMethod(sqlite3_vtab *pVtab){ + + /* Following an incremental-merge operation, assuming that the input + ** segments are not completely consumed (the usual case), they are updated + ** in place to remove the entries that have already been merged. This + ** involves updating the leaf block that contains the smallest unmerged + ** entry and each block (if any) between the leaf and the root node. So + ** if the height of the input segment b-trees is N, and input segments + ** are merged eight at a time, updating the input segments at the end + ** of an incremental-merge requires writing (8*(1+N)) blocks. N is usually + ** small - often between 0 and 2. So the overhead of the incremental + ** merge is somewhere between 8 and 24 blocks. To avoid this overhead + ** dwarfing the actual productive work accomplished, the incremental merge + ** is only attempted if it will write at least 64 leaf blocks. Hence + ** nMinMerge. + ** + ** Of course, updating the input segments also involves deleting a bunch + ** of blocks from the segments table. But this is not considered overhead + ** as it would also be required by a crisis-merge that used the same input + ** segments. + */ + const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ + + Fts3Table *p = (Fts3Table*)pVtab; + int rc; + i64 iLastRowid = sqlite3_last_insert_rowid(p->db); + + rc = sqlite3Fts3PendingTermsFlush(p); + if( rc==SQLITE_OK + && p->nLeafAdd>(nMinMerge/16) + && p->nAutoincrmerge && p->nAutoincrmerge!=0xff + ){ + int mxLevel = 0; /* Maximum relative level value in db */ + int A; /* Incr-merge parameter A */ + + rc = sqlite3Fts3MaxLevel(p, &mxLevel); + assert( rc==SQLITE_OK || mxLevel==0 ); + A = p->nLeafAdd * mxLevel; + A += (A/2); + if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); + } + sqlite3Fts3SegmentsClose(p); + sqlite3_set_last_insert_rowid(p->db, iLastRowid); + return rc; +} + +/* +** If it is currently unknown whether or not the FTS table has an %_stat +** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat +** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code +** if an error occurs. +*/ +static int fts3SetHasStat(Fts3Table *p){ + int rc = SQLITE_OK; + if( p->bHasStat==2 ){ + char *zTbl = sqlite3_mprintf("%s_stat", p->zName); + if( zTbl ){ + int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0); + sqlite3_free(zTbl); + p->bHasStat = (res==SQLITE_OK); + }else{ + rc = SQLITE_NOMEM; + } + } + return rc; +} + +/* +** Implementation of xBegin() method. +*/ +static int fts3BeginMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table*)pVtab; + int rc; + UNUSED_PARAMETER(pVtab); + assert( p->pSegments==0 ); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=1 ); + p->nLeafAdd = 0; + rc = fts3SetHasStat(p); +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK ){ + p->inTransaction = 1; + p->mxSavepoint = -1; + } +#endif + return rc; +} + +/* +** Implementation of xCommit() method. This is a no-op. The contents of +** the pending-terms hash-table have already been flushed into the database +** by fts3SyncMethod(). +*/ +static int fts3CommitMethod(sqlite3_vtab *pVtab){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(pVtab); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=0 ); + assert( p->pSegments==0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); + return SQLITE_OK; +} + +/* +** Implementation of xRollback(). Discard the contents of the pending-terms +** hash-table. Any changes made to the database are reverted by SQLite. +*/ +static int fts3RollbackMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table*)pVtab; + sqlite3Fts3PendingTermsClear(p); + assert( p->inTransaction!=0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); + return SQLITE_OK; +} + +/* +** When called, *ppPoslist must point to the byte immediately following the +** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function +** moves *ppPoslist so that it instead points to the first byte of the +** same position list. +*/ +static void fts3ReversePoslist(char *pStart, char **ppPoslist){ + char *p = &(*ppPoslist)[-2]; + char c = 0; + + /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */ + while( p>pStart && (c=*p--)==0 ); + + /* Search backwards for a varint with value zero (the end of the previous + ** poslist). This is an 0x00 byte preceded by some byte that does not + ** have the 0x80 bit set. */ + while( p>pStart && (*p & 0x80) | c ){ + c = *p--; + } + assert( p==pStart || c==0 ); + + /* At this point p points to that preceding byte without the 0x80 bit + ** set. So to find the start of the poslist, skip forward 2 bytes then + ** over a varint. + ** + ** Normally. The other case is that p==pStart and the poslist to return + ** is the first in the doclist. In this case do not skip forward 2 bytes. + ** The second part of the if condition (c==0 && *ppPoslist>&p[2]) + ** is required for cases where the first byte of a doclist and the + ** doclist is empty. For example, if the first docid is 10, a doclist + ** that begins with: + ** + ** 0x0A 0x00 + */ + if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; } + while( *p++&0x80 ); + *ppPoslist = p; +} + +/* +** Helper function used by the implementation of the overloaded snippet(), +** offsets() and optimize() SQL functions. +** +** If the value passed as the third argument is a blob of size +** sizeof(Fts3Cursor*), then the blob contents are copied to the +** output variable *ppCsr and SQLITE_OK is returned. Otherwise, an error +** message is written to context pContext and SQLITE_ERROR returned. The +** string passed via zFunc is used as part of the error message. +*/ +static int fts3FunctionArg( + sqlite3_context *pContext, /* SQL function call context */ + const char *zFunc, /* Function name */ + sqlite3_value *pVal, /* argv[0] passed to function */ + Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ +){ + int rc; + *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor"); + if( (*ppCsr)!=0 ){ + rc = SQLITE_OK; + }else{ + char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Implementation of the snippet() function for FTS3 +*/ +static void fts3SnippetFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of apVal[] array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + const char *zStart = ""; + const char *zEnd = ""; + const char *zEllipsis = "..."; + int iCol = -1; + int nToken = 15; /* Default number of tokens in snippet */ + + /* There must be at least one argument passed to this function (otherwise + ** the non-overloaded version would have been called instead of this one). + */ + assert( nVal>=1 ); + + if( nVal>6 ){ + sqlite3_result_error(pContext, + "wrong number of arguments to function snippet()", -1); + return; + } + if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; + + switch( nVal ){ + case 6: nToken = sqlite3_value_int(apVal[5]); + /* no break */ deliberate_fall_through + case 5: iCol = sqlite3_value_int(apVal[4]); + /* no break */ deliberate_fall_through + case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); + /* no break */ deliberate_fall_through + case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]); + /* no break */ deliberate_fall_through + case 2: zStart = (const char*)sqlite3_value_text(apVal[1]); + } + if( !zEllipsis || !zEnd || !zStart ){ + sqlite3_result_error_nomem(pContext); + }else if( nToken==0 ){ + sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); + }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); + } +} + +/* +** Implementation of the offsets() function for FTS3 +*/ +static void fts3OffsetsFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + + UNUSED_PARAMETER(nVal); + + assert( nVal==1 ); + if( fts3FunctionArg(pContext, "offsets", apVal[0], &pCsr) ) return; + assert( pCsr ); + if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + sqlite3Fts3Offsets(pContext, pCsr); + } +} + +/* +** Implementation of the special optimize() function for FTS3. This +** function merges all segments in the database to a single segment. +** Example usage is: +** +** SELECT optimize(t) FROM t LIMIT 1; +** +** where 't' is the name of an FTS3 table. +*/ +static void fts3OptimizeFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + int rc; /* Return code */ + Fts3Table *p; /* Virtual table handle */ + Fts3Cursor *pCursor; /* Cursor handle passed through apVal[0] */ + + UNUSED_PARAMETER(nVal); + + assert( nVal==1 ); + if( fts3FunctionArg(pContext, "optimize", apVal[0], &pCursor) ) return; + p = (Fts3Table *)pCursor->base.pVtab; + assert( p ); + + rc = sqlite3Fts3Optimize(p); + + switch( rc ){ + case SQLITE_OK: + sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC); + break; + case SQLITE_DONE: + sqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC); + break; + default: + sqlite3_result_error_code(pContext, rc); + break; + } +} + +/* +** Implementation of the matchinfo() function for FTS3 +*/ +static void fts3MatchinfoFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + assert( nVal==1 || nVal==2 ); + if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ + const char *zArg = 0; + if( nVal>1 ){ + zArg = (const char *)sqlite3_value_text(apVal[1]); + } + sqlite3Fts3Matchinfo(pContext, pCsr, zArg); + } +} + +/* +** This routine implements the xFindFunction method for the FTS3 +** virtual table. +*/ +static int fts3FindFunctionMethod( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Number of SQL function arguments */ + const char *zName, /* Name of SQL function */ + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ + void **ppArg /* Unused */ +){ + struct Overloaded { + const char *zName; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aOverload[] = { + { "snippet", fts3SnippetFunc }, + { "offsets", fts3OffsetsFunc }, + { "optimize", fts3OptimizeFunc }, + { "matchinfo", fts3MatchinfoFunc }, + }; + int i; /* Iterator variable */ + + UNUSED_PARAMETER(pVtab); + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(ppArg); + + for(i=0; idb; /* Database connection */ + int rc; /* Return Code */ + + /* At this point it must be known if the %_stat table exists or not. + ** So bHasStat may not be 2. */ + rc = fts3SetHasStat(p); + + /* As it happens, the pending terms table is always empty here. This is + ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction + ** always opens a savepoint transaction. And the xSavepoint() method + ** flushes the pending terms table. But leave the (no-op) call to + ** PendingTermsFlush() in in case that changes. + */ + assert( p->nPendingData==0 ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } + + p->bIgnoreSavepoint = 1; + + if( p->zContentTbl==0 ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", + p->zDb, p->zName, zName + ); + } + + if( p->bHasDocsize ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';", + p->zDb, p->zName, zName + ); + } + if( p->bHasStat ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_stat' RENAME TO '%q_stat';", + p->zDb, p->zName, zName + ); + } + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';", + p->zDb, p->zName, zName + ); + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", + p->zDb, p->zName, zName + ); + + p->bIgnoreSavepoint = 0; + return rc; +} + +/* +** The xSavepoint() method. +** +** Flush the contents of the pending-terms table to disk. +*/ +static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ + int rc = SQLITE_OK; + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint<=iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + + if( pTab->bIgnoreSavepoint==0 ){ + if( fts3HashCount(&pTab->aIndex[0].hPending)>0 ){ + char *zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->zDb, pTab->zName, pTab->zName + ); + if( zSql ){ + pTab->bIgnoreSavepoint = 1; + rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); + pTab->bIgnoreSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } + } + return rc; +} + +/* +** The xRelease() method. +** +** This is a no-op. +*/ +static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint >= iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint-1 ); + pTab->iSavepoint = iSavepoint; + return SQLITE_OK; +} + +/* +** The xRollbackTo() method. +** +** Discard the contents of the pending terms table. +*/ +static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ + Fts3Table *pTab = (Fts3Table*)pVtab; + UNUSED_PARAMETER(iSavepoint); + assert( pTab->inTransaction ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + sqlite3Fts3PendingTermsClear(pTab); + } + return SQLITE_OK; +} + +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int fts3ShadowName(const char *zName){ + static const char *azName[] = { + "content", "docsize", "segdir", "segments", "stat", + }; + unsigned int i; + for(i=0; ibFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); + }else if( bOk==0 ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); + } + sqlite3Fts3SegmentsClose(p); + return SQLITE_OK; +} + + + +static const sqlite3_module fts3Module = { + /* iVersion */ 4, + /* xCreate */ fts3CreateMethod, + /* xConnect */ fts3ConnectMethod, + /* xBestIndex */ fts3BestIndexMethod, + /* xDisconnect */ fts3DisconnectMethod, + /* xDestroy */ fts3DestroyMethod, + /* xOpen */ fts3OpenMethod, + /* xClose */ fts3CloseMethod, + /* xFilter */ fts3FilterMethod, + /* xNext */ fts3NextMethod, + /* xEof */ fts3EofMethod, + /* xColumn */ fts3ColumnMethod, + /* xRowid */ fts3RowidMethod, + /* xUpdate */ fts3UpdateMethod, + /* xBegin */ fts3BeginMethod, + /* xSync */ fts3SyncMethod, + /* xCommit */ fts3CommitMethod, + /* xRollback */ fts3RollbackMethod, + /* xFindFunction */ fts3FindFunctionMethod, + /* xRename */ fts3RenameMethod, + /* xSavepoint */ fts3SavepointMethod, + /* xRelease */ fts3ReleaseMethod, + /* xRollbackTo */ fts3RollbackToMethod, + /* xShadowName */ fts3ShadowName, + /* xIntegrity */ fts3IntegrityMethod, +}; + +/* +** This function is registered as the module destructor (called when an +** FTS3 enabled database connection is closed). It frees the memory +** allocated for the tokenizer hash table. +*/ +static void hashDestroy(void *p){ + Fts3HashWrapper *pHash = (Fts3HashWrapper *)p; + pHash->nRef--; + if( pHash->nRef<=0 ){ + sqlite3Fts3HashClear(&pHash->hash); + sqlite3_free(pHash); + } +} + +/* +** The fts3 built-in tokenizers - "simple", "porter" and "icu"- are +** implemented in files fts3_tokenizer1.c, fts3_porter.c and fts3_icu.c +** respectively. The following three forward declarations are for functions +** declared in these files used to retrieve the respective implementations. +** +** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed +** to by the argument to point to the "simple" tokenizer implementation. +** And so on. +*/ +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#ifndef SQLITE_DISABLE_FTS3_UNICODE +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); +#endif +#ifdef SQLITE_ENABLE_ICU +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#endif + +/* +** Initialize the fts3 extension. If this extension is built as part +** of the sqlite library, then this function is called directly by +** SQLite. If fts3 is built as a dynamically loadable extension, this +** function is called by the sqlite3_extension_init() entry point. +*/ +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ + int rc = SQLITE_OK; + Fts3HashWrapper *pHash = 0; + const sqlite3_tokenizer_module *pSimple = 0; + const sqlite3_tokenizer_module *pPorter = 0; +#ifndef SQLITE_DISABLE_FTS3_UNICODE + const sqlite3_tokenizer_module *pUnicode = 0; +#endif + +#ifdef SQLITE_ENABLE_ICU + const sqlite3_tokenizer_module *pIcu = 0; + sqlite3Fts3IcuTokenizerModule(&pIcu); +#endif + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + sqlite3Fts3UnicodeTokenizer(&pUnicode); +#endif + +#ifdef SQLITE_TEST + rc = sqlite3Fts3InitTerm(db); + if( rc!=SQLITE_OK ) return rc; +#endif + + rc = sqlite3Fts3InitAux(db); + if( rc!=SQLITE_OK ) return rc; + + sqlite3Fts3SimpleTokenizerModule(&pSimple); + sqlite3Fts3PorterTokenizerModule(&pPorter); + + /* Allocate and initialize the hash-table used to store tokenizers. */ + pHash = sqlite3_malloc(sizeof(Fts3HashWrapper)); + if( !pHash ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3Fts3HashInit(&pHash->hash, FTS3_HASH_STRING, 1); + pHash->nRef = 0; + } + + /* Load the built-in tokenizers into the hash table */ + if( rc==SQLITE_OK ){ + if( sqlite3Fts3HashInsert(&pHash->hash, "simple", 7, (void *)pSimple) + || sqlite3Fts3HashInsert(&pHash->hash, "porter", 7, (void *)pPorter) + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + || sqlite3Fts3HashInsert(&pHash->hash, "unicode61", 10, (void *)pUnicode) +#endif +#ifdef SQLITE_ENABLE_ICU + || (pIcu && sqlite3Fts3HashInsert(&pHash->hash, "icu", 4, (void *)pIcu)) +#endif + ){ + rc = SQLITE_NOMEM; + } + } + +#ifdef SQLITE_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash); + } +#endif + + /* Create the virtual table wrapper around the hash-table and overload + ** the four scalar functions. If this is successful, register the + ** module with sqlite. + */ + if( SQLITE_OK==rc + && SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer")) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) + ){ + pHash->nRef++; + rc = sqlite3_create_module_v2( + db, "fts3", &fts3Module, (void *)pHash, hashDestroy + ); + if( rc==SQLITE_OK ){ + pHash->nRef++; + rc = sqlite3_create_module_v2( + db, "fts4", &fts3Module, (void *)pHash, hashDestroy + ); + } + if( rc==SQLITE_OK ){ + pHash->nRef++; + rc = sqlite3Fts3InitTok(db, (void *)pHash, hashDestroy); + } + return rc; + } + + + /* An error has occurred. Delete the hash table and return the error code. */ + assert( rc!=SQLITE_OK ); + if( pHash ){ + sqlite3Fts3HashClear(&pHash->hash); + sqlite3_free(pHash); + } + return rc; +} + +/* +** Allocate an Fts3MultiSegReader for each token in the expression headed +** by pExpr. +** +** An Fts3SegReader object is a cursor that can seek or scan a range of +** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple +** Fts3SegReader objects internally to provide an interface to seek or scan +** within the union of all segments of a b-tree. Hence the name. +** +** If the allocated Fts3MultiSegReader just seeks to a single entry in a +** segment b-tree (if the term is not a prefix or it is a prefix for which +** there exists prefix b-tree of the right length) then it may be traversed +** and merged incrementally. Otherwise, it has to be merged into an in-memory +** doclist and then traversed. +*/ +static void fts3EvalAllocateReaders( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Allocate readers for this expression */ + int *pnToken, /* OUT: Total number of tokens in phrase. */ + int *pnOr, /* OUT: Total number of OR nodes in expr. */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int i; + int nToken = pExpr->pPhrase->nToken; + *pnToken += nToken; + for(i=0; ipPhrase->aToken[i]; + int rc = fts3TermSegReaderCursor(pCsr, + pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr + ); + if( rc!=SQLITE_OK ){ + *pRc = rc; + return; + } + } + assert( pExpr->pPhrase->iDoclistToken==0 ); + pExpr->pPhrase->iDoclistToken = -1; + }else{ + *pnOr += (pExpr->eType==FTSQUERY_OR); + fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); + fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); + } + } +} + +/* +** Arguments pList/nList contain the doclist for token iToken of phrase p. +** It is merged into the main doclist stored in p->doclist.aAll/nAll. +** +** This function assumes that pList points to a buffer allocated using +** sqlite3_malloc(). This function takes responsibility for eventually +** freeing the buffer. +** +** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs. +*/ +static int fts3EvalPhraseMergeToken( + Fts3Table *pTab, /* FTS Table pointer */ + Fts3Phrase *p, /* Phrase to merge pList/nList into */ + int iToken, /* Token pList/nList corresponds to */ + char *pList, /* Pointer to doclist */ + int nList /* Number of bytes in pList */ +){ + int rc = SQLITE_OK; + assert( iToken!=p->iDoclistToken ); + + if( pList==0 ){ + sqlite3_free(p->doclist.aAll); + p->doclist.aAll = 0; + p->doclist.nAll = 0; + } + + else if( p->iDoclistToken<0 ){ + p->doclist.aAll = pList; + p->doclist.nAll = nList; + } + + else if( p->doclist.aAll==0 ){ + sqlite3_free(pList); + } + + else { + char *pLeft; + char *pRight; + int nLeft; + int nRight; + int nDiff; + + if( p->iDoclistTokendoclist.aAll; + nLeft = p->doclist.nAll; + pRight = pList; + nRight = nList; + nDiff = iToken - p->iDoclistToken; + }else{ + pRight = p->doclist.aAll; + nRight = p->doclist.nAll; + pLeft = pList; + nLeft = nList; + nDiff = p->iDoclistToken - iToken; + } + + rc = fts3DoclistPhraseMerge( + pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight + ); + sqlite3_free(pLeft); + p->doclist.aAll = pRight; + p->doclist.nAll = nRight; + } + + if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; + return rc; +} + +/* +** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist +** does not take deferred tokens into account. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseLoad( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p /* Phrase object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int iToken; + int rc = SQLITE_OK; + + for(iToken=0; rc==SQLITE_OK && iTokennToken; iToken++){ + Fts3PhraseToken *pToken = &p->aToken[iToken]; + assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); + + if( pToken->pSegcsr ){ + int nThis = 0; + char *pThis = 0; + rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); + } + } + assert( pToken->pSegcsr==0 ); + } + + return rc; +} + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +/* +** This function is called on each phrase after the position lists for +** any deferred tokens have been loaded into memory. It updates the phrases +** current position list to include only those positions that are really +** instances of the phrase (after considering deferred tokens). If this +** means that the phrase does not appear in the current row, doclist.pList +** and doclist.nList are both zeroed. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ + int iToken; /* Used to iterate through phrase tokens */ + char *aPoslist = 0; /* Position list for deferred tokens */ + int nPoslist = 0; /* Number of bytes in aPoslist */ + int iPrev = -1; /* Token number of previous deferred token */ + char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0); + + for(iToken=0; iTokennToken; iToken++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + Fts3DeferredToken *pDeferred = pToken->pDeferred; + + if( pDeferred ){ + char *pList; + int nList; + int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); + if( rc!=SQLITE_OK ) return rc; + + if( pList==0 ){ + sqlite3_free(aPoslist); + sqlite3_free(aFree); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + + }else if( aPoslist==0 ){ + aPoslist = pList; + nPoslist = nList; + + }else{ + char *aOut = pList; + char *p1 = aPoslist; + char *p2 = aOut; + + assert( iPrev>=0 ); + fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); + sqlite3_free(aPoslist); + aPoslist = pList; + nPoslist = (int)(aOut - aPoslist); + if( nPoslist==0 ){ + sqlite3_free(aPoslist); + sqlite3_free(aFree); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + } + } + iPrev = iToken; + } + } + + if( iPrev>=0 ){ + int nMaxUndeferred = pPhrase->iDoclistToken; + if( nMaxUndeferred<0 ){ + pPhrase->doclist.pList = aPoslist; + pPhrase->doclist.nList = nPoslist; + pPhrase->doclist.iDocid = pCsr->iPrevId; + pPhrase->doclist.bFreeList = 1; + }else{ + int nDistance; + char *p1; + char *p2; + char *aOut; + + if( nMaxUndeferred>iPrev ){ + p1 = aPoslist; + p2 = pPhrase->doclist.pList; + nDistance = nMaxUndeferred - iPrev; + }else{ + p1 = pPhrase->doclist.pList; + p2 = aPoslist; + nDistance = iPrev - nMaxUndeferred; + } + + aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING); + if( !aOut ){ + sqlite3_free(aPoslist); + return SQLITE_NOMEM; + } + + pPhrase->doclist.pList = aOut; + assert( p1 && p2 ); + if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ + pPhrase->doclist.bFreeList = 1; + pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); + }else{ + sqlite3_free(aOut); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + } + sqlite3_free(aPoslist); + } + } + + if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree); + return SQLITE_OK; +} +#endif /* SQLITE_DISABLE_FTS4_DEFERRED */ + +/* +** Maximum number of tokens a phrase may have to be considered for the +** incremental doclists strategy. +*/ +#define MAX_INCR_PHRASE_TOKENS 4 + +/* +** This function is called for each Fts3Phrase in a full-text query +** expression to initialize the mechanism for returning rows. Once this +** function has been called successfully on an Fts3Phrase, it may be +** used with fts3EvalPhraseNext() to iterate through the matching docids. +** +** If parameter bOptOk is true, then the phrase may (or may not) use the +** incremental loading strategy. Otherwise, the entire doclist is loaded into +** memory within this call. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; /* Error code */ + int i; + + /* Determine if doclists may be loaded from disk incrementally. This is + ** possible if the bOptOk argument is true, the FTS doclists will be + ** scanned in forward order, and the phrase consists of + ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first" + ** tokens or prefix tokens that cannot use a prefix-index. */ + int bHaveIncr = 0; + int bIncrOk = (bOptOk + && pCsr->bDesc==pTab->bDescIdx + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + && pTab->bNoIncrDoclist==0 +#endif + ); + for(i=0; bIncrOk==1 && inToken; i++){ + Fts3PhraseToken *pToken = &p->aToken[i]; + if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){ + bIncrOk = 0; + } + if( pToken->pSegcsr ) bHaveIncr = 1; + } + + if( bIncrOk && bHaveIncr ){ + /* Use the incremental approach. */ + int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); + for(i=0; rc==SQLITE_OK && inToken; i++){ + Fts3PhraseToken *pToken = &p->aToken[i]; + Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; + if( pSegcsr ){ + rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); + } + } + p->bIncr = 1; + }else{ + /* Load the full doclist for the phrase into memory. */ + rc = fts3EvalPhraseLoad(pCsr, p); + p->bIncr = 0; + } + + assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr ); + return rc; +} + +/* +** This function is used to iterate backwards (from the end to start) +** through doclists. It is used by this module to iterate through phrase +** doclists in reverse and by the fts3_write.c module to iterate through +** pending-terms lists when writing to databases with "order=desc". +** +** The doclist may be sorted in ascending (parameter bDescIdx==0) or +** descending (parameter bDescIdx==1) order of docid. Regardless, this +** function iterates from the end of the doclist to the beginning. +*/ +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( + int bDescIdx, /* True if the doclist is desc */ + char *aDoclist, /* Pointer to entire doclist */ + int nDoclist, /* Length of aDoclist in bytes */ + char **ppIter, /* IN/OUT: Iterator pointer */ + sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ + int *pnList, /* OUT: List length pointer */ + u8 *pbEof /* OUT: End-of-file flag */ +){ + char *p = *ppIter; + + assert( nDoclist>0 ); + assert( *pbEof==0 ); + assert_fts3_nc( p || *piDocid==0 ); + assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); + + if( p==0 ){ + sqlite3_int64 iDocid = 0; + char *pNext = 0; + char *pDocid = aDoclist; + char *pEnd = &aDoclist[nDoclist]; + int iMul = 1; + + while( pDocid0 ); + assert( *pbEof==0 ); + assert_fts3_nc( p || *piDocid==0 ); + assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) ); + + if( p==0 ){ + p = aDoclist; + p += sqlite3Fts3GetVarint(p, piDocid); + }else{ + fts3PoslistCopy(0, &p); + while( p<&aDoclist[nDoclist] && *p==0 ) p++; + if( p>=&aDoclist[nDoclist] ){ + *pbEof = 1; + }else{ + sqlite3_int64 iVar; + p += sqlite3Fts3GetVarint(p, &iVar); + *piDocid += ((bDescIdx ? -1 : 1) * iVar); + } + } + + *ppIter = p; +} + +/* +** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof +** to true if EOF is reached. +*/ +static void fts3EvalDlPhraseNext( + Fts3Table *pTab, + Fts3Doclist *pDL, + u8 *pbEof +){ + char *pIter; /* Used to iterate through aAll */ + char *pEnd; /* 1 byte past end of aAll */ + + if( pDL->pNextDocid ){ + pIter = pDL->pNextDocid; + assert( pDL->aAll!=0 || pIter==0 ); + }else{ + pIter = pDL->aAll; + } + + if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){ + /* We have already reached the end of this doclist. EOF. */ + *pbEof = 1; + }else{ + sqlite3_int64 iDelta; + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); + if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ + pDL->iDocid += iDelta; + }else{ + pDL->iDocid -= iDelta; + } + pDL->pList = pIter; + fts3PoslistCopy(0, &pIter); + pDL->nList = (int)(pIter - pDL->pList); + + /* pIter now points just past the 0x00 that terminates the position- + ** list for document pDL->iDocid. However, if this position-list was + ** edited in place by fts3EvalNearTrim(), then pIter may not actually + ** point to the start of the next docid value. The following line deals + ** with this case by advancing pIter past the zero-padding added by + ** fts3EvalNearTrim(). */ + while( pIterpNextDocid = pIter; + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); + *pbEof = 0; + } +} + +/* +** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext(). +*/ +typedef struct TokenDoclist TokenDoclist; +struct TokenDoclist { + int bIgnore; + sqlite3_int64 iDocid; + char *pList; + int nList; +}; + +/* +** Token pToken is an incrementally loaded token that is part of a +** multi-token phrase. Advance it to the next matching document in the +** database and populate output variable *p with the details of the new +** entry. Or, if the iterator has reached EOF, set *pbEof to true. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +*/ +static int incrPhraseTokenNext( + Fts3Table *pTab, /* Virtual table handle */ + Fts3Phrase *pPhrase, /* Phrase to advance token of */ + int iToken, /* Specific token to advance */ + TokenDoclist *p, /* OUT: Docid and doclist for new entry */ + u8 *pbEof /* OUT: True if iterator is at EOF */ +){ + int rc = SQLITE_OK; + + if( pPhrase->iDoclistToken==iToken ){ + assert( p->bIgnore==0 ); + assert( pPhrase->aToken[iToken].pSegcsr==0 ); + fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof); + p->pList = pPhrase->doclist.pList; + p->nList = pPhrase->doclist.nList; + p->iDocid = pPhrase->doclist.iDocid; + }else{ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + assert( pToken->pDeferred==0 ); + assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); + if( pToken->pSegcsr ){ + assert( p->bIgnore==0 ); + rc = sqlite3Fts3MsrIncrNext( + pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList + ); + if( p->pList==0 ) *pbEof = 1; + }else{ + p->bIgnore = 1; + } + } + + return rc; +} + + +/* +** The phrase iterator passed as the second argument: +** +** * features at least one token that uses an incremental doclist, and +** +** * does not contain any deferred tokens. +** +** Advance it to the next matching documnent in the database and populate +** the Fts3Doclist.pList and nList fields. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +*/ +static int fts3EvalIncrPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + u8 bEof = 0; + + /* This is only called if it is guaranteed that the phrase has at least + ** one incremental token. In which case the bIncr flag is set. */ + assert( p->bIncr==1 ); + + if( p->nToken==1 ){ + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, + &pDL->iDocid, &pDL->pList, &pDL->nList + ); + if( pDL->pList==0 ) bEof = 1; + }else{ + int bDescDoclist = pCsr->bDesc; + struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS]; + + memset(a, 0, sizeof(a)); + assert( p->nToken<=MAX_INCR_PHRASE_TOKENS ); + assert( p->iDoclistTokennToken && bEof==0; i++){ + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); + if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ + iMax = a[i].iDocid; + bMaxSet = 1; + } + } + assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) ); + assert( rc!=SQLITE_OK || bMaxSet ); + + /* Keep advancing iterators until they all point to the same document */ + for(i=0; inToken; i++){ + while( rc==SQLITE_OK && bEof==0 + && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 + ){ + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); + if( DOCID_CMP(a[i].iDocid, iMax)>0 ){ + iMax = a[i].iDocid; + i = 0; + } + } + } + + /* Check if the current entries really are a phrase match */ + if( bEof==0 ){ + int nList = 0; + int nByte = a[p->nToken-1].nList; + char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING); + if( !aDoclist ) return SQLITE_NOMEM; + memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); + memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); + + for(i=0; i<(p->nToken-1); i++){ + if( a[i].bIgnore==0 ){ + char *pL = a[i].pList; + char *pR = aDoclist; + char *pOut = aDoclist; + int nDist = p->nToken-1-i; + int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR); + if( res==0 ) break; + nList = (int)(pOut - aDoclist); + } + } + if( i==(p->nToken-1) ){ + pDL->iDocid = iMax; + pDL->pList = aDoclist; + pDL->nList = nList; + pDL->bFreeList = 1; + break; + } + sqlite3_free(aDoclist); + } + } + } + + *pbEof = bEof; + return rc; +} + +/* +** Attempt to move the phrase iterator to point to the next matching docid. +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +*/ +static int fts3EvalPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + + if( p->bIncr ){ + rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); + }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ + sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, + &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof + ); + pDL->pList = pDL->pNextDocid; + }else{ + fts3EvalDlPhraseNext(pTab, pDL, pbEof); + } + + return rc; +} + +/* +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, fts3EvalPhraseStart() is called on all phrases within the +** expression. Also the Fts3Expr.bDeferred variable is set to true for any +** expressions for which all descendent tokens are deferred. +** +** If parameter bOptOk is zero, then it is guaranteed that the +** Fts3Phrase.doclist.aAll/nAll variables contain the entire doclist for +** each phrase in the expression (subject to deferred token processing). +** Or, if bOptOk is non-zero, then one or more tokens within the expression +** may be loaded incrementally, meaning doclist.aAll/nAll is not available. +** +** If an error occurs within this function, *pRc is set to an SQLite error +** code before returning. +*/ +static void fts3EvalStartReaders( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expression to initialize phrases in */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int nToken = pExpr->pPhrase->nToken; + if( nToken ){ + int i; + for(i=0; ipPhrase->aToken[i].pDeferred==0 ) break; + } + pExpr->bDeferred = (i==nToken); + } + *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); + }else{ + fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); + fts3EvalStartReaders(pCsr, pExpr->pRight, pRc); + pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); + } + } +} + +/* +** An array of the following structures is assembled as part of the process +** of selecting tokens to defer before the query starts executing (as part +** of the xFilter() method). There is one element in the array for each +** token in the FTS expression. +** +** Tokens are divided into AND/NEAR clusters. All tokens in a cluster belong +** to phrases that are connected only by AND and NEAR operators (not OR or +** NOT). When determining tokens to defer, each AND/NEAR cluster is considered +** separately. The root of a tokens AND/NEAR cluster is stored in +** Fts3TokenAndCost.pRoot. +*/ +typedef struct Fts3TokenAndCost Fts3TokenAndCost; +struct Fts3TokenAndCost { + Fts3Phrase *pPhrase; /* The phrase the token belongs to */ + int iToken; /* Position of token in phrase */ + Fts3PhraseToken *pToken; /* The token itself */ + Fts3Expr *pRoot; /* Root of NEAR/AND cluster */ + int nOvfl; /* Number of overflow pages to load doclist */ + int iCol; /* The column the token must match */ +}; + +/* +** This function is used to populate an allocated Fts3TokenAndCost array. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if an error occurs during execution, *pRc is set to an +** SQLite error code. +*/ +static void fts3EvalTokenCosts( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Root of current AND/NEAR cluster */ + Fts3Expr *pExpr, /* Expression to consider */ + Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */ + Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + for(i=0; *pRc==SQLITE_OK && inToken; i++){ + Fts3TokenAndCost *pTC = (*ppTC)++; + pTC->pPhrase = pPhrase; + pTC->iToken = i; + pTC->pRoot = pRoot; + pTC->pToken = &pPhrase->aToken[i]; + pTC->iCol = pPhrase->iColumn; + *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); + } + }else if( pExpr->eType!=FTSQUERY_NOT ){ + assert( pExpr->eType==FTSQUERY_OR + || pExpr->eType==FTSQUERY_AND + || pExpr->eType==FTSQUERY_NEAR + ); + assert( pExpr->pLeft && pExpr->pRight ); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pLeft; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pRight; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pRight, ppTC, ppOr, pRc); + } + } +} + +/* +** Determine the average document (row) size in pages. If successful, +** write this value to *pnPage and return SQLITE_OK. Otherwise, return +** an SQLite error code. +** +** The average document size in pages is calculated by first calculating +** determining the average size in bytes, B. If B is less than the amount +** of data that will fit on a single leaf page of an intkey table in +** this database, then the average docsize is 1. Otherwise, it is 1 plus +** the number of overflow pages consumed by a record B bytes in size. +*/ +static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ + int rc = SQLITE_OK; + if( pCsr->nRowAvg==0 ){ + /* The average document size, which is required to calculate the cost + ** of each doclist, has not yet been determined. Read the required + ** data from the %_stat table to calculate it. + ** + ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 + ** varints, where nCol is the number of columns in the FTS3 table. + ** The first varint is the number of documents currently stored in + ** the table. The following nCol varints contain the total amount of + ** data stored in all rows of each column of the table, from left + ** to right. + */ + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + sqlite3_stmt *pStmt; + sqlite3_int64 nDoc = 0; + sqlite3_int64 nByte = 0; + const char *pEnd; + const char *a; + + rc = sqlite3Fts3SelectDoctotal(p, &pStmt); + if( rc!=SQLITE_OK ) return rc; + a = sqlite3_column_blob(pStmt, 0); + testcase( a==0 ); /* If %_stat.value set to X'' */ + if( a ){ + pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); + while( anDoc = nDoc; + pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); + assert( pCsr->nRowAvg>0 ); + rc = sqlite3_reset(pStmt); + } + + *pnPage = pCsr->nRowAvg; + return rc; +} + +/* +** This function is called to select the tokens (if any) that will be +** deferred. The array aTC[] has already been populated when this is +** called. +** +** This function is called once for each AND/NEAR cluster in the +** expression. Each invocation determines which tokens to defer within +** the cluster with root node pRoot. See comments above the definition +** of struct Fts3TokenAndCost for more details. +** +** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken() +** called on each token to defer. Otherwise, an SQLite error code is +** returned. +*/ +static int fts3EvalSelectDeferred( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Consider tokens with this root node */ + Fts3TokenAndCost *aTC, /* Array of expression tokens and costs */ + int nTC /* Number of entries in aTC[] */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int nDocSize = 0; /* Number of pages per doc loaded */ + int rc = SQLITE_OK; /* Return code */ + int ii; /* Iterator variable for various purposes */ + int nOvfl = 0; /* Total overflow pages used by doclists */ + int nToken = 0; /* Total number of tokens in cluster */ + + int nMinEst = 0; /* The minimum count for any phrase so far. */ + int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ + + /* Tokens are never deferred for FTS tables created using the content=xxx + ** option. The reason being that it is not guaranteed that the content + ** table actually contains the same data as the index. To prevent this from + ** causing any problems, the deferred token optimization is completely + ** disabled for content=xxx tables. */ + if( pTab->zContentTbl ){ + return SQLITE_OK; + } + + /* Count the tokens in this AND/NEAR cluster. If none of the doclists + ** associated with the tokens spill onto overflow pages, or if there is + ** only 1 token, exit early. No tokens to defer in this case. */ + for(ii=0; ii0 ); + + + /* Iterate through all tokens in this AND/NEAR cluster, in ascending order + ** of the number of overflow pages that will be loaded by the pager layer + ** to retrieve the entire doclist for the token from the full-text index. + ** Load the doclists for tokens that are either: + ** + ** a. The cheapest token in the entire query (i.e. the one visited by the + ** first iteration of this loop), or + ** + ** b. Part of a multi-token phrase. + ** + ** After each token doclist is loaded, merge it with the others from the + ** same phrase and count the number of documents that the merged doclist + ** contains. Set variable "nMinEst" to the smallest number of documents in + ** any phrase doclist for which 1 or more token doclists have been loaded. + ** Let nOther be the number of other phrases for which it is certain that + ** one or more tokens will not be deferred. + ** + ** Then, for each token, defer it if loading the doclist would result in + ** loading N or more overflow pages into memory, where N is computed as: + ** + ** (nMinEst + 4^nOther - 1) / (4^nOther) + */ + for(ii=0; iinOvfl) + ){ + pTC = &aTC[iTC]; + } + } + assert( pTC ); + + if( ii && pTC->nOvfl>=((nMinEst+(nLoad4/4)-1)/(nLoad4/4))*nDocSize ){ + /* The number of overflow pages to load for this (and therefore all + ** subsequent) tokens is greater than the estimated number of pages + ** that will be loaded if all subsequent tokens are deferred. + */ + Fts3PhraseToken *pToken = pTC->pToken; + rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); + fts3SegReaderCursorFree(pToken->pSegcsr); + pToken->pSegcsr = 0; + }else{ + /* Set nLoad4 to the value of (4^nOther) for the next iteration of the + ** for-loop. Except, limit the value to 2^24 to prevent it from + ** overflowing the 32-bit integer it is stored in. */ + if( ii<12 ) nLoad4 = nLoad4*4; + + if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){ + /* Either this is the cheapest token in the entire query, or it is + ** part of a multi-token phrase. Either way, the entire doclist will + ** (eventually) be loaded into memory. It may as well be now. */ + Fts3PhraseToken *pToken = pTC->pToken; + int nList = 0; + char *pList = 0; + rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList); + assert( rc==SQLITE_OK || pList==0 ); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken( + pTab, pTC->pPhrase, pTC->iToken,pList,nList + ); + } + if( rc==SQLITE_OK ){ + int nCount; + nCount = fts3DoclistCountDocids( + pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll + ); + if( ii==0 || nCountpToken = 0; + } + + return rc; +} + +/* +** This function is called from within the xFilter method. It initializes +** the full-text query currently stored in pCsr->pExpr. To iterate through +** the results of a query, the caller does: +** +** fts3EvalStart(pCsr); +** while( 1 ){ +** fts3EvalNext(pCsr); +** if( pCsr->bEof ) break; +** ... return row pCsr->iPrevId to the caller ... +** } +*/ +static int fts3EvalStart(Fts3Cursor *pCsr){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int nToken = 0; + int nOr = 0; + + /* Allocate a MultiSegReader for each token in the expression. */ + fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); + + /* Determine which, if any, tokens in the expression should be deferred. */ +#ifndef SQLITE_DISABLE_FTS4_DEFERRED + if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ + Fts3TokenAndCost *aTC; + aTC = (Fts3TokenAndCost *)sqlite3_malloc64( + sizeof(Fts3TokenAndCost) * nToken + + sizeof(Fts3Expr *) * nOr * 2 + ); + + if( !aTC ){ + rc = SQLITE_NOMEM; + }else{ + Fts3Expr **apOr = (Fts3Expr **)&aTC[nToken]; + int ii; + Fts3TokenAndCost *pTC = aTC; + Fts3Expr **ppOr = apOr; + + fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc); + nToken = (int)(pTC-aTC); + nOr = (int)(ppOr-apOr); + + if( rc==SQLITE_OK ){ + rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken); + for(ii=0; rc==SQLITE_OK && iipExpr, &rc); + return rc; +} + +/* +** Invalidate the current position list for phrase pPhrase. +*/ +static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){ + if( pPhrase->doclist.bFreeList ){ + sqlite3_free(pPhrase->doclist.pList); + } + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + pPhrase->doclist.bFreeList = 0; +} + +/* +** This function is called to edit the position list associated with +** the phrase object passed as the fifth argument according to a NEAR +** condition. For example: +** +** abc NEAR/5 "def ghi" +** +** Parameter nNear is passed the NEAR distance of the expression (5 in +** the example above). When this function is called, *paPoslist points to +** the position list, and *pnToken is the number of phrase tokens in the +** phrase on the other side of the NEAR operator to pPhrase. For example, +** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to +** the position list associated with phrase "abc". +** +** All positions in the pPhrase position list that are not sufficiently +** close to a position in the *paPoslist position list are removed. If this +** leaves 0 positions, zero is returned. Otherwise, non-zero. +** +** Before returning, *paPoslist is set to point to the position lsit +** associated with pPhrase. And *pnToken is set to the number of tokens in +** pPhrase. +*/ +static int fts3EvalNearTrim( + int nNear, /* NEAR distance. As in "NEAR/nNear". */ + char *aTmp, /* Temporary space to use */ + char **paPoslist, /* IN/OUT: Position list */ + int *pnToken, /* IN/OUT: Tokens in phrase of *paPoslist */ + Fts3Phrase *pPhrase /* The phrase object to trim the doclist of */ +){ + int nParam1 = nNear + pPhrase->nToken; + int nParam2 = nNear + *pnToken; + int nNew; + char *p2; + char *pOut; + int res; + + assert( pPhrase->doclist.pList ); + + p2 = pOut = pPhrase->doclist.pList; + res = fts3PoslistNearMerge( + &pOut, aTmp, nParam1, nParam2, paPoslist, &p2 + ); + if( res ){ + nNew = (int)(pOut - pPhrase->doclist.pList) - 1; + assert_fts3_nc( nNew<=pPhrase->doclist.nList && nNew>0 ); + if( nNew>=0 && nNew<=pPhrase->doclist.nList ){ + assert( pPhrase->doclist.pList[nNew]=='\0' ); + memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); + pPhrase->doclist.nList = nNew; + } + *paPoslist = pPhrase->doclist.pList; + *pnToken = pPhrase->nToken; + } + + return res; +} + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is called. +** Otherwise, it advances the expression passed as the second argument to +** point to the next matching row in the database. Expressions iterate through +** matching rows in docid order. Ascending order if Fts3Cursor.bDesc is zero, +** or descending if it is non-zero. +** +** If an error occurs, *pRc is set to an SQLite error code. Otherwise, if +** successful, the following variables in pExpr are set: +** +** Fts3Expr.bEof (non-zero if EOF - there is no next row) +** Fts3Expr.iDocid (valid if bEof==0. The docid of the next row) +** +** If the expression is of type FTSQUERY_PHRASE, and the expression is not +** at EOF, then the following variables are populated with the position list +** for the phrase for the visited row: +** +** FTs3Expr.pPhrase->doclist.nList (length of pList in bytes) +** FTs3Expr.pPhrase->doclist.pList (pointer to position list) +** +** It says above that this function advances the expression to the next +** matching row. This is usually true, but there are the following exceptions: +** +** 1. Deferred tokens are not taken into account. If a phrase consists +** entirely of deferred tokens, it is assumed to match every row in +** the db. In this case the position-list is not populated at all. +** +** Or, if a phrase contains one or more deferred tokens and one or +** more non-deferred tokens, then the expression is advanced to the +** next possible match, considering only non-deferred tokens. In other +** words, if the phrase is "A B C", and "B" is deferred, the expression +** is advanced to the next row that contains an instance of "A * C", +** where "*" may match any single token. The position list in this case +** is populated as for "A * C" before returning. +** +** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is +** advanced to point to the next row that matches "x AND y". +** +** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is +** really a match, taking into account deferred tokens and NEAR operators. +*/ +static void fts3EvalNextRow( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expr. to advance to next matching row */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK && pExpr->bEof==0 ){ + int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ + pExpr->bStart = 1; + + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + assert( !pLeft->bDeferred || !pRight->bDeferred ); + + if( pLeft->bDeferred ){ + /* LHS is entirely deferred. So we assume it matches every row. + ** Advance the RHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pRight, pRc); + pExpr->iDocid = pRight->iDocid; + pExpr->bEof = pRight->bEof; + }else if( pRight->bDeferred ){ + /* RHS is entirely deferred. So we assume it matches every row. + ** Advance the LHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + }else{ + /* Neither the RHS or LHS are deferred. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){ + sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( iDiff==0 ) break; + if( iDiff<0 ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else{ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = (pLeft->bEof || pRight->bEof); + if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ + assert( pRight->eType==FTSQUERY_PHRASE ); + if( pRight->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pRight->pPhrase->doclist; + while( *pRc==SQLITE_OK && pRight->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pLeft->pPhrase->doclist; + while( *pRc==SQLITE_OK && pLeft->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pLeft, pRc); + } + } + pRight->bEof = pLeft->bEof = 1; + } + } + break; + } + + case FTSQUERY_OR: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + + assert_fts3_nc( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); + assert_fts3_nc( pRight->bStart || pLeft->iDocid==pRight->iDocid ); + + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else if( pLeft->bEof || iCmp>0 ){ + fts3EvalNextRow(pCsr, pRight, pRc); + }else{ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + } + + pExpr->bEof = (pLeft->bEof && pRight->bEof); + iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + pExpr->iDocid = pLeft->iDocid; + }else{ + pExpr->iDocid = pRight->iDocid; + } + + break; + } + + case FTSQUERY_NOT: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + + if( pRight->bStart==0 ){ + fts3EvalNextRow(pCsr, pRight, pRc); + assert( *pRc!=SQLITE_OK || pRight->bStart ); + } + + fts3EvalNextRow(pCsr, pLeft, pRc); + if( pLeft->bEof==0 ){ + while( !*pRc + && !pRight->bEof + && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0 + ){ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + break; + } + + default: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + fts3EvalInvalidatePoslist(pPhrase); + *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof); + pExpr->iDocid = pPhrase->doclist.iDocid; + break; + } + } + } +} + +/* +** If *pRc is not SQLITE_OK, or if pExpr is not the root node of a NEAR +** cluster, then this function returns 1 immediately. +** +** Otherwise, it checks if the current row really does match the NEAR +** expression, using the data currently stored in the position lists +** (Fts3Expr->pPhrase.doclist.pList/nList) for each phrase in the expression. +** +** If the current row is a match, the position list associated with each +** phrase in the NEAR expression is edited in place to contain only those +** phrase instances sufficiently close to their peers to satisfy all NEAR +** constraints. In this case it returns 1. If the NEAR expression does not +** match the current row, 0 is returned. The position lists may or may not +** be edited if 0 is returned. +*/ +static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ + int res = 1; + + /* The following block runs if pExpr is the root of a NEAR query. + ** For example, the query: + ** + ** "w" NEAR "x" NEAR "y" NEAR "z" + ** + ** which is represented in tree form as: + ** + ** | + ** +--NEAR--+ <-- root of NEAR query + ** | | + ** +--NEAR--+ "z" + ** | | + ** +--NEAR--+ "y" + ** | | + ** "w" "x" + ** + ** The right-hand child of a NEAR node is always a phrase. The + ** left-hand child may be either a phrase or a NEAR node. There are + ** no exceptions to this - it's the way the parser in fts3_expr.c works. + */ + if( *pRc==SQLITE_OK + && pExpr->eType==FTSQUERY_NEAR + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + sqlite3_int64 nTmp = 0; /* Bytes of temp space */ + char *aTmp; /* Temp space for PoslistNearMerge() */ + + /* Allocate temporary working space. */ + for(p=pExpr; p->pLeft; p=p->pLeft){ + assert( p->pRight->pPhrase->doclist.nList>0 ); + nTmp += p->pRight->pPhrase->doclist.nList; + } + nTmp += p->pPhrase->doclist.nList; + aTmp = sqlite3_malloc64(nTmp*2); + if( !aTmp ){ + *pRc = SQLITE_NOMEM; + res = 0; + }else{ + char *aPoslist = p->pPhrase->doclist.pList; + int nToken = p->pPhrase->nToken; + + for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ + Fts3Phrase *pPhrase = p->pRight->pPhrase; + int nNear = p->nNear; + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + + aPoslist = pExpr->pRight->pPhrase->doclist.pList; + nToken = pExpr->pRight->pPhrase->nToken; + for(p=pExpr->pLeft; p && res; p=p->pLeft){ + int nNear; + Fts3Phrase *pPhrase; + assert( p->pParent && p->pParent->pLeft==p ); + nNear = p->pParent->nNear; + pPhrase = ( + p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase + ); + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + } + + sqlite3_free(aTmp); + } + + return res; +} + +/* +** This function is a helper function for sqlite3Fts3EvalTestDeferred(). +** Assuming no error occurs or has occurred, It returns non-zero if the +** expression passed as the second argument matches the row that pCsr +** currently points to, or zero if it does not. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** If an error occurs during execution of this function, *pRc is set to +** the appropriate SQLite error code. In this case the returned value is +** undefined. +*/ +static int fts3EvalTestExpr( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Expr to test. May or may not be root. */ + int *pRc /* IN/OUT: Error code */ +){ + int bHit = 1; /* Return value */ + if( *pRc==SQLITE_OK ){ + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + && fts3EvalNearTest(pExpr, pRc) + ); + + /* If the NEAR expression does not match any rows, zero the doclist for + ** all phrases involved in the NEAR. This is because the snippet(), + ** offsets() and matchinfo() functions are not supposed to recognize + ** any instances of phrases that are part of unmatched NEAR queries. + ** For example if this expression: + ** + ** ... MATCH 'a OR (b NEAR c)' + ** + ** is matched against a row containing: + ** + ** 'a b d e' + ** + ** then any snippet() should ony highlight the "a" term, not the "b" + ** (as "b" is part of a non-matching NEAR clause). + */ + if( bHit==0 + && pExpr->eType==FTSQUERY_NEAR + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + for(p=pExpr; p->pPhrase==0; p=p->pLeft){ + if( p->pRight->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pRight->pPhrase); + } + } + if( p->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pPhrase); + } + } + + break; + + case FTSQUERY_OR: { + int bHit1 = fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc); + int bHit2 = fts3EvalTestExpr(pCsr, pExpr->pRight, pRc); + bHit = bHit1 || bHit2; + break; + } + + case FTSQUERY_NOT: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + ); + break; + + default: { +#ifndef SQLITE_DISABLE_FTS4_DEFERRED + if( pCsr->pDeferred && (pExpr->bDeferred || ( + pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList + ))){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + if( pExpr->bDeferred ){ + fts3EvalInvalidatePoslist(pPhrase); + } + *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); + bHit = (pPhrase->doclist.pList!=0); + pExpr->iDocid = pCsr->iPrevId; + }else +#endif + { + bHit = ( + pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId + && pExpr->pPhrase->doclist.nList>0 + ); + } + break; + } + } + } + return bHit; +} + +/* +** This function is called as the second part of each xNext operation when +** iterating through the results of a full-text query. At this point the +** cursor points to a row that matches the query expression, with the +** following caveats: +** +** * Up until this point, "NEAR" operators in the expression have been +** treated as "AND". +** +** * Deferred tokens have not yet been considered. +** +** If *pRc is not SQLITE_OK when this function is called, it immediately +** returns 0. Otherwise, it tests whether or not after considering NEAR +** operators and deferred tokens the current row is still a match for the +** expression. It returns 1 if both of the following are true: +** +** 1. *pRc is SQLITE_OK when this function returns, and +** +** 2. After scanning the current FTS table row for the deferred tokens, +** it is determined that the row does *not* match the query. +** +** Or, if no error occurs and it seems the current row does match the FTS +** query, return 0. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){ + int rc = *pRc; + int bMiss = 0; + if( rc==SQLITE_OK ){ + + /* If there are one or more deferred tokens, load the current row into + ** memory and scan it to determine the position list for each deferred + ** token. Then, see if this row is really a match, considering deferred + ** tokens and NEAR operators (neither of which were taken into account + ** earlier, by fts3EvalNextRow()). + */ + if( pCsr->pDeferred ){ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3CacheDeferredDoclists(pCsr); + } + } + bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc)); + + /* Free the position-lists accumulated for each deferred token above. */ + sqlite3Fts3FreeDeferredDoclists(pCsr); + *pRc = rc; + } + return (rc==SQLITE_OK && bMiss); +} + +/* +** Advance to the next document that matches the FTS expression in +** Fts3Cursor.pExpr. +*/ +static int fts3EvalNext(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Expr *pExpr = pCsr->pExpr; + assert( pCsr->isEof==0 ); + if( pExpr==0 ){ + pCsr->isEof = 1; + }else{ + do { + if( pCsr->isRequireSeek==0 ){ + sqlite3_reset(pCsr->pStmt); + } + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + fts3EvalNextRow(pCsr, pExpr, &rc); + pCsr->isEof = pExpr->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pExpr->iDocid; + }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) ); + } + + /* Check if the cursor is past the end of the docid range specified + ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */ + if( rc==SQLITE_OK && ( + (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid) + || (pCsr->bDesc!=0 && pCsr->iPrevIdiMinDocid) + )){ + pCsr->isEof = 1; + } + + return rc; +} + +/* +** Restart interation for expression pExpr so that the next call to +** fts3EvalNext() visits the first row. Do not allow incremental +** loading or merging of phrase doclists for this iteration. +** +** If *pRc is other than SQLITE_OK when this function is called, it is +** a no-op. If an error occurs within this function, *pRc is set to an +** SQLite error code before returning. +*/ +static void fts3EvalRestart( + Fts3Cursor *pCsr, + Fts3Expr *pExpr, + int *pRc +){ + if( pExpr && *pRc==SQLITE_OK ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + + if( pPhrase ){ + fts3EvalInvalidatePoslist(pPhrase); + if( pPhrase->bIncr ){ + int i; + for(i=0; inToken; i++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[i]; + assert( pToken->pDeferred==0 ); + if( pToken->pSegcsr ){ + sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); + } + } + *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); + } + pPhrase->doclist.pNextDocid = 0; + pPhrase->doclist.iDocid = 0; + pPhrase->pOrPoslist = 0; + } + + pExpr->iDocid = 0; + pExpr->bEof = 0; + pExpr->bStart = 0; + + fts3EvalRestart(pCsr, pExpr->pLeft, pRc); + fts3EvalRestart(pCsr, pExpr->pRight, pRc); + } +} + +/* +** After allocating the Fts3Expr.aMI[] array for each phrase in the +** expression rooted at pExpr, the cursor iterates through all rows matched +** by pExpr, calling this function for each row. This function increments +** the values in Fts3Expr.aMI[] according to the position-list currently +** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase +** expression nodes. +*/ +static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){ + if( pExpr ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + if( pPhrase && pPhrase->doclist.pList ){ + int iCol = 0; + char *p = pPhrase->doclist.pList; + + do{ + u8 c = 0; + int iCnt = 0; + while( 0xFE & (*p | c) ){ + if( (c&0x80)==0 ) iCnt++; + c = *p++ & 0x80; + } + + /* aMI[iCol*3 + 1] = Number of occurrences + ** aMI[iCol*3 + 2] = Number of rows containing at least one instance + */ + pExpr->aMI[iCol*3 + 1] += iCnt; + pExpr->aMI[iCol*3 + 2] += (iCnt>0); + if( *p==0x00 ) break; + p++; + p += fts3GetVarint32(p, &iCol); + }while( iColpLeft, nCol); + fts3EvalUpdateCounts(pExpr->pRight, nCol); + } +} + +/* +** This is an sqlite3Fts3ExprIterate() callback. If the Fts3Expr.aMI[] array +** has not yet been allocated, allocate and zero it. Otherwise, just zero +** it. +*/ +static int fts3AllocateMSI(Fts3Expr *pExpr, int iPhrase, void *pCtx){ + Fts3Table *pTab = (Fts3Table*)pCtx; + UNUSED_PARAMETER(iPhrase); + if( pExpr->aMI==0 ){ + pExpr->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); + if( pExpr->aMI==0 ) return SQLITE_NOMEM; + } + memset(pExpr->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); + return SQLITE_OK; +} + +/* +** Expression pExpr must be of type FTSQUERY_PHRASE. +** +** If it is not already allocated and populated, this function allocates and +** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part +** of a NEAR expression, then it also allocates and populates the same array +** for all other phrases that are part of the NEAR expression. +** +** SQLITE_OK is returned if the aMI[] array is successfully allocated and +** populated. Otherwise, if an error occurs, an SQLite error code is returned. +*/ +static int fts3EvalGatherStats( + Fts3Cursor *pCsr, /* Cursor object */ + Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pExpr->eType==FTSQUERY_PHRASE ); + if( pExpr->aMI==0 ){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + Fts3Expr *pRoot; /* Root of NEAR expression */ + + sqlite3_int64 iPrevId = pCsr->iPrevId; + sqlite3_int64 iDocid; + u8 bEof; + + /* Find the root of the NEAR expression */ + pRoot = pExpr; + while( pRoot->pParent + && (pRoot->pParent->eType==FTSQUERY_NEAR || pRoot->bDeferred) + ){ + pRoot = pRoot->pParent; + } + iDocid = pRoot->iDocid; + bEof = pRoot->bEof; + assert( pRoot->bStart ); + + /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ + rc = sqlite3Fts3ExprIterate(pRoot, fts3AllocateMSI, (void*)pTab); + if( rc!=SQLITE_OK ) return rc; + fts3EvalRestart(pCsr, pRoot, &rc); + + while( pCsr->isEof==0 && rc==SQLITE_OK ){ + + do { + /* Ensure the %_content statement is reset. */ + if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt); + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + + /* Advance to the next document */ + fts3EvalNextRow(pCsr, pRoot, &rc); + pCsr->isEof = pRoot->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pRoot->iDocid; + }while( pCsr->isEof==0 + && pRoot->eType==FTSQUERY_NEAR + && sqlite3Fts3EvalTestDeferred(pCsr, &rc) + ); + + if( rc==SQLITE_OK && pCsr->isEof==0 ){ + fts3EvalUpdateCounts(pRoot, pTab->nColumn); + } + } + + pCsr->isEof = 0; + pCsr->iPrevId = iPrevId; + + if( bEof ){ + pRoot->bEof = bEof; + }else{ + /* Caution: pRoot may iterate through docids in ascending or descending + ** order. For this reason, even though it seems more defensive, the + ** do loop can not be written: + ** + ** do {...} while( pRoot->iDocidbEof==0 ); + if( pRoot->bEof ) rc = FTS_CORRUPT_VTAB; + }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK ); + } + } + return rc; +} + +/* +** This function is used by the matchinfo() module to query a phrase +** expression node for the following information: +** +** 1. The total number of occurrences of the phrase in each column of +** the FTS table (considering all rows), and +** +** 2. For each column, the number of rows in the table for which the +** column contains at least one instance of the phrase. +** +** If no error occurs, SQLITE_OK is returned and the values for each column +** written into the array aiOut as follows: +** +** aiOut[iCol*3 + 1] = Number of occurrences +** aiOut[iCol*3 + 2] = Number of rows containing at least one instance +** +** Caveats: +** +** * If a phrase consists entirely of deferred tokens, then all output +** values are set to the number of documents in the table. In other +** words we assume that very common tokens occur exactly once in each +** column of each row of the table. +** +** * If a phrase contains some deferred tokens (and some non-deferred +** tokens), count the potential occurrence identified by considering +** the non-deferred tokens instead of actual phrase occurrences. +** +** * If the phrase is part of a NEAR expression, then only phrase instances +** that meet the NEAR constraint are included in the counts. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Phrase expression */ + u32 *aiOut /* Array to write results into (see above) */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int iCol; + + if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ + assert( pCsr->nDoc>0 ); + for(iCol=0; iColnColumn; iCol++){ + aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; + aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; + } + }else{ + rc = fts3EvalGatherStats(pCsr, pExpr); + if( rc==SQLITE_OK ){ + assert( pExpr->aMI ); + for(iCol=0; iColnColumn; iCol++){ + aiOut[iCol*3 + 1] = pExpr->aMI[iCol*3 + 1]; + aiOut[iCol*3 + 2] = pExpr->aMI[iCol*3 + 2]; + } + } + } + + return rc; +} + +/* +** The expression pExpr passed as the second argument to this function +** must be of type FTSQUERY_PHRASE. +** +** The returned value is either NULL or a pointer to a buffer containing +** a position-list indicating the occurrences of the phrase in column iCol +** of the current row. +** +** More specifically, the returned buffer contains 1 varint for each +** occurrence of the phrase in the column, stored using the normal (delta+2) +** compression and is terminated by either an 0x01 or 0x00 byte. For example, +** if the requested column contains "a b X c d X X" and the position-list +** for 'X' is requested, the buffer returned may contain: +** +** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 +** +** This function works regardless of whether or not the phrase is deferred, +** incremental, or neither. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + Fts3Expr *pExpr, /* Phrase to return doclist for */ + int iCol, /* Column to return position list for */ + char **ppOut /* OUT: Pointer to position list */ +){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + char *pIter; + int iThis; + sqlite3_int64 iDocid; + + /* If this phrase is applies specifically to some column other than + ** column iCol, return a NULL pointer. */ + *ppOut = 0; + assert( iCol>=0 && iColnColumn ); + if( (pPhrase->iColumnnColumn && pPhrase->iColumn!=iCol) ){ + return SQLITE_OK; + } + + iDocid = pExpr->iDocid; + pIter = pPhrase->doclist.pList; + if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ + int rc = SQLITE_OK; + int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ + int bOr = 0; + u8 bTreeEof = 0; + Fts3Expr *p; /* Used to iterate from pExpr to root */ + Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ + Fts3Expr *pRun; /* Closest non-deferred ancestor of pNear */ + int bMatch; + + /* Check if this phrase descends from an OR expression node. If not, + ** return NULL. Otherwise, the entry that corresponds to docid + ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the + ** tree that the node is part of has been marked as EOF, but the node + ** itself is not EOF, then it may point to an earlier entry. */ + pNear = pExpr; + for(p=pExpr->pParent; p; p=p->pParent){ + if( p->eType==FTSQUERY_OR ) bOr = 1; + if( p->eType==FTSQUERY_NEAR ) pNear = p; + if( p->bEof ) bTreeEof = 1; + } + if( bOr==0 ) return SQLITE_OK; + pRun = pNear; + while( pRun->bDeferred ){ + assert( pRun->pParent ); + pRun = pRun->pParent; + } + + /* This is the descendent of an OR node. In this case we cannot use + ** an incremental phrase. Load the entire doclist for the phrase + ** into memory in this case. */ + if( pPhrase->bIncr ){ + int bEofSave = pRun->bEof; + fts3EvalRestart(pCsr, pRun, &rc); + while( rc==SQLITE_OK && !pRun->bEof ){ + fts3EvalNextRow(pCsr, pRun, &rc); + if( bEofSave==0 && pRun->iDocid==iDocid ) break; + } + assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); + if( rc==SQLITE_OK && pRun->bEof!=bEofSave ){ + rc = FTS_CORRUPT_VTAB; + } + } + if( bTreeEof ){ + while( rc==SQLITE_OK && !pRun->bEof ){ + fts3EvalNextRow(pCsr, pRun, &rc); + } + } + if( rc!=SQLITE_OK ) return rc; + + bMatch = 1; + for(p=pNear; p; p=p->pLeft){ + u8 bEof = 0; + Fts3Expr *pTest = p; + Fts3Phrase *pPh; + assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE ); + if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight; + assert( pTest->eType==FTSQUERY_PHRASE ); + pPh = pTest->pPhrase; + + pIter = pPh->pOrPoslist; + iDocid = pPh->iOrDocid; + if( pCsr->bDesc==bDescDoclist ){ + bEof = !pPh->doclist.nAll || + (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll)); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ + sqlite3Fts3DoclistNext( + bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, + &pIter, &iDocid, &bEof + ); + } + }else{ + bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ + int dummy; + sqlite3Fts3DoclistPrev( + bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, + &pIter, &iDocid, &dummy, &bEof + ); + } + } + pPh->pOrPoslist = pIter; + pPh->iOrDocid = iDocid; + if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0; + } + + if( bMatch ){ + pIter = pPhrase->pOrPoslist; + }else{ + pIter = 0; + } + } + if( pIter==0 ) return SQLITE_OK; + + if( *pIter==0x01 ){ + pIter++; + pIter += fts3GetVarint32(pIter, &iThis); + }else{ + iThis = 0; + } + while( iThisdoclist, and +** * any Fts3MultiSegReader objects held by phrase tokens. +*/ +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ + if( pPhrase ){ + int i; + sqlite3_free(pPhrase->doclist.aAll); + fts3EvalInvalidatePoslist(pPhrase); + memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); + for(i=0; inToken; i++){ + fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); + pPhrase->aToken[i].pSegcsr = 0; + } + } +} + + +/* +** Return SQLITE_CORRUPT_VTAB. +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ + return SQLITE_CORRUPT_VTAB; +} +#endif + +#if !SQLITE_CORE +/* +** Initialize API pointer table, if required. +*/ +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_fts3_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3Fts3Init(db); +} +#endif + +#endif + +/************** End of fts3.c ************************************************/ +/************** Begin file fts3_aux.c ****************************************/ +/* +** 2011 Jan 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +typedef struct Fts3auxTable Fts3auxTable; +typedef struct Fts3auxCursor Fts3auxCursor; + +struct Fts3auxTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + Fts3Table *pFts3Tab; +}; + +struct Fts3auxCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + Fts3MultiSegReader csr; /* Must be right after "base" */ + Fts3SegFilter filter; + char *zStop; + int nStop; /* Byte-length of string zStop */ + int iLangid; /* Language id to query */ + int isEof; /* True if cursor is at EOF */ + sqlite3_int64 iRowid; /* Current rowid */ + + int iCol; /* Current value of 'col' column */ + int nStat; /* Size of aStat[] array */ + struct Fts3auxColstats { + sqlite3_int64 nDoc; /* 'documents' values for current csr row */ + sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ + } *aStat; +}; + +/* +** Schema of the terms table. +*/ +#define FTS3_AUX_SCHEMA \ + "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)" + +/* +** This function does all the work for both the xConnect and xCreate methods. +** These tables have no persistent representation of their own, so xConnect +** and xCreate are identical operations. +*/ +static int fts3auxConnectMethod( + sqlite3 *db, /* Database connection */ + void *pUnused, /* Unused */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + char const *zDb; /* Name of database (e.g. "main") */ + char const *zFts3; /* Name of fts3 table */ + int nDb; /* Result of strlen(zDb) */ + int nFts3; /* Result of strlen(zFts3) */ + sqlite3_int64 nByte; /* Bytes of space to allocate here */ + int rc; /* value returned by declare_vtab() */ + Fts3auxTable *p; /* Virtual table object to return */ + + UNUSED_PARAMETER(pUnused); + + /* The user should invoke this in one of two forms: + ** + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table); + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table); + */ + if( argc!=4 && argc!=5 ) goto bad_args; + + zDb = argv[1]; + nDb = (int)strlen(zDb); + if( argc==5 ){ + if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){ + zDb = argv[3]; + nDb = (int)strlen(zDb); + zFts3 = argv[4]; + }else{ + goto bad_args; + } + }else{ + zFts3 = argv[3]; + } + nFts3 = (int)strlen(zFts3); + + rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); + if( rc!=SQLITE_OK ) return rc; + + nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; + p = (Fts3auxTable *)sqlite3_malloc64(nByte); + if( !p ) return SQLITE_NOMEM; + memset(p, 0, nByte); + + p->pFts3Tab = (Fts3Table *)&p[1]; + p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1]; + p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1]; + p->pFts3Tab->db = db; + p->pFts3Tab->nIndex = 1; + + memcpy((char *)p->pFts3Tab->zDb, zDb, nDb); + memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); + sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); + + *ppVtab = (sqlite3_vtab *)p; + return SQLITE_OK; + + bad_args: + sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); + return SQLITE_ERROR; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3auxTable *p = (Fts3auxTable *)pVtab; + Fts3Table *pFts3 = p->pFts3Tab; + int i; + + /* Free any prepared statements held */ + for(i=0; iaStmt); i++){ + sqlite3_finalize(pFts3->aStmt[i]); + } + sqlite3_free(pFts3->zSegmentsTbl); + sqlite3_free(p); + return SQLITE_OK; +} + +#define FTS4AUX_EQ_CONSTRAINT 1 +#define FTS4AUX_GE_CONSTRAINT 2 +#define FTS4AUX_LE_CONSTRAINT 4 + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3auxBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + int iEq = -1; + int iGe = -1; + int iLe = -1; + int iLangid = -1; + int iNext = 1; /* Next free argvIndex value */ + + UNUSED_PARAMETER(pVTab); + + /* This vtab delivers always results in "ORDER BY term ASC" order. */ + if( pInfo->nOrderBy==1 + && pInfo->aOrderBy[0].iColumn==0 + && pInfo->aOrderBy[0].desc==0 + ){ + pInfo->orderByConsumed = 1; + } + + /* Search for equality and range constraints on the "term" column. + ** And equality constraints on the hidden "languageid" column. */ + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable ){ + int op = pInfo->aConstraint[i].op; + int iCol = pInfo->aConstraint[i].iColumn; + + if( iCol==0 ){ + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; + if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; + } + if( iCol==4 ){ + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i; + } + } + } + + if( iEq>=0 ){ + pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; + pInfo->aConstraintUsage[iEq].argvIndex = iNext++; + pInfo->estimatedCost = 5; + }else{ + pInfo->idxNum = 0; + pInfo->estimatedCost = 20000; + if( iGe>=0 ){ + pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; + pInfo->aConstraintUsage[iGe].argvIndex = iNext++; + pInfo->estimatedCost /= 2; + } + if( iLe>=0 ){ + pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; + pInfo->aConstraintUsage[iLe].argvIndex = iNext++; + pInfo->estimatedCost /= 2; + } + } + if( iLangid>=0 ){ + pInfo->aConstraintUsage[iLangid].argvIndex = iNext++; + pInfo->estimatedCost--; + } + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3auxCursor *pCsr; /* Pointer to cursor object to return */ + + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor)); + if( !pCsr ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(Fts3auxCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + + sqlite3Fts3SegmentsClose(pFts3); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->zStop); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ + if( nSize>pCsr->nStat ){ + struct Fts3auxColstats *aNew; + aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat, + sizeof(struct Fts3auxColstats) * nSize + ); + if( aNew==0 ) return SQLITE_NOMEM; + memset(&aNew[pCsr->nStat], 0, + sizeof(struct Fts3auxColstats) * (nSize - pCsr->nStat) + ); + pCsr->aStat = aNew; + pCsr->nStat = nSize; + } + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + + /* Increment our pretend rowid value. */ + pCsr->iRowid++; + + for(pCsr->iCol++; pCsr->iColnStat; pCsr->iCol++){ + if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK; + } + + rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); + if( rc==SQLITE_ROW ){ + int i = 0; + int nDoclist = pCsr->csr.nDoclist; + char *aDoclist = pCsr->csr.aDoclist; + int iCol; + + int eState = 0; + + if( pCsr->zStop ){ + int n = (pCsr->nStopcsr.nTerm) ? pCsr->nStop : pCsr->csr.nTerm; + int mc = memcmp(pCsr->zStop, pCsr->csr.zTerm, n); + if( mc<0 || (mc==0 && pCsr->csr.nTerm>pCsr->nStop) ){ + pCsr->isEof = 1; + return SQLITE_OK; + } + } + + if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM; + memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat); + iCol = 0; + rc = SQLITE_OK; + + while( iaStat[0].nDoc++; + eState = 1; + iCol = 0; + break; + + /* State 1. In this state we are expecting either a 1, indicating + ** that the following integer will be a column number, or the + ** start of a position list for column 0. + ** + ** The only difference between state 1 and state 2 is that if the + ** integer encountered in state 1 is not 0 or 1, then we need to + ** increment the column 0 "nDoc" count for this term. + */ + case 1: + assert( iCol==0 ); + if( v>1 ){ + pCsr->aStat[1].nDoc++; + } + eState = 2; + /* fall through */ + + case 2: + if( v==0 ){ /* 0x00. Next integer will be a docid. */ + eState = 0; + }else if( v==1 ){ /* 0x01. Next integer will be a column number. */ + eState = 3; + }else{ /* 2 or greater. A position. */ + pCsr->aStat[iCol+1].nOcc++; + pCsr->aStat[0].nOcc++; + } + break; + + /* State 3. The integer just read is a column number. */ + default: assert( eState==3 ); + iCol = (int)v; + if( iCol<1 ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } + if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; + pCsr->aStat[iCol+1].nDoc++; + eState = 2; + break; + } + } + + pCsr->iCol = 0; + }else{ + pCsr->isEof = 1; + } + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3auxFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + int isScan = 0; + int iLangVal = 0; /* Language id to query */ + + int iEq = -1; /* Index of term=? value in apVal */ + int iGe = -1; /* Index of term>=? value in apVal */ + int iLe = -1; /* Index of term<=? value in apVal */ + int iLangid = -1; /* Index of languageid=? value in apVal */ + int iNext = 0; + + UNUSED_PARAMETER(nVal); + UNUSED_PARAMETER(idxStr); + + assert( idxStr==0 ); + assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 + || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT + || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) + ); + + if( idxNum==FTS4AUX_EQ_CONSTRAINT ){ + iEq = iNext++; + }else{ + isScan = 1; + if( idxNum & FTS4AUX_GE_CONSTRAINT ){ + iGe = iNext++; + } + if( idxNum & FTS4AUX_LE_CONSTRAINT ){ + iLe = iNext++; + } + } + if( iNextfilter.zTerm); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr->zStop); + memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); + + pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; + + if( iEq>=0 || iGe>=0 ){ + const unsigned char *zStr = sqlite3_value_text(apVal[0]); + assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); + if( zStr ){ + pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); + if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; + pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm); + } + } + + if( iLe>=0 ){ + pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); + if( pCsr->zStop==0 ) return SQLITE_NOMEM; + pCsr->nStop = (int)strlen(pCsr->zStop); + } + + if( iLangid>=0 ){ + iLangVal = sqlite3_value_int(apVal[iLangid]); + + /* If the user specified a negative value for the languageid, use zero + ** instead. This works, as the "languageid=?" constraint will also + ** be tested by the VDBE layer. The test will always be false (since + ** this module will not return a row with a negative languageid), and + ** so the overall query will return zero rows. */ + if( iLangVal<0 ) iLangVal = 0; + } + pCsr->iLangid = iLangVal; + + rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, + pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); + } + + if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor); + return rc; +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + return pCsr->isEof; +} + +/* +** xColumn - Return a column value. +*/ +static int fts3auxColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3auxCursor *p = (Fts3auxCursor *)pCursor; + + assert( p->isEof==0 ); + switch( iCol ){ + case 0: /* term */ + sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); + break; + + case 1: /* col */ + if( p->iCol ){ + sqlite3_result_int(pCtx, p->iCol-1); + }else{ + sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); + } + break; + + case 2: /* documents */ + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); + break; + + case 3: /* occurrences */ + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); + break; + + default: /* languageid */ + assert( iCol==4 ); + sqlite3_result_int(pCtx, p->iLangid); + break; + } + + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3auxRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3aux module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ + static const sqlite3_module fts3aux_module = { + 0, /* iVersion */ + fts3auxConnectMethod, /* xCreate */ + fts3auxConnectMethod, /* xConnect */ + fts3auxBestIndexMethod, /* xBestIndex */ + fts3auxDisconnectMethod, /* xDisconnect */ + fts3auxDisconnectMethod, /* xDestroy */ + fts3auxOpenMethod, /* xOpen */ + fts3auxCloseMethod, /* xClose */ + fts3auxFilterMethod, /* xFilter */ + fts3auxNextMethod, /* xNext */ + fts3auxEofMethod, /* xEof */ + fts3auxColumnMethod, /* xColumn */ + fts3auxRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_aux.c ********************************************/ +/************** Begin file fts3_expr.c ***************************************/ +/* +** 2008 Nov 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This module contains code that implements a parser for fts3 query strings +** (the right-hand argument to the MATCH operator). Because the supported +** syntax is relatively simple, the whole tokenizer/parser system is +** hand-coded. +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* +** By default, this module parses the legacy syntax that has been +** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS +** is defined, then it uses the new syntax. The differences between +** the new and the old syntaxes are: +** +** a) The new syntax supports parenthesis. The old does not. +** +** b) The new syntax supports the AND and NOT operators. The old does not. +** +** c) The old syntax supports the "-" token qualifier. This is not +** supported by the new syntax (it is replaced by the NOT operator). +** +** d) When using the old syntax, the OR operator has a greater precedence +** than an implicit AND. When using the new, both implicity and explicit +** AND operators have a higher precedence than OR. +** +** If compiled with SQLITE_TEST defined, then this module exports the +** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable +** to zero causes the module to use the old syntax. If it is set to +** non-zero the new syntax is activated. This is so both syntaxes can +** be tested using a single build of testfixture. +** +** The following describes the syntax supported by the fts3 MATCH +** operator in a similar format to that used by the lemon parser +** generator. This module does not use actually lemon, it uses a +** custom parser. +** +** query ::= andexpr (OR andexpr)*. +** +** andexpr ::= notexpr (AND? notexpr)*. +** +** notexpr ::= nearexpr (NOT nearexpr|-TOKEN)*. +** notexpr ::= LP query RP. +** +** nearexpr ::= phrase (NEAR distance_opt nearexpr)*. +** +** distance_opt ::= . +** distance_opt ::= / INTEGER. +** +** phrase ::= TOKEN. +** phrase ::= COLUMN:TOKEN. +** phrase ::= "TOKEN TOKEN TOKEN...". +*/ + +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_fts3_enable_parentheses = 0; +#else +# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS +# define sqlite3_fts3_enable_parentheses 1 +# else +# define sqlite3_fts3_enable_parentheses 0 +# endif +#endif + +/* +** Default span for NEAR operators. +*/ +#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10 + +/* #include */ +/* #include */ + +/* +** isNot: +** This variable is used by function getNextNode(). When getNextNode() is +** called, it sets ParseContext.isNot to true if the 'next node' is a +** FTSQUERY_PHRASE with a unary "-" attached to it. i.e. "mysql" in the +** FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to +** zero. +*/ +typedef struct ParseContext ParseContext; +struct ParseContext { + sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ + int iLangid; /* Language id used with tokenizer */ + const char **azCol; /* Array of column names for fts3 table */ + int bFts4; /* True to allow FTS4-only syntax */ + int nCol; /* Number of entries in azCol[] */ + int iDefaultCol; /* Default column to query */ + int isNot; /* True if getNextNode() sees a unary - */ + sqlite3_context *pCtx; /* Write error message here */ + int nNest; /* Number of nested brackets */ +}; + +/* +** This function is equivalent to the standard isspace() function. +** +** The standard isspace() can be awkward to use safely, because although it +** is defined to accept an argument of type int, its behavior when passed +** an integer that falls outside of the range of the unsigned char type +** is undefined (and sometimes, "undefined" means segfault). This wrapper +** is defined to accept an argument of type char, and always returns 0 for +** any values that fall outside of the range of the unsigned char type (i.e. +** negative values). +*/ +static int fts3isspace(char c){ + return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; +} + +/* +** Allocate nByte bytes of memory using sqlite3_malloc(). If successful, +** zero the memory before returning a pointer to it. If unsuccessful, +** return NULL. +*/ +SQLITE_PRIVATE void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){ + void *pRet = sqlite3_malloc64(nByte); + if( pRet ) memset(pRet, 0, nByte); + return pRet; +} + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( + sqlite3_tokenizer *pTokenizer, + int iLangid, + const char *z, + int n, + sqlite3_tokenizer_cursor **ppCsr +){ + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr = 0; + int rc; + + rc = pModule->xOpen(pTokenizer, z, n, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( rc==SQLITE_OK ){ + pCsr->pTokenizer = pTokenizer; + if( pModule->iVersion>=1 ){ + rc = pModule->xLanguageid(pCsr, iLangid); + if( rc!=SQLITE_OK ){ + pModule->xClose(pCsr); + pCsr = 0; + } + } + } + *ppCsr = pCsr; + return rc; +} + +/* +** Function getNextNode(), which is called by fts3ExprParse(), may itself +** call fts3ExprParse(). So this forward declaration is required. +*/ +static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); + +/* +** Extract the next token from buffer z (length n) using the tokenizer +** and other information (column names etc.) in pParse. Create an Fts3Expr +** structure of type FTSQUERY_PHRASE containing a phrase consisting of this +** single token and set *ppExpr to point to it. If the end of the buffer is +** reached before a token is found, set *ppExpr to zero. It is the +** responsibility of the caller to eventually deallocate the allocated +** Fts3Expr structure (if any) by passing it to sqlite3_free(). +** +** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation +** fails. +*/ +static int getNextToken( + ParseContext *pParse, /* fts3 query parse context */ + int iCol, /* Value for Fts3Phrase.iColumn */ + const char *z, int n, /* Input string */ + Fts3Expr **ppExpr, /* OUT: expression */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + int rc; + sqlite3_tokenizer_cursor *pCursor; + Fts3Expr *pRet = 0; + int i = 0; + + /* Set variable i to the maximum number of bytes of input to tokenize. */ + for(i=0; iiLangid, z, i, &pCursor); + if( rc==SQLITE_OK ){ + const char *zToken; + int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; + sqlite3_int64 nByte; /* total space to allocate */ + + rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); + if( rc==SQLITE_OK ){ + nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; + pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); + if( !pRet ){ + rc = SQLITE_NOMEM; + }else{ + pRet->eType = FTSQUERY_PHRASE; + pRet->pPhrase = (Fts3Phrase *)&pRet[1]; + pRet->pPhrase->nToken = 1; + pRet->pPhrase->iColumn = iCol; + pRet->pPhrase->aToken[0].n = nToken; + pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1]; + memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); + + if( iEndpPhrase->aToken[0].isPrefix = 1; + iEnd++; + } + + while( 1 ){ + if( !sqlite3_fts3_enable_parentheses + && iStart>0 && z[iStart-1]=='-' + ){ + pParse->isNot = 1; + iStart--; + }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){ + pRet->pPhrase->aToken[0].bFirst = 1; + iStart--; + }else{ + break; + } + } + + } + *pnConsumed = iEnd; + }else if( i && rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + + pModule->xClose(pCursor); + } + + *ppExpr = pRet; + return rc; +} + + +/* +** Enlarge a memory allocation. If an out-of-memory allocation occurs, +** then free the old allocation. +*/ +static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){ + void *pRet = sqlite3_realloc64(pOrig, nNew); + if( !pRet ){ + sqlite3_free(pOrig); + } + return pRet; +} + +/* +** Buffer zInput, length nInput, contains the contents of a quoted string +** that appeared as part of an fts3 query expression. Neither quote character +** is included in the buffer. This function attempts to tokenize the entire +** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE +** containing the results. +** +** If successful, SQLITE_OK is returned and *ppExpr set to point at the +** allocated Fts3Expr structure. Otherwise, either SQLITE_NOMEM (out of memory +** error) or SQLITE_ERROR (tokenization error) is returned and *ppExpr set +** to 0. +*/ +static int getNextString( + ParseContext *pParse, /* fts3 query parse context */ + const char *zInput, int nInput, /* Input string */ + Fts3Expr **ppExpr /* OUT: expression */ +){ + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + int rc; + Fts3Expr *p = 0; + sqlite3_tokenizer_cursor *pCursor = 0; + char *zTemp = 0; + int nTemp = 0; + + const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); + int nToken = 0; + + /* The final Fts3Expr data structure, including the Fts3Phrase, + ** Fts3PhraseToken structures token buffers are all stored as a single + ** allocation so that the expression can be freed with a single call to + ** sqlite3_free(). Setting this up requires a two pass approach. + ** + ** The first pass, in the block below, uses a tokenizer cursor to iterate + ** through the tokens in the expression. This pass uses fts3ReallocOrFree() + ** to assemble data in two dynamic buffers: + ** + ** Buffer p: Points to the Fts3Expr structure, followed by the Fts3Phrase + ** structure, followed by the array of Fts3PhraseToken + ** structures. This pass only populates the Fts3PhraseToken array. + ** + ** Buffer zTemp: Contains copies of all tokens. + ** + ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below, + ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase + ** structures. + */ + rc = sqlite3Fts3OpenTokenizer( + pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); + if( rc==SQLITE_OK ){ + int ii; + for(ii=0; rc==SQLITE_OK; ii++){ + const char *zByte; + int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0; + rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); + if( rc==SQLITE_OK ){ + Fts3PhraseToken *pToken; + + p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); + if( !p ) goto no_mem; + + zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); + if( !zTemp ) goto no_mem; + + assert( nToken==ii ); + pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; + memset(pToken, 0, sizeof(Fts3PhraseToken)); + + memcpy(&zTemp[nTemp], zByte, nByte); + nTemp += nByte; + + pToken->n = nByte; + pToken->isPrefix = (iEndbFirst = (iBegin>0 && zInput[iBegin-1]=='^'); + nToken = ii+1; + } + } + + pModule->xClose(pCursor); + pCursor = 0; + } + + if( rc==SQLITE_DONE ){ + int jj; + char *zBuf = 0; + + p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); + if( !p ) goto no_mem; + memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); + p->eType = FTSQUERY_PHRASE; + p->pPhrase = (Fts3Phrase *)&p[1]; + p->pPhrase->iColumn = pParse->iDefaultCol; + p->pPhrase->nToken = nToken; + + zBuf = (char *)&p->pPhrase->aToken[nToken]; + if( zTemp ){ + memcpy(zBuf, zTemp, nTemp); + sqlite3_free(zTemp); + }else{ + assert( nTemp==0 ); + } + + for(jj=0; jjpPhrase->nToken; jj++){ + p->pPhrase->aToken[jj].z = zBuf; + zBuf += p->pPhrase->aToken[jj].n; + } + rc = SQLITE_OK; + } + + *ppExpr = p; + return rc; +no_mem: + + if( pCursor ){ + pModule->xClose(pCursor); + } + sqlite3_free(zTemp); + sqlite3_free(p); + *ppExpr = 0; + return SQLITE_NOMEM; +} + +/* +** The output variable *ppExpr is populated with an allocated Fts3Expr +** structure, or set to 0 if the end of the input buffer is reached. +** +** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM +** if a malloc failure occurs, or SQLITE_ERROR if a parse error is encountered. +** If SQLITE_ERROR is returned, pContext is populated with an error message. +*/ +static int getNextNode( + ParseContext *pParse, /* fts3 query parse context */ + const char *z, int n, /* Input string */ + Fts3Expr **ppExpr, /* OUT: expression */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + static const struct Fts3Keyword { + char *z; /* Keyword text */ + unsigned char n; /* Length of the keyword */ + unsigned char parenOnly; /* Only valid in paren mode */ + unsigned char eType; /* Keyword code */ + } aKeyword[] = { + { "OR" , 2, 0, FTSQUERY_OR }, + { "AND", 3, 1, FTSQUERY_AND }, + { "NOT", 3, 1, FTSQUERY_NOT }, + { "NEAR", 4, 0, FTSQUERY_NEAR } + }; + int ii; + int iCol; + int iColLen; + int rc; + Fts3Expr *pRet = 0; + + const char *zInput = z; + int nInput = n; + + pParse->isNot = 0; + + /* Skip over any whitespace before checking for a keyword, an open or + ** close bracket, or a quoted string. + */ + while( nInput>0 && fts3isspace(*zInput) ){ + nInput--; + zInput++; + } + if( nInput==0 ){ + return SQLITE_DONE; + } + + /* See if we are dealing with a keyword. */ + for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){ + const struct Fts3Keyword *pKey = &aKeyword[ii]; + + if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){ + continue; + } + + if( nInput>=pKey->n && 0==memcmp(zInput, pKey->z, pKey->n) ){ + int nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM; + int nKey = pKey->n; + char cNext; + + /* If this is a "NEAR" keyword, check for an explicit nearness. */ + if( pKey->eType==FTSQUERY_NEAR ){ + assert( nKey==4 ); + if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ + nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear); + } + } + + /* At this point this is probably a keyword. But for that to be true, + ** the next byte must contain either whitespace, an open or close + ** parenthesis, a quote character, or EOF. + */ + cNext = zInput[nKey]; + if( fts3isspace(cNext) + || cNext=='"' || cNext=='(' || cNext==')' || cNext==0 + ){ + pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr)); + if( !pRet ){ + return SQLITE_NOMEM; + } + pRet->eType = pKey->eType; + pRet->nNear = nNear; + *ppExpr = pRet; + *pnConsumed = (int)((zInput - z) + nKey); + return SQLITE_OK; + } + + /* Turns out that wasn't a keyword after all. This happens if the + ** user has supplied a token such as "ORacle". Continue. + */ + } + } + + /* See if we are dealing with a quoted phrase. If this is the case, then + ** search for the closing quote and pass the whole string to getNextString() + ** for processing. This is easy to do, as fts3 has no syntax for escaping + ** a quote character embedded in a string. + */ + if( *zInput=='"' ){ + for(ii=1; iinNest++; +#if !defined(SQLITE_MAX_EXPR_DEPTH) + if( pParse->nNest>1000 ) return SQLITE_ERROR; +#elif SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR; +#endif + rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); + *pnConsumed = (int)(zInput - z) + 1 + nConsumed; + return rc; + }else if( *zInput==')' ){ + pParse->nNest--; + *pnConsumed = (int)((zInput - z) + 1); + *ppExpr = 0; + return SQLITE_DONE; + } + } + + /* If control flows to this point, this must be a regular token, or + ** the end of the input. Read a regular token using the sqlite3_tokenizer + ** interface. Before doing so, figure out if there is an explicit + ** column specifier for the token. + ** + ** TODO: Strangely, it is not possible to associate a column specifier + ** with a quoted phrase, only with a single token. Not sure if this was + ** an implementation artifact or an intentional decision when fts3 was + ** first implemented. Whichever it was, this module duplicates the + ** limitation. + */ + iCol = pParse->iDefaultCol; + iColLen = 0; + for(ii=0; iinCol; ii++){ + const char *zStr = pParse->azCol[ii]; + int nStr = (int)strlen(zStr); + if( nInput>nStr && zInput[nStr]==':' + && sqlite3_strnicmp(zStr, zInput, nStr)==0 + ){ + iCol = ii; + iColLen = (int)((zInput - z) + nStr + 1); + break; + } + } + rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed); + *pnConsumed += iColLen; + return rc; +} + +/* +** The argument is an Fts3Expr structure for a binary operator (any type +** except an FTSQUERY_PHRASE). Return an integer value representing the +** precedence of the operator. Lower values have a higher precedence (i.e. +** group more tightly). For example, in the C language, the == operator +** groups more tightly than ||, and would therefore have a higher precedence. +** +** When using the new fts3 query syntax (when SQLITE_ENABLE_FTS3_PARENTHESIS +** is defined), the order of the operators in precedence from highest to +** lowest is: +** +** NEAR +** NOT +** AND (including implicit ANDs) +** OR +** +** Note that when using the old query syntax, the OR operator has a higher +** precedence than the AND operator. +*/ +static int opPrecedence(Fts3Expr *p){ + assert( p->eType!=FTSQUERY_PHRASE ); + if( sqlite3_fts3_enable_parentheses ){ + return p->eType; + }else if( p->eType==FTSQUERY_NEAR ){ + return 1; + }else if( p->eType==FTSQUERY_OR ){ + return 2; + } + assert( p->eType==FTSQUERY_AND ); + return 3; +} + +/* +** Argument ppHead contains a pointer to the current head of a query +** expression tree being parsed. pPrev is the expression node most recently +** inserted into the tree. This function adds pNew, which is always a binary +** operator node, into the expression tree based on the relative precedence +** of pNew and the existing nodes of the tree. This may result in the head +** of the tree changing, in which case *ppHead is set to the new root node. +*/ +static void insertBinaryOperator( + Fts3Expr **ppHead, /* Pointer to the root node of a tree */ + Fts3Expr *pPrev, /* Node most recently inserted into the tree */ + Fts3Expr *pNew /* New binary node to insert into expression tree */ +){ + Fts3Expr *pSplit = pPrev; + while( pSplit->pParent && opPrecedence(pSplit->pParent)<=opPrecedence(pNew) ){ + pSplit = pSplit->pParent; + } + + if( pSplit->pParent ){ + assert( pSplit->pParent->pRight==pSplit ); + pSplit->pParent->pRight = pNew; + pNew->pParent = pSplit->pParent; + }else{ + *ppHead = pNew; + } + pNew->pLeft = pSplit; + pSplit->pParent = pNew; +} + +/* +** Parse the fts3 query expression found in buffer z, length n. This function +** returns either when the end of the buffer is reached or an unmatched +** closing bracket - ')' - is encountered. +** +** If successful, SQLITE_OK is returned, *ppExpr is set to point to the +** parsed form of the expression and *pnConsumed is set to the number of +** bytes read from buffer z. Otherwise, *ppExpr is set to 0 and SQLITE_NOMEM +** (out of memory error) or SQLITE_ERROR (parse error) is returned. +*/ +static int fts3ExprParse( + ParseContext *pParse, /* fts3 query parse context */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr, /* OUT: Parsed query structure */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + Fts3Expr *pRet = 0; + Fts3Expr *pPrev = 0; + Fts3Expr *pNotBranch = 0; /* Only used in legacy parse mode */ + int nIn = n; + const char *zIn = z; + int rc = SQLITE_OK; + int isRequirePhrase = 1; + + while( rc==SQLITE_OK ){ + Fts3Expr *p = 0; + int nByte = 0; + + rc = getNextNode(pParse, zIn, nIn, &p, &nByte); + assert( nByte>0 || (rc!=SQLITE_OK && p==0) ); + if( rc==SQLITE_OK ){ + if( p ){ + int isPhrase; + + if( !sqlite3_fts3_enable_parentheses + && p->eType==FTSQUERY_PHRASE && pParse->isNot + ){ + /* Create an implicit NOT operator. */ + Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr)); + if( !pNot ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_NOMEM; + goto exprparse_out; + } + pNot->eType = FTSQUERY_NOT; + pNot->pRight = p; + p->pParent = pNot; + if( pNotBranch ){ + pNot->pLeft = pNotBranch; + pNotBranch->pParent = pNot; + } + pNotBranch = pNot; + p = pPrev; + }else{ + int eType = p->eType; + isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); + + /* The isRequirePhrase variable is set to true if a phrase or + ** an expression contained in parenthesis is required. If a + ** binary operator (AND, OR, NOT or NEAR) is encounted when + ** isRequirePhrase is set, this is a syntax error. + */ + if( !isPhrase && isRequirePhrase ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_ERROR; + goto exprparse_out; + } + + if( isPhrase && !isRequirePhrase ){ + /* Insert an implicit AND operator. */ + Fts3Expr *pAnd; + assert( pRet && pPrev ); + pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr)); + if( !pAnd ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_NOMEM; + goto exprparse_out; + } + pAnd->eType = FTSQUERY_AND; + insertBinaryOperator(&pRet, pPrev, pAnd); + pPrev = pAnd; + } + + /* This test catches attempts to make either operand of a NEAR + ** operator something other than a phrase. For example, either of + ** the following: + ** + ** (bracketed expression) NEAR phrase + ** phrase NEAR (bracketed expression) + ** + ** Return an error in either case. + */ + if( pPrev && ( + (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) + || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) + )){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_ERROR; + goto exprparse_out; + } + + if( isPhrase ){ + if( pRet ){ + assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); + pPrev->pRight = p; + p->pParent = pPrev; + }else{ + pRet = p; + } + }else{ + insertBinaryOperator(&pRet, pPrev, p); + } + isRequirePhrase = !isPhrase; + } + pPrev = p; + } + assert( nByte>0 ); + } + assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); + nIn -= nByte; + zIn += nByte; + } + + if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + if( !sqlite3_fts3_enable_parentheses && pNotBranch ){ + if( !pRet ){ + rc = SQLITE_ERROR; + }else{ + Fts3Expr *pIter = pNotBranch; + while( pIter->pLeft ){ + pIter = pIter->pLeft; + } + pIter->pLeft = pRet; + pRet->pParent = pIter; + pRet = pNotBranch; + } + } + } + *pnConsumed = n - nIn; + +exprparse_out: + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRet); + sqlite3Fts3ExprFree(pNotBranch); + pRet = 0; + } + *ppExpr = pRet; + return rc; +} + +/* +** Return SQLITE_ERROR if the maximum depth of the expression tree passed +** as the only argument is more than nMaxDepth. +*/ +static int fts3ExprCheckDepth(Fts3Expr *p, int nMaxDepth){ + int rc = SQLITE_OK; + if( p ){ + if( nMaxDepth<0 ){ + rc = SQLITE_TOOBIG; + }else{ + rc = fts3ExprCheckDepth(p->pLeft, nMaxDepth-1); + if( rc==SQLITE_OK ){ + rc = fts3ExprCheckDepth(p->pRight, nMaxDepth-1); + } + } + } + return rc; +} + +/* +** This function attempts to transform the expression tree at (*pp) to +** an equivalent but more balanced form. The tree is modified in place. +** If successful, SQLITE_OK is returned and (*pp) set to point to the +** new root expression node. +** +** nMaxDepth is the maximum allowable depth of the balanced sub-tree. +** +** Otherwise, if an error occurs, an SQLite error code is returned and +** expression (*pp) freed. +*/ +static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ + int rc = SQLITE_OK; /* Return code */ + Fts3Expr *pRoot = *pp; /* Initial root node */ + Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */ + int eType = pRoot->eType; /* Type of node in this tree */ + + if( nMaxDepth==0 ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_OK ){ + if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ + Fts3Expr **apLeaf; + apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth); + if( 0==apLeaf ){ + rc = SQLITE_NOMEM; + }else{ + memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth); + } + + if( rc==SQLITE_OK ){ + int i; + Fts3Expr *p; + + /* Set $p to point to the left-most leaf in the tree of eType nodes. */ + for(p=pRoot; p->eType==eType; p=p->pLeft){ + assert( p->pParent==0 || p->pParent->pLeft==p ); + assert( p->pLeft && p->pRight ); + } + + /* This loop runs once for each leaf in the tree of eType nodes. */ + while( 1 ){ + int iLvl; + Fts3Expr *pParent = p->pParent; /* Current parent of p */ + + assert( pParent==0 || pParent->pLeft==p ); + p->pParent = 0; + if( pParent ){ + pParent->pLeft = 0; + }else{ + pRoot = 0; + } + rc = fts3ExprBalance(&p, nMaxDepth-1); + if( rc!=SQLITE_OK ) break; + + for(iLvl=0; p && iLvlpLeft = apLeaf[iLvl]; + pFree->pRight = p; + pFree->pLeft->pParent = pFree; + pFree->pRight->pParent = pFree; + + p = pFree; + pFree = pFree->pParent; + p->pParent = 0; + apLeaf[iLvl] = 0; + } + } + if( p ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_TOOBIG; + break; + } + + /* If that was the last leaf node, break out of the loop */ + if( pParent==0 ) break; + + /* Set $p to point to the next leaf in the tree of eType nodes */ + for(p=pParent->pRight; p->eType==eType; p=p->pLeft); + + /* Remove pParent from the original tree. */ + assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent ); + pParent->pRight->pParent = pParent->pParent; + if( pParent->pParent ){ + pParent->pParent->pLeft = pParent->pRight; + }else{ + assert( pParent==pRoot ); + pRoot = pParent->pRight; + } + + /* Link pParent into the free node list. It will be used as an + ** internal node of the new tree. */ + pParent->pParent = pFree; + pFree = pParent; + } + + if( rc==SQLITE_OK ){ + p = 0; + for(i=0; ipParent = 0; + }else{ + assert( pFree!=0 ); + pFree->pRight = p; + pFree->pLeft = apLeaf[i]; + pFree->pLeft->pParent = pFree; + pFree->pRight->pParent = pFree; + + p = pFree; + pFree = pFree->pParent; + p->pParent = 0; + } + } + } + pRoot = p; + }else{ + /* An error occurred. Delete the contents of the apLeaf[] array + ** and pFree list. Everything else is cleaned up by the call to + ** sqlite3Fts3ExprFree(pRoot) below. */ + Fts3Expr *pDel; + for(i=0; ipParent; + sqlite3_free(pDel); + } + } + + assert( pFree==0 ); + sqlite3_free( apLeaf ); + } + }else if( eType==FTSQUERY_NOT ){ + Fts3Expr *pLeft = pRoot->pLeft; + Fts3Expr *pRight = pRoot->pRight; + + pRoot->pLeft = 0; + pRoot->pRight = 0; + pLeft->pParent = 0; + pRight->pParent = 0; + + rc = fts3ExprBalance(&pLeft, nMaxDepth-1); + if( rc==SQLITE_OK ){ + rc = fts3ExprBalance(&pRight, nMaxDepth-1); + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRight); + sqlite3Fts3ExprFree(pLeft); + }else{ + assert( pLeft && pRight ); + pRoot->pLeft = pLeft; + pLeft->pParent = pRoot; + pRoot->pRight = pRight; + pRight->pParent = pRoot; + } + } + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRoot); + pRoot = 0; + } + *pp = pRoot; + return rc; +} + +/* +** This function is similar to sqlite3Fts3ExprParse(), with the following +** differences: +** +** 1. It does not do expression rebalancing. +** 2. It does not check that the expression does not exceed the +** maximum allowable depth. +** 3. Even if it fails, *ppExpr may still be set to point to an +** expression tree. It should be deleted using sqlite3Fts3ExprFree() +** in this case. +*/ +static int fts3ExprParseUnbalanced( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ + char **azCol, /* Array of column names for fts3 table */ + int bFts4, /* True to allow FTS4-only syntax */ + int nCol, /* Number of entries in azCol[] */ + int iDefaultCol, /* Default column to query */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr /* OUT: Parsed query structure */ +){ + int nParsed; + int rc; + ParseContext sParse; + + memset(&sParse, 0, sizeof(ParseContext)); + sParse.pTokenizer = pTokenizer; + sParse.iLangid = iLangid; + sParse.azCol = (const char **)azCol; + sParse.nCol = nCol; + sParse.iDefaultCol = iDefaultCol; + sParse.bFts4 = bFts4; + if( z==0 ){ + *ppExpr = 0; + return SQLITE_OK; + } + if( n<0 ){ + n = (int)strlen(z); + } + rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed); + assert( rc==SQLITE_OK || *ppExpr==0 ); + + /* Check for mismatched parenthesis */ + if( rc==SQLITE_OK && sParse.nNest ){ + rc = SQLITE_ERROR; + } + + return rc; +} + +/* +** Parameters z and n contain a pointer to and length of a buffer containing +** an fts3 query expression, respectively. This function attempts to parse the +** query expression and create a tree of Fts3Expr structures representing the +** parsed expression. If successful, *ppExpr is set to point to the head +** of the parsed expression tree and SQLITE_OK is returned. If an error +** occurs, either SQLITE_NOMEM (out-of-memory error) or SQLITE_ERROR (parse +** error) is returned and *ppExpr is set to 0. +** +** If parameter n is a negative number, then z is assumed to point to a +** nul-terminated string and the length is determined using strlen(). +** +** The first parameter, pTokenizer, is passed the fts3 tokenizer module to +** use to normalize query tokens while parsing the expression. The azCol[] +** array, which is assumed to contain nCol entries, should contain the names +** of each column in the target fts3 table, in order from left to right. +** Column names must be nul-terminated strings. +** +** The iDefaultCol parameter should be passed the index of the table column +** that appears on the left-hand-side of the MATCH operator (the default +** column to match against for tokens for which a column name is not explicitly +** specified as part of the query string), or -1 if tokens may by default +** match any table column. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprParse( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ + char **azCol, /* Array of column names for fts3 table */ + int bFts4, /* True to allow FTS4-only syntax */ + int nCol, /* Number of entries in azCol[] */ + int iDefaultCol, /* Default column to query */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr, /* OUT: Parsed query structure */ + char **pzErr /* OUT: Error message (sqlite3_malloc) */ +){ + int rc = fts3ExprParseUnbalanced( + pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr + ); + + /* Rebalance the expression. And check that its depth does not exceed + ** SQLITE_FTS3_MAX_EXPR_DEPTH. */ + if( rc==SQLITE_OK && *ppExpr ){ + rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); + if( rc==SQLITE_OK ){ + rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(*ppExpr); + *ppExpr = 0; + if( rc==SQLITE_TOOBIG ){ + sqlite3Fts3ErrMsg(pzErr, + "FTS expression tree is too large (maximum depth %d)", + SQLITE_FTS3_MAX_EXPR_DEPTH + ); + rc = SQLITE_ERROR; + }else if( rc==SQLITE_ERROR ){ + sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); + } + } + + return rc; +} + +/* +** Free a single node of an expression tree. +*/ +static void fts3FreeExprNode(Fts3Expr *p){ + assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 ); + sqlite3Fts3EvalPhraseCleanup(p->pPhrase); + sqlite3_free(p->aMI); + sqlite3_free(p); +} + +/* +** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse(). +** +** This function would be simpler if it recursively called itself. But +** that would mean passing a sufficiently large expression to ExprParse() +** could cause a stack overflow. +*/ +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){ + Fts3Expr *p; + assert( pDel==0 || pDel->pParent==0 ); + for(p=pDel; p && (p->pLeft||p->pRight); p=(p->pLeft ? p->pLeft : p->pRight)){ + assert( p->pParent==0 || p==p->pParent->pRight || p==p->pParent->pLeft ); + } + while( p ){ + Fts3Expr *pParent = p->pParent; + fts3FreeExprNode(p); + if( pParent && p==pParent->pLeft && pParent->pRight ){ + p = pParent->pRight; + while( p && (p->pLeft || p->pRight) ){ + assert( p==p->pParent->pRight || p==p->pParent->pLeft ); + p = (p->pLeft ? p->pLeft : p->pRight); + } + }else{ + p = pParent; + } + } +} + +/**************************************************************************** +***************************************************************************** +** Everything after this point is just test code. +*/ + +#ifdef SQLITE_TEST + +/* #include */ + +/* +** Return a pointer to a buffer containing a text representation of the +** expression passed as the first argument. The buffer is obtained from +** sqlite3_malloc(). It is the responsibility of the caller to use +** sqlite3_free() to release the memory. If an OOM condition is encountered, +** NULL is returned. +** +** If the second argument is not NULL, then its contents are prepended to +** the returned expression text and then freed using sqlite3_free(). +*/ +static char *exprToString(Fts3Expr *pExpr, char *zBuf){ + if( pExpr==0 ){ + return sqlite3_mprintf(""); + } + switch( pExpr->eType ){ + case FTSQUERY_PHRASE: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + zBuf = sqlite3_mprintf( + "%zPHRASE %d 0", zBuf, pPhrase->iColumn); + for(i=0; zBuf && inToken; i++){ + zBuf = sqlite3_mprintf("%z %.*s%s", zBuf, + pPhrase->aToken[i].n, pPhrase->aToken[i].z, + (pPhrase->aToken[i].isPrefix?"+":"") + ); + } + return zBuf; + } + + case FTSQUERY_NEAR: + zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); + break; + case FTSQUERY_NOT: + zBuf = sqlite3_mprintf("%zNOT ", zBuf); + break; + case FTSQUERY_AND: + zBuf = sqlite3_mprintf("%zAND ", zBuf); + break; + case FTSQUERY_OR: + zBuf = sqlite3_mprintf("%zOR ", zBuf); + break; + } + + if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf); + if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf); + + if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf); + + return zBuf; +} + +/* +** This is the implementation of a scalar SQL function used to test the +** expression parser. It should be called as follows: +** +** fts3_exprtest(, , , ...); +** +** The first argument, , is the name of the fts3 tokenizer used +** to parse the query expression (see README.tokenizers). The second argument +** is the query expression to parse. Each subsequent argument is the name +** of a column of the fts3 table that the query expression may refer to. +** For example: +** +** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); +*/ +static void fts3ExprTestCommon( + int bRebalance, + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_tokenizer *pTokenizer = 0; + int rc; + char **azCol = 0; + const char *zExpr; + int nExpr; + int nCol; + int ii; + Fts3Expr *pExpr; + char *zBuf = 0; + Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context); + const char *zTokenizer = 0; + char *zErr = 0; + + if( argc<3 ){ + sqlite3_result_error(context, + "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 + ); + return; + } + + zTokenizer = (const char*)sqlite3_value_text(argv[0]); + rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_error(context, zErr, -1); + } + sqlite3_free(zErr); + return; + } + + zExpr = (const char *)sqlite3_value_text(argv[1]); + nExpr = sqlite3_value_bytes(argv[1]); + nCol = argc-2; + azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *)); + if( !azCol ){ + sqlite3_result_error_nomem(context); + goto exprtest_out; + } + for(ii=0; iipModule->xDestroy(pTokenizer); + } + sqlite3_free(azCol); +} + +static void fts3ExprTest( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3ExprTestCommon(0, context, argc, argv); +} +static void fts3ExprTestRebalance( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3ExprTestCommon(1, context, argc, argv); +} + +/* +** Register the query expression parser test function fts3_exprtest() +** with database connection db. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){ + int rc = sqlite3_create_function( + db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0 + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", + -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0 + ); + } + return rc; +} + +#endif +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_expr.c *******************************************/ +/************** Begin file fts3_hash.c ***************************************/ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the implementation of generic hash-tables used in SQLite. +** We've modified it slightly to serve as a standalone hash table +** implementation for the full-text indexing module. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_hash.h" */ + +/* +** Malloc and Free functions +*/ +static void *fts3HashMalloc(sqlite3_int64 n){ + void *p = sqlite3_malloc64(n); + if( p ){ + memset(p, 0, n); + } + return p; +} +static void fts3HashFree(void *p){ + sqlite3_free(p); +} + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +** keyClass is one of the constants +** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass +** determines what kind of key the hash table will use. "copyKey" is +** true if the hash table should make its own private copy of keys and +** false if it should just use the supplied pointer. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){ + assert( pNew!=0 ); + assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY ); + pNew->keyClass = keyClass; + pNew->copyKey = copyKey; + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){ + Fts3HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + fts3HashFree(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + Fts3HashElem *next_elem = elem->next; + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_STRING +*/ +static int fts3StrHash(const void *pKey, int nKey){ + const char *z = (const char *)pKey; + unsigned h = 0; + if( nKey<=0 ) nKey = (int) strlen(z); + while( nKey > 0 ){ + h = (h<<3) ^ h ^ *z++; + nKey--; + } + return (int)(h & 0x7fffffff); +} +static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return strncmp((const char*)pKey1,(const char*)pKey2,n1); +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_BINARY +*/ +static int fts3BinHash(const void *pKey, int nKey){ + int h = 0; + const char *z = (const char *)pKey; + while( nKey-- > 0 ){ + h = (h<<3) ^ h ^ *(z++); + } + return h & 0x7fffffff; +} +static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return memcmp(pKey1,pKey2,n1); +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** The C syntax in this function definition may be unfamilar to some +** programmers, so we provide the following additional explanation: +** +** The name of the function is "ftsHashFunction". The function takes a +** single parameter "keyClass". The return value of ftsHashFunction() +** is a pointer to another function. Specifically, the return value +** of ftsHashFunction() is a pointer to a function that takes two parameters +** with types "const void*" and "int" and returns an "int". +*/ +static int (*ftsHashFunction(int keyClass))(const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrHash; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinHash; + } +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** For help in interpreted the obscure C code in the function definition, +** see the header comment on the previous function. +*/ +static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrCompare; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinCompare; + } +} + +/* Link an element into the hash table +*/ +static void fts3HashInsertElement( + Fts3Hash *pH, /* The complete hash table */ + struct _fts3ht *pEntry, /* The entry into which pNew is inserted */ + Fts3HashElem *pNew /* The element to be inserted */ +){ + Fts3HashElem *pHead; /* First element already in pEntry */ + pHead = pEntry->chain; + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } + pEntry->count++; + pEntry->chain = pNew; +} + + +/* Resize the hash table so that it cantains "new_size" buckets. +** "new_size" must be a power of 2. The hash table might fail +** to resize if sqliteMalloc() fails. +** +** Return non-zero if a memory allocation error occurs. +*/ +static int fts3Rehash(Fts3Hash *pH, int new_size){ + struct _fts3ht *new_ht; /* The new hash table */ + Fts3HashElem *elem, *next_elem; /* For looping over existing elements */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( (new_size & (new_size-1))==0 ); + new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) ); + if( new_ht==0 ) return 1; + fts3HashFree(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size; + xHash = ftsHashFunction(pH->keyClass); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); + next_elem = elem->next; + fts3HashInsertElement(pH, &new_ht[h], elem); + } + return 0; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. The hash for this key has +** already been computed and is passed as the 4th parameter. +*/ +static Fts3HashElem *fts3FindElementByHash( + const Fts3Hash *pH, /* The pH to be searched */ + const void *pKey, /* The key we are searching for */ + int nKey, + int h /* The hash for this key. */ +){ + Fts3HashElem *elem; /* Used to loop thru the element list */ + int count; /* Number of elements left to test */ + int (*xCompare)(const void*,int,const void*,int); /* comparison function */ + + if( pH->ht ){ + struct _fts3ht *pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + xCompare = ftsCompareFunction(pH->keyClass); + while( count-- && elem ){ + if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ + return elem; + } + elem = elem->next; + } + } + return 0; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void fts3RemoveElementByHash( + Fts3Hash *pH, /* The pH containing "elem" */ + Fts3HashElem* elem, /* The element to be removed from the pH */ + int h /* Hash value for the element */ +){ + struct _fts3ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + pEntry->count--; + if( pEntry->count<=0 ){ + pEntry->chain = 0; + } + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree( elem ); + pH->count--; + if( pH->count<=0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + fts3HashClear(pH); + } +} + +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( + const Fts3Hash *pH, + const void *pKey, + int nKey +){ + int h; /* A hash on key */ + int (*xHash)(const void*,int); /* The hash function */ + + if( pH==0 || pH->ht==0 ) return 0; + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + h = (*xHash)(pKey,nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1)); +} + +/* +** Attempt to locate an element of the hash table pH with a key +** that matches pKey,nKey. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){ + Fts3HashElem *pElem; /* The element that matches key (if any) */ + + pElem = sqlite3Fts3HashFindElem(pH, pKey, nKey); + return pElem ? pElem->data : 0; +} + +/* Insert an element into the hash table pH. The key is pKey,nKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created. A copy of the key is made if the copyKey +** flag is set. NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +SQLITE_PRIVATE void *sqlite3Fts3HashInsert( + Fts3Hash *pH, /* The hash table to insert into */ + const void *pKey, /* The key */ + int nKey, /* Number of bytes in the key */ + void *data /* The data */ +){ + int hraw; /* Raw hash value of the key */ + int h; /* the hash of the key modulo hash table size */ + Fts3HashElem *elem; /* Used to loop thru the element list */ + Fts3HashElem *new_elem; /* New element added to the pH */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( pH!=0 ); + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + hraw = (*xHash)(pKey, nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + elem = fts3FindElementByHash(pH,pKey,nKey,h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + fts3RemoveElementByHash(pH,elem,h); + }else{ + elem->data = data; + } + return old_data; + } + if( data==0 ) return 0; + if( (pH->htsize==0 && fts3Rehash(pH,8)) + || (pH->count>=pH->htsize && fts3Rehash(pH, pH->htsize*2)) + ){ + pH->count = 0; + return data; + } + assert( pH->htsize>0 ); + new_elem = (Fts3HashElem*)fts3HashMalloc( sizeof(Fts3HashElem) ); + if( new_elem==0 ) return data; + if( pH->copyKey && pKey!=0 ){ + new_elem->pKey = fts3HashMalloc( nKey ); + if( new_elem->pKey==0 ){ + fts3HashFree(new_elem); + return data; + } + memcpy((void*)new_elem->pKey, pKey, nKey); + }else{ + new_elem->pKey = (void*)pKey; + } + new_elem->nKey = nKey; + pH->count++; + assert( pH->htsize>0 ); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + fts3HashInsertElement(pH, &pH->ht[h], new_elem); + new_elem->data = data; + return 0; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_hash.c *******************************************/ +/************** Begin file fts3_porter.c *************************************/ +/* +** 2006 September 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Implementation of the full-text-search tokenizer that implements +** a Porter stemmer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_tokenizer.h" */ + +/* +** Class derived from sqlite3_tokenizer +*/ +typedef struct porter_tokenizer { + sqlite3_tokenizer base; /* Base class */ +} porter_tokenizer; + +/* +** Class derived from sqlite3_tokenizer_cursor +*/ +typedef struct porter_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *zInput; /* input we are tokenizing */ + int nInput; /* size of the input */ + int iOffset; /* current position in zInput */ + int iToken; /* index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAllocated; /* space allocated to zToken buffer */ +} porter_tokenizer_cursor; + + +/* +** Create a new tokenizer instance. +*/ +static int porterCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + porter_tokenizer *t; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int porterDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is zInput[0..nInput-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int porterOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, int nInput, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + porter_tokenizer_cursor *c; + + UNUSED_PARAMETER(pTokenizer); + + c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->zInput = zInput; + if( zInput==0 ){ + c->nInput = 0; + }else if( nInput<0 ){ + c->nInput = (int)strlen(zInput); + }else{ + c->nInput = nInput; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->zToken = NULL; /* no space allocated, yet. */ + c->nAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** porterOpen() above. +*/ +static int porterClose(sqlite3_tokenizer_cursor *pCursor){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + sqlite3_free(c->zToken); + sqlite3_free(c); + return SQLITE_OK; +} +/* +** Vowel or consonant +*/ +static const char cType[] = { + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 2, 1 +}; + +/* +** isConsonant() and isVowel() determine if their first character in +** the string they point to is a consonant or a vowel, according +** to Porter ruls. +** +** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. +** 'Y' is a consonant unless it follows another consonant, +** in which case it is a vowel. +** +** In these routine, the letters are in reverse order. So the 'y' rule +** is that 'y' is a consonant unless it is followed by another +** consonent. +*/ +static int isVowel(const char*); +static int isConsonant(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return j; + return z[1]==0 || isVowel(z + 1); +} +static int isVowel(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return 1-j; + return isConsonant(z + 1); +} + +/* +** Let any sequence of one or more vowels be represented by V and let +** C be sequence of one or more consonants. Then every word can be +** represented as: +** +** [C] (VC){m} [V] +** +** In prose: A word is an optional consonant followed by zero or +** vowel-consonant pairs followed by an optional vowel. "m" is the +** number of vowel consonant pairs. This routine computes the value +** of m for the first i bytes of a word. +** +** Return true if the m-value for z is 1 or more. In other words, +** return true if z contains at least one vowel that is followed +** by a consonant. +** +** In this routine z[] is in reverse order. So we are really looking +** for an instance of a consonant followed by a vowel. +*/ +static int m_gt_0(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* Like mgt0 above except we are looking for a value of m which is +** exactly 1 +*/ +static int m_eq_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 1; + while( isConsonant(z) ){ z++; } + return *z==0; +} + +/* Like mgt0 above except we are looking for a value of m>1 instead +** or m>0 +*/ +static int m_gt_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if there is a vowel anywhere within z[0..n-1] +*/ +static int hasVowel(const char *z){ + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if the word ends in a double consonant. +** +** The text is reversed here. So we are really looking at +** the first two characters of z[]. +*/ +static int doubleConsonant(const char *z){ + return isConsonant(z) && z[0]==z[1]; +} + +/* +** Return TRUE if the word ends with three letters which +** are consonant-vowel-consonent and where the final consonant +** is not 'w', 'x', or 'y'. +** +** The word is reversed here. So we are really checking the +** first three letters and the first one cannot be in [wxy]. +*/ +static int star_oh(const char *z){ + return + isConsonant(z) && + z[0]!='w' && z[0]!='x' && z[0]!='y' && + isVowel(z+1) && + isConsonant(z+2); +} + +/* +** If the word ends with zFrom and xCond() is true for the stem +** of the word that preceeds the zFrom ending, then change the +** ending to zTo. +** +** The input word *pz and zFrom are both in reverse order. zTo +** is in normal order. +** +** Return TRUE if zFrom matches. Return FALSE if zFrom does not +** match. Not that TRUE is returned even if xCond() fails and +** no substitution occurs. +*/ +static int stem( + char **pz, /* The word being stemmed (Reversed) */ + const char *zFrom, /* If the ending matches this... (Reversed) */ + const char *zTo, /* ... change the ending to this (not reversed) */ + int (*xCond)(const char*) /* Condition that must be true */ +){ + char *z = *pz; + while( *zFrom && *zFrom==*z ){ z++; zFrom++; } + if( *zFrom!=0 ) return 0; + if( xCond && !xCond(z) ) return 1; + while( *zTo ){ + *(--z) = *(zTo++); + } + *pz = z; + return 1; +} + +/* +** This is the fallback stemmer used when the porter stemmer is +** inappropriate. The input word is copied into the output with +** US-ASCII case folding. If the input word is too long (more +** than 20 bytes if it contains no digits or more than 6 bytes if +** it contains digits) then word is truncated to 20 or 6 bytes +** by taking 10 or 3 bytes from the beginning and end. +*/ +static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ + int i, mx, j; + int hasDigit = 0; + for(i=0; i='A' && c<='Z' ){ + zOut[i] = c - 'A' + 'a'; + }else{ + if( c>='0' && c<='9' ) hasDigit = 1; + zOut[i] = c; + } + } + mx = hasDigit ? 3 : 10; + if( nIn>mx*2 ){ + for(j=mx, i=nIn-mx; i=(int)sizeof(zReverse)-7 ){ + /* The word is too big or too small for the porter stemmer. + ** Fallback to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + for(i=0, j=sizeof(zReverse)-6; i='A' && c<='Z' ){ + zReverse[j] = c + 'a' - 'A'; + }else if( c>='a' && c<='z' ){ + zReverse[j] = c; + }else{ + /* The use of a character not in [a-zA-Z] means that we fallback + ** to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + } + memset(&zReverse[sizeof(zReverse)-5], 0, 5); + z = &zReverse[j+1]; + + + /* Step 1a */ + if( z[0]=='s' ){ + if( + !stem(&z, "sess", "ss", 0) && + !stem(&z, "sei", "i", 0) && + !stem(&z, "ss", "ss", 0) + ){ + z++; + } + } + + /* Step 1b */ + z2 = z; + if( stem(&z, "dee", "ee", m_gt_0) ){ + /* Do nothing. The work was all in the test */ + }else if( + (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel)) + && z!=z2 + ){ + if( stem(&z, "ta", "ate", 0) || + stem(&z, "lb", "ble", 0) || + stem(&z, "zi", "ize", 0) ){ + /* Do nothing. The work was all in the test */ + }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){ + z++; + }else if( m_eq_1(z) && star_oh(z) ){ + *(--z) = 'e'; + } + } + + /* Step 1c */ + if( z[0]=='y' && hasVowel(z+1) ){ + z[0] = 'i'; + } + + /* Step 2 */ + switch( z[1] ){ + case 'a': + if( !stem(&z, "lanoita", "ate", m_gt_0) ){ + stem(&z, "lanoit", "tion", m_gt_0); + } + break; + case 'c': + if( !stem(&z, "icne", "ence", m_gt_0) ){ + stem(&z, "icna", "ance", m_gt_0); + } + break; + case 'e': + stem(&z, "rezi", "ize", m_gt_0); + break; + case 'g': + stem(&z, "igol", "log", m_gt_0); + break; + case 'l': + if( !stem(&z, "ilb", "ble", m_gt_0) + && !stem(&z, "illa", "al", m_gt_0) + && !stem(&z, "iltne", "ent", m_gt_0) + && !stem(&z, "ile", "e", m_gt_0) + ){ + stem(&z, "ilsuo", "ous", m_gt_0); + } + break; + case 'o': + if( !stem(&z, "noitazi", "ize", m_gt_0) + && !stem(&z, "noita", "ate", m_gt_0) + ){ + stem(&z, "rota", "ate", m_gt_0); + } + break; + case 's': + if( !stem(&z, "msila", "al", m_gt_0) + && !stem(&z, "ssenevi", "ive", m_gt_0) + && !stem(&z, "ssenluf", "ful", m_gt_0) + ){ + stem(&z, "ssensuo", "ous", m_gt_0); + } + break; + case 't': + if( !stem(&z, "itila", "al", m_gt_0) + && !stem(&z, "itivi", "ive", m_gt_0) + ){ + stem(&z, "itilib", "ble", m_gt_0); + } + break; + } + + /* Step 3 */ + switch( z[0] ){ + case 'e': + if( !stem(&z, "etaci", "ic", m_gt_0) + && !stem(&z, "evita", "", m_gt_0) + ){ + stem(&z, "ezila", "al", m_gt_0); + } + break; + case 'i': + stem(&z, "itici", "ic", m_gt_0); + break; + case 'l': + if( !stem(&z, "laci", "ic", m_gt_0) ){ + stem(&z, "luf", "", m_gt_0); + } + break; + case 's': + stem(&z, "ssen", "", m_gt_0); + break; + } + + /* Step 4 */ + switch( z[1] ){ + case 'a': + if( z[0]=='l' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'c': + if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'e': + if( z[0]=='r' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'i': + if( z[0]=='c' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'l': + if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'n': + if( z[0]=='t' ){ + if( z[2]=='a' ){ + if( m_gt_1(z+3) ){ + z += 3; + } + }else if( z[2]=='e' ){ + if( !stem(&z, "tneme", "", m_gt_1) + && !stem(&z, "tnem", "", m_gt_1) + ){ + stem(&z, "tne", "", m_gt_1); + } + } + } + break; + case 'o': + if( z[0]=='u' ){ + if( m_gt_1(z+2) ){ + z += 2; + } + }else if( z[3]=='s' || z[3]=='t' ){ + stem(&z, "noi", "", m_gt_1); + } + break; + case 's': + if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 't': + if( !stem(&z, "eta", "", m_gt_1) ){ + stem(&z, "iti", "", m_gt_1); + } + break; + case 'u': + if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 'v': + case 'z': + if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + } + + /* Step 5a */ + if( z[0]=='e' ){ + if( m_gt_1(z+1) ){ + z++; + }else if( m_eq_1(z+1) && !star_oh(z+1) ){ + z++; + } + } + + /* Step 5b */ + if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){ + z++; + } + + /* z[] is now the stemmed word in reverse order. Flip it back + ** around into forward order and return. + */ + *pnOut = i = (int)strlen(z); + zOut[i] = 0; + while( *z ){ + zOut[--i] = *(z++); + } +} + +/* +** Characters that can be part of a token. We assume any character +** whose value is greater than 0x80 (any UTF character) can be +** part of a token. In other words, delimiters all must have +** values of 0x7f or lower. +*/ +static const char porterIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ +}; +#define isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30])) + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to porterOpen(). +*/ +static int porterNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ + const char **pzToken, /* OUT: *pzToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + const char *z = c->zInput; + + while( c->iOffsetnInput ){ + int iStartOffset, ch; + + /* Scan past delimiter characters */ + while( c->iOffsetnInput && isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffsetnInput && !isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int n = c->iOffset-iStartOffset; + if( n>c->nAllocated ){ + char *pNew; + c->nAllocated = n+20; + pNew = sqlite3_realloc64(c->zToken, c->nAllocated); + if( !pNew ) return SQLITE_NOMEM; + c->zToken = pNew; + } + porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); + *pzToken = c->zToken; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the porter-stemmer tokenizer +*/ +static const sqlite3_tokenizer_module porterTokenizerModule = { + 0, + porterCreate, + porterDestroy, + porterOpen, + porterClose, + porterNext, + 0 +}; + +/* +** Allocate a new porter tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &porterTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_porter.c *****************************************/ +/************** Begin file fts3_tokenizer.c **********************************/ +/* +** 2007 June 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This is part of an SQLite module implementing full-text search. +** This particular file implements the generic tokenizer interface. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +/* +** Return true if the two-argument version of fts3_tokenizer() +** has been activated via a prior call to sqlite3_db_config(db, +** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); +*/ +static int fts3TokenizerEnabled(sqlite3_context *context){ + sqlite3 *db = sqlite3_context_db_handle(context); + int isEnabled = 0; + sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled); + return isEnabled; +} + +/* +** Implementation of the SQL scalar function for accessing the underlying +** hash table. This function may be called as follows: +** +** SELECT (); +** SELECT (, ); +** +** where is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). +** +** If the argument is specified, it must be a blob value +** containing a pointer to be stored as the hash data corresponding +** to the string . If is not specified, then +** the string must already exist in the has table. Otherwise, +** an error is returned. +** +** Whether or not the argument is specified, the value returned +** is a blob containing the pointer stored as the hash data corresponding +** to string (after the hash-table is updated, if applicable). +*/ +static void fts3TokenizerFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Fts3Hash *pHash; + void *pPtr = 0; + const unsigned char *zName; + int nName; + + assert( argc==1 || argc==2 ); + + pHash = (Fts3Hash *)sqlite3_user_data(context); + + zName = sqlite3_value_text(argv[0]); + nName = sqlite3_value_bytes(argv[0])+1; + + if( argc==2 ){ + if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){ + void *pOld; + int n = sqlite3_value_bytes(argv[1]); + if( zName==0 || n!=sizeof(pPtr) ){ + sqlite3_result_error(context, "argument type mismatch", -1); + return; + } + pPtr = *(void **)sqlite3_value_blob(argv[1]); + pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); + if( pOld==pPtr ){ + sqlite3_result_error(context, "out of memory", -1); + } + }else{ + sqlite3_result_error(context, "fts3tokenize disabled", -1); + return; + } + }else{ + if( zName ){ + pPtr = sqlite3Fts3HashFind(pHash, zName, nName); + } + if( !pPtr ){ + char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + } + if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){ + sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); + } +} + +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){ + static const char isFtsIdChar[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ + }; + return (c&0x80 || isFtsIdChar[(int)(c)]); +} + +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ + const char *z1; + const char *z2 = 0; + + /* Find the start of the next token. */ + z1 = zStr; + while( z2==0 ){ + char c = *z1; + switch( c ){ + case '\0': return 0; /* No more tokens here */ + case '\'': + case '"': + case '`': { + z2 = z1; + while( *++z2 && (*z2!=c || *++z2==c) ); + break; + } + case '[': + z2 = &z1[1]; + while( *z2 && z2[0]!=']' ) z2++; + if( *z2 ) z2++; + break; + + default: + if( sqlite3Fts3IsIdChar(*z1) ){ + z2 = &z1[1]; + while( sqlite3Fts3IsIdChar(*z2) ) z2++; + }else{ + z1++; + } + } + } + + *pn = (int)(z2-z1); + return z1; +} + +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( + Fts3Hash *pHash, /* Tokenizer hash table */ + const char *zArg, /* Tokenizer name */ + sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ + char **pzErr /* OUT: Set to malloced error message */ +){ + int rc; + char *z = (char *)zArg; + int n = 0; + char *zCopy; + char *zEnd; /* Pointer to nul-term of zCopy */ + sqlite3_tokenizer_module *m; + + zCopy = sqlite3_mprintf("%s", zArg); + if( !zCopy ) return SQLITE_NOMEM; + zEnd = &zCopy[strlen(zCopy)]; + + z = (char *)sqlite3Fts3NextToken(zCopy, &n); + if( z==0 ){ + assert( n==0 ); + z = zCopy; + } + z[n] = '\0'; + sqlite3Fts3Dequote(z); + + m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); + if( !m ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); + rc = SQLITE_ERROR; + }else{ + char const **aArg = 0; + int iArg = 0; + z = &z[n+1]; + while( zxCreate(iArg, aArg, ppTok); + assert( rc!=SQLITE_OK || *ppTok ); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); + }else{ + (*ppTok)->pModule = m; + } + sqlite3_free((void *)aArg); + } + + sqlite3_free(zCopy); + return rc; +} + + +#ifdef SQLITE_TEST + +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif +/* #include */ + +/* +** Implementation of a special SQL scalar function for testing tokenizers +** designed to be used in concert with the Tcl testing framework. This +** function must be called with two or more arguments: +** +** SELECT (, ..., ); +** +** where is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') +** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). +** +** The return value is a string that may be interpreted as a Tcl +** list. For each token in the , three elements are +** added to the returned list. The first is the token position, the +** second is the token text (folded, stemmed, etc.) and the third is the +** substring of associated with the token. For example, +** using the built-in "simple" tokenizer: +** +** SELECT fts_tokenizer_test('simple', 'I don't see how'); +** +** will return the string: +** +** "{0 i I 1 dont don't 2 see see 3 how how}" +** +*/ +static void testFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Fts3Hash *pHash; + sqlite3_tokenizer_module *p; + sqlite3_tokenizer *pTokenizer = 0; + sqlite3_tokenizer_cursor *pCsr = 0; + + const char *zErr = 0; + + const char *zName; + int nName; + const char *zInput; + int nInput; + + const char *azArg[64]; + + const char *zToken; + int nToken = 0; + int iStart = 0; + int iEnd = 0; + int iPos = 0; + int i; + + Tcl_Obj *pRet; + + if( argc<2 ){ + sqlite3_result_error(context, "insufficient arguments", -1); + return; + } + + nName = sqlite3_value_bytes(argv[0]); + zName = (const char *)sqlite3_value_text(argv[0]); + nInput = sqlite3_value_bytes(argv[argc-1]); + zInput = (const char *)sqlite3_value_text(argv[argc-1]); + + pHash = (Fts3Hash *)sqlite3_user_data(context); + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + + if( !p ){ + char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr2, -1); + sqlite3_free(zErr2); + return; + } + + pRet = Tcl_NewObj(); + Tcl_IncrRefCount(pRet); + + for(i=1; ixCreate(argc-2, azArg, &pTokenizer) ){ + zErr = "error in xCreate()"; + goto finish; + } + pTokenizer->pModule = p; + if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ + zErr = "error in xOpen()"; + goto finish; + } + + while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){ + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + zToken = &zInput[iStart]; + nToken = iEnd-iStart; + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + } + + if( SQLITE_OK!=p->xClose(pCsr) ){ + zErr = "error in xClose()"; + goto finish; + } + if( SQLITE_OK!=p->xDestroy(pTokenizer) ){ + zErr = "error in xDestroy()"; + goto finish; + } + +finish: + if( zErr ){ + sqlite3_result_error(context, zErr, -1); + }else{ + sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); + } + Tcl_DecrRefCount(pRet); +} + +static +int registerTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module *p +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?, ?)"; + + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); + sqlite3_step(pStmt); + + return sqlite3_finalize(pStmt); +} + + +static +int queryTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module **pp +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?)"; + + *pp = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB + && sqlite3_column_bytes(pStmt, 0)==sizeof(*pp) + ){ + memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); + } + } + + return sqlite3_finalize(pStmt); +} + +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); + +/* +** Implementation of the scalar function fts3_tokenizer_internal_test(). +** This function is used for testing only, it is not included in the +** build unless SQLITE_TEST is defined. +** +** The purpose of this is to test that the fts3_tokenizer() function +** can be used as designed by the C-code in the queryTokenizer and +** registerTokenizer() functions above. These two functions are repeated +** in the README.tokenizer file as an example, so it is important to +** test them. +** +** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar +** function with no arguments. An assert() will fail if a problem is +** detected. i.e.: +** +** SELECT fts3_tokenizer_internal_test(); +** +*/ +static void intTestFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int rc; + const sqlite3_tokenizer_module *p1; + const sqlite3_tokenizer_module *p2; + sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + /* Test the query function */ + sqlite3Fts3SimpleTokenizerModule(&p1); + rc = queryTokenizer(db, "simple", &p2); + assert( rc==SQLITE_OK ); + assert( p1==p2 ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_ERROR ); + assert( p2==0 ); + assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); + + /* Test the storage function */ + if( fts3TokenizerEnabled(context) ){ + rc = registerTokenizer(db, "nosuchtokenizer", p1); + assert( rc==SQLITE_OK ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_OK ); + assert( p2==p1 ); + } + + sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); +} + +#endif + +/* +** Set up SQL objects in database db used to access the contents of +** the hash table pointed to by argument pHash. The hash table must +** been initialized to use string keys, and to take a private copy +** of the key when a value is inserted. i.e. by a call similar to: +** +** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); +** +** This function adds a scalar function (see header comment above +** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is +** defined at compilation time, a temporary virtual table (see header +** comment above struct HashTableVtab) to the database schema. Both +** provide read/write access to the contents of *pHash. +** +** The third argument to this function, zName, is used as the name +** of both the scalar and, if created, the virtual table. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitHashTable( + sqlite3 *db, + Fts3Hash *pHash, + const char *zName +){ + int rc = SQLITE_OK; + void *p = (void *)pHash; + const int any = SQLITE_UTF8|SQLITE_DIRECTONLY; + +#ifdef SQLITE_TEST + char *zTest = 0; + char *zTest2 = 0; + void *pdb = (void *)db; + zTest = sqlite3_mprintf("%s_test", zName); + zTest2 = sqlite3_mprintf("%s_internal_test", zName); + if( !zTest || !zTest2 ){ + rc = SQLITE_NOMEM; + } +#endif + + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0); + } +#ifdef SQLITE_TEST + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); + } +#endif + +#ifdef SQLITE_TEST + sqlite3_free(zTest); + sqlite3_free(zTest2); +#endif + + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer.c **************************************/ +/************** Begin file fts3_tokenizer1.c *********************************/ +/* +** 2006 Oct 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Implementation of the "simple" full-text-search tokenizer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_tokenizer.h" */ + +typedef struct simple_tokenizer { + sqlite3_tokenizer base; + char delim[128]; /* flag ASCII delimiters */ +} simple_tokenizer; + +typedef struct simple_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *pInput; /* input we are tokenizing */ + int nBytes; /* size of the input */ + int iOffset; /* current position in pInput */ + int iToken; /* index of next token to be returned */ + char *pToken; /* storage for current token */ + int nTokenAllocated; /* space allocated to zToken buffer */ +} simple_tokenizer_cursor; + + +static int simpleDelim(simple_tokenizer *t, unsigned char c){ + return c<0x80 && t->delim[c]; +} +static int fts3_isalnum(int x){ + return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z'); +} + +/* +** Create a new tokenizer instance. +*/ +static int simpleCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + simple_tokenizer *t; + + t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + + /* TODO(shess) Delimiters need to remain the same from run to run, + ** else we need to reindex. One solution would be a meta-table to + ** track such information in the database, then we'd only want this + ** information on the initial create. + */ + if( argc>1 ){ + int i, n = (int)strlen(argv[1]); + for(i=0; i=0x80 ){ + sqlite3_free(t); + return SQLITE_ERROR; + } + t->delim[ch] = 1; + } + } else { + /* Mark non-alphanumeric ASCII characters as delimiters */ + int i; + for(i=1; i<0x80; i++){ + t->delim[i] = !fts3_isalnum(i) ? -1 : 0; + } + } + + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int simpleOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *pInput, int nBytes, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + simple_tokenizer_cursor *c; + + UNUSED_PARAMETER(pTokenizer); + + c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->pInput = pInput; + if( pInput==0 ){ + c->nBytes = 0; + }else if( nBytes<0 ){ + c->nBytes = (int)strlen(pInput); + }else{ + c->nBytes = nBytes; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->pToken = NULL; /* no space allocated, yet. */ + c->nTokenAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int simpleClose(sqlite3_tokenizer_cursor *pCursor){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + sqlite3_free(c->pToken); + sqlite3_free(c); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int simpleNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer; + unsigned char *p = (unsigned char *)c->pInput; + + while( c->iOffsetnBytes ){ + int iStartOffset; + + /* Scan past delimiter characters */ + while( c->iOffsetnBytes && simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffsetnBytes && !simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int i, n = c->iOffset-iStartOffset; + if( n>c->nTokenAllocated ){ + char *pNew; + c->nTokenAllocated = n+20; + pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated); + if( !pNew ) return SQLITE_NOMEM; + c->pToken = pNew; + } + for(i=0; ipToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch); + } + *ppToken = c->pToken; + *pnBytes = n; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module simpleTokenizerModule = { + 0, + simpleCreate, + simpleDestroy, + simpleOpen, + simpleClose, + simpleNext, + 0, +}; + +/* +** Allocate a new simple tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &simpleTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer1.c *************************************/ +/************** Begin file fts3_tokenize_vtab.c ******************************/ +/* +** 2013 Apr 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code for the "fts3tokenize" virtual table module. +** An fts3tokenize virtual table is created as follows: +** +** CREATE VIRTUAL TABLE USING fts3tokenize( +** , , ... +** ); +** +** The table created has the following schema: +** +** CREATE TABLE (input, token, start, end, position) +** +** When queried, the query must include a WHERE clause of type: +** +** input = +** +** The virtual table module tokenizes this , using the FTS3 +** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE +** statement and returns one row for each token in the result. With +** fields set as follows: +** +** input: Always set to a copy of +** token: A token from the input. +** start: Byte offset of the token within the input . +** end: Byte offset of the byte immediately following the end of the +** token within the input string. +** pos: Token offset of token within input. +** +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +typedef struct Fts3tokTable Fts3tokTable; +typedef struct Fts3tokCursor Fts3tokCursor; + +/* +** Virtual table structure. +*/ +struct Fts3tokTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + const sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer *pTok; +}; + +/* +** Virtual table cursor structure. +*/ +struct Fts3tokCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + char *zInput; /* Input string */ + sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ + int iRowid; /* Current 'rowid' value */ + const char *zToken; /* Current 'token' value */ + int nToken; /* Size of zToken in bytes */ + int iStart; /* Current 'start' value */ + int iEnd; /* Current 'end' value */ + int iPos; /* Current 'pos' value */ +}; + +/* +** Query FTS for the tokenizer implementation named zName. +*/ +static int fts3tokQueryTokenizer( + Fts3Hash *pHash, + const char *zName, + const sqlite3_tokenizer_module **pp, + char **pzErr +){ + sqlite3_tokenizer_module *p; + int nName = (int)strlen(zName); + + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + if( !p ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); + return SQLITE_ERROR; + } + + *pp = p; + return SQLITE_OK; +} + +/* +** The second argument, argv[], is an array of pointers to nul-terminated +** strings. This function makes a copy of the array and strings into a +** single block of memory. It then dequotes any of the strings that appear +** to be quoted. +** +** If successful, output parameter *pazDequote is set to point at the +** array of dequoted strings and SQLITE_OK is returned. The caller is +** responsible for eventually calling sqlite3_free() to free the array +** in this case. Or, if an error occurs, an SQLite error code is returned. +** The final value of *pazDequote is undefined in this case. +*/ +static int fts3tokDequoteArray( + int argc, /* Number of elements in argv[] */ + const char * const *argv, /* Input array */ + char ***pazDequote /* Output array */ +){ + int rc = SQLITE_OK; /* Return code */ + if( argc==0 ){ + *pazDequote = 0; + }else{ + int i; + int nByte = 0; + char **azDequote; + + for(i=0; i1 ) azArg = (const char * const *)&azDequote[1]; + rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok); + } + + if( rc==SQLITE_OK ){ + pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + memset(pTab, 0, sizeof(Fts3tokTable)); + pTab->pMod = pMod; + pTab->pTok = pTok; + *ppVtab = &pTab->base; + }else{ + if( pTok ){ + pMod->xDestroy(pTok); + } + } + + sqlite3_free(azDequote); + return rc; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3tokTable *pTab = (Fts3tokTable *)pVtab; + + pTab->pMod->xDestroy(pTab->pTok); + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3tokBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + UNUSED_PARAMETER(pVTab); + + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable + && pInfo->aConstraint[i].iColumn==0 + && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + pInfo->idxNum = 1; + pInfo->aConstraintUsage[i].argvIndex = 1; + pInfo->aConstraintUsage[i].omit = 1; + pInfo->estimatedCost = 1; + return SQLITE_OK; + } + } + + pInfo->idxNum = 0; + assert( pInfo->estimatedCost>1000000.0 ); + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3tokCursor *pCsr; + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts3tokCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Reset the tokenizer cursor passed as the only argument. As if it had +** just been returned by fts3tokOpenMethod(). +*/ +static void fts3tokResetCursor(Fts3tokCursor *pCsr){ + if( pCsr->pCsr ){ + Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab); + pTab->pMod->xClose(pCsr->pCsr); + pCsr->pCsr = 0; + } + sqlite3_free(pCsr->zInput); + pCsr->zInput = 0; + pCsr->zToken = 0; + pCsr->nToken = 0; + pCsr->iStart = 0; + pCsr->iEnd = 0; + pCsr->iPos = 0; + pCsr->iRowid = 0; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + + fts3tokResetCursor(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); + int rc; /* Return code */ + + pCsr->iRowid++; + rc = pTab->pMod->xNext(pCsr->pCsr, + &pCsr->zToken, &pCsr->nToken, + &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos + ); + + if( rc!=SQLITE_OK ){ + fts3tokResetCursor(pCsr); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3tokFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_ERROR; + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(nVal); + + fts3tokResetCursor(pCsr); + if( idxNum==1 ){ + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); + int nByte = sqlite3_value_bytes(apVal[0]); + pCsr->zInput = sqlite3_malloc64(nByte+1); + if( pCsr->zInput==0 ){ + rc = SQLITE_NOMEM; + }else{ + if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte); + pCsr->zInput[nByte] = 0; + rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); + if( rc==SQLITE_OK ){ + pCsr->pCsr->pTokenizer = pTab->pTok; + } + } + } + + if( rc!=SQLITE_OK ) return rc; + return fts3tokNextMethod(pCursor); +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + return (pCsr->zToken==0); +} + +/* +** xColumn - Return a column value. +*/ +static int fts3tokColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + + /* CREATE TABLE x(input, token, start, end, position) */ + switch( iCol ){ + case 0: + sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); + break; + case 1: + sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); + break; + case 2: + sqlite3_result_int(pCtx, pCsr->iStart); + break; + case 3: + sqlite3_result_int(pCtx, pCsr->iEnd); + break; + default: + assert( iCol==4 ); + sqlite3_result_int(pCtx, pCsr->iPos); + break; + } + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3tokRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + *pRowid = (sqlite3_int64)pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3tok module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){ + static const sqlite3_module fts3tok_module = { + 0, /* iVersion */ + fts3tokConnectMethod, /* xCreate */ + fts3tokConnectMethod, /* xConnect */ + fts3tokBestIndexMethod, /* xBestIndex */ + fts3tokDisconnectMethod, /* xDisconnect */ + fts3tokDisconnectMethod, /* xDestroy */ + fts3tokOpenMethod, /* xOpen */ + fts3tokCloseMethod, /* xClose */ + fts3tokFilterMethod, /* xFilter */ + fts3tokNextMethod, /* xNext */ + fts3tokEofMethod, /* xEof */ + fts3tokColumnMethod, /* xColumn */ + fts3tokRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module_v2( + db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy + ); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenize_vtab.c **********************************/ +/************** Begin file fts3_write.c **************************************/ +/* +** 2009 Oct 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file is part of the SQLite FTS3 extension module. Specifically, +** this file contains code to insert, update and delete rows from FTS3 +** tables. It also contains code to merge FTS3 b-tree segments. Some +** of the sub-routines used to merge segments are also used by the query +** code in fts3.c. +*/ + +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +#define FTS_MAX_APPENDABLE_HEIGHT 16 + +/* +** When full-text index nodes are loaded from disk, the buffer that they +** are loaded into has the following number of bytes of padding at the end +** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer +** of 920 bytes is allocated for it. +** +** This means that if we have a pointer into a buffer containing node data, +** it is always safe to read up to two varints from it without risking an +** overread, even if the node data is corrupted. +*/ +#define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2) + +/* +** Under certain circumstances, b-tree nodes (doclists) can be loaded into +** memory incrementally instead of all at once. This can be a big performance +** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext() +** method before retrieving all query results (as may happen, for example, +** if a query has a LIMIT clause). +** +** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD +** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes. +** The code is written so that the hard lower-limit for each of these values +** is 1. Clearly such small values would be inefficient, but can be useful +** for testing purposes. +** +** If this module is built with SQLITE_TEST defined, these constants may +** be overridden at runtime for testing purposes. File fts3_test.c contains +** a Tcl interface to read and write the values. +*/ +#ifdef SQLITE_TEST +int test_fts3_node_chunksize = (4*1024); +int test_fts3_node_chunk_threshold = (4*1024)*4; +# define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize +# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold +#else +# define FTS3_NODE_CHUNKSIZE (4*1024) +# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) +#endif + +/* +** The values that may be meaningfully bound to the :1 parameter in +** statements SQL_REPLACE_STAT and SQL_SELECT_STAT. +*/ +#define FTS_STAT_DOCTOTAL 0 +#define FTS_STAT_INCRMERGEHINT 1 +#define FTS_STAT_AUTOINCRMERGE 2 + +/* +** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic +** and incremental merge operation that takes place. This is used for +** debugging FTS only, it should not usually be turned on in production +** systems. +*/ +#ifdef FTS3_LOG_MERGES +static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){ + sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); +} +#else +#define fts3LogMerge(x, y) +#endif + + +typedef struct PendingList PendingList; +typedef struct SegmentNode SegmentNode; +typedef struct SegmentWriter SegmentWriter; + +/* +** An instance of the following data structure is used to build doclists +** incrementally. See function fts3PendingListAppend() for details. +*/ +struct PendingList { + int nData; + char *aData; + int nSpace; + sqlite3_int64 iLastDocid; + sqlite3_int64 iLastCol; + sqlite3_int64 iLastPos; +}; + + +/* +** Each cursor has a (possibly empty) linked list of the following objects. +*/ +struct Fts3DeferredToken { + Fts3PhraseToken *pToken; /* Pointer to corresponding expr token */ + int iCol; /* Column token must occur in */ + Fts3DeferredToken *pNext; /* Next in list of deferred tokens */ + PendingList *pList; /* Doclist is assembled here */ +}; + +/* +** An instance of this structure is used to iterate through the terms on +** a contiguous set of segment b-tree leaf nodes. Although the details of +** this structure are only manipulated by code in this file, opaque handles +** of type Fts3SegReader* are also used by code in fts3.c to iterate through +** terms when querying the full-text index. See functions: +** +** sqlite3Fts3SegReaderNew() +** sqlite3Fts3SegReaderFree() +** sqlite3Fts3SegReaderIterate() +** +** Methods used to manipulate Fts3SegReader structures: +** +** fts3SegReaderNext() +** fts3SegReaderFirstDocid() +** fts3SegReaderNextDocid() +*/ +struct Fts3SegReader { + int iIdx; /* Index within level, or 0x7FFFFFFF for PT */ + u8 bLookup; /* True for a lookup only */ + u8 rootOnly; /* True for a root-only reader */ + + sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ + sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ + sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ + sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ + + char *aNode; /* Pointer to node data (or NULL) */ + int nNode; /* Size of buffer at aNode (or 0) */ + int nPopulate; /* If >0, bytes of buffer aNode[] loaded */ + sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ + + Fts3HashElem **ppNextElem; + + /* Variables set by fts3SegReaderNext(). These may be read directly + ** by the caller. They are valid from the time SegmentReaderNew() returns + ** until SegmentReaderNext() returns something other than SQLITE_OK + ** (i.e. SQLITE_DONE). + */ + int nTerm; /* Number of bytes in current term */ + char *zTerm; /* Pointer to current term */ + int nTermAlloc; /* Allocated size of zTerm buffer */ + char *aDoclist; /* Pointer to doclist of current entry */ + int nDoclist; /* Size of doclist in current entry */ + + /* The following variables are used by fts3SegReaderNextDocid() to iterate + ** through the current doclist (aDoclist/nDoclist). + */ + char *pOffsetList; + int nOffsetList; /* For descending pending seg-readers only */ + sqlite3_int64 iDocid; +}; + +#define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) +#define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0) + +/* +** An instance of this structure is used to create a segment b-tree in the +** database. The internal details of this type are only accessed by the +** following functions: +** +** fts3SegWriterAdd() +** fts3SegWriterFlush() +** fts3SegWriterFree() +*/ +struct SegmentWriter { + SegmentNode *pTree; /* Pointer to interior tree structure */ + sqlite3_int64 iFirst; /* First slot in %_segments written */ + sqlite3_int64 iFree; /* Next free slot in %_segments */ + char *zTerm; /* Pointer to previous term buffer */ + int nTerm; /* Number of bytes in zTerm */ + int nMalloc; /* Size of malloc'd buffer at zMalloc */ + char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ + int nSize; /* Size of allocation at aData */ + int nData; /* Bytes of data in aData */ + char *aData; /* Pointer to block from malloc() */ + i64 nLeafData; /* Number of bytes of leaf data written */ +}; + +/* +** Type SegmentNode is used by the following three functions to create +** the interior part of the segment b+-tree structures (everything except +** the leaf nodes). These functions and type are only ever used by code +** within the fts3SegWriterXXX() family of functions described above. +** +** fts3NodeAddTerm() +** fts3NodeWrite() +** fts3NodeFree() +** +** When a b+tree is written to the database (either as a result of a merge +** or the pending-terms table being flushed), leaves are written into the +** database file as soon as they are completely populated. The interior of +** the tree is assembled in memory and written out only once all leaves have +** been populated and stored. This is Ok, as the b+-tree fanout is usually +** very large, meaning that the interior of the tree consumes relatively +** little memory. +*/ +struct SegmentNode { + SegmentNode *pParent; /* Parent node (or NULL for root node) */ + SegmentNode *pRight; /* Pointer to right-sibling */ + SegmentNode *pLeftmost; /* Pointer to left-most node of this depth */ + int nEntry; /* Number of terms written to node so far */ + char *zTerm; /* Pointer to previous term buffer */ + int nTerm; /* Number of bytes in zTerm */ + int nMalloc; /* Size of malloc'd buffer at zMalloc */ + char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ + int nData; /* Bytes of valid data so far */ + char *aData; /* Node data */ +}; + +/* +** Valid values for the second argument to fts3SqlStmt(). +*/ +#define SQL_DELETE_CONTENT 0 +#define SQL_IS_EMPTY 1 +#define SQL_DELETE_ALL_CONTENT 2 +#define SQL_DELETE_ALL_SEGMENTS 3 +#define SQL_DELETE_ALL_SEGDIR 4 +#define SQL_DELETE_ALL_DOCSIZE 5 +#define SQL_DELETE_ALL_STAT 6 +#define SQL_SELECT_CONTENT_BY_ROWID 7 +#define SQL_NEXT_SEGMENT_INDEX 8 +#define SQL_INSERT_SEGMENTS 9 +#define SQL_NEXT_SEGMENTS_ID 10 +#define SQL_INSERT_SEGDIR 11 +#define SQL_SELECT_LEVEL 12 +#define SQL_SELECT_LEVEL_RANGE 13 +#define SQL_SELECT_LEVEL_COUNT 14 +#define SQL_SELECT_SEGDIR_MAX_LEVEL 15 +#define SQL_DELETE_SEGDIR_LEVEL 16 +#define SQL_DELETE_SEGMENTS_RANGE 17 +#define SQL_CONTENT_INSERT 18 +#define SQL_DELETE_DOCSIZE 19 +#define SQL_REPLACE_DOCSIZE 20 +#define SQL_SELECT_DOCSIZE 21 +#define SQL_SELECT_STAT 22 +#define SQL_REPLACE_STAT 23 + +#define SQL_SELECT_ALL_PREFIX_LEVEL 24 +#define SQL_DELETE_ALL_TERMS_SEGDIR 25 +#define SQL_DELETE_SEGDIR_RANGE 26 +#define SQL_SELECT_ALL_LANGID 27 +#define SQL_FIND_MERGE_LEVEL 28 +#define SQL_MAX_LEAF_NODE_ESTIMATE 29 +#define SQL_DELETE_SEGDIR_ENTRY 30 +#define SQL_SHIFT_SEGDIR_ENTRY 31 +#define SQL_SELECT_SEGDIR 32 +#define SQL_CHOMP_SEGDIR 33 +#define SQL_SEGMENT_IS_APPENDABLE 34 +#define SQL_SELECT_INDEXES 35 +#define SQL_SELECT_MXLEVEL 36 + +#define SQL_SELECT_LEVEL_RANGE2 37 +#define SQL_UPDATE_LEVEL_IDX 38 +#define SQL_UPDATE_LEVEL 39 + +/* +** This function is used to obtain an SQLite prepared statement handle +** for the statement identified by the second argument. If successful, +** *pp is set to the requested statement handle and SQLITE_OK returned. +** Otherwise, an SQLite error code is returned and *pp is set to 0. +** +** If argument apVal is not NULL, then it must point to an array with +** at least as many entries as the requested statement has bound +** parameters. The values are bound to the statements parameters before +** returning. +*/ +static int fts3SqlStmt( + Fts3Table *p, /* Virtual table handle */ + int eStmt, /* One of the SQL_XXX constants above */ + sqlite3_stmt **pp, /* OUT: Statement handle */ + sqlite3_value **apVal /* Values to bind to statement */ +){ + const char *azSql[] = { +/* 0 */ "DELETE FROM %Q.'%q_content' WHERE rowid = ?", +/* 1 */ "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)", +/* 2 */ "DELETE FROM %Q.'%q_content'", +/* 3 */ "DELETE FROM %Q.'%q_segments'", +/* 4 */ "DELETE FROM %Q.'%q_segdir'", +/* 5 */ "DELETE FROM %Q.'%q_docsize'", +/* 6 */ "DELETE FROM %Q.'%q_stat'", +/* 7 */ "SELECT %s WHERE rowid=?", +/* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", +/* 9 */ "REPLACE INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)", +/* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)", +/* 11 */ "REPLACE INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)", + + /* Return segments in order from oldest to newest.*/ +/* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC", +/* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?" + "ORDER BY level DESC, idx ASC", + +/* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?", +/* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", + +/* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?", +/* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?", +/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", +/* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", +/* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", +/* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", +/* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", +/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", +/* 24 */ "", +/* 25 */ "", + +/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", +/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", + +/* This statement is used to determine which level to read the input from +** when performing an incremental merge. It returns the absolute level number +** of the oldest level in the db that contains at least ? segments. Or, +** if no level in the FTS index contains more than ? segments, the statement +** returns zero rows. */ +/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " + " GROUP BY level HAVING cnt>=?" + " ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1", + +/* Estimate the upper limit on the number of leaf nodes in a new segment +** created by merging the oldest :2 segments from absolute level :1. See +** function sqlite3Fts3Incrmerge() for details. */ +/* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " + " FROM (SELECT * FROM %Q.'%q_segdir' " + " WHERE level = ? ORDER BY idx ASC LIMIT ?" + " )", + +/* SQL_DELETE_SEGDIR_ENTRY +** Delete the %_segdir entry on absolute level :1 with index :2. */ +/* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", + +/* SQL_SHIFT_SEGDIR_ENTRY +** Modify the idx value for the segment with idx=:3 on absolute level :2 +** to :1. */ +/* 31 */ "UPDATE %Q.'%q_segdir' SET idx = ? WHERE level=? AND idx=?", + +/* SQL_SELECT_SEGDIR +** Read a single entry from the %_segdir table. The entry from absolute +** level :1 with index value :2. */ +/* 32 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", + +/* SQL_CHOMP_SEGDIR +** Update the start_block (:1) and root (:2) fields of the %_segdir +** entry located on absolute level :3 with index :4. */ +/* 33 */ "UPDATE %Q.'%q_segdir' SET start_block = ?, root = ?" + "WHERE level = ? AND idx = ?", + +/* SQL_SEGMENT_IS_APPENDABLE +** Return a single row if the segment with end_block=? is appendable. Or +** no rows otherwise. */ +/* 34 */ "SELECT 1 FROM %Q.'%q_segments' WHERE blockid=? AND block IS NULL", + +/* SQL_SELECT_INDEXES +** Return the list of valid segment indexes for absolute level ? */ +/* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", + +/* SQL_SELECT_MXLEVEL +** Return the largest relative level in the FTS index or indexes. */ +/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'", + + /* Return segments in order from oldest to newest.*/ +/* 37 */ "SELECT level, idx, end_block " + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? " + "ORDER BY level DESC, idx ASC", + + /* Update statements used while promoting segments */ +/* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? " + "WHERE level=? AND idx=?", +/* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1" + + }; + int rc = SQLITE_OK; + sqlite3_stmt *pStmt; + + assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); + assert( eStmt=0 ); + + pStmt = p->aStmt[eStmt]; + if( !pStmt ){ + int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB; + char *zSql; + if( eStmt==SQL_CONTENT_INSERT ){ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); + }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ + f &= ~SQLITE_PREPARE_NO_VTAB; + zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); + }else{ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); + } + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL); + sqlite3_free(zSql); + assert( rc==SQLITE_OK || pStmt==0 ); + p->aStmt[eStmt] = pStmt; + } + } + if( apVal ){ + int i; + int nParam = sqlite3_bind_parameter_count(pStmt); + for(i=0; rc==SQLITE_OK && inPendingData==0 ){ + sqlite3_stmt *pStmt; + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_null(pStmt, 1); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + } + } + + return rc; +} + +/* +** FTS maintains a separate indexes for each language-id (a 32-bit integer). +** Within each language id, a separate index is maintained to store the +** document terms, and each configured prefix size (configured the FTS +** "prefix=" option). And each index consists of multiple levels ("relative +** levels"). +** +** All three of these values (the language id, the specific index and the +** level within the index) are encoded in 64-bit integer values stored +** in the %_segdir table on disk. This function is used to convert three +** separate component values into the single 64-bit integer value that +** can be used to query the %_segdir table. +** +** Specifically, each language-id/index combination is allocated 1024 +** 64-bit integer level values ("absolute levels"). The main terms index +** for language-id 0 is allocate values 0-1023. The first prefix index +** (if any) for language-id 0 is allocated values 1024-2047. And so on. +** Language 1 indexes are allocated immediately following language 0. +** +** So, for a system with nPrefix prefix indexes configured, the block of +** absolute levels that corresponds to language-id iLangid and index +** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). +*/ +static sqlite3_int64 getAbsoluteLevel( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index in p->aIndex[] */ + int iLevel /* Level of segments */ +){ + sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ + assert_fts3_nc( iLangid>=0 ); + assert( p->nIndex>0 ); + assert( iIndex>=0 && iIndexnIndex ); + + iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; + return iBase + iLevel; +} + +/* +** Set *ppStmt to a statement handle that may be used to iterate through +** all rows in the %_segdir table, from oldest to newest. If successful, +** return SQLITE_OK. If an error occurs while preparing the statement, +** return an SQLite error code. +** +** There is only ever one instance of this SQL statement compiled for +** each FTS3 table. +** +** The statement returns the following columns from the %_segdir table: +** +** 0: idx +** 1: start_block +** 2: leaves_end_block +** 3: end_block +** 4: root +*/ +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( + Fts3Table *p, /* FTS3 table */ + int iLangid, /* Language being queried */ + int iIndex, /* Index for p->aIndex[] */ + int iLevel, /* Level to select (relative level) */ + sqlite3_stmt **ppStmt /* OUT: Compiled statement */ +){ + int rc; + sqlite3_stmt *pStmt = 0; + + assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 ); + assert( iLevel=0 && iIndexnIndex ); + + if( iLevel<0 ){ + /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + } + }else{ + /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel)); + } + } + *ppStmt = pStmt; + return rc; +} + + +/* +** Append a single varint to a PendingList buffer. SQLITE_OK is returned +** if successful, or an SQLite error code otherwise. +** +** This function also serves to allocate the PendingList structure itself. +** For example, to create a new PendingList structure containing two +** varints: +** +** PendingList *p = 0; +** fts3PendingListAppendVarint(&p, 1); +** fts3PendingListAppendVarint(&p, 2); +*/ +static int fts3PendingListAppendVarint( + PendingList **pp, /* IN/OUT: Pointer to PendingList struct */ + sqlite3_int64 i /* Value to append to data */ +){ + PendingList *p = *pp; + + /* Allocate or grow the PendingList as required. */ + if( !p ){ + p = sqlite3_malloc64(sizeof(*p) + 100); + if( !p ){ + return SQLITE_NOMEM; + } + p->nSpace = 100; + p->aData = (char *)&p[1]; + p->nData = 0; + } + else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ + i64 nNew = p->nSpace * 2; + p = sqlite3_realloc64(p, sizeof(*p) + nNew); + if( !p ){ + sqlite3_free(*pp); + *pp = 0; + return SQLITE_NOMEM; + } + p->nSpace = (int)nNew; + p->aData = (char *)&p[1]; + } + + /* Append the new serialized varint to the end of the list. */ + p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); + p->aData[p->nData] = '\0'; + *pp = p; + return SQLITE_OK; +} + +/* +** Add a docid/column/position entry to a PendingList structure. Non-zero +** is returned if the structure is sqlite3_realloced as part of adding +** the entry. Otherwise, zero. +** +** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning. +** Zero is always returned in this case. Otherwise, if no OOM error occurs, +** it is set to SQLITE_OK. +*/ +static int fts3PendingListAppend( + PendingList **pp, /* IN/OUT: PendingList structure */ + sqlite3_int64 iDocid, /* Docid for entry to add */ + sqlite3_int64 iCol, /* Column for entry to add */ + sqlite3_int64 iPos, /* Position of term for entry to add */ + int *pRc /* OUT: Return code */ +){ + PendingList *p = *pp; + int rc = SQLITE_OK; + + assert( !p || p->iLastDocid<=iDocid ); + + if( !p || p->iLastDocid!=iDocid ){ + u64 iDelta = (u64)iDocid - (u64)(p ? p->iLastDocid : 0); + if( p ){ + assert( p->nDatanSpace ); + assert( p->aData[p->nData]==0 ); + p->nData++; + } + if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){ + goto pendinglistappend_out; + } + p->iLastCol = -1; + p->iLastPos = 0; + p->iLastDocid = iDocid; + } + if( iCol>0 && p->iLastCol!=iCol ){ + if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, 1)) + || SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iCol)) + ){ + goto pendinglistappend_out; + } + p->iLastCol = iCol; + p->iLastPos = 0; + } + if( iCol>=0 ){ + assert( iPos>p->iLastPos || (iPos==0 && p->iLastPos==0) ); + rc = fts3PendingListAppendVarint(&p, 2+iPos-p->iLastPos); + if( rc==SQLITE_OK ){ + p->iLastPos = iPos; + } + } + + pendinglistappend_out: + *pRc = rc; + if( p!=*pp ){ + *pp = p; + return 1; + } + return 0; +} + +/* +** Free a PendingList object allocated by fts3PendingListAppend(). +*/ +static void fts3PendingListDelete(PendingList *pList){ + sqlite3_free(pList); +} + +/* +** Add an entry to one of the pending-terms hash tables. +*/ +static int fts3PendingTermsAddOne( + Fts3Table *p, + int iCol, + int iPos, + Fts3Hash *pHash, /* Pending terms hash table to add entry to */ + const char *zToken, + int nToken +){ + PendingList *pList; + int rc = SQLITE_OK; + + pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); + if( pList ){ + p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); + } + if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ + if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ + /* Malloc failed while inserting the new entry. This can only + ** happen if there was no previous entry for this token. + */ + assert( 0==fts3HashFind(pHash, zToken, nToken) ); + sqlite3_free(pList); + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); + } + return rc; +} + +/* +** Tokenize the nul-terminated string zText and add all tokens to the +** pending-terms hash-table. The docid used is that currently stored in +** p->iPrevDocid, and the column is specified by argument iCol. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int fts3PendingTermsAdd( + Fts3Table *p, /* Table into which text will be inserted */ + int iLangid, /* Language id to use */ + const char *zText, /* Text of document to be inserted */ + int iCol, /* Column into which text is being inserted */ + u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */ +){ + int rc; + int iStart = 0; + int iEnd = 0; + int iPos = 0; + int nWord = 0; + + char const *zToken; + int nToken = 0; + + sqlite3_tokenizer *pTokenizer = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr; + int (*xNext)(sqlite3_tokenizer_cursor *pCursor, + const char**,int*,int*,int*,int*); + + assert( pTokenizer && pModule ); + + /* If the user has inserted a NULL value, this function may be called with + ** zText==0. In this case, add zero token entries to the hash table and + ** return early. */ + if( zText==0 ){ + *pnWord = 0; + return SQLITE_OK; + } + + rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + + xNext = pModule->xNext; + while( SQLITE_OK==rc + && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos)) + ){ + int i; + if( iPos>=nWord ) nWord = iPos+1; + + /* Positions cannot be negative; we use -1 as a terminator internally. + ** Tokens must have a non-zero length. + */ + if( iPos<0 || !zToken || nToken<=0 ){ + rc = SQLITE_ERROR; + break; + } + + /* Add the term to the terms index */ + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken + ); + + /* Add the term to each of the prefix indexes that it is not too + ** short for. */ + for(i=1; rc==SQLITE_OK && inIndex; i++){ + struct Fts3Index *pIndex = &p->aIndex[i]; + if( nTokennPrefix ) continue; + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix + ); + } + } + + pModule->xClose(pCsr); + *pnWord += nWord; + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Calling this function indicates that subsequent calls to +** fts3PendingTermsAdd() are to add term/position-list pairs for the +** contents of the document with docid iDocid. +*/ +static int fts3PendingTermsDocid( + Fts3Table *p, /* Full-text table handle */ + int bDelete, /* True if this op is a delete */ + int iLangid, /* Language id of row being written */ + sqlite_int64 iDocid /* Docid of row being written */ +){ + assert( iLangid>=0 ); + assert( bDelete==1 || bDelete==0 ); + + /* TODO(shess) Explore whether partially flushing the buffer on + ** forced-flush would provide better performance. I suspect that if + ** we ordered the doclists by size and flushed the largest until the + ** buffer was half empty, that would let the less frequent terms + ** generate longer doclists. + */ + if( iDocidiPrevDocid + || (iDocid==p->iPrevDocid && p->bPrevDelete==0) + || p->iPrevLangid!=iLangid + || p->nPendingData>p->nMaxPendingData + ){ + int rc = sqlite3Fts3PendingTermsFlush(p); + if( rc!=SQLITE_OK ) return rc; + } + p->iPrevDocid = iDocid; + p->iPrevLangid = iLangid; + p->bPrevDelete = bDelete; + return SQLITE_OK; +} + +/* +** Discard the contents of the pending-terms hash tables. +*/ +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){ + int i; + for(i=0; inIndex; i++){ + Fts3HashElem *pElem; + Fts3Hash *pHash = &p->aIndex[i].hPending; + for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){ + PendingList *pList = (PendingList *)fts3HashData(pElem); + fts3PendingListDelete(pList); + } + fts3HashClear(pHash); + } + p->nPendingData = 0; +} + +/* +** This function is called by the xUpdate() method as part of an INSERT +** operation. It adds entries for each term in the new record to the +** pendingTerms hash table. +** +** Argument apVal is the same as the similarly named argument passed to +** fts3InsertData(). Parameter iDocid is the docid of the new row. +*/ +static int fts3InsertTerms( + Fts3Table *p, + int iLangid, + sqlite3_value **apVal, + u32 *aSz +){ + int i; /* Iterator variable */ + for(i=2; inColumn+2; i++){ + int iCol = i-2; + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_value_text(apVal[i]); + int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); + if( rc!=SQLITE_OK ){ + return rc; + } + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); + } + } + return SQLITE_OK; +} + +/* +** This function is called by the xUpdate() method for an INSERT operation. +** The apVal parameter is passed a copy of the apVal argument passed by +** SQLite to the xUpdate() method. i.e: +** +** apVal[0] Not used for INSERT. +** apVal[1] rowid +** apVal[2] Left-most user-defined column +** ... +** apVal[p->nColumn+1] Right-most user-defined column +** apVal[p->nColumn+2] Hidden column with same name as table +** apVal[p->nColumn+3] Hidden "docid" column (alias for rowid) +** apVal[p->nColumn+4] Hidden languageid column +*/ +static int fts3InsertData( + Fts3Table *p, /* Full-text table */ + sqlite3_value **apVal, /* Array of values to insert */ + sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ +){ + int rc; /* Return code */ + sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */ + + if( p->zContentTbl ){ + sqlite3_value *pRowid = apVal[p->nColumn+3]; + if( sqlite3_value_type(pRowid)==SQLITE_NULL ){ + pRowid = apVal[1]; + } + if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){ + return SQLITE_CONSTRAINT; + } + *piDocid = sqlite3_value_int64(pRowid); + return SQLITE_OK; + } + + /* Locate the statement handle used to insert data into the %_content + ** table. The SQL for this statement is: + ** + ** INSERT INTO %_content VALUES(?, ?, ?, ...) + ** + ** The statement features N '?' variables, where N is the number of user + ** defined columns in the FTS3 table, plus one for the docid field. + */ + rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]); + if( rc==SQLITE_OK && p->zLanguageid ){ + rc = sqlite3_bind_int( + pContentInsert, p->nColumn+2, + sqlite3_value_int(apVal[p->nColumn+4]) + ); + } + if( rc!=SQLITE_OK ) return rc; + + /* There is a quirk here. The users INSERT statement may have specified + ** a value for the "rowid" field, for the "docid" field, or for both. + ** Which is a problem, since "rowid" and "docid" are aliases for the + ** same value. For example: + ** + ** INSERT INTO fts3tbl(rowid, docid) VALUES(1, 2); + ** + ** In FTS3, this is an error. It is an error to specify non-NULL values + ** for both docid and some other rowid alias. + */ + if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){ + if( SQLITE_NULL==sqlite3_value_type(apVal[0]) + && SQLITE_NULL!=sqlite3_value_type(apVal[1]) + ){ + /* A rowid/docid conflict. */ + return SQLITE_ERROR; + } + rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]); + if( rc!=SQLITE_OK ) return rc; + } + + /* Execute the statement to insert the record. Set *piDocid to the + ** new docid value. + */ + sqlite3_step(pContentInsert); + rc = sqlite3_reset(pContentInsert); + + *piDocid = sqlite3_last_insert_rowid(p->db); + return rc; +} + + + +/* +** Remove all data from the FTS3 table. Clear the hash table containing +** pending terms. +*/ +static int fts3DeleteAll(Fts3Table *p, int bContent){ + int rc = SQLITE_OK; /* Return code */ + + /* Discard the contents of the pending-terms hash table. */ + sqlite3Fts3PendingTermsClear(p); + + /* Delete everything from the shadow tables. Except, leave %_content as + ** is if bContent is false. */ + assert( p->zContentTbl==0 || bContent==0 ); + if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0); + fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0); + fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0); + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0); + } + if( p->bHasStat ){ + fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0); + } + return rc; +} + +/* +** +*/ +static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){ + int iLangid = 0; + if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1); + return iLangid; +} + +/* +** The first element in the apVal[] array is assumed to contain the docid +** (an integer) of a row about to be deleted. Remove all terms from the +** full-text index. +*/ +static void fts3DeleteTerms( + int *pRC, /* Result code */ + Fts3Table *p, /* The FTS table to delete from */ + sqlite3_value *pRowid, /* The docid to be deleted */ + u32 *aSz, /* Sizes of deleted document written here */ + int *pbFound /* OUT: Set to true if row really does exist */ +){ + int rc; + sqlite3_stmt *pSelect; + + assert( *pbFound==0 ); + if( *pRC ) return; + rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + int i; + int iLangid = langidFromSelect(p, pSelect); + i64 iDocid = sqlite3_column_int64(pSelect, 0); + rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid); + for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ + int iCol = i-1; + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pSelect, i); + rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); + } + } + if( rc!=SQLITE_OK ){ + sqlite3_reset(pSelect); + *pRC = rc; + return; + } + *pbFound = 1; + } + rc = sqlite3_reset(pSelect); + }else{ + sqlite3_reset(pSelect); + } + *pRC = rc; +} + +/* +** Forward declaration to account for the circular dependency between +** functions fts3SegmentMerge() and fts3AllocateSegdirIdx(). +*/ +static int fts3SegmentMerge(Fts3Table *, int, int, int); + +/* +** This function allocates a new level iLevel index in the segdir table. +** Usually, indexes are allocated within a level sequentially starting +** with 0, so the allocated index is one greater than the value returned +** by: +** +** SELECT max(idx) FROM %_segdir WHERE level = :iLevel +** +** However, if there are already FTS3_MERGE_COUNT indexes at the requested +** level, they are merged into a single level (iLevel+1) segment and the +** allocated index is 0. +** +** If successful, *piIdx is set to the allocated index slot and SQLITE_OK +** returned. Otherwise, an SQLite error code is returned. +*/ +static int fts3AllocateSegdirIdx( + Fts3Table *p, + int iLangid, /* Language id */ + int iIndex, /* Index for p->aIndex */ + int iLevel, + int *piIdx +){ + int rc; /* Return Code */ + sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ + int iNext = 0; /* Result of query pNextIdx */ + + assert( iLangid>=0 ); + assert( p->nIndex>=1 ); + + /* Set variable iNext to the next available segdir index at level iLevel. */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64( + pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); + if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ + iNext = sqlite3_column_int(pNextIdx, 0); + } + rc = sqlite3_reset(pNextIdx); + } + + if( rc==SQLITE_OK ){ + /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already + ** full, merge all segments in level iLevel into a single iLevel+1 + ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, + ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. + */ + if( iNext>=MergeCount(p) ){ + fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); + rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); + *piIdx = 0; + }else{ + *piIdx = iNext; + } + } + + return rc; +} + +/* +** The %_segments table is declared as follows: +** +** CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB) +** +** This function reads data from a single row of the %_segments table. The +** specific row is identified by the iBlockid parameter. If paBlob is not +** NULL, then a buffer is allocated using sqlite3_malloc() and populated +** with the contents of the blob stored in the "block" column of the +** identified table row is. Whether or not paBlob is NULL, *pnBlob is set +** to the size of the blob in bytes before returning. +** +** If an error occurs, or the table does not contain the specified row, +** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If +** paBlob is non-NULL, then it is the responsibility of the caller to +** eventually free the returned buffer. +** +** This function may leave an open sqlite3_blob* handle in the +** Fts3Table.pSegments variable. This handle is reused by subsequent calls +** to this function. The handle may be closed by calling the +** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy +** performance improvement, but the blob handle should always be closed +** before control is returned to the user (to prevent a lock being held +** on the database file for longer than necessary). Thus, any virtual table +** method (xFilter etc.) that may directly or indirectly call this function +** must call sqlite3Fts3SegmentsClose() before returning. +*/ +SQLITE_PRIVATE int sqlite3Fts3ReadBlock( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ + char **paBlob, /* OUT: Blob data in malloc'd buffer */ + int *pnBlob, /* OUT: Size of blob data */ + int *pnLoad /* OUT: Bytes actually loaded */ +){ + int rc; /* Return code */ + + /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ + assert( pnBlob ); + + if( p->pSegments ){ + rc = sqlite3_blob_reopen(p->pSegments, iBlockid); + }else{ + if( 0==p->zSegmentsTbl ){ + p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); + if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; + } + rc = sqlite3_blob_open( + p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments + ); + } + + if( rc==SQLITE_OK ){ + int nByte = sqlite3_blob_bytes(p->pSegments); + *pnBlob = nByte; + if( paBlob ){ + char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING); + if( !aByte ){ + rc = SQLITE_NOMEM; + }else{ + if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){ + nByte = FTS3_NODE_CHUNKSIZE; + *pnLoad = nByte; + } + rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0); + memset(&aByte[nByte], 0, FTS3_NODE_PADDING); + if( rc!=SQLITE_OK ){ + sqlite3_free(aByte); + aByte = 0; + } + } + *paBlob = aByte; + } + }else if( rc==SQLITE_ERROR ){ + rc = FTS_CORRUPT_VTAB; + } + + return rc; +} + +/* +** Close the blob handle at p->pSegments, if it is open. See comments above +** the sqlite3Fts3ReadBlock() function for details. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){ + sqlite3_blob_close(p->pSegments); + p->pSegments = 0; +} + +static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ + int nRead; /* Number of bytes to read */ + int rc; /* Return code */ + + nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE); + rc = sqlite3_blob_read( + pReader->pBlob, + &pReader->aNode[pReader->nPopulate], + nRead, + pReader->nPopulate + ); + + if( rc==SQLITE_OK ){ + pReader->nPopulate += nRead; + memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING); + if( pReader->nPopulate==pReader->nNode ){ + sqlite3_blob_close(pReader->pBlob); + pReader->pBlob = 0; + pReader->nPopulate = 0; + } + } + return rc; +} + +static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){ + int rc = SQLITE_OK; + assert( !pReader->pBlob + || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode]) + ); + while( pReader->pBlob && rc==SQLITE_OK + && (pFrom - pReader->aNode + nByte)>pReader->nPopulate + ){ + rc = fts3SegReaderIncrRead(pReader); + } + return rc; +} + +/* +** Set an Fts3SegReader cursor to point at EOF. +*/ +static void fts3SegReaderSetEof(Fts3SegReader *pSeg){ + if( !fts3SegReaderIsRootOnly(pSeg) ){ + sqlite3_free(pSeg->aNode); + sqlite3_blob_close(pSeg->pBlob); + pSeg->pBlob = 0; + } + pSeg->aNode = 0; +} + +/* +** Move the iterator passed as the first argument to the next term in the +** segment. If successful, SQLITE_OK is returned. If there is no next term, +** SQLITE_DONE. Otherwise, an SQLite error code. +*/ +static int fts3SegReaderNext( + Fts3Table *p, + Fts3SegReader *pReader, + int bIncr +){ + int rc; /* Return code of various sub-routines */ + char *pNext; /* Cursor variable */ + int nPrefix; /* Number of bytes in term prefix */ + int nSuffix; /* Number of bytes in term suffix */ + + if( !pReader->aDoclist ){ + pNext = pReader->aNode; + }else{ + pNext = &pReader->aDoclist[pReader->nDoclist]; + } + + if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){ + + if( fts3SegReaderIsPending(pReader) ){ + Fts3HashElem *pElem = *(pReader->ppNextElem); + sqlite3_free(pReader->aNode); + pReader->aNode = 0; + if( pElem ){ + char *aCopy; + PendingList *pList = (PendingList *)fts3HashData(pElem); + int nCopy = pList->nData+1; + + int nTerm = fts3HashKeysize(pElem); + if( (nTerm+1)>pReader->nTermAlloc ){ + sqlite3_free(pReader->zTerm); + pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2); + if( !pReader->zTerm ) return SQLITE_NOMEM; + pReader->nTermAlloc = (nTerm+1)*2; + } + memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm); + pReader->zTerm[nTerm] = '\0'; + pReader->nTerm = nTerm; + + aCopy = (char*)sqlite3_malloc64(nCopy); + if( !aCopy ) return SQLITE_NOMEM; + memcpy(aCopy, pList->aData, nCopy); + pReader->nNode = pReader->nDoclist = nCopy; + pReader->aNode = pReader->aDoclist = aCopy; + pReader->ppNextElem++; + assert( pReader->aNode ); + } + return SQLITE_OK; + } + + fts3SegReaderSetEof(pReader); + + /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf + ** blocks have already been traversed. */ +#ifdef CORRUPT_DB + assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock || CORRUPT_DB ); +#endif + if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){ + return SQLITE_OK; + } + + rc = sqlite3Fts3ReadBlock( + p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, + (bIncr ? &pReader->nPopulate : 0) + ); + if( rc!=SQLITE_OK ) return rc; + assert( pReader->pBlob==0 ); + if( bIncr && pReader->nPopulatenNode ){ + pReader->pBlob = p->pSegments; + p->pSegments = 0; + } + pNext = pReader->aNode; + } + + assert( !fts3SegReaderIsPending(pReader) ); + + rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); + if( rc!=SQLITE_OK ) return rc; + + /* Because of the FTS3_NODE_PADDING bytes of padding, the following is + ** safe (no risk of overread) even if the node data is corrupted. */ + pNext += fts3GetVarint32(pNext, &nPrefix); + pNext += fts3GetVarint32(pNext, &nSuffix); + if( nSuffix<=0 + || (&pReader->aNode[pReader->nNode] - pNext)pReader->nTerm + ){ + return FTS_CORRUPT_VTAB; + } + + /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are + ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer + ** overflow - hence the (i64) casts. */ + if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){ + i64 nNew = ((i64)nPrefix+nSuffix)*2; + char *zNew = sqlite3_realloc64(pReader->zTerm, nNew); + if( !zNew ){ + return SQLITE_NOMEM; + } + pReader->zTerm = zNew; + pReader->nTermAlloc = nNew; + } + + rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX); + if( rc!=SQLITE_OK ) return rc; + + memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); + pReader->nTerm = nPrefix+nSuffix; + pNext += nSuffix; + pNext += fts3GetVarint32(pNext, &pReader->nDoclist); + pReader->aDoclist = pNext; + pReader->pOffsetList = 0; + + /* Check that the doclist does not appear to extend past the end of the + ** b-tree node. And that the final byte of the doclist is 0x00. If either + ** of these statements is untrue, then the data structure is corrupt. + */ + if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode) + || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) + || pReader->nDoclist==0 + ){ + return FTS_CORRUPT_VTAB; + } + return SQLITE_OK; +} + +/* +** Set the SegReader to point to the first docid in the doclist associated +** with the current term. +*/ +static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){ + int rc = SQLITE_OK; + assert( pReader->aDoclist ); + assert( !pReader->pOffsetList ); + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + u8 bEof = 0; + pReader->iDocid = 0; + pReader->nOffsetList = 0; + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, + &pReader->iDocid, &pReader->nOffsetList, &bEof + ); + }else{ + rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); + pReader->pOffsetList = &pReader->aDoclist[n]; + } + } + return rc; +} + +/* +** Advance the SegReader to point to the next docid in the doclist +** associated with the current term. +** +** If arguments ppOffsetList and pnOffsetList are not NULL, then +** *ppOffsetList is set to point to the first column-offset list +** in the doclist entry (i.e. immediately past the docid varint). +** *pnOffsetList is set to the length of the set of column-offset +** lists, not including the nul-terminator byte. For example: +*/ +static int fts3SegReaderNextDocid( + Fts3Table *pTab, + Fts3SegReader *pReader, /* Reader to advance to next docid */ + char **ppOffsetList, /* OUT: Pointer to current position-list */ + int *pnOffsetList /* OUT: Length of *ppOffsetList in bytes */ +){ + int rc = SQLITE_OK; + char *p = pReader->pOffsetList; + char c = 0; + + assert( p ); + + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + /* A pending-terms seg-reader for an FTS4 table that uses order=desc. + ** Pending-terms doclists are always built up in ascending order, so + ** we have to iterate through them backwards here. */ + u8 bEof = 0; + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = pReader->nOffsetList - 1; + } + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid, + &pReader->nOffsetList, &bEof + ); + if( bEof ){ + pReader->pOffsetList = 0; + }else{ + pReader->pOffsetList = p; + } + }else{ + char *pEnd = &pReader->aDoclist[pReader->nDoclist]; + + /* Pointer p currently points at the first byte of an offset list. The + ** following block advances it to point one byte past the end of + ** the same offset list. */ + while( 1 ){ + + /* The following line of code (and the "p++" below the while() loop) is + ** normally all that is required to move pointer p to the desired + ** position. The exception is if this node is being loaded from disk + ** incrementally and pointer "p" now points to the first byte past + ** the populated part of pReader->aNode[]. + */ + while( *p | c ) c = *p++ & 0x80; + assert( *p==0 ); + + if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break; + rc = fts3SegReaderIncrRead(pReader); + if( rc!=SQLITE_OK ) return rc; + } + p++; + + /* If required, populate the output variables with a pointer to and the + ** size of the previous offset-list. + */ + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = (int)(p - pReader->pOffsetList - 1); + } + + /* List may have been edited in place by fts3EvalNearTrim() */ + while( p=pEnd ){ + pReader->pOffsetList = 0; + }else{ + rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + u64 iDelta; + pReader->pOffsetList = p + sqlite3Fts3GetVarintU(p, &iDelta); + if( pTab->bDescIdx ){ + pReader->iDocid = (i64)((u64)pReader->iDocid - iDelta); + }else{ + pReader->iDocid = (i64)((u64)pReader->iDocid + iDelta); + } + } + } + } + + return rc; +} + + +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( + Fts3Cursor *pCsr, + Fts3MultiSegReader *pMsr, + int *pnOvfl +){ + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + int nOvfl = 0; + int ii; + int rc = SQLITE_OK; + int pgsz = p->nPgsz; + + assert( p->bFts4 ); + assert( pgsz>0 ); + + for(ii=0; rc==SQLITE_OK && iinSegment; ii++){ + Fts3SegReader *pReader = pMsr->apSegment[ii]; + if( !fts3SegReaderIsPending(pReader) + && !fts3SegReaderIsRootOnly(pReader) + ){ + sqlite3_int64 jj; + for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ + int nBlob; + rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); + if( rc!=SQLITE_OK ) break; + if( (nBlob+35)>pgsz ){ + nOvfl += (nBlob + 34)/pgsz; + } + } + } + } + *pnOvfl = nOvfl; + return rc; +} + +/* +** Free all allocations associated with the iterator passed as the +** second argument. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ + if( pReader ){ + sqlite3_free(pReader->zTerm); + if( !fts3SegReaderIsRootOnly(pReader) ){ + sqlite3_free(pReader->aNode); + } + sqlite3_blob_close(pReader->pBlob); + } + sqlite3_free(pReader); +} + +/* +** Allocate a new SegReader object. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( + int iAge, /* Segment "age". */ + int bLookup, /* True for a lookup only */ + sqlite3_int64 iStartLeaf, /* First leaf to traverse */ + sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ + sqlite3_int64 iEndBlock, /* Final block of segment */ + const char *zRoot, /* Buffer containing root node */ + int nRoot, /* Size of buffer containing root node */ + Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ +){ + Fts3SegReader *pReader; /* Newly allocated SegReader object */ + int nExtra = 0; /* Bytes to allocate segment root node */ + + assert( zRoot!=0 || nRoot==0 ); +#ifdef CORRUPT_DB + assert( zRoot!=0 || CORRUPT_DB ); +#endif + + if( iStartLeaf==0 ){ + if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB; + nExtra = nRoot + FTS3_NODE_PADDING; + } + + pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra); + if( !pReader ){ + return SQLITE_NOMEM; + } + memset(pReader, 0, sizeof(Fts3SegReader)); + pReader->iIdx = iAge; + pReader->bLookup = bLookup!=0; + pReader->iStartBlock = iStartLeaf; + pReader->iLeafEndBlock = iEndLeaf; + pReader->iEndBlock = iEndBlock; + + if( nExtra ){ + /* The entire segment is stored in the root node. */ + pReader->aNode = (char *)&pReader[1]; + pReader->rootOnly = 1; + pReader->nNode = nRoot; + if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot); + memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING); + }else{ + pReader->iCurrentBlock = iStartLeaf-1; + } + *ppReader = pReader; + return SQLITE_OK; +} + +/* +** This is a comparison function used as a qsort() callback when sorting +** an array of pending terms by term. This occurs as part of flushing +** the contents of the pending-terms hash table to the database. +*/ +static int SQLITE_CDECL fts3CompareElemByTerm( + const void *lhs, + const void *rhs +){ + char *z1 = fts3HashKey(*(Fts3HashElem **)lhs); + char *z2 = fts3HashKey(*(Fts3HashElem **)rhs); + int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs); + int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs); + + int n = (n1aIndex */ + const char *zTerm, /* Term to search for */ + int nTerm, /* Size of buffer zTerm */ + int bPrefix, /* True for a prefix iterator */ + Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ +){ + Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ + Fts3HashElem *pE; /* Iterator variable */ + Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ + int nElem = 0; /* Size of array at aElem */ + int rc = SQLITE_OK; /* Return Code */ + Fts3Hash *pHash; + + pHash = &p->aIndex[iIndex].hPending; + if( bPrefix ){ + int nAlloc = 0; /* Size of allocated array at aElem */ + + for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ + char *zKey = (char *)fts3HashKey(pE); + int nKey = fts3HashKeysize(pE); + if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ + if( nElem==nAlloc ){ + Fts3HashElem **aElem2; + nAlloc += 16; + aElem2 = (Fts3HashElem **)sqlite3_realloc64( + aElem, nAlloc*sizeof(Fts3HashElem *) + ); + if( !aElem2 ){ + rc = SQLITE_NOMEM; + nElem = 0; + break; + } + aElem = aElem2; + } + + aElem[nElem++] = pE; + } + } + + /* If more than one term matches the prefix, sort the Fts3HashElem + ** objects in term order using qsort(). This uses the same comparison + ** callback as is used when flushing terms to disk. + */ + if( nElem>1 ){ + qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm); + } + + }else{ + /* The query is a simple term lookup that matches at most one term in + ** the index. All that is required is a straight hash-lookup. + ** + ** Because the stack address of pE may be accessed via the aElem pointer + ** below, the "Fts3HashElem *pE" must be declared so that it is valid + ** within this entire function, not just this "else{...}" block. + */ + pE = fts3HashFindElem(pHash, zTerm, nTerm); + if( pE ){ + aElem = &pE; + nElem = 1; + } + } + + if( nElem>0 ){ + sqlite3_int64 nByte; + nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); + pReader = (Fts3SegReader *)sqlite3_malloc64(nByte); + if( !pReader ){ + rc = SQLITE_NOMEM; + }else{ + memset(pReader, 0, nByte); + pReader->iIdx = 0x7FFFFFFF; + pReader->ppNextElem = (Fts3HashElem **)&pReader[1]; + memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *)); + } + } + + if( bPrefix ){ + sqlite3_free(aElem); + } + *ppReader = pReader; + return rc; +} + +/* +** Compare the entries pointed to by two Fts3SegReader structures. +** Comparison is as follows: +** +** 1) EOF is greater than not EOF. +** +** 2) The current terms (if any) are compared using memcmp(). If one +** term is a prefix of another, the longer term is considered the +** larger. +** +** 3) By segment age. An older segment is considered larger. +*/ +static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc; + if( pLhs->aNode && pRhs->aNode ){ + int rc2 = pLhs->nTerm - pRhs->nTerm; + if( rc2<0 ){ + rc = memcmp(pLhs->zTerm, pRhs->zTerm, pLhs->nTerm); + }else{ + rc = memcmp(pLhs->zTerm, pRhs->zTerm, pRhs->nTerm); + } + if( rc==0 ){ + rc = rc2; + } + }else{ + rc = (pLhs->aNode==0) - (pRhs->aNode==0); + } + if( rc==0 ){ + rc = pRhs->iIdx - pLhs->iIdx; + } + assert_fts3_nc( rc!=0 ); + return rc; +} + +/* +** A different comparison function for SegReader structures. In this +** version, it is assumed that each SegReader points to an entry in +** a doclist for identical terms. Comparison is made as follows: +** +** 1) EOF (end of doclist in this case) is greater than not EOF. +** +** 2) By current docid. +** +** 3) By segment age. An older segment is considered larger. +*/ +static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} +static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} + +/* +** Compare the term that the Fts3SegReader object passed as the first argument +** points to with the term specified by arguments zTerm and nTerm. +** +** If the pSeg iterator is already at EOF, return 0. Otherwise, return +** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are +** equal, or +ve if the pSeg term is greater than zTerm/nTerm. +*/ +static int fts3SegReaderTermCmp( + Fts3SegReader *pSeg, /* Segment reader object */ + const char *zTerm, /* Term to compare to */ + int nTerm /* Size of term zTerm in bytes */ +){ + int res = 0; + if( pSeg->aNode ){ + if( pSeg->nTerm>nTerm ){ + res = memcmp(pSeg->zTerm, zTerm, nTerm); + }else{ + res = memcmp(pSeg->zTerm, zTerm, pSeg->nTerm); + } + if( res==0 ){ + res = pSeg->nTerm-nTerm; + } + } + return res; +} + +/* +** Argument apSegment is an array of nSegment elements. It is known that +** the final (nSegment-nSuspect) members are already in sorted order +** (according to the comparison function provided). This function shuffles +** the array around until all entries are in sorted order. +*/ +static void fts3SegReaderSort( + Fts3SegReader **apSegment, /* Array to sort entries of */ + int nSegment, /* Size of apSegment array */ + int nSuspect, /* Unsorted entry count */ + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) /* Comparison function */ +){ + int i; /* Iterator variable */ + + assert( nSuspect<=nSegment ); + + if( nSuspect==nSegment ) nSuspect--; + for(i=nSuspect-1; i>=0; i--){ + int j; + for(j=i; j<(nSegment-1); j++){ + Fts3SegReader *pTmp; + if( xCmp(apSegment[j], apSegment[j+1])<0 ) break; + pTmp = apSegment[j+1]; + apSegment[j+1] = apSegment[j]; + apSegment[j] = pTmp; + } + } + +#ifndef NDEBUG + /* Check that the list really is sorted now. */ + for(i=0; i<(nSuspect-1); i++){ + assert( xCmp(apSegment[i], apSegment[i+1])<0 ); + } +#endif +} + +/* +** Insert a record into the %_segments table. +*/ +static int fts3WriteSegment( + Fts3Table *p, /* Virtual table handle */ + sqlite3_int64 iBlock, /* Block id for new block */ + char *z, /* Pointer to buffer containing block data */ + int n /* Size of buffer z in bytes */ +){ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, iBlock); + sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); + } + return rc; +} + +/* +** Find the largest relative level number in the table. If successful, set +** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs, +** set *pnMax to zero and return an SQLite error code. +*/ +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ + int rc; + int mxLevel = 0; + sqlite3_stmt *pStmt = 0; + + rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + mxLevel = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_reset(pStmt); + } + *pnMax = mxLevel; + return rc; +} + +/* +** Insert a record into the %_segdir table. +*/ +static int fts3WriteSegdir( + Fts3Table *p, /* Virtual table handle */ + sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ + int iIdx, /* Value for "idx" field */ + sqlite3_int64 iStartBlock, /* Value for "start_block" field */ + sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ + sqlite3_int64 iEndBlock, /* Value for "end_block" field */ + sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ + char *zRoot, /* Blob value for "root" field */ + int nRoot /* Number of bytes in buffer zRoot */ +){ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, iLevel); + sqlite3_bind_int(pStmt, 2, iIdx); + sqlite3_bind_int64(pStmt, 3, iStartBlock); + sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); + if( nLeafData==0 ){ + sqlite3_bind_int64(pStmt, 5, iEndBlock); + }else{ + char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); + if( !zEnd ) return SQLITE_NOMEM; + sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); + } + sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 6); + } + return rc; +} + +/* +** Return the size of the common prefix (if any) shared by zPrev and +** zNext, in bytes. For example, +** +** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3 +** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2 +** fts3PrefixCompress("abX", 3, "Xbcdef", 6) // returns 0 +*/ +static int fts3PrefixCompress( + const char *zPrev, /* Buffer containing previous term */ + int nPrev, /* Size of buffer zPrev in bytes */ + const char *zNext, /* Buffer containing next term */ + int nNext /* Size of buffer zNext in bytes */ +){ + int n; + for(n=0; nnData; /* Current size of node in bytes */ + int nReq = nData; /* Required space after adding zTerm */ + int nPrefix; /* Number of bytes of prefix compression */ + int nSuffix; /* Suffix length */ + + nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + + /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of + ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when + ** compared with BINARY collation. This indicates corruption. */ + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + + nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; + if( nReq<=p->nNodeSize || !pTree->zTerm ){ + + if( nReq>p->nNodeSize ){ + /* An unusual case: this is the first term to be added to the node + ** and the static node buffer (p->nNodeSize bytes) is not large + ** enough. Use a separately malloced buffer instead This wastes + ** p->nNodeSize bytes, but since this scenario only comes about when + ** the database contain two terms that share a prefix of almost 2KB, + ** this is not expected to be a serious problem. + */ + assert( pTree->aData==(char *)&pTree[1] ); + pTree->aData = (char *)sqlite3_malloc64(nReq); + if( !pTree->aData ){ + return SQLITE_NOMEM; + } + } + + if( pTree->zTerm ){ + /* There is no prefix-length field for first term in a node */ + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix); + } + + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix); + memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix); + pTree->nData = nData + nSuffix; + pTree->nEntry++; + + if( isCopyTerm ){ + if( pTree->nMalloczMalloc, (i64)nTerm*2); + if( !zNew ){ + return SQLITE_NOMEM; + } + pTree->nMalloc = nTerm*2; + pTree->zMalloc = zNew; + } + pTree->zTerm = pTree->zMalloc; + memcpy(pTree->zTerm, zTerm, nTerm); + pTree->nTerm = nTerm; + }else{ + pTree->zTerm = (char *)zTerm; + pTree->nTerm = nTerm; + } + return SQLITE_OK; + } + } + + /* If control flows to here, it was not possible to append zTerm to the + ** current node. Create a new node (a right-sibling of the current node). + ** If this is the first node in the tree, the term is added to it. + ** + ** Otherwise, the term is not added to the new node, it is left empty for + ** now. Instead, the term is inserted into the parent of pTree. If pTree + ** has no parent, one is created here. + */ + pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize); + if( !pNew ){ + return SQLITE_NOMEM; + } + memset(pNew, 0, sizeof(SegmentNode)); + pNew->nData = 1 + FTS3_VARINT_MAX; + pNew->aData = (char *)&pNew[1]; + + if( pTree ){ + SegmentNode *pParent = pTree->pParent; + rc = fts3NodeAddTerm(p, &pParent, isCopyTerm, zTerm, nTerm); + if( pTree->pParent==0 ){ + pTree->pParent = pParent; + } + pTree->pRight = pNew; + pNew->pLeftmost = pTree->pLeftmost; + pNew->pParent = pParent; + pNew->zMalloc = pTree->zMalloc; + pNew->nMalloc = pTree->nMalloc; + pTree->zMalloc = 0; + }else{ + pNew->pLeftmost = pNew; + rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); + } + + *ppTree = pNew; + return rc; +} + +/* +** Helper function for fts3NodeWrite(). +*/ +static int fts3TreeFinishNode( + SegmentNode *pTree, + int iHeight, + sqlite3_int64 iLeftChild +){ + int nStart; + assert( iHeight>=1 && iHeight<128 ); + nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild); + pTree->aData[nStart] = (char)iHeight; + sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild); + return nStart; +} + +/* +** Write the buffer for the segment node pTree and all of its peers to the +** database. Then call this function recursively to write the parent of +** pTree and its peers to the database. +** +** Except, if pTree is a root node, do not write it to the database. Instead, +** set output variables *paRoot and *pnRoot to contain the root node. +** +** If successful, SQLITE_OK is returned and output variable *piLast is +** set to the largest blockid written to the database (or zero if no +** blocks were written to the db). Otherwise, an SQLite error code is +** returned. +*/ +static int fts3NodeWrite( + Fts3Table *p, /* Virtual table handle */ + SegmentNode *pTree, /* SegmentNode handle */ + int iHeight, /* Height of this node in tree */ + sqlite3_int64 iLeaf, /* Block id of first leaf node */ + sqlite3_int64 iFree, /* Block id of next free slot in %_segments */ + sqlite3_int64 *piLast, /* OUT: Block id of last entry written */ + char **paRoot, /* OUT: Data for root node */ + int *pnRoot /* OUT: Size of root node in bytes */ +){ + int rc = SQLITE_OK; + + if( !pTree->pParent ){ + /* Root node of the tree. */ + int nStart = fts3TreeFinishNode(pTree, iHeight, iLeaf); + *piLast = iFree-1; + *pnRoot = pTree->nData - nStart; + *paRoot = &pTree->aData[nStart]; + }else{ + SegmentNode *pIter; + sqlite3_int64 iNextFree = iFree; + sqlite3_int64 iNextLeaf = iLeaf; + for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){ + int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf); + int nWrite = pIter->nData - nStart; + + rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite); + iNextFree++; + iNextLeaf += (pIter->nEntry+1); + } + if( rc==SQLITE_OK ){ + assert( iNextLeaf==iFree ); + rc = fts3NodeWrite( + p, pTree->pParent, iHeight+1, iFree, iNextFree, piLast, paRoot, pnRoot + ); + } + } + + return rc; +} + +/* +** Free all memory allocations associated with the tree pTree. +*/ +static void fts3NodeFree(SegmentNode *pTree){ + if( pTree ){ + SegmentNode *p = pTree->pLeftmost; + fts3NodeFree(p->pParent); + while( p ){ + SegmentNode *pRight = p->pRight; + if( p->aData!=(char *)&p[1] ){ + sqlite3_free(p->aData); + } + assert( pRight==0 || p->zMalloc==0 ); + sqlite3_free(p->zMalloc); + sqlite3_free(p); + p = pRight; + } + } +} + +/* +** Add a term to the segment being constructed by the SegmentWriter object +** *ppWriter. When adding the first term to a segment, *ppWriter should +** be passed NULL. This function will allocate a new SegmentWriter object +** and return it via the input/output variable *ppWriter in this case. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int fts3SegWriterAdd( + Fts3Table *p, /* Virtual table handle */ + SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ + int isCopyTerm, /* True if buffer zTerm must be copied */ + const char *zTerm, /* Pointer to buffer containing term */ + int nTerm, /* Size of term in bytes */ + const char *aDoclist, /* Pointer to buffer containing doclist */ + int nDoclist /* Size of doclist in bytes */ +){ + int nPrefix; /* Size of term prefix in bytes */ + int nSuffix; /* Size of term suffix in bytes */ + i64 nReq; /* Number of bytes required on leaf page */ + int nData; + SegmentWriter *pWriter = *ppWriter; + + if( !pWriter ){ + int rc; + sqlite3_stmt *pStmt; + + /* Allocate the SegmentWriter structure */ + pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter)); + if( !pWriter ) return SQLITE_NOMEM; + memset(pWriter, 0, sizeof(SegmentWriter)); + *ppWriter = pWriter; + + /* Allocate a buffer in which to accumulate data */ + pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize); + if( !pWriter->aData ) return SQLITE_NOMEM; + pWriter->nSize = p->nNodeSize; + + /* Find the next free blockid in the %_segments table */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + pWriter->iFree = sqlite3_column_int64(pStmt, 0); + pWriter->iFirst = pWriter->iFree; + } + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ) return rc; + } + nData = pWriter->nData; + + nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + + /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of + ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when + ** compared with BINARY collation. This indicates corruption. */ + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + + /* Figure out how many bytes are required by this new entry */ + nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ + nSuffix + /* Term suffix */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + nDoclist; /* Doclist data */ + + if( nData>0 && nData+nReq>p->nNodeSize ){ + int rc; + + /* The current leaf node is full. Write it out to the database. */ + if( pWriter->iFree==LARGEST_INT64 ) return FTS_CORRUPT_VTAB; + rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); + if( rc!=SQLITE_OK ) return rc; + p->nLeafAdd++; + + /* Add the current term to the interior node tree. The term added to + ** the interior tree must: + ** + ** a) be greater than the largest term on the leaf node just written + ** to the database (still available in pWriter->zTerm), and + ** + ** b) be less than or equal to the term about to be added to the new + ** leaf node (zTerm/nTerm). + ** + ** In other words, it must be the prefix of zTerm 1 byte longer than + ** the common prefix (if any) of zTerm and pWriter->zTerm. + */ + assert( nPrefixpTree, isCopyTerm, zTerm, nPrefix+1); + if( rc!=SQLITE_OK ) return rc; + + nData = 0; + pWriter->nTerm = 0; + + nPrefix = 0; + nSuffix = nTerm; + nReq = 1 + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ + nTerm + /* Term suffix */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + nDoclist; /* Doclist data */ + } + + /* Increase the total number of bytes written to account for the new entry. */ + pWriter->nLeafData += nReq; + + /* If the buffer currently allocated is too small for this entry, realloc + ** the buffer to make it large enough. + */ + if( nReq>pWriter->nSize ){ + char *aNew = sqlite3_realloc64(pWriter->aData, nReq); + if( !aNew ) return SQLITE_NOMEM; + pWriter->aData = aNew; + pWriter->nSize = nReq; + } + assert( nData+nReq<=pWriter->nSize ); + + /* Append the prefix-compressed term and doclist to the buffer. */ + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); + assert( nSuffix>0 ); + memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); + nData += nSuffix; + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); + assert( nDoclist>0 ); + memcpy(&pWriter->aData[nData], aDoclist, nDoclist); + pWriter->nData = nData + nDoclist; + + /* Save the current term so that it can be used to prefix-compress the next. + ** If the isCopyTerm parameter is true, then the buffer pointed to by + ** zTerm is transient, so take a copy of the term data. Otherwise, just + ** store a copy of the pointer. + */ + if( isCopyTerm ){ + if( nTerm>pWriter->nMalloc ){ + char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2); + if( !zNew ){ + return SQLITE_NOMEM; + } + pWriter->nMalloc = nTerm*2; + pWriter->zMalloc = zNew; + pWriter->zTerm = zNew; + } + assert( pWriter->zTerm==pWriter->zMalloc ); + assert( nTerm>0 ); + memcpy(pWriter->zTerm, zTerm, nTerm); + }else{ + pWriter->zTerm = (char *)zTerm; + } + pWriter->nTerm = nTerm; + + return SQLITE_OK; +} + +/* +** Flush all data associated with the SegmentWriter object pWriter to the +** database. This function must be called after all terms have been added +** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is +** returned. Otherwise, an SQLite error code. +*/ +static int fts3SegWriterFlush( + Fts3Table *p, /* Virtual table handle */ + SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ + sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ + int iIdx /* Value for 'idx' column of %_segdir */ +){ + int rc; /* Return code */ + if( pWriter->pTree ){ + sqlite3_int64 iLast = 0; /* Largest block id written to database */ + sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ + char *zRoot = NULL; /* Pointer to buffer containing root node */ + int nRoot = 0; /* Size of buffer zRoot */ + + iLastLeaf = pWriter->iFree; + rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData); + if( rc==SQLITE_OK ){ + rc = fts3NodeWrite(p, pWriter->pTree, 1, + pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); + } + if( rc==SQLITE_OK ){ + rc = fts3WriteSegdir(p, iLevel, iIdx, + pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, zRoot, nRoot); + } + }else{ + /* The entire tree fits on the root node. Write it to the segdir table. */ + rc = fts3WriteSegdir(p, iLevel, iIdx, + 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData); + } + p->nLeafAdd++; + return rc; +} + +/* +** Release all memory held by the SegmentWriter object passed as the +** first argument. +*/ +static void fts3SegWriterFree(SegmentWriter *pWriter){ + if( pWriter ){ + sqlite3_free(pWriter->aData); + sqlite3_free(pWriter->zMalloc); + fts3NodeFree(pWriter->pTree); + sqlite3_free(pWriter); + } +} + +/* +** The first value in the apVal[] array is assumed to contain an integer. +** This function tests if there exist any documents with docid values that +** are different from that integer. i.e. if deleting the document with docid +** pRowid would mean the FTS3 table were empty. +** +** If successful, *pisEmpty is set to true if the table is empty except for +** document pRowid, or false otherwise, and SQLITE_OK is returned. If an +** error occurs, an SQLite error code is returned. +*/ +static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){ + sqlite3_stmt *pStmt; + int rc; + if( p->zContentTbl ){ + /* If using the content=xxx option, assume the table is never empty */ + *pisEmpty = 0; + rc = SQLITE_OK; + }else{ + rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pisEmpty = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_reset(pStmt); + } + } + return rc; +} + +/* +** Set *pnMax to the largest segment level in the database for the index +** iIndex. +** +** Segment levels are stored in the 'level' column of the %_segdir table. +** +** Return SQLITE_OK if successful, or an SQLite error code if not. +*/ +static int fts3SegmentMaxLevel( + Fts3Table *p, + int iLangid, + int iIndex, + sqlite3_int64 *pnMax +){ + sqlite3_stmt *pStmt; + int rc; + assert( iIndex>=0 && iIndexnIndex ); + + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pnMax = sqlite3_column_int64(pStmt, 0); + } + return sqlite3_reset(pStmt); +} + +/* +** iAbsLevel is an absolute level that may be assumed to exist within +** the database. This function checks if it is the largest level number +** within its index. Assuming no error occurs, *pbMax is set to 1 if +** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK +** is returned. If an error occurs, an error code is returned and the +** final value of *pbMax is undefined. +*/ +static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ + + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); + sqlite3_bind_int64(pStmt, 2, + (((u64)iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL + ); + + *pbMax = 0; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; + } + return sqlite3_reset(pStmt); +} + +/* +** Delete all entries in the %_segments table associated with the segment +** opened with seg-reader pSeg. This function does not affect the contents +** of the %_segdir table. +*/ +static int fts3DeleteSegment( + Fts3Table *p, /* FTS table handle */ + Fts3SegReader *pSeg /* Segment to delete */ +){ + int rc = SQLITE_OK; /* Return code */ + if( pSeg->iStartBlock ){ + sqlite3_stmt *pDelete; /* SQL statement to delete rows */ + rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); + sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + } + return rc; +} + +/* +** This function is used after merging multiple segments into a single large +** segment to delete the old, now redundant, segment b-trees. Specifically, +** it: +** +** 1) Deletes all %_segments entries for the segments associated with +** each of the SegReader objects in the array passed as the third +** argument, and +** +** 2) deletes all %_segdir entries with level iLevel, or all %_segdir +** entries regardless of level if (iLevel<0). +** +** SQLITE_OK is returned if successful, otherwise an SQLite error code. +*/ +static int fts3DeleteSegdir( + Fts3Table *p, /* Virtual table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index for p->aIndex */ + int iLevel, /* Level of %_segdir entries to delete */ + Fts3SegReader **apSegment, /* Array of SegReader objects */ + int nReader /* Size of array apSegment */ +){ + int rc = SQLITE_OK; /* Return Code */ + int i; /* Iterator variable */ + sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ + + for(i=0; rc==SQLITE_OK && i=0 || iLevel==FTS3_SEGCURSOR_ALL ); + if( iLevel==FTS3_SEGCURSOR_ALL ){ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pDelete, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + } + }else{ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64( + pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + + return rc; +} + +/* +** When this function is called, buffer *ppList (size *pnList bytes) contains +** a position list that may (or may not) feature multiple columns. This +** function adjusts the pointer *ppList and the length *pnList so that they +** identify the subset of the position list that corresponds to column iCol. +** +** If there are no entries in the input position list for column iCol, then +** *pnList is set to zero before returning. +** +** If parameter bZero is non-zero, then any part of the input list following +** the end of the output list is zeroed before returning. +*/ +static void fts3ColumnFilter( + int iCol, /* Column to filter on */ + int bZero, /* Zero out anything following *ppList */ + char **ppList, /* IN/OUT: Pointer to position list */ + int *pnList /* IN/OUT: Size of buffer *ppList in bytes */ +){ + char *pList = *ppList; + int nList = *pnList; + char *pEnd = &pList[nList]; + int iCurrent = 0; + char *p = pList; + + assert( iCol>=0 ); + while( 1 ){ + char c = 0; + while( p0){ + memset(&pList[nList], 0, pEnd - &pList[nList]); + } + *ppList = pList; + *pnList = nList; +} + +/* +** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any +** existing data). Grow the buffer if required. +** +** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered +** trying to resize the buffer, return SQLITE_NOMEM. +*/ +static int fts3MsrBufferData( + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + char *pList, + i64 nList +){ + if( (nList+FTS3_NODE_PADDING)>pMsr->nBuffer ){ + char *pNew; + int nNew = nList*2 + FTS3_NODE_PADDING; + pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, nNew); + if( !pNew ) return SQLITE_NOMEM; + pMsr->aBuffer = pNew; + pMsr->nBuffer = nNew; + } + + assert( nList>0 ); + memcpy(pMsr->aBuffer, pList, nList); + memset(&pMsr->aBuffer[nList], 0, FTS3_NODE_PADDING); + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + sqlite3_int64 *piDocid, /* OUT: Docid value */ + char **paPoslist, /* OUT: Pointer to position list */ + int *pnPoslist /* OUT: Size of position list in bytes */ +){ + int nMerge = pMsr->nAdvance; + Fts3SegReader **apSegment = pMsr->apSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( nMerge==0 ){ + *paPoslist = 0; + return SQLITE_OK; + } + + while( 1 ){ + Fts3SegReader *pSeg; + pSeg = pMsr->apSegment[0]; + + if( pSeg->pOffsetList==0 ){ + *paPoslist = 0; + break; + }else{ + int rc; + char *pList; + int nList; + int j; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + + rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( rc==SQLITE_OK + && jpOffsetList + && apSegment[j]->iDocid==iDocid + ){ + rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + if( rc!=SQLITE_OK ) return rc; + fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); + + if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1); + if( rc!=SQLITE_OK ) return rc; + assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); + pList = pMsr->aBuffer; + } + + if( pMsr->iColFilter>=0 ){ + fts3ColumnFilter(pMsr->iColFilter, 1, &pList, &nList); + } + + if( nList>0 ){ + *paPoslist = pList; + *piDocid = iDocid; + *pnPoslist = nList; + break; + } + } + } + + return SQLITE_OK; +} + +static int fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + const char *zTerm, /* Term searched for (or NULL) */ + int nTerm /* Length of zTerm in bytes */ +){ + int i; + int nSeg = pCsr->nSegment; + + /* If the Fts3SegFilter defines a specific term (or term prefix) to search + ** for, then advance each segment iterator until it points to a term of + ** equal or greater value than the specified term. This prevents many + ** unnecessary merge/sort operations for the case where single segment + ** b-tree leaf nodes contain more than one term. + */ + for(i=0; pCsr->bRestart==0 && inSegment; i++){ + int res = 0; + Fts3SegReader *pSeg = pCsr->apSegment[i]; + do { + int rc = fts3SegReaderNext(p, pSeg, 0); + if( rc!=SQLITE_OK ) return rc; + }while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 ); + + if( pSeg->bLookup && res!=0 ){ + fts3SegReaderSetEof(pSeg); + } + } + fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); + + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + Fts3SegFilter *pFilter /* Restrictions on range of iteration */ +){ + pCsr->pFilter = pFilter; + return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + int iCol, /* Column to match on. */ + const char *zTerm, /* Term to iterate through a doclist for */ + int nTerm /* Number of bytes in zTerm */ +){ + int i; + int rc; + int nSegment = pCsr->nSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + assert( pCsr->pFilter==0 ); + assert( zTerm && nTerm>0 ); + + /* Advance each segment iterator until it points to the term zTerm/nTerm. */ + rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); + if( rc!=SQLITE_OK ) return rc; + + /* Determine how many of the segments actually point to zTerm/nTerm. */ + for(i=0; iapSegment[i]; + if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ + break; + } + } + pCsr->nAdvance = i; + + /* Advance each of the segments to point to the first docid. */ + for(i=0; inAdvance; i++){ + rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); + + assert( iCol<0 || iColnColumn ); + pCsr->iColFilter = iCol; + + return SQLITE_OK; +} + +/* +** This function is called on a MultiSegReader that has been started using +** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also +** have been made. Calling this function puts the MultiSegReader in such +** a state that if the next two calls are: +** +** sqlite3Fts3SegReaderStart() +** sqlite3Fts3SegReaderStep() +** +** then the entire doclist for the term is available in +** MultiSegReader.aDoclist/nDoclist. +*/ +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ + int i; /* Used to iterate through segment-readers */ + + assert( pCsr->zTerm==0 ); + assert( pCsr->nTerm==0 ); + assert( pCsr->aDoclist==0 ); + assert( pCsr->nDoclist==0 ); + + pCsr->nAdvance = 0; + pCsr->bRestart = 1; + for(i=0; inSegment; i++){ + pCsr->apSegment[i]->pOffsetList = 0; + pCsr->apSegment[i]->nOffsetList = 0; + pCsr->apSegment[i]->iDocid = 0; + } + + return SQLITE_OK; +} + +static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){ + if( nReq>pCsr->nBuffer ){ + char *aNew; + pCsr->nBuffer = nReq*2; + aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer); + if( !aNew ){ + return SQLITE_NOMEM; + } + pCsr->aBuffer = aNew; + } + return SQLITE_OK; +} + + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + int rc = SQLITE_OK; + + int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY); + int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS); + int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER); + int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX); + int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN); + int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST); + + Fts3SegReader **apSegment = pCsr->apSegment; + int nSegment = pCsr->nSegment; + Fts3SegFilter *pFilter = pCsr->pFilter; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( pCsr->nSegment==0 ) return SQLITE_OK; + + do { + int nMerge; + int i; + + /* Advance the first pCsr->nAdvance entries in the apSegment[] array + ** forward. Then sort the list in order of current term again. + */ + for(i=0; inAdvance; i++){ + Fts3SegReader *pSeg = apSegment[i]; + if( pSeg->bLookup ){ + fts3SegReaderSetEof(pSeg); + }else{ + rc = fts3SegReaderNext(p, pSeg, 0); + } + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp); + pCsr->nAdvance = 0; + + /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */ + assert( rc==SQLITE_OK ); + if( apSegment[0]->aNode==0 ) break; + + pCsr->nTerm = apSegment[0]->nTerm; + pCsr->zTerm = apSegment[0]->zTerm; + + /* If this is a prefix-search, and if the term that apSegment[0] points + ** to does not share a suffix with pFilter->zTerm/nTerm, then all + ** required callbacks have been made. In this case exit early. + ** + ** Similarly, if this is a search for an exact match, and the first term + ** of segment apSegment[0] is not a match, exit early. + */ + if( pFilter->zTerm && !isScan ){ + if( pCsr->nTermnTerm + || (!isPrefix && pCsr->nTerm>pFilter->nTerm) + || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm) + ){ + break; + } + } + + nMerge = 1; + while( nMergeaNode + && apSegment[nMerge]->nTerm==pCsr->nTerm + && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm) + ){ + nMerge++; + } + + assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); + if( nMerge==1 + && !isIgnoreEmpty + && !isFirst + && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) + ){ + pCsr->nDoclist = apSegment[0]->nDoclist; + if( fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, + (i64)pCsr->nDoclist); + pCsr->aDoclist = pCsr->aBuffer; + }else{ + pCsr->aDoclist = apSegment[0]->aDoclist; + } + if( rc==SQLITE_OK ) rc = SQLITE_ROW; + }else{ + int nDoclist = 0; /* Size of doclist */ + sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ + + /* The current term of the first nMerge entries in the array + ** of Fts3SegReader objects is the same. The doclists must be merged + ** and a single term returned with the merged doclist. + */ + for(i=0; ipOffsetList ){ + int j; /* Number of segments that share a docid */ + char *pList = 0; + int nList = 0; + int nByte; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( jpOffsetList + && apSegment[j]->iDocid==iDocid + ){ + fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + + if( isColFilter ){ + fts3ColumnFilter(pFilter->iCol, 0, &pList, &nList); + } + + if( !isIgnoreEmpty || nList>0 ){ + + /* Calculate the 'docid' delta value to write into the merged + ** doclist. */ + sqlite3_int64 iDelta; + if( p->bDescIdx && nDoclist>0 ){ + if( iPrev<=iDocid ) return FTS_CORRUPT_VTAB; + iDelta = (i64)((u64)iPrev - (u64)iDocid); + }else{ + if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB; + iDelta = (i64)((u64)iDocid - (u64)iPrev); + } + + nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); + + rc = fts3GrowSegReaderBuffer(pCsr, + (i64)nByte+nDoclist+FTS3_NODE_PADDING); + if( rc ) return rc; + + if( isFirst ){ + char *a = &pCsr->aBuffer[nDoclist]; + int nWrite; + + nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a); + if( nWrite ){ + iPrev = iDocid; + nDoclist += nWrite; + } + }else{ + nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); + iPrev = iDocid; + if( isRequirePos ){ + memcpy(&pCsr->aBuffer[nDoclist], pList, nList); + nDoclist += nList; + pCsr->aBuffer[nDoclist++] = '\0'; + } + } + } + + fts3SegReaderSort(apSegment, nMerge, j, xCmp); + } + if( nDoclist>0 ){ + rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING); + if( rc ) return rc; + memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING); + pCsr->aDoclist = pCsr->aBuffer; + pCsr->nDoclist = nDoclist; + rc = SQLITE_ROW; + } + } + pCsr->nAdvance = nMerge; + }while( rc==SQLITE_OK ); + + return rc; +} + + +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish( + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + if( pCsr ){ + int i; + for(i=0; inSegment; i++){ + sqlite3Fts3SegReaderFree(pCsr->apSegment[i]); + } + sqlite3_free(pCsr->apSegment); + sqlite3_free(pCsr->aBuffer); + + pCsr->nSegment = 0; + pCsr->apSegment = 0; + pCsr->aBuffer = 0; + } +} + +/* +** Decode the "end_block" field, selected by column iCol of the SELECT +** statement passed as the first argument. +** +** The "end_block" field may contain either an integer, or a text field +** containing the text representation of two non-negative integers separated +** by one or more space (0x20) characters. In the first case, set *piEndBlock +** to the integer value and *pnByte to zero before returning. In the second, +** set *piEndBlock to the first value and *pnByte to the second. +*/ +static void fts3ReadEndBlockField( + sqlite3_stmt *pStmt, + int iCol, + i64 *piEndBlock, + i64 *pnByte +){ + const unsigned char *zText = sqlite3_column_text(pStmt, iCol); + if( zText ){ + int i; + int iMul = 1; + u64 iVal = 0; + for(i=0; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } + *piEndBlock = (i64)iVal; + while( zText[i]==' ' ) i++; + iVal = 0; + if( zText[i]=='-' ){ + i++; + iMul = -1; + } + for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } + *pnByte = ((i64)iVal * (i64)iMul); + } +} + + +/* +** A segment of size nByte bytes has just been written to absolute level +** iAbsLevel. Promote any segments that should be promoted as a result. +*/ +static int fts3PromoteSegments( + Fts3Table *p, /* FTS table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level just updated */ + sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ +){ + int rc = SQLITE_OK; + sqlite3_stmt *pRange; + + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); + + if( rc==SQLITE_OK ){ + int bOk = 0; + i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1; + i64 nLimit = (nByte*3)/2; + + /* Loop through all entries in the %_segdir table corresponding to + ** segments in this index on levels greater than iAbsLevel. If there is + ** at least one such segment, and it is possible to determine that all + ** such segments are smaller than nLimit bytes in size, they will be + ** promoted to level iAbsLevel. */ + sqlite3_bind_int64(pRange, 1, iAbsLevel+1); + sqlite3_bind_int64(pRange, 2, iLast); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + i64 nSize = 0, dummy; + fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); + if( nSize<=0 || nSize>nLimit ){ + /* If nSize==0, then the %_segdir.end_block field does not not + ** contain a size value. This happens if it was written by an + ** old version of FTS. In this case it is not possible to determine + ** the size of the segment, and so segment promotion does not + ** take place. */ + bOk = 0; + break; + } + bOk = 1; + } + rc = sqlite3_reset(pRange); + + if( bOk ){ + int iIdx = 0; + sqlite3_stmt *pUpdate1 = 0; + sqlite3_stmt *pUpdate2 = 0; + + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); + } + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); + } + + if( rc==SQLITE_OK ){ + + /* Loop through all %_segdir entries for segments in this index with + ** levels equal to or greater than iAbsLevel. As each entry is visited, + ** updated it to set (level = -1) and (idx = N), where N is 0 for the + ** oldest segment in the range, 1 for the next oldest, and so on. + ** + ** In other words, move all segments being promoted to level -1, + ** setting the "idx" fields as appropriate to keep them in the same + ** order. The contents of level -1 (which is never used, except + ** transiently here), will be moved back to level iAbsLevel below. */ + sqlite3_bind_int64(pRange, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + sqlite3_bind_int(pUpdate1, 1, iIdx++); + sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); + sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); + sqlite3_step(pUpdate1); + rc = sqlite3_reset(pUpdate1); + if( rc!=SQLITE_OK ){ + sqlite3_reset(pRange); + break; + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3_reset(pRange); + } + + /* Move level -1 to level iAbsLevel */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); + sqlite3_step(pUpdate2); + rc = sqlite3_reset(pUpdate2); + } + } + } + + + return rc; +} + +/* +** Merge all level iLevel segments in the database into a single +** iLevel+1 segment. Or, if iLevel<0, merge all segments into a +** single segment with a level equal to the numerically largest level +** currently present in the database. +** +** If this function is called with iLevel<0, but there is only one +** segment in the database, SQLITE_DONE is returned immediately. +** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, +** an SQLite error code is returned. +*/ +static int fts3SegmentMerge( + Fts3Table *p, + int iLangid, /* Language id to merge */ + int iIndex, /* Index in p->aIndex[] to merge */ + int iLevel /* Level to merge */ +){ + int rc; /* Return code */ + int iIdx = 0; /* Index of new segment */ + sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ + SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ + Fts3SegFilter filter; /* Segment term filter condition */ + Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ + int bIgnoreEmpty = 0; /* True to ignore empty segments */ + i64 iMaxLevel = 0; /* Max level number for this index/langid */ + + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevel=0 && iIndexnIndex ); + + rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); + if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; + + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); + if( rc!=SQLITE_OK ) goto finished; + } + + if( iLevel==FTS3_SEGCURSOR_ALL ){ + /* This call is to merge all segments in the database to a single + ** segment. The level of the new segment is equal to the numerically + ** greatest segment level currently present in the database for this + ** index. The idx of the new segment is always 0. */ + if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){ + rc = SQLITE_DONE; + goto finished; + } + iNewLevel = iMaxLevel; + bIgnoreEmpty = 1; + + }else{ + /* This call is to merge all segments at level iLevel. find the next + ** available segment index at level iLevel+1. The call to + ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to + ** a single iLevel+2 segment if necessary. */ + assert( FTS3_SEGCURSOR_PENDING==-1 ); + iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); + rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); + bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel); + } + if( rc!=SQLITE_OK ) goto finished; + + assert( csr.nSegment>0 ); + assert_fts3_nc( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); + assert_fts3_nc( + iNewLevelnLeafData); + } + } + } + + finished: + fts3SegWriterFree(pWriter); + sqlite3Fts3SegReaderFinish(&csr); + return rc; +} + + +/* +** Flush the contents of pendingTerms to level 0 segments. +*/ +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + + /* Determine the auto-incr-merge setting if unknown. If enabled, + ** estimate the number of leaf blocks of content to be written + */ + if( rc==SQLITE_OK && p->bHasStat + && p->nAutoincrmerge==0xff && p->nLeafAdd>0 + ){ + sqlite3_stmt *pStmt = 0; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); + if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; + }else if( rc==SQLITE_DONE ){ + p->nAutoincrmerge = 0; + } + rc = sqlite3_reset(pStmt); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts3PendingTermsClear(p); + } + return rc; +} + +/* +** Encode N integers as varints into a blob. +*/ +static void fts3EncodeIntArray( + int N, /* The number of integers to encode */ + u32 *a, /* The integer values */ + char *zBuf, /* Write the BLOB here */ + int *pNBuf /* Write number of bytes if zBuf[] used here */ +){ + int i, j; + for(i=j=0; iiPrevDocid. The sizes are encoded as +** a blob of varints. +*/ +static void fts3InsertDocsize( + int *pRC, /* Result code */ + Fts3Table *p, /* Table into which to insert */ + u32 *aSz /* Sizes of each column, in tokens */ +){ + char *pBlob; /* The BLOB encoding of the document size */ + int nBlob; /* Number of bytes in the BLOB */ + sqlite3_stmt *pStmt; /* Statement used to insert the encoding */ + int rc; /* Result code from subfunctions */ + + if( *pRC ) return; + pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn ); + if( pBlob==0 ){ + *pRC = SQLITE_NOMEM; + return; + } + fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob); + rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0); + if( rc ){ + sqlite3_free(pBlob); + *pRC = rc; + return; + } + sqlite3_bind_int64(pStmt, 1, p->iPrevDocid); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); +} + +/* +** Record 0 of the %_stat table contains a blob consisting of N varints, +** where N is the number of user defined columns in the fts3 table plus +** two. If nCol is the number of user defined columns, then values of the +** varints are set as follows: +** +** Varint 0: Total number of rows in the table. +** +** Varint 1..nCol: For each column, the total number of tokens stored in +** the column for all rows of the table. +** +** Varint 1+nCol: The total size, in bytes, of all text values in all +** columns of all rows of the table. +** +*/ +static void fts3UpdateDocTotals( + int *pRC, /* The result code */ + Fts3Table *p, /* Table being updated */ + u32 *aSzIns, /* Size increases */ + u32 *aSzDel, /* Size decreases */ + int nChng /* Change in the number of documents */ +){ + char *pBlob; /* Storage for BLOB written into %_stat */ + int nBlob; /* Size of BLOB written into %_stat */ + u32 *a; /* Array of integers that becomes the BLOB */ + sqlite3_stmt *pStmt; /* Statement for reading and writing */ + int i; /* Loop counter */ + int rc; /* Result code from subfunctions */ + + const int nStat = p->nColumn+2; + + if( *pRC ) return; + a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat ); + if( a==0 ){ + *pRC = SQLITE_NOMEM; + return; + } + pBlob = (char*)&a[nStat]; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); + if( rc ){ + sqlite3_free(a); + *pRC = rc; + return; + } + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + fts3DecodeIntArray(nStat, a, + sqlite3_column_blob(pStmt, 0), + sqlite3_column_bytes(pStmt, 0)); + }else{ + memset(a, 0, sizeof(u32)*(nStat) ); + } + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ){ + sqlite3_free(a); + *pRC = rc; + return; + } + if( nChng<0 && a[0]<(u32)(-nChng) ){ + a[0] = 0; + }else{ + a[0] += nChng; + } + for(i=0; inColumn+1; i++){ + u32 x = a[i+1]; + if( x+aSzIns[i] < aSzDel[i] ){ + x = 0; + }else{ + x = x + aSzIns[i] - aSzDel[i]; + } + a[i+1] = x; + } + fts3EncodeIntArray(nStat, a, pBlob, &nBlob); + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); + if( rc ){ + sqlite3_free(a); + *pRC = rc; + return; + } + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); + sqlite3_free(a); +} + +/* +** Merge the entire database so that there is one segment for each +** iIndex/iLangid combination. +*/ +static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ + int bSeenDone = 0; + int rc; + sqlite3_stmt *pAllLangid = 0; + + rc = sqlite3Fts3PendingTermsFlush(p); + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + } + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int i; + int iLangid = sqlite3_column_int(pAllLangid, 0); + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); + if( rc==SQLITE_DONE ){ + bSeenDone = 1; + rc = SQLITE_OK; + } + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + + sqlite3Fts3SegmentsClose(p); + + return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; +} + +/* +** This function is called when the user executes the following statement: +** +** INSERT INTO () VALUES('rebuild'); +** +** The entire FTS index is discarded and rebuilt. If the table is one +** created using the content=xxx option, then the new index is based on +** the current contents of the xxx table. Otherwise, it is rebuilt based +** on the contents of the %_content table. +*/ +static int fts3DoRebuild(Fts3Table *p){ + int rc; /* Return Code */ + + rc = fts3DeleteAll(p, 0); + if( rc==SQLITE_OK ){ + u32 *aSz = 0; + u32 *aSzIns = 0; + u32 *aSzDel = 0; + sqlite3_stmt *pStmt = 0; + int nEntry = 0; + + /* Compose and prepare an SQL statement to loop through the content table */ + char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + + if( rc==SQLITE_OK ){ + sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3; + aSz = (u32 *)sqlite3_malloc64(nByte); + if( aSz==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(aSz, 0, nByte); + aSzIns = &aSz[p->nColumn+1]; + aSzDel = &aSzIns[p->nColumn+1]; + } + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int iCol; + int iLangid = langidFromSelect(p, pStmt); + rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0)); + memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); + for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ + if( p->abNotindexed[iCol]==0 ){ + const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); + rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); + aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); + } + } + if( p->bHasDocsize ){ + fts3InsertDocsize(&rc, p, aSz); + } + if( rc!=SQLITE_OK ){ + sqlite3_finalize(pStmt); + pStmt = 0; + }else{ + nEntry++; + for(iCol=0; iCol<=p->nColumn; iCol++){ + aSzIns[iCol] += aSz[iCol]; + } + } + } + if( p->bFts4 ){ + fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); + } + sqlite3_free(aSz); + + if( pStmt ){ + int rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + return rc; +} + + +/* +** This function opens a cursor used to read the input data for an +** incremental merge operation. Specifically, it opens a cursor to scan +** the oldest nSeg segments (idx=0 through idx=(nSeg-1)) in absolute +** level iAbsLevel. +*/ +static int fts3IncrmergeCsr( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level to open */ + int nSeg, /* Number of segments to merge */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + int rc; /* Return Code */ + sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ + sqlite3_int64 nByte; /* Bytes allocated at pCsr->apSegment[] */ + + /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ + memset(pCsr, 0, sizeof(*pCsr)); + nByte = sizeof(Fts3SegReader *) * nSeg; + pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte); + + if( pCsr->apSegment==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->apSegment, 0, nByte); + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + } + if( rc==SQLITE_OK ){ + int i; + int rc2; + sqlite3_bind_int64(pStmt, 1, iAbsLevel); + assert( pCsr->nSegment==0 ); + for(i=0; rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW && iapSegment[i] + ); + pCsr->nSegment++; + } + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +typedef struct IncrmergeWriter IncrmergeWriter; +typedef struct NodeWriter NodeWriter; +typedef struct Blob Blob; +typedef struct NodeReader NodeReader; + +/* +** An instance of the following structure is used as a dynamic buffer +** to build up nodes or other blobs of data in. +** +** The function blobGrowBuffer() is used to extend the allocation. +*/ +struct Blob { + char *a; /* Pointer to allocation */ + int n; /* Number of valid bytes of data in a[] */ + int nAlloc; /* Allocated size of a[] (nAlloc>=n) */ +}; + +/* +** This structure is used to build up buffers containing segment b-tree +** nodes (blocks). +*/ +struct NodeWriter { + sqlite3_int64 iBlock; /* Current block id */ + Blob key; /* Last key written to the current block */ + Blob block; /* Current block image */ +}; + +/* +** An object of this type contains the state required to create or append +** to an appendable b-tree segment. +*/ +struct IncrmergeWriter { + int nLeafEst; /* Space allocated for leaf blocks */ + int nWork; /* Number of leaf pages flushed */ + sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ + int iIdx; /* Index of *output* segment in iAbsLevel+1 */ + sqlite3_int64 iStart; /* Block number of first allocated block */ + sqlite3_int64 iEnd; /* Block number of last allocated block */ + sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ + u8 bNoLeafData; /* If true, store 0 for segment size */ + NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; +}; + +/* +** An object of the following type is used to read data from a single +** FTS segment node. See the following functions: +** +** nodeReaderInit() +** nodeReaderNext() +** nodeReaderRelease() +*/ +struct NodeReader { + const char *aNode; + int nNode; + int iOff; /* Current offset within aNode[] */ + + /* Output variables. Containing the current node entry. */ + sqlite3_int64 iChild; /* Pointer to child node */ + Blob term; /* Current term */ + const char *aDoclist; /* Pointer to doclist */ + int nDoclist; /* Size of doclist in bytes */ +}; + +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if the allocation at pBlob->a is not already at least nMin +** bytes in size, extend (realloc) it to be so. +** +** If an OOM error occurs, set *pRc to SQLITE_NOMEM and leave pBlob->a +** unmodified. Otherwise, if the allocation succeeds, update pBlob->nAlloc +** to reflect the new size of the pBlob->a[] buffer. +*/ +static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ + if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ + int nAlloc = nMin; + char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc); + if( a ){ + pBlob->nAlloc = nAlloc; + pBlob->a = a; + }else{ + *pRc = SQLITE_NOMEM; + } + } +} + +/* +** Attempt to advance the node-reader object passed as the first argument to +** the next entry on the node. +** +** Return an error code if an error occurs (SQLITE_NOMEM is possible). +** Otherwise return SQLITE_OK. If there is no next entry on the node +** (e.g. because the current entry is the last) set NodeReader->aNode to +** NULL to indicate EOF. Otherwise, populate the NodeReader structure output +** variables for the new entry. +*/ +static int nodeReaderNext(NodeReader *p){ + int bFirst = (p->term.n==0); /* True for first term on the node */ + int nPrefix = 0; /* Bytes to copy from previous term */ + int nSuffix = 0; /* Bytes to append to the prefix */ + int rc = SQLITE_OK; /* Return code */ + + assert( p->aNode ); + if( p->iChild && bFirst==0 ) p->iChild++; + if( p->iOff>=p->nNode ){ + /* EOF */ + p->aNode = 0; + }else{ + if( bFirst==0 ){ + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); + } + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); + + if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){ + return FTS_CORRUPT_VTAB; + } + blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); + if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){ + memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); + p->term.n = nPrefix+nSuffix; + p->iOff += nSuffix; + if( p->iChild==0 ){ + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); + if( (p->nNode-p->iOff)nDoclist ){ + return FTS_CORRUPT_VTAB; + } + p->aDoclist = &p->aNode[p->iOff]; + p->iOff += p->nDoclist; + } + } + } + + assert_fts3_nc( p->iOff<=p->nNode ); + return rc; +} + +/* +** Release all dynamic resources held by node-reader object *p. +*/ +static void nodeReaderRelease(NodeReader *p){ + sqlite3_free(p->term.a); +} + +/* +** Initialize a node-reader object to read the node in buffer aNode/nNode. +** +** If successful, SQLITE_OK is returned and the NodeReader object set to +** point to the first entry on the node (if any). Otherwise, an SQLite +** error code is returned. +*/ +static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){ + memset(p, 0, sizeof(NodeReader)); + p->aNode = aNode; + p->nNode = nNode; + + /* Figure out if this is a leaf or an internal node. */ + if( aNode && aNode[0] ){ + /* An internal node. */ + p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); + }else{ + p->iOff = 1; + } + + return aNode ? nodeReaderNext(p) : SQLITE_OK; +} + +/* +** This function is called while writing an FTS segment each time a leaf o +** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed +** to be greater than the largest key on the node just written, but smaller +** than or equal to the first key that will be written to the next leaf +** node. +** +** The block id of the leaf node just written to disk may be found in +** (pWriter->aNodeWriter[0].iBlock) when this function is called. +*/ +static int fts3IncrmergePush( + Fts3Table *p, /* Fts3 table handle */ + IncrmergeWriter *pWriter, /* Writer object */ + const char *zTerm, /* Term to write to internal node */ + int nTerm /* Bytes at zTerm */ +){ + sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; + int iLayer; + + assert( nTerm>0 ); + for(iLayer=1; ALWAYS(iLayeraNodeWriter[iLayer]; + int rc = SQLITE_OK; + int nPrefix; + int nSuffix; + int nSpace; + + /* Figure out how much space the key will consume if it is written to + ** the current node of layer iLayer. Due to the prefix compression, + ** the space required changes depending on which node the key is to + ** be added to. */ + nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + + if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ + /* If the current node of layer iLayer contains zero keys, or if adding + ** the key to it will not cause it to grow to larger than nNodeSize + ** bytes in size, write the key here. */ + + Blob *pBlk = &pNode->block; + if( pBlk->n==0 ){ + blobGrowBuffer(pBlk, p->nNodeSize, &rc); + if( rc==SQLITE_OK ){ + pBlk->a[0] = (char)iLayer; + pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr); + } + } + blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc); + blobGrowBuffer(&pNode->key, nTerm, &rc); + + if( rc==SQLITE_OK ){ + if( pNode->key.n ){ + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); + } + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); + assert( nPrefix+nSuffix<=nTerm ); + assert( nPrefix>=0 ); + memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); + pBlk->n += nSuffix; + + memcpy(pNode->key.a, zTerm, nTerm); + pNode->key.n = nTerm; + } + }else{ + /* Otherwise, flush the current node of layer iLayer to disk. + ** Then allocate a new, empty sibling node. The key will be written + ** into the parent of this node. */ + rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); + + assert( pNode->block.nAlloc>=p->nNodeSize ); + pNode->block.a[0] = (char)iLayer; + pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); + + iNextPtr = pNode->iBlock; + pNode->iBlock++; + pNode->key.n = 0; + } + + if( rc!=SQLITE_OK || iNextPtr==0 ) return rc; + iPtr = iNextPtr; + } + + assert( 0 ); + return 0; +} + +/* +** Append a term and (optionally) doclist to the FTS segment node currently +** stored in blob *pNode. The node need not contain any terms, but the +** header must be written before this function is called. +** +** A node header is a single 0x00 byte for a leaf node, or a height varint +** followed by the left-hand-child varint for an internal node. +** +** The term to be appended is passed via arguments zTerm/nTerm. For a +** leaf node, the doclist is passed as aDoclist/nDoclist. For an internal +** node, both aDoclist and nDoclist must be passed 0. +** +** If the size of the value in blob pPrev is zero, then this is the first +** term written to the node. Otherwise, pPrev contains a copy of the +** previous term. Before this function returns, it is updated to contain a +** copy of zTerm/nTerm. +** +** It is assumed that the buffer associated with pNode is already large +** enough to accommodate the new entry. The buffer associated with pPrev +** is extended by this function if requrired. +** +** If an error (i.e. OOM condition) occurs, an SQLite error code is +** returned. Otherwise, SQLITE_OK. +*/ +static int fts3AppendToNode( + Blob *pNode, /* Current node image to append to */ + Blob *pPrev, /* Buffer containing previous term written */ + const char *zTerm, /* New term to write */ + int nTerm, /* Size of zTerm in bytes */ + const char *aDoclist, /* Doclist (or NULL) to write */ + int nDoclist /* Size of aDoclist in bytes */ +){ + int rc = SQLITE_OK; /* Return code */ + int bFirst = (pPrev->n==0); /* True if this is the first term written */ + int nPrefix; /* Size of term prefix in bytes */ + int nSuffix; /* Size of term suffix in bytes */ + + /* Node must have already been started. There must be a doclist for a + ** leaf node, and there must not be a doclist for an internal node. */ + assert( pNode->n>0 ); + assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) ); + + blobGrowBuffer(pPrev, nTerm, &rc); + if( rc!=SQLITE_OK ) return rc; + assert( pPrev!=0 ); + assert( pPrev->a!=0 ); + + nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + memcpy(pPrev->a, zTerm, nTerm); + pPrev->n = nTerm; + + if( bFirst==0 ){ + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); + } + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); + memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix); + pNode->n += nSuffix; + + if( aDoclist ){ + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); + memcpy(&pNode->a[pNode->n], aDoclist, nDoclist); + pNode->n += nDoclist; + } + + assert( pNode->n<=pNode->nAlloc ); + + return SQLITE_OK; +} + +/* +** Append the current term and doclist pointed to by cursor pCsr to the +** appendable b-tree segment opened for writing by pWriter. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int fts3IncrmergeAppend( + Fts3Table *p, /* Fts3 table handle */ + IncrmergeWriter *pWriter, /* Writer object */ + Fts3MultiSegReader *pCsr /* Cursor containing term and doclist */ +){ + const char *zTerm = pCsr->zTerm; + int nTerm = pCsr->nTerm; + const char *aDoclist = pCsr->aDoclist; + int nDoclist = pCsr->nDoclist; + int rc = SQLITE_OK; /* Return code */ + int nSpace; /* Total space in bytes required on leaf */ + int nPrefix; /* Size of prefix shared with previous term */ + int nSuffix; /* Size of suffix (nTerm - nPrefix) */ + NodeWriter *pLeaf; /* Object used to write leaf nodes */ + + pLeaf = &pWriter->aNodeWriter[0]; + nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; + + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; + + /* If the current block is not empty, and if adding this term/doclist + ** to the current block would make it larger than Fts3Table.nNodeSize bytes, + ** and if there is still room for another leaf page, write this block out to + ** the database. */ + if( pLeaf->block.n>0 + && (pLeaf->block.n + nSpace)>p->nNodeSize + && pLeaf->iBlock < (pWriter->iStart + pWriter->nLeafEst) + ){ + rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); + pWriter->nWork++; + + /* Add the current term to the parent node. The term added to the + ** parent must: + ** + ** a) be greater than the largest term on the leaf node just written + ** to the database (still available in pLeaf->key), and + ** + ** b) be less than or equal to the term about to be added to the new + ** leaf node (zTerm/nTerm). + ** + ** In other words, it must be the prefix of zTerm 1 byte longer than + ** the common prefix (if any) of zTerm and pWriter->zTerm. + */ + if( rc==SQLITE_OK ){ + rc = fts3IncrmergePush(p, pWriter, zTerm, nPrefix+1); + } + + /* Advance to the next output block */ + pLeaf->iBlock++; + pLeaf->key.n = 0; + pLeaf->block.n = 0; + + nSuffix = nTerm; + nSpace = 1; + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; + } + + pWriter->nLeafData += nSpace; + blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); + if( rc==SQLITE_OK ){ + if( pLeaf->block.n==0 ){ + pLeaf->block.n = 1; + pLeaf->block.a[0] = '\0'; + } + rc = fts3AppendToNode( + &pLeaf->block, &pLeaf->key, zTerm, nTerm, aDoclist, nDoclist + ); + } + + return rc; +} + +/* +** This function is called to release all dynamic resources held by the +** merge-writer object pWriter, and if no error has occurred, to flush +** all outstanding node buffers held by pWriter to disk. +** +** If *pRc is not SQLITE_OK when this function is called, then no attempt +** is made to write any data to disk. Instead, this function serves only +** to release outstanding resources. +** +** Otherwise, if *pRc is initially SQLITE_OK and an error occurs while +** flushing buffers to disk, *pRc is set to an SQLite error code before +** returning. +*/ +static void fts3IncrmergeRelease( + Fts3Table *p, /* FTS3 table handle */ + IncrmergeWriter *pWriter, /* Merge-writer object */ + int *pRc /* IN/OUT: Error code */ +){ + int i; /* Used to iterate through non-root layers */ + int iRoot; /* Index of root in pWriter->aNodeWriter */ + NodeWriter *pRoot; /* NodeWriter for root node */ + int rc = *pRc; /* Error code */ + + /* Set iRoot to the index in pWriter->aNodeWriter[] of the output segment + ** root node. If the segment fits entirely on a single leaf node, iRoot + ** will be set to 0. If the root node is the parent of the leaves, iRoot + ** will be 1. And so on. */ + for(iRoot=FTS_MAX_APPENDABLE_HEIGHT-1; iRoot>=0; iRoot--){ + NodeWriter *pNode = &pWriter->aNodeWriter[iRoot]; + if( pNode->block.n>0 ) break; + assert( *pRc || pNode->block.nAlloc==0 ); + assert( *pRc || pNode->key.nAlloc==0 ); + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); + } + + /* Empty output segment. This is a no-op. */ + if( iRoot<0 ) return; + + /* The entire output segment fits on a single node. Normally, this means + ** the node would be stored as a blob in the "root" column of the %_segdir + ** table. However, this is not permitted in this case. The problem is that + ** space has already been reserved in the %_segments table, and so the + ** start_block and end_block fields of the %_segdir table must be populated. + ** And, by design or by accident, released versions of FTS cannot handle + ** segments that fit entirely on the root node with start_block!=0. + ** + ** Instead, create a synthetic root node that contains nothing but a + ** pointer to the single content node. So that the segment consists of a + ** single leaf and a single interior (root) node. + ** + ** Todo: Better might be to defer allocating space in the %_segments + ** table until we are sure it is needed. + */ + if( iRoot==0 ){ + Blob *pBlock = &pWriter->aNodeWriter[1].block; + blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc); + if( rc==SQLITE_OK ){ + pBlock->a[0] = 0x01; + pBlock->n = 1 + sqlite3Fts3PutVarint( + &pBlock->a[1], pWriter->aNodeWriter[0].iBlock + ); + } + iRoot = 1; + } + pRoot = &pWriter->aNodeWriter[iRoot]; + + /* Flush all currently outstanding nodes to disk. */ + for(i=0; iaNodeWriter[i]; + if( pNode->block.n>0 && rc==SQLITE_OK ){ + rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); + } + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); + } + + /* Write the %_segdir record. */ + if( rc==SQLITE_OK ){ + rc = fts3WriteSegdir(p, + pWriter->iAbsLevel+1, /* level */ + pWriter->iIdx, /* idx */ + pWriter->iStart, /* start_block */ + pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ + pWriter->iEnd, /* end_block */ + (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */ + pRoot->block.a, pRoot->block.n /* root */ + ); + } + sqlite3_free(pRoot->block.a); + sqlite3_free(pRoot->key.a); + + *pRc = rc; +} + +/* +** Compare the term in buffer zLhs (size in bytes nLhs) with that in +** zRhs (size in bytes nRhs) using memcmp. If one term is a prefix of +** the other, it is considered to be smaller than the other. +** +** Return -ve if zLhs is smaller than zRhs, 0 if it is equal, or +ve +** if it is greater. +*/ +static int fts3TermCmp( + const char *zLhs, int nLhs, /* LHS of comparison */ + const char *zRhs, int nRhs /* RHS of comparison */ +){ + int nCmp = MIN(nLhs, nRhs); + int res; + + if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){ + res = memcmp(zLhs, zRhs, nCmp); + }else{ + res = 0; + } + if( res==0 ) res = nLhs - nRhs; + + return res; +} + + +/* +** Query to see if the entry in the %_segments table with blockid iEnd is +** NULL. If no error occurs and the entry is NULL, set *pbRes 1 before +** returning. Otherwise, set *pbRes to 0. +** +** Or, if an error occurs while querying the database, return an SQLite +** error code. The final value of *pbRes is undefined in this case. +** +** This is used to test if a segment is an "appendable" segment. If it +** is, then a NULL entry has been inserted into the %_segments table +** with blockid %_segdir.end_block. +*/ +static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){ + int bRes = 0; /* Result to set *pbRes to */ + sqlite3_stmt *pCheck = 0; /* Statement to query database with */ + int rc; /* Return code */ + + rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pCheck, 1, iEnd); + if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1; + rc = sqlite3_reset(pCheck); + } + + *pbRes = bRes; + return rc; +} + +/* +** This function is called when initializing an incremental-merge operation. +** It checks if the existing segment with index value iIdx at absolute level +** (iAbsLevel+1) can be appended to by the incremental merge. If it can, the +** merge-writer object *pWriter is initialized to write to it. +** +** An existing segment can be appended to by an incremental merge if: +** +** * It was initially created as an appendable segment (with all required +** space pre-allocated), and +** +** * The first key read from the input (arguments zKey and nKey) is +** greater than the largest key currently stored in the potential +** output segment. +*/ +static int fts3IncrmergeLoad( + Fts3Table *p, /* Fts3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + int iIdx, /* Index of candidate output segment */ + const char *zKey, /* First key to write */ + int nKey, /* Number of bytes in nKey */ + IncrmergeWriter *pWriter /* Populate this object */ +){ + int rc; /* Return code */ + sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ + + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0); + if( rc==SQLITE_OK ){ + sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ + sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ + sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ + const char *aRoot = 0; /* Pointer to %_segdir.root buffer */ + int nRoot = 0; /* Size of aRoot[] in bytes */ + int rc2; /* Return code from sqlite3_reset() */ + int bAppendable = 0; /* Set to true if segment is appendable */ + + /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */ + sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); + sqlite3_bind_int(pSelect, 2, iIdx); + if( sqlite3_step(pSelect)==SQLITE_ROW ){ + iStart = sqlite3_column_int64(pSelect, 1); + iLeafEnd = sqlite3_column_int64(pSelect, 2); + fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); + if( pWriter->nLeafData<0 ){ + pWriter->nLeafData = pWriter->nLeafData * -1; + } + pWriter->bNoLeafData = (pWriter->nLeafData==0); + nRoot = sqlite3_column_bytes(pSelect, 4); + aRoot = sqlite3_column_blob(pSelect, 4); + if( aRoot==0 ){ + sqlite3_reset(pSelect); + return nRoot ? SQLITE_NOMEM : FTS_CORRUPT_VTAB; + } + }else{ + return sqlite3_reset(pSelect); + } + + /* Check for the zero-length marker in the %_segments table */ + rc = fts3IsAppendable(p, iEnd, &bAppendable); + + /* Check that zKey/nKey is larger than the largest key the candidate */ + if( rc==SQLITE_OK && bAppendable ){ + char *aLeaf = 0; + int nLeaf = 0; + + rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); + if( rc==SQLITE_OK ){ + NodeReader reader; + for(rc = nodeReaderInit(&reader, aLeaf, nLeaf); + rc==SQLITE_OK && reader.aNode; + rc = nodeReaderNext(&reader) + ){ + assert( reader.aNode ); + } + if( fts3TermCmp(zKey, nKey, reader.term.a, reader.term.n)<=0 ){ + bAppendable = 0; + } + nodeReaderRelease(&reader); + } + sqlite3_free(aLeaf); + } + + if( rc==SQLITE_OK && bAppendable ){ + /* It is possible to append to this segment. Set up the IncrmergeWriter + ** object to do so. */ + int i; + int nHeight = (int)aRoot[0]; + NodeWriter *pNode; + if( nHeight<1 || nHeight>=FTS_MAX_APPENDABLE_HEIGHT ){ + sqlite3_reset(pSelect); + return FTS_CORRUPT_VTAB; + } + + pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; + pWriter->iStart = iStart; + pWriter->iEnd = iEnd; + pWriter->iAbsLevel = iAbsLevel; + pWriter->iIdx = iIdx; + + for(i=nHeight+1; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; + } + + pNode = &pWriter->aNodeWriter[nHeight]; + pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight; + blobGrowBuffer(&pNode->block, + MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc + ); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aRoot, nRoot); + pNode->block.n = nRoot; + memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING); + } + + for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ + NodeReader reader; + memset(&reader, 0, sizeof(reader)); + pNode = &pWriter->aNodeWriter[i]; + + if( pNode->block.a){ + rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n); + while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); + blobGrowBuffer(&pNode->key, reader.term.n, &rc); + if( rc==SQLITE_OK ){ + assert_fts3_nc( reader.term.n>0 || reader.aNode==0 ); + if( reader.term.n>0 ){ + memcpy(pNode->key.a, reader.term.a, reader.term.n); + } + pNode->key.n = reader.term.n; + if( i>0 ){ + char *aBlock = 0; + int nBlock = 0; + pNode = &pWriter->aNodeWriter[i-1]; + pNode->iBlock = reader.iChild; + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); + blobGrowBuffer(&pNode->block, + MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc + ); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aBlock, nBlock); + pNode->block.n = nBlock; + memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); + } + sqlite3_free(aBlock); + } + } + } + nodeReaderRelease(&reader); + } + } + + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +/* +** Determine the largest segment index value that exists within absolute +** level iAbsLevel+1. If no error occurs, set *piIdx to this value plus +** one before returning SQLITE_OK. Or, if there are no segments at all +** within level iAbsLevel, set *piIdx to zero. +** +** If an error occurs, return an SQLite error code. The final value of +** *piIdx is undefined in this case. +*/ +static int fts3IncrmergeOutputIdx( + Fts3Table *p, /* FTS Table handle */ + sqlite3_int64 iAbsLevel, /* Absolute index of input segments */ + int *piIdx /* OUT: Next free index at iAbsLevel+1 */ +){ + int rc; + sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ + + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); + sqlite3_step(pOutputIdx); + *piIdx = sqlite3_column_int(pOutputIdx, 0); + rc = sqlite3_reset(pOutputIdx); + } + + return rc; +} + +/* +** Allocate an appendable output segment on absolute level iAbsLevel+1 +** with idx value iIdx. +** +** In the %_segdir table, a segment is defined by the values in three +** columns: +** +** start_block +** leaves_end_block +** end_block +** +** When an appendable segment is allocated, it is estimated that the +** maximum number of leaf blocks that may be required is the sum of the +** number of leaf blocks consumed by the input segments, plus the number +** of input segments, multiplied by two. This value is stored in stack +** variable nLeafEst. +** +** A total of 16*nLeafEst blocks are allocated when an appendable segment +** is created ((1 + end_block - start_block)==16*nLeafEst). The contiguous +** array of leaf nodes starts at the first block allocated. The array +** of interior nodes that are parents of the leaf nodes start at block +** (start_block + (1 + end_block - start_block) / 16). And so on. +** +** In the actual code below, the value "16" is replaced with the +** pre-processor macro FTS_MAX_APPENDABLE_HEIGHT. +*/ +static int fts3IncrmergeWriter( + Fts3Table *p, /* Fts3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + int iIdx, /* Index of new output segment */ + Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */ + IncrmergeWriter *pWriter /* Populate this object */ +){ + int rc; /* Return Code */ + int i; /* Iterator variable */ + int nLeafEst = 0; /* Blocks allocated for leaf nodes */ + sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ + sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ + + /* Calculate nLeafEst. */ + rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pLeafEst, 1, iAbsLevel); + sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); + if( SQLITE_ROW==sqlite3_step(pLeafEst) ){ + nLeafEst = sqlite3_column_int(pLeafEst, 0); + } + rc = sqlite3_reset(pLeafEst); + } + if( rc!=SQLITE_OK ) return rc; + + /* Calculate the first block to use in the output segment */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){ + pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0); + pWriter->iEnd = pWriter->iStart - 1; + pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT; + } + rc = sqlite3_reset(pFirstBlock); + } + if( rc!=SQLITE_OK ) return rc; + + /* Insert the marker in the %_segments table to make sure nobody tries + ** to steal the space just allocated. This is also used to identify + ** appendable segments. */ + rc = fts3WriteSegment(p, pWriter->iEnd, 0, 0); + if( rc!=SQLITE_OK ) return rc; + + pWriter->iAbsLevel = iAbsLevel; + pWriter->nLeafEst = nLeafEst; + pWriter->iIdx = iIdx; + + /* Set up the array of NodeWriter objects */ + for(i=0; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; + } + return SQLITE_OK; +} + +/* +** Remove an entry from the %_segdir table. This involves running the +** following two statements: +** +** DELETE FROM %_segdir WHERE level = :iAbsLevel AND idx = :iIdx +** UPDATE %_segdir SET idx = idx - 1 WHERE level = :iAbsLevel AND idx > :iIdx +** +** The DELETE statement removes the specific %_segdir level. The UPDATE +** statement ensures that the remaining segments have contiguously allocated +** idx values. +*/ +static int fts3RemoveSegdirEntry( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level to delete from */ + int iIdx /* Index of %_segdir entry to delete */ +){ + int rc; /* Return code */ + sqlite3_stmt *pDelete = 0; /* DELETE statement */ + + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, iAbsLevel); + sqlite3_bind_int(pDelete, 2, iIdx); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + + return rc; +} + +/* +** One or more segments have just been removed from absolute level iAbsLevel. +** Update the 'idx' values of the remaining segments in the level so that +** the idx values are a contiguous sequence starting from 0. +*/ +static int fts3RepackSegdirLevel( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel /* Absolute level to repack */ +){ + int rc; /* Return code */ + int *aIdx = 0; /* Array of remaining idx values */ + int nIdx = 0; /* Valid entries in aIdx[] */ + int nAlloc = 0; /* Allocated size of aIdx[] */ + int i; /* Iterator variable */ + sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ + sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ + + rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int64(pSelect, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pSelect) ){ + if( nIdx>=nAlloc ){ + int *aNew; + nAlloc += 16; + aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int)); + if( !aNew ){ + rc = SQLITE_NOMEM; + break; + } + aIdx = aNew; + } + aIdx[nIdx++] = sqlite3_column_int(pSelect, 0); + } + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0); + } + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pUpdate, 2, iAbsLevel); + } + + assert( p->bIgnoreSavepoint==0 ); + p->bIgnoreSavepoint = 1; + for(i=0; rc==SQLITE_OK && ibIgnoreSavepoint = 0; + + sqlite3_free(aIdx); + return rc; +} + +static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){ + pNode->a[0] = (char)iHeight; + if( iChild ){ + assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) ); + pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild); + }else{ + assert( pNode->nAlloc>=1 ); + pNode->n = 1; + } +} + +/* +** The first two arguments are a pointer to and the size of a segment b-tree +** node. The node may be a leaf or an internal node. +** +** This function creates a new node image in blob object *pNew by copying +** all terms that are greater than or equal to zTerm/nTerm (for leaf nodes) +** or greater than zTerm/nTerm (for internal nodes) from aNode/nNode. +*/ +static int fts3TruncateNode( + const char *aNode, /* Current node image */ + int nNode, /* Size of aNode in bytes */ + Blob *pNew, /* OUT: Write new node image here */ + const char *zTerm, /* Omit all terms smaller than this */ + int nTerm, /* Size of zTerm in bytes */ + sqlite3_int64 *piBlock /* OUT: Block number in next layer down */ +){ + NodeReader reader; /* Reader object */ + Blob prev = {0, 0, 0}; /* Previous term written to new node */ + int rc = SQLITE_OK; /* Return code */ + int bLeaf; /* True for a leaf node */ + + if( nNode<1 ) return FTS_CORRUPT_VTAB; + bLeaf = aNode[0]=='\0'; + + /* Allocate required output space */ + blobGrowBuffer(pNew, nNode, &rc); + if( rc!=SQLITE_OK ) return rc; + pNew->n = 0; + + /* Populate new node buffer */ + for(rc = nodeReaderInit(&reader, aNode, nNode); + rc==SQLITE_OK && reader.aNode; + rc = nodeReaderNext(&reader) + ){ + if( pNew->n==0 ){ + int res = fts3TermCmp(reader.term.a, reader.term.n, zTerm, nTerm); + if( res<0 || (bLeaf==0 && res==0) ) continue; + fts3StartNode(pNew, (int)aNode[0], reader.iChild); + *piBlock = reader.iChild; + } + rc = fts3AppendToNode( + pNew, &prev, reader.term.a, reader.term.n, + reader.aDoclist, reader.nDoclist + ); + if( rc!=SQLITE_OK ) break; + } + if( pNew->n==0 ){ + fts3StartNode(pNew, (int)aNode[0], reader.iChild); + *piBlock = reader.iChild; + } + assert( pNew->n<=pNew->nAlloc ); + + nodeReaderRelease(&reader); + sqlite3_free(prev.a); + return rc; +} + +/* +** Remove all terms smaller than zTerm/nTerm from segment iIdx in absolute +** level iAbsLevel. This may involve deleting entries from the %_segments +** table, and modifying existing entries in both the %_segments and %_segdir +** tables. +** +** SQLITE_OK is returned if the segment is updated successfully. Or an +** SQLite error code otherwise. +*/ +static int fts3TruncateSegment( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ + int iIdx, /* Index within level of segment to modify */ + const char *zTerm, /* Remove terms smaller than this */ + int nTerm /* Number of bytes in buffer zTerm */ +){ + int rc = SQLITE_OK; /* Return code */ + Blob root = {0,0,0}; /* New root page image */ + Blob block = {0,0,0}; /* Buffer used for any other block */ + sqlite3_int64 iBlock = 0; /* Block id */ + sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ + sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ + sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ + + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0); + if( rc==SQLITE_OK ){ + int rc2; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pFetch, 1, iAbsLevel); + sqlite3_bind_int(pFetch, 2, iIdx); + if( SQLITE_ROW==sqlite3_step(pFetch) ){ + const char *aRoot = sqlite3_column_blob(pFetch, 4); + int nRoot = sqlite3_column_bytes(pFetch, 4); + iOldStart = sqlite3_column_int64(pFetch, 1); + rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock); + } + rc2 = sqlite3_reset(pFetch); + if( rc==SQLITE_OK ) rc = rc2; + } + + while( rc==SQLITE_OK && iBlock ){ + char *aBlock = 0; + int nBlock = 0; + iNewStart = iBlock; + + rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); + if( rc==SQLITE_OK ){ + rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock); + } + if( rc==SQLITE_OK ){ + rc = fts3WriteSegment(p, iNewStart, block.a, block.n); + } + sqlite3_free(aBlock); + } + + /* Variable iNewStart now contains the first valid leaf node. */ + if( rc==SQLITE_OK && iNewStart ){ + sqlite3_stmt *pDel = 0; + rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDel, 1, iOldStart); + sqlite3_bind_int64(pDel, 2, iNewStart-1); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_stmt *pChomp = 0; + rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pChomp, 1, iNewStart); + sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); + sqlite3_bind_int64(pChomp, 3, iAbsLevel); + sqlite3_bind_int(pChomp, 4, iIdx); + sqlite3_step(pChomp); + rc = sqlite3_reset(pChomp); + sqlite3_bind_null(pChomp, 2); + } + } + + sqlite3_free(root.a); + sqlite3_free(block.a); + return rc; +} + +/* +** This function is called after an incrmental-merge operation has run to +** merge (or partially merge) two or more segments from absolute level +** iAbsLevel. +** +** Each input segment is either removed from the db completely (if all of +** its data was copied to the output segment by the incrmerge operation) +** or modified in place so that it no longer contains those entries that +** have been duplicated in the output segment. +*/ +static int fts3IncrmergeChomp( + Fts3Table *p, /* FTS table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level containing segments */ + Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */ + int *pnRem /* Number of segments not deleted */ +){ + int i; + int nRem = 0; + int rc = SQLITE_OK; + + for(i=pCsr->nSegment-1; i>=0 && rc==SQLITE_OK; i--){ + Fts3SegReader *pSeg = 0; + int j; + + /* Find the Fts3SegReader object with Fts3SegReader.iIdx==i. It is hiding + ** somewhere in the pCsr->apSegment[] array. */ + for(j=0; ALWAYS(jnSegment); j++){ + pSeg = pCsr->apSegment[j]; + if( pSeg->iIdx==i ) break; + } + assert( jnSegment && pSeg->iIdx==i ); + + if( pSeg->aNode==0 ){ + /* Seg-reader is at EOF. Remove the entire input segment. */ + rc = fts3DeleteSegment(p, pSeg); + if( rc==SQLITE_OK ){ + rc = fts3RemoveSegdirEntry(p, iAbsLevel, pSeg->iIdx); + } + *pnRem = 0; + }else{ + /* The incremental merge did not copy all the data from this + ** segment to the upper level. The segment is modified in place + ** so that it contains no keys smaller than zTerm/nTerm. */ + const char *zTerm = pSeg->zTerm; + int nTerm = pSeg->nTerm; + rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm); + nRem++; + } + } + + if( rc==SQLITE_OK && nRem!=pCsr->nSegment ){ + rc = fts3RepackSegdirLevel(p, iAbsLevel); + } + + *pnRem = nRem; + return rc; +} + +/* +** Store an incr-merge hint in the database. +*/ +static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ + sqlite3_stmt *pReplace = 0; + int rc; /* Return code */ + + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); + sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); + } + + return rc; +} + +/* +** Load an incr-merge hint from the database. The incr-merge hint, if one +** exists, is stored in the rowid==1 row of the %_stat table. +** +** If successful, populate blob *pHint with the value read from the %_stat +** table and return SQLITE_OK. Otherwise, if an error occurs, return an +** SQLite error code. +*/ +static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ + sqlite3_stmt *pSelect = 0; + int rc; + + pHint->n = 0; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + const char *aHint = sqlite3_column_blob(pSelect, 0); + int nHint = sqlite3_column_bytes(pSelect, 0); + if( aHint ){ + blobGrowBuffer(pHint, nHint, &rc); + if( rc==SQLITE_OK ){ + if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint); + pHint->n = nHint; + } + } + } + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, append an entry to the hint stored in blob *pHint. Each entry +** consists of two varints, the absolute level number of the input segments +** and the number of input segments. +** +** If successful, leave *pRc set to SQLITE_OK and return. If an error occurs, +** set *pRc to an SQLite error code before returning. +*/ +static void fts3IncrmergeHintPush( + Blob *pHint, /* Hint blob to append to */ + i64 iAbsLevel, /* First varint to store in hint */ + int nInput, /* Second varint to store in hint */ + int *pRc /* IN/OUT: Error code */ +){ + blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc); + if( *pRc==SQLITE_OK ){ + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); + } +} + +/* +** Read the last entry (most recently pushed) from the hint blob *pHint +** and then remove the entry. Write the two values read to *piAbsLevel and +** *pnInput before returning. +** +** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does +** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB. +*/ +static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ + const int nHint = pHint->n; + int i; + + i = pHint->n-1; + if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + if( i==0 ) return FTS_CORRUPT_VTAB; + i--; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + + pHint->n = i; + i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); + i += fts3GetVarint32(&pHint->a[i], pnInput); + assert( i<=nHint ); + if( i!=nHint ) return FTS_CORRUPT_VTAB; + + return SQLITE_OK; +} + + +/* +** Attempt an incremental merge that writes nMerge leaf blocks. +** +** Incremental merges happen nMin segments at a time. The segments +** to be merged are the nMin oldest segments (the ones with the smallest +** values for the _segdir.idx field) in the highest level that contains +** at least nMin segments. Multiple merges might occur in an attempt to +** write the quota of nMerge leaf blocks. +*/ +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ + int rc; /* Return code */ + int nRem = nMerge; /* Number of leaf pages yet to be written */ + Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ + Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ + IncrmergeWriter *pWriter; /* Writer object */ + int nSeg = 0; /* Number of input segments */ + sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ + Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ + int bDirtyHint = 0; /* True if blob 'hint' has been modified */ + + /* Allocate space for the cursor, filter and writer objects */ + const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); + pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc); + if( !pWriter ) return SQLITE_NOMEM; + pFilter = (Fts3SegFilter *)&pWriter[1]; + pCsr = (Fts3MultiSegReader *)&pFilter[1]; + + rc = fts3IncrmergeHintLoad(p, &hint); + while( rc==SQLITE_OK && nRem>0 ){ + const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; + sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ + int bUseHint = 0; /* True if attempting to append */ + int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ + + /* Search the %_segdir table for the absolute level with the smallest + ** relative level number that contains at least nMin segments, if any. + ** If one is found, set iAbsLevel to the absolute level number and + ** nSeg to nMin. If no level with at least nMin segments can be found, + ** set nSeg to -1. + */ + rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); + sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); + if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ + iAbsLevel = sqlite3_column_int64(pFindLevel, 0); + nSeg = sqlite3_column_int(pFindLevel, 1); + assert( nSeg>=2 ); + }else{ + nSeg = -1; + } + rc = sqlite3_reset(pFindLevel); + + /* If the hint read from the %_stat table is not empty, check if the + ** last entry in it specifies a relative level smaller than or equal + ** to the level identified by the block above (if any). If so, this + ** iteration of the loop will work on merging at the hinted level. + */ + if( rc==SQLITE_OK && hint.n ){ + int nHint = hint.n; + sqlite3_int64 iHintAbsLevel = 0; /* Hint level */ + int nHintSeg = 0; /* Hint number of segments */ + + rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); + if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ + /* Based on the scan in the block above, it is known that there + ** are no levels with a relative level smaller than that of + ** iAbsLevel with more than nSeg segments, or if nSeg is -1, + ** no levels with more than nMin segments. Use this to limit the + ** value of nHintSeg to avoid a large memory allocation in case the + ** merge-hint is corrupt*/ + iAbsLevel = iHintAbsLevel; + nSeg = MIN(MAX(nMin,nSeg), nHintSeg); + bUseHint = 1; + bDirtyHint = 1; + }else{ + /* This undoes the effect of the HintPop() above - so that no entry + ** is removed from the hint blob. */ + hint.n = nHint; + } + } + + /* If nSeg is less that zero, then there is no level with at least + ** nMin segments and no hint in the %_stat table. No work to do. + ** Exit early in this case. */ + if( nSeg<=0 ) break; + + assert( nMod<=0x7FFFFFFF ); + if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){ + rc = FTS_CORRUPT_VTAB; + break; + } + + /* Open a cursor to iterate through the contents of the oldest nSeg + ** indexes of absolute level iAbsLevel. If this cursor is opened using + ** the 'hint' parameters, it is possible that there are less than nSeg + ** segments available in level iAbsLevel. In this case, no work is + ** done on iAbsLevel - fall through to the next iteration of the loop + ** to start work on some other level. */ + memset(pWriter, 0, nAlloc); + pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; + + if( rc==SQLITE_OK ){ + rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); + assert( bUseHint==1 || bUseHint==0 ); + if( iIdx==0 || (bUseHint && iIdx==1) ){ + int bIgnore = 0; + rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); + if( bIgnore ){ + pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; + } + } + } + + if( rc==SQLITE_OK ){ + rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); + } + if( SQLITE_OK==rc && pCsr->nSegment==nSeg + && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) + ){ + int bEmpty = 0; + rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( rc==SQLITE_OK ){ + bEmpty = 1; + }else if( rc!=SQLITE_ROW ){ + sqlite3Fts3SegReaderFinish(pCsr); + break; + } + if( bUseHint && iIdx>0 ){ + const char *zKey = pCsr->zTerm; + int nKey = pCsr->nTerm; + rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); + }else{ + rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); + } + + if( rc==SQLITE_OK && pWriter->nLeafEst ){ + fts3LogMerge(nSeg, iAbsLevel); + if( bEmpty==0 ){ + do { + rc = fts3IncrmergeAppend(p, pWriter, pCsr); + if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; + }while( rc==SQLITE_ROW ); + } + + /* Update or delete the input segments */ + if( rc==SQLITE_OK ){ + nRem -= (1 + pWriter->nWork); + rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg); + if( nSeg!=0 ){ + bDirtyHint = 1; + fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); + } + } + } + + if( nSeg!=0 ){ + pWriter->nLeafData = pWriter->nLeafData * -1; + } + fts3IncrmergeRelease(p, pWriter, &rc); + if( nSeg==0 && pWriter->bNoLeafData==0 ){ + fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData); + } + } + + sqlite3Fts3SegReaderFinish(pCsr); + } + + /* Write the hint values into the %_stat table for the next incr-merger */ + if( bDirtyHint && rc==SQLITE_OK ){ + rc = fts3IncrmergeHintStore(p, &hint); + } + + sqlite3_free(pWriter); + sqlite3_free(hint.a); + return rc; +} + +/* +** Convert the text beginning at *pz into an integer and return +** its value. Advance *pz to point to the first character past +** the integer. +** +** This function used for parameters to merge= and incrmerge= +** commands. +*/ +static int fts3Getint(const char **pz){ + const char *z = *pz; + int i = 0; + while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0'; + *pz = z; + return i; +} + +/* +** Process statements of the form: +** +** INSERT INTO table(table) VALUES('merge=A,B'); +** +** A and B are integers that decode to be the number of leaf pages +** written for the merge, and the minimum number of segments on a level +** before it will be selected for a merge, respectively. +*/ +static int fts3DoIncrmerge( + Fts3Table *p, /* FTS3 table handle */ + const char *zParam /* Nul-terminated string containing "A,B" */ +){ + int rc; + int nMin = (MergeCount(p) / 2); + int nMerge = 0; + const char *z = zParam; + + /* Read the first integer value */ + nMerge = fts3Getint(&z); + + /* If the first integer value is followed by a ',', read the second + ** integer value. */ + if( z[0]==',' && z[1]!='\0' ){ + z++; + nMin = fts3Getint(&z); + } + + if( z[0]!='\0' || nMin<2 ){ + rc = SQLITE_ERROR; + }else{ + rc = SQLITE_OK; + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); + } + sqlite3Fts3SegmentsClose(p); + } + return rc; +} + +/* +** Process statements of the form: +** +** INSERT INTO table(table) VALUES('automerge=X'); +** +** where X is an integer. X==0 means to turn automerge off. X!=0 means +** turn it on. The setting is persistent. +*/ +static int fts3DoAutoincrmerge( + Fts3Table *p, /* FTS3 table handle */ + const char *zParam /* Nul-terminated string containing boolean */ +){ + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = 0; + p->nAutoincrmerge = fts3Getint(&zParam); + if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){ + p->nAutoincrmerge = 8; + } + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + if( rc ) return rc; + } + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); + if( rc ) return rc; + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + return rc; +} + +/* +** Return a 64-bit checksum for the FTS index entry specified by the +** arguments to this function. +*/ +static u64 fts3ChecksumEntry( + const char *zTerm, /* Pointer to buffer containing term */ + int nTerm, /* Size of zTerm in bytes */ + int iLangid, /* Language id for current row */ + int iIndex, /* Index (0..Fts3Table.nIndex-1) */ + i64 iDocid, /* Docid for current row. */ + int iCol, /* Column number */ + int iPos /* Position */ +){ + int i; + u64 ret = (u64)iDocid; + + ret += (ret<<3) + iLangid; + ret += (ret<<3) + iIndex; + ret += (ret<<3) + iCol; + ret += (ret<<3) + iPos; + for(i=0; inIndex-1) */ + int *pRc /* OUT: Return code */ +){ + Fts3SegFilter filter; + Fts3MultiSegReader csr; + int rc; + u64 cksum = 0; + + if( *pRc ) return 0; + + memset(&filter, 0, sizeof(filter)); + memset(&csr, 0, sizeof(csr)); + filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + filter.flags |= FTS3_SEGMENT_SCAN; + + rc = sqlite3Fts3SegReaderCursor( + p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); + } + + if( rc==SQLITE_OK ){ + while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ + char *pCsr = csr.aDoclist; + char *pEnd = &pCsr[csr.nDoclist]; + + i64 iDocid = 0; + i64 iCol = 0; + u64 iPos = 0; + + pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); + while( pCsrbDescIdx ){ + iDocid = (i64)((u64)iDocid - iVal); + }else{ + iDocid = (i64)((u64)iDocid + iVal); + } + } + }else{ + iPos += (iVal - 2); + cksum = cksum ^ fts3ChecksumEntry( + csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid, + (int)iCol, (int)iPos + ); + } + } + } + } + } + sqlite3Fts3SegReaderFinish(&csr); + + *pRc = rc; + return cksum; +} + +/* +** Check if the contents of the FTS index match the current contents of the +** content table. If no error occurs and the contents do match, set *pbOk +** to true and return SQLITE_OK. Or if the contents do not match, set *pbOk +** to false before returning. +** +** If an error occurs (e.g. an OOM or IO error), return an SQLite error +** code. The final value of *pbOk is undefined in this case. +*/ +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ + int rc = SQLITE_OK; /* Return code */ + u64 cksum1 = 0; /* Checksum based on FTS index contents */ + u64 cksum2 = 0; /* Checksum based on %_content contents */ + sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ + + /* This block calculates the checksum according to the FTS index. */ + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int iLangid = sqlite3_column_int(pAllLangid, 0); + int i; + for(i=0; inIndex; i++){ + cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + + /* This block calculates the checksum according to the %_content table */ + if( rc==SQLITE_OK ){ + sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; + sqlite3_stmt *pStmt = 0; + char *zSql; + + zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + i64 iDocid = sqlite3_column_int64(pStmt, 0); + int iLang = langidFromSelect(p, pStmt); + int iCol; + + for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); + sqlite3_tokenizer_cursor *pT = 0; + + rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, -1, &pT); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ + + rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); + if( rc==SQLITE_OK ){ + int i; + cksum2 = cksum2 ^ fts3ChecksumEntry( + zToken, nToken, iLang, 0, iDocid, iCol, iPos + ); + for(i=1; inIndex; i++){ + if( p->aIndex[i].nPrefix<=nToken ){ + cksum2 = cksum2 ^ fts3ChecksumEntry( + zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos + ); + } + } + } + } + if( pT ) pModule->xClose(pT); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + } + } + + sqlite3_finalize(pStmt); + } + + *pbOk = (rc==SQLITE_OK && cksum1==cksum2); + return rc; +} + +/* +** Run the integrity-check. If no error occurs and the current contents of +** the FTS index are correct, return SQLITE_OK. Or, if the contents of the +** FTS index are incorrect, return SQLITE_CORRUPT_VTAB. +** +** Or, if an error (e.g. an OOM or IO error) occurs, return an SQLite +** error code. +** +** The integrity-check works as follows. For each token and indexed token +** prefix in the document set, a 64-bit checksum is calculated (by code +** in fts3ChecksumEntry()) based on the following: +** +** + The index number (0 for the main index, 1 for the first prefix +** index etc.), +** + The token (or token prefix) text itself, +** + The language-id of the row it appears in, +** + The docid of the row it appears in, +** + The column it appears in, and +** + The tokens position within that column. +** +** The checksums for all entries in the index are XORed together to create +** a single checksum for the entire index. +** +** The integrity-check code calculates the same checksum in two ways: +** +** 1. By scanning the contents of the FTS index, and +** 2. By scanning and tokenizing the content table. +** +** If the two checksums are identical, the integrity-check is deemed to have +** passed. +*/ +static int fts3DoIntegrityCheck( + Fts3Table *p /* FTS3 table handle */ +){ + int rc; + int bOk = 0; + rc = sqlite3Fts3IntegrityCheck(p, &bOk); + if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; + return rc; +} + +/* +** Handle a 'special' INSERT of the form: +** +** "INSERT INTO tbl(tbl) VALUES()" +** +** Argument pVal contains the result of . Currently the only +** meaningful value to insert is the text 'optimize'. +*/ +static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ + int rc = SQLITE_ERROR; /* Return Code */ + const char *zVal = (const char *)sqlite3_value_text(pVal); + int nVal = sqlite3_value_bytes(pVal); + + if( !zVal ){ + return SQLITE_NOMEM; + }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ + rc = fts3DoOptimize(p, 0); + }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){ + rc = fts3DoRebuild(p); + }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){ + rc = fts3DoIntegrityCheck(p); + }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){ + rc = fts3DoIncrmerge(p, &zVal[6]); + }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ + rc = fts3DoAutoincrmerge(p, &zVal[10]); + }else if( nVal==5 && 0==sqlite3_strnicmp(zVal, "flush", 5) ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + else{ + int v; + if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ + v = atoi(&zVal[9]); + if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v; + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ + v = atoi(&zVal[11]); + if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; + rc = SQLITE_OK; + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ + p->bNoIncrDoclist = atoi(&zVal[21]); + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){ + v = atoi(&zVal[11]); + if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; + rc = SQLITE_OK; + } + } +#endif + return rc; +} + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +/* +** Delete all cached deferred doclists. Deferred doclists are cached +** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ + fts3PendingListDelete(pDef->pList); + pDef->pList = 0; + } +} + +/* +** Free all entries in the pCsr->pDeffered list. Entries are added to +** this list using sqlite3Fts3DeferToken(). +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + Fts3DeferredToken *pNext; + for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ + pNext = pDef->pNext; + fts3PendingListDelete(pDef->pList); + sqlite3_free(pDef); + } + pCsr->pDeferred = 0; +} + +/* +** Generate deferred-doclists for all tokens in the pCsr->pDeferred list +** based on the row that pCsr currently points to. +** +** A deferred-doclist is like any other doclist with position information +** included, except that it only contains entries for a single row of the +** table, not for all rows. +*/ +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return code */ + if( pCsr->pDeferred ){ + int i; /* Used to iterate through table columns */ + sqlite3_int64 iDocid; /* Docid of the row pCsr points to */ + Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */ + + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer *pT = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pT->pModule; + + assert( pCsr->isRequireSeek==0 ); + iDocid = sqlite3_column_int64(pCsr->pStmt, 0); + + for(i=0; inColumn && rc==SQLITE_OK; i++){ + if( p->abNotindexed[i]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); + sqlite3_tokenizer_cursor *pTC = 0; + + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ + + rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + Fts3PhraseToken *pPT = pDef->pToken; + if( (pDef->iCol>=p->nColumn || pDef->iCol==i) + && (pPT->bFirst==0 || iPos==0) + && (pPT->n==nToken || (pPT->isPrefix && pPT->nz, pPT->n)) + ){ + fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); + } + } + } + if( pTC ) pModule->xClose(pTC); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + } + + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + if( pDef->pList ){ + rc = fts3PendingListAppendVarint(&pDef->pList, 0); + } + } + } + + return rc; +} + +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( + Fts3DeferredToken *p, + char **ppData, + int *pnData +){ + char *pRet; + int nSkip; + sqlite3_int64 dummy; + + *ppData = 0; + *pnData = 0; + + if( p->pList==0 ){ + return SQLITE_OK; + } + + pRet = (char *)sqlite3_malloc64(p->pList->nData); + if( !pRet ) return SQLITE_NOMEM; + + nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); + *pnData = p->pList->nData - nSkip; + *ppData = pRet; + + memcpy(pRet, &p->pList->aData[nSkip], *pnData); + return SQLITE_OK; +} + +/* +** Add an entry for token pToken to the pCsr->pDeferred list. +*/ +SQLITE_PRIVATE int sqlite3Fts3DeferToken( + Fts3Cursor *pCsr, /* Fts3 table cursor */ + Fts3PhraseToken *pToken, /* Token to defer */ + int iCol /* Column that token must appear in (or -1) */ +){ + Fts3DeferredToken *pDeferred; + pDeferred = sqlite3_malloc64(sizeof(*pDeferred)); + if( !pDeferred ){ + return SQLITE_NOMEM; + } + memset(pDeferred, 0, sizeof(*pDeferred)); + pDeferred->pToken = pToken; + pDeferred->pNext = pCsr->pDeferred; + pDeferred->iCol = iCol; + pCsr->pDeferred = pDeferred; + + assert( pToken->pDeferred==0 ); + pToken->pDeferred = pDeferred; + + return SQLITE_OK; +} +#endif + +/* +** SQLite value pRowid contains the rowid of a row that may or may not be +** present in the FTS3 table. If it is, delete it and adjust the contents +** of subsiduary data structures accordingly. +*/ +static int fts3DeleteByRowid( + Fts3Table *p, + sqlite3_value *pRowid, + int *pnChng, /* IN/OUT: Decrement if row is deleted */ + u32 *aSzDel +){ + int rc = SQLITE_OK; /* Return code */ + int bFound = 0; /* True if *pRowid really is in the table */ + + fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound); + if( bFound && rc==SQLITE_OK ){ + int isEmpty = 0; /* Deleting *pRowid leaves the table empty */ + rc = fts3IsEmpty(p, pRowid, &isEmpty); + if( rc==SQLITE_OK ){ + if( isEmpty ){ + /* Deleting this row means the whole table is empty. In this case + ** delete the contents of all three tables and throw away any + ** data in the pendingTerms hash table. */ + rc = fts3DeleteAll(p, 1); + *pnChng = 0; + memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2); + }else{ + *pnChng = *pnChng - 1; + if( p->zContentTbl==0 ){ + fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid); + } + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid); + } + } + } + } + + return rc; +} + +/* +** This function does the work for the xUpdate method of FTS3 virtual +** tables. The schema of the virtual table being: +** +** CREATE TABLE
( +** , +**
HIDDEN, +** docid HIDDEN, +** HIDDEN +** ); +** +** +*/ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( + sqlite3_vtab *pVtab, /* FTS3 vtab object */ + int nArg, /* Size of argument array */ + sqlite3_value **apVal, /* Array of arguments */ + sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ +){ + Fts3Table *p = (Fts3Table *)pVtab; + int rc = SQLITE_OK; /* Return Code */ + u32 *aSzIns = 0; /* Sizes of inserted documents */ + u32 *aSzDel = 0; /* Sizes of deleted documents */ + int nChng = 0; /* Net change in number of documents */ + int bInsertDone = 0; + + /* At this point it must be known if the %_stat table exists or not. + ** So bHasStat may not be 2. */ + assert( p->bHasStat==0 || p->bHasStat==1 ); + + assert( p->pSegments==0 ); + assert( + nArg==1 /* DELETE operations */ + || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ + ); + + /* Check for a "special" INSERT operation. One of the form: + ** + ** INSERT INTO xyz(xyz) VALUES('command'); + */ + if( nArg>1 + && sqlite3_value_type(apVal[0])==SQLITE_NULL + && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL + ){ + rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); + goto update_out; + } + + if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ + rc = SQLITE_CONSTRAINT; + goto update_out; + } + + /* Allocate space to hold the change in document sizes */ + aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2); + if( aSzDel==0 ){ + rc = SQLITE_NOMEM; + goto update_out; + } + aSzIns = &aSzDel[p->nColumn+1]; + memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2); + + rc = fts3Writelock(p); + if( rc!=SQLITE_OK ) goto update_out; + + /* If this is an INSERT operation, or an UPDATE that modifies the rowid + ** value, then this operation requires constraint handling. + ** + ** If the on-conflict mode is REPLACE, this means that the existing row + ** should be deleted from the database before inserting the new row. Or, + ** if the on-conflict mode is other than REPLACE, then this method must + ** detect the conflict and return SQLITE_CONSTRAINT before beginning to + ** modify the database file. + */ + if( nArg>1 && p->zContentTbl==0 ){ + /* Find the value object that holds the new rowid value. */ + sqlite3_value *pNewRowid = apVal[3+p->nColumn]; + if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){ + pNewRowid = apVal[1]; + } + + if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( + sqlite3_value_type(apVal[0])==SQLITE_NULL + || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid) + )){ + /* The new rowid is not NULL (in this case the rowid will be + ** automatically assigned and there is no chance of a conflict), and + ** the statement is either an INSERT or an UPDATE that modifies the + ** rowid column. So if the conflict mode is REPLACE, then delete any + ** existing row with rowid=pNewRowid. + ** + ** Or, if the conflict mode is not REPLACE, insert the new record into + ** the %_content table. If we hit the duplicate rowid constraint (or any + ** other error) while doing so, return immediately. + ** + ** This branch may also run if pNewRowid contains a value that cannot + ** be losslessly converted to an integer. In this case, the eventual + ** call to fts3InsertData() (either just below or further on in this + ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is + ** invoked, it will delete zero rows (since no row will have + ** docid=$pNewRowid if $pNewRowid is not an integer value). + */ + if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ + rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel); + }else{ + rc = fts3InsertData(p, apVal, pRowid); + bInsertDone = 1; + } + } + } + if( rc!=SQLITE_OK ){ + goto update_out; + } + + /* If this is a DELETE or UPDATE operation, remove the old record. */ + if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); + rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); + } + + /* If this is an INSERT or UPDATE operation, insert the new record. */ + if( nArg>1 && rc==SQLITE_OK ){ + int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); + if( bInsertDone==0 ){ + rc = fts3InsertData(p, apVal, pRowid); + if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ + rc = FTS_CORRUPT_VTAB; + } + } + if( rc==SQLITE_OK ){ + rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid); + } + if( rc==SQLITE_OK ){ + assert( p->iPrevDocid==*pRowid ); + rc = fts3InsertTerms(p, iLangid, apVal, aSzIns); + } + if( p->bHasDocsize ){ + fts3InsertDocsize(&rc, p, aSzIns); + } + nChng++; + } + + if( p->bFts4 ){ + fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); + } + + update_out: + sqlite3_free(aSzDel); + sqlite3Fts3SegmentsClose(p); + return rc; +} + +/* +** Flush any data in the pending-terms hash table to disk. If successful, +** merge all segments in the database (including the new segment, if +** there was any data to flush) into a single segment. +*/ +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ + int rc; + rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3DoOptimize(p, 1); + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + if( rc2!=SQLITE_OK ) rc = rc2; + }else{ + sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); + sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + } + } + sqlite3Fts3SegmentsClose(p); + return rc; +} + +#endif + +/************** End of fts3_write.c ******************************************/ +/************** Begin file fts3_snippet.c ************************************/ +/* +** 2009 Oct 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +*/ + +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +#ifndef SQLITE_AMALGAMATION +typedef sqlite3_int64 i64; +#endif + +/* +** Characters that may appear in the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ +#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ +#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ +#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ +#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ +#define FTS3_MATCHINFO_LCS 's' /* nCol values */ +#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ +#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */ +#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */ + +/* +** The default value for the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_DEFAULT "pcx" + + +/* +** Used as an sqlite3Fts3ExprIterate() context when loading phrase doclists to +** Fts3Expr.aDoclist[]/nDoclist. +*/ +typedef struct LoadDoclistCtx LoadDoclistCtx; +struct LoadDoclistCtx { + Fts3Cursor *pCsr; /* FTS3 Cursor */ + int nPhrase; /* Number of phrases seen so far */ + int nToken; /* Number of tokens seen so far */ +}; + +/* +** The following types are used as part of the implementation of the +** fts3BestSnippet() routine. +*/ +typedef struct SnippetIter SnippetIter; +typedef struct SnippetPhrase SnippetPhrase; +typedef struct SnippetFragment SnippetFragment; + +struct SnippetIter { + Fts3Cursor *pCsr; /* Cursor snippet is being generated from */ + int iCol; /* Extract snippet from this column */ + int nSnippet; /* Requested snippet length (in tokens) */ + int nPhrase; /* Number of phrases in query */ + SnippetPhrase *aPhrase; /* Array of size nPhrase */ + int iCurrent; /* First token of current snippet */ +}; + +struct SnippetPhrase { + int nToken; /* Number of tokens in phrase */ + char *pList; /* Pointer to start of phrase position list */ + i64 iHead; /* Next value in position list */ + char *pHead; /* Position list data following iHead */ + i64 iTail; /* Next value in trailing position list */ + char *pTail; /* Position list data following iTail */ +}; + +struct SnippetFragment { + int iCol; /* Column snippet is extracted from */ + int iPos; /* Index of first token in snippet */ + u64 covered; /* Mask of query phrases covered */ + u64 hlmask; /* Mask of snippet terms to highlight */ +}; + +/* +** This type is used as an sqlite3Fts3ExprIterate() context object while +** accumulating the data returned by the matchinfo() function. +*/ +typedef struct MatchInfo MatchInfo; +struct MatchInfo { + Fts3Cursor *pCursor; /* FTS3 Cursor */ + int nCol; /* Number of columns in table */ + int nPhrase; /* Number of matchable phrases in query */ + sqlite3_int64 nDoc; /* Number of docs in database */ + char flag; + u32 *aMatchinfo; /* Pre-allocated buffer */ +}; + +/* +** An instance of this structure is used to manage a pair of buffers, each +** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below +** for details. +*/ +struct MatchinfoBuffer { + u8 aRef[3]; + int nElem; + int bGlobal; /* Set if global data is loaded */ + char *zMatchinfo; + u32 aMatchinfo[1]; +}; + + +/* +** The snippet() and offsets() functions both return text values. An instance +** of the following structure is used to accumulate those values while the +** functions are running. See fts3StringAppend() for details. +*/ +typedef struct StrBuffer StrBuffer; +struct StrBuffer { + char *z; /* Pointer to buffer containing string */ + int n; /* Length of z in bytes (excl. nul-term) */ + int nAlloc; /* Allocated size of buffer z in bytes */ +}; + + +/************************************************************************* +** Start of MatchinfoBuffer code. +*/ + +/* +** Allocate a two-slot MatchinfoBuffer object. +*/ +static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ + MatchinfoBuffer *pRet; + sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) + + sizeof(MatchinfoBuffer); + sqlite3_int64 nStr = strlen(zMatchinfo); + + pRet = sqlite3Fts3MallocZero(nByte + nStr+1); + if( pRet ){ + pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; + pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + + sizeof(u32)*((int)nElem+1); + pRet->nElem = (int)nElem; + pRet->zMatchinfo = ((char*)pRet) + nByte; + memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1); + pRet->aRef[0] = 1; + } + + return pRet; +} + +static void fts3MIBufferFree(void *p){ + MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); + + assert( (u32*)p==&pBuf->aMatchinfo[1] + || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2] + ); + if( (u32*)p==&pBuf->aMatchinfo[1] ){ + pBuf->aRef[1] = 0; + }else{ + pBuf->aRef[2] = 0; + } + + if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){ + sqlite3_free(pBuf); + } +} + +static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ + void (*xRet)(void*) = 0; + u32 *aOut = 0; + + if( p->aRef[1]==0 ){ + p->aRef[1] = 1; + aOut = &p->aMatchinfo[1]; + xRet = fts3MIBufferFree; + } + else if( p->aRef[2]==0 ){ + p->aRef[2] = 1; + aOut = &p->aMatchinfo[p->nElem+2]; + xRet = fts3MIBufferFree; + }else{ + aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); + if( aOut ){ + xRet = sqlite3_free; + if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); + } + } + + *paOut = aOut; + return xRet; +} + +static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ + p->bGlobal = 1; + memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32)); +} + +/* +** Free a MatchinfoBuffer object allocated using fts3MIBufferNew() +*/ +SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ + if( p ){ + assert( p->aRef[0]==1 ); + p->aRef[0] = 0; + if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){ + sqlite3_free(p); + } + } +} + +/* +** End of MatchinfoBuffer code. +*************************************************************************/ + + +/* +** This function is used to help iterate through a position-list. A position +** list is a list of unique integers, sorted from smallest to largest. Each +** element of the list is represented by an FTS3 varint that takes the value +** of the difference between the current element and the previous one plus +** two. For example, to store the position-list: +** +** 4 9 113 +** +** the three varints: +** +** 6 7 106 +** +** are encoded. +** +** When this function is called, *pp points to the start of an element of +** the list. *piPos contains the value of the previous entry in the list. +** After it returns, *piPos contains the value of the next element of the +** list and *pp is advanced to the following varint. +*/ +static void fts3GetDeltaPosition(char **pp, i64 *piPos){ + int iVal; + *pp += fts3GetVarint32(*pp, &iVal); + *piPos += (iVal-2); +} + +/* +** Helper function for sqlite3Fts3ExprIterate() (see below). +*/ +static int fts3ExprIterate2( + Fts3Expr *pExpr, /* Expression to iterate phrases of */ + int *piPhrase, /* Pointer to phrase counter */ + int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ + void *pCtx /* Second argument to pass to callback */ +){ + int rc; /* Return code */ + int eType = pExpr->eType; /* Type of expression node pExpr */ + + if( eType!=FTSQUERY_PHRASE ){ + assert( pExpr->pLeft && pExpr->pRight ); + rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx); + if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){ + rc = fts3ExprIterate2(pExpr->pRight, piPhrase, x, pCtx); + } + }else{ + rc = x(pExpr, *piPhrase, pCtx); + (*piPhrase)++; + } + return rc; +} + +/* +** Iterate through all phrase nodes in an FTS3 query, except those that +** are part of a sub-tree that is the right-hand-side of a NOT operator. +** For each phrase node found, the supplied callback function is invoked. +** +** If the callback function returns anything other than SQLITE_OK, +** the iteration is abandoned and the error code returned immediately. +** Otherwise, SQLITE_OK is returned after a callback has been made for +** all eligible phrase nodes. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprIterate( + Fts3Expr *pExpr, /* Expression to iterate phrases of */ + int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ + void *pCtx /* Second argument to pass to callback */ +){ + int iPhrase = 0; /* Variable used as the phrase counter */ + return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); +} + +/* +** This is an sqlite3Fts3ExprIterate() callback used while loading the +** doclists for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also +** fts3ExprLoadDoclists(). +*/ +static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + int rc = SQLITE_OK; + Fts3Phrase *pPhrase = pExpr->pPhrase; + LoadDoclistCtx *p = (LoadDoclistCtx *)ctx; + + UNUSED_PARAMETER(iPhrase); + + p->nPhrase++; + p->nToken += pPhrase->nToken; + + return rc; +} + +/* +** Load the doclists for each phrase in the query associated with FTS3 cursor +** pCsr. +** +** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable +** phrases in the expression (all phrases except those directly or +** indirectly descended from the right-hand-side of a NOT operator). If +** pnToken is not NULL, then it is set to the number of tokens in all +** matchable phrases of the expression. +*/ +static int fts3ExprLoadDoclists( + Fts3Cursor *pCsr, /* Fts3 cursor for current query */ + int *pnPhrase, /* OUT: Number of phrases in query */ + int *pnToken /* OUT: Number of tokens in query */ +){ + int rc; /* Return Code */ + LoadDoclistCtx sCtx = {0,0,0}; /* Context for sqlite3Fts3ExprIterate() */ + sCtx.pCsr = pCsr; + rc = sqlite3Fts3ExprIterate(pCsr->pExpr,fts3ExprLoadDoclistsCb,(void*)&sCtx); + if( pnPhrase ) *pnPhrase = sCtx.nPhrase; + if( pnToken ) *pnToken = sCtx.nToken; + return rc; +} + +static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + (*(int *)ctx)++; + pExpr->iPhrase = iPhrase; + return SQLITE_OK; +} +static int fts3ExprPhraseCount(Fts3Expr *pExpr){ + int nPhrase = 0; + (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); + return nPhrase; +} + +/* +** Advance the position list iterator specified by the first two +** arguments so that it points to the first element with a value greater +** than or equal to parameter iNext. +*/ +static void fts3SnippetAdvance(char **ppIter, i64 *piIter, int iNext){ + char *pIter = *ppIter; + if( pIter ){ + i64 iIter = *piIter; + + while( iIteriCurrent<0 ){ + /* The SnippetIter object has just been initialized. The first snippet + ** candidate always starts at offset 0 (even if this candidate has a + ** score of 0.0). + */ + pIter->iCurrent = 0; + + /* Advance the 'head' iterator of each phrase to the first offset that + ** is greater than or equal to (iNext+nSnippet). + */ + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, pIter->nSnippet); + } + }else{ + int iStart; + int iEnd = 0x7FFFFFFF; + + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + if( pPhrase->pHead && pPhrase->iHeadiHead; + } + } + if( iEnd==0x7FFFFFFF ){ + return 1; + } + + pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); + fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); + } + } + + return 0; +} + +/* +** Retrieve information about the current candidate snippet of snippet +** iterator pIter. +*/ +static void fts3SnippetDetails( + SnippetIter *pIter, /* Snippet iterator */ + u64 mCovered, /* Bitmask of phrases already covered */ + int *piToken, /* OUT: First token of proposed snippet */ + int *piScore, /* OUT: "Score" for this snippet */ + u64 *pmCover, /* OUT: Bitmask of phrases covered */ + u64 *pmHighlight /* OUT: Bitmask of terms to highlight */ +){ + int iStart = pIter->iCurrent; /* First token of snippet */ + int iScore = 0; /* Score of this snippet */ + int i; /* Loop counter */ + u64 mCover = 0; /* Mask of phrases covered by this snippet */ + u64 mHighlight = 0; /* Mask of tokens to highlight in snippet */ + + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + if( pPhrase->pTail ){ + char *pCsr = pPhrase->pTail; + i64 iCsr = pPhrase->iTail; + + while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){ + int j; + u64 mPhrase = (u64)1 << (i%64); + u64 mPos = (u64)1 << (iCsr - iStart); + assert( iCsr>=iStart && (iCsr - iStart)<=64 ); + assert( i>=0 ); + if( (mCover|mCovered)&mPhrase ){ + iScore++; + }else{ + iScore += 1000; + } + mCover |= mPhrase; + + for(j=0; jnToken; j++){ + mHighlight |= (mPos>>j); + } + + if( 0==(*pCsr & 0x0FE) ) break; + fts3GetDeltaPosition(&pCsr, &iCsr); + } + } + } + + /* Set the output variables before returning. */ + *piToken = iStart; + *piScore = iScore; + *pmCover = mCover; + *pmHighlight = mHighlight; +} + +/* +** This function is an sqlite3Fts3ExprIterate() callback used by +** fts3BestSnippet(). Each invocation populates an element of the +** SnippetIter.aPhrase[] array. +*/ +static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ + SnippetIter *p = (SnippetIter *)ctx; + SnippetPhrase *pPhrase = &p->aPhrase[iPhrase]; + char *pCsr; + int rc; + + pPhrase->nToken = pExpr->pPhrase->nToken; + rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( pCsr ){ + i64 iFirst = 0; + pPhrase->pList = pCsr; + fts3GetDeltaPosition(&pCsr, &iFirst); + if( iFirst<0 ){ + rc = FTS_CORRUPT_VTAB; + }else{ + pPhrase->pHead = pCsr; + pPhrase->pTail = pCsr; + pPhrase->iHead = iFirst; + pPhrase->iTail = iFirst; + } + }else{ + assert( rc!=SQLITE_OK || ( + pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 + )); + } + + return rc; +} + +/* +** Select the fragment of text consisting of nFragment contiguous tokens +** from column iCol that represent the "best" snippet. The best snippet +** is the snippet with the highest score, where scores are calculated +** by adding: +** +** (a) +1 point for each occurrence of a matchable phrase in the snippet. +** +** (b) +1000 points for the first occurrence of each matchable phrase in +** the snippet for which the corresponding mCovered bit is not set. +** +** The selected snippet parameters are stored in structure *pFragment before +** returning. The score of the selected snippet is stored in *piScore +** before returning. +*/ +static int fts3BestSnippet( + int nSnippet, /* Desired snippet length */ + Fts3Cursor *pCsr, /* Cursor to create snippet for */ + int iCol, /* Index of column to create snippet from */ + u64 mCovered, /* Mask of phrases already covered */ + u64 *pmSeen, /* IN/OUT: Mask of phrases seen */ + SnippetFragment *pFragment, /* OUT: Best snippet found */ + int *piScore /* OUT: Score of snippet pFragment */ +){ + int rc; /* Return Code */ + int nList; /* Number of phrases in expression */ + SnippetIter sIter; /* Iterates through snippet candidates */ + sqlite3_int64 nByte; /* Number of bytes of space to allocate */ + int iBestScore = -1; /* Best snippet score found so far */ + int i; /* Loop counter */ + + memset(&sIter, 0, sizeof(sIter)); + + /* Iterate through the phrases in the expression to count them. The same + ** callback makes sure the doclists are loaded for each phrase. + */ + rc = fts3ExprLoadDoclists(pCsr, &nList, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Now that it is known how many phrases there are, allocate and zero + ** the required space using malloc(). + */ + nByte = sizeof(SnippetPhrase) * nList; + sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte); + if( !sIter.aPhrase ){ + return SQLITE_NOMEM; + } + + /* Initialize the contents of the SnippetIter object. Then iterate through + ** the set of phrases in the expression to populate the aPhrase[] array. + */ + sIter.pCsr = pCsr; + sIter.iCol = iCol; + sIter.nSnippet = nSnippet; + sIter.nPhrase = nList; + sIter.iCurrent = -1; + rc = sqlite3Fts3ExprIterate( + pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter + ); + if( rc==SQLITE_OK ){ + + /* Set the *pmSeen output variable. */ + for(i=0; iiCol = iCol; + while( !fts3SnippetNextCandidate(&sIter) ){ + int iPos; + int iScore; + u64 mCover; + u64 mHighlite; + fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite); + assert( iScore>=0 ); + if( iScore>iBestScore ){ + pFragment->iPos = iPos; + pFragment->hlmask = mHighlite; + pFragment->covered = mCover; + iBestScore = iScore; + } + } + + *piScore = iBestScore; + } + sqlite3_free(sIter.aPhrase); + return rc; +} + + +/* +** Append a string to the string-buffer passed as the first argument. +** +** If nAppend is negative, then the length of the string zAppend is +** determined using strlen(). +*/ +static int fts3StringAppend( + StrBuffer *pStr, /* Buffer to append to */ + const char *zAppend, /* Pointer to data to append to buffer */ + int nAppend /* Size of zAppend in bytes (or -1) */ +){ + if( nAppend<0 ){ + nAppend = (int)strlen(zAppend); + } + + /* If there is insufficient space allocated at StrBuffer.z, use realloc() + ** to grow the buffer until so that it is big enough to accomadate the + ** appended data. + */ + if( pStr->n+nAppend+1>=pStr->nAlloc ){ + sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; + char *zNew = sqlite3_realloc64(pStr->z, nAlloc); + if( !zNew ){ + return SQLITE_NOMEM; + } + pStr->z = zNew; + pStr->nAlloc = nAlloc; + } + assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) ); + + /* Append the data to the string buffer. */ + memcpy(&pStr->z[pStr->n], zAppend, nAppend); + pStr->n += nAppend; + pStr->z[pStr->n] = '\0'; + + return SQLITE_OK; +} + +/* +** The fts3BestSnippet() function often selects snippets that end with a +** query term. That is, the final term of the snippet is always a term +** that requires highlighting. For example, if 'X' is a highlighted term +** and '.' is a non-highlighted term, BestSnippet() may select: +** +** ........X.....X +** +** This function "shifts" the beginning of the snippet forward in the +** document so that there are approximately the same number of +** non-highlighted terms to the right of the final highlighted term as there +** are to the left of the first highlighted term. For example, to this: +** +** ....X.....X.... +** +** This is done as part of extracting the snippet text, not when selecting +** the snippet. Snippet selection is done based on doclists only, so there +** is no way for fts3BestSnippet() to know whether or not the document +** actually contains terms that follow the final highlighted term. +*/ +static int fts3SnippetShift( + Fts3Table *pTab, /* FTS3 table snippet comes from */ + int iLangid, /* Language id to use in tokenizing */ + int nSnippet, /* Number of tokens desired for snippet */ + const char *zDoc, /* Document text to extract snippet from */ + int nDoc, /* Size of buffer zDoc in bytes */ + int *piPos, /* IN/OUT: First token of snippet */ + u64 *pHlmask /* IN/OUT: Mask of tokens to highlight */ +){ + u64 hlmask = *pHlmask; /* Local copy of initial highlight-mask */ + + if( hlmask ){ + int nLeft; /* Tokens to the left of first highlight */ + int nRight; /* Tokens to the right of last highlight */ + int nDesired; /* Ideal number of tokens to shift forward */ + + for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++); + for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++); + assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 ); + nDesired = (nLeft-nRight)/2; + + /* Ideally, the start of the snippet should be pushed forward in the + ** document nDesired tokens. This block checks if there are actually + ** nDesired tokens to the right of the snippet. If so, *piPos and + ** *pHlMask are updated to shift the snippet nDesired tokens to the + ** right. Otherwise, the snippet is shifted by the number of tokens + ** available. + */ + if( nDesired>0 ){ + int nShift; /* Number of tokens to shift snippet by */ + int iCurrent = 0; /* Token counter */ + int rc; /* Return Code */ + sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer_cursor *pC; + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + + /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired) + ** or more tokens in zDoc/nDoc. + */ + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); + if( rc!=SQLITE_OK ){ + return rc; + } + while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ + const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0; + rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); + } + pMod->xClose(pC); + if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; } + + nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet; + assert( nShift<=nDesired ); + if( nShift>0 ){ + *piPos += nShift; + *pHlmask = hlmask >> nShift; + } + } + } + return SQLITE_OK; +} + +/* +** Extract the snippet text for fragment pFragment from cursor pCsr and +** append it to string buffer pOut. +*/ +static int fts3SnippetText( + Fts3Cursor *pCsr, /* FTS3 Cursor */ + SnippetFragment *pFragment, /* Snippet to extract */ + int iFragment, /* Fragment number */ + int isLast, /* True for final fragment in snippet */ + int nSnippet, /* Number of tokens in extracted snippet */ + const char *zOpen, /* String inserted before highlighted term */ + const char *zClose, /* String inserted after highlighted term */ + const char *zEllipsis, /* String inserted between snippets */ + StrBuffer *pOut /* Write output here */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc; /* Return code */ + const char *zDoc; /* Document text to extract snippet from */ + int nDoc; /* Size of zDoc in bytes */ + int iCurrent = 0; /* Current token number of document */ + int iEnd = 0; /* Byte offset of end of current token */ + int isShiftDone = 0; /* True after snippet is shifted */ + int iPos = pFragment->iPos; /* First token of snippet */ + u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */ + int iCol = pFragment->iCol+1; /* Query column to extract text from */ + sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ + + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); + if( zDoc==0 ){ + if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ + return SQLITE_NOMEM; + } + return SQLITE_OK; + } + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol); + + /* Open a token cursor on the document. */ + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); + if( rc!=SQLITE_OK ){ + return rc; + } + + while( rc==SQLITE_OK ){ + const char *ZDUMMY; /* Dummy argument used with tokenizer */ + int DUMMY1 = -1; /* Dummy argument used with tokenizer */ + int iBegin = 0; /* Offset in zDoc of start of token */ + int iFin = 0; /* Offset in zDoc of end of token */ + int isHighlight = 0; /* True for highlighted terms */ + + /* Variable DUMMY1 is initialized to a negative value above. Elsewhere + ** in the FTS code the variable that the third argument to xNext points to + ** is initialized to zero before the first (*but not necessarily + ** subsequent*) call to xNext(). This is done for a particular application + ** that needs to know whether or not the tokenizer is being used for + ** snippet generation or for some other purpose. + ** + ** Extreme care is required when writing code to depend on this + ** initialization. It is not a documented part of the tokenizer interface. + ** If a tokenizer is used directly by any code outside of FTS, this + ** convention might not be respected. */ + rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + /* Special case - the last token of the snippet is also the last token + ** of the column. Append any punctuation that occurred between the end + ** of the previous token and the end of the document to the output. + ** Then break out of the loop. */ + rc = fts3StringAppend(pOut, &zDoc[iEnd], -1); + } + break; + } + if( iCurrentiLangid, nSnippet, &zDoc[iBegin], n, &iPos, &hlmask + ); + isShiftDone = 1; + + /* Now that the shift has been done, check if the initial "..." are + ** required. They are required if (a) this is not the first fragment, + ** or (b) this fragment does not begin at position 0 of its column. + */ + if( rc==SQLITE_OK ){ + if( iPos>0 || iFragment>0 ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + }else if( iBegin ){ + rc = fts3StringAppend(pOut, zDoc, iBegin); + } + } + if( rc!=SQLITE_OK || iCurrent=(iPos+nSnippet) ){ + if( isLast ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + } + break; + } + + /* Set isHighlight to true if this term should be highlighted. */ + isHighlight = (hlmask & ((u64)1 << (iCurrent-iPos)))!=0; + + if( iCurrent>iPos ) rc = fts3StringAppend(pOut, &zDoc[iEnd], iBegin-iEnd); + if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zOpen, -1); + if( rc==SQLITE_OK ) rc = fts3StringAppend(pOut, &zDoc[iBegin], iFin-iBegin); + if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zClose, -1); + + iEnd = iFin; + } + + pMod->xClose(pC); + return rc; +} + + +/* +** This function is used to count the entries in a column-list (a +** delta-encoded list of term offsets within a single column of a single +** row). When this function is called, *ppCollist should point to the +** beginning of the first varint in the column-list (the varint that +** contains the position of the first matching term in the column data). +** Before returning, *ppCollist is set to point to the first byte after +** the last varint in the column-list (either the 0x00 signifying the end +** of the position-list, or the 0x01 that precedes the column number of +** the next column in the position-list). +** +** The number of elements in the column-list is returned. +*/ +static int fts3ColumnlistCount(char **ppCollist){ + char *pEnd = *ppCollist; + char c = 0; + int nEntry = 0; + + /* A column-list is terminated by either a 0x01 or 0x00. */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + if( !c ) nEntry++; + } + + *ppCollist = pEnd; + return nEntry; +} + +/* +** This function gathers 'y' or 'b' data for a single phrase. +*/ +static int fts3ExprLHits( + Fts3Expr *pExpr, /* Phrase expression node */ + MatchInfo *p /* Matchinfo context */ +){ + Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab; + int iStart; + Fts3Phrase *pPhrase = pExpr->pPhrase; + char *pIter = pPhrase->doclist.pList; + int iCol = 0; + + assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS ); + if( p->flag==FTS3_MATCHINFO_LHITS ){ + iStart = pExpr->iPhrase * p->nCol; + }else{ + iStart = pExpr->iPhrase * ((p->nCol + 31) / 32); + } + + if( pIter ) while( 1 ){ + int nHit = fts3ColumnlistCount(&pIter); + if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ + if( p->flag==FTS3_MATCHINFO_LHITS ){ + p->aMatchinfo[iStart + iCol] = (u32)nHit; + }else if( nHit ){ + p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F)); + } + } + assert( *pIter==0x00 || *pIter==0x01 ); + if( *pIter!=0x01 ) break; + pIter++; + pIter += fts3GetVarint32(pIter, &iCol); + if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB; + } + return SQLITE_OK; +} + +/* +** Gather the results for matchinfo directives 'y' and 'b'. +*/ +static int fts3ExprLHitGather( + Fts3Expr *pExpr, + MatchInfo *p +){ + int rc = SQLITE_OK; + assert( (pExpr->pLeft==0)==(pExpr->pRight==0) ); + if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){ + if( pExpr->pLeft ){ + rc = fts3ExprLHitGather(pExpr->pLeft, p); + if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p); + }else{ + rc = fts3ExprLHits(pExpr, p); + } + } + return rc; +} + +/* +** sqlite3Fts3ExprIterate() callback used to collect the "global" matchinfo +** stats for a single query. +** +** sqlite3Fts3ExprIterate() callback to load the 'global' elements of a +** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements +** of the matchinfo array that are constant for all rows returned by the +** current query. +** +** Argument pCtx is actually a pointer to a struct of type MatchInfo. This +** function populates Matchinfo.aMatchinfo[] as follows: +** +** for(iCol=0; iColpCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] + ); +} + +/* +** sqlite3Fts3ExprIterate() callback used to collect the "local" part of the +** FTS3_MATCHINFO_HITS array. The local stats are those elements of the +** array that are different for each row returned by the query. +*/ +static int fts3ExprLocalHitsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + int rc = SQLITE_OK; + MatchInfo *p = (MatchInfo *)pCtx; + int iStart = iPhrase * p->nCol * 3; + int i; + + for(i=0; inCol && rc==SQLITE_OK; i++){ + char *pCsr; + rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr); + if( pCsr ){ + p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr); + }else{ + p->aMatchinfo[iStart+i*3] = 0; + } + } + + return rc; +} + +static int fts3MatchinfoCheck( + Fts3Table *pTab, + char cArg, + char **pzErr +){ + if( (cArg==FTS3_MATCHINFO_NPHRASE) + || (cArg==FTS3_MATCHINFO_NCOL) + || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) + || (cArg==FTS3_MATCHINFO_LCS) + || (cArg==FTS3_MATCHINFO_HITS) + || (cArg==FTS3_MATCHINFO_LHITS) + || (cArg==FTS3_MATCHINFO_LHITS_BM) + ){ + return SQLITE_OK; + } + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); + return SQLITE_ERROR; +} + +static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ + size_t nVal; /* Number of integers output by cArg */ + + switch( cArg ){ + case FTS3_MATCHINFO_NDOC: + case FTS3_MATCHINFO_NPHRASE: + case FTS3_MATCHINFO_NCOL: + nVal = 1; + break; + + case FTS3_MATCHINFO_AVGLENGTH: + case FTS3_MATCHINFO_LENGTH: + case FTS3_MATCHINFO_LCS: + nVal = pInfo->nCol; + break; + + case FTS3_MATCHINFO_LHITS: + nVal = pInfo->nCol * pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_LHITS_BM: + nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32); + break; + + default: + assert( cArg==FTS3_MATCHINFO_HITS ); + nVal = pInfo->nCol * pInfo->nPhrase * 3; + break; + } + + return nVal; +} + +static int fts3MatchinfoSelectDoctotal( + Fts3Table *pTab, + sqlite3_stmt **ppStmt, + sqlite3_int64 *pnDoc, + const char **paLen, + const char **ppEnd +){ + sqlite3_stmt *pStmt; + const char *a; + const char *pEnd; + sqlite3_int64 nDoc; + int n; + + + if( !*ppStmt ){ + int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); + if( rc!=SQLITE_OK ) return rc; + } + pStmt = *ppStmt; + assert( sqlite3_data_count(pStmt)==1 ); + + n = sqlite3_column_bytes(pStmt, 0); + a = sqlite3_column_blob(pStmt, 0); + if( a==0 ){ + return FTS_CORRUPT_VTAB; + } + pEnd = a + n; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); + if( nDoc<=0 || a>pEnd ){ + return FTS_CORRUPT_VTAB; + } + *pnDoc = nDoc; + + if( paLen ) *paLen = a; + if( ppEnd ) *ppEnd = pEnd; + return SQLITE_OK; +} + +/* +** An instance of the following structure is used to store state while +** iterating through a multi-column position-list corresponding to the +** hits for a single phrase on a single row in order to calculate the +** values for a matchinfo() FTS3_MATCHINFO_LCS request. +*/ +typedef struct LcsIterator LcsIterator; +struct LcsIterator { + Fts3Expr *pExpr; /* Pointer to phrase expression */ + int iPosOffset; /* Tokens count up to end of this phrase */ + char *pRead; /* Cursor used to iterate through aDoclist */ + int iPos; /* Current position */ +}; + +/* +** If LcsIterator.iCol is set to the following value, the iterator has +** finished iterating through all offsets for all columns. +*/ +#define LCS_ITERATOR_FINISHED 0x7FFFFFFF; + +static int fts3MatchinfoLcsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number (numbered from zero) */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + LcsIterator *aIter = (LcsIterator *)pCtx; + aIter[iPhrase].pExpr = pExpr; + return SQLITE_OK; +} + +/* +** Advance the iterator passed as an argument to the next position. Return +** 1 if the iterator is at EOF or if it now points to the start of the +** position list for the next column. +*/ +static int fts3LcsIteratorAdvance(LcsIterator *pIter){ + char *pRead; + sqlite3_int64 iRead; + int rc = 0; + + if( NEVER(pIter==0) ) return 1; + pRead = pIter->pRead; + pRead += sqlite3Fts3GetVarint(pRead, &iRead); + if( iRead==0 || iRead==1 ){ + pRead = 0; + rc = 1; + }else{ + pIter->iPos += (int)(iRead-2); + } + + pIter->pRead = pRead; + return rc; +} + +/* +** This function implements the FTS3_MATCHINFO_LCS matchinfo() flag. +** +** If the call is successful, the longest-common-substring lengths for each +** column are written into the first nCol elements of the pInfo->aMatchinfo[] +** array before returning. SQLITE_OK is returned in this case. +** +** Otherwise, if an error occurs, an SQLite error code is returned and the +** data written to the first nCol elements of pInfo->aMatchinfo[] is +** undefined. +*/ +static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ + LcsIterator *aIter; + int i; + int iCol; + int nToken = 0; + int rc = SQLITE_OK; + + /* Allocate and populate the array of LcsIterator objects. The array + ** contains one element for each matchable phrase in the query. + **/ + aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); + if( !aIter ) return SQLITE_NOMEM; + (void)sqlite3Fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); + + for(i=0; inPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + nToken -= pIter->pExpr->pPhrase->nToken; + pIter->iPosOffset = nToken; + } + + for(iCol=0; iColnCol; iCol++){ + int nLcs = 0; /* LCS value for this column */ + int nLive = 0; /* Number of iterators in aIter not at EOF */ + + for(i=0; inPhrase; i++){ + LcsIterator *pIt = &aIter[i]; + rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); + if( rc!=SQLITE_OK ) goto matchinfo_lcs_out; + if( pIt->pRead ){ + pIt->iPos = pIt->iPosOffset; + fts3LcsIteratorAdvance(pIt); + if( pIt->pRead==0 ){ + rc = FTS_CORRUPT_VTAB; + goto matchinfo_lcs_out; + } + nLive++; + } + } + + while( nLive>0 ){ + LcsIterator *pAdv = 0; /* The iterator to advance by one position */ + int nThisLcs = 0; /* LCS for the current iterator positions */ + + for(i=0; inPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + if( pIter->pRead==0 ){ + /* This iterator is already at EOF for this column. */ + nThisLcs = 0; + }else{ + if( pAdv==0 || pIter->iPosiPos ){ + pAdv = pIter; + } + if( nThisLcs==0 || pIter->iPos==pIter[-1].iPos ){ + nThisLcs++; + }else{ + nThisLcs = 1; + } + if( nThisLcs>nLcs ) nLcs = nThisLcs; + } + } + if( fts3LcsIteratorAdvance(pAdv) ) nLive--; + } + + pInfo->aMatchinfo[iCol] = nLcs; + } + + matchinfo_lcs_out: + sqlite3_free(aIter); + return rc; +} + +/* +** Populate the buffer pInfo->aMatchinfo[] with an array of integers to +** be returned by the matchinfo() function. Argument zArg contains the +** format string passed as the second argument to matchinfo (or the +** default value "pcx" if no second argument was specified). The format +** string has already been validated and the pInfo->aMatchinfo[] array +** is guaranteed to be large enough for the output. +** +** If bGlobal is true, then populate all fields of the matchinfo() output. +** If it is false, then assume that those fields that do not change between +** rows (i.e. FTS3_MATCHINFO_NPHRASE, NCOL, NDOC, AVGLENGTH and part of HITS) +** have already been populated. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. If a value other than SQLITE_OK is returned, the state the +** pInfo->aMatchinfo[] buffer is left in is undefined. +*/ +static int fts3MatchinfoValues( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + int bGlobal, /* True to grab the global stats */ + MatchInfo *pInfo, /* Matchinfo context object */ + const char *zArg /* Matchinfo format string */ +){ + int rc = SQLITE_OK; + int i; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_stmt *pSelect = 0; + + for(i=0; rc==SQLITE_OK && zArg[i]; i++){ + pInfo->flag = zArg[i]; + switch( zArg[i] ){ + case FTS3_MATCHINFO_NPHRASE: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_NCOL: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; + break; + + case FTS3_MATCHINFO_NDOC: + if( bGlobal ){ + sqlite3_int64 nDoc = 0; + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0, 0); + pInfo->aMatchinfo[0] = (u32)nDoc; + } + break; + + case FTS3_MATCHINFO_AVGLENGTH: + if( bGlobal ){ + sqlite3_int64 nDoc; /* Number of rows in table */ + const char *a; /* Aggregate column length array */ + const char *pEnd; /* First byte past end of length array */ + + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a, &pEnd); + if( rc==SQLITE_OK ){ + int iCol; + for(iCol=0; iColnCol; iCol++){ + u32 iVal; + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + if( a>pEnd ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } + iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc); + pInfo->aMatchinfo[iCol] = iVal; + } + } + } + break; + + case FTS3_MATCHINFO_LENGTH: { + sqlite3_stmt *pSelectDocsize = 0; + rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); + if( rc==SQLITE_OK ){ + int iCol; + const char *a = sqlite3_column_blob(pSelectDocsize, 0); + const char *pEnd = a + sqlite3_column_bytes(pSelectDocsize, 0); + for(iCol=0; iColnCol; iCol++){ + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nToken); + if( a>pEnd ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } + pInfo->aMatchinfo[iCol] = (u32)nToken; + } + } + sqlite3_reset(pSelectDocsize); + break; + } + + case FTS3_MATCHINFO_LCS: + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3MatchinfoLcs(pCsr, pInfo); + } + break; + + case FTS3_MATCHINFO_LHITS_BM: + case FTS3_MATCHINFO_LHITS: { + size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); + memset(pInfo->aMatchinfo, 0, nZero); + rc = fts3ExprLHitGather(pCsr->pExpr, pInfo); + break; + } + + default: { + Fts3Expr *pExpr; + assert( zArg[i]==FTS3_MATCHINFO_HITS ); + pExpr = pCsr->pExpr; + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc!=SQLITE_OK ) break; + if( bGlobal ){ + if( pCsr->pDeferred ){ + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); + if( rc!=SQLITE_OK ) break; + } + rc = sqlite3Fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + sqlite3Fts3EvalTestDeferred(pCsr, &rc); + if( rc!=SQLITE_OK ) break; + } + (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + break; + } + } + + pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); + } + + sqlite3_reset(pSelect); + return rc; +} + + +/* +** Populate pCsr->aMatchinfo[] with data for the current row. The +** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). +*/ +static void fts3GetMatchinfo( + sqlite3_context *pCtx, /* Return results here */ + Fts3Cursor *pCsr, /* FTS3 Cursor object */ + const char *zArg /* Second argument to matchinfo() function */ +){ + MatchInfo sInfo; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int bGlobal = 0; /* Collect 'global' stats as well as local */ + + u32 *aOut = 0; + void (*xDestroyOut)(void*) = 0; + + memset(&sInfo, 0, sizeof(MatchInfo)); + sInfo.pCursor = pCsr; + sInfo.nCol = pTab->nColumn; + + /* If there is cached matchinfo() data, but the format string for the + ** cache does not match the format string for this request, discard + ** the cached data. */ + if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){ + sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); + pCsr->pMIBuffer = 0; + } + + /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the + ** matchinfo function has been called for this query. In this case + ** allocate the array used to accumulate the matchinfo data and + ** initialize those elements that are constant for every row. + */ + if( pCsr->pMIBuffer==0 ){ + size_t nMatchinfo = 0; /* Number of u32 elements in match-info */ + int i; /* Used to iterate through zArg */ + + /* Determine the number of phrases in the query */ + pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr); + sInfo.nPhrase = pCsr->nPhrase; + + /* Determine the number of integers in the buffer returned by this call. */ + for(i=0; zArg[i]; i++){ + char *zErr = 0; + if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); + return; + } + nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); + } + + /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */ + pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg); + if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM; + + pCsr->isMatchinfoNeeded = 1; + bGlobal = 1; + } + + if( rc==SQLITE_OK ){ + xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut); + if( xDestroyOut==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + sInfo.aMatchinfo = aOut; + sInfo.nPhrase = pCsr->nPhrase; + rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg); + if( bGlobal ){ + fts3MIBufferSetGlobal(pCsr->pMIBuffer); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + if( xDestroyOut ) xDestroyOut(aOut); + }else{ + int n = pCsr->pMIBuffer->nElem * sizeof(u32); + sqlite3_result_blob(pCtx, aOut, n, xDestroyOut); + } +} + +/* +** Implementation of snippet() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Snippet( + sqlite3_context *pCtx, /* SQLite function call context */ + Fts3Cursor *pCsr, /* Cursor object */ + const char *zStart, /* Snippet start text - "" */ + const char *zEnd, /* Snippet end text - "" */ + const char *zEllipsis, /* Snippet ellipsis text - "..." */ + int iCol, /* Extract snippet from this column */ + int nToken /* Approximate number of tokens in snippet */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int i; + StrBuffer res = {0, 0, 0}; + + /* The returned text includes up to four fragments of text extracted from + ** the data in the current row. The first iteration of the for(...) loop + ** below attempts to locate a single fragment of text nToken tokens in + ** size that contains at least one instance of all phrases in the query + ** expression that appear in the current row. If such a fragment of text + ** cannot be found, the second iteration of the loop attempts to locate + ** a pair of fragments, and so on. + */ + int nSnippet = 0; /* Number of fragments in this snippet */ + SnippetFragment aSnippet[4]; /* Maximum of 4 fragments per snippet */ + int nFToken = -1; /* Number of tokens in each fragment */ + + if( !pCsr->pExpr ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + return; + } + + /* Limit the snippet length to 64 tokens. */ + if( nToken<-64 ) nToken = -64; + if( nToken>+64 ) nToken = +64; + + for(nSnippet=1; 1; nSnippet++){ + + int iSnip; /* Loop counter 0..nSnippet-1 */ + u64 mCovered = 0; /* Bitmask of phrases covered by snippet */ + u64 mSeen = 0; /* Bitmask of phrases seen by BestSnippet() */ + + if( nToken>=0 ){ + nFToken = (nToken+nSnippet-1) / nSnippet; + }else{ + nFToken = -1 * nToken; + } + + for(iSnip=0; iSnipnColumn; iRead++){ + SnippetFragment sF = {0, 0, 0, 0}; + int iS = 0; + if( iCol>=0 && iRead!=iCol ) continue; + + /* Find the best snippet of nFToken tokens in column iRead. */ + rc = fts3BestSnippet(nFToken, pCsr, iRead, mCovered, &mSeen, &sF, &iS); + if( rc!=SQLITE_OK ){ + goto snippet_out; + } + if( iS>iBestScore ){ + *pFragment = sF; + iBestScore = iS; + } + } + + mCovered |= pFragment->covered; + } + + /* If all query phrases seen by fts3BestSnippet() are present in at least + ** one of the nSnippet snippet fragments, break out of the loop. + */ + assert( (mCovered&mSeen)==mCovered ); + if( mSeen==mCovered || nSnippet==SizeofArray(aSnippet) ) break; + } + + assert( nFToken>0 ); + + for(i=0; ipCsr, pExpr, p->iCol, &pList); + nTerm = pExpr->pPhrase->nToken; + if( pList ){ + fts3GetDeltaPosition(&pList, &iPos); + assert_fts3_nc( iPos>=0 ); + } + + for(iTerm=0; iTermaTerm[p->iTerm++]; + pT->iOff = nTerm-iTerm-1; + pT->pList = pList; + pT->iPos = iPos; + } + + return rc; +} + +/* +** Implementation of offsets() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Offsets( + sqlite3_context *pCtx, /* SQLite function call context */ + Fts3Cursor *pCsr /* Cursor object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; + int rc; /* Return Code */ + int nToken; /* Number of tokens in query */ + int iCol; /* Column currently being processed */ + StrBuffer res = {0, 0, 0}; /* Result string */ + TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */ + + if( !pCsr->pExpr ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + return; + } + + memset(&sCtx, 0, sizeof(sCtx)); + assert( pCsr->isRequireSeek==0 ); + + /* Count the number of terms in the query */ + rc = fts3ExprLoadDoclists(pCsr, 0, &nToken); + if( rc!=SQLITE_OK ) goto offsets_out; + + /* Allocate the array of TermOffset iterators. */ + sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken); + if( 0==sCtx.aTerm ){ + rc = SQLITE_NOMEM; + goto offsets_out; + } + sCtx.iDocid = pCsr->iPrevId; + sCtx.pCsr = pCsr; + + /* Loop through the table columns, appending offset information to + ** string-buffer res for each column. + */ + for(iCol=0; iColnColumn; iCol++){ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ + const char *ZDUMMY; /* Dummy argument used with xNext() */ + int NDUMMY = 0; /* Dummy argument used with xNext() */ + int iStart = 0; + int iEnd = 0; + int iCurrent = 0; + const char *zDoc; + int nDoc; + + /* Initialize the contents of sCtx.aTerm[] for column iCol. This + ** operation may fail if the database contains corrupt records. + */ + sCtx.iCol = iCol; + sCtx.iTerm = 0; + rc = sqlite3Fts3ExprIterate( + pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx + ); + if( rc!=SQLITE_OK ) goto offsets_out; + + /* Retreive the text stored in column iCol. If an SQL NULL is stored + ** in column iCol, jump immediately to the next iteration of the loop. + ** If an OOM occurs while retrieving the data (this can happen if SQLite + ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM + ** to the caller. + */ + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1); + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1); + if( zDoc==0 ){ + if( sqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){ + continue; + } + rc = SQLITE_NOMEM; + goto offsets_out; + } + + /* Initialize a tokenizer iterator to iterate through column iCol. */ + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, + zDoc, nDoc, &pC + ); + if( rc!=SQLITE_OK ) goto offsets_out; + + rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); + while( rc==SQLITE_OK ){ + int i; /* Used to loop through terms */ + int iMinPos = 0x7FFFFFFF; /* Position of next token */ + TermOffset *pTerm = 0; /* TermOffset associated with next token */ + + for(i=0; ipList && (pT->iPos-pT->iOff)iPos-pT->iOff; + pTerm = pT; + } + } + + if( !pTerm ){ + /* All offsets for this column have been gathered. */ + rc = SQLITE_DONE; + }else{ + assert_fts3_nc( iCurrent<=iMinPos ); + if( 0==(0xFE&*pTerm->pList) ){ + pTerm->pList = 0; + }else{ + fts3GetDeltaPosition(&pTerm->pList, &pTerm->iPos); + } + while( rc==SQLITE_OK && iCurrentxNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); + } + if( rc==SQLITE_OK ){ + char aBuffer[64]; + sqlite3_snprintf(sizeof(aBuffer), aBuffer, + "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart + ); + rc = fts3StringAppend(&res, aBuffer, -1); + }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){ + rc = FTS_CORRUPT_VTAB; + } + } + } + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + + pMod->xClose(pC); + if( rc!=SQLITE_OK ) goto offsets_out; + } + + offsets_out: + sqlite3_free(sCtx.aTerm); + assert( rc!=SQLITE_DONE ); + sqlite3Fts3SegmentsClose(pTab); + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + sqlite3_free(res.z); + }else{ + sqlite3_result_text(pCtx, res.z, res.n-1, sqlite3_free); + } + return; +} + +/* +** Implementation of matchinfo() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Matchinfo( + sqlite3_context *pContext, /* Function call context */ + Fts3Cursor *pCsr, /* FTS3 table cursor */ + const char *zArg /* Second arg to matchinfo() function */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + const char *zFormat; + + if( zArg ){ + zFormat = zArg; + }else{ + zFormat = FTS3_MATCHINFO_DEFAULT; + } + + if( !pCsr->pExpr ){ + sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); + return; + }else{ + /* Retrieve matchinfo() data. */ + fts3GetMatchinfo(pContext, pCsr, zFormat); + sqlite3Fts3SegmentsClose(pTab); + } +} + +#endif + +/************** End of fts3_snippet.c ****************************************/ +/************** Begin file fts3_unicode.c ************************************/ +/* +** 2012 May 24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Implementation of the "unicode" full-text-search tokenizer. +*/ + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_tokenizer.h" */ + +/* +** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied +** from the sqlite3 source file utf.c. If this file is compiled as part +** of the amalgamation, they are not required. +*/ +#ifndef SQLITE_AMALGAMATION + +static const unsigned char sqlite3Utf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + +#define READ_UTF8(zIn, zTerm, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = sqlite3Utf8Trans1[c-0xc0]; \ + while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + if( c<0x80 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ + } + +#define WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ +} + +#endif /* ifndef SQLITE_AMALGAMATION */ + +typedef struct unicode_tokenizer unicode_tokenizer; +typedef struct unicode_cursor unicode_cursor; + +struct unicode_tokenizer { + sqlite3_tokenizer base; + int eRemoveDiacritic; + int nException; + int *aiException; +}; + +struct unicode_cursor { + sqlite3_tokenizer_cursor base; + const unsigned char *aInput; /* Input text being tokenized */ + int nInput; /* Size of aInput[] in bytes */ + int iOff; /* Current offset within aInput[] */ + int iToken; /* Index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAlloc; /* space allocated at zToken */ +}; + + +/* +** Destroy a tokenizer allocated by unicodeCreate(). +*/ +static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){ + if( pTokenizer ){ + unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer; + sqlite3_free(p->aiException); + sqlite3_free(p); + } + return SQLITE_OK; +} + +/* +** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE +** statement has specified that the tokenizer for this table shall consider +** all characters in string zIn/nIn to be separators (if bAlnum==0) or +** token characters (if bAlnum==1). +** +** For each codepoint in the zIn/nIn string, this function checks if the +** sqlite3FtsUnicodeIsalnum() function already returns the desired result. +** If so, no action is taken. Otherwise, the codepoint is added to the +** unicode_tokenizer.aiException[] array. For the purposes of tokenization, +** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all +** codepoints in the aiException[] array. +** +** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic() +** identifies as a diacritic) occurs in the zIn/nIn string it is ignored. +** It is not possible to change the behavior of the tokenizer with respect +** to these codepoints. +*/ +static int unicodeAddExceptions( + unicode_tokenizer *p, /* Tokenizer to add exceptions to */ + int bAlnum, /* Replace Isalnum() return value with this */ + const char *zIn, /* Array of characters to make exceptions */ + int nIn /* Length of z in bytes */ +){ + const unsigned char *z = (const unsigned char *)zIn; + const unsigned char *zTerm = &z[nIn]; + unsigned int iCode; + int nEntry = 0; + + assert( bAlnum==0 || bAlnum==1 ); + + while( zaiException,(p->nException+nEntry)*sizeof(int)); + if( aNew==0 ) return SQLITE_NOMEM; + nNew = p->nException; + + z = (const unsigned char *)zIn; + while( zi; j--) aNew[j] = aNew[j-1]; + aNew[i] = (int)iCode; + nNew++; + } + } + p->aiException = aNew; + p->nException = nNew; + } + + return SQLITE_OK; +} + +/* +** Return true if the p->aiException[] array contains the value iCode. +*/ +static int unicodeIsException(unicode_tokenizer *p, int iCode){ + if( p->nException>0 ){ + int *a = p->aiException; + int iLo = 0; + int iHi = p->nException-1; + + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( iCode==a[iTest] ){ + return 1; + }else if( iCode>a[iTest] ){ + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + } + + return 0; +} + +/* +** Return true if, for the purposes of tokenization, codepoint iCode is +** considered a token character (not a separator). +*/ +static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){ + assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 ); + return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode); +} + +/* +** Create a new tokenizer instance. +*/ +static int unicodeCreate( + int nArg, /* Size of array argv[] */ + const char * const *azArg, /* Tokenizer creation arguments */ + sqlite3_tokenizer **pp /* OUT: New tokenizer handle */ +){ + unicode_tokenizer *pNew; /* New tokenizer object */ + int i; + int rc = SQLITE_OK; + + pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer)); + if( pNew==NULL ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(unicode_tokenizer)); + pNew->eRemoveDiacritic = 1; + + for(i=0; rc==SQLITE_OK && ieRemoveDiacritic = 1; + } + else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ + pNew->eRemoveDiacritic = 0; + } + else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){ + pNew->eRemoveDiacritic = 2; + } + else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){ + rc = unicodeAddExceptions(pNew, 1, &z[11], n-11); + } + else if( n>=11 && memcmp("separators=", z, 11)==0 ){ + rc = unicodeAddExceptions(pNew, 0, &z[11], n-11); + } + else{ + /* Unrecognized argument */ + rc = SQLITE_ERROR; + } + } + + if( rc!=SQLITE_OK ){ + unicodeDestroy((sqlite3_tokenizer *)pNew); + pNew = 0; + } + *pp = (sqlite3_tokenizer *)pNew; + return rc; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int unicodeOpen( + sqlite3_tokenizer *p, /* The tokenizer */ + const char *aInput, /* Input string */ + int nInput, /* Size of string aInput in bytes */ + sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ +){ + unicode_cursor *pCsr; + + pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(unicode_cursor)); + + pCsr->aInput = (const unsigned char *)aInput; + if( aInput==0 ){ + pCsr->nInput = 0; + pCsr->aInput = (const unsigned char*)""; + }else if( nInput<0 ){ + pCsr->nInput = (int)strlen(aInput); + }else{ + pCsr->nInput = nInput; + } + + *pp = &pCsr->base; + UNUSED_PARAMETER(p); + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){ + unicode_cursor *pCsr = (unicode_cursor *) pCursor; + sqlite3_free(pCsr->zToken); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int unicodeNext( + sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */ + const char **paToken, /* OUT: Token text */ + int *pnToken, /* OUT: Number of bytes at *paToken */ + int *piStart, /* OUT: Starting offset of token */ + int *piEnd, /* OUT: Ending offset of token */ + int *piPos /* OUT: Position integer of token */ +){ + unicode_cursor *pCsr = (unicode_cursor *)pC; + unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer); + unsigned int iCode = 0; + char *zOut; + const unsigned char *z = &pCsr->aInput[pCsr->iOff]; + const unsigned char *zStart = z; + const unsigned char *zEnd; + const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput]; + + /* Scan past any delimiter characters before the start of the next token. + ** Return SQLITE_DONE early if this takes us all the way to the end of + ** the input. */ + while( z=zTerm ) return SQLITE_DONE; + + zOut = pCsr->zToken; + do { + int iOut; + + /* Grow the output buffer if required. */ + if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ + char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64); + if( !zNew ) return SQLITE_NOMEM; + zOut = &zNew[zOut - pCsr->zToken]; + pCsr->zToken = zNew; + pCsr->nAlloc += 64; + } + + /* Write the folded case of the last character read to the output */ + zEnd = z; + iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic); + if( iOut ){ + WRITE_UTF8(zOut, iOut); + } + + /* If the cursor is not at EOF, read the next character */ + if( z>=zTerm ) break; + READ_UTF8(z, zTerm, iCode); + }while( unicodeIsAlnum(p, (int)iCode) + || sqlite3FtsUnicodeIsdiacritic((int)iCode) + ); + + /* Set the output variables and return. */ + pCsr->iOff = (int)(z - pCsr->aInput); + *paToken = pCsr->zToken; + *pnToken = (int)(zOut - pCsr->zToken); + *piStart = (int)(zStart - pCsr->aInput); + *piEnd = (int)(zEnd - pCsr->aInput); + *piPos = pCsr->iToken++; + return SQLITE_OK; +} + +/* +** Set *ppModule to a pointer to the sqlite3_tokenizer_module +** structure for the unicode tokenizer. +*/ +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){ + static const sqlite3_tokenizer_module module = { + 0, + unicodeCreate, + unicodeDestroy, + unicodeOpen, + unicodeClose, + unicodeNext, + 0, + }; + *ppModule = &module; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ +#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ + +/************** End of fts3_unicode.c ****************************************/ +/************** Begin file fts3_unicode2.c ***********************************/ +/* +** 2012-05-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +*/ + +/* +** DO NOT EDIT THIS MACHINE GENERATED FILE. +*/ + +#ifndef SQLITE_DISABLE_FTS3_UNICODE +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) + +/* #include */ + +/* +** Return true if the argument corresponds to a unicode codepoint +** classified as either a letter or a number. Otherwise false. +** +** The results are undefined if the value passed to this function +** is less than zero. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ + /* Each unsigned integer in the following array corresponds to a contiguous + ** range of unicode codepoints that are not either letters or numbers (i.e. + ** codepoints for which this function should return 0). + ** + ** The most significant 22 bits in each 32-bit value contain the first + ** codepoint in the range. The least significant 10 bits are used to store + ** the size of the range (always at least 1). In other words, the value + ** ((C<<22) + N) represents a range of N codepoints starting with codepoint + ** C. It is not possible to represent a range larger than 1023 codepoints + ** using this format. + */ + static const unsigned int aEntry[] = { + 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, + 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, + 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, + 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, + 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, + 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, + 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, + 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, + 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, + 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, + 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, + 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, + 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, + 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, + 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, + 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, + 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, + 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, + 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, + 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, + 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, + 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, + 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, + 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, + 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, + 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, + 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, + 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, + 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, + 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, + 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, + 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, + 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, + 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, + 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, + 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, + 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, + 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, + 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, + 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, + 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, + 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, + 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, + 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, + 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, + 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, + 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, + 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, + 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, + 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, + 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, + 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, + 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, + 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, + 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, + 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, + 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, + 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, + 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, + 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, + 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, + 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, + 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, + 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, + 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, + 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, + 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, + 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, + 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, + 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, + 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, + 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, + 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, + 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, + 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, + 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, + 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, + 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, + 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, + 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, + 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, + 0x380400F0, + }; + static const unsigned int aAscii[4] = { + 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, + }; + + if( (unsigned int)c<128 ){ + return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 ); + }else if( (unsigned int)c<(1<<22) ){ + unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; + int iRes = 0; + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; + int iLo = 0; + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( key >= aEntry[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( aEntry[0]=aEntry[iRes] ); + return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); + } + return 1; +} + + +/* +** If the argument is a codepoint corresponding to a lowercase letter +** in the ASCII range with a diacritic added, return the codepoint +** of the ASCII letter only. For example, if passed 235 - "LATIN +** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER +** E"). The resuls of passing a codepoint that corresponds to an +** uppercase letter are undefined. +*/ +static int remove_diacritic(int c, int bComplex){ + unsigned short aDia[] = { + 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, + 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, + 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, + 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, + 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896, + 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106, + 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344, + 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198, + 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468, + 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704, + 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, + 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, + 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, + 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, + 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, + 63182, 63242, 63274, 63310, 63368, 63390, + }; +#define HIBIT ((unsigned char)0x80) + unsigned char aChar[] = { + '\0', 'a', 'c', 'e', 'i', 'n', + 'o', 'u', 'y', 'y', 'a', 'c', + 'd', 'e', 'e', 'g', 'h', 'i', + 'j', 'k', 'l', 'n', 'o', 'r', + 's', 't', 'u', 'u', 'w', 'y', + 'z', 'o', 'u', 'a', 'i', 'o', + 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o', + 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a', + 'e', 'i', 'o', 'r', 'u', 's', + 't', 'h', 'a', 'e', 'o'|HIBIT, 'o', + 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', 'a', 'b', + 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT, + 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT, + 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n', + 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's', + 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w', + 'w', 'x', 'y', 'z', 'h', 't', + 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, + 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT, + 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y', + }; + + unsigned int key = (((unsigned int)c)<<3) | 0x00000007; + int iRes = 0; + int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; + int iLo = 0; + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( key >= aDia[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( key>=aDia[iRes] ); + if( bComplex==0 && (aChar[iRes] & 0x80) ) return c; + return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F); +} + + +/* +** Return true if the argument interpreted as a unicode codepoint +** is a diacritical modifier character. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ + unsigned int mask0 = 0x08029FDF; + unsigned int mask1 = 0x000361F8; + if( c<768 || c>817 ) return 0; + return (c < 768+32) ? + (mask0 & ((unsigned int)1 << (c-768))) : + (mask1 & ((unsigned int)1 << (c-768-32))); +} + + +/* +** Interpret the argument as a unicode codepoint. If the codepoint +** is an upper case character that has a lower case equivalent, +** return the codepoint corresponding to the lower case version. +** Otherwise, return a copy of the argument. +** +** The results are undefined if the value passed to this function +** is less than zero. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ + /* Each entry in the following array defines a rule for folding a range + ** of codepoints to lower case. The rule applies to a range of nRange + ** codepoints starting at codepoint iCode. + ** + ** If the least significant bit in flags is clear, then the rule applies + ** to all nRange codepoints (i.e. all nRange codepoints are upper case and + ** need to be folded). Or, if it is set, then the rule only applies to + ** every second codepoint in the range, starting with codepoint C. + ** + ** The 7 most significant bits in flags are an index into the aiOff[] + ** array. If a specific codepoint C does require folding, then its lower + ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF). + ** + ** The contents of this array are generated by parsing the CaseFolding.txt + ** file distributed as part of the "Unicode Character Database". See + ** http://www.unicode.org for details. + */ + static const struct TableEntry { + unsigned short iCode; + unsigned char flags; + unsigned char nRange; + } aEntry[] = { + {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, + {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, + {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, + {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, + {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, + {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, + {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, + {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, + {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, + {413, 54, 1}, {415, 56, 1}, {416, 1, 6}, + {422, 60, 1}, {423, 0, 1}, {425, 60, 1}, + {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, + {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, + {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, + {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, + {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, + {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, + {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, + {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, + {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, + {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, + {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, + {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, + {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, + {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, + {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, + {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, + {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, + {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, + {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, + {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, + {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, + {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, + {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, + {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, + {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, + {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, + {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, + {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, + {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, + {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, + {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, + {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, + {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, + {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, + {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, + {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, + {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, + {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, + {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, + {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, + {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, + {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, + {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, + {65313, 14, 26}, + }; + static const unsigned short aiOff[] = { + 1, 2, 8, 15, 16, 26, 28, 32, + 37, 38, 40, 48, 63, 64, 69, 71, + 79, 80, 116, 202, 203, 205, 206, 207, + 209, 210, 211, 213, 214, 217, 218, 219, + 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, + 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, + 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, + 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, + 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, + 65514, 65521, 65527, 65528, 65529, + }; + + int ret = c; + + assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 ); + + if( c<128 ){ + if( c>='A' && c<='Z' ) ret = c + ('a' - 'A'); + }else if( c<65536 ){ + const struct TableEntry *p; + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; + int iLo = 0; + int iRes = -1; + + assert( c>aEntry[0].iCode ); + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + int cmp = (c - aEntry[iTest].iCode); + if( cmp>=0 ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + + assert( iRes>=0 && c>=aEntry[iRes].iCode ); + p = &aEntry[iRes]; + if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ + ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; + assert( ret>0 ); + } + + if( eRemoveDiacritic ){ + ret = remove_diacritic(ret, eRemoveDiacritic==2); + } + } + + else if( c>=66560 && c<66600 ){ + ret = c + 40; + } + + return ret; +} +#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ +#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ + +/************** End of fts3_unicode2.c ***************************************/ +/************** Begin file json.c ********************************************/ +/* +** 2015-08-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** SQLite JSON functions. +** +** This file began as an extension in ext/misc/json1.c in 2015. That +** extension proved so useful that it has now been moved into the core. +** +** The original design stored all JSON as pure text, canonical RFC-8259. +** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). +** All generated JSON text still conforms strictly to RFC-8259, but text +** with JSON-5 extensions is accepted as input. +** +** Beginning with version 3.45.0 (circa 2024-01-01), these routines also +** accept BLOB values that have JSON encoded using a binary representation +** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk +** format SQLite JSONB is completely different and incompatible with +** PostgreSQL JSONB. +** +** Decoding and interpreting JSONB is still O(N) where N is the size of +** the input, the same as text JSON. However, the constant of proportionality +** for JSONB is much smaller due to faster parsing. The size of each +** element in JSONB is encoded in its header, so there is no need to search +** for delimiters using persnickety syntax rules. JSONB seems to be about +** 3x faster than text JSON as a result. JSONB is also tends to be slightly +** smaller than text JSON, by 5% or 10%, but there are corner cases where +** JSONB can be slightly larger. So you are not far mistaken to say that +** a JSONB blob is the same size as the equivalent RFC-8259 text. +** +** +** THE JSONB ENCODING: +** +** Every JSON element is encoded in JSONB as a header and a payload. +** The header is between 1 and 9 bytes in size. The payload is zero +** or more bytes. +** +** The lower 4 bits of the first byte of the header determines the +** element type: +** +** 0: NULL +** 1: TRUE +** 2: FALSE +** 3: INT -- RFC-8259 integer literal +** 4: INT5 -- JSON5 integer literal +** 5: FLOAT -- RFC-8259 floating point literal +** 6: FLOAT5 -- JSON5 floating point literal +** 7: TEXT -- Text literal acceptable to both SQL and JSON +** 8: TEXTJ -- Text containing RFC-8259 escapes +** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes +** 10: TEXTRAW -- Text containing unescaped syntax characters +** 11: ARRAY +** 12: OBJECT +** +** The other three possible values (13-15) are reserved for future +** enhancements. +** +** The upper 4 bits of the first byte determine the size of the header +** and sometimes also the size of the payload. If X is the first byte +** of the element and if X>>4 is between 0 and 11, then the payload +** will be that many bytes in size and the header is exactly one byte +** in size. Other four values for X>>4 (12-15) indicate that the header +** is more than one byte in size and that the payload size is determined +** by the remainder of the header, interpreted as a unsigned big-endian +** integer. +** +** Value of X>>4 Size integer Total header size +** ------------- -------------------- ----------------- +** 12 1 byte (0-255) 2 +** 13 2 byte (0-65535) 3 +** 14 4 byte (0-4294967295) 5 +** 15 8 byte (0-1.8e19) 9 +** +** The payload size need not be expressed in its minimal form. For example, +** if the payload size is 10, the size can be expressed in any of 5 different +** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, +** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by +** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and +** a single byte of 0x0a. The shorter forms are preferred, of course, but +** sometimes when generating JSONB, the payload size is not known in advance +** and it is convenient to reserve sufficient header space to cover the +** largest possible payload size and then come back later and patch up +** the size when it becomes known, resulting in a non-minimal encoding. +** +** The value (X>>4)==15 is not actually used in the current implementation +** (as SQLite is currently unable handle BLOBs larger than about 2GB) +** but is included in the design to allow for future enhancements. +** +** The payload follows the header. NULL, TRUE, and FALSE have no payload and +** their payload size must always be zero. The payload for INT, INT5, +** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the +** "..." or '...' delimiters are omitted from the various text encodings. +** The payload for ARRAY and OBJECT is a list of additional elements that +** are the content for the array or object. The payload for an OBJECT +** must be an even number of elements. The first element of each pair is +** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW. +** +** A valid JSONB blob consists of a single element, as described above. +** Usually this will be an ARRAY or OBJECT element which has many more +** elements as its content. But the overall blob is just a single element. +** +** Input validation for JSONB blobs simply checks that the element type +** code is between 0 and 12 and that the total size of the element +** (header plus payload) is the same as the size of the BLOB. If those +** checks are true, the BLOB is assumed to be JSONB and processing continues. +** Errors are only raised if some other miscoding is discovered during +** processing. +** +** Additional information can be found in the doc/jsonb.md file of the +** canonical SQLite source tree. +*/ +#ifndef SQLITE_OMIT_JSON +/* #include "sqliteInt.h" */ + +/* JSONB element types +*/ +#define JSONB_NULL 0 /* "null" */ +#define JSONB_TRUE 1 /* "true" */ +#define JSONB_FALSE 2 /* "false" */ +#define JSONB_INT 3 /* integer acceptable to JSON and SQL */ +#define JSONB_INT5 4 /* integer in 0x000 notation */ +#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */ +#define JSONB_FLOAT5 6 /* float with JSON5 extensions */ +#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */ +#define JSONB_TEXTJ 8 /* Text with JSON escapes */ +#define JSONB_TEXT5 9 /* Text with JSON-5 escape */ +#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */ +#define JSONB_ARRAY 11 /* An array */ +#define JSONB_OBJECT 12 /* An object */ + +/* Human-readable names for the JSONB values. The index for each +** string must correspond to the JSONB_* integer above. +*/ +static const char * const jsonbType[] = { + "null", "true", "false", "integer", "integer", + "real", "real", "text", "text", "text", + "text", "array", "object", "", "", "", "" +}; + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function, resulting in a 7% overall performance +** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +*/ +static const char jsonIsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) + +/* +** The set of all space characters recognized by jsonIsspace(). +** Useful as the second argument to strspn(). +*/ +static const char jsonSpaces[] = "\011\012\015\040"; + +/* +** Characters that are special to JSON. Control characters, +** '"' and '\\' and '\''. Actually, '\'' is not special to +** canonical JSON, but it is special in JSON-5, so we include +** it in the set of special characters. +*/ +static const char jsonIsOk[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +/* Objects */ +typedef struct JsonCache JsonCache; +typedef struct JsonString JsonString; +typedef struct JsonParse JsonParse; + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) /* Cache entry */ +#define JSON_CACHE_SIZE 4 /* Max number of cache entries */ + +/* +** jsonUnescapeOneChar() returns this invalid code point if it encounters +** a syntax error. +*/ +#define JSON_INVALID_CHAR 0x99999 + +/* A cache mapping JSON text into JSONB blobs. +** +** Each cache entry is a JsonParse object with the following restrictions: +** +** * The bReadOnly flag must be set +** +** * The aBlob[] array must be owned by the JsonParse object. In other +** words, nBlobAlloc must be non-zero. +** +** * eEdit and delta must be zero. +** +** * zJson must be an RCStr. In other words bJsonIsRCStr must be true. +*/ +struct JsonCache { + sqlite3 *db; /* Database connection */ + int nUsed; /* Number of active entries in the cache */ + JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */ +}; + +/* An instance of this object represents a JSON string +** under construction. Really, this is a generic string accumulator +** that can be and is used to create strings other than JSON. +** +** If the generated string is longer than will fit into the zSpace[] buffer, +** then it will be an RCStr string. This aids with caching of large +** JSON strings. +*/ +struct JsonString { + sqlite3_context *pCtx; /* Function context - put error messages here */ + char *zBuf; /* Append JSON content here */ + u64 nAlloc; /* Bytes of storage available in zBuf[] */ + u64 nUsed; /* Bytes of zBuf[] currently used */ + u8 bStatic; /* True if zBuf is static space */ + u8 eErr; /* True if an error has been encountered */ + char zSpace[100]; /* Initial static space */ +}; + +/* Allowed values for JsonString.eErr */ +#define JSTRING_OOM 0x01 /* Out of memory */ +#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ +#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */ + +/* The "subtype" set for text JSON values passed through using +** sqlite3_result_subtype() and sqlite3_value_subtype(). +*/ +#define JSON_SUBTYPE 74 /* Ascii for "J" */ + +/* +** Bit values for the flags passed into various SQL function implementations +** via the sqlite3_user_data() value. +*/ +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +#define JSON_BLOB 0x08 /* Use the BLOB output format */ + + +/* A parsed JSON value. Lifecycle: +** +** 1. JSON comes in and is parsed into a JSONB value in aBlob. The +** original text is stored in zJson. This step is skipped if the +** input is JSONB instead of text JSON. +** +** 2. The aBlob[] array is searched using the JSON path notation, if needed. +** +** 3. Zero or more changes are made to aBlob[] (via json_remove() or +** json_replace() or json_patch() or similar). +** +** 4. New JSON text is generated from the aBlob[] for output. This step +** is skipped if the function is one of the jsonb_* functions that +** returns JSONB instead of text JSON. +*/ +struct JsonParse { + u8 *aBlob; /* JSONB representation of JSON value */ + u32 nBlob; /* Bytes of aBlob[] actually used */ + u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */ + char *zJson; /* Json text used for parsing */ + sqlite3 *db; /* The database connection to which this object belongs */ + int nJson; /* Length of the zJson string in bytes */ + u32 nJPRef; /* Number of references to this object */ + u32 iErr; /* Error location in zJson[] */ + u16 iDepth; /* Nesting depth */ + u8 nErr; /* Number of errors seen */ + u8 oom; /* Set to true if out of memory */ + u8 bJsonIsRCStr; /* True if zJson is an RCStr */ + u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ + u8 bReadOnly; /* Do not modify. */ + /* Search and edit information. See jsonLookupStep() */ + u8 eEdit; /* Edit operation to apply */ + int delta; /* Size change due to the edit */ + u32 nIns; /* Number of bytes to insert */ + u32 iLabel; /* Location of label if search landed on an object value */ + u8 *aIns; /* Content to be inserted */ +}; + +/* Allowed values for JsonParse.eEdit */ +#define JEDIT_DEL 1 /* Delete if exists */ +#define JEDIT_REPL 2 /* Overwrite if exists */ +#define JEDIT_INS 3 /* Insert if not exists */ +#define JEDIT_SET 4 /* Insert or overwrite */ + +/* +** Maximum nesting depth of JSON for this implementation. +** +** This limit is needed to avoid a stack overflow in the recursive +** descent parser. A depth of 1000 is far deeper than any sane JSON +** should go. Historical note: This limit was 2000 prior to version 3.42.0 +*/ +#ifndef SQLITE_JSON_MAX_DEPTH +# define JSON_MAX_DEPTH 1000 +#else +# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH +#endif + +/* +** Allowed values for the flgs argument to jsonParseFuncArg(); +*/ +#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ +#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ + +/************************************************************************** +** Forward references +**************************************************************************/ +static void jsonReturnStringAsBlob(JsonString*); +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); +static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); +static void jsonReturnParse(sqlite3_context*,JsonParse*); +static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); +static void jsonParseFree(JsonParse*); +static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); +static u32 jsonUnescapeOneChar(const char*, u32, u32*); + +/************************************************************************** +** Utility routines for dealing with JsonCache objects +**************************************************************************/ + +/* +** Free a JsonCache object. +*/ +static void jsonCacheDelete(JsonCache *p){ + int i; + for(i=0; inUsed; i++){ + jsonParseFree(p->a[i]); + } + sqlite3DbFree(p->db, p); +} +static void jsonCacheDeleteGeneric(void *p){ + jsonCacheDelete((JsonCache*)p); +} + +/* +** Insert a new entry into the cache. If the cache is full, expel +** the least recently used entry. Return SQLITE_OK on success or a +** result code otherwise. +** +** Cache entries are stored in age order, oldest first. +*/ +static int jsonCacheInsert( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + JsonParse *pParse /* The parse object to be added to the cache */ +){ + JsonCache *p; + + assert( pParse->zJson!=0 ); + assert( pParse->bJsonIsRCStr ); + assert( pParse->delta==0 ); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + sqlite3 *db = sqlite3_context_db_handle(ctx); + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + p->db = db; + sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ) return SQLITE_NOMEM; + } + if( p->nUsed >= JSON_CACHE_SIZE ){ + jsonParseFree(p->a[0]); + memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0])); + p->nUsed = JSON_CACHE_SIZE-1; + } + assert( pParse->nBlobAlloc>0 ); + pParse->eEdit = 0; + pParse->nJPRef++; + pParse->bReadOnly = 1; + p->a[p->nUsed] = pParse; + p->nUsed++; + return SQLITE_OK; +} + +/* +** Search for a cached translation the json text supplied by pArg. Return +** the JsonParse object if found. Return NULL if not found. +** +** When a match if found, the matching entry is moved to become the +** most-recently used entry if it isn't so already. +** +** The JsonParse object returned still belongs to the Cache and might +** be deleted at any moment. If the caller whants the JsonParse to +** linger, it needs to increment the nPJRef reference counter. +*/ +static JsonParse *jsonCacheSearch( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + sqlite3_value *pArg /* Function argument containing SQL text */ +){ + JsonCache *p; + int i; + const char *zJson; + int nJson; + + if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){ + return 0; + } + zJson = (const char*)sqlite3_value_text(pArg); + if( zJson==0 ) return 0; + nJson = sqlite3_value_bytes(pArg); + + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + return 0; + } + for(i=0; inUsed; i++){ + if( p->a[i]->zJson==zJson ) break; + } + if( i>=p->nUsed ){ + for(i=0; inUsed; i++){ + if( p->a[i]->nJson!=nJson ) continue; + if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break; + } + } + if( inUsed ){ + if( inUsed-1 ){ + /* Make the matching entry the most recently used entry */ + JsonParse *tmp = p->a[i]; + memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp)); + p->a[p->nUsed-1] = tmp; + i = p->nUsed - 1; + } + assert( p->a[i]->delta==0 ); + return p->a[i]; + }else{ + return 0; + } +} + +/************************************************************************** +** Utility routines for dealing with JsonString objects +**************************************************************************/ + +/* Turn uninitialized bulk memory into a valid JsonString object +** holding a zero-length string. +*/ +static void jsonStringZero(JsonString *p){ + p->zBuf = p->zSpace; + p->nAlloc = sizeof(p->zSpace); + p->nUsed = 0; + p->bStatic = 1; +} + +/* Initialize the JsonString object +*/ +static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){ + p->pCtx = pCtx; + p->eErr = 0; + jsonStringZero(p); +} + +/* Free all allocated memory and reset the JsonString object back to its +** initial state. +*/ +static void jsonStringReset(JsonString *p){ + if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); + jsonStringZero(p); +} + +/* Report an out-of-memory (OOM) condition +*/ +static void jsonStringOom(JsonString *p){ + p->eErr |= JSTRING_OOM; + if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx); + jsonStringReset(p); +} + +/* Enlarge pJson->zBuf so that it can hold at least N more bytes. +** Return zero on success. Return non-zero on an OOM error +*/ +static int jsonStringGrow(JsonString *p, u32 N){ + u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; + char *zNew; + if( p->bStatic ){ + if( p->eErr ) return 1; + zNew = sqlite3RCStrNew(nTotal); + if( zNew==0 ){ + jsonStringOom(p); + return SQLITE_NOMEM; + } + memcpy(zNew, p->zBuf, (size_t)p->nUsed); + p->zBuf = zNew; + p->bStatic = 0; + }else{ + p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); + if( p->zBuf==0 ){ + p->eErr |= JSTRING_OOM; + jsonStringZero(p); + return SQLITE_NOMEM; + } + } + p->nAlloc = nTotal; + return SQLITE_OK; +} + +/* Append N bytes from zIn onto the end of the JsonString string. +*/ +static SQLITE_NOINLINE void jsonStringExpandAndAppend( + JsonString *p, + const char *zIn, + u32 N +){ + assert( N>0 ); + if( jsonStringGrow(p,N) ) return; + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; +} +static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ + if( N==0 ) return; + if( N+p->nUsed >= p->nAlloc ){ + jsonStringExpandAndAppend(p,zIn,N); + }else{ + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; + } +} +static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ + assert( N>0 ); + if( N+p->nUsed >= p->nAlloc ){ + jsonStringExpandAndAppend(p,zIn,N); + }else{ + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; + } +} + + +/* Append formatted text (not to exceed N bytes) to the JsonString. +*/ +static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ + va_list ap; + if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return; + va_start(ap, zFormat); + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); + va_end(ap); + p->nUsed += (int)strlen(p->zBuf+p->nUsed); +} + +/* Append a single character +*/ +static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ + if( jsonStringGrow(p,1) ) return; + p->zBuf[p->nUsed++] = c; +} +static void jsonAppendChar(JsonString *p, char c){ + if( p->nUsed>=p->nAlloc ){ + jsonAppendCharExpand(p,c); + }else{ + p->zBuf[p->nUsed++] = c; + } +} + +/* Remove a single character from the end of the string +*/ +static void jsonStringTrimOneChar(JsonString *p){ + if( p->eErr==0 ){ + assert( p->nUsed>0 ); + p->nUsed--; + } +} + + +/* Make sure there is a zero terminator on p->zBuf[] +** +** Return true on success. Return false if an OOM prevents this +** from happening. +*/ +static int jsonStringTerminate(JsonString *p){ + jsonAppendChar(p, 0); + jsonStringTrimOneChar(p); + return p->eErr==0; +} + +/* Append a comma separator to the output buffer, if the previous +** character is not '[' or '{'. +*/ +static void jsonAppendSeparator(JsonString *p){ + char c; + if( p->nUsed==0 ) return; + c = p->zBuf[p->nUsed-1]; + if( c=='[' || c=='{' ) return; + jsonAppendChar(p, ','); +} + +/* Append the N-byte string in zIn to the end of the JsonString string +** under construction. Enclose the string in double-quotes ("...") and +** escape any double-quotes or backslash characters contained within the +** string. +** +** This routine is a high-runner. There is a measurable performance +** increase associated with unwinding the jsonIsOk[] loop. +*/ +static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ + u32 k; + u8 c; + const u8 *z = (const u8*)zIn; + if( z==0 ) return; + if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return; + p->zBuf[p->nUsed++] = '"'; + while( 1 /*exit-by-break*/ ){ + k = 0; + /* The following while() is the 4-way unwound equivalent of + ** + ** while( k=N ){ + while( k=N ){ + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + } + break; + } + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + z += k; + N -= k; + } + c = z[0]; + if( c=='"' || c=='\\' ){ + json_simple_escape: + if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = c; + }else if( c=='\'' ){ + p->zBuf[p->nUsed++] = c; + }else{ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + assert( c>=0 && cnUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = 'u'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; + p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; + } + z++; + N--; + } + p->zBuf[p->nUsed++] = '"'; + assert( p->nUsednAlloc ); +} + +/* +** Append an sqlite3_value (such as a function parameter) to the JSON +** string under construction in p. +*/ +static void jsonAppendSqlValue( + JsonString *p, /* Append to this JSON string */ + sqlite3_value *pValue /* Value to append */ +){ + switch( sqlite3_value_type(pValue) ){ + case SQLITE_NULL: { + jsonAppendRawNZ(p, "null", 4); + break; + } + case SQLITE_FLOAT: { + jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue)); + break; + } + case SQLITE_INTEGER: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + jsonAppendRaw(p, z, n); + break; + } + case SQLITE_TEXT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ + jsonAppendRaw(p, z, n); + }else{ + jsonAppendString(p, z, n); + } + break; + } + default: { + if( jsonFuncArgMightBeBinary(pValue) ){ + JsonParse px; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(pValue); + px.nBlob = sqlite3_value_bytes(pValue); + jsonTranslateBlobToText(&px, 0, p); + }else if( p->eErr==0 ){ + sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); + p->eErr = JSTRING_ERR; + jsonStringReset(p); + } + break; + } + } +} + +/* Make the text in p (which is probably a generated JSON text string) +** the result of the SQL function. +** +** The JsonString is reset. +** +** If pParse and ctx are both non-NULL, then the SQL string in p is +** loaded into the zJson field of the pParse object as a RCStr and the +** pParse is added to the cache. +*/ +static void jsonReturnString( + JsonString *p, /* String to return */ + JsonParse *pParse, /* JSONB source or NULL */ + sqlite3_context *ctx /* Where to cache */ +){ + assert( (pParse!=0)==(ctx!=0) ); + assert( ctx==0 || ctx==p->pCtx ); + if( p->eErr==0 ){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); + if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(p); + }else if( p->bStatic ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + }else if( jsonStringTerminate(p) ){ + if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ + int rc; + pParse->zJson = sqlite3RCStrRef(p->zBuf); + pParse->nJson = p->nUsed; + pParse->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, pParse); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(ctx); + jsonStringReset(p); + return; + } + } + sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, + sqlite3RCStrUnref, + SQLITE_UTF8); + }else{ + sqlite3_result_error_nomem(p->pCtx); + } + }else if( p->eErr & JSTRING_OOM ){ + sqlite3_result_error_nomem(p->pCtx); + }else if( p->eErr & JSTRING_MALFORMED ){ + sqlite3_result_error(p->pCtx, "malformed JSON", -1); + } + jsonStringReset(p); +} + +/************************************************************************** +** Utility routines for dealing with JsonParse objects +**************************************************************************/ + +/* +** Reclaim all memory allocated by a JsonParse object. But do not +** delete the JsonParse object itself. +*/ +static void jsonParseReset(JsonParse *pParse){ + assert( pParse->nJPRef<=1 ); + if( pParse->bJsonIsRCStr ){ + sqlite3RCStrUnref(pParse->zJson); + pParse->zJson = 0; + pParse->nJson = 0; + pParse->bJsonIsRCStr = 0; + } + if( pParse->nBlobAlloc ){ + sqlite3DbFree(pParse->db, pParse->aBlob); + pParse->aBlob = 0; + pParse->nBlob = 0; + pParse->nBlobAlloc = 0; + } +} + +/* +** Decrement the reference count on the JsonParse object. When the +** count reaches zero, free the object. +*/ +static void jsonParseFree(JsonParse *pParse){ + if( pParse ){ + if( pParse->nJPRef>1 ){ + pParse->nJPRef--; + }else{ + jsonParseReset(pParse); + sqlite3DbFree(pParse->db, pParse); + } + } +} + +/************************************************************************** +** Utility routines for the JSON text parser +**************************************************************************/ + +/* +** Translate a single byte of Hex into an integer. +** This routine only gives a correct answer if h really is a valid hexadecimal +** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not +** assert() if the digit is not hex. +*/ +static u8 jsonHexToInt(int h){ +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} + +/* +** Convert a 4-byte hex string into an integer +*/ +static u32 jsonHexToInt4(const char *z){ + u32 v; + v = (jsonHexToInt(z[0])<<12) + + (jsonHexToInt(z[1])<<8) + + (jsonHexToInt(z[2])<<4) + + jsonHexToInt(z[3]); + return v; +} + +/* +** Return true if z[] begins with 2 (or more) hexadecimal digits +*/ +static int jsonIs2Hex(const char *z){ + return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]); +} + +/* +** Return true if z[] begins with 4 (or more) hexadecimal digits +*/ +static int jsonIs4Hex(const char *z){ + return jsonIs2Hex(z) && jsonIs2Hex(&z[2]); +} + +/* +** Return the number of bytes of JSON5 whitespace at the beginning of +** the input string z[]. +** +** JSON5 whitespace consists of any of the following characters: +** +** Unicode UTF-8 Name +** U+0009 09 horizontal tab +** U+000a 0a line feed +** U+000b 0b vertical tab +** U+000c 0c form feed +** U+000d 0d carriage return +** U+0020 20 space +** U+00a0 c2 a0 non-breaking space +** U+1680 e1 9a 80 ogham space mark +** U+2000 e2 80 80 en quad +** U+2001 e2 80 81 em quad +** U+2002 e2 80 82 en space +** U+2003 e2 80 83 em space +** U+2004 e2 80 84 three-per-em space +** U+2005 e2 80 85 four-per-em space +** U+2006 e2 80 86 six-per-em space +** U+2007 e2 80 87 figure space +** U+2008 e2 80 88 punctuation space +** U+2009 e2 80 89 thin space +** U+200a e2 80 8a hair space +** U+2028 e2 80 a8 line separator +** U+2029 e2 80 a9 paragraph separator +** U+202f e2 80 af narrow no-break space (NNBSP) +** U+205f e2 81 9f medium mathematical space (MMSP) +** U+3000 e3 80 80 ideographical space +** U+FEFF ef bb bf byte order mark +** +** In addition, comments between '/', '*' and '*', '/' and +** from '/', '/' to end-of-line are also considered to be whitespace. +*/ +static int json5Whitespace(const char *zIn){ + int n = 0; + const u8 *z = (u8*)zIn; + while( 1 /*exit by "goto whitespace_done"*/ ){ + switch( z[n] ){ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x20: { + n++; + break; + } + case '/': { + if( z[n+1]=='*' && z[n+2]!=0 ){ + int j; + for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){ + if( z[j]==0 ) goto whitespace_done; + } + n = j+1; + break; + }else if( z[n+1]=='/' ){ + int j; + char c; + for(j=n+2; (c = z[j])!=0; j++){ + if( c=='\n' || c=='\r' ) break; + if( 0xe2==(u8)c && 0x80==(u8)z[j+1] + && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]) + ){ + j += 2; + break; + } + } + n = j; + if( z[n] ) n++; + break; + } + goto whitespace_done; + } + case 0xc2: { + if( z[n+1]==0xa0 ){ + n += 2; + break; + } + goto whitespace_done; + } + case 0xe1: { + if( z[n+1]==0x9a && z[n+2]==0x80 ){ + n += 3; + break; + } + goto whitespace_done; + } + case 0xe2: { + if( z[n+1]==0x80 ){ + u8 c = z[n+2]; + if( c<0x80 ) goto whitespace_done; + if( c<=0x8a || c==0xa8 || c==0xa9 || c==0xaf ){ + n += 3; + break; + } + }else if( z[n+1]==0x81 && z[n+2]==0x9f ){ + n += 3; + break; + } + goto whitespace_done; + } + case 0xe3: { + if( z[n+1]==0x80 && z[n+2]==0x80 ){ + n += 3; + break; + } + goto whitespace_done; + } + case 0xef: { + if( z[n+1]==0xbb && z[n+2]==0xbf ){ + n += 3; + break; + } + goto whitespace_done; + } + default: { + goto whitespace_done; + } + } + } + whitespace_done: + return n; +} + +/* +** Extra floating-point literals to allow in JSON. +*/ +static const struct NanInfName { + char c1; + char c2; + char n; + char eType; + char nRepl; + char *zMatch; + char *zRepl; +} aNanInfName[] = { + { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" }, + { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" }, + { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" }, + { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" }, + { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" }, +}; + + +/* +** Report the wrong number of arguments for json_insert(), json_replace() +** or json_set(). +*/ +static void jsonWrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/**************************************************************************** +** Utility routines for dealing with the binary BLOB representation of JSON +****************************************************************************/ + +/* +** Expand pParse->aBlob so that it holds at least N bytes. +** +** Return the number of errors. +*/ +static int jsonBlobExpand(JsonParse *pParse, u32 N){ + u8 *aNew; + u32 t; + assert( N>pParse->nBlobAlloc ); + if( pParse->nBlobAlloc==0 ){ + t = 100; + }else{ + t = pParse->nBlobAlloc*2; + } + if( tdb, pParse->aBlob, t); + if( aNew==0 ){ pParse->oom = 1; return 1; } + pParse->aBlob = aNew; + pParse->nBlobAlloc = t; + return 0; +} + +/* +** If pParse->aBlob is not previously editable (because it is taken +** from sqlite3_value_blob(), as indicated by the fact that +** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable +** by making a copy into space obtained from malloc. +** +** Return true on success. Return false on OOM. +*/ +static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ + u8 *aOld; + u32 nSize; + assert( !pParse->bReadOnly ); + if( pParse->oom ) return 0; + if( pParse->nBlobAlloc>0 ) return 1; + aOld = pParse->aBlob; + nSize = pParse->nBlob + nExtra; + pParse->aBlob = 0; + if( jsonBlobExpand(pParse, nSize) ){ + return 0; + } + assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra ); + memcpy(pParse->aBlob, aOld, pParse->nBlob); + return 1; +} + +/* Expand pParse->aBlob and append one bytes. +*/ +static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( + JsonParse *pParse, + u8 c +){ + jsonBlobExpand(pParse, pParse->nBlob+1); + if( pParse->oom==0 ){ + assert( pParse->nBlob+1<=pParse->nBlobAlloc ); + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Append a single character. +*/ +static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ + if( pParse->nBlob >= pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendOneByte(pParse, c); + }else{ + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Slow version of jsonBlobAppendNode() that first resizes the +** pParse->aBlob structure. +*/ +static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); +static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + JsonParse *pParse, + u8 eType, + u32 szPayload, + const void *aPayload +){ + if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; + jsonBlobAppendNode(pParse, eType, szPayload, aPayload); +} + + +/* Append an node type byte together with the payload size and +** possibly also the payload. +** +** If aPayload is not NULL, then it is a pointer to the payload which +** is also appended. If aPayload is NULL, the pParse->aBlob[] array +** is resized (if necessary) so that it is big enough to hold the +** payload, but the payload is not appended and pParse->nBlob is left +** pointing to where the first byte of payload will eventually be. +*/ +static void jsonBlobAppendNode( + JsonParse *pParse, /* The JsonParse object under construction */ + u8 eType, /* Node type. One of JSONB_* */ + u32 szPayload, /* Number of bytes of payload */ + const void *aPayload /* The payload. Might be NULL */ +){ + u8 *a; + if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload); + return; + } + assert( pParse->aBlob!=0 ); + a = &pParse->aBlob[pParse->nBlob]; + if( szPayload<=11 ){ + a[0] = eType | (szPayload<<4); + pParse->nBlob += 1; + }else if( szPayload<=0xff ){ + a[0] = eType | 0xc0; + a[1] = szPayload & 0xff; + pParse->nBlob += 2; + }else if( szPayload<=0xffff ){ + a[0] = eType | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + pParse->nBlob += 3; + }else{ + a[0] = eType | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + pParse->nBlob += 5; + } + if( aPayload ){ + pParse->nBlob += szPayload; + memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload); + } +} + +/* Change the payload size for the node at index i to be szPayload. +*/ +static int jsonBlobChangePayloadSize( + JsonParse *pParse, + u32 i, + u32 szPayload +){ + u8 *a; + u8 szType; + u8 nExtra; + u8 nNeeded; + int delta; + if( pParse->oom ) return 0; + a = &pParse->aBlob[i]; + szType = a[0]>>4; + if( szType<=11 ){ + nExtra = 0; + }else if( szType==12 ){ + nExtra = 1; + }else if( szType==13 ){ + nExtra = 2; + }else{ + nExtra = 4; + } + if( szPayload<=11 ){ + nNeeded = 0; + }else if( szPayload<=0xff ){ + nNeeded = 1; + }else if( szPayload<=0xffff ){ + nNeeded = 2; + }else{ + nNeeded = 4; + } + delta = nNeeded - nExtra; + if( delta ){ + u32 newSize = pParse->nBlob + delta; + if( delta>0 ){ + if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ + return 0; /* OOM error. Error state recorded in pParse->oom. */ + } + a = &pParse->aBlob[i]; + memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); + }else{ + memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); + } + pParse->nBlob = newSize; + } + if( nNeeded==0 ){ + a[0] = (a[0] & 0x0f) | (szPayload<<4); + }else if( nNeeded==1 ){ + a[0] = (a[0] & 0x0f) | 0xc0; + a[1] = szPayload & 0xff; + }else if( nNeeded==2 ){ + a[0] = (a[0] & 0x0f) | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + }else{ + a[0] = (a[0] & 0x0f) | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + } + return delta; +} + +/* +** If z[0] is 'u' and is followed by exactly 4 hexadecimal character, +** then set *pOp to JSONB_TEXTJ and return true. If not, do not make +** any changes to *pOp and return false. +*/ +static int jsonIs4HexB(const char *z, int *pOp){ + if( z[0]!='u' ) return 0; + if( !jsonIs4Hex(&z[1]) ) return 0; + *pOp = JSONB_TEXTJ; + return 1; +} + +/* +** Check a single element of the JSONB in pParse for validity. +** +** The element to be checked starts at offset i and must end at on the +** last byte before iEnd. +** +** Return 0 if everything is correct. Return the 1-based byte offset of the +** error if a problem is detected. (In other words, if the error is at offset +** 0, return 1). +*/ +static u32 jsonbValidityCheck( + const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */ + u32 i, /* Start of element as pParse->aBlob[i] */ + u32 iEnd, /* One more than the last byte of the element */ + u32 iDepth /* Current nesting depth */ +){ + u32 n, sz, j, k; + const u8 *z; + u8 x; + if( iDepth>JSON_MAX_DEPTH ) return i+1; + sz = 0; + n = jsonbPayloadSize(pParse, i, &sz); + if( NEVER(n==0) ) return i+1; /* Checked by caller */ + if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */ + z = pParse->aBlob; + x = z[i] & 0x0f; + switch( x ){ + case JSONB_NULL: + case JSONB_TRUE: + case JSONB_FALSE: { + return n+sz==1 ? 0 : i+1; + } + case JSONB_INT: { + if( sz<1 ) return i+1; + j = i+n; + if( z[j]=='-' ){ + j++; + if( sz<2 ) return i+1; + } + k = i+n+sz; + while( jk ) return j+1; + if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1; + j++; + } + for(; j0 ) return j+1; + if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){ + return j+1; + } + seen = 1; + continue; + } + if( z[j]=='e' || z[j]=='E' ){ + if( seen==2 ) return j+1; + if( j==k-1 ) return j+1; + if( z[j+1]=='+' || z[j+1]=='-' ){ + j++; + if( j==k-1 ) return j+1; + } + seen = 2; + continue; + } + return j+1; + } + if( seen==0 ) return i+1; + return 0; + } + case JSONB_TEXT: { + j = i+n; + k = j+sz; + while( j=k ){ + return j+1; + }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ + j++; + }else if( z[j+1]=='u' ){ + if( j+5>=k ) return j+1; + if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1; + j++; + }else if( x!=JSONB_TEXT5 ){ + return j+1; + }else{ + u32 c = 0; + u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c); + if( c==JSON_INVALID_CHAR ) return j+1; + j += szC - 1; + } + } + j++; + } + return 0; + } + case JSONB_TEXTRAW: { + return 0; + } + case JSONB_ARRAY: { + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + j += n + sz; + } + assert( j==k ); + return 0; + } + case JSONB_OBJECT: { + u32 cnt = 0; + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + if( (cnt & 1)==0 ){ + x = z[j] & 0x0f; + if( xJSONB_TEXTRAW ) return j+1; + } + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + cnt++; + j += n + sz; + } + assert( j==k ); + if( (cnt & 1)!=0 ) return j+1; + return 0; + } + default: { + return i+1; + } + } +} + +/* +** Translate a single element of JSON text at pParse->zJson[i] into +** its equivalent binary JSONB representation. Append the translation into +** pParse->aBlob[] beginning at pParse->nBlob. The size of +** pParse->aBlob[] is increased as necessary. +** +** Return the index of the first character past the end of the element parsed, +** or one of the following special result codes: +** +** 0 End of input +** -1 Syntax error or OOM +** -2 '}' seen \ +** -3 ']' seen \___ For these returns, pParse->iErr is set to +** -4 ',' seen / the index in zJson[] of the seen character +** -5 ':' seen / +*/ +static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){ + char c; + u32 j; + u32 iThis, iStart; + int x; + u8 t; + const char *z = pParse->zJson; +json_parse_restart: + switch( (u8)z[i] ){ + case '{': { + /* Parse object */ + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0); + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + pParse->iErr = i; + return -1; + } + iStart = pParse->nBlob; + for(j=i+1;;j++){ + u32 iBlob = pParse->nBlob; + x = jsonTranslateTextToBlob(pParse, j); + if( x<=0 ){ + int op; + if( x==(-2) ){ + j = pParse->iErr; + if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1; + break; + } + j += json5Whitespace(&z[j]); + op = JSONB_TEXT; + if( sqlite3JsonId1(z[j]) + || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op)) + ){ + int k = j+1; + while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) + || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op)) + ){ + k++; + } + assert( iBlob==pParse->nBlob ); + jsonBlobAppendNode(pParse, op, k-j, &z[j]); + pParse->hasNonstd = 1; + x = k; + }else{ + if( x!=-1 ) pParse->iErr = j; + return -1; + } + } + if( pParse->oom ) return -1; + t = pParse->aBlob[iBlob] & 0x0f; + if( tJSONB_TEXTRAW ){ + pParse->iErr = j; + return -1; + } + j = x; + if( z[j]==':' ){ + j++; + }else{ + if( jsonIsspace(z[j]) ){ + /* strspn() is not helpful here */ + do{ j++; }while( jsonIsspace(z[j]) ); + if( z[j]==':' ){ + j++; + goto parse_object_value; + } + } + x = jsonTranslateTextToBlob(pParse, j); + if( x!=(-5) ){ + if( x!=(-1) ) pParse->iErr = j; + return -1; + } + j = pParse->iErr+1; + } + parse_object_value: + x = jsonTranslateTextToBlob(pParse, j); + if( x<=0 ){ + if( x!=(-1) ) pParse->iErr = j; + return -1; + } + j = x; + if( z[j]==',' ){ + continue; + }else if( z[j]=='}' ){ + break; + }else{ + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); + if( z[j]==',' ){ + continue; + }else if( z[j]=='}' ){ + break; + } + } + x = jsonTranslateTextToBlob(pParse, j); + if( x==(-4) ){ + j = pParse->iErr; + continue; + } + if( x==(-2) ){ + j = pParse->iErr; + break; + } + } + pParse->iErr = j; + return -1; + } + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); + pParse->iDepth--; + return j+1; + } + case '[': { + /* Parse array */ + iThis = pParse->nBlob; + assert( i<=(u32)pParse->nJson ); + jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); + iStart = pParse->nBlob; + if( pParse->oom ) return -1; + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + pParse->iErr = i; + return -1; + } + for(j=i+1;;j++){ + x = jsonTranslateTextToBlob(pParse, j); + if( x<=0 ){ + if( x==(-3) ){ + j = pParse->iErr; + if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1; + break; + } + if( x!=(-1) ) pParse->iErr = j; + return -1; + } + j = x; + if( z[j]==',' ){ + continue; + }else if( z[j]==']' ){ + break; + }else{ + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); + if( z[j]==',' ){ + continue; + }else if( z[j]==']' ){ + break; + } + } + x = jsonTranslateTextToBlob(pParse, j); + if( x==(-4) ){ + j = pParse->iErr; + continue; + } + if( x==(-3) ){ + j = pParse->iErr; + break; + } + } + pParse->iErr = j; + return -1; + } + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); + pParse->iDepth--; + return j+1; + } + case '\'': { + u8 opcode; + char cDelim; + pParse->hasNonstd = 1; + opcode = JSONB_TEXT; + goto parse_string; + case '"': + /* Parse string */ + opcode = JSONB_TEXT; + parse_string: + cDelim = z[i]; + j = i+1; + while( 1 /*exit-by-break*/ ){ + if( jsonIsOk[(u8)z[j]] ){ + if( !jsonIsOk[(u8)z[j+1]] ){ + j += 1; + }else if( !jsonIsOk[(u8)z[j+2]] ){ + j += 2; + }else{ + j += 3; + continue; + } + } + c = z[j]; + if( c==cDelim ){ + break; + }else if( c=='\\' ){ + c = z[++j]; + if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' + || c=='n' || c=='r' || c=='t' + || (c=='u' && jsonIs4Hex(&z[j+1])) ){ + if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; + }else if( c=='\'' || c=='0' || c=='v' || c=='\n' + || (0xe2==(u8)c && 0x80==(u8)z[j+1] + && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) + || (c=='x' && jsonIs2Hex(&z[j+1])) ){ + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; + }else if( c=='\r' ){ + if( z[j+1]=='\n' ) j++; + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; + }else{ + pParse->iErr = j; + return -1; + } + }else if( c<=0x1f ){ + /* Control characters are not allowed in strings */ + pParse->iErr = j; + return -1; + }else if( c=='"' ){ + opcode = JSONB_TEXT5; + } + j++; + } + jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]); + return j+1; + } + case 't': { + if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ + jsonBlobAppendOneByte(pParse, JSONB_TRUE); + return i+4; + } + pParse->iErr = i; + return -1; + } + case 'f': { + if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ + jsonBlobAppendOneByte(pParse, JSONB_FALSE); + return i+5; + } + pParse->iErr = i; + return -1; + } + case '+': { + u8 seenE; + pParse->hasNonstd = 1; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ + goto parse_number; + case '.': + if( sqlite3Isdigit(z[i+1]) ){ + pParse->hasNonstd = 1; + t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ + seenE = 0; + goto parse_number_2; + } + pParse->iErr = i; + return -1; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* Parse number */ + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ + parse_number: + seenE = 0; + assert( '-' < '0' ); + assert( '+' < '0' ); + assert( '.' < '0' ); + c = z[i]; + + if( c<='0' ){ + if( c=='0' ){ + if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ + assert( t==0x00 ); + pParse->hasNonstd = 1; + t = 0x01; + for(j=i+3; sqlite3Isxdigit(z[j]); j++){} + goto parse_number_finish; + }else if( sqlite3Isdigit(z[i+1]) ){ + pParse->iErr = i+1; + return -1; + } + }else{ + if( !sqlite3Isdigit(z[i+1]) ){ + /* JSON5 allows for "+Infinity" and "-Infinity" using exactly + ** that case. SQLite also allows these in any case and it allows + ** "+inf" and "-inf". */ + if( (z[i+1]=='I' || z[i+1]=='i') + && sqlite3StrNICmp(&z[i+1], "inf",3)==0 + ){ + pParse->hasNonstd = 1; + if( z[i]=='-' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + } + return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); + } + if( z[i+1]=='.' ){ + pParse->hasNonstd = 1; + t |= 0x01; + goto parse_number_2; + } + pParse->iErr = i; + return -1; + } + if( z[i+1]=='0' ){ + if( sqlite3Isdigit(z[i+2]) ){ + pParse->iErr = i+1; + return -1; + }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ + pParse->hasNonstd = 1; + t |= 0x01; + for(j=i+4; sqlite3Isxdigit(z[j]); j++){} + goto parse_number_finish; + } + } + } + } + + parse_number_2: + for(j=i+1;; j++){ + c = z[j]; + if( sqlite3Isdigit(c) ) continue; + if( c=='.' ){ + if( (t & 0x02)!=0 ){ + pParse->iErr = j; + return -1; + } + t |= 0x02; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ){ + if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ + pParse->hasNonstd = 1; + t |= 0x01; + }else{ + pParse->iErr = j; + return -1; + } + } + if( seenE ){ + pParse->iErr = j; + return -1; + } + t |= 0x02; + seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ){ + pParse->iErr = j; + return -1; + } + continue; + } + break; + } + if( z[j-1]<'0' ){ + if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ + pParse->hasNonstd = 1; + t |= 0x01; + }else{ + pParse->iErr = j; + return -1; + } + } + parse_number_finish: + assert( JSONB_INT+0x01==JSONB_INT5 ); + assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 ); + assert( JSONB_INT+0x02==JSONB_FLOAT ); + if( z[i]=='+' ) i++; + jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]); + return j; + } + case '}': { + pParse->iErr = i; + return -2; /* End of {...} */ + } + case ']': { + pParse->iErr = i; + return -3; /* End of [...] */ + } + case ',': { + pParse->iErr = i; + return -4; /* List separator */ + } + case ':': { + pParse->iErr = i; + return -5; /* Object label/value separator */ + } + case 0: { + return 0; /* End of file */ + } + case 0x09: + case 0x0a: + case 0x0d: + case 0x20: { + i += 1 + (u32)strspn(&z[i+1], jsonSpaces); + goto json_parse_restart; + } + case 0x0b: + case 0x0c: + case '/': + case 0xc2: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xef: { + j = json5Whitespace(&z[i]); + if( j>0 ){ + i += j; + pParse->hasNonstd = 1; + goto json_parse_restart; + } + pParse->iErr = i; + return -1; + } + case 'n': { + if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ + jsonBlobAppendOneByte(pParse, JSONB_NULL); + return i+4; + } + /* fall-through into the default case that checks for NaN */ + } + default: { + u32 k; + int nn; + c = z[i]; + for(k=0; khasNonstd = 1; + return i + nn; + } + pParse->iErr = i; + return -1; /* Syntax error */ + } + } /* End switch(z[i]) */ +} + + +/* +** Parse a complete JSON string. Return 0 on success or non-zero if there +** are any errors. If an error occurs, free all memory held by pParse, +** but not pParse itself. +** +** pParse must be initialized to an empty parse object prior to calling +** this routine. +*/ +static int jsonConvertTextToBlob( + JsonParse *pParse, /* Initialize and fill this JsonParse object */ + sqlite3_context *pCtx /* Report errors here */ +){ + int i; + const char *zJson = pParse->zJson; + i = jsonTranslateTextToBlob(pParse, 0); + if( pParse->oom ) i = -1; + if( i>0 ){ +#ifdef SQLITE_DEBUG + assert( pParse->iDepth==0 ); + if( sqlite3Config.bJsonSelfcheck ){ + assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 ); + } +#endif + while( jsonIsspace(zJson[i]) ) i++; + if( zJson[i] ){ + i += json5Whitespace(&zJson[i]); + if( zJson[i] ){ + if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1); + jsonParseReset(pParse); + return 1; + } + pParse->hasNonstd = 1; + } + } + if( i<=0 ){ + if( pCtx!=0 ){ + if( pParse->oom ){ + sqlite3_result_error_nomem(pCtx); + }else{ + sqlite3_result_error(pCtx, "malformed JSON", -1); + } + } + jsonParseReset(pParse); + return 1; + } + return 0; +} + +/* +** The input string pStr is a well-formed JSON text string. Convert +** this into the JSONB format and make it the return value of the +** SQL function. +*/ +static void jsonReturnStringAsBlob(JsonString *pStr){ + JsonParse px; + memset(&px, 0, sizeof(px)); + jsonStringTerminate(pStr); + if( pStr->eErr ){ + sqlite3_result_error_nomem(pStr->pCtx); + return; + } + px.zJson = pStr->zBuf; + px.nJson = pStr->nUsed; + px.db = sqlite3_context_db_handle(pStr->pCtx); + (void)jsonTranslateTextToBlob(&px, 0); + if( px.oom ){ + sqlite3DbFree(px.db, px.aBlob); + sqlite3_result_error_nomem(pStr->pCtx); + }else{ + assert( px.nBlobAlloc>0 ); + assert( !px.bReadOnly ); + sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); + } +} + +/* The byte at index i is a node type-code. This routine +** determines the payload size for that node and writes that +** payload size in to *pSz. It returns the offset from i to the +** beginning of the payload. Return 0 on error. +*/ +static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + u8 x; + u32 sz; + u32 n; + if( NEVER(i>pParse->nBlob) ){ + *pSz = 0; + return 0; + } + x = pParse->aBlob[i]>>4; + if( x<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = pParse->aBlob[i+1]; + n = 2; + }else if( x==13 ){ + if( i+2>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; + n = 3; + }else if( x==14 ){ + if( i+4>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; + n = 5; + }else{ + if( i+8>=pParse->nBlob + || pParse->aBlob[i+1]!=0 + || pParse->aBlob[i+2]!=0 + || pParse->aBlob[i+3]!=0 + || pParse->aBlob[i+4]!=0 + ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; + n = 9; + } + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta + ){ + sz = 0; + n = 0; + } + *pSz = sz; + return n; +} + + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToText( + const JsonParse *pParse, /* the complete parse of the JSON */ + u32 i, /* Start rendering at this index */ + JsonString *pOut /* Write JSON here */ +){ + u32 sz, n, j, iEnd; + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + jsonAppendRawNZ(pOut, "null", 4); + return i+1; + } + case JSONB_TRUE: { + jsonAppendRawNZ(pOut, "true", 4); + return i+1; + } + case JSONB_FALSE: { + jsonAppendRawNZ(pOut, "false", 5); + return i+1; + } + case JSONB_INT: + case JSONB_FLOAT: { + if( sz==0 ) goto malformed_jsonb; + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_INT5: { /* Integer literal in hexadecimal notation */ + u32 k = 2; + sqlite3_uint64 u = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + int bOverflow = 0; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + }else if( zIn[0]=='+' ){ + k++; + } + for(; keErr |= JSTRING_MALFORMED; + break; + }else if( (u>>60)!=0 ){ + bOverflow = 1; + }else{ + u = u*16 + sqlite3HexToInt(zIn[k]); + } + } + jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u); + break; + } + case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ + u32 k = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + } + if( zIn[k]=='.' ){ + jsonAppendChar(pOut, '0'); + } + for(; kaBlob[i+n], sz); + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXT5: { + const char *zIn; + u32 k; + u32 sz2 = sz; + zIn = (const char*)&pParse->aBlob[i+n]; + jsonAppendChar(pOut, '"'); + while( sz2>0 ){ + for(k=0; k0 ){ + jsonAppendRawNZ(pOut, zIn, k); + if( k>=sz2 ){ + break; + } + zIn += k; + sz2 -= k; + } + if( zIn[0]=='"' ){ + jsonAppendRawNZ(pOut, "\\\"", 2); + zIn++; + sz2--; + continue; + } + assert( zIn[0]=='\\' ); + assert( sz2>=1 ); + if( sz2<2 ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + switch( (u8)zIn[1] ){ + case '\'': + jsonAppendChar(pOut, '\''); + break; + case 'v': + jsonAppendRawNZ(pOut, "\\u0009", 6); + break; + case 'x': + if( sz2<4 ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + jsonAppendRawNZ(pOut, "\\u00", 4); + jsonAppendRawNZ(pOut, &zIn[2], 2); + zIn += 2; + sz2 -= 2; + break; + case '0': + jsonAppendRawNZ(pOut, "\\u0000", 6); + break; + case '\r': + if( sz2>2 && zIn[2]=='\n' ){ + zIn++; + sz2--; + } + break; + case '\n': + break; + case 0xe2: + /* '\' followed by either U+2028 or U+2029 is ignored as + ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. + ** U+2029 is the same except for the last byte */ + if( sz2<4 + || 0x80!=(u8)zIn[2] + || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) + ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + zIn += 2; + sz2 -= 2; + break; + default: + jsonAppendRawNZ(pOut, zIn, 2); + break; + } + assert( sz2>=2 ); + zIn += 2; + sz2 -= 2; + } + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXTRAW: { + jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_ARRAY: { + jsonAppendChar(pOut, '['); + j = i+n; + iEnd = j+sz; + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, ','); + } + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, ']'); + break; + } + case JSONB_OBJECT: { + int x = 0; + jsonAppendChar(pOut, '{'); + j = i+n; + iEnd = j+sz; + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); + } + if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, '}'); + break; + } + + default: { + malformed_jsonb: + pOut->eErr |= JSTRING_MALFORMED; + break; + } + } + return i+n+sz; +} + +/* Return true if the input pJson +** +** For performance reasons, this routine does not do a detailed check of the +** input BLOB to ensure that it is well-formed. Hence, false positives are +** possible. False negatives should never occur, however. +*/ +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ + u32 sz, n; + const u8 *aBlob; + int nBlob; + JsonParse s; + if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; + aBlob = sqlite3_value_blob(pJson); + nBlob = sqlite3_value_bytes(pJson); + if( nBlob<1 ) return 0; + if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; + memset(&s, 0, sizeof(s)); + s.aBlob = (u8*)aBlob; + s.nBlob = nBlob; + n = jsonbPayloadSize(&s, 0, &sz); + if( n==0 ) return 0; + if( sz+n!=(u32)nBlob ) return 0; + if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; + return sz+n==(u32)nBlob; +} + +/* +** Given that a JSONB_ARRAY object starts at offset i, return +** the number of entries in that array. +*/ +static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ + u32 n, sz, i, iEnd; + u32 k = 0; + n = jsonbPayloadSize(pParse, iRoot, &sz); + iEnd = iRoot+n+sz; + for(i=iRoot+n; n>0 && idelta. +*/ +static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ + u32 sz = 0; + u32 nBlob; + assert( pParse->delta!=0 ); + assert( pParse->nBlobAlloc >= pParse->nBlob ); + nBlob = pParse->nBlob; + pParse->nBlob = pParse->nBlobAlloc; + (void)jsonbPayloadSize(pParse, iRoot, &sz); + pParse->nBlob = nBlob; + sz += pParse->delta; + pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); +} + +/* +** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of +** content beginning at iDel, and replacing them with nIns bytes of +** content given by aIns. +** +** nDel may be zero, in which case no bytes are removed. But iDel is +** still important as new bytes will be insert beginning at iDel. +** +** aIns may be zero, in which case space is created to hold nIns bytes +** beginning at iDel, but that space is uninitialized. +** +** Set pParse->oom if an OOM occurs. +*/ +static void jsonBlobEdit( + JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ + u32 iDel, /* First byte to be removed */ + u32 nDel, /* Number of bytes to remove */ + const u8 *aIns, /* Content to insert */ + u32 nIns /* Bytes of content to insert */ +){ + i64 d = (i64)nIns - (i64)nDel; + if( d!=0 ){ + if( pParse->nBlob + d > pParse->nBlobAlloc ){ + jsonBlobExpand(pParse, pParse->nBlob+d); + if( pParse->oom ) return; + } + memmove(&pParse->aBlob[iDel+nIns], + &pParse->aBlob[iDel+nDel], + pParse->nBlob - (iDel+nDel)); + pParse->nBlob += d; + pParse->delta += d; + } + if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); +} + +/* +** Return the number of escaped newlines to be ignored. +** An escaped newline is a one of the following byte sequences: +** +** 0x5c 0x0a +** 0x5c 0x0d +** 0x5c 0x0d 0x0a +** 0x5c 0xe2 0x80 0xa8 +** 0x5c 0xe2 0x80 0xa9 +*/ +static u32 jsonBytesToBypass(const char *z, u32 n){ + u32 i = 0; + while( i+10 ); + assert( z[0]=='\\' ); + if( n<2 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + switch( (u8)z[1] ){ + case 'u': { + u32 v, vlo; + if( n<6 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + v = jsonHexToInt4(&z[2]); + if( (v & 0xfc00)==0xd800 + && n>=12 + && z[6]=='\\' + && z[7]=='u' + && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00 + ){ + *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; + return 12; + }else{ + *piOut = v; + return 6; + } + } + case 'b': { *piOut = '\b'; return 2; } + case 'f': { *piOut = '\f'; return 2; } + case 'n': { *piOut = '\n'; return 2; } + case 'r': { *piOut = '\r'; return 2; } + case 't': { *piOut = '\t'; return 2; } + case 'v': { *piOut = '\v'; return 2; } + case '0': { *piOut = 0; return 2; } + case '\'': + case '"': + case '/': + case '\\':{ *piOut = z[1]; return 2; } + case 'x': { + if( n<4 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]); + return 4; + } + case 0xe2: + case '\r': + case '\n': { + u32 nSkip = jsonBytesToBypass(z, n); + if( nSkip==0 ){ + *piOut = JSON_INVALID_CHAR; + return n; + }else if( nSkip==n ){ + *piOut = 0; + return n; + }else if( z[nSkip]=='\\' ){ + return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut); + }else{ + int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut); + return nSkip + sz; + } + } + default: { + *piOut = JSON_INVALID_CHAR; + return 2; + } + } +} + + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. +** +** In this version, we know that one or the other or both of the +** two comparands contains an escape sequence. +*/ +static SQLITE_NOINLINE int jsonLabelCompareEscaped( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + u32 cLeft, cRight; + assert( rawLeft==0 || rawRight==0 ); + while( 1 /*exit-by-return*/ ){ + if( nLeft==0 ){ + cLeft = 0; + }else if( rawLeft || zLeft[0]!='\\' ){ + cLeft = ((u8*)zLeft)[0]; + if( cLeft>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft); + zLeft += sz; + nLeft -= sz; + }else{ + zLeft++; + nLeft--; + } + }else{ + u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft); + zLeft += n; + assert( n<=nLeft ); + nLeft -= n; + } + if( nRight==0 ){ + cRight = 0; + }else if( rawRight || zRight[0]!='\\' ){ + cRight = ((u8*)zRight)[0]; + if( cRight>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight); + zRight += sz; + nRight -= sz; + }else{ + zRight++; + nRight--; + } + }else{ + u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight); + zRight += n; + assert( n<=nRight ); + nRight -= n; + } + if( cLeft!=cRight ) return 0; + if( cLeft==0 ) return 1; + } +} + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. Return -1 if an OOM occurs. +*/ +static int jsonLabelCompare( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + if( rawLeft && rawRight ){ + /* Simpliest case: Neither label contains escapes. A simple + ** memcmp() is sufficient. */ + if( nLeft!=nRight ) return 0; + return memcmp(zLeft, zRight, nLeft)==0; + }else{ + return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft, + zRight, nRight, rawRight); + } +} + +/* +** Error returns from jsonLookupStep() +*/ +#define JSON_LOOKUP_ERROR 0xffffffff +#define JSON_LOOKUP_NOTFOUND 0xfffffffe +#define JSON_LOOKUP_PATHERROR 0xfffffffd +#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) + +/* Forward declaration */ +static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); + + +/* This helper routine for jsonLookupStep() populates pIns with +** binary data that is to be inserted into pParse. +** +** In the common case, pIns just points to pParse->aIns and pParse->nIns. +** But if the zPath of the original edit operation includes path elements +** that go deeper, additional substructure must be created. +** +** For example: +** +** json_insert('{}', '$.a.b.c', 123); +** +** The search stops at '$.a' But additional substructure must be +** created for the ".b.c" part of the patch so that the final result +** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with +** the binary equivalent of {"b":{"c":123}} so that it can be inserted. +** +** The caller is responsible for resetting pIns when it has finished +** using the substructure. +*/ +static u32 jsonCreateEditSubstructure( + JsonParse *pParse, /* The original JSONB that is being edited */ + JsonParse *pIns, /* Populate this with the blob data to insert */ + const char *zTail /* Tail of the path that determins substructure */ +){ + static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; + int rc; + memset(pIns, 0, sizeof(*pIns)); + pIns->db = pParse->db; + if( zTail[0]==0 ){ + /* No substructure. Just insert what is given in pParse. */ + pIns->aBlob = pParse->aIns; + pIns->nBlob = pParse->nIns; + rc = 0; + }else{ + /* Construct the binary substructure */ + pIns->nBlob = 1; + pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.']; + pIns->eEdit = pParse->eEdit; + pIns->nIns = pParse->nIns; + pIns->aIns = pParse->aIns; + rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->oom |= pIns->oom; + } + return rc; /* Error code only */ +} + +/* +** Search along zPath to find the Json element specified. Return an +** index into pParse->aBlob[] for the start of that element's value. +** +** If the value found by this routine is the value half of label/value pair +** within an object, then set pPath->iLabel to the start of the corresponding +** label, before returning. +** +** Return one of the JSON_LOOKUP error codes if problems are seen. +** +** This routine will also modify the blob. If pParse->eEdit is one of +** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be +** made to the selected value. If an edit is performed, then the return +** value does not necessarily point to the select element. If an edit +** is performed, the return value is only useful for detecting error +** conditions. +*/ +static u32 jsonLookupStep( + JsonParse *pParse, /* The JSON to search */ + u32 iRoot, /* Begin the search at this element of aBlob[] */ + const char *zPath, /* The path to search */ + u32 iLabel /* Label if iRoot is a value of in an object */ +){ + u32 i, j, k, nKey, sz, n, iEnd, rc; + const char *zKey; + u8 x; + + if( zPath[0]==0 ){ + if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){ + n = jsonbPayloadSize(pParse, iRoot, &sz); + sz += n; + if( pParse->eEdit==JEDIT_DEL ){ + if( iLabel>0 ){ + sz += iRoot - iLabel; + iRoot = iLabel; + } + jsonBlobEdit(pParse, iRoot, sz, 0, 0); + }else if( pParse->eEdit==JEDIT_INS ){ + /* Already exists, so json_insert() is a no-op */ + }else{ + /* json_set() or json_replace() */ + jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); + } + } + pParse->iLabel = iLabel; + return iRoot; + } + if( zPath[0]=='.' ){ + int rawKey = 1; + x = pParse->aBlob[iRoot]; + zPath++; + if( zPath[0]=='"' ){ + zKey = zPath + 1; + for(i=1; zPath[i] && zPath[i]!='"'; i++){} + nKey = i-1; + if( zPath[i] ){ + i++; + }else{ + return JSON_LOOKUP_PATHERROR; + } + testcase( nKey==0 ); + rawKey = memchr(zKey, '\\', nKey)==0; + }else{ + zKey = zPath; + for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} + nKey = i; + if( nKey==0 ){ + return JSON_LOOKUP_PATHERROR; + } + } + if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + j = iRoot + n; /* j is the index of a label */ + iEnd = j+sz; + while( jaBlob[j] & 0x0f; + if( xJSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + k = j+n; /* k is the index of the label text */ + if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; + zLabel = (const char*)&pParse->aBlob[k]; + rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; + if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){ + u32 v = k+sz; /* v is the index of the value */ + if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, v, &sz); + if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; + assert( j>0 ); + rc = jsonLookupStep(pParse, v, &zPath[i], j); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + j = k+sz; + if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( pParse->eEdit>=JEDIT_INS ){ + u32 nIns; /* Total bytes to insert (label+value) */ + JsonParse v; /* BLOB encoding of the value to be inserted */ + JsonParse ix; /* Header of the label to be inserted */ + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + memset(&ix, 0, sizeof(ix)); + ix.db = pParse->db; + jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); + pParse->oom |= ix.oom; + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) + ){ + assert( !pParse->oom ); + nIns = ix.nBlob + nKey + v.nBlob; + jsonBlobEdit(pParse, j, 0, 0, nIns); + if( !pParse->oom ){ + assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */ + assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */ + memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob); + k = j + ix.nBlob; + memcpy(&pParse->aBlob[k], zKey, nKey); + k += nKey; + memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob); + if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot); + } + } + jsonParseReset(&v); + jsonParseReset(&ix); + return rc; + } + }else if( zPath[0]=='[' ){ + x = pParse->aBlob[iRoot] & 0x0f; + if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + k = 0; + i = 1; + while( sqlite3Isdigit(zPath[i]) ){ + k = k*10 + zPath[i] - '0'; + i++; + } + if( i<2 || zPath[i]!=']' ){ + if( zPath[1]=='#' ){ + k = jsonbArrayCount(pParse, iRoot); + i = 2; + if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ + unsigned int nn = 0; + i = 3; + do{ + nn = nn*10 + zPath[i] - '0'; + i++; + }while( sqlite3Isdigit(zPath[i]) ); + if( nn>k ) return JSON_LOOKUP_NOTFOUND; + k -= nn; + } + if( zPath[i]!=']' ){ + return JSON_LOOKUP_PATHERROR; + } + }else{ + return JSON_LOOKUP_PATHERROR; + } + } + j = iRoot+n; + iEnd = j+sz; + while( jdelta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + k--; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( k>0 ) return JSON_LOOKUP_NOTFOUND; + if( pParse->eEdit>=JEDIT_INS ){ + JsonParse v; + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, v.nBlob) + ){ + assert( !pParse->oom ); + jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob); + } + jsonParseReset(&v); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + }else{ + return JSON_LOOKUP_PATHERROR; + } + return JSON_LOOKUP_NOTFOUND; +} + +/* +** Convert a JSON BLOB into text and make that text the return value +** of an SQL function. +*/ +static void jsonReturnTextJsonFromBlob( + sqlite3_context *ctx, + const u8 *aBlob, + u32 nBlob +){ + JsonParse x; + JsonString s; + + if( NEVER(aBlob==0) ) return; + memset(&x, 0, sizeof(x)); + x.aBlob = (u8*)aBlob; + x.nBlob = nBlob; + jsonStringInit(&s, ctx); + jsonTranslateBlobToText(&x, 0, &s); + jsonReturnString(&s, 0, 0); +} + + +/* +** Return the value of the BLOB node at index i. +** +** If the value is a primitive, return it as an SQL value. +** If the value is an array or object, return it as either +** JSON text or the BLOB encoding, depending on the JSON_B flag +** on the userdata. +*/ +static void jsonReturnFromBlob( + JsonParse *pParse, /* Complete JSON parse tree */ + u32 i, /* Index of the node */ + sqlite3_context *pCtx, /* Return value for this function */ + int textOnly /* return text JSON. Disregard user-data */ +){ + u32 n, sz; + int rc; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_null(pCtx); + break; + } + case JSONB_TRUE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 1); + break; + } + case JSONB_FALSE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 0); + break; + } + case JSONB_INT5: + case JSONB_INT: { + sqlite3_int64 iRes = 0; + char *z; + int bNeg = 0; + char x; + if( sz==0 ) goto returnfromblob_malformed; + x = (char)pParse->aBlob[i+n]; + if( x=='-' ){ + if( sz<2 ) goto returnfromblob_malformed; + n++; + sz--; + bNeg = 1; + } + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3DecOrHexToI64(z, &iRes); + sqlite3DbFree(db, z); + if( rc==0 ){ + sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes); + }else if( rc==3 && bNeg ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + }else if( rc==1 ){ + goto returnfromblob_malformed; + }else{ + if( bNeg ){ n--; sz++; } + goto to_double; + } + break; + } + case JSONB_FLOAT5: + case JSONB_FLOAT: { + double r; + char *z; + if( sz==0 ) goto returnfromblob_malformed; + to_double: + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); + sqlite3DbFree(db, z); + if( rc<=0 ) goto returnfromblob_malformed; + sqlite3_result_double(pCtx, r); + break; + } + case JSONB_TEXTRAW: + case JSONB_TEXT: { + sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz, + SQLITE_TRANSIENT); + break; + } + case JSONB_TEXT5: + case JSONB_TEXTJ: { + /* Translate JSON formatted string into raw text */ + u32 iIn, iOut; + const char *z; + char *zOut; + u32 nOut = sz; + z = (const char*)&pParse->aBlob[i+n]; + zOut = sqlite3DbMallocRaw(db, nOut+1); + if( zOut==0 ) goto returnfromblob_oom; + for(iIn=iOut=0; iIn=2 ); + zOut[iOut++] = (char)(0xc0 | (v>>6)); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v<0x10000 ){ + assert( szEscape>=3 ); + zOut[iOut++] = 0xe0 | (v>>12); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v==JSON_INVALID_CHAR ){ + /* Silently ignore illegal unicode */ + }else{ + assert( szEscape>=4 ); + zOut[iOut++] = 0xf0 | (v>>18); + zOut[iOut++] = 0x80 | ((v>>12)&0x3f); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + } + iIn += szEscape - 1; + }else{ + zOut[iOut++] = c; + } + } /* end for() */ + assert( iOut<=nOut ); + zOut[iOut] = 0; + sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC); + break; + } + case JSONB_ARRAY: + case JSONB_OBJECT: { + int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)); + if( flags & JSON_BLOB ){ + sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT); + }else{ + jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n); + } + break; + } + default: { + goto returnfromblob_malformed; + } + } + return; + +returnfromblob_oom: + sqlite3_result_error_nomem(pCtx); + return; + +returnfromblob_malformed: + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; +} + +/* +** pArg is a function argument that might be an SQL value or a JSON +** value. Figure out what it is and encode it as a JSONB blob. +** Return the results in pParse. +** +** pParse is uninitialized upon entry. This routine will handle the +** initialization of pParse. The result will be contained in +** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically +** allocated (if pParse->nBlobAlloc is greater than zero) in which case +** the caller is responsible for freeing the space allocated to pParse->aBlob +** when it has finished with it. Or pParse->aBlob might be a static string +** or a value obtained from sqlite3_value_blob(pArg). +** +** If the argument is a BLOB that is clearly not a JSONB, then this +** function might set an error message in ctx and return non-zero. +** It might also set an error message and return non-zero on an OOM error. +*/ +static int jsonFunctionArgToBlob( + sqlite3_context *ctx, + sqlite3_value *pArg, + JsonParse *pParse +){ + int eType = sqlite3_value_type(pArg); + static u8 aNull[] = { 0x00 }; + memset(pParse, 0, sizeof(pParse[0])); + pParse->db = sqlite3_context_db_handle(ctx); + switch( eType ){ + default: { + pParse->aBlob = aNull; + pParse->nBlob = 1; + return 0; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(pArg) ){ + pParse->aBlob = (u8*)sqlite3_value_blob(pArg); + pParse->nBlob = sqlite3_value_bytes(pArg); + }else{ + sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); + return 1; + } + break; + } + case SQLITE_TEXT: { + const char *zJson = (const char*)sqlite3_value_text(pArg); + int nJson = sqlite3_value_bytes(pArg); + if( zJson==0 ) return 1; + if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){ + pParse->zJson = (char*)zJson; + pParse->nJson = nJson; + if( jsonConvertTextToBlob(pParse, ctx) ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + sqlite3DbFree(pParse->db, pParse->aBlob); + memset(pParse, 0, sizeof(pParse[0])); + return 1; + } + }else{ + jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); + } + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pArg); + if( NEVER(sqlite3IsNaN(r)) ){ + jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); + }else{ + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + if( z[0]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else if( z[0]=='-' && z[1]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z); + } + } + break; + } + case SQLITE_INTEGER: { + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + jsonBlobAppendNode(pParse, JSONB_INT, n, z); + break; + } + } + if( pParse->oom ){ + sqlite3_result_error_nomem(ctx); + return 1; + }else{ + return 0; + } +} + +/* +** Generate a bad path error. +** +** If ctx is not NULL then push the error message into ctx and return NULL. +** If ctx is NULL, then return the text of the error message. +*/ +static char *jsonBadPathError( + sqlite3_context *ctx, /* The function call containing the error */ + const char *zPath /* The path with the problem */ +){ + char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + if( ctx==0 ) return zMsg; + if( zMsg ){ + sqlite3_result_error(ctx, zMsg, -1); + sqlite3_free(zMsg); + }else{ + sqlite3_result_error_nomem(ctx); + } + return 0; +} + +/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent +** arguments come in parse where each pair contains a JSON path and +** content to insert or set at that patch. Do the updates +** and return the result. +** +** The specific operation is determined by eEdit, which can be one +** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. +*/ +static void jsonInsertIntoBlob( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv, + int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ +){ + int i; + u32 rc = 0; + const char *zPath = 0; + int flgs; + JsonParse *p; + JsonParse ax; + + assert( (argc&1)==1 ); + flgs = argc==1 ? 0 : JSON_EDITABLE; + p = jsonParseFuncArg(ctx, argv[0], flgs); + if( p==0 ) return; + for(i=1; inBlob, ax.aBlob, ax.nBlob); + } + rc = 0; + }else{ + p->eEdit = eEdit; + p->nIns = ax.nBlob; + p->aIns = ax.aBlob; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + } + jsonParseReset(&ax); + if( rc==JSON_LOOKUP_NOTFOUND ) continue; + if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror; + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +jsonInsertIntoBlob_patherror: + jsonParseFree(p); + if( rc==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + }else{ + jsonBadPathError(ctx, zPath); + } + return; +} + +/* +** If pArg is a blob that seems like a JSONB blob, then initialize +** p to point to that JSONB and return TRUE. If pArg does not seem like +** a JSONB blob, then return FALSE; +** +** This routine is only called if it is already known that pArg is a +** blob. The only open question is whether or not the blob appears +** to be a JSONB blob. +*/ +static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ + u32 n, sz = 0; + p->aBlob = (u8*)sqlite3_value_blob(pArg); + p->nBlob = (u32)sqlite3_value_bytes(pArg); + if( p->nBlob==0 ){ + p->aBlob = 0; + return 0; + } + if( NEVER(p->aBlob==0) ){ + return 0; + } + if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT + && (n = jsonbPayloadSize(p, 0, &sz))>0 + && sz+n==p->nBlob + && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) + ){ + return 1; + } + p->aBlob = 0; + p->nBlob = 0; + return 0; +} + +/* +** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, +** from the SQL function argument pArg. Return a pointer to the new +** JsonParse object. +** +** Ownership of the new JsonParse object is passed to the caller. The +** caller should invoke jsonParseFree() on the return value when it +** has finished using it. +** +** If any errors are detected, an appropriate error messages is set +** using sqlite3_result_error() or the equivalent and this routine +** returns NULL. This routine also returns NULL if the pArg argument +** is an SQL NULL value, but no error message is set in that case. This +** is so that SQL functions that are given NULL arguments will return +** a NULL value. +*/ +static JsonParse *jsonParseFuncArg( + sqlite3_context *ctx, + sqlite3_value *pArg, + u32 flgs +){ + int eType; /* Datatype of pArg */ + JsonParse *p = 0; /* Value to be returned */ + JsonParse *pFromCache = 0; /* Value taken from cache */ + sqlite3 *db; /* The database connection */ + + assert( ctx!=0 ); + eType = sqlite3_value_type(pArg); + if( eType==SQLITE_NULL ){ + return 0; + } + pFromCache = jsonCacheSearch(ctx, pArg); + if( pFromCache ){ + pFromCache->nJPRef++; + if( (flgs & JSON_EDITABLE)==0 ){ + return pFromCache; + } + } + db = sqlite3_context_db_handle(ctx); +rebuild_from_cache: + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) goto json_pfa_oom; + memset(p, 0, sizeof(*p)); + p->db = db; + p->nJPRef = 1; + if( pFromCache!=0 ){ + u32 nBlob = pFromCache->nBlob; + p->aBlob = sqlite3DbMallocRaw(db, nBlob); + if( p->aBlob==0 ) goto json_pfa_oom; + memcpy(p->aBlob, pFromCache->aBlob, nBlob); + p->nBlobAlloc = p->nBlob = nBlob; + p->hasNonstd = pFromCache->hasNonstd; + jsonParseFree(pFromCache); + return p; + } + if( eType==SQLITE_BLOB ){ + if( jsonArgIsJsonb(pArg,p) ){ + if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ + goto json_pfa_oom; + } + return p; + } + /* If the blob is not valid JSONB, fall through into trying to cast + ** the blob into text which is then interpreted as JSON. (tag-20240123-a) + ** + ** This goes against all historical documentation about how the SQLite + ** JSON functions were suppose to work. From the beginning, blob was + ** reserved for expansion and a blob value should have raised an error. + ** But it did not, due to a bug. And many applications came to depend + ** upon this buggy behavior, espeically when using the CLI and reading + ** JSON text using readfile(), which returns a blob. For this reason + ** we will continue to support the bug moving forward. + ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d + */ + } + p->zJson = (char*)sqlite3_value_text(pArg); + p->nJson = sqlite3_value_bytes(pArg); + if( db->mallocFailed ) goto json_pfa_oom; + if( p->nJson==0 ) goto json_pfa_malformed; + assert( p->zJson!=0 ); + if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + return 0; + } + }else{ + int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref); + int rc; + if( !isRCStr ){ + char *zNew = sqlite3RCStrNew( p->nJson ); + if( zNew==0 ) goto json_pfa_oom; + memcpy(zNew, p->zJson, p->nJson); + p->zJson = zNew; + p->zJson[p->nJson] = 0; + }else{ + sqlite3RCStrRef(p->zJson); + } + p->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, p); + if( rc==SQLITE_NOMEM ) goto json_pfa_oom; + if( flgs & JSON_EDITABLE ){ + pFromCache = p; + p = 0; + goto rebuild_from_cache; + } + } + return p; + +json_pfa_malformed: + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + sqlite3_result_error(ctx, "malformed JSON", -1); + return 0; + } + +json_pfa_oom: + jsonParseFree(pFromCache); + jsonParseFree(p); + sqlite3_result_error_nomem(ctx); + return 0; +} + +/* +** Make the return value of a JSON function either the raw JSONB blob +** or make it JSON text, depending on whether the JSON_BLOB flag is +** set on the function. +*/ +static void jsonReturnParse( + sqlite3_context *ctx, + JsonParse *p +){ + int flgs; + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + return; + } + flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( flgs & JSON_BLOB ){ + if( p->nBlobAlloc>0 && !p->bReadOnly ){ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC); + p->nBlobAlloc = 0; + }else{ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT); + } + }else{ + JsonString s; + jsonStringInit(&s, ctx); + p->delta = 0; + jsonTranslateBlobToText(p, 0, &s); + jsonReturnString(&s, p, ctx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } +} + +/**************************************************************************** +** SQL functions used for testing and debugging +****************************************************************************/ + +#if SQLITE_DEBUG +/* +** Decode JSONB bytes in aBlob[] starting at iStart through but not +** including iEnd. Indent the +** content by nIndent spaces. +*/ +static void jsonDebugPrintBlob( + JsonParse *pParse, /* JSON content */ + u32 iStart, /* Start rendering here */ + u32 iEnd, /* Do not render this byte or any byte after this one */ + int nIndent, /* Indent by this many spaces */ + sqlite3_str *pOut /* Generate output into this sqlite3_str object */ +){ + while( iStartaBlob[iStart] & 0x0f; + u32 savedNBlob = pParse->nBlob; + sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, ""); + if( pParse->nBlobAlloc>pParse->nBlob ){ + pParse->nBlob = pParse->nBlobAlloc; + } + nn = n = jsonbPayloadSize(pParse, iStart, &sz); + if( nn==0 ) nn = 1; + if( sz>0 && xaBlob[iStart+i]); + } + if( n==0 ){ + sqlite3_str_appendf(pOut, " ERROR invalid node size\n"); + iStart = n==0 ? iStart+1 : iEnd; + continue; + } + pParse->nBlob = savedNBlob; + if( iStart+n+sz>iEnd ){ + iEnd = iStart+n+sz; + if( iEnd>pParse->nBlob ){ + if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){ + iEnd = pParse->nBlobAlloc; + }else{ + iEnd = pParse->nBlob; + } + } + } + sqlite3_str_appendall(pOut," <-- "); + switch( x ){ + case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break; + case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break; + case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break; + case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break; + case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break; + case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break; + case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break; + case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break; + case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break; + case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break; + case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break; + case JSONB_ARRAY: { + sqlite3_str_appendf(pOut,"array, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + case JSONB_OBJECT: { + sqlite3_str_appendf(pOut, "object, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + default: { + sqlite3_str_appendall(pOut, "ERROR: unknown node type\n"); + showContent = 0; + break; + } + } + if( showContent ){ + if( sz==0 && x<=JSONB_FALSE ){ + sqlite3_str_append(pOut, "\n", 1); + }else{ + u32 j; + sqlite3_str_appendall(pOut, ": \""); + for(j=iStart+n; jaBlob[j]; + if( c<0x20 || c>=0x7f ) c = '.'; + sqlite3_str_append(pOut, (char*)&c, 1); + } + sqlite3_str_append(pOut, "\"\n", 2); + } + } + iStart += n + sz; + } +} +static void jsonShowParse(JsonParse *pParse){ + sqlite3_str out; + char zBuf[1000]; + if( pParse==0 ){ + printf("NULL pointer\n"); + return; + }else{ + printf("nBlobAlloc = %u\n", pParse->nBlobAlloc); + printf("nBlob = %u\n", pParse->nBlob); + printf("delta = %d\n", pParse->delta); + if( pParse->nBlob==0 ) return; + printf("content (bytes 0..%u):\n", pParse->nBlob-1); + } + sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000); + jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out); + printf("%s", sqlite3_str_value(&out)); + sqlite3_str_reset(&out); +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** SQL function: json_parse(JSON) +** +** Parse JSON using jsonParseFuncArg(). Return text that is a +** human-readable dump of the binary JSONB for the input parameter. +*/ +static void jsonParseFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + sqlite3_str out; + + assert( argc>=1 ); + sqlite3StrAccumInit(&out, 0, 0, 0, 1000000); + p = jsonParseFuncArg(ctx, argv[0], 0); + if( p==0 ) return; + if( argc==1 ){ + jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); + sqlite3_result_text64(ctx, out.zText, out.nChar, SQLITE_DYNAMIC, SQLITE_UTF8); + }else{ + jsonShowParse(p); + } + jsonParseFree(p); +} +#endif /* SQLITE_DEBUG */ + +/**************************************************************************** +** Scalar SQL function implementations +****************************************************************************/ + +/* +** Implementation of the json_quote(VALUE) function. Return a JSON value +** corresponding to the SQL value input. Mostly this means putting +** double-quotes around strings and returning the unquoted string "null" +** when given a NULL input. +*/ +static void jsonQuoteFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString jx; + UNUSED_PARAMETER(argc); + + jsonStringInit(&jx, ctx); + jsonAppendSqlValue(&jx, argv[0]); + jsonReturnString(&jx, 0, 0); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} + +/* +** Implementation of the json_array(VALUE,...) function. Return a JSON +** array that contains all values given in arguments. Or if any argument +** is a BLOB, throw an error. +*/ +static void jsonArrayFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + JsonString jx; + + jsonStringInit(&jx, ctx); + jsonAppendChar(&jx, '['); + for(i=0; iaBlob[i] & 0x0f)==JSONB_ARRAY ){ + cnt = jsonbArrayCount(p, i); + } + if( !eErr ) sqlite3_result_int64(ctx, cnt); + jsonParseFree(p); +} + +/* True if the string is all digits */ +static int jsonAllDigits(const char *z, int n){ + int i; + for(i=0; i"(JSON,PATH) +** "->>"(JSON,PATH) +** +** Return the element described by PATH. Return NULL if that PATH element +** is not found. +** +** If JSON_JSON is set or if more that one PATH argument is supplied then +** always return a JSON representation of the result. If JSON_SQL is set, +** then always return an SQL representation of the result. If neither flag +** is present and argc==2, then return JSON for objects and arrays and SQL +** for all other values. +** +** When multiple PATH arguments are supplied, the result is a JSON array +** containing the result of each PATH. +** +** Abbreviated JSON path expressions are allows if JSON_ABPATH, for +** compatibility with PG. +*/ +static void jsonExtractFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p = 0; /* The parse */ + int flags; /* Flags associated with the function */ + int i; /* Loop counter */ + JsonString jx; /* String for array result */ + + if( argc<2 ) return; + p = jsonParseFuncArg(ctx, argv[0], 0); + if( p==0 ) return; + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + jsonStringInit(&jx, ctx); + if( argc>2 ){ + jsonAppendChar(&jx, '['); + } + for(i=1; i and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + */ + jsonStringInit(&jx, ctx); + if( jsonAllDigits(zPath, nPath) ){ + jsonAppendRawNZ(&jx, "[", 1); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "]", 2); + }else if( jsonAllAlphanum(zPath, nPath) ){ + jsonAppendRawNZ(&jx, ".", 1); + jsonAppendRaw(&jx, zPath, nPath); + }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ + jsonAppendRaw(&jx, zPath, nPath); + }else{ + jsonAppendRawNZ(&jx, ".\"", 2); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "\"", 1); + } + jsonStringTerminate(&jx); + j = jsonLookupStep(p, 0, jx.zBuf, 0); + jsonStringReset(&jx); + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; + } + if( jnBlob ){ + if( argc==2 ){ + if( flags & JSON_JSON ){ + jsonStringInit(&jx, ctx); + jsonTranslateBlobToText(p, j, &jx); + jsonReturnString(&jx, 0, 0); + jsonStringReset(&jx); + assert( (flags & JSON_BLOB)==0 ); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + }else{ + jsonReturnFromBlob(p, j, ctx, 0); + if( (flags & (JSON_SQL|JSON_BLOB))==0 + && (p->aBlob[j]&0x0f)>=JSONB_ARRAY + ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + } + }else{ + jsonAppendSeparator(&jx); + jsonTranslateBlobToText(p, j, &jx); + } + }else if( j==JSON_LOOKUP_NOTFOUND ){ + if( argc==2 ){ + goto json_extract_error; /* Return NULL if not found */ + }else{ + jsonAppendSeparator(&jx); + jsonAppendRawNZ(&jx, "null", 4); + } + }else if( j==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + goto json_extract_error; + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; + } + } + if( argc>2 ){ + jsonAppendChar(&jx, ']'); + jsonReturnString(&jx, 0, 0); + if( (flags & JSON_BLOB)==0 ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + } +json_extract_error: + jsonStringReset(&jx); + jsonParseFree(p); + return; +} + +/* +** Return codes for jsonMergePatch() +*/ +#define JSON_MERGE_OK 0 /* Success */ +#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ +#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ +#define JSON_MERGE_OOM 3 /* Out-of-memory condition */ + +/* +** RFC-7396 MergePatch for two JSONB blobs. +** +** pTarget is the target. pPatch is the patch. The target is updated +** in place. The patch is read-only. +** +** The original RFC-7396 algorithm is this: +** +** define MergePatch(Target, Patch): +** if Patch is an Object: +** if Target is not an Object: +** Target = {} # Ignore the contents and set it to an empty Object +** for each Name/Value pair in Patch: +** if Value is null: +** if Name exists in Target: +** remove the Name/Value pair from Target +** else: +** Target[Name] = MergePatch(Target[Name], Value) +** return Target +** else: +** return Patch +** +** Here is an equivalent algorithm restructured to show the actual +** implementation: +** +** 01 define MergePatch(Target, Patch): +** 02 if Patch is not an Object: +** 03 return Patch +** 04 else: // if Patch is an Object +** 05 if Target is not an Object: +** 06 Target = {} +** 07 for each Name/Value pair in Patch: +** 08 if Name exists in Target: +** 09 if Value is null: +** 10 remove the Name/Value pair from Target +** 11 else +** 12 Target[name] = MergePatch(Target[Name], Value) +** 13 else if Value is not NULL: +** 14 if Value is not an Object: +** 15 Target[name] = Value +** 16 else: +** 17 Target[name] = MergePatch('{}',value) +** 18 return Target +** | +** ^---- Line numbers referenced in comments in the implementation +*/ +static int jsonMergePatch( + JsonParse *pTarget, /* The JSON parser that contains the TARGET */ + u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ + const JsonParse *pPatch, /* The PATCH */ + u32 iPatch /* Index of PATCH in pPatch->aBlob[] */ +){ + u8 x; /* Type of a single node */ + u32 n, sz=0; /* Return values from jsonbPayloadSize() */ + u32 iTCursor; /* Cursor position while scanning the target object */ + u32 iTStart; /* First label in the target object */ + u32 iTEndBE; /* Original first byte past end of target, before edit */ + u32 iTEnd; /* Current first byte past end of target */ + u8 eTLabel; /* Node type of the target label */ + u32 iTLabel = 0; /* Index of the label */ + u32 nTLabel = 0; /* Header size in bytes for the target label */ + u32 szTLabel = 0; /* Size of the target label payload */ + u32 iTValue = 0; /* Index of the target value */ + u32 nTValue = 0; /* Header size of the target value */ + u32 szTValue = 0; /* Payload size for the target value */ + + u32 iPCursor; /* Cursor position while scanning the patch */ + u32 iPEnd; /* First byte past the end of the patch */ + u8 ePLabel; /* Node type of the patch label */ + u32 iPLabel; /* Start of patch label */ + u32 nPLabel; /* Size of header on the patch label */ + u32 szPLabel; /* Payload size of the patch label */ + u32 iPValue; /* Start of patch value */ + u32 nPValue; /* Header size for the patch value */ + u32 szPValue; /* Payload size of the patch value */ + + assert( iTarget>=0 && iTargetnBlob ); + assert( iPatch>=0 && iPatchnBlob ); + x = pPatch->aBlob[iPatch] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */ + u32 szPatch; /* Total size of the patch, header+payload */ + u32 szTarget; /* Total size of the target, header+payload */ + n = jsonbPayloadSize(pPatch, iPatch, &sz); + szPatch = n+sz; + sz = 0; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + szTarget = n+sz; + jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */ + } + x = pTarget->aBlob[iTarget] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */ + n = jsonbPayloadSize(pTarget, iTarget, &sz); + jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0); + x = pTarget->aBlob[iTarget]; + pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT; + } + n = jsonbPayloadSize(pPatch, iPatch, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADPATCH; + iPCursor = iPatch+n; + iPEnd = iPCursor+sz; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADTARGET; + iTStart = iTarget+n; + iTEndBE = iTStart+sz; + + while( iPCursoraBlob[iPCursor] & 0x0f; + if( ePLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADPATCH; + } + nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel); + if( nPLabel==0 ) return JSON_MERGE_BADPATCH; + iPValue = iPCursor + nPLabel + szPLabel; + if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH; + nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue); + if( nPValue==0 ) return JSON_MERGE_BADPATCH; + iPCursor = iPValue + nPValue + szPValue; + if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH; + + iTCursor = iTStart; + iTEnd = iTEndBE + pTarget->delta; + while( iTCursoraBlob[iTCursor] & 0x0f; + if( eTLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADTARGET; + } + nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel); + if( nTLabel==0 ) return JSON_MERGE_BADTARGET; + iTValue = iTLabel + nTLabel + szTLabel; + if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET; + nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue); + if( nTValue==0 ) return JSON_MERGE_BADTARGET; + if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET; + isEqual = jsonLabelCompare( + (const char*)&pPatch->aBlob[iPLabel+nPLabel], + szPLabel, + (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW), + (const char*)&pTarget->aBlob[iTLabel+nTLabel], + szTLabel, + (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW)); + if( isEqual ) break; + iTCursor = iTValue + nTValue + szTValue; + } + x = pPatch->aBlob[iPValue] & 0x0f; + if( iTCursoroom) ) return JSON_MERGE_OOM; + }else{ + /* Algorithm line 12 */ + int rc, savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + }else if( x>0 ){ /* Algorithm line 13 */ + /* No match and patch value is not NULL */ + u32 szNew = szPLabel+nPLabel; + if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */ + jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + memcpy(&pTarget->aBlob[iTEnd+szNew], + &pPatch->aBlob[iPValue], szPValue+nPValue); + }else{ + int rc, savedDelta; + jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + pTarget->aBlob[iTEnd+szNew] = 0x00; + savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + } + } + if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; +} + + +/* +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON +** object that is the result of running the RFC 7396 MergePatch() algorithm +** on the two arguments. +*/ +static void jsonPatchFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *pTarget; /* The TARGET */ + JsonParse *pPatch; /* The PATCH */ + int rc; /* Result code */ + + UNUSED_PARAMETER(argc); + assert( argc==2 ); + pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE); + if( pTarget==0 ) return; + pPatch = jsonParseFuncArg(ctx, argv[1], 0); + if( pPatch ){ + rc = jsonMergePatch(pTarget, 0, pPatch, 0); + if( rc==JSON_MERGE_OK ){ + jsonReturnParse(ctx, pTarget); + }else if( rc==JSON_MERGE_OOM ){ + sqlite3_result_error_nomem(ctx); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + jsonParseFree(pPatch); + } + jsonParseFree(pTarget); +} + + +/* +** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON +** object that contains all name/value given in arguments. Or if any name +** is not a string or if any value is a BLOB, throw an error. +*/ +static void jsonObjectFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + JsonString jx; + const char *z; + u32 n; + + if( argc&1 ){ + sqlite3_result_error(ctx, "json_object() requires an even number " + "of arguments", -1); + return; + } + jsonStringInit(&jx, ctx); + jsonAppendChar(&jx, '{'); + for(i=0; i1 ? JSON_EDITABLE : 0); + if( p==0 ) return; + for(i=1; ieEdit = JEDIT_DEL; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(rc) ){ + if( rc==JSON_LOOKUP_NOTFOUND ){ + continue; /* No-op */ + }else if( rc==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + goto json_remove_done; + } + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +json_remove_patherror: + jsonBadPathError(ctx, zPath); + +json_remove_done: + jsonParseFree(p); + return; +} + +/* +** json_replace(JSON, PATH, VALUE, ...) +** +** Replace the value at PATH with VALUE. If PATH does not already exist, +** this routine is a no-op. If JSON or PATH is malformed, throw an error. +*/ +static void jsonReplaceFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + if( argc<1 ) return; + if( (argc&1)==0 ) { + jsonWrongNumArgs(ctx, "replace"); + return; + } + jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL); +} + + +/* +** json_set(JSON, PATH, VALUE, ...) +** +** Set the value at PATH to VALUE. Create the PATH if it does not already +** exist. Overwrite existing values that do exist. +** If JSON or PATH is malformed, throw an error. +** +** json_insert(JSON, PATH, VALUE, ...) +** +** Create PATH and initialize it to VALUE. If PATH already exists, this +** routine is a no-op. If JSON or PATH is malformed, throw an error. +*/ +static void jsonSetFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + int bIsSet = (flags&JSON_ISSET)!=0; + + if( argc<1 ) return; + if( (argc&1)==0 ) { + jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); + return; + } + jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); +} + +/* +** json_type(JSON) +** json_type(JSON, PATH) +** +** Return the top-level "type" of a JSON string. json_type() raises an +** error if either the JSON or PATH inputs are not well-formed. +*/ +static void jsonTypeFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + const char *zPath = 0; + u32 i; + + p = jsonParseFuncArg(ctx, argv[0], 0); + if( p==0 ) return; + if( argc==2 ){ + zPath = (const char*)sqlite3_value_text(argv[1]); + if( zPath==0 ) goto json_type_done; + if( zPath[0]!='$' ){ + jsonBadPathError(ctx, zPath); + goto json_type_done; + } + i = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + goto json_type_done; + } + }else{ + i = 0; + } + sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC); +json_type_done: + jsonParseFree(p); +} + +/* +** json_valid(JSON) +** json_valid(JSON, FLAGS) +** +** Check the JSON argument to see if it is well-formed. The FLAGS argument +** encodes the various constraints on what is meant by "well-formed": +** +** 0x01 Canonical RFC-8259 JSON text +** 0x02 JSON text with optional JSON-5 extensions +** 0x04 Superficially appears to be JSONB +** 0x08 Strictly well-formed JSONB +** +** If the FLAGS argument is omitted, it defaults to 1. Useful values for +** FLAGS include: +** +** 1 Strict canonical JSON text +** 2 JSON text perhaps with JSON-5 extensions +** 4 Superficially appears to be JSONB +** 5 Canonical JSON text or superficial JSONB +** 6 JSON-5 text or superficial JSONB +** 8 Strict JSONB +** 9 Canonical JSON text or strict JSONB +** 10 JSON-5 text or strict JSONB +** +** Other flag combinations are redundant. For example, every canonical +** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3 +** are the same. Similarly, any input that passes a strict JSONB validation +** will also pass the superficial validation so 12 through 15 are the same +** as 8 through 11 respectively. +** +** This routine runs in linear time to validate text and when doing strict +** JSONB validation. Superficial JSONB validation is constant time, +** assuming the BLOB is already in memory. The performance advantage +** of superficial JSONB validation is why that option is provided. +** Application developers can choose to do fast superficial validation or +** slower strict validation, according to their specific needs. +** +** Only the lower four bits of the FLAGS argument are currently used. +** Higher bits are reserved for future expansion. To facilitate +** compatibility, the current implementation raises an error if any bit +** in FLAGS is set other than the lower four bits. +** +** The original circa 2015 implementation of the JSON routines in +** SQLite only supported canonical RFC-8259 JSON text and the json_valid() +** function only accepted one argument. That is why the default value +** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only +** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS +** argument was added when the JSON routines were extended to support +** JSON5-like extensions and binary JSONB stored in BLOBs. +** +** Return Values: +** +** * Raise an error if FLAGS is outside the range of 1 to 15. +** * Return NULL if the input is NULL +** * Return 1 if the input is well-formed. +** * Return 0 if the input is not well-formed. +*/ +static void jsonValidFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + u8 flags = 1; + u8 res = 0; + if( argc==2 ){ + i64 f = sqlite3_value_int64(argv[1]); + if( f<1 || f>15 ){ + sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be" + " between 1 and 15", -1); + return; + } + flags = f & 0x0f; + } + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { +#ifdef SQLITE_LEGACY_JSON_VALID + /* Incorrect legacy behavior was to return FALSE for a NULL input */ + sqlite3_result_int(ctx, 0); +#endif + return; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(argv[0]) ){ + if( flags & 0x04 ){ + /* Superficial checking only - accomplished by the + ** jsonFuncArgMightBeBinary() call above. */ + res = 1; + }else if( flags & 0x08 ){ + /* Strict checking. Check by translating BLOB->TEXT->BLOB. If + ** no errors occur, call that a "strict check". */ + JsonParse px; + u32 iErr; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(argv[0]); + px.nBlob = sqlite3_value_bytes(argv[0]); + iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); + res = iErr==0; + } + break; + } + /* Fall through into interpreting the input as text. See note + ** above at tag-20240123-a. */ + /* no break */ deliberate_fall_through + } + default: { + JsonParse px; + if( (flags & 0x3)==0 ) break; + memset(&px, 0, sizeof(px)); + + p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); + if( p ){ + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + }else if( p->nErr ){ + /* no-op */ + }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){ + res = 1; + } + jsonParseFree(p); + }else{ + sqlite3_result_error_nomem(ctx); + } + break; + } + } + sqlite3_result_int(ctx, res); +} + +/* +** json_error_position(JSON) +** +** If the argument is NULL, return NULL +** +** If the argument is BLOB, do a full validity check and return non-zero +** if the check fails. The return value is the approximate 1-based offset +** to the byte of the element that contains the first error. +** +** Otherwise interpret the argument is TEXT (even if it is numeric) and +** return the 1-based character position for where the parser first recognized +** that the input was not valid JSON, or return 0 if the input text looks +** ok. JSON-5 extensions are accepted. +*/ +static void jsonErrorFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + i64 iErrPos = 0; /* Error position to be returned */ + JsonParse s; + + assert( argc==1 ); + UNUSED_PARAMETER(argc); + memset(&s, 0, sizeof(s)); + s.db = sqlite3_context_db_handle(ctx); + if( jsonFuncArgMightBeBinary(argv[0]) ){ + s.aBlob = (u8*)sqlite3_value_blob(argv[0]); + s.nBlob = sqlite3_value_bytes(argv[0]); + iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); + }else{ + s.zJson = (char*)sqlite3_value_text(argv[0]); + if( s.zJson==0 ) return; /* NULL input or OOM */ + s.nJson = sqlite3_value_bytes(argv[0]); + if( jsonConvertTextToBlob(&s,0) ){ + if( s.oom ){ + iErrPos = -1; + }else{ + /* Convert byte-offset s.iErr into a character offset */ + u32 k; + assert( s.zJson!=0 ); /* Because s.oom is false */ + for(k=0; kzBuf==0 ){ + jsonStringInit(pStr, ctx); + jsonAppendChar(pStr, '['); + }else if( pStr->nUsed>1 ){ + jsonAppendChar(pStr, ','); + } + pStr->pCtx = ctx; + jsonAppendSqlValue(pStr, argv[0]); + } +} +static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + int flags; + pStr->pCtx = ctx; + jsonAppendChar(pStr, ']'); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : + sqlite3RCStrUnref); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + jsonStringTrimOneChar(pStr); + } + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} +static void jsonArrayValue(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 0); +} +static void jsonArrayFinal(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 1); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** This method works for both json_group_array() and json_group_object(). +** It works by removing the first element of the group by searching forward +** to the first comma (",") that is not within a string and deleting all +** text through that comma. +*/ +static void jsonGroupInverse( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + unsigned int i; + int inStr = 0; + int nNest = 0; + char *z; + char c; + JsonString *pStr; + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); +#ifdef NEVER + /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will + ** always have been called to initialize it */ + if( NEVER(!pStr) ) return; +#endif + z = pStr->zBuf; + for(i=1; inUsed && ((c = z[i])!=',' || inStr || nNest); i++){ + if( c=='"' ){ + inStr = !inStr; + }else if( c=='\\' ){ + i++; + }else if( !inStr ){ + if( c=='{' || c=='[' ) nNest++; + if( c=='}' || c==']' ) nNest--; + } + } + if( inUsed ){ + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); + z[pStr->nUsed] = 0; + }else{ + pStr->nUsed = 1; + } +} +#else +# define jsonGroupInverse 0 +#endif + + +/* +** json_group_obj(NAME,VALUE) +** +** Return a JSON object composed of all names and values in the aggregate. +*/ +static void jsonObjectStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString *pStr; + const char *z; + u32 n; + UNUSED_PARAMETER(argc); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + jsonStringInit(pStr, ctx); + jsonAppendChar(pStr, '{'); + }else if( pStr->nUsed>1 ){ + jsonAppendChar(pStr, ','); + } + pStr->pCtx = ctx; + z = (const char*)sqlite3_value_text(argv[0]); + n = sqlite3Strlen30(z); + jsonAppendString(pStr, z, n); + jsonAppendChar(pStr, ':'); + jsonAppendSqlValue(pStr, argv[1]); + } +} +static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + int flags; + jsonAppendChar(pStr, '}'); + pStr->pCtx = ctx; + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : + sqlite3RCStrUnref); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + jsonStringTrimOneChar(pStr); + } + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} +static void jsonObjectValue(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 0); +} +static void jsonObjectFinal(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 1); +} + + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/**************************************************************************** +** The json_each virtual table +****************************************************************************/ +typedef struct JsonParent JsonParent; +struct JsonParent { + u32 iHead; /* Start of object or array */ + u32 iValue; /* Start of the value */ + u32 iEnd; /* First byte past the end */ + u32 nPath; /* Length of path */ + i64 iKey; /* Key for JSONB_ARRAY */ +}; + +typedef struct JsonEachCursor JsonEachCursor; +struct JsonEachCursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + u32 iRowid; /* The rowid */ + u32 i; /* Index in sParse.aBlob[] of current row */ + u32 iEnd; /* EOF when i equals or exceeds this value */ + u32 nRoot; /* Size of the root path in bytes */ + u8 eType; /* Type of the container for element i */ + u8 bRecursive; /* True for json_tree(). False for json_each() */ + u32 nParent; /* Current nesting depth */ + u32 nParentAlloc; /* Space allocated for aParent[] */ + JsonParent *aParent; /* Parent elements of i */ + sqlite3 *db; /* Database connection */ + JsonString path; /* Current path */ + JsonParse sParse; /* Parse of the input JSON */ +}; +typedef struct JsonEachConnection JsonEachConnection; +struct JsonEachConnection { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ +}; + + +/* Constructor for the json_each virtual table */ +static int jsonEachConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + JsonEachConnection *pNew; + int rc; + +/* Column numbers */ +#define JEACH_KEY 0 +#define JEACH_VALUE 1 +#define JEACH_TYPE 2 +#define JEACH_ATOM 3 +#define JEACH_ID 4 +#define JEACH_PARENT 5 +#define JEACH_FULLKEY 6 +#define JEACH_PATH 7 +/* The xBestIndex method assumes that the JSON and ROOT columns are +** the last two columns in the table. Should this ever changes, be +** sure to update the xBestIndex method. */ +#define JEACH_JSON 8 +#define JEACH_ROOT 9 + + UNUSED_PARAMETER(pzErr); + UNUSED_PARAMETER(argv); + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(pAux); + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," + "json HIDDEN,root HIDDEN)"); + if( rc==SQLITE_OK ){ + pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew)); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + pNew->db = db; + } + return rc; +} + +/* destructor for json_each virtual table */ +static int jsonEachDisconnect(sqlite3_vtab *pVtab){ + JsonEachConnection *p = (JsonEachConnection*)pVtab; + sqlite3DbFree(p->db, pVtab); + return SQLITE_OK; +} + +/* constructor for a JsonEachCursor object for json_each(). */ +static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + JsonEachConnection *pVtab = (JsonEachConnection*)p; + JsonEachCursor *pCur; + + UNUSED_PARAMETER(p); + pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur)); + if( pCur==0 ) return SQLITE_NOMEM; + pCur->db = pVtab->db; + jsonStringZero(&pCur->path); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* constructor for a JsonEachCursor object for json_tree(). */ +static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + int rc = jsonEachOpenEach(p, ppCursor); + if( rc==SQLITE_OK ){ + JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; + pCur->bRecursive = 1; + } + return rc; +} + +/* Reset a JsonEachCursor back to its original state. Free any memory +** held. */ +static void jsonEachCursorReset(JsonEachCursor *p){ + jsonParseReset(&p->sParse); + jsonStringReset(&p->path); + sqlite3DbFree(p->db, p->aParent); + p->iRowid = 0; + p->i = 0; + p->aParent = 0; + p->nParent = 0; + p->nParentAlloc = 0; + p->iEnd = 0; + p->eType = 0; +} + +/* Destructor for a jsonEachCursor object */ +static int jsonEachClose(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + jsonEachCursorReset(p); + + sqlite3DbFree(p->db, cur); + return SQLITE_OK; +} + +/* Return TRUE if the jsonEachCursor object has been advanced off the end +** of the JSON object */ +static int jsonEachEof(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + return p->i >= p->iEnd; +} + +/* +** If the cursor is currently pointing at the label of a object entry, +** then return the index of the value. For all other cases, return the +** current pointer position, which is the value. +*/ +static int jsonSkipLabel(JsonEachCursor *p){ + if( p->eType==JSONB_OBJECT ){ + u32 sz = 0; + u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); + return p->i + n + sz; + }else{ + return p->i; + } +} + +/* +** Append the path name for the current element. +*/ +static void jsonAppendPathName(JsonEachCursor *p){ + assert( p->nParent>0 ); + assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT ); + if( p->eType==JSONB_ARRAY ){ + jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey); + }else{ + u32 n, sz = 0, k, i; + const char *z; + int needQuote = 0; + n = jsonbPayloadSize(&p->sParse, p->i, &sz); + k = p->i + n; + z = (const char*)&p->sParse.aBlob[k]; + if( sz==0 || !sqlite3Isalpha(z[0]) ){ + needQuote = 1; + }else{ + for(i=0; ipath,".\"%.*s\"", sz, z); + }else{ + jsonPrintf(sz+2,&p->path,".%.*s", sz, z); + } + } +} + +/* Advance the cursor to the next element for json_tree() */ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + int rc = SQLITE_OK; + if( p->bRecursive ){ + u8 x; + u8 levelChange = 0; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + x = p->sParse.aBlob[i] & 0x0f; + n = jsonbPayloadSize(&p->sParse, i, &sz); + if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ + JsonParent *pParent; + if( p->nParent>=p->nParentAlloc ){ + JsonParent *pNew; + u64 nNew; + nNew = p->nParentAlloc*2 + 3; + pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew); + if( pNew==0 ) return SQLITE_NOMEM; + p->nParentAlloc = (u32)nNew; + p->aParent = pNew; + } + levelChange = 1; + pParent = &p->aParent[p->nParent]; + pParent->iHead = p->i; + pParent->iValue = i; + pParent->iEnd = i + n + sz; + pParent->iKey = -1; + pParent->nPath = (u32)p->path.nUsed; + if( p->eType && p->nParent ){ + jsonAppendPathName(p); + if( p->path.eErr ) rc = SQLITE_NOMEM; + } + p->nParent++; + p->i = i + n; + }else{ + p->i = i + n + sz; + } + while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){ + p->nParent--; + p->path.nUsed = p->aParent[p->nParent].nPath; + levelChange = 1; + } + if( levelChange ){ + if( p->nParent>0 ){ + JsonParent *pParent = &p->aParent[p->nParent-1]; + u32 iVal = pParent->iValue; + p->eType = p->sParse.aBlob[iVal] & 0x0f; + }else{ + p->eType = 0; + } + } + }else{ + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->i = i + n + sz; + } + if( p->eType==JSONB_ARRAY && p->nParent ){ + p->aParent[p->nParent-1].iKey++; + } + p->iRowid++; + return rc; +} + +/* Length of the path for rowid==0 in bRecursive mode. +*/ +static int jsonEachPathLength(JsonEachCursor *p){ + u32 n = p->path.nUsed; + char *z = p->path.zBuf; + if( p->iRowid==0 && p->bRecursive && n>=2 ){ + while( n>1 ){ + n--; + if( z[n]=='[' || z[n]=='.' ){ + u32 x, sz = 0; + char cSaved = z[n]; + z[n] = 0; + assert( p->sParse.eEdit==0 ); + x = jsonLookupStep(&p->sParse, 0, z+1, 0); + z[n] = cSaved; + if( JSON_LOOKUP_ISERROR(x) ) continue; + if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break; + } + } + } + return n; +} + +/* Return the value of a column */ +static int jsonEachColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int iColumn /* Which column to return */ +){ + JsonEachCursor *p = (JsonEachCursor*)cur; + switch( iColumn ){ + case JEACH_KEY: { + if( p->nParent==0 ){ + u32 n, j; + if( p->nRoot==1 ) break; + j = jsonEachPathLength(p); + n = p->nRoot - j; + if( n==0 ){ + break; + }else if( p->path.zBuf[j]=='[' ){ + i64 x; + sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8); + sqlite3_result_int64(ctx, x); + }else if( p->path.zBuf[j+1]=='"' ){ + sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT); + } + break; + } + if( p->eType==JSONB_OBJECT ){ + jsonReturnFromBlob(&p->sParse, p->i, ctx, 1); + }else{ + assert( p->eType==JSONB_ARRAY ); + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey); + } + break; + } + case JEACH_VALUE: { + u32 i = jsonSkipLabel(p); + jsonReturnFromBlob(&p->sParse, i, ctx, 1); + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + break; + } + case JEACH_TYPE: { + u32 i = jsonSkipLabel(p); + u8 eType = p->sParse.aBlob[i] & 0x0f; + sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC); + break; + } + case JEACH_ATOM: { + u32 i = jsonSkipLabel(p); + if( (p->sParse.aBlob[i] & 0x0f)sParse, i, ctx, 1); + } + break; + } + case JEACH_ID: { + sqlite3_result_int64(ctx, (sqlite3_int64)p->i); + break; + } + case JEACH_PARENT: { + if( p->nParent>0 && p->bRecursive ){ + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead); + } + break; + } + case JEACH_FULLKEY: { + u64 nBase = p->path.nUsed; + if( p->nParent ) jsonAppendPathName(p); + sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + p->path.nUsed = nBase; + break; + } + case JEACH_PATH: { + u32 n = jsonEachPathLength(p); + sqlite3_result_text64(ctx, p->path.zBuf, n, + SQLITE_TRANSIENT, SQLITE_UTF8); + break; + } + default: { + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); + break; + } + case JEACH_JSON: { + if( p->sParse.zJson==0 ){ + sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, + SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT); + } + break; + } + } + return SQLITE_OK; +} + +/* Return the current rowid value */ +static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + JsonEachCursor *p = (JsonEachCursor*)cur; + *pRowid = p->iRowid; + return SQLITE_OK; +} + +/* The query strategy is to look for an equality constraint on the json +** column. Without such a constraint, the table cannot operate. idxNum is +** 1 if the constraint is found, 3 if the constraint and zRoot are found, +** and 0 otherwise. +*/ +static int jsonEachBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop counter or computed array index */ + int aIdx[2]; /* Index of constraints for JSON and ROOT */ + int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */ + int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */ + const struct sqlite3_index_constraint *pConstraint; + + /* This implementation assumes that JSON and ROOT are the last two + ** columns in the table */ + assert( JEACH_ROOT == JEACH_JSON+1 ); + UNUSED_PARAMETER(tab); + aIdx[0] = aIdx[1] = -1; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + int iCol; + int iMask; + if( pConstraint->iColumn < JEACH_JSON ) continue; + iCol = pConstraint->iColumn - JEACH_JSON; + assert( iCol==0 || iCol==1 ); + testcase( iCol==0 ); + iMask = 1 << iCol; + if( pConstraint->usable==0 ){ + unusableMask |= iMask; + }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + aIdx[iCol] = i; + idxMask |= iMask; + } + } + if( pIdxInfo->nOrderBy>0 + && pIdxInfo->aOrderBy[0].iColumn<0 + && pIdxInfo->aOrderBy[0].desc==0 + ){ + pIdxInfo->orderByConsumed = 1; + } + + if( (unusableMask & ~idxMask)!=0 ){ + /* If there are any unusable constraints on JSON or ROOT, then reject + ** this entire plan */ + return SQLITE_CONSTRAINT; + } + if( aIdx[0]<0 ){ + /* No JSON input. Leave estimatedCost at the huge value that it was + ** initialized to to discourage the query planner from selecting this + ** plan. */ + pIdxInfo->idxNum = 0; + }else{ + pIdxInfo->estimatedCost = 1.0; + i = aIdx[0]; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + if( aIdx[1]<0 ){ + pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */ + }else{ + i = aIdx[1]; + pIdxInfo->aConstraintUsage[i].argvIndex = 2; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */ + } + } + return SQLITE_OK; +} + +/* Start a search on a new JSON string */ +static int jsonEachFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + JsonEachCursor *p = (JsonEachCursor*)cur; + const char *zRoot = 0; + u32 i, n, sz; + + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(argc); + jsonEachCursorReset(p); + if( idxNum==0 ) return SQLITE_OK; + memset(&p->sParse, 0, sizeof(p->sParse)); + p->sParse.nJPRef = 1; + p->sParse.db = p->db; + if( jsonFuncArgMightBeBinary(argv[0]) ){ + p->sParse.nBlob = sqlite3_value_bytes(argv[0]); + p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); + }else{ + p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); + p->sParse.nJson = sqlite3_value_bytes(argv[0]); + if( p->sParse.zJson==0 ){ + p->i = p->iEnd = 0; + return SQLITE_OK; + } + if( jsonConvertTextToBlob(&p->sParse, 0) ){ + if( p->sParse.oom ){ + return SQLITE_NOMEM; + } + goto json_each_malformed_input; + } + } + if( idxNum==3 ){ + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + if( zRoot[0]!='$' ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + p->nRoot = sqlite3Strlen30(zRoot); + if( zRoot[1]==0 ){ + i = p->i = 0; + p->eType = 0; + }else{ + i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + p->i = 0; + p->eType = 0; + p->iEnd = 0; + return SQLITE_OK; + } + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + if( p->sParse.iLabel ){ + p->i = p->sParse.iLabel; + p->eType = JSONB_OBJECT; + }else{ + p->i = i; + p->eType = JSONB_ARRAY; + } + } + jsonAppendRaw(&p->path, zRoot, p->nRoot); + }else{ + i = p->i = 0; + p->eType = 0; + p->nRoot = 1; + jsonAppendRaw(&p->path, "$", 1); + } + p->nParent = 0; + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->iEnd = i+n+sz; + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){ + p->i = i + n; + p->eType = p->sParse.aBlob[i] & 0x0f; + p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent)); + if( p->aParent==0 ) return SQLITE_NOMEM; + p->nParent = 1; + p->nParentAlloc = 1; + p->aParent[0].iKey = 0; + p->aParent[0].iEnd = p->iEnd; + p->aParent[0].iHead = p->i; + p->aParent[0].iValue = i; + } + return SQLITE_OK; + +json_each_malformed_input: + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; +} + +/* The methods of the json_each virtual table */ +static sqlite3_module jsonEachModule = { + 0, /* iVersion */ + 0, /* xCreate */ + jsonEachConnect, /* xConnect */ + jsonEachBestIndex, /* xBestIndex */ + jsonEachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + jsonEachOpenEach, /* xOpen - open a cursor */ + jsonEachClose, /* xClose - close a cursor */ + jsonEachFilter, /* xFilter - configure scan constraints */ + jsonEachNext, /* xNext - advance a cursor */ + jsonEachEof, /* xEof - check for end of scan */ + jsonEachColumn, /* xColumn - read data */ + jsonEachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ +}; + +/* The methods of the json_tree virtual table. */ +static sqlite3_module jsonTreeModule = { + 0, /* iVersion */ + 0, /* xCreate */ + jsonEachConnect, /* xConnect */ + jsonEachBestIndex, /* xBestIndex */ + jsonEachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + jsonEachOpenTree, /* xOpen - open a cursor */ + jsonEachClose, /* xClose - close a cursor */ + jsonEachFilter, /* xFilter - configure scan constraints */ + jsonEachNext, /* xNext - advance a cursor */ + jsonEachEof, /* xEof - check for end of scan */ + jsonEachColumn, /* xColumn - read data */ + jsonEachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ +}; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ +#endif /* !defined(SQLITE_OMIT_JSON) */ + +/* +** Register JSON functions. +*/ +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ +#ifndef SQLITE_OMIT_JSON + static FuncDef aJsonFunc[] = { + /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */ + /* | | */ + /* Uses cache ------, | | ,---- Returns JSONB */ + /* | | | | */ + /* Number of arguments ---, | | | | ,--- Flags */ + /* | | | | | | */ + JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), + JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), + JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), + JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc), + JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc), + JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc), + JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc), + JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc), + JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), + JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), + JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), + JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), + JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc), + JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc), + JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc), + JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc), + JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc), +#if SQLITE_DEBUG + JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc), +#endif + WAGGREGATE(json_group_array, 1, 0, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| + SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| + SQLITE_DETERMINISTIC) + }; + sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); +#endif +} + +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +/* +** Register the JSON table-valued functions +*/ +SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){ + int rc = SQLITE_OK; + static const struct { + const char *zName; + sqlite3_module *pModule; + } aMod[] = { + { "json_each", &jsonEachModule }, + { "json_tree", &jsonTreeModule }, + }; + unsigned int i; + for(i=0; i */ +/* #include */ +/* #include */ +/* #include */ + +/* The following macro is used to suppress compiler warnings. +*/ +#ifndef UNUSED_PARAMETER +# define UNUSED_PARAMETER(x) (void)(x) +#endif + +typedef struct Rtree Rtree; +typedef struct RtreeCursor RtreeCursor; +typedef struct RtreeNode RtreeNode; +typedef struct RtreeCell RtreeCell; +typedef struct RtreeConstraint RtreeConstraint; +typedef struct RtreeMatchArg RtreeMatchArg; +typedef struct RtreeGeomCallback RtreeGeomCallback; +typedef union RtreeCoord RtreeCoord; +typedef struct RtreeSearchPoint RtreeSearchPoint; + +/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ +#define RTREE_MAX_DIMENSIONS 5 + +/* Maximum number of auxiliary columns */ +#define RTREE_MAX_AUX_COLUMN 100 + +/* Size of hash table Rtree.aHash. This hash table is not expected to +** ever contain very many entries, so a fixed number of buckets is +** used. +*/ +#define HASHSIZE 97 + +/* The xBestIndex method of this virtual table requires an estimate of +** the number of rows in the virtual table to calculate the costs of +** various strategies. If possible, this estimate is loaded from the +** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). +** Otherwise, if no sqlite_stat1 entry is available, use +** RTREE_DEFAULT_ROWEST. +*/ +#define RTREE_DEFAULT_ROWEST 1048576 +#define RTREE_MIN_ROWEST 100 + +/* +** An rtree virtual-table object. +*/ +struct Rtree { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* Host database connection */ + int iNodeSize; /* Size in bytes of each node in the node table */ + u8 nDim; /* Number of dimensions */ + u8 nDim2; /* Twice the number of dimensions */ + u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ + u8 nBytesPerCell; /* Bytes consumed per cell */ + u8 inWrTrans; /* True if inside write transaction */ + u8 nAux; /* # of auxiliary columns in %_rowid */ +#ifdef SQLITE_ENABLE_GEOPOLY + u8 nAuxNotNull; /* Number of initial not-null aux columns */ +#endif +#ifdef SQLITE_DEBUG + u8 bCorrupt; /* Shadow table corruption detected */ +#endif + int iDepth; /* Current depth of the r-tree structure */ + char *zDb; /* Name of database containing r-tree table */ + char *zName; /* Name of r-tree table */ + char *zNodeName; /* Name of the %_node table */ + u32 nBusy; /* Current number of users of this structure */ + i64 nRowEst; /* Estimated number of rows in this table */ + u32 nCursor; /* Number of open cursors */ + u32 nNodeRef; /* Number RtreeNodes with positive nRef */ + char *zReadAuxSql; /* SQL for statement to read aux data */ + + /* List of nodes removed during a CondenseTree operation. List is + ** linked together via the pointer normally used for hash chains - + ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree + ** headed by the node (leaf nodes have RtreeNode.iNode==0). + */ + RtreeNode *pDeleted; + + /* Blob I/O on xxx_node */ + sqlite3_blob *pNodeBlob; + + /* Statements to read/write/delete a record from xxx_node */ + sqlite3_stmt *pWriteNode; + sqlite3_stmt *pDeleteNode; + + /* Statements to read/write/delete a record from xxx_rowid */ + sqlite3_stmt *pReadRowid; + sqlite3_stmt *pWriteRowid; + sqlite3_stmt *pDeleteRowid; + + /* Statements to read/write/delete a record from xxx_parent */ + sqlite3_stmt *pReadParent; + sqlite3_stmt *pWriteParent; + sqlite3_stmt *pDeleteParent; + + /* Statement for writing to the "aux:" fields, if there are any */ + sqlite3_stmt *pWriteAux; + + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ +}; + +/* Possible values for Rtree.eCoordType: */ +#define RTREE_COORD_REAL32 0 +#define RTREE_COORD_INT32 1 + +/* +** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will +** only deal with integer coordinates. No floating point operations +** will be done. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ + typedef int RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0 +#else + typedef double RtreeDValue; /* High accuracy coordinate */ + typedef float RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0.0 +#endif + +/* +** Set the Rtree.bCorrupt flag +*/ +#ifdef SQLITE_DEBUG +# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1) +#else +# define RTREE_IS_CORRUPT(X) +#endif + +/* +** When doing a search of an r-tree, instances of the following structure +** record intermediate results from the tree walk. +** +** The id is always a node-id. For iLevel>=1 the id is the node-id of +** the node that the RtreeSearchPoint represents. When iLevel==0, however, +** the id is of the parent node and the cell that RtreeSearchPoint +** represents is the iCell-th entry in the parent node. +*/ +struct RtreeSearchPoint { + RtreeDValue rScore; /* The score for this node. Smallest goes first. */ + sqlite3_int64 id; /* Node ID */ + u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ + u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ + u8 iCell; /* Cell index within the node */ +}; + +/* +** The minimum number of cells allowed for a node is a third of the +** maximum. In Gutman's notation: +** +** m = M/3 +** +** If an R*-tree "Reinsert" operation is required, the same number of +** cells are removed from the overfull node and reinserted into the tree. +*/ +#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) +#define RTREE_REINSERT(p) RTREE_MINCELLS(p) +#define RTREE_MAXCELLS 51 + +/* +** The smallest possible node-size is (512-64)==448 bytes. And the largest +** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). +** Therefore all non-root nodes must contain at least 3 entries. Since +** 3^40 is greater than 2^64, an r-tree structure always has a depth of +** 40 or less. +*/ +#define RTREE_MAX_DEPTH 40 + + +/* +** Number of entries in the cursor RtreeNode cache. The first entry is +** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining +** entries cache the RtreeNode for the first elements of the priority queue. +*/ +#define RTREE_CACHE_SZ 5 + +/* +** An rtree cursor object. +*/ +struct RtreeCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + u8 atEOF; /* True if at end of search */ + u8 bPoint; /* True if sPoint is valid */ + u8 bAuxValid; /* True if pReadAux is valid */ + int iStrategy; /* Copy of idxNum search parameter */ + int nConstraint; /* Number of entries in aConstraint */ + RtreeConstraint *aConstraint; /* Search constraints. */ + int nPointAlloc; /* Number of slots allocated for aPoint[] */ + int nPoint; /* Number of slots used in aPoint[] */ + int mxLevel; /* iLevel value for root of the tree */ + RtreeSearchPoint *aPoint; /* Priority queue for search points */ + sqlite3_stmt *pReadAux; /* Statement to read aux-data */ + RtreeSearchPoint sPoint; /* Cached next search point */ + RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ + u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ +}; + +/* Return the Rtree of a RtreeCursor */ +#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) + +/* +** A coordinate can be either a floating point number or a integer. All +** coordinates within a single R-Tree are always of the same time. +*/ +union RtreeCoord { + RtreeValue f; /* Floating point value */ + int i; /* Integer value */ + u32 u; /* Unsigned for byte-order conversions */ +}; + +/* +** The argument is an RtreeCoord. Return the value stored within the RtreeCoord +** formatted as a RtreeDValue (double or int64). This macro assumes that local +** variable pRtree points to the Rtree structure associated with the +** RtreeCoord. +*/ +#ifdef SQLITE_RTREE_INT_ONLY +# define DCOORD(coord) ((RtreeDValue)coord.i) +#else +# define DCOORD(coord) ( \ + (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ + ((double)coord.f) : \ + ((double)coord.i) \ + ) +#endif + +/* +** A search constraint. +*/ +struct RtreeConstraint { + int iCoord; /* Index of constrained coordinate */ + int op; /* Constraining operation */ + union { + RtreeDValue rValue; /* Constraint value. */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + } u; + sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ +}; + +/* Possible values for RtreeConstraint.op */ +#define RTREE_EQ 0x41 /* A */ +#define RTREE_LE 0x42 /* B */ +#define RTREE_LT 0x43 /* C */ +#define RTREE_GE 0x44 /* D */ +#define RTREE_GT 0x45 /* E */ +#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ +#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ + +/* Special operators available only on cursors. Needs to be consecutive +** with the normal values above, but must be less than RTREE_MATCH. These +** are used in the cursor for contraints such as x=NULL (RTREE_FALSE) or +** x<'xyz' (RTREE_TRUE) */ +#define RTREE_TRUE 0x3f /* ? */ +#define RTREE_FALSE 0x40 /* @ */ + +/* +** An rtree structure node. +*/ +struct RtreeNode { + RtreeNode *pParent; /* Parent node */ + i64 iNode; /* The node number */ + int nRef; /* Number of references to this node */ + int isDirty; /* True if the node needs to be written to disk */ + u8 *zData; /* Content of the node, as should be on disk */ + RtreeNode *pNext; /* Next node in this hash collision chain */ +}; + +/* Return the number of cells in a node */ +#define NCELL(pNode) readInt16(&(pNode)->zData[2]) + +/* +** A single cell from a node, deserialized +*/ +struct RtreeCell { + i64 iRowid; /* Node or entry ID */ + RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ +}; + + +/* +** This object becomes the sqlite3_user_data() for the SQL functions +** that are created by sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() and which appear on the right of MATCH +** operators in order to constrain a search. +** +** xGeom and xQueryFunc are the callback functions. Exactly one of +** xGeom and xQueryFunc fields is non-NULL, depending on whether the +** SQL function was created using sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback(). +** +** This object is deleted automatically by the destructor mechanism in +** sqlite3_create_function_v2(). +*/ +struct RtreeGeomCallback { + int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + void (*xDestructor)(void*); + void *pContext; +}; + +/* +** An instance of this structure (in the form of a BLOB) is returned by +** the SQL functions that sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() create, and is read as the right-hand +** operand to the MATCH operator of an R-Tree. +*/ +struct RtreeMatchArg { + u32 iSize; /* Size of this object */ + RtreeGeomCallback cb; /* Info about the callback functions */ + int nParam; /* Number of parameters to the SQL function */ + sqlite3_value **apSqlParam; /* Original SQL parameter values */ + RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ +}; + +#ifndef MAX +# define MAX(x,y) ((x) < (y) ? (y) : (x)) +#endif +#ifndef MIN +# define MIN(x,y) ((x) > (y) ? (y) : (x)) +#endif + +/* What version of GCC is being used. 0 means GCC is not being used . +** Note that the GCC_VERSION macro will also be set correctly when using +** clang, since clang works hard to be gcc compatible. So the gcc +** optimizations will also work when compiling with clang. +*/ +#ifndef GCC_VERSION +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif + +/* The testcase() macro should already be defined in the amalgamation. If +** it is not, make it a no-op. +*/ +#ifndef SQLITE_AMALGAMATION +# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) + unsigned int sqlite3RtreeTestcase = 0; +# define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; } +# else +# define testcase(X) +# endif +#endif + +/* +** Make sure that the compiler intrinsics we desire are enabled when +** compiling with an appropriate version of MSVC unless prevented by +** the SQLITE_DISABLE_INTRINSIC define. +*/ +#if !defined(SQLITE_DISABLE_INTRINSIC) +# if defined(_MSC_VER) && _MSC_VER>=1400 +# if !defined(_WIN32_WCE) +/* # include */ +# pragma intrinsic(_byteswap_ulong) +# pragma intrinsic(_byteswap_uint64) +# else +/* # include */ +# endif +# endif +#endif + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 +# else +# define SQLITE_BYTEORDER 0 +# endif +#endif + + +/* What version of MSVC is being used. 0 means MSVC is not being used */ +#ifndef MSVC_VERSION +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + +/* +** Functions to deserialize a 16 bit integer, 32 bit real number and +** 64 bit integer. The deserialized value is returned. +*/ +static int readInt16(u8 *p){ + return (p[0]<<8) + p[1]; +} +static void readCoord(u8 *p, RtreeCoord *pCoord){ + assert( FOUR_BYTE_ALIGNED(p) ); +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + pCoord->u = _byteswap_ulong(*(u32*)p); +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + pCoord->u = __builtin_bswap32(*(u32*)p); +#elif SQLITE_BYTEORDER==4321 + pCoord->u = *(u32*)p; +#else + pCoord->u = ( + (((u32)p[0]) << 24) + + (((u32)p[1]) << 16) + + (((u32)p[2]) << 8) + + (((u32)p[3]) << 0) + ); +#endif +} +static i64 readInt64(u8 *p){ +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u64 x; + memcpy(&x, p, 8); + return (i64)_byteswap_uint64(x); +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u64 x; + memcpy(&x, p, 8); + return (i64)__builtin_bswap64(x); +#elif SQLITE_BYTEORDER==4321 + i64 x; + memcpy(&x, p, 8); + return x; +#else + return (i64)( + (((u64)p[0]) << 56) + + (((u64)p[1]) << 48) + + (((u64)p[2]) << 40) + + (((u64)p[3]) << 32) + + (((u64)p[4]) << 24) + + (((u64)p[5]) << 16) + + (((u64)p[6]) << 8) + + (((u64)p[7]) << 0) + ); +#endif +} + +/* +** Functions to serialize a 16 bit integer, 32 bit real number and +** 64 bit integer. The value returned is the number of bytes written +** to the argument buffer (always 2, 4 and 8 respectively). +*/ +static void writeInt16(u8 *p, int i){ + p[0] = (i>> 8)&0xFF; + p[1] = (i>> 0)&0xFF; +} +static int writeCoord(u8 *p, RtreeCoord *pCoord){ + u32 i; + assert( FOUR_BYTE_ALIGNED(p) ); + assert( sizeof(RtreeCoord)==4 ); + assert( sizeof(u32)==4 ); +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + i = __builtin_bswap32(pCoord->u); + memcpy(p, &i, 4); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + i = _byteswap_ulong(pCoord->u); + memcpy(p, &i, 4); +#elif SQLITE_BYTEORDER==4321 + i = pCoord->u; + memcpy(p, &i, 4); +#else + i = pCoord->u; + p[0] = (i>>24)&0xFF; + p[1] = (i>>16)&0xFF; + p[2] = (i>> 8)&0xFF; + p[3] = (i>> 0)&0xFF; +#endif + return 4; +} +static int writeInt64(u8 *p, i64 i){ +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + i = (i64)__builtin_bswap64((u64)i); + memcpy(p, &i, 8); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + i = (i64)_byteswap_uint64((u64)i); + memcpy(p, &i, 8); +#elif SQLITE_BYTEORDER==4321 + memcpy(p, &i, 8); +#else + p[0] = (i>>56)&0xFF; + p[1] = (i>>48)&0xFF; + p[2] = (i>>40)&0xFF; + p[3] = (i>>32)&0xFF; + p[4] = (i>>24)&0xFF; + p[5] = (i>>16)&0xFF; + p[6] = (i>> 8)&0xFF; + p[7] = (i>> 0)&0xFF; +#endif + return 8; +} + +/* +** Increment the reference count of node p. +*/ +static void nodeReference(RtreeNode *p){ + if( p ){ + assert( p->nRef>0 ); + p->nRef++; + } +} + +/* +** Clear the content of node p (set all bytes to 0x00). +*/ +static void nodeZero(Rtree *pRtree, RtreeNode *p){ + memset(&p->zData[2], 0, pRtree->iNodeSize-2); + p->isDirty = 1; +} + +/* +** Given a node number iNode, return the corresponding key to use +** in the Rtree.aHash table. +*/ +static unsigned int nodeHash(i64 iNode){ + return ((unsigned)iNode) % HASHSIZE; +} + +/* +** Search the node hash table for node iNode. If found, return a pointer +** to it. Otherwise, return 0. +*/ +static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ + RtreeNode *p; + for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); + return p; +} + +/* +** Add node pNode to the node hash table. +*/ +static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ + int iHash; + assert( pNode->pNext==0 ); + iHash = nodeHash(pNode->iNode); + pNode->pNext = pRtree->aHash[iHash]; + pRtree->aHash[iHash] = pNode; +} + +/* +** Remove node pNode from the node hash table. +*/ +static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ + RtreeNode **pp; + if( pNode->iNode!=0 ){ + pp = &pRtree->aHash[nodeHash(pNode->iNode)]; + for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } + *pp = pNode->pNext; + pNode->pNext = 0; + } +} + +/* +** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0), +** indicating that node has not yet been assigned a node number. It is +** assigned a node number when nodeWrite() is called to write the +** node contents out to the database. +*/ +static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ + RtreeNode *pNode; + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize); + if( pNode ){ + memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pRtree->nNodeRef++; + pNode->pParent = pParent; + pNode->isDirty = 1; + nodeReference(pParent); + } + return pNode; +} + +/* +** Clear the Rtree.pNodeBlob object +*/ +static void nodeBlobReset(Rtree *pRtree){ + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + sqlite3_blob_close(pBlob); +} + +/* +** Obtain a reference to an r-tree node. +*/ +static int nodeAcquire( + Rtree *pRtree, /* R-tree structure */ + i64 iNode, /* Node number to load */ + RtreeNode *pParent, /* Either the parent node or NULL */ + RtreeNode **ppNode /* OUT: Acquired node */ +){ + int rc = SQLITE_OK; + RtreeNode *pNode = 0; + + /* Check if the requested node is already in the hash table. If so, + ** increase its reference count and return it. + */ + if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ + if( pParent && ALWAYS(pParent!=pNode->pParent) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + pNode->nRef++; + *ppNode = pNode; + return SQLITE_OK; + } + + if( pRtree->pNodeBlob ){ + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + rc = sqlite3_blob_reopen(pBlob, iNode); + pRtree->pNodeBlob = pBlob; + if( rc ){ + nodeBlobReset(pRtree); + if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM; + } + } + if( pRtree->pNodeBlob==0 ){ + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, pRtree->zNodeName, + "data", iNode, 0, + &pRtree->pNodeBlob); + } + if( rc ){ + *ppNode = 0; + /* If unable to open an sqlite3_blob on the desired row, that can only + ** be because the shadow tables hold erroneous data. */ + if( rc==SQLITE_ERROR ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); + if( !pNode ){ + rc = SQLITE_NOMEM; + }else{ + pNode->pParent = pParent; + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pRtree->nNodeRef++; + pNode->iNode = iNode; + pNode->isDirty = 0; + pNode->pNext = 0; + rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData, + pRtree->iNodeSize, 0); + } + } + + /* If the root node was just loaded, set pRtree->iDepth to the height + ** of the r-tree structure. A height of zero means all data is stored on + ** the root node. A height of one means the children of the root node + ** are the leaves, and so on. If the depth as specified on the root node + ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. + */ + if( rc==SQLITE_OK && pNode && iNode==1 ){ + pRtree->iDepth = readInt16(pNode->zData); + if( pRtree->iDepth>RTREE_MAX_DEPTH ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + } + + /* If no error has occurred so far, check if the "number of entries" + ** field on the node is too large. If so, set the return code to + ** SQLITE_CORRUPT_VTAB. + */ + if( pNode && rc==SQLITE_OK ){ + if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + } + + if( rc==SQLITE_OK ){ + if( pNode!=0 ){ + nodeReference(pParent); + nodeHashInsert(pRtree, pNode); + }else{ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + *ppNode = pNode; + }else{ + nodeBlobReset(pRtree); + if( pNode ){ + pRtree->nNodeRef--; + sqlite3_free(pNode); + } + *ppNode = 0; + } + + return rc; +} + +/* +** Overwrite cell iCell of node pNode with the contents of pCell. +*/ +static void nodeOverwriteCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node into which the cell is to be written */ + RtreeCell *pCell, /* The cell to write */ + int iCell /* Index into pNode into which pCell is written */ +){ + int ii; + u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; + p += writeInt64(p, pCell->iRowid); + for(ii=0; iinDim2; ii++){ + p += writeCoord(p, &pCell->aCoord[ii]); + } + pNode->isDirty = 1; +} + +/* +** Remove the cell with index iCell from node pNode. +*/ +static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ + u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; + u8 *pSrc = &pDst[pRtree->nBytesPerCell]; + int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; + memmove(pDst, pSrc, nByte); + writeInt16(&pNode->zData[2], NCELL(pNode)-1); + pNode->isDirty = 1; +} + +/* +** Insert the contents of cell pCell into node pNode. If the insert +** is successful, return SQLITE_OK. +** +** If there is not enough free space in pNode, return SQLITE_FULL. +*/ +static int nodeInsertCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* Write new cell into this node */ + RtreeCell *pCell /* The cell to be inserted */ +){ + int nCell; /* Current number of cells in pNode */ + int nMaxCell; /* Maximum number of cells for pNode */ + + nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; + nCell = NCELL(pNode); + + assert( nCell<=nMaxCell ); + if( nCellzData[2], nCell+1); + pNode->isDirty = 1; + } + + return (nCell==nMaxCell); +} + +/* +** If the node is dirty, write it out to the database. +*/ +static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ + int rc = SQLITE_OK; + if( pNode->isDirty ){ + sqlite3_stmt *p = pRtree->pWriteNode; + if( pNode->iNode ){ + sqlite3_bind_int64(p, 1, pNode->iNode); + }else{ + sqlite3_bind_null(p, 1); + } + sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); + sqlite3_step(p); + pNode->isDirty = 0; + rc = sqlite3_reset(p); + sqlite3_bind_null(p, 2); + if( pNode->iNode==0 && rc==SQLITE_OK ){ + pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); + nodeHashInsert(pRtree, pNode); + } + } + return rc; +} + +/* +** Release a reference to a node. If the node is dirty and the reference +** count drops to zero, the node data is written to the database. +*/ +static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ + int rc = SQLITE_OK; + if( pNode ){ + assert( pNode->nRef>0 ); + assert( pRtree->nNodeRef>0 ); + pNode->nRef--; + if( pNode->nRef==0 ){ + pRtree->nNodeRef--; + if( pNode->iNode==1 ){ + pRtree->iDepth = -1; + } + if( pNode->pParent ){ + rc = nodeRelease(pRtree, pNode->pParent); + } + if( rc==SQLITE_OK ){ + rc = nodeWrite(pRtree, pNode); + } + nodeHashDelete(pRtree, pNode); + sqlite3_free(pNode); + } + } + return rc; +} + +/* +** Return the 64-bit integer value associated with cell iCell of +** node pNode. If pNode is a leaf node, this is a rowid. If it is +** an internal node, then the 64-bit integer is a child page number. +*/ +static i64 nodeGetRowid( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract the ID */ + int iCell /* The cell index from which to extract the ID */ +){ + assert( iCellzData[4 + pRtree->nBytesPerCell*iCell]); +} + +/* +** Return coordinate iCoord from cell iCell in node pNode. +*/ +static void nodeGetCoord( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract a coordinate */ + int iCell, /* The index of the cell within the node */ + int iCoord, /* Which coordinate to extract */ + RtreeCoord *pCoord /* OUT: Space to write result to */ +){ + assert( iCellzData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); +} + +/* +** Deserialize cell iCell of node pNode. Populate the structure pointed +** to by pCell with the results. +*/ +static void nodeGetCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node containing the cell to be read */ + int iCell, /* Index of the cell within the node */ + RtreeCell *pCell /* OUT: Write the cell contents here */ +){ + u8 *pData; + RtreeCoord *pCoord; + int ii = 0; + pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); + pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); + pCoord = pCell->aCoord; + do{ + readCoord(pData, &pCoord[ii]); + readCoord(pData+4, &pCoord[ii+1]); + pData += 8; + ii += 2; + }while( iinDim2 ); +} + + +/* Forward declaration for the function that does the work of +** the virtual table module xCreate() and xConnect() methods. +*/ +static int rtreeInit( + sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int +); + +/* +** Rtree virtual table module xCreate method. +*/ +static int rtreeCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** Rtree virtual table module xConnect method. +*/ +static int rtreeConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + +/* +** Increment the r-tree reference count. +*/ +static void rtreeReference(Rtree *pRtree){ + pRtree->nBusy++; +} + +/* +** Decrement the r-tree reference count. When the reference count reaches +** zero the structure is deleted. +*/ +static void rtreeRelease(Rtree *pRtree){ + pRtree->nBusy--; + if( pRtree->nBusy==0 ){ + pRtree->inWrTrans = 0; + assert( pRtree->nCursor==0 ); + nodeBlobReset(pRtree); + assert( pRtree->nNodeRef==0 || pRtree->bCorrupt ); + sqlite3_finalize(pRtree->pWriteNode); + sqlite3_finalize(pRtree->pDeleteNode); + sqlite3_finalize(pRtree->pReadRowid); + sqlite3_finalize(pRtree->pWriteRowid); + sqlite3_finalize(pRtree->pDeleteRowid); + sqlite3_finalize(pRtree->pReadParent); + sqlite3_finalize(pRtree->pWriteParent); + sqlite3_finalize(pRtree->pDeleteParent); + sqlite3_finalize(pRtree->pWriteAux); + sqlite3_free(pRtree->zReadAuxSql); + sqlite3_free(pRtree); + } +} + +/* +** Rtree virtual table module xDisconnect method. +*/ +static int rtreeDisconnect(sqlite3_vtab *pVtab){ + rtreeRelease((Rtree *)pVtab); + return SQLITE_OK; +} + +/* +** Rtree virtual table module xDestroy method. +*/ +static int rtreeDestroy(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + int rc; + char *zCreate = sqlite3_mprintf( + "DROP TABLE '%q'.'%q_node';" + "DROP TABLE '%q'.'%q_rowid';" + "DROP TABLE '%q'.'%q_parent';", + pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName + ); + if( !zCreate ){ + rc = SQLITE_NOMEM; + }else{ + nodeBlobReset(pRtree); + rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + } + if( rc==SQLITE_OK ){ + rtreeRelease(pRtree); + } + + return rc; +} + +/* +** Rtree virtual table module xOpen method. +*/ +static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + int rc = SQLITE_NOMEM; + Rtree *pRtree = (Rtree *)pVTab; + RtreeCursor *pCsr; + + pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor)); + if( pCsr ){ + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = pVTab; + rc = SQLITE_OK; + pRtree->nCursor++; + } + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + + return rc; +} + + +/* +** Reset a cursor back to its initial state. +*/ +static void resetCursor(RtreeCursor *pCsr){ + Rtree *pRtree = (Rtree *)(pCsr->base.pVtab); + int ii; + sqlite3_stmt *pStmt; + if( pCsr->aConstraint ){ + int i; /* Used to iterate through constraint array */ + for(i=0; inConstraint; i++){ + sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; + if( pInfo ){ + if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); + sqlite3_free(pInfo); + } + } + sqlite3_free(pCsr->aConstraint); + pCsr->aConstraint = 0; + } + for(ii=0; iiaNode[ii]); + sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; + +} + +/* +** Rtree virtual table module xClose method. +*/ +static int rtreeClose(sqlite3_vtab_cursor *cur){ + Rtree *pRtree = (Rtree *)(cur->pVtab); + RtreeCursor *pCsr = (RtreeCursor *)cur; + assert( pRtree->nCursor>0 ); + resetCursor(pCsr); + sqlite3_finalize(pCsr->pReadAux); + sqlite3_free(pCsr); + pRtree->nCursor--; + if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){ + nodeBlobReset(pRtree); + } + return SQLITE_OK; +} + +/* +** Rtree virtual table module xEof method. +** +** Return non-zero if the cursor does not currently point to a valid +** record (i.e if the scan has finished), or zero otherwise. +*/ +static int rtreeEof(sqlite3_vtab_cursor *cur){ + RtreeCursor *pCsr = (RtreeCursor *)cur; + return pCsr->atEOF; +} + +/* +** Convert raw bits from the on-disk RTree record into a coordinate value. +** The on-disk format is big-endian and needs to be converted for little- +** endian platforms. The on-disk record stores integer coordinates if +** eInt is true and it stores 32-bit floating point records if eInt is +** false. a[] is the four bytes of the on-disk record to be decoded. +** Store the results in "r". +** +** There are five versions of this macro. The last one is generic. The +** other four are various architectures-specific optimizations. +*/ +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = _byteswap_ulong(*(u32*)a); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = __builtin_bswap32(*(u32*)a); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==1234 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ + ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==4321 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#else +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ + +((u32)a[2]<<8) + a[3]; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#endif + +/* +** Check the RTree node or entry given by pCellData and p against the MATCH +** constraint pConstraint. +*/ +static int rtreeCallbackConstraint( + RtreeConstraint *pConstraint, /* The constraint to test */ + int eInt, /* True if RTree holding integer coordinates */ + u8 *pCellData, /* Raw cell content */ + RtreeSearchPoint *pSearch, /* Container of this cell */ + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ + int *peWithin /* OUT: visibility of the cell */ +){ + sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ + int nCoord = pInfo->nCoord; /* No. of coordinates */ + int rc; /* Callback return code */ + RtreeCoord c; /* Translator union */ + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ + + assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); + assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); + + if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ + pInfo->iRowid = readInt64(pCellData); + } + pCellData += 8; +#ifndef SQLITE_RTREE_INT_ONLY + if( eInt==0 ){ + switch( nCoord ){ + case 10: readCoord(pCellData+36, &c); aCoord[9] = c.f; + readCoord(pCellData+32, &c); aCoord[8] = c.f; + case 8: readCoord(pCellData+28, &c); aCoord[7] = c.f; + readCoord(pCellData+24, &c); aCoord[6] = c.f; + case 6: readCoord(pCellData+20, &c); aCoord[5] = c.f; + readCoord(pCellData+16, &c); aCoord[4] = c.f; + case 4: readCoord(pCellData+12, &c); aCoord[3] = c.f; + readCoord(pCellData+8, &c); aCoord[2] = c.f; + default: readCoord(pCellData+4, &c); aCoord[1] = c.f; + readCoord(pCellData, &c); aCoord[0] = c.f; + } + }else +#endif + { + switch( nCoord ){ + case 10: readCoord(pCellData+36, &c); aCoord[9] = c.i; + readCoord(pCellData+32, &c); aCoord[8] = c.i; + case 8: readCoord(pCellData+28, &c); aCoord[7] = c.i; + readCoord(pCellData+24, &c); aCoord[6] = c.i; + case 6: readCoord(pCellData+20, &c); aCoord[5] = c.i; + readCoord(pCellData+16, &c); aCoord[4] = c.i; + case 4: readCoord(pCellData+12, &c); aCoord[3] = c.i; + readCoord(pCellData+8, &c); aCoord[2] = c.i; + default: readCoord(pCellData+4, &c); aCoord[1] = c.i; + readCoord(pCellData, &c); aCoord[0] = c.i; + } + } + if( pConstraint->op==RTREE_MATCH ){ + int eWithin = 0; + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, + nCoord, aCoord, &eWithin); + if( eWithin==0 ) *peWithin = NOT_WITHIN; + *prScore = RTREE_ZERO; + }else{ + pInfo->aCoord = aCoord; + pInfo->iLevel = pSearch->iLevel - 1; + pInfo->rScore = pInfo->rParentScore = pSearch->rScore; + pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; + rc = pConstraint->u.xQueryFunc(pInfo); + if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; + if( pInfo->rScore<*prScore || *prScorerScore; + } + } + return rc; +} + +/* +** Check the internal RTree node given by pCellData against constraint p. +** If this constraint cannot be satisfied by any child within the node, +** set *peWithin to NOT_WITHIN. +*/ +static void rtreeNonleafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ + + /* p->iCoord might point to either a lower or upper bound coordinate + ** in a coordinate pair. But make pCellData point to the lower bound. + */ + pCellData += 8 + 4*(p->iCoord&0xfe); + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE + || p->op==RTREE_FALSE ); + assert( FOUR_BYTE_ALIGNED(pCellData) ); + switch( p->op ){ + case RTREE_TRUE: return; /* Always satisfied */ + case RTREE_FALSE: break; /* Never satisfied */ + case RTREE_EQ: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ){ + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; + } + break; + case RTREE_LE: + case RTREE_LT: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ) return; + break; + + default: + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; + break; + } + *peWithin = NOT_WITHIN; +} + +/* +** Check the leaf RTree cell given by pCellData against constraint p. +** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. +** If the constraint is satisfied, leave *peWithin unchanged. +** +** The constraint is of the form: xN op $val +** +** The op is given by p->op. The xN is p->iCoord-th coordinate in +** pCellData. $val is given by p->u.rValue. +*/ +static void rtreeLeafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + RtreeDValue xN; /* Coordinate value converted to a double */ + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE + || p->op==RTREE_FALSE ); + pCellData += 8 + p->iCoord*4; + assert( FOUR_BYTE_ALIGNED(pCellData) ); + RTREE_DECODE_COORD(eInt, pCellData, xN); + switch( p->op ){ + case RTREE_TRUE: return; /* Always satisfied */ + case RTREE_FALSE: break; /* Never satisfied */ + case RTREE_LE: if( xN <= p->u.rValue ) return; break; + case RTREE_LT: if( xN < p->u.rValue ) return; break; + case RTREE_GE: if( xN >= p->u.rValue ) return; break; + case RTREE_GT: if( xN > p->u.rValue ) return; break; + default: if( xN == p->u.rValue ) return; break; + } + *peWithin = NOT_WITHIN; +} + +/* +** One of the cells in node pNode is guaranteed to have a 64-bit +** integer value equal to iRowid. Return the index of this cell. +*/ +static int nodeRowidIndex( + Rtree *pRtree, + RtreeNode *pNode, + i64 iRowid, + int *piIndex +){ + int ii; + int nCell = NCELL(pNode); + assert( nCell<200 ); + for(ii=0; iipParent; + if( ALWAYS(pParent) ){ + return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); + }else{ + *piIndex = -1; + return SQLITE_OK; + } +} + +/* +** Compare two search points. Return negative, zero, or positive if the first +** is less than, equal to, or greater than the second. +** +** The rScore is the primary key. Smaller rScore values come first. +** If the rScore is a tie, then use iLevel as the tie breaker with smaller +** iLevel values coming first. In this way, if rScore is the same for all +** SearchPoints, then iLevel becomes the deciding factor and the result +** is a depth-first search, which is the desired default behavior. +*/ +static int rtreeSearchPointCompare( + const RtreeSearchPoint *pA, + const RtreeSearchPoint *pB +){ + if( pA->rScorerScore ) return -1; + if( pA->rScore>pB->rScore ) return +1; + if( pA->iLeveliLevel ) return -1; + if( pA->iLevel>pB->iLevel ) return +1; + return 0; +} + +/* +** Interchange two search points in a cursor. +*/ +static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ + RtreeSearchPoint t = p->aPoint[i]; + assert( iaPoint[i] = p->aPoint[j]; + p->aPoint[j] = t; + i++; j++; + if( i=RTREE_CACHE_SZ ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + }else{ + RtreeNode *pTemp = p->aNode[i]; + p->aNode[i] = p->aNode[j]; + p->aNode[j] = pTemp; + } + } +} + +/* +** Return the search point with the lowest current score. +*/ +static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ + return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; +} + +/* +** Get the RtreeNode for the search point with the lowest score. +*/ +static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ + sqlite3_int64 id; + int ii = 1 - pCur->bPoint; + assert( ii==0 || ii==1 ); + assert( pCur->bPoint || pCur->nPoint ); + if( pCur->aNode[ii]==0 ){ + assert( pRC!=0 ); + id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; + *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); + } + return pCur->aNode[ii]; +} + +/* +** Push a new element onto the priority queue +*/ +static RtreeSearchPoint *rtreeEnqueue( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + int i, j; + RtreeSearchPoint *pNew; + if( pCur->nPoint>=pCur->nPointAlloc ){ + int nNew = pCur->nPointAlloc*2 + 8; + pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); + if( pNew==0 ) return 0; + pCur->aPoint = pNew; + pCur->nPointAlloc = nNew; + } + i = pCur->nPoint++; + pNew = pCur->aPoint + i; + pNew->rScore = rScore; + pNew->iLevel = iLevel; + assert( iLevel<=RTREE_MAX_DEPTH ); + while( i>0 ){ + RtreeSearchPoint *pParent; + j = (i-1)/2; + pParent = pCur->aPoint + j; + if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; + rtreeSearchPointSwap(pCur, j, i); + i = j; + pNew = pParent; + } + return pNew; +} + +/* +** Allocate a new RtreeSearchPoint and return a pointer to it. Return +** NULL if malloc fails. +*/ +static RtreeSearchPoint *rtreeSearchPointNew( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + RtreeSearchPoint *pNew, *pFirst; + pFirst = rtreeSearchPointFirst(pCur); + pCur->anQueue[iLevel]++; + if( pFirst==0 + || pFirst->rScore>rScore + || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) + ){ + if( pCur->bPoint ){ + int ii; + pNew = rtreeEnqueue(pCur, rScore, iLevel); + if( pNew==0 ) return 0; + ii = (int)(pNew - pCur->aPoint) + 1; + assert( ii==1 ); + if( ALWAYS(iiaNode[ii]==0 ); + pCur->aNode[ii] = pCur->aNode[0]; + }else{ + nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); + } + pCur->aNode[0] = 0; + *pNew = pCur->sPoint; + } + pCur->sPoint.rScore = rScore; + pCur->sPoint.iLevel = iLevel; + pCur->bPoint = 1; + return &pCur->sPoint; + }else{ + return rtreeEnqueue(pCur, rScore, iLevel); + } +} + +#if 0 +/* Tracing routines for the RtreeSearchPoint queue */ +static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ + if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } + printf(" %d.%05lld.%02d %g %d", + p->iLevel, p->id, p->iCell, p->rScore, p->eWithin + ); + idx++; + if( idxaNode[idx]); + }else{ + printf("\n"); + } +} +static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ + int ii; + printf("=== %9s ", zPrefix); + if( pCur->bPoint ){ + tracePoint(&pCur->sPoint, -1, pCur); + } + for(ii=0; iinPoint; ii++){ + if( ii>0 || pCur->bPoint ) printf(" "); + tracePoint(&pCur->aPoint[ii], ii, pCur); + } +} +# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) +#else +# define RTREE_QUEUE_TRACE(A,B) /* no-op */ +#endif + +/* Remove the search point with the lowest current score. +*/ +static void rtreeSearchPointPop(RtreeCursor *p){ + int i, j, k, n; + i = 1 - p->bPoint; + assert( i==0 || i==1 ); + if( p->aNode[i] ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + } + if( p->bPoint ){ + p->anQueue[p->sPoint.iLevel]--; + p->bPoint = 0; + }else if( ALWAYS(p->nPoint) ){ + p->anQueue[p->aPoint[0].iLevel]--; + n = --p->nPoint; + p->aPoint[0] = p->aPoint[n]; + if( naNode[1] = p->aNode[n+1]; + p->aNode[n+1] = 0; + } + i = 0; + while( (j = i*2+1)aPoint[k], &p->aPoint[j])<0 ){ + if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, k); + i = k; + }else{ + break; + } + }else{ + if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, j); + i = j; + }else{ + break; + } + } + } + } +} + + +/* +** Continue the search on cursor pCur until the front of the queue +** contains an entry suitable for returning as a result-set row, +** or until the RtreeSearchPoint queue is empty, indicating that the +** query has completed. +*/ +static int rtreeStepToLeaf(RtreeCursor *pCur){ + RtreeSearchPoint *p; + Rtree *pRtree = RTREE_OF_CURSOR(pCur); + RtreeNode *pNode; + int eWithin; + int rc = SQLITE_OK; + int nCell; + int nConstraint = pCur->nConstraint; + int ii; + int eInt; + RtreeSearchPoint x; + + eInt = pRtree->eCoordType==RTREE_COORD_INT32; + while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ + u8 *pCellData; + pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); + if( rc ) return rc; + nCell = NCELL(pNode); + assert( nCell<200 ); + pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); + while( p->iCellaConstraint + ii; + if( pConstraint->op>=RTREE_MATCH ){ + rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, + &rScore, &eWithin); + if( rc ) return rc; + }else if( p->iLevel==1 ){ + rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); + }else{ + rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); + } + if( eWithin==NOT_WITHIN ){ + p->iCell++; + pCellData += pRtree->nBytesPerCell; + break; + } + } + if( eWithin==NOT_WITHIN ) continue; + p->iCell++; + x.iLevel = p->iLevel - 1; + if( x.iLevel ){ + x.id = readInt64(pCellData); + for(ii=0; iinPoint; ii++){ + if( pCur->aPoint[ii].id==x.id ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + } + x.iCell = 0; + }else{ + x.id = p->id; + x.iCell = p->iCell - 1; + } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-S:"); + rtreeSearchPointPop(pCur); + } + if( rScoreeWithin = (u8)eWithin; + p->id = x.id; + p->iCell = x.iCell; + RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); + break; + } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-Se:"); + rtreeSearchPointPop(pCur); + } + } + pCur->atEOF = p==0; + return SQLITE_OK; +} + +/* +** Rtree virtual table module xNext method. +*/ +static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + int rc = SQLITE_OK; + + /* Move to the next entry that matches the configured constraints. */ + RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); + if( pCsr->bAuxValid ){ + pCsr->bAuxValid = 0; + sqlite3_reset(pCsr->pReadAux); + } + rtreeSearchPointPop(pCsr); + rc = rtreeStepToLeaf(pCsr); + return rc; +} + +/* +** Rtree virtual table module xRowid method. +*/ +static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + if( rc==SQLITE_OK && ALWAYS(p) ){ + if( p->iCell>=NCELL(pNode) ){ + rc = SQLITE_ABORT; + }else{ + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + } + } + return rc; +} + +/* +** Rtree virtual table module xColumn method. +*/ +static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + RtreeCoord c; + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( NEVER(p==0) ) return SQLITE_OK; + if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT; + if( i==0 ){ + sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); + }else if( i<=pRtree->nDim2 ){ + nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + sqlite3_result_double(ctx, c.f); + }else +#endif + { + assert( pRtree->eCoordType==RTREE_COORD_INT32 ); + sqlite3_result_int(ctx, c.i); + } + }else{ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, + sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1)); + } + return SQLITE_OK; +} + +/* +** Use nodeAcquire() to obtain the leaf node containing the record with +** rowid iRowid. If successful, set *ppLeaf to point to the node and +** return SQLITE_OK. If there is no such record in the table, set +** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf +** to zero and return an SQLite error code. +*/ +static int findLeafNode( + Rtree *pRtree, /* RTree to search */ + i64 iRowid, /* The rowid searching for */ + RtreeNode **ppLeaf, /* Write the node here */ + sqlite3_int64 *piNode /* Write the node-id here */ +){ + int rc; + *ppLeaf = 0; + sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); + if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ + i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); + if( piNode ) *piNode = iNode; + rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); + sqlite3_reset(pRtree->pReadRowid); + }else{ + rc = sqlite3_reset(pRtree->pReadRowid); + } + return rc; +} + +/* +** This function is called to configure the RtreeConstraint object passed +** as the second argument for a MATCH constraint. The value passed as the +** first argument to this function is the right-hand operand to the MATCH +** operator. +*/ +static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ + RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */ + sqlite3_rtree_query_info *pInfo; /* Callback information */ + + pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg"); + if( pSrc==0 ) return SQLITE_ERROR; + pInfo = (sqlite3_rtree_query_info*) + sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize ); + if( !pInfo ) return SQLITE_NOMEM; + memset(pInfo, 0, sizeof(*pInfo)); + pBlob = (RtreeMatchArg*)&pInfo[1]; + memcpy(pBlob, pSrc, pSrc->iSize); + pInfo->pContext = pBlob->cb.pContext; + pInfo->nParam = pBlob->nParam; + pInfo->aParam = pBlob->aParam; + pInfo->apSqlParam = pBlob->apSqlParam; + + if( pBlob->cb.xGeom ){ + pCons->u.xGeom = pBlob->cb.xGeom; + }else{ + pCons->op = RTREE_QUERY; + pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; + } + pCons->pInfo = pInfo; + return SQLITE_OK; +} + +/* +** Rtree virtual table module xFilter method. +*/ +static int rtreeFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int ii; + int rc = SQLITE_OK; + int iCell = 0; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + resetCursor(pCsr); + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + int eType = sqlite3_value_numeric_type(argv[0]); + if( eType==SQLITE_INTEGER + || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid) + ){ + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + }else{ + rc = SQLITE_OK; + pLeaf = 0; + } + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = (u8)iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && argc>0 ){ + pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc); + pCsr->nConstraint = argc; + if( !pCsr->aConstraint ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + assert( (idxStr==0 && argc==0) + || (idxStr && (int)strlen(idxStr)==argc*2) ); + for(ii=0; iiaConstraint[ii]; + int eType = sqlite3_value_numeric_type(argv[ii]); + p->op = idxStr[ii*2]; + p->iCoord = idxStr[ii*2+1]-'0'; + if( p->op>=RTREE_MATCH ){ + /* A MATCH operator. The right-hand-side must be a blob that + ** can be cast into an RtreeMatchArg object. One created using + ** an sqlite3_rtree_geometry_callback() SQL user function. + */ + rc = deserializeGeometry(argv[ii], p); + if( rc!=SQLITE_OK ){ + break; + } + p->pInfo->nCoord = pRtree->nDim2; + p->pInfo->anQueue = pCsr->anQueue; + p->pInfo->mxLevel = pRtree->iDepth + 1; + }else if( eType==SQLITE_INTEGER ){ + sqlite3_int64 iVal = sqlite3_value_int64(argv[ii]); +#ifdef SQLITE_RTREE_INT_ONLY + p->u.rValue = iVal; +#else + p->u.rValue = (double)iVal; + if( iVal>=((sqlite3_int64)1)<<48 + || iVal<=-(((sqlite3_int64)1)<<48) + ){ + if( p->op==RTREE_LT ) p->op = RTREE_LE; + if( p->op==RTREE_GT ) p->op = RTREE_GE; + } +#endif + }else if( eType==SQLITE_FLOAT ){ +#ifdef SQLITE_RTREE_INT_ONLY + p->u.rValue = sqlite3_value_int64(argv[ii]); +#else + p->u.rValue = sqlite3_value_double(argv[ii]); +#endif + }else{ + p->u.rValue = RTREE_ZERO; + if( eType==SQLITE_NULL ){ + p->op = RTREE_FALSE; + }else if( p->op==RTREE_LT || p->op==RTREE_LE ){ + p->op = RTREE_TRUE; + }else{ + p->op = RTREE_FALSE; + } + } + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + assert( pCsr->bPoint==0 ); /* Due to the resetCursor() call above */ + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); + if( NEVER(pNew==0) ){ /* Because pCsr->bPoint was FALSE */ + return SQLITE_NOMEM; + } + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 Unused Direct lookup by rowid. +** 2 See below R-tree query or full-table scan. +** ------------------------------------------------ +** +** If strategy 1 is used, then idxStr is not meaningful. If strategy +** 2 is used, idxStr is formatted to contain 2 bytes for each +** constraint used. The first two bytes of idxStr correspond to +** the constraint in sqlite3_index_info.aConstraintUsage[] with +** (argvIndex==1) etc. +** +** The first of each pair of bytes in idxStr identifies the constraint +** operator as follows: +** +** Operator Byte Value +** ---------------------- +** = 0x41 ('A') +** <= 0x42 ('B') +** < 0x43 ('C') +** >= 0x44 ('D') +** > 0x45 ('E') +** MATCH 0x46 ('F') +** ---------------------- +** +** The second of each pair of bytes identifies the coordinate column +** to which the constraint applies. The leftmost coordinate column +** is 'a', the second from the left 'b' etc. +*/ +static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + Rtree *pRtree = (Rtree*)tab; + int rc = SQLITE_OK; + int ii; + int bMatch = 0; /* True if there exists a MATCH constraint */ + i64 nRow; /* Estimated rows returned by this scan */ + + int iIdx = 0; + char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; + memset(zIdxStr, 0, sizeof(zIdxStr)); + + /* Check if there exists a MATCH constraint - even an unusable one. If there + ** is, do not consider the lookup-by-rowid plan as using such a plan would + ** require the VDBE to evaluate the MATCH constraint, which is not currently + ** possible. */ + for(ii=0; iinConstraint; ii++){ + if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + bMatch = 1; + } + } + + assert( pIdxInfo->idxStr==0 ); + for(ii=0; iinConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + + if( bMatch==0 && p->usable + && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + /* We have an equality constraint on the rowid. Use strategy 1. */ + int jj; + for(jj=0; jjaConstraintUsage[jj].argvIndex = 0; + pIdxInfo->aConstraintUsage[jj].omit = 0; + } + pIdxInfo->idxNum = 1; + pIdxInfo->aConstraintUsage[ii].argvIndex = 1; + pIdxInfo->aConstraintUsage[jj].omit = 1; + + /* This strategy involves a two rowid lookups on an B-Tree structures + ** and then a linear search of an R-Tree node. This should be + ** considered almost as quick as a direct rowid lookup (for which + ** sqlite uses an internal cost of 0.0). It is expected to return + ** a single row. + */ + pIdxInfo->estimatedCost = 30.0; + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + return SQLITE_OK; + } + + if( p->usable + && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2) + || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) + ){ + u8 op; + u8 doOmit = 1; + switch( p->op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; + case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; + case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; + default: op = 0; break; + } + if( op ){ + zIdxStr[iIdx++] = op; + zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); + pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); + pIdxInfo->aConstraintUsage[ii].omit = doOmit; + } + } + } + + pIdxInfo->idxNum = 2; + pIdxInfo->needToFreeIdxStr = 1; + if( iIdx>0 ){ + pIdxInfo->idxStr = sqlite3_malloc( iIdx+1 ); + if( pIdxInfo->idxStr==0 ){ + return SQLITE_NOMEM; + } + memcpy(pIdxInfo->idxStr, zIdxStr, iIdx+1); + } + + nRow = pRtree->nRowEst >> (iIdx/2); + pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; + pIdxInfo->estimatedRows = nRow; + + return rc; +} + +/* +** Return the N-dimensional volumn of the cell stored in *p. +*/ +static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ + RtreeDValue area = (RtreeDValue)1; + assert( pRtree->nDim>=1 && pRtree->nDim<=5 ); +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + switch( pRtree->nDim ){ + case 5: area = p->aCoord[9].f - p->aCoord[8].f; + case 4: area *= p->aCoord[7].f - p->aCoord[6].f; + case 3: area *= p->aCoord[5].f - p->aCoord[4].f; + case 2: area *= p->aCoord[3].f - p->aCoord[2].f; + default: area *= p->aCoord[1].f - p->aCoord[0].f; + } + }else +#endif + { + switch( pRtree->nDim ){ + case 5: area = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i; + case 4: area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i; + case 3: area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i; + case 2: area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i; + default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i; + } + } + return area; +} + +/* +** Return the margin length of cell p. The margin length is the sum +** of the objects size in each dimension. +*/ +static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ + RtreeDValue margin = 0; + int ii = pRtree->nDim2 - 2; + do{ + margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); + ii -= 2; + }while( ii>=0 ); + return margin; +} + +/* +** Store the union of cells p1 and p2 in p1. +*/ +static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ + int ii = 0; + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + do{ + p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f); + p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f); + ii += 2; + }while( iinDim2 ); + }else{ + do{ + p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i); + p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i); + ii += 2; + }while( iinDim2 ); + } +} + +/* +** Return true if the area covered by p2 is a subset of the area covered +** by p1. False otherwise. +*/ +static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ + int ii; + if( pRtree->eCoordType==RTREE_COORD_INT32 ){ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].ia1[1].i ) return 0; + } + }else{ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].fa1[1].f ) return 0; + } + } + return 1; +} + +static RtreeDValue cellOverlap( + Rtree *pRtree, + RtreeCell *p, + RtreeCell *aCell, + int nCell +){ + int ii; + RtreeDValue overlap = RTREE_ZERO; + for(ii=0; iinDim2; jj+=2){ + RtreeDValue x1, x2; + x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); + x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); + if( x2iDepth-iHeight); ii++){ + int iCell; + sqlite3_int64 iBest = 0; + int bFound = 0; + RtreeDValue fMinGrowth = RTREE_ZERO; + RtreeDValue fMinArea = RTREE_ZERO; + int nCell = NCELL(pNode); + RtreeNode *pChild = 0; + + /* First check to see if there is are any cells in pNode that completely + ** contains pCell. If two or more cells in pNode completely contain pCell + ** then pick the smallest. + */ + for(iCell=0; iCellpParent ){ + RtreeNode *pParent = p->pParent; + RtreeCell cell; + int iCell; + + cnt++; + if( NEVER(cnt>100) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + rc = nodeParentIndex(pRtree, p, &iCell); + if( NEVER(rc!=SQLITE_OK) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + + nodeGetCell(pRtree, pParent, iCell, &cell); + if( !cellContains(pRtree, &cell, pCell) ){ + cellUnion(pRtree, &cell, pCell); + nodeOverwriteCell(pRtree, pParent, &cell, iCell); + } + + p = pParent; + } + return SQLITE_OK; +} + +/* +** Write mapping (iRowid->iNode) to the _rowid table. +*/ +static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ + sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); + sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); + sqlite3_step(pRtree->pWriteRowid); + return sqlite3_reset(pRtree->pWriteRowid); +} + +/* +** Write mapping (iNode->iPar) to the _parent table. +*/ +static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){ + sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); + sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); + sqlite3_step(pRtree->pWriteParent); + return sqlite3_reset(pRtree->pWriteParent); +} + +static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); + + + +/* +** Arguments aIdx, aCell and aSpare all point to arrays of size +** nIdx. The aIdx array contains the set of integers from 0 to +** (nIdx-1) in no particular order. This function sorts the values +** in aIdx according to dimension iDim of the cells in aCell. The +** minimum value of dimension iDim is considered first, the +** maximum used to break ties. +** +** The aSpare array is used as temporary working space by the +** sorting algorithm. +*/ +static void SortByDimension( + Rtree *pRtree, + int *aIdx, + int nIdx, + int iDim, + RtreeCell *aCell, + int *aSpare +){ + if( nIdx>1 ){ + + int iLeft = 0; + int iRight = 0; + + int nLeft = nIdx/2; + int nRight = nIdx-nLeft; + int *aLeft = aIdx; + int *aRight = &aIdx[nLeft]; + + SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); + SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); + + memcpy(aSpare, aLeft, sizeof(int)*nLeft); + aLeft = aSpare; + while( iLeftnDim+1)*(sizeof(int*)+nCell*sizeof(int)); + + aaSorted = (int **)sqlite3_malloc64(nByte); + if( !aaSorted ){ + return SQLITE_NOMEM; + } + + aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell]; + memset(aaSorted, 0, nByte); + for(ii=0; iinDim; ii++){ + int jj; + aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell]; + for(jj=0; jjnDim; ii++){ + RtreeDValue margin = RTREE_ZERO; + RtreeDValue fBestOverlap = RTREE_ZERO; + RtreeDValue fBestArea = RTREE_ZERO; + int iBestLeft = 0; + int nLeft; + + for( + nLeft=RTREE_MINCELLS(pRtree); + nLeft<=(nCell-RTREE_MINCELLS(pRtree)); + nLeft++ + ){ + RtreeCell left; + RtreeCell right; + int kk; + RtreeDValue overlap; + RtreeDValue area; + + memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); + memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); + for(kk=1; kk<(nCell-1); kk++){ + if( kk0 ){ + RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); + RtreeNode *p; + for(p=pNode; p; p=p->pParent){ + if( p==pChild ) return SQLITE_CORRUPT_VTAB; + } + if( pChild ){ + nodeRelease(pRtree, pChild->pParent); + nodeReference(pNode); + pChild->pParent = pNode; + } + } + if( NEVER(pNode==0) ) return SQLITE_ERROR; + return xSetMapping(pRtree, iRowid, pNode->iNode); +} + +static int SplitNode( + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell, + int iHeight +){ + int i; + int newCellIsRight = 0; + + int rc = SQLITE_OK; + int nCell = NCELL(pNode); + RtreeCell *aCell; + int *aiUsed; + + RtreeNode *pLeft = 0; + RtreeNode *pRight = 0; + + RtreeCell leftbbox; + RtreeCell rightbbox; + + /* Allocate an array and populate it with a copy of pCell and + ** all cells from node pLeft. Then zero the original node. + */ + aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); + if( !aCell ){ + rc = SQLITE_NOMEM; + goto splitnode_out; + } + aiUsed = (int *)&aCell[nCell+1]; + memset(aiUsed, 0, sizeof(int)*(nCell+1)); + for(i=0; iiNode==1 ){ + pRight = nodeNew(pRtree, pNode); + pLeft = nodeNew(pRtree, pNode); + pRtree->iDepth++; + pNode->isDirty = 1; + writeInt16(pNode->zData, pRtree->iDepth); + }else{ + pLeft = pNode; + pRight = nodeNew(pRtree, pLeft->pParent); + pLeft->nRef++; + } + + if( !pLeft || !pRight ){ + rc = SQLITE_NOMEM; + goto splitnode_out; + } + + memset(pLeft->zData, 0, pRtree->iNodeSize); + memset(pRight->zData, 0, pRtree->iNodeSize); + + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, + &leftbbox, &rightbbox); + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + + /* Ensure both child nodes have node numbers assigned to them by calling + ** nodeWrite(). Node pRight always needs a node number, as it was created + ** by nodeNew() above. But node pLeft sometimes already has a node number. + ** In this case avoid the all to nodeWrite(). + */ + if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) + || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) + ){ + goto splitnode_out; + } + + rightbbox.iRowid = pRight->iNode; + leftbbox.iRowid = pLeft->iNode; + + if( pNode->iNode==1 ){ + rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + }else{ + RtreeNode *pParent = pLeft->pParent; + int iCell; + rc = nodeParentIndex(pRtree, pLeft, &iCell); + if( ALWAYS(rc==SQLITE_OK) ){ + nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); + rc = AdjustTree(pRtree, pParent, &leftbbox); + assert( rc==SQLITE_OK ); + } + if( NEVER(rc!=SQLITE_OK) ){ + goto splitnode_out; + } + } + if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ + goto splitnode_out; + } + + for(i=0; iiRowid ){ + newCellIsRight = 1; + } + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + } + if( pNode->iNode==1 ){ + for(i=0; iiRowid, pLeft, iHeight); + } + + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pRight); + pRight = 0; + } + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pLeft); + pLeft = 0; + } + +splitnode_out: + nodeRelease(pRtree, pRight); + nodeRelease(pRtree, pLeft); + sqlite3_free(aCell); + return rc; +} + +/* +** If node pLeaf is not the root of the r-tree and its pParent pointer is +** still NULL, load all ancestor nodes of pLeaf into memory and populate +** the pLeaf->pParent chain all the way up to the root node. +** +** This operation is required when a row is deleted (or updated - an update +** is implemented as a delete followed by an insert). SQLite provides the +** rowid of the row to delete, which can be used to find the leaf on which +** the entry resides (argument pLeaf). Once the leaf is located, this +** function is called to determine its ancestry. +*/ +static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ + int rc = SQLITE_OK; + RtreeNode *pChild = pLeaf; + while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ + int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); + rc = sqlite3_step(pRtree->pReadParent); + if( rc==SQLITE_ROW ){ + RtreeNode *pTest; /* Used to test for reference loops */ + i64 iNode; /* Node number of parent node */ + + /* Before setting pChild->pParent, test that we are not creating a + ** loop of references (as we would if, say, pChild==pParent). We don't + ** want to do this as it leads to a memory leak when trying to delete + ** the referenced counted node structures. + */ + iNode = sqlite3_column_int64(pRtree->pReadParent, 0); + for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); + if( pTest==0 ){ + rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); + } + } + rc = sqlite3_reset(pRtree->pReadParent); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && !pChild->pParent ){ + RTREE_IS_CORRUPT(pRtree); + rc = SQLITE_CORRUPT_VTAB; + } + pChild = pChild->pParent; + } + return rc; +} + +static int deleteCell(Rtree *, RtreeNode *, int, int); + +static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ + int rc; + int rc2; + RtreeNode *pParent = 0; + int iCell; + + assert( pNode->nRef==1 ); + + /* Remove the entry in the parent cell. */ + rc = nodeParentIndex(pRtree, pNode, &iCell); + if( rc==SQLITE_OK ){ + pParent = pNode->pParent; + pNode->pParent = 0; + rc = deleteCell(pRtree, pParent, iCell, iHeight+1); + testcase( rc!=SQLITE_OK ); + } + rc2 = nodeRelease(pRtree, pParent); + if( rc==SQLITE_OK ){ + rc = rc2; + } + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Remove the xxx_node entry. */ + sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteNode); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ + return rc; + } + + /* Remove the xxx_parent entry. */ + sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteParent); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ + return rc; + } + + /* Remove the node from the in-memory hash table and link it into + ** the Rtree.pDeleted list. Its contents will be re-inserted later on. + */ + nodeHashDelete(pRtree, pNode); + pNode->iNode = iHeight; + pNode->pNext = pRtree->pDeleted; + pNode->nRef++; + pRtree->pDeleted = pNode; + + return SQLITE_OK; +} + +static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ + RtreeNode *pParent = pNode->pParent; + int rc = SQLITE_OK; + if( pParent ){ + int ii; + int nCell = NCELL(pNode); + RtreeCell box; /* Bounding box for pNode */ + nodeGetCell(pRtree, pNode, 0, &box); + for(ii=1; iiiNode; + rc = nodeParentIndex(pRtree, pNode, &ii); + if( rc==SQLITE_OK ){ + nodeOverwriteCell(pRtree, pParent, &box, ii); + rc = fixBoundingBox(pRtree, pParent); + } + } + return rc; +} + +/* +** Delete the cell at index iCell of node pNode. After removing the +** cell, adjust the r-tree data structure if required. +*/ +static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ + RtreeNode *pParent; + int rc; + + if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ + return rc; + } + + /* Remove the cell from the node. This call just moves bytes around + ** the in-memory node image, so it cannot fail. + */ + nodeDeleteCell(pRtree, pNode, iCell); + + /* If the node is not the tree root and now has less than the minimum + ** number of cells, remove it from the tree. Otherwise, update the + ** cell in the parent node so that it tightly contains the updated + ** node. + */ + pParent = pNode->pParent; + assert( pParent || pNode->iNode==1 ); + if( pParent ){ + if( NCELL(pNode)0 ){ + RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid); + if( pChild ){ + nodeRelease(pRtree, pChild->pParent); + nodeReference(pNode); + pChild->pParent = pNode; + } + } + if( nodeInsertCell(pRtree, pNode, pCell) ){ + rc = SplitNode(pRtree, pNode, pCell, iHeight); + }else{ + rc = AdjustTree(pRtree, pNode, pCell); + if( ALWAYS(rc==SQLITE_OK) ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); + }else{ + rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); + } + } + } + return rc; +} + +static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ + int ii; + int rc = SQLITE_OK; + int nCell = NCELL(pNode); + + for(ii=0; rc==SQLITE_OK && iiiNode currently contains + ** the height of the sub-tree headed by the cell. + */ + rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); + rc2 = nodeRelease(pRtree, pInsert); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + return rc; +} + +/* +** Select a currently unused rowid for a new r-tree record. +*/ +static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){ + int rc; + sqlite3_bind_null(pRtree->pWriteRowid, 1); + sqlite3_bind_null(pRtree->pWriteRowid, 2); + sqlite3_step(pRtree->pWriteRowid); + rc = sqlite3_reset(pRtree->pWriteRowid); + *piRowid = sqlite3_last_insert_rowid(pRtree->db); + return rc; +} + +/* +** Remove the entry with rowid=iDelete from the r-tree structure. +*/ +static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ + int rc; /* Return code */ + RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ + int iCell; /* Index of iDelete cell in pLeaf */ + RtreeNode *pRoot = 0; /* Root node of rtree structure */ + + + /* Obtain a reference to the root node to initialize Rtree.iDepth */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + + /* Obtain a reference to the leaf node that contains the entry + ** about to be deleted. + */ + if( rc==SQLITE_OK ){ + rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); + } + +#ifdef CORRUPT_DB + assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB ); +#endif + + /* Delete the cell in question from the leaf node. */ + if( rc==SQLITE_OK && pLeaf ){ + int rc2; + rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); + if( rc==SQLITE_OK ){ + rc = deleteCell(pRtree, pLeaf, iCell, 0); + } + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + + /* Delete the corresponding entry in the _rowid table. */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); + sqlite3_step(pRtree->pDeleteRowid); + rc = sqlite3_reset(pRtree->pDeleteRowid); + } + + /* Check if the root node now has exactly one child. If so, remove + ** it, schedule the contents of the child for reinsertion and + ** reduce the tree height by one. + ** + ** This is equivalent to copying the contents of the child into + ** the root node (the operation that Gutman's paper says to perform + ** in this scenario). + */ + if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ + int rc2; + RtreeNode *pChild = 0; + i64 iChild = nodeGetRowid(pRtree, pRoot, 0); + rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); /* tag-20210916a */ + if( rc==SQLITE_OK ){ + rc = removeNode(pRtree, pChild, pRtree->iDepth-1); + } + rc2 = nodeRelease(pRtree, pChild); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK ){ + pRtree->iDepth--; + writeInt16(pRoot->zData, pRtree->iDepth); + pRoot->isDirty = 1; + } + } + + /* Re-insert the contents of any underfull nodes removed from the tree. */ + for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ + if( rc==SQLITE_OK ){ + rc = reinsertNodeContent(pRtree, pLeaf); + } + pRtree->pDeleted = pLeaf->pNext; + pRtree->nNodeRef--; + sqlite3_free(pLeaf); + } + + /* Release the reference to the root node. */ + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pRoot); + }else{ + nodeRelease(pRtree, pRoot); + } + + return rc; +} + +/* +** Rounding constants for float->double conversion. +*/ +#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ +#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ + +#if !defined(SQLITE_RTREE_INT_ONLY) +/* +** Convert an sqlite3_value into an RtreeValue (presumably a float) +** while taking care to round toward negative or positive, respectively. +*/ +static RtreeValue rtreeValueDown(sqlite3_value *v){ + double d = sqlite3_value_double(v); + float f = (float)d; + if( f>d ){ + f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); + } + return f; +} +static RtreeValue rtreeValueUp(sqlite3_value *v){ + double d = sqlite3_value_double(v); + float f = (float)d; + if( fbase.zErrMsg) to an appropriate value and returns +** SQLITE_CONSTRAINT. +** +** Parameter iCol is the index of the leftmost column involved in the +** constraint failure. If it is 0, then the constraint that failed is +** the unique constraint on the id column. Otherwise, it is the rtree +** (c1<=c2) constraint on columns iCol and iCol+1 that has failed. +** +** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT. +*/ +static int rtreeConstraintError(Rtree *pRtree, int iCol){ + sqlite3_stmt *pStmt = 0; + char *zSql; + int rc; + + assert( iCol==0 || iCol%2 ); + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName); + if( zSql ){ + rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3_free(zSql); + + if( rc==SQLITE_OK ){ + if( iCol==0 ){ + const char *zCol = sqlite3_column_name(pStmt, 0); + pRtree->base.zErrMsg = sqlite3_mprintf( + "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol + ); + }else{ + const char *zCol1 = sqlite3_column_name(pStmt, iCol); + const char *zCol2 = sqlite3_column_name(pStmt, iCol+1); + pRtree->base.zErrMsg = sqlite3_mprintf( + "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2 + ); + } + } + + sqlite3_finalize(pStmt); + return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc); +} + + + +/* +** The xUpdate method for rtree module virtual tables. +*/ +static int rtreeUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **aData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ + + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } + rtreeReference(pRtree); + assert(nData>=1); + + memset(&cell, 0, sizeof(cell)); + + /* Constraint handling. A write operation on an r-tree table may return + ** SQLITE_CONSTRAINT for two reasons: + ** + ** 1. A duplicate rowid value, or + ** 2. The supplied data violates the "x2>=x1" constraint. + ** + ** In the first case, if the conflict-handling mode is REPLACE, then + ** the conflicting row can be removed before proceeding. In the second + ** case, SQLITE_CONSTRAINT must be returned regardless of the + ** conflict-handling mode specified by the user. + */ + if( nData>1 ){ + int ii; + int nn = nData - 4; + + if( nn > pRtree->nDim2 ) nn = pRtree->nDim2; + /* Populate the cell.aCoord[] array. The first coordinate is aData[3]. + ** + ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared + ** with "column" that are interpreted as table constraints. + ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5)); + ** This problem was discovered after years of use, so we silently ignore + ** these kinds of misdeclared tables to avoid breaking any legacy. + */ + +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + for(ii=0; iicell.aCoord[ii+1].f ){ + rc = rtreeConstraintError(pRtree, ii+1); + goto constraint; + } + } + }else +#endif + { + for(ii=0; iicell.aCoord[ii+1].i ){ + rc = rtreeConstraintError(pRtree, ii+1); + goto constraint; + } + } + } + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){ + cell.iRowid = sqlite3_value_int64(aData[2]); + if( sqlite3_value_type(aData[0])==SQLITE_NULL + || sqlite3_value_int64(aData[0])!=cell.iRowid + ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = rtreeConstraintError(pRtree, 0); + goto constraint; + } + } + } + bHaveRowid = 1; + } + } + + /* If aData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){ + rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0])); + } + + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + + /* Figure out the rowid of the new row. */ + if( bHaveRowid==0 ){ + rc = rtreeNewRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + if( rc==SQLITE_OK && pRtree->nAux ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + sqlite3_bind_int64(pUp, 1, *pRowid); + for(jj=0; jjnAux; jj++){ + sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]); + } + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); + } + } + +constraint: + rtreeRelease(pRtree); + return rc; +} + +/* +** Called when a transaction starts. +*/ +static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + pRtree->inWrTrans = 1; + return SQLITE_OK; +} + +/* +** Called when a transaction completes (either by COMMIT or ROLLBACK). +** The sqlite3_blob object should be released at this point. +*/ +static int rtreeEndTransaction(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + pRtree->inWrTrans = 0; + nodeBlobReset(pRtree); + return SQLITE_OK; +} +static int rtreeRollback(sqlite3_vtab *pVtab){ + return rtreeEndTransaction(pVtab); +} + +/* +** The xRename method for rtree module virtual tables. +*/ +static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_NOMEM; + char *zSql = sqlite3_mprintf( + "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";" + "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" + "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";" + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + ); + if( zSql ){ + nodeBlobReset(pRtree); + rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } + return rc; +} + +/* +** The xSavepoint method. +** +** This module does not need to do anything to support savepoints. However, +** it uses this hook to close any open blob handle. This is done because a +** DROP TABLE command - which fortunately always opens a savepoint - cannot +** succeed if there are any open blob handles. i.e. if the blob handle were +** not closed here, the following would fail: +** +** BEGIN; +** INSERT INTO rtree... +** DROP TABLE ; -- Would fail with SQLITE_LOCKED +** COMMIT; +*/ +static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ + Rtree *pRtree = (Rtree *)pVtab; + u8 iwt = pRtree->inWrTrans; + UNUSED_PARAMETER(iSavepoint); + pRtree->inWrTrans = 0; + nodeBlobReset(pRtree); + pRtree->inWrTrans = iwt; + return SQLITE_OK; +} + +/* +** This function populates the pRtree->nRowEst variable with an estimate +** of the number of rows in the virtual table. If possible, this is based +** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. +*/ +static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ + const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'"; + char *zSql; + sqlite3_stmt *p; + int rc; + i64 nRow = RTREE_MIN_ROWEST; + + rc = sqlite3_table_column_metadata( + db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0 + ); + if( rc!=SQLITE_OK ){ + pRtree->nRowEst = RTREE_DEFAULT_ROWEST; + return rc==SQLITE_ERROR ? SQLITE_OK : rc; + } + zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); + if( rc==SQLITE_OK ){ + if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); + rc = sqlite3_finalize(p); + } + sqlite3_free(zSql); + } + pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); + return rc; +} + + +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int rtreeShadowName(const char *zName){ + static const char *azName[] = { + "node", "parent", "rowid" + }; + unsigned int i; + for(i=0; idb = db; + + if( isCreate ){ + char *zCreate; + sqlite3_str *p = sqlite3_str_new(db); + int ii; + sqlite3_str_appendf(p, + "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno", + zDb, zPrefix); + for(ii=0; iinAux; ii++){ + sqlite3_str_appendf(p,",a%d",ii); + } + sqlite3_str_appendf(p, + ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);", + zDb, zPrefix); + sqlite3_str_appendf(p, + "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);", + zDb, zPrefix); + sqlite3_str_appendf(p, + "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))", + zDb, zPrefix, pRtree->iNodeSize); + zCreate = sqlite3_str_finish(p); + if( !zCreate ){ + return SQLITE_NOMEM; + } + rc = sqlite3_exec(db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + if( rc!=SQLITE_OK ){ + return rc; + } + } + + appStmt[0] = &pRtree->pWriteNode; + appStmt[1] = &pRtree->pDeleteNode; + appStmt[2] = &pRtree->pReadRowid; + appStmt[3] = &pRtree->pWriteRowid; + appStmt[4] = &pRtree->pDeleteRowid; + appStmt[5] = &pRtree->pReadParent; + appStmt[6] = &pRtree->pWriteParent; + appStmt[7] = &pRtree->pDeleteParent; + + rc = rtreeQueryStat1(db, pRtree); + for(i=0; inAux==0 ){ + zFormat = azSql[i]; + }else { + /* An UPSERT is very slightly slower than REPLACE, but it is needed + ** if there are auxiliary columns */ + zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)" + "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno"; + } + zSql = sqlite3_mprintf(zFormat, zDb, zPrefix); + if( zSql ){ + rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3_free(zSql); + } + if( pRtree->nAux && rc!=SQLITE_NOMEM ){ + pRtree->zReadAuxSql = sqlite3_mprintf( + "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", + zDb, zPrefix); + if( pRtree->zReadAuxSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_str *p = sqlite3_str_new(db); + int ii; + char *zSql; + sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); + for(ii=0; iinAux; ii++){ + if( ii ) sqlite3_str_append(p, ",", 1); +#ifdef SQLITE_ENABLE_GEOPOLY + if( iinAuxNotNull ){ + sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); + }else +#endif + { + sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); + } + } + sqlite3_str_appendf(p, " WHERE rowid=?1"); + zSql = sqlite3_str_finish(p); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); + sqlite3_free(zSql); + } + } + } + + return rc; +} + +/* +** The second argument to this function contains the text of an SQL statement +** that returns a single integer value. The statement is compiled and executed +** using database connection db. If successful, the integer value returned +** is written to *piVal and SQLITE_OK returned. Otherwise, an SQLite error +** code is returned and the value of *piVal after returning is not defined. +*/ +static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){ + int rc = SQLITE_NOMEM; + if( zSql ){ + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *piVal = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_finalize(pStmt); + } + } + return rc; +} + +/* +** This function is called from within the xConnect() or xCreate() method to +** determine the node-size used by the rtree table being created or connected +** to. If successful, pRtree->iNodeSize is populated and SQLITE_OK returned. +** Otherwise, an SQLite error code is returned. +** +** If this function is being called as part of an xConnect(), then the rtree +** table already exists. In this case the node-size is determined by inspecting +** the root node of the tree. +** +** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. +** This ensures that each node is stored on a single database page. If the +** database page-size is so large that more than RTREE_MAXCELLS entries +** would fit in a single node, use a smaller node-size. +*/ +static int getNodeSize( + sqlite3 *db, /* Database handle */ + Rtree *pRtree, /* Rtree handle */ + int isCreate, /* True for xCreate, false for xConnect */ + char **pzErr /* OUT: Error message, if any */ +){ + int rc; + char *zSql; + if( isCreate ){ + int iPageSize = 0; + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); + rc = getIntFromStmt(db, zSql, &iPageSize); + if( rc==SQLITE_OK ){ + pRtree->iNodeSize = iPageSize-64; + if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)iNodeSize ){ + pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + }else{ + zSql = sqlite3_mprintf( + "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1", + pRtree->zDb, pRtree->zName + ); + rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + }else if( pRtree->iNodeSize<(512-64) ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", + pRtree->zName); + } + } + + sqlite3_free(zSql); + return rc; +} + +/* +** Return the length of a token +*/ +static int rtreeTokenLength(const char *z){ + int dummy = 0; + return sqlite3GetToken((const unsigned char*)z,&dummy); +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the r-tree virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int rtreeInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + int nDb; /* Length of string argv[1] */ + int nName; /* Length of string argv[2] */ + int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); + sqlite3_str *pSql; + char *zSql; + int ii = 4; + int iErr; + + const char *aErrMsg[] = { + 0, /* 0 */ + "Wrong number of columns for an rtree table", /* 1 */ + "Too few columns for an rtree table", /* 2 */ + "Too many columns for an rtree table", /* 3 */ + "Auxiliary rtree columns must be last" /* 4 */ + }; + + assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */ + if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); + return SQLITE_ERROR; + } + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + + + /* Allocate the sqlite3_vtab structure */ + nDb = (int)strlen(argv[1]); + nName = (int)strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; + pRtree->eCoordType = (u8)eCoordType; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); + + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT", + rtreeTokenLength(argv[3]), argv[3]); + for(ii=4; iinAux++; + sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1); + }else if( pRtree->nAux>0 ){ + break; + }else{ + static const char *azFormat[] = {",%.*s REAL", ",%.*s INT"}; + pRtree->nDim2++; + sqlite3_str_appendf(pSql, azFormat[eCoordType], + rtreeTokenLength(zArg), zArg); + } + } + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( iinDim = pRtree->nDim2/2; + if( pRtree->nDim<1 ){ + iErr = 2; + }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){ + iErr = 3; + }else if( pRtree->nDim2 % 2 ){ + iErr = 1; + }else{ + iErr = 0; + } + if( iErr ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); + goto rtreeInit_fail; + } + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto rtreeInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto rtreeInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +rtreeInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); + return rc; +} + + +/* +** Implementation of a scalar function that decodes r-tree nodes to +** human readable strings. This can be used for debugging and analysis. +** +** The scalar function takes two arguments: (1) the number of dimensions +** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing +** an r-tree node. For a two-dimensional r-tree structure called "rt", to +** deserialize all nodes, a statement like: +** +** SELECT rtreenode(2, data) FROM rt_node; +** +** The human readable string takes the form of a Tcl list with one +** entry for each cell in the r-tree node. Each entry is itself a +** list, containing the 8-byte rowid/pageno followed by the +** *2 coordinates. +*/ +static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ + RtreeNode node; + Rtree tree; + int ii; + int nData; + int errCode; + sqlite3_str *pOut; + + UNUSED_PARAMETER(nArg); + memset(&node, 0, sizeof(RtreeNode)); + memset(&tree, 0, sizeof(Rtree)); + tree.nDim = (u8)sqlite3_value_int(apArg[0]); + if( tree.nDim<1 || tree.nDim>5 ) return; + tree.nDim2 = tree.nDim*2; + tree.nBytesPerCell = 8 + 8 * tree.nDim; + node.zData = (u8 *)sqlite3_value_blob(apArg[1]); + if( node.zData==0 ) return; + nData = sqlite3_value_bytes(apArg[1]); + if( nData<4 ) return; + if( nData0 ) sqlite3_str_append(pOut, " ", 1); + sqlite3_str_appendf(pOut, "{%lld", cell.iRowid); + for(jj=0; jjrc==SQLITE_OK ) pCheck->rc = rc; +} + +/* +** The second and subsequent arguments to this function are a format string +** and printf style arguments. This function formats the string and attempts +** to compile it as an SQL statement. +** +** If successful, a pointer to the new SQL statement is returned. Otherwise, +** NULL is returned and an error code left in RtreeCheck.rc. +*/ +static sqlite3_stmt *rtreeCheckPrepare( + RtreeCheck *pCheck, /* RtreeCheck object */ + const char *zFmt, ... /* Format string and trailing args */ +){ + va_list ap; + char *z; + sqlite3_stmt *pRet = 0; + + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + + if( pCheck->rc==SQLITE_OK ){ + if( z==0 ){ + pCheck->rc = SQLITE_NOMEM; + }else{ + pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); + } + } + + sqlite3_free(z); + va_end(ap); + return pRet; +} + +/* +** The second and subsequent arguments to this function are a printf() +** style format string and arguments. This function formats the string and +** appends it to the report being accumuated in pCheck. +*/ +static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + if( pCheck->rc==SQLITE_OK && pCheck->nErrrc = SQLITE_NOMEM; + }else{ + pCheck->zReport = sqlite3_mprintf("%z%s%z", + pCheck->zReport, (pCheck->zReport ? "\n" : ""), z + ); + if( pCheck->zReport==0 ){ + pCheck->rc = SQLITE_NOMEM; + } + } + pCheck->nErr++; + } + va_end(ap); +} + +/* +** This function is a no-op if there is already an error code stored +** in the RtreeCheck object indicated by the first argument. NULL is +** returned in this case. +** +** Otherwise, the contents of rtree table node iNode are loaded from +** the database and copied into a buffer obtained from sqlite3_malloc(). +** If no error occurs, a pointer to the buffer is returned and (*pnNode) +** is set to the size of the buffer in bytes. +** +** Or, if an error does occur, NULL is returned and an error code left +** in the RtreeCheck object. The final value of *pnNode is undefined in +** this case. +*/ +static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ + u8 *pRet = 0; /* Return value */ + + if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){ + pCheck->pGetNode = rtreeCheckPrepare(pCheck, + "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", + pCheck->zDb, pCheck->zTab + ); + } + + if( pCheck->rc==SQLITE_OK ){ + sqlite3_bind_int64(pCheck->pGetNode, 1, iNode); + if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ + int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); + const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); + pRet = sqlite3_malloc64(nNode); + if( pRet==0 ){ + pCheck->rc = SQLITE_NOMEM; + }else{ + memcpy(pRet, pNode, nNode); + *pnNode = nNode; + } + } + rtreeCheckReset(pCheck, pCheck->pGetNode); + if( pCheck->rc==SQLITE_OK && pRet==0 ){ + rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode); + } + } + + return pRet; +} + +/* +** This function is used to check that the %_parent (if bLeaf==0) or %_rowid +** (if bLeaf==1) table contains a specified entry. The schemas of the +** two tables are: +** +** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) +** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...) +** +** In both cases, this function checks that there exists an entry with +** IPK value iKey and the second column set to iVal. +** +*/ +static void rtreeCheckMapping( + RtreeCheck *pCheck, /* RtreeCheck object */ + int bLeaf, /* True for a leaf cell, false for interior */ + i64 iKey, /* Key for mapping */ + i64 iVal /* Expected value for mapping */ +){ + int rc; + sqlite3_stmt *pStmt; + const char *azSql[2] = { + "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1", + "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1" + }; + + assert( bLeaf==0 || bLeaf==1 ); + if( pCheck->aCheckMapping[bLeaf]==0 ){ + pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck, + azSql[bLeaf], pCheck->zDb, pCheck->zTab + ); + } + if( pCheck->rc!=SQLITE_OK ) return; + + pStmt = pCheck->aCheckMapping[bLeaf]; + sqlite3_bind_int64(pStmt, 1, iKey); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_DONE ){ + rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table", + iKey, iVal, (bLeaf ? "%_rowid" : "%_parent") + ); + }else if( rc==SQLITE_ROW ){ + i64 ii = sqlite3_column_int64(pStmt, 0); + if( ii!=iVal ){ + rtreeCheckAppendMsg(pCheck, + "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)", + iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal + ); + } + } + rtreeCheckReset(pCheck, pStmt); +} + +/* +** Argument pCell points to an array of coordinates stored on an rtree page. +** This function checks that the coordinates are internally consistent (no +** x1>x2 conditions) and adds an error message to the RtreeCheck object +** if they are not. +** +** Additionally, if pParent is not NULL, then it is assumed to point to +** the array of coordinates on the parent page that bound the page +** containing pCell. In this case it is also verified that the two +** sets of coordinates are mutually consistent and an error message added +** to the RtreeCheck object if they are not. +*/ +static void rtreeCheckCellCoord( + RtreeCheck *pCheck, + i64 iNode, /* Node id to use in error messages */ + int iCell, /* Cell number to use in error messages */ + u8 *pCell, /* Pointer to cell coordinates */ + u8 *pParent /* Pointer to parent coordinates */ +){ + RtreeCoord c1, c2; + RtreeCoord p1, p2; + int i; + + for(i=0; inDim; i++){ + readCoord(&pCell[4*2*i], &c1); + readCoord(&pCell[4*(2*i + 1)], &c2); + + /* printf("%e, %e\n", c1.u.f, c2.u.f); */ + if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){ + rtreeCheckAppendMsg(pCheck, + "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode + ); + } + + if( pParent ){ + readCoord(&pParent[4*2*i], &p1); + readCoord(&pParent[4*(2*i + 1)], &p2); + + if( (pCheck->bInt ? c1.ibInt ? c2.i>p2.i : c2.f>p2.f) + ){ + rtreeCheckAppendMsg(pCheck, + "Dimension %d of cell %d on node %lld is corrupt relative to parent" + , i, iCell, iNode + ); + } + } + } +} + +/* +** Run rtreecheck() checks on node iNode, which is at depth iDepth within +** the r-tree structure. Argument aParent points to the array of coordinates +** that bound node iNode on the parent node. +** +** If any problems are discovered, an error message is appended to the +** report accumulated in the RtreeCheck object. +*/ +static void rtreeCheckNode( + RtreeCheck *pCheck, + int iDepth, /* Depth of iNode (0==leaf) */ + u8 *aParent, /* Buffer containing parent coords */ + i64 iNode /* Node to check */ +){ + u8 *aNode = 0; + int nNode = 0; + + assert( iNode==1 || aParent!=0 ); + assert( pCheck->nDim>0 ); + + aNode = rtreeCheckGetNode(pCheck, iNode, &nNode); + if( aNode ){ + if( nNode<4 ){ + rtreeCheckAppendMsg(pCheck, + "Node %lld is too small (%d bytes)", iNode, nNode + ); + }else{ + int nCell; /* Number of cells on page */ + int i; /* Used to iterate through cells */ + if( aParent==0 ){ + iDepth = readInt16(aNode); + if( iDepth>RTREE_MAX_DEPTH ){ + rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth); + sqlite3_free(aNode); + return; + } + } + nCell = readInt16(&aNode[2]); + if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){ + rtreeCheckAppendMsg(pCheck, + "Node %lld is too small for cell count of %d (%d bytes)", + iNode, nCell, nNode + ); + }else{ + for(i=0; inDim*2*4)]; + i64 iVal = readInt64(pCell); + rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent); + + if( iDepth>0 ){ + rtreeCheckMapping(pCheck, 0, iVal, iNode); + rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal); + pCheck->nNonLeaf++; + }else{ + rtreeCheckMapping(pCheck, 1, iVal, iNode); + pCheck->nLeaf++; + } + } + } + } + sqlite3_free(aNode); + } +} + +/* +** The second argument to this function must be either "_rowid" or +** "_parent". This function checks that the number of entries in the +** %_rowid or %_parent table is exactly nExpect. If not, it adds +** an error message to the report in the RtreeCheck object indicated +** by the first argument. +*/ +static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ + if( pCheck->rc==SQLITE_OK ){ + sqlite3_stmt *pCount; + pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'", + pCheck->zDb, pCheck->zTab, zTbl + ); + if( pCount ){ + if( sqlite3_step(pCount)==SQLITE_ROW ){ + i64 nActual = sqlite3_column_int64(pCount, 0); + if( nActual!=nExpect ){ + rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table" + " - expected %lld, actual %lld" , zTbl, nExpect, nActual + ); + } + } + pCheck->rc = sqlite3_finalize(pCount); + } + } +} + +/* +** This function does the bulk of the work for the rtree integrity-check. +** It is called by rtreecheck(), which is the SQL function implementation. +*/ +static int rtreeCheckTable( + sqlite3 *db, /* Database handle to access db through */ + const char *zDb, /* Name of db ("main", "temp" etc.) */ + const char *zTab, /* Name of rtree table to check */ + char **pzReport /* OUT: sqlite3_malloc'd report text */ +){ + RtreeCheck check; /* Common context for various routines */ + sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ + int nAux = 0; /* Number of extra columns. */ + + /* Initialize the context object */ + memset(&check, 0, sizeof(check)); + check.db = db; + check.zDb = zDb; + check.zTab = zTab; + + /* Find the number of auxiliary columns */ + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); + if( pStmt ){ + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); + }else + if( check.rc!=SQLITE_NOMEM ){ + check.rc = SQLITE_OK; + } + + /* Find number of dimensions in the rtree table. */ + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab); + if( pStmt ){ + int rc; + check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2; + if( check.nDim<1 ){ + rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree"); + }else if( SQLITE_ROW==sqlite3_step(pStmt) ){ + check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); + } + rc = sqlite3_finalize(pStmt); + if( rc!=SQLITE_CORRUPT ) check.rc = rc; + } + + /* Do the actual integrity-check */ + if( check.nDim>=1 ){ + if( check.rc==SQLITE_OK ){ + rtreeCheckNode(&check, 0, 0, 1); + } + rtreeCheckCount(&check, "_rowid", check.nLeaf); + rtreeCheckCount(&check, "_parent", check.nNonLeaf); + } + + /* Finalize SQL statements used by the integrity-check */ + sqlite3_finalize(check.pGetNode); + sqlite3_finalize(check.aCheckMapping[0]); + sqlite3_finalize(check.aCheckMapping[1]); + + *pzReport = check.zReport; + return check.rc; +} + +/* +** Implementation of the xIntegrity method for Rtree. +*/ +static int rtreeIntegrity( + sqlite3_vtab *pVtab, /* The virtual table to check */ + const char *zSchema, /* Schema in which the virtual table lives */ + const char *zName, /* Name of the virtual table */ + int isQuick, /* True for a quick_check */ + char **pzErr /* Write results here */ +){ + Rtree *pRtree = (Rtree*)pVtab; + int rc; + assert( pzErr!=0 && *pzErr==0 ); + UNUSED_PARAMETER(zSchema); + UNUSED_PARAMETER(zName); + UNUSED_PARAMETER(isQuick); + rc = rtreeCheckTable(pRtree->db, pRtree->zDb, pRtree->zName, pzErr); + if( rc==SQLITE_OK && *pzErr ){ + *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", + pRtree->zDb, pRtree->zName, *pzErr); + if( (*pzErr)==0 ) rc = SQLITE_NOMEM; + } + return rc; +} + +/* +** Usage: +** +** rtreecheck(); +** rtreecheck(, ); +** +** Invoking this SQL function runs an integrity-check on the named rtree +** table. The integrity-check verifies the following: +** +** 1. For each cell in the r-tree structure (%_node table), that: +** +** a) for each dimension, (coord1 <= coord2). +** +** b) unless the cell is on the root node, that the cell is bounded +** by the parent cell on the parent node. +** +** c) for leaf nodes, that there is an entry in the %_rowid +** table corresponding to the cell's rowid value that +** points to the correct node. +** +** d) for cells on non-leaf nodes, that there is an entry in the +** %_parent table mapping from the cell's child node to the +** node that it resides on. +** +** 2. That there are the same number of entries in the %_rowid table +** as there are leaf cells in the r-tree structure, and that there +** is a leaf cell that corresponds to each entry in the %_rowid table. +** +** 3. That there are the same number of entries in the %_parent table +** as there are non-leaf cells in the r-tree structure, and that +** there is a non-leaf cell that corresponds to each entry in the +** %_parent table. +*/ +static void rtreecheck( + sqlite3_context *ctx, + int nArg, + sqlite3_value **apArg +){ + if( nArg!=1 && nArg!=2 ){ + sqlite3_result_error(ctx, + "wrong number of arguments to function rtreecheck()", -1 + ); + }else{ + int rc; + char *zReport = 0; + const char *zDb = (const char*)sqlite3_value_text(apArg[0]); + const char *zTab; + if( nArg==1 ){ + zTab = zDb; + zDb = "main"; + }else{ + zTab = (const char*)sqlite3_value_text(apArg[1]); + } + rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport); + if( rc==SQLITE_OK ){ + sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_error_code(ctx, rc); + } + sqlite3_free(zReport); + } +} + +/* Conditionally include the geopoly code */ +#ifdef SQLITE_ENABLE_GEOPOLY +/************** Include geopoly.c in the middle of rtree.c *******************/ +/************** Begin file geopoly.c *****************************************/ +/* +** 2018-05-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements an alternative R-Tree virtual table that +** uses polygons to express the boundaries of 2-dimensional objects. +** +** This file is #include-ed onto the end of "rtree.c" so that it has +** access to all of the R-Tree internals. +*/ +/* #include */ + +/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ +#ifdef GEOPOLY_ENABLE_DEBUG + static int geo_debug = 0; +# define GEODEBUG(X) if(geo_debug)printf X +#else +# define GEODEBUG(X) +#endif + +/* Character class routines */ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +#ifndef JSON_NULL /* The following stuff repeats things found in json1 */ +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function. +*/ +static const char geopolyIsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define fast_isspace(x) (geopolyIsSpace[(unsigned char)x]) +#endif /* JSON NULL - back to original code */ + +/* Compiler and version */ +#ifndef GCC_VERSION +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif +#ifndef MSVC_VERSION +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + +/* Datatype for coordinates +*/ +typedef float GeoCoord; + +/* +** Internal representation of a polygon. +** +** The polygon consists of a sequence of vertexes. There is a line +** segment between each pair of vertexes, and one final segment from +** the last vertex back to the first. (This differs from the GeoJSON +** standard in which the final vertex is a repeat of the first.) +** +** The polygon follows the right-hand rule. The area to the right of +** each segment is "outside" and the area to the left is "inside". +** +** The on-disk representation consists of a 4-byte header followed by +** the values. The 4-byte header is: +** +** encoding (1 byte) 0=big-endian, 1=little-endian +** nvertex (3 bytes) Number of vertexes as a big-endian integer +** +** Enough space is allocated for 4 coordinates, to work around over-zealous +** warnings coming from some compiler (notably, clang). In reality, the size +** of each GeoPoly memory allocate is adjusted as necessary so that the +** GeoPoly.a[] array at the end is the appropriate size. +*/ +typedef struct GeoPoly GeoPoly; +struct GeoPoly { + int nVertex; /* Number of vertexes */ + unsigned char hdr[4]; /* Header for on-disk representation */ + GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */ +}; + +/* The size of a memory allocation needed for a GeoPoly object sufficient +** to hold N coordinate pairs. +*/ +#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4)) + +/* Macros to access coordinates of a GeoPoly. +** We have to use these macros, rather than just say p->a[i] in order +** to silence (incorrect) UBSAN warnings if the array index is too large. +*/ +#define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2]) +#define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1]) + + +/* +** State of a parse of a GeoJSON input. +*/ +typedef struct GeoParse GeoParse; +struct GeoParse { + const unsigned char *z; /* Unparsed input */ + int nVertex; /* Number of vertexes in a[] */ + int nAlloc; /* Space allocated to a[] */ + int nErr; /* Number of errors encountered */ + GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ +}; + +/* Do a 4-byte byte swap */ +static void geopolySwab32(unsigned char *a){ + unsigned char t = a[0]; + a[0] = a[3]; + a[3] = t; + t = a[1]; + a[1] = a[2]; + a[2] = t; +} + +/* Skip whitespace. Return the next non-whitespace character. */ +static char geopolySkipSpace(GeoParse *p){ + while( fast_isspace(p->z[0]) ) p->z++; + return p->z[0]; +} + +/* Parse out a number. Write the value into *pVal if pVal!=0. +** return non-zero on success and zero if the next token is not a number. +*/ +static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ + char c = geopolySkipSpace(p); + const unsigned char *z = p->z; + int j = 0; + int seenDP = 0; + int seenE = 0; + if( c=='-' ){ + j = 1; + c = z[j]; + } + if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; + for(;; j++){ + c = z[j]; + if( safe_isdigit(c) ) continue; + if( c=='.' ){ + if( z[j-1]=='-' ) return 0; + if( seenDP ) return 0; + seenDP = 1; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ) return 0; + if( seenE ) return -1; + seenDP = seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ) return 0; + continue; + } + break; + } + if( z[j-1]<'0' ) return 0; + if( pVal ){ +#ifdef SQLITE_AMALGAMATION + /* The sqlite3AtoF() routine is much much faster than atof(), if it + ** is available */ + double r; + (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); + *pVal = r; +#else + *pVal = (GeoCoord)atof((const char*)p->z); +#endif + } + p->z += j; + return 1; +} + +/* +** If the input is a well-formed JSON array of coordinates with at least +** four coordinates and where each coordinate is itself a two-value array, +** then convert the JSON into a GeoPoly object and return a pointer to +** that object. +** +** If any error occurs, return NULL. +*/ +static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ + GeoParse s; + int rc = SQLITE_OK; + memset(&s, 0, sizeof(s)); + s.z = z; + if( geopolySkipSpace(&s)=='[' ){ + s.z++; + while( geopolySkipSpace(&s)=='[' ){ + int ii = 0; + char c; + s.z++; + if( s.nVertex>=s.nAlloc ){ + GeoCoord *aNew; + s.nAlloc = s.nAlloc*2 + 16; + aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); + if( aNew==0 ){ + rc = SQLITE_NOMEM; + s.nErr++; + break; + } + s.a = aNew; + } + while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ + ii++; + if( ii==2 ) s.nVertex++; + c = geopolySkipSpace(&s); + s.z++; + if( c==',' ) continue; + if( c==']' && ii>=2 ) break; + s.nErr++; + rc = SQLITE_ERROR; + goto parse_json_err; + } + if( geopolySkipSpace(&s)==',' ){ + s.z++; + continue; + } + break; + } + if( geopolySkipSpace(&s)==']' + && s.nVertex>=4 + && s.a[0]==s.a[s.nVertex*2-2] + && s.a[1]==s.a[s.nVertex*2-1] + && (s.z++, geopolySkipSpace(&s)==0) + ){ + GeoPoly *pOut; + int x = 1; + s.nVertex--; /* Remove the redundant vertex at the end */ + pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) ); + x = 1; + if( pOut==0 ) goto parse_json_err; + pOut->nVertex = s.nVertex; + memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord)); + pOut->hdr[0] = *(unsigned char*)&x; + pOut->hdr[1] = (s.nVertex>>16)&0xff; + pOut->hdr[2] = (s.nVertex>>8)&0xff; + pOut->hdr[3] = s.nVertex&0xff; + sqlite3_free(s.a); + if( pRc ) *pRc = SQLITE_OK; + return pOut; + }else{ + s.nErr++; + rc = SQLITE_ERROR; + } + } +parse_json_err: + if( pRc ) *pRc = rc; + sqlite3_free(s.a); + return 0; +} + +/* +** Given a function parameter, try to interpret it as a polygon, either +** in the binary format or JSON text. Compute a GeoPoly object and +** return a pointer to that object. Or if the input is not a well-formed +** polygon, put an error message in sqlite3_context and return NULL. +*/ +static GeoPoly *geopolyFuncParam( + sqlite3_context *pCtx, /* Context for error messages */ + sqlite3_value *pVal, /* The value to decode */ + int *pRc /* Write error here */ +){ + GeoPoly *p = 0; + int nByte; + testcase( pCtx==0 ); + if( sqlite3_value_type(pVal)==SQLITE_BLOB + && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord)) + ){ + const unsigned char *a = sqlite3_value_blob(pVal); + int nVertex; + if( a==0 ){ + if( pCtx ) sqlite3_result_error_nomem(pCtx); + return 0; + } + nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; + if( (a[0]==0 || a[0]==1) + && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte + ){ + p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + if( pCtx ) sqlite3_result_error_nomem(pCtx); + }else{ + int x = 1; + p->nVertex = nVertex; + memcpy(p->hdr, a, nByte); + if( a[0] != *(unsigned char*)&x ){ + int ii; + for(ii=0; iihdr[0] ^= 1; + } + } + } + if( pRc ) *pRc = SQLITE_OK; + return p; + }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ + const unsigned char *zJson = sqlite3_value_text(pVal); + if( zJson==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + return geopolyParseJson(zJson, pRc); + }else{ + if( pRc ) *pRc = SQLITE_ERROR; + return 0; + } +} + +/* +** Implementation of the geopoly_blob(X) function. +** +** If the input is a well-formed Geopoly BLOB or JSON string +** then return the BLOB representation of the polygon. Otherwise +** return NULL. +*/ +static void geopolyBlobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_json(X) +** +** Interpret X as a polygon and render it as a JSON array +** of coordinates. Or, if X is not a valid polygon, return NULL. +*/ +static void geopolyJsonFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + sqlite3_str_append(x, "[", 1); + for(i=0; inVertex; i++){ + sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i)); + } + sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0)); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_svg(X, ....) +** +** Interpret X as a polygon and render it as a SVG . +** Additional arguments are added as attributes to the . +*/ +static void geopolySvgFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p; + if( argc<1 ) return; + p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + char cSep = '\''; + sqlite3_str_appendf(x, ""); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL Function: geopoly_xform(poly, A, B, C, D, E, F) +** +** Transform and/or translate a polygon as follows: +** +** x1 = A*x0 + B*y0 + E +** y1 = C*x0 + D*y0 + F +** +** For a translation: +** +** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset) +** +** Rotate by R around the point (0,0): +** +** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) +*/ +static void geopolyXformFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + double A = sqlite3_value_double(argv[1]); + double B = sqlite3_value_double(argv[2]); + double C = sqlite3_value_double(argv[3]); + double D = sqlite3_value_double(argv[4]); + double E = sqlite3_value_double(argv[5]); + double F = sqlite3_value_double(argv[6]); + GeoCoord x1, y1, x0, y0; + int ii; + (void)argc; + if( p ){ + for(ii=0; iinVertex; ii++){ + x0 = GeoX(p,ii); + y0 = GeoY(p,ii); + x1 = (GeoCoord)(A*x0 + B*y0 + E); + y1 = (GeoCoord)(C*x0 + D*y0 + F); + GeoX(p,ii) = x1; + GeoY(p,ii) = y1; + } + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** Compute the area enclosed by the polygon. +** +** This routine can also be used to detect polygons that rotate in +** the wrong direction. Polygons are suppose to be counter-clockwise (CCW). +** This routine returns a negative value for clockwise (CW) polygons. +*/ +static double geopolyArea(GeoPoly *p){ + double rArea = 0.0; + int ii; + for(ii=0; iinVertex-1; ii++){ + rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */ + * (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */ + * 0.5; + } + rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */ + * (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */ + * 0.5; + return rArea; +} + +/* +** Implementation of the geopoly_area(X) function. +** +** If the input is a well-formed Geopoly BLOB then return the area +** enclosed by the polygon. If the polygon circulates clockwise instead +** of counterclockwise (as it should) then return the negative of the +** enclosed area. Otherwise return NULL. +*/ +static void geopolyAreaFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + sqlite3_result_double(context, geopolyArea(p)); + sqlite3_free(p); + } +} + +/* +** Implementation of the geopoly_ccw(X) function. +** +** If the rotation of polygon X is clockwise (incorrect) instead of +** counter-clockwise (the correct winding order according to RFC7946) +** then reverse the order of the vertexes in polygon X. +** +** In other words, this routine returns a CCW polygon regardless of the +** winding order of its input. +** +** Use this routine to sanitize historical inputs that that sometimes +** contain polygons that wind in the wrong direction. +*/ +static void geopolyCcwFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + if( geopolyArea(p)<0.0 ){ + int ii, jj; + for(ii=1, jj=p->nVertex-1; iihdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +#define GEOPOLY_PI 3.1415926535897932385 + +/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi +*/ +static double geopolySine(double r){ + assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI ); + if( r>=1.5*GEOPOLY_PI ){ + r -= 2.0*GEOPOLY_PI; + } + if( r>=0.5*GEOPOLY_PI ){ + return -geopolySine(r-GEOPOLY_PI); + }else{ + double r2 = r*r; + double r3 = r2*r; + double r5 = r3*r2; + return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5; + } +} + +/* +** Function: geopoly_regular(X,Y,R,N) +** +** Construct a simple, convex, regular polygon centered at X, Y +** with circumradius R and with N sides. +*/ +static void geopolyRegularFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x = sqlite3_value_double(argv[0]); + double y = sqlite3_value_double(argv[1]); + double r = sqlite3_value_double(argv[2]); + int n = sqlite3_value_int(argv[3]); + int i; + GeoPoly *p; + (void)argc; + + if( n<3 || r<=0.0 ) return; + if( n>1000 ) n = 1000; + p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + i = 1; + p->hdr[0] = *(unsigned char*)&i; + p->hdr[1] = 0; + p->hdr[2] = (n>>8)&0xff; + p->hdr[3] = n&0xff; + for(i=0; ihdr, 4+8*n, SQLITE_TRANSIENT); + sqlite3_free(p); +} + +/* +** If pPoly is a polygon, compute its bounding box. Then: +** +** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL +** (2) otherwise, compute a GeoPoly for the bounding box and return the +** new GeoPoly +** +** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from +** the bounding box in aCoord and return a pointer to that GeoPoly. +*/ +static GeoPoly *geopolyBBox( + sqlite3_context *context, /* For recording the error */ + sqlite3_value *pPoly, /* The polygon */ + RtreeCoord *aCoord, /* Results here */ + int *pRc /* Error code here */ +){ + GeoPoly *pOut = 0; + GeoPoly *p; + float mnX, mxX, mnY, mxY; + if( pPoly==0 && aCoord!=0 ){ + p = 0; + mnX = aCoord[0].f; + mxX = aCoord[1].f; + mnY = aCoord[2].f; + mxY = aCoord[3].f; + goto geopolyBboxFill; + }else{ + p = geopolyFuncParam(context, pPoly, pRc); + } + if( p ){ + int ii; + mnX = mxX = GeoX(p,0); + mnY = mxY = GeoY(p,0); + for(ii=1; iinVertex; ii++){ + double r = GeoX(p,ii); + if( rmxX ) mxX = (float)r; + r = GeoY(p,ii); + if( rmxY ) mxY = (float)r; + } + if( pRc ) *pRc = SQLITE_OK; + if( aCoord==0 ){ + geopolyBboxFill: + pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4)); + if( pOut==0 ){ + sqlite3_free(p); + if( context ) sqlite3_result_error_nomem(context); + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + pOut->nVertex = 4; + ii = 1; + pOut->hdr[0] = *(unsigned char*)ⅈ + pOut->hdr[1] = 0; + pOut->hdr[2] = 0; + pOut->hdr[3] = 4; + GeoX(pOut,0) = mnX; + GeoY(pOut,0) = mnY; + GeoX(pOut,1) = mxX; + GeoY(pOut,1) = mnY; + GeoX(pOut,2) = mxX; + GeoY(pOut,2) = mxY; + GeoX(pOut,3) = mnX; + GeoY(pOut,3) = mxY; + }else{ + sqlite3_free(p); + aCoord[0].f = mnX; + aCoord[1].f = mxX; + aCoord[2].f = mnY; + aCoord[3].f = mxY; + } + }else if( aCoord ){ + memset(aCoord, 0, sizeof(RtreeCoord)*4); + } + return pOut; +} + +/* +** Implementation of the geopoly_bbox(X) SQL function. +*/ +static void geopolyBBoxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); + (void)argc; + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** State vector for the geopoly_group_bbox() aggregate function. +*/ +typedef struct GeoBBox GeoBBox; +struct GeoBBox { + int isInit; + RtreeCoord a[4]; +}; + + +/* +** Implementation of the geopoly_group_bbox(X) aggregate SQL function. +*/ +static void geopolyBBoxStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + RtreeCoord a[4]; + int rc = SQLITE_OK; + (void)argc; + (void)geopolyBBox(context, argv[0], a, &rc); + if( rc==SQLITE_OK ){ + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); + if( pBBox==0 ) return; + if( pBBox->isInit==0 ){ + pBBox->isInit = 1; + memcpy(pBBox->a, a, sizeof(RtreeCoord)*4); + }else{ + if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0]; + if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1]; + if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2]; + if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3]; + } + } +} +static void geopolyBBoxFinal( + sqlite3_context *context +){ + GeoPoly *p; + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); + if( pBBox==0 ) return; + p = geopolyBBox(context, 0, pBBox->a, 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + + +/* +** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). +** Returns: +** +** +2 x0,y0 is on the line segement +** +** +1 x0,y0 is beneath line segment +** +** 0 x0,y0 is not on or beneath the line segment or the line segment +** is vertical and x0,y0 is not on the line segment +** +** The left-most coordinate min(x1,x2) is not considered to be part of +** the line segment for the purposes of this analysis. +*/ +static int pointBeneathLine( + double x0, double y0, + double x1, double y1, + double x2, double y2 +){ + double y; + if( x0==x1 && y0==y1 ) return 2; + if( x1x2 ) return 0; + }else if( x1>x2 ){ + if( x0<=x2 || x0>x1 ) return 0; + }else{ + /* Vertical line segment */ + if( x0!=x1 ) return 0; + if( y0y1 && y0>y2 ) return 0; + return 2; + } + y = y1 + (y2-y1)*(x0-x1)/(x2-x1); + if( y0==y ) return 2; + if( y0nVertex-1; ii++){ + v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), + GeoX(p1,ii+1),GeoY(p1,ii+1)); + if( v==2 ) break; + cnt += v; + } + if( v!=2 ){ + v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), + GeoX(p1,0), GeoY(p1,0)); + } + if( v==2 ){ + sqlite3_result_int(context, 1); + }else if( ((v+cnt)&1)==0 ){ + sqlite3_result_int(context, 0); + }else{ + sqlite3_result_int(context, 2); + } + sqlite3_free(p1); +} + +/* Forward declaration */ +static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); + +/* +** SQL function: geopoly_within(P1,P2) +** +** Return +2 if P1 and P2 are the same polygon +** Return +1 if P2 is contained within P1 +** Return 0 if any part of P2 is on the outside of P1 +** +*/ +static void geopolyWithinFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + (void)argc; + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* Objects used by the overlap algorihm. */ +typedef struct GeoEvent GeoEvent; +typedef struct GeoSegment GeoSegment; +typedef struct GeoOverlap GeoOverlap; +struct GeoEvent { + double x; /* X coordinate at which event occurs */ + int eType; /* 0 for ADD, 1 for REMOVE */ + GeoSegment *pSeg; /* The segment to be added or removed */ + GeoEvent *pNext; /* Next event in the sorted list */ +}; +struct GeoSegment { + double C, B; /* y = C*x + B */ + double y; /* Current y value */ + float y0; /* Initial y value */ + unsigned char side; /* 1 for p1, 2 for p2 */ + unsigned int idx; /* Which segment within the side */ + GeoSegment *pNext; /* Next segment in a list sorted by y */ +}; +struct GeoOverlap { + GeoEvent *aEvent; /* Array of all events */ + GeoSegment *aSegment; /* Array of all segments */ + int nEvent; /* Number of events */ + int nSegment; /* Number of segments */ +}; + +/* +** Add a single segment and its associated events. +*/ +static void geopolyAddOneSegment( + GeoOverlap *p, + GeoCoord x0, + GeoCoord y0, + GeoCoord x1, + GeoCoord y1, + unsigned char side, + unsigned int idx +){ + GeoSegment *pSeg; + GeoEvent *pEvent; + if( x0==x1 ) return; /* Ignore vertical segments */ + if( x0>x1 ){ + GeoCoord t = x0; + x0 = x1; + x1 = t; + t = y0; + y0 = y1; + y1 = t; + } + pSeg = p->aSegment + p->nSegment; + p->nSegment++; + pSeg->C = (y1-y0)/(x1-x0); + pSeg->B = y1 - x1*pSeg->C; + pSeg->y0 = y0; + pSeg->side = side; + pSeg->idx = idx; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x0; + pEvent->eType = 0; + pEvent->pSeg = pSeg; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x1; + pEvent->eType = 1; + pEvent->pSeg = pSeg; +} + + + +/* +** Insert all segments and events for polygon pPoly. +*/ +static void geopolyAddSegments( + GeoOverlap *p, /* Add segments to this Overlap object */ + GeoPoly *pPoly, /* Take all segments from this polygon */ + unsigned char side /* The side of pPoly */ +){ + unsigned int i; + GeoCoord *x; + for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ + x = &GeoX(pPoly,i); + geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); + } + x = &GeoX(pPoly,i); + geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); +} + +/* +** Merge two lists of sorted events by X coordinate +*/ +static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){ + GeoEvent head, *pLast; + head.pNext = 0; + pLast = &head; + while( pRight && pLeft ){ + if( pRight->x <= pLeft->x ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort an array of nEvent event objects into a list. +*/ +static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){ + int mx = 0; + int i, j; + GeoEvent *p; + GeoEvent *a[50]; + for(i=0; ipNext = 0; + for(j=0; j=mx ) mx = j+1; + } + p = 0; + for(i=0; iy - pLeft->y; + if( r==0.0 ) r = pRight->C - pLeft->C; + if( r<0.0 ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort a list of GeoSegments in order of increasing Y and in the event of +** a tie, increasing C (slope). +*/ +static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ + int mx = 0; + int i; + GeoSegment *p; + GeoSegment *a[50]; + while( pList ){ + p = pList; + pList = pList->pNext; + p->pNext = 0; + for(i=0; i=mx ) mx = i+1; + } + p = 0; + for(i=0; inVertex + p2->nVertex + 2; + GeoOverlap *p; + sqlite3_int64 nByte; + GeoEvent *pThisEvent; + double rX; + int rc = 0; + int needSort = 0; + GeoSegment *pActive = 0; + GeoSegment *pSeg; + unsigned char aOverlap[4]; + + nByte = sizeof(GeoEvent)*nVertex*2 + + sizeof(GeoSegment)*nVertex + + sizeof(GeoOverlap); + p = sqlite3_malloc64( nByte ); + if( p==0 ) return -1; + p->aEvent = (GeoEvent*)&p[1]; + p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; + p->nEvent = p->nSegment = 0; + geopolyAddSegments(p, p1, 1); + geopolyAddSegments(p, p2, 2); + pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); + rX = pThisEvent && pThisEvent->x==0.0 ? -1.0 : 0.0; + memset(aOverlap, 0, sizeof(aOverlap)); + while( pThisEvent ){ + if( pThisEvent->x!=rX ){ + GeoSegment *pPrev = 0; + int iMask = 0; + GEODEBUG(("Distinct X: %g\n", pThisEvent->x)); + rX = pThisEvent->x; + if( needSort ){ + GEODEBUG(("SORT\n")); + pActive = geopolySortSegmentsByYAndC(pActive); + needSort = 0; + } + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pPrev ){ + if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + pPrev = 0; + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + double y = pSeg->C*rX + pSeg->B; + GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y)); + pSeg->y = y; + if( pPrev ){ + if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){ + rc = 1; + GEODEBUG(("Crossing: %d.%d and %d.%d\n", + pPrev->side, pPrev->idx, + pSeg->side, pSeg->idx)); + goto geopolyOverlapDone; + }else if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + } + GEODEBUG(("%s %d.%d C=%g B=%g\n", + pThisEvent->eType ? "RM " : "ADD", + pThisEvent->pSeg->side, pThisEvent->pSeg->idx, + pThisEvent->pSeg->C, + pThisEvent->pSeg->B)); + if( pThisEvent->eType==0 ){ + /* Add a segment */ + pSeg = pThisEvent->pSeg; + pSeg->y = pSeg->y0; + pSeg->pNext = pActive; + pActive = pSeg; + needSort = 1; + }else{ + /* Remove a segment */ + if( pActive==pThisEvent->pSeg ){ + pActive = ALWAYS(pActive) ? pActive->pNext : 0; + }else{ + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pSeg->pNext==pThisEvent->pSeg ){ + pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0; + break; + } + } + } + } + pThisEvent = pThisEvent->pNext; + } + if( aOverlap[3]==0 ){ + rc = 0; + }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){ + rc = 3; + }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){ + rc = 2; + }else if( aOverlap[1]==0 && aOverlap[2]==0 ){ + rc = 4; + }else{ + rc = 1; + } + +geopolyOverlapDone: + sqlite3_free(p); + return rc; +} + +/* +** SQL function: geopoly_overlap(P1,P2) +** +** Determine whether or not P1 and P2 overlap. Return value: +** +** 0 The two polygons are disjoint +** 1 They overlap +** 2 P1 is completely contained within P2 +** 3 P2 is completely contained within P1 +** 4 P1 and P2 are the same polygon +** NULL Either P1 or P2 or both are not valid polygons +*/ +static void geopolyOverlapFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + (void)argc; + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* +** Enable or disable debugging output +*/ +static void geopolyDebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + (void)context; + (void)argc; +#ifdef GEOPOLY_ENABLE_DEBUG + geo_debug = sqlite3_value_int(argv[0]); +#else + (void)argv; +#endif +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the geopoly virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int geopolyInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + sqlite3_int64 nDb; /* Length of string argv[1] */ + sqlite3_int64 nName; /* Length of string argv[2] */ + sqlite3_str *pSql; + char *zSql; + int ii; + (void)pAux; + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + + /* Allocate the sqlite3_vtab structure */ + nDb = strlen(argv[1]); + nName = strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; + pRtree->eCoordType = RTREE_COORD_REAL32; + pRtree->nDim = 2; + pRtree->nDim2 = 4; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); + + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); + pRtree->nAux = 1; /* Add one for _shape */ + pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ + for(ii=3; iinAux++; + sqlite3_str_appendf(pSql, ",%s", argv[ii]); + } + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + sqlite3_free(zSql); + if( rc ) goto geopolyInit_fail; + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto geopolyInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto geopolyInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +geopolyInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); + return rc; +} + + +/* +** GEOPOLY virtual table module xCreate method. +*/ +static int geopolyCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** GEOPOLY virtual table module xConnect method. +*/ +static int geopolyConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + + +/* +** GEOPOLY virtual table module xFilter method. +** +** Query plans: +** +** 1 rowid lookup +** 2 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 3 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 4 full table scan +*/ +static int geopolyFilter( + sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ + int idxNum, /* Query plan */ + const char *idxStr, /* Not Used */ + int argc, sqlite3_value **argv /* Parameters to the query plan */ +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int rc = SQLITE_OK; + int iCell = 0; + (void)idxStr; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + resetCursor(pCsr); + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = (u8)iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && idxNum<=3 ){ + RtreeCoord bbox[4]; + RtreeConstraint *p; + assert( argc==1 ); + assert( argv[0]!=0 ); + geopolyBBox(0, argv[0], bbox, &rc); + if( rc ){ + goto geopoly_filter_end; + } + pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); + pCsr->nConstraint = 4; + if( p==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + if( idxNum==2 ){ + /* Overlap query */ + p->op = 'B'; + p->iCoord = 0; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 1; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 2; + p->u.rValue = bbox[3].f; + p++; + p->op = 'D'; + p->iCoord = 3; + p->u.rValue = bbox[2].f; + }else{ + /* Within query */ + p->op = 'D'; + p->iCoord = 0; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 1; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 2; + p->u.rValue = bbox[2].f; + p++; + p->op = 'B'; + p->iCoord = 3; + p->u.rValue = bbox[3].f; + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + goto geopoly_filter_end; + } + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + +geopoly_filter_end: + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 "rowid" Direct lookup by rowid. +** 2 "rtree" R-tree overlap query using geopoly_overlap() +** 3 "rtree" R-tree within query using geopoly_within() +** 4 "fullscan" full-table scan. +** ------------------------------------------------ +*/ +static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int ii; + int iRowidTerm = -1; + int iFuncTerm = -1; + int idxNum = 0; + (void)tab; + + for(ii=0; iinConstraint; ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + if( !p->usable ) continue; + if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + iRowidTerm = ii; + break; + } + if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap() + ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within(). + ** See geopolyFindFunction() */ + iFuncTerm = ii; + idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2; + } + } + + if( iRowidTerm>=0 ){ + pIdxInfo->idxNum = 1; + pIdxInfo->idxStr = "rowid"; + pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; + pIdxInfo->estimatedCost = 30.0; + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + return SQLITE_OK; + } + if( iFuncTerm>=0 ){ + pIdxInfo->idxNum = idxNum; + pIdxInfo->idxStr = "rtree"; + pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0; + pIdxInfo->estimatedCost = 300.0; + pIdxInfo->estimatedRows = 10; + return SQLITE_OK; + } + pIdxInfo->idxNum = 4; + pIdxInfo->idxStr = "fullscan"; + pIdxInfo->estimatedCost = 3000000.0; + pIdxInfo->estimatedRows = 100000; + return SQLITE_OK; +} + + +/* +** GEOPOLY virtual table module xColumn method. +*/ +static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( p==0 ) return SQLITE_OK; + if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; + if( i<=pRtree->nAux ){ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); + } + return SQLITE_OK; +} + + +/* +** The xUpdate method for GEOPOLY module virtual tables. +** +** For DELETE: +** +** argv[0] = the rowid to be deleted +** +** For INSERT: +** +** argv[0] = SQL NULL +** argv[1] = rowid to insert, or an SQL NULL to select automatically +** argv[2] = _shape column +** argv[3] = first application-defined column.... +** +** For UPDATE: +** +** argv[0] = rowid to modify. Never NULL +** argv[1] = rowid after the change. Never NULL +** argv[2] = new value for _shape +** argv[3] = new value for first application-defined column.... +*/ +static int geopolyUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **aData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + i64 oldRowid; /* The old rowid */ + int oldRowidValid; /* True if oldRowid is valid */ + i64 newRowid; /* The new rowid */ + int newRowidValid; /* True if newRowid is valid */ + int coordChange = 0; /* Change in coordinates */ + + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } + rtreeReference(pRtree); + assert(nData>=1); + + oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; + oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; + newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; + newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; + cell.iRowid = newRowid; + + if( nData>1 /* not a DELETE */ + && (!oldRowidValid /* INSERT */ + || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ + || oldRowid!=newRowid) /* Rowid change */ + ){ + assert( aData[2]!=0 ); + geopolyBBox(0, aData[2], cell.aCoord, &rc); + if( rc ){ + if( rc==SQLITE_ERROR ){ + pVtab->zErrMsg = + sqlite3_mprintf("_shape does not contain a valid polygon"); + } + goto geopoly_update_end; + } + coordChange = 1; + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = rtreeConstraintError(pRtree, 0); + } + } + } + } + + /* If aData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){ + rc = rtreeDeleteRowid(pRtree, oldRowid); + } + + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 && coordChange ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + if( !newRowidValid ){ + rc = rtreeNewRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + /* Change the data */ + if( rc==SQLITE_OK && nData>1 ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + int nChange = 0; + sqlite3_bind_int64(pUp, 1, cell.iRowid); + assert( pRtree->nAux>=1 ); + if( sqlite3_value_nochange(aData[2]) ){ + sqlite3_bind_null(pUp, 2); + }else{ + GeoPoly *p = 0; + if( sqlite3_value_type(aData[2])==SQLITE_TEXT + && (p = geopolyFuncParam(0, aData[2], &rc))!=0 + && rc==SQLITE_OK + ){ + sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); + }else{ + sqlite3_bind_value(pUp, 2, aData[2]); + } + sqlite3_free(p); + nChange = 1; + } + for(jj=1; jjxDestructor ) pInfo->xDestructor(pInfo->pContext); + sqlite3_free(p); +} + +/* +** This routine frees the BLOB that is returned by geomCallback(). +*/ +static void rtreeMatchArgFree(void *pArg){ + int i; + RtreeMatchArg *p = (RtreeMatchArg*)pArg; + for(i=0; inParam; i++){ + sqlite3_value_free(p->apSqlParam[i]); + } + sqlite3_free(p); +} + +/* +** Each call to sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback() creates an ordinary SQLite +** scalar function that is implemented by this routine. +** +** All this function does is construct an RtreeMatchArg object that +** contains the geometry-checking callback routines and a list of +** parameters to this function, then return that RtreeMatchArg object +** as a BLOB. +** +** The R-Tree MATCH operator will read the returned BLOB, deserialize +** the RtreeMatchArg object, and use the RtreeMatchArg object to figure +** out which elements of the R-Tree should be returned by the query. +*/ +static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ + RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); + RtreeMatchArg *pBlob; + sqlite3_int64 nBlob; + int memErr = 0; + + nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) + + nArg*sizeof(sqlite3_value*); + pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); + if( !pBlob ){ + sqlite3_result_error_nomem(ctx); + }else{ + int i; + pBlob->iSize = nBlob; + pBlob->cb = pGeomCtx[0]; + pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg]; + pBlob->nParam = nArg; + for(i=0; iapSqlParam[i] = sqlite3_value_dup(aArg[i]); + if( pBlob->apSqlParam[i]==0 ) memErr = 1; +#ifdef SQLITE_RTREE_INT_ONLY + pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); +#else + pBlob->aParam[i] = sqlite3_value_double(aArg[i]); +#endif + } + if( memErr ){ + sqlite3_result_error_nomem(ctx); + rtreeMatchArgFree(pBlob); + }else{ + sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree); + } + } +} + +/* +** Register a new geometry function for use with the r-tree MATCH operator. +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, /* Register SQL function on this connection */ + const char *zGeom, /* Name of the new SQL function */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ + void *pContext /* Extra data associated with the callback */ +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ) return SQLITE_NOMEM; + pGeomCtx->xGeom = xGeom; + pGeomCtx->xQueryFunc = 0; + pGeomCtx->xDestructor = 0; + pGeomCtx->pContext = pContext; + return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +/* +** Register a new 2nd-generation geometry function for use with the +** r-tree MATCH operator. +*/ +SQLITE_API int sqlite3_rtree_query_callback( + sqlite3 *db, /* Register SQL function on this connection */ + const char *zQueryFunc, /* Name of new SQL function */ + int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ + void *pContext, /* Extra data passed into the callback */ + void (*xDestructor)(void*) /* Destructor for the extra data */ +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ){ + if( xDestructor ) xDestructor(pContext); + return SQLITE_NOMEM; + } + pGeomCtx->xGeom = 0; + pGeomCtx->xQueryFunc = xQueryFunc; + pGeomCtx->xDestructor = xDestructor; + pGeomCtx->pContext = pContext; + return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_rtree_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3RtreeInit(db); +} +#endif + +#endif + +/************** End of rtree.c ***********************************************/ +/************** Begin file icu.c *********************************************/ +/* +** 2007 May 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $ +** +** This file implements an integration between the ICU library +** ("International Components for Unicode", an open-source library +** for handling unicode data) and SQLite. The integration uses +** ICU to provide the following to SQLite: +** +** * An implementation of the SQL regexp() function (and hence REGEXP +** operator) using the ICU uregex_XX() APIs. +** +** * Implementations of the SQL scalar upper() and lower() functions +** for case mapping. +** +** * Integration of ICU and SQLite collation sequences. +** +** * An implementation of the LIKE operator that uses ICU to +** provide case-independent matching. +*/ + +#if !defined(SQLITE_CORE) \ + || defined(SQLITE_ENABLE_ICU) \ + || defined(SQLITE_ENABLE_ICU_COLLATIONS) + +/* Include ICU headers */ +#include +#include +#include +#include + +/* #include */ + +#ifndef SQLITE_CORE +/* #include "sqlite3ext.h" */ + SQLITE_EXTENSION_INIT1 +#else +/* #include "sqlite3.h" */ +#endif + +/* +** This function is called when an ICU function called from within +** the implementation of an SQL scalar function returns an error. +** +** The scalar function context passed as the first argument is +** loaded with an error message based on the following two args. +*/ +static void icuFunctionError( + sqlite3_context *pCtx, /* SQLite scalar function context */ + const char *zName, /* Name of ICU function that failed */ + UErrorCode e /* Error code returned by ICU function */ +){ + char zBuf[128]; + sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); + zBuf[127] = '\0'; + sqlite3_result_error(pCtx, zBuf, -1); +} + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/* +** Version of sqlite3_free() that is always a function, never a macro. +*/ +static void xFree(void *p){ + sqlite3_free(p); +} + +/* +** This lookup table is used to help decode the first byte of +** a multi-byte UTF8 character. It is copied here from SQLite source +** code file utf8.c. +*/ +static const unsigned char icuUtf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + +#define SQLITE_ICU_READ_UTF8(zIn, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = icuUtf8Trans1[c-0xc0]; \ + while( (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + } + +#define SQLITE_ICU_SKIP_UTF8(zIn) \ + assert( *zIn ); \ + if( *(zIn++)>=0xc0 ){ \ + while( (*zIn & 0xc0)==0x80 ){zIn++;} \ + } + + +/* +** Compare two UTF-8 strings for equality where the first string is +** a "LIKE" expression. Return true (1) if they are the same and +** false (0) if they are different. +*/ +static int icuLikeCompare( + const uint8_t *zPattern, /* LIKE pattern */ + const uint8_t *zString, /* The UTF-8 string to compare against */ + const UChar32 uEsc /* The escape character */ +){ + static const uint32_t MATCH_ONE = (uint32_t)'_'; + static const uint32_t MATCH_ALL = (uint32_t)'%'; + + int prevEscape = 0; /* True if the previous character was uEsc */ + + while( 1 ){ + + /* Read (and consume) the next character from the input pattern. */ + uint32_t uPattern; + SQLITE_ICU_READ_UTF8(zPattern, uPattern); + if( uPattern==0 ) break; + + /* There are now 4 possibilities: + ** + ** 1. uPattern is an unescaped match-all character "%", + ** 2. uPattern is an unescaped match-one character "_", + ** 3. uPattern is an unescaped escape character, or + ** 4. uPattern is to be handled as an ordinary character + */ + if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){ + /* Case 1. */ + uint8_t c; + + /* Skip any MATCH_ALL or MATCH_ONE characters that follow a + ** MATCH_ALL. For each MATCH_ONE, skip one character in the + ** test string. + */ + while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){ + if( c==MATCH_ONE ){ + if( *zString==0 ) return 0; + SQLITE_ICU_SKIP_UTF8(zString); + } + zPattern++; + } + + if( *zPattern==0 ) return 1; + + while( *zString ){ + if( icuLikeCompare(zPattern, zString, uEsc) ){ + return 1; + } + SQLITE_ICU_SKIP_UTF8(zString); + } + return 0; + + }else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){ + /* Case 2. */ + if( *zString==0 ) return 0; + SQLITE_ICU_SKIP_UTF8(zString); + + }else if( uPattern==(uint32_t)uEsc && !prevEscape ){ + /* Case 3. */ + prevEscape = 1; + + }else{ + /* Case 4. */ + uint32_t uString; + SQLITE_ICU_READ_UTF8(zString, uString); + uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT); + uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT); + if( uString!=uPattern ){ + return 0; + } + prevEscape = 0; + } + } + + return *zString==0; +} + +/* +** Implementation of the like() SQL function. This function implements +** the build-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B, A). If there is an escape character E, +** +** A LIKE B ESCAPE E +** +** is mapped to like(B, A, E). +*/ +static void icuLikeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA = sqlite3_value_text(argv[0]); + const unsigned char *zB = sqlite3_value_text(argv[1]); + UChar32 uEsc = 0; + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + + + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + int nE= sqlite3_value_bytes(argv[2]); + const unsigned char *zE = sqlite3_value_text(argv[2]); + int i = 0; + if( zE==0 ) return; + U8_NEXT(zE, i, nE, uEsc); + if( i!=nE){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + } + + if( zA && zB ){ + sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); + } +} + +/* +** Function to delete compiled regexp objects. Registered as +** a destructor function with sqlite3_set_auxdata(). +*/ +static void icuRegexpDelete(void *p){ + URegularExpression *pExpr = (URegularExpression *)p; + uregex_close(pExpr); +} + +/* +** Implementation of SQLite REGEXP operator. This scalar function takes +** two arguments. The first is a regular expression pattern to compile +** the second is a string to match against that pattern. If either +** argument is an SQL NULL, then NULL Is returned. Otherwise, the result +** is 1 if the string matches the pattern, or 0 otherwise. +** +** SQLite maps the regexp() function to the regexp() operator such +** that the following two are equivalent: +** +** zString REGEXP zPattern +** regexp(zPattern, zString) +** +** Uses the following ICU regexp APIs: +** +** uregex_open() +** uregex_matches() +** uregex_close() +*/ +static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + UErrorCode status = U_ZERO_ERROR; + URegularExpression *pExpr; + UBool res; + const UChar *zString = sqlite3_value_text16(apArg[1]); + + (void)nArg; /* Unused parameter */ + + /* If the left hand side of the regexp operator is NULL, + ** then the result is also NULL. + */ + if( !zString ){ + return; + } + + pExpr = sqlite3_get_auxdata(p, 0); + if( !pExpr ){ + const UChar *zPattern = sqlite3_value_text16(apArg[0]); + if( !zPattern ){ + return; + } + pExpr = uregex_open(zPattern, -1, 0, 0, &status); + + if( U_SUCCESS(status) ){ + sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); + pExpr = sqlite3_get_auxdata(p, 0); + } + if( !pExpr ){ + icuFunctionError(p, "uregex_open", status); + return; + } + } + + /* Configure the text that the regular expression operates on. */ + uregex_setText(pExpr, zString, -1, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_setText", status); + return; + } + + /* Attempt the match */ + res = uregex_matches(pExpr, 0, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_matches", status); + return; + } + + /* Set the text that the regular expression operates on to a NULL + ** pointer. This is not really necessary, but it is tidier than + ** leaving the regular expression object configured with an invalid + ** pointer after this function returns. + */ + uregex_setText(pExpr, 0, 0, &status); + + /* Return 1 or 0. */ + sqlite3_result_int(p, res ? 1 : 0); +} + +/* +** Implementations of scalar functions for case mapping - upper() and +** lower(). Function upper() converts its input to upper-case (ABC). +** Function lower() converts to lower-case (abc). +** +** ICU provides two types of case mapping, "general" case mapping and +** "language specific". Refer to ICU documentation for the differences +** between the two. +** +** To utilise "general" case mapping, the upper() or lower() scalar +** functions are invoked with one argument: +** +** upper('ABC') -> 'abc' +** lower('abc') -> 'ABC' +** +** To access ICU "language specific" case mapping, upper() or lower() +** should be invoked with two arguments. The second argument is the name +** of the locale to use. Passing an empty string ("") or SQL NULL value +** as the second argument is the same as invoking the 1 argument version +** of upper() or lower(). +** +** lower('I', 'en_us') -> 'i' +** lower('I', 'tr_tr') -> '\u131' (small dotless i) +** +** http://www.icu-project.org/userguide/posix.html#case_mappings +*/ +static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + const UChar *zInput; /* Pointer to input string */ + UChar *zOutput = 0; /* Pointer to output buffer */ + int nInput; /* Size of utf-16 input string in bytes */ + int nOut; /* Size of output buffer in bytes */ + int cnt; + int bToUpper; /* True for toupper(), false for tolower() */ + UErrorCode status; + const char *zLocale = 0; + + assert(nArg==1 || nArg==2); + bToUpper = (sqlite3_user_data(p)!=0); + if( nArg==2 ){ + zLocale = (const char *)sqlite3_value_text(apArg[1]); + } + + zInput = sqlite3_value_text16(apArg[0]); + if( !zInput ){ + return; + } + nOut = nInput = sqlite3_value_bytes16(apArg[0]); + if( nOut==0 ){ + sqlite3_result_text16(p, "", 0, SQLITE_STATIC); + return; + } + + for(cnt=0; cnt<2; cnt++){ + UChar *zNew = sqlite3_realloc(zOutput, nOut); + if( zNew==0 ){ + sqlite3_free(zOutput); + sqlite3_result_error_nomem(p); + return; + } + zOutput = zNew; + status = U_ZERO_ERROR; + if( bToUpper ){ + nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + }else{ + nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + } + + if( U_SUCCESS(status) ){ + sqlite3_result_text16(p, zOutput, nOut, xFree); + }else if( status==U_BUFFER_OVERFLOW_ERROR ){ + assert( cnt==0 ); + continue; + }else{ + icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status); + } + return; + } + assert( 0 ); /* Unreachable */ +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ + +/* +** Collation sequence destructor function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static void icuCollationDel(void *pCtx){ + UCollator *p = (UCollator *)pCtx; + ucol_close(p); +} + +/* +** Collation sequence comparison function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static int icuCollationColl( + void *pCtx, + int nLeft, + const void *zLeft, + int nRight, + const void *zRight +){ + UCollationResult res; + UCollator *p = (UCollator *)pCtx; + res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2); + switch( res ){ + case UCOL_LESS: return -1; + case UCOL_GREATER: return +1; + case UCOL_EQUAL: return 0; + } + assert(!"Unexpected return value from ucol_strcoll()"); + return 0; +} + +/* +** Implementation of the scalar function icu_load_collation(). +** +** This scalar function is used to add ICU collation based collation +** types to an SQLite database connection. It is intended to be called +** as follows: +** +** SELECT icu_load_collation(, ); +** +** Where is a string containing an ICU locale identifier (i.e. +** "en_AU", "tr_TR" etc.) and is the name of the +** collation sequence to create. +*/ +static void icuLoadCollation( + sqlite3_context *p, + int nArg, + sqlite3_value **apArg +){ + sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); + UErrorCode status = U_ZERO_ERROR; + const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ + const char *zName; /* SQL Collation sequence name (eg. "japanese") */ + UCollator *pUCollator; /* ICU library collation object */ + int rc; /* Return code from sqlite3_create_collation_x() */ + + assert(nArg==2); + (void)nArg; /* Unused parameter */ + zLocale = (const char *)sqlite3_value_text(apArg[0]); + zName = (const char *)sqlite3_value_text(apArg[1]); + + if( !zLocale || !zName ){ + return; + } + + pUCollator = ucol_open(zLocale, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "ucol_open", status); + return; + } + assert(p); + + rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, + icuCollationColl, icuCollationDel + ); + if( rc!=SQLITE_OK ){ + ucol_close(pUCollator); + sqlite3_result_error(p, "Error registering collation function", -1); + } +} + +/* +** Register the ICU extension functions with database db. +*/ +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ +# define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) + static const struct IcuScalar { + const char *zName; /* Function name */ + unsigned char nArg; /* Number of arguments */ + unsigned int enc; /* Optimal text encoding */ + unsigned char iContext; /* sqlite3_user_data() context */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } scalars[] = { + {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) + {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, + {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"lower", 1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"like", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc}, + {"like", 3, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc}, +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ + }; + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ + const struct IcuScalar *p = &scalars[i]; + rc = sqlite3_create_function( + db, p->zName, p->nArg, p->enc, + p->iContext ? (void*)db : (void*)0, + p->xFunc, 0, 0 + ); + } + + return rc; +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_icu_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3IcuInit(db); +} +#endif + +#endif + +/************** End of icu.c *************************************************/ +/************** Begin file fts3_icu.c ****************************************/ +/* +** 2007 June 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements a tokenizer for fts3 based on the ICU library. +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +#ifdef SQLITE_ENABLE_ICU + +/* #include */ +/* #include */ +/* #include "fts3_tokenizer.h" */ + +#include +/* #include */ +/* #include */ +#include + +typedef struct IcuTokenizer IcuTokenizer; +typedef struct IcuCursor IcuCursor; + +struct IcuTokenizer { + sqlite3_tokenizer base; + char *zLocale; +}; + +struct IcuCursor { + sqlite3_tokenizer_cursor base; + + UBreakIterator *pIter; /* ICU break-iterator object */ + int nChar; /* Number of UChar elements in pInput */ + UChar *aChar; /* Copy of input using utf-16 encoding */ + int *aOffset; /* Offsets of each character in utf-8 input */ + + int nBuffer; + char *zBuffer; + + int iToken; +}; + +/* +** Create a new tokenizer instance. +*/ +static int icuCreate( + int argc, /* Number of entries in argv[] */ + const char * const *argv, /* Tokenizer creation arguments */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ +){ + IcuTokenizer *p; + int n = 0; + + if( argc>0 ){ + n = strlen(argv[0])+1; + } + p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n); + if( !p ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(IcuTokenizer)); + + if( n ){ + p->zLocale = (char *)&p[1]; + memcpy(p->zLocale, argv[0], n); + } + + *ppTokenizer = (sqlite3_tokenizer *)p; + + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int icuDestroy(sqlite3_tokenizer *pTokenizer){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int icuOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, /* Input string */ + int nInput, /* Length of zInput in bytes */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + IcuCursor *pCsr; + + const int32_t opt = U_FOLD_CASE_DEFAULT; + UErrorCode status = U_ZERO_ERROR; + int nChar; + + UChar32 c; + int iInput = 0; + int iOut = 0; + + *ppCursor = 0; + + if( zInput==0 ){ + nInput = 0; + zInput = ""; + }else if( nInput<0 ){ + nInput = strlen(zInput); + } + nChar = nInput+1; + pCsr = (IcuCursor *)sqlite3_malloc64( + sizeof(IcuCursor) + /* IcuCursor */ + ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ + (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ + ); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(IcuCursor)); + pCsr->aChar = (UChar *)&pCsr[1]; + pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; + + pCsr->aOffset[iOut] = iInput; + U8_NEXT(zInput, iInput, nInput, c); + while( c>0 ){ + int isError = 0; + c = u_foldCase(c, opt); + U16_APPEND(pCsr->aChar, iOut, nChar, c, isError); + if( isError ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->aOffset[iOut] = iInput; + + if( iInputpIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status); + if( !U_SUCCESS(status) ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->nChar = iOut; + + ubrk_first(pCsr->pIter); + *ppCursor = (sqlite3_tokenizer_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to icuOpen(). +*/ +static int icuClose(sqlite3_tokenizer_cursor *pCursor){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + ubrk_close(pCsr->pIter); + sqlite3_free(pCsr->zBuffer); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. +*/ +static int icuNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + + int iStart = 0; + int iEnd = 0; + int nByte = 0; + + while( iStart==iEnd ){ + UChar32 c; + + iStart = ubrk_current(pCsr->pIter); + iEnd = ubrk_next(pCsr->pIter); + if( iEnd==UBRK_DONE ){ + return SQLITE_DONE; + } + + while( iStartaChar, iWhite, pCsr->nChar, c); + if( u_isspace(c) ){ + iStart = iWhite; + }else{ + break; + } + } + assert(iStart<=iEnd); + } + + do { + UErrorCode status = U_ZERO_ERROR; + if( nByte ){ + char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte); + if( !zNew ){ + return SQLITE_NOMEM; + } + pCsr->zBuffer = zNew; + pCsr->nBuffer = nByte; + } + + u_strToUTF8( + pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */ + &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */ + &status /* Output success/failure */ + ); + } while( nByte>pCsr->nBuffer ); + + *ppToken = pCsr->zBuffer; + *pnBytes = nByte; + *piStartOffset = pCsr->aOffset[iStart]; + *piEndOffset = pCsr->aOffset[iEnd]; + *piPosition = pCsr->iToken++; + + return SQLITE_OK; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module icuTokenizerModule = { + 0, /* iVersion */ + icuCreate, /* xCreate */ + icuDestroy, /* xCreate */ + icuOpen, /* xOpen */ + icuClose, /* xClose */ + icuNext, /* xNext */ + 0, /* xLanguageid */ +}; + +/* +** Set *ppModule to point at the implementation of the ICU tokenizer. +*/ +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &icuTokenizerModule; +} + +#endif /* defined(SQLITE_ENABLE_ICU) */ +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_icu.c ********************************************/ +/************** Begin file sqlite3rbu.c **************************************/ +/* +** 2014 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** +** OVERVIEW +** +** The RBU extension requires that the RBU update be packaged as an +** SQLite database. The tables it expects to find are described in +** sqlite3rbu.h. Essentially, for each table xyz in the target database +** that the user wishes to write to, a corresponding data_xyz table is +** created in the RBU database and populated with one row for each row to +** update, insert or delete from the target table. +** +** The update proceeds in three stages: +** +** 1) The database is updated. The modified database pages are written +** to a *-oal file. A *-oal file is just like a *-wal file, except +** that it is named "-oal" instead of "-wal". +** Because regular SQLite clients do not look for file named +** "-oal", they go on using the original database in +** rollback mode while the *-oal file is being generated. +** +** During this stage RBU does not update the database by writing +** directly to the target tables. Instead it creates "imposter" +** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses +** to update each b-tree individually. All updates required by each +** b-tree are completed before moving on to the next, and all +** updates are done in sorted key order. +** +** 2) The "-oal" file is moved to the equivalent "-wal" +** location using a call to rename(2). Before doing this the RBU +** module takes an EXCLUSIVE lock on the database file, ensuring +** that there are no other active readers. +** +** Once the EXCLUSIVE lock is released, any other database readers +** detect the new *-wal file and read the database in wal mode. At +** this point they see the new version of the database - including +** the updates made as part of the RBU update. +** +** 3) The new *-wal file is checkpointed. This proceeds in the same way +** as a regular database checkpoint, except that a single frame is +** checkpointed each time sqlite3rbu_step() is called. If the RBU +** handle is closed before the entire *-wal file is checkpointed, +** the checkpoint progress is saved in the RBU database and the +** checkpoint can be resumed by another RBU client at some point in +** the future. +** +** POTENTIAL PROBLEMS +** +** The rename() call might not be portable. And RBU is not currently +** syncing the directory after renaming the file. +** +** When state is saved, any commit to the *-oal file and the commit to +** the RBU update database are not atomic. So if the power fails at the +** wrong moment they might get out of sync. As the main database will be +** committed before the RBU update database this will likely either just +** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE +** constraint violations). +** +** If some client does modify the target database mid RBU update, or some +** other error occurs, the RBU extension will keep throwing errors. It's +** not really clear how to get out of this state. The system could just +** by delete the RBU update database and *-oal file and have the device +** download the update again and start over. +** +** At present, for an UPDATE, both the new.* and old.* records are +** collected in the rbu_xyz table. And for both UPDATEs and DELETEs all +** fields are collected. This means we're probably writing a lot more +** data to disk when saving the state of an ongoing update to the RBU +** update database than is strictly necessary. +** +*/ + +/* #include */ +/* #include */ +/* #include */ + +/* #include "sqlite3.h" */ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) +/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/ +/************** Begin file sqlite3rbu.h **************************************/ +/* +** 2014 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the public interface for the RBU extension. +*/ + +/* +** SUMMARY +** +** Writing a transaction containing a large number of operations on +** b-tree indexes that are collectively larger than the available cache +** memory can be very inefficient. +** +** The problem is that in order to update a b-tree, the leaf page (at least) +** containing the entry being inserted or deleted must be modified. If the +** working set of leaves is larger than the available cache memory, then a +** single leaf that is modified more than once as part of the transaction +** may be loaded from or written to the persistent media multiple times. +** Additionally, because the index updates are likely to be applied in +** random order, access to pages within the database is also likely to be in +** random order, which is itself quite inefficient. +** +** One way to improve the situation is to sort the operations on each index +** by index key before applying them to the b-tree. This leads to an IO +** pattern that resembles a single linear scan through the index b-tree, +** and all but guarantees each modified leaf page is loaded and stored +** exactly once. SQLite uses this trick to improve the performance of +** CREATE INDEX commands. This extension allows it to be used to improve +** the performance of large transactions on existing databases. +** +** Additionally, this extension allows the work involved in writing the +** large transaction to be broken down into sub-transactions performed +** sequentially by separate processes. This is useful if the system cannot +** guarantee that a single update process will run for long enough to apply +** the entire update, for example because the update is being applied on a +** mobile device that is frequently rebooted. Even after the writer process +** has committed one or more sub-transactions, other database clients continue +** to read from the original database snapshot. In other words, partially +** applied transactions are not visible to other clients. +** +** "RBU" stands for "Resumable Bulk Update". As in a large database update +** transmitted via a wireless network to a mobile device. A transaction +** applied using this extension is hence refered to as an "RBU update". +** +** +** LIMITATIONS +** +** An "RBU update" transaction is subject to the following limitations: +** +** * The transaction must consist of INSERT, UPDATE and DELETE operations +** only. +** +** * INSERT statements may not use any default values. +** +** * UPDATE and DELETE statements must identify their target rows by +** non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY +** KEY fields may not be updated or deleted. If the table being written +** has no PRIMARY KEY, affected rows must be identified by rowid. +** +** * UPDATE statements may not modify PRIMARY KEY columns. +** +** * No triggers will be fired. +** +** * No foreign key violations are detected or reported. +** +** * CHECK constraints are not enforced. +** +** * No constraint handling mode except for "OR ROLLBACK" is supported. +** +** +** PREPARATION +** +** An "RBU update" is stored as a separate SQLite database. A database +** containing an RBU update is an "RBU database". For each table in the +** target database to be updated, the RBU database should contain a table +** named "data_" containing the same set of columns as the +** target table, and one more - "rbu_control". The data_% table should +** have no PRIMARY KEY or UNIQUE constraints, but each column should have +** the same type as the corresponding column in the target database. +** The "rbu_control" column should have no type at all. For example, if +** the target database contains: +** +** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE); +** +** Then the RBU database should contain: +** +** CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control); +** +** The order of the columns in the data_% table does not matter. +** +** Instead of a regular table, the RBU database may also contain virtual +** tables or views named using the data_ naming scheme. +** +** Instead of the plain data_ naming scheme, RBU database tables +** may also be named data_, where is any sequence +** of zero or more numeric characters (0-9). This can be significant because +** tables within the RBU database are always processed in order sorted by +** name. By judicious selection of the portion of the names +** of the RBU tables the user can therefore control the order in which they +** are processed. This can be useful, for example, to ensure that "external +** content" FTS4 tables are updated before their underlying content tables. +** +** If the target database table is a virtual table or a table that has no +** PRIMARY KEY declaration, the data_% table must also contain a column +** named "rbu_rowid". This column is mapped to the table's implicit primary +** key column - "rowid". Virtual tables for which the "rowid" column does +** not function like a primary key value cannot be updated using RBU. For +** example, if the target db contains either of the following: +** +** CREATE VIRTUAL TABLE x1 USING fts3(a, b); +** CREATE TABLE x1(a, b) +** +** then the RBU database should contain: +** +** CREATE TABLE data_x1(a, b, rbu_rowid, rbu_control); +** +** All non-hidden columns (i.e. all columns matched by "SELECT *") of the +** target table must be present in the input table. For virtual tables, +** hidden columns are optional - they are updated by RBU if present in +** the input table, or not otherwise. For example, to write to an fts4 +** table with a hidden languageid column such as: +** +** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid'); +** +** Either of the following input table schemas may be used: +** +** CREATE TABLE data_ft1(a, b, langid, rbu_rowid, rbu_control); +** CREATE TABLE data_ft1(a, b, rbu_rowid, rbu_control); +** +** For each row to INSERT into the target database as part of the RBU +** update, the corresponding data_% table should contain a single record +** with the "rbu_control" column set to contain integer value 0. The +** other columns should be set to the values that make up the new record +** to insert. +** +** If the target database table has an INTEGER PRIMARY KEY, it is not +** possible to insert a NULL value into the IPK column. Attempting to +** do so results in an SQLITE_MISMATCH error. +** +** For each row to DELETE from the target database as part of the RBU +** update, the corresponding data_% table should contain a single record +** with the "rbu_control" column set to contain integer value 1. The +** real primary key values of the row to delete should be stored in the +** corresponding columns of the data_% table. The values stored in the +** other columns are not used. +** +** For each row to UPDATE from the target database as part of the RBU +** update, the corresponding data_% table should contain a single record +** with the "rbu_control" column set to contain a value of type text. +** The real primary key values identifying the row to update should be +** stored in the corresponding columns of the data_% table row, as should +** the new values of all columns being update. The text value in the +** "rbu_control" column must contain the same number of characters as +** there are columns in the target database table, and must consist entirely +** of 'x' and '.' characters (or in some special cases 'd' - see below). For +** each column that is being updated, the corresponding character is set to +** 'x'. For those that remain as they are, the corresponding character of the +** rbu_control value should be set to '.'. For example, given the tables +** above, the update statement: +** +** UPDATE t1 SET c = 'usa' WHERE a = 4; +** +** is represented by the data_t1 row created by: +** +** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..x'); +** +** Instead of an 'x' character, characters of the rbu_control value specified +** for UPDATEs may also be set to 'd'. In this case, instead of updating the +** target table with the value stored in the corresponding data_% column, the +** user-defined SQL function "rbu_delta()" is invoked and the result stored in +** the target table column. rbu_delta() is invoked with two arguments - the +** original value currently stored in the target table column and the +** value specified in the data_xxx table. +** +** For example, this row: +** +** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d'); +** +** is similar to an UPDATE statement such as: +** +** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4; +** +** Finally, if an 'f' character appears in place of a 'd' or 's' in an +** ota_control string, the contents of the data_xxx table column is assumed +** to be a "fossil delta" - a patch to be applied to a blob value in the +** format used by the fossil source-code management system. In this case +** the existing value within the target database table must be of type BLOB. +** It is replaced by the result of applying the specified fossil delta to +** itself. +** +** If the target database table is a virtual table or a table with no PRIMARY +** KEY, the rbu_control value should not include a character corresponding +** to the rbu_rowid value. For example, this: +** +** INSERT INTO data_ft1(a, b, rbu_rowid, rbu_control) +** VALUES(NULL, 'usa', 12, '.x'); +** +** causes a result similar to: +** +** UPDATE ft1 SET b = 'usa' WHERE rowid = 12; +** +** The data_xxx tables themselves should have no PRIMARY KEY declarations. +** However, RBU is more efficient if reading the rows in from each data_xxx +** table in "rowid" order is roughly the same as reading them sorted by +** the PRIMARY KEY of the corresponding target database table. In other +** words, rows should be sorted using the destination table PRIMARY KEY +** fields before they are inserted into the data_xxx tables. +** +** USAGE +** +** The API declared below allows an application to apply an RBU update +** stored on disk to an existing target database. Essentially, the +** application: +** +** 1) Opens an RBU handle using the sqlite3rbu_open() function. +** +** 2) Registers any required virtual table modules with the database +** handle returned by sqlite3rbu_db(). Also, if required, register +** the rbu_delta() implementation. +** +** 3) Calls the sqlite3rbu_step() function one or more times on +** the new handle. Each call to sqlite3rbu_step() performs a single +** b-tree operation, so thousands of calls may be required to apply +** a complete update. +** +** 4) Calls sqlite3rbu_close() to close the RBU update handle. If +** sqlite3rbu_step() has been called enough times to completely +** apply the update to the target database, then the RBU database +** is marked as fully applied. Otherwise, the state of the RBU +** update application is saved in the RBU database for later +** resumption. +** +** See comments below for more detail on APIs. +** +** If an update is only partially applied to the target database by the +** time sqlite3rbu_close() is called, various state information is saved +** within the RBU database. This allows subsequent processes to automatically +** resume the RBU update from where it left off. +** +** To remove all RBU extension state information, returning an RBU database +** to its original contents, it is sufficient to drop all tables that begin +** with the prefix "rbu_" +** +** DATABASE LOCKING +** +** An RBU update may not be applied to a database in WAL mode. Attempting +** to do so is an error (SQLITE_ERROR). +** +** While an RBU handle is open, a SHARED lock may be held on the target +** database file. This means it is possible for other clients to read the +** database, but not to write it. +** +** If an RBU update is started and then suspended before it is completed, +** then an external client writes to the database, then attempting to resume +** the suspended RBU update is also an error (SQLITE_BUSY). +*/ + +#ifndef _SQLITE3RBU_H +#define _SQLITE3RBU_H + +/* #include "sqlite3.h" ** Required for error code definitions ** */ + +#if 0 +extern "C" { +#endif + +typedef struct sqlite3rbu sqlite3rbu; + +/* +** Open an RBU handle. +** +** Argument zTarget is the path to the target database. Argument zRbu is +** the path to the RBU database. Each call to this function must be matched +** by a call to sqlite3rbu_close(). When opening the databases, RBU passes +** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget +** or zRbu begin with "file:", it will be interpreted as an SQLite +** database URI, not a regular file name. +** +** If the zState argument is passed a NULL value, the RBU extension stores +** the current state of the update (how many rows have been updated, which +** indexes are yet to be updated etc.) within the RBU database itself. This +** can be convenient, as it means that the RBU application does not need to +** organize removing a separate state file after the update is concluded. +** Or, if zState is non-NULL, it must be a path to a database file in which +** the RBU extension can store the state of the update. +** +** When resuming an RBU update, the zState argument must be passed the same +** value as when the RBU update was started. +** +** Once the RBU update is finished, the RBU extension does not +** automatically remove any zState database file, even if it created it. +** +** By default, RBU uses the default VFS to access the files on disk. To +** use a VFS other than the default, an SQLite "file:" URI containing a +** "vfs=..." option may be passed as the zTarget option. +** +** IMPORTANT NOTE FOR ZIPVFS USERS: The RBU extension works with all of +** SQLite's built-in VFSs, including the multiplexor VFS. However it does +** not work out of the box with zipvfs. Refer to the comment describing +** the zipvfs_create_vfs() API below for details on using RBU with zipvfs. +*/ +SQLITE_API sqlite3rbu *sqlite3rbu_open( + const char *zTarget, + const char *zRbu, + const char *zState +); + +/* +** Open an RBU handle to perform an RBU vacuum on database file zTarget. +** An RBU vacuum is similar to SQLite's built-in VACUUM command, except +** that it can be suspended and resumed like an RBU update. +** +** The second argument to this function identifies a database in which +** to store the state of the RBU vacuum operation if it is suspended. The +** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum +** operation, the state database should either not exist or be empty +** (contain no tables). If an RBU vacuum is suspended by calling +** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has +** returned SQLITE_DONE, the vacuum state is stored in the state database. +** The vacuum can be resumed by calling this function to open a new RBU +** handle specifying the same target and state databases. +** +** If the second argument passed to this function is NULL, then the +** name of the state database is "-vacuum", where +** is the name of the target database file. In this case, on UNIX, if the +** state database is not already present in the file-system, it is created +** with the same permissions as the target db is made. +** +** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the +** state database ends with "-vactmp". This name is reserved for internal +** use. +** +** This function does not delete the state database after an RBU vacuum +** is completed, even if it created it. However, if the call to +** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents +** of the state tables within the state database are zeroed. This way, +** the next call to sqlite3rbu_vacuum() opens a handle that starts a +** new RBU vacuum operation. +** +** As with sqlite3rbu_open(), Zipvfs users should rever to the comment +** describing the sqlite3rbu_create_vfs() API function below for +** a description of the complications associated with using RBU with +** zipvfs databases. +*/ +SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( + const char *zTarget, + const char *zState +); + +/* +** Configure a limit for the amount of temp space that may be used by +** the RBU handle passed as the first argument. The new limit is specified +** in bytes by the second parameter. If it is positive, the limit is updated. +** If the second parameter to this function is passed zero, then the limit +** is removed entirely. If the second parameter is negative, the limit is +** not modified (this is useful for querying the current limit). +** +** In all cases the returned value is the current limit in bytes (zero +** indicates unlimited). +** +** If the temp space limit is exceeded during operation, an SQLITE_FULL +** error is returned. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64); + +/* +** Return the current amount of temp file space, in bytes, currently used by +** the RBU handle passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*); + +/* +** Internally, each RBU connection uses a separate SQLite database +** connection to access the target and rbu update databases. This +** API allows the application direct access to these database handles. +** +** The first argument passed to this function must be a valid, open, RBU +** handle. The second argument should be passed zero to access the target +** database handle, or non-zero to access the rbu update database handle. +** Accessing the underlying database handles may be useful in the +** following scenarios: +** +** * If any target tables are virtual tables, it may be necessary to +** call sqlite3_create_module() on the target database handle to +** register the required virtual table implementations. +** +** * If the data_xxx tables in the RBU source database are virtual +** tables, the application may need to call sqlite3_create_module() on +** the rbu update db handle to any required virtual table +** implementations. +** +** * If the application uses the "rbu_delta()" feature described above, +** it must use sqlite3_create_function() or similar to register the +** rbu_delta() implementation with the target database handle. +** +** If an error has occurred, either while opening or stepping the RBU object, +** this function may return NULL. The error code and message may be collected +** when sqlite3rbu_close() is called. +** +** Database handles returned by this function remain valid until the next +** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db(). +*/ +SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu); + +/* +** Do some work towards applying the RBU update to the target db. +** +** Return SQLITE_DONE if the update has been completely applied, or +** SQLITE_OK if no error occurs but there remains work to do to apply +** the RBU update. If an error does occur, some other error code is +** returned. +** +** Once a call to sqlite3rbu_step() has returned a value other than +** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops +** that immediately return the same value. +*/ +SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu); + +/* +** Force RBU to save its state to disk. +** +** If a power failure or application crash occurs during an update, following +** system recovery RBU may resume the update from the point at which the state +** was last saved. In other words, from the most recent successful call to +** sqlite3rbu_close() or this function. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); + +/* +** Close an RBU handle. +** +** If the RBU update has been completely applied, mark the RBU database +** as fully applied. Otherwise, assuming no error has occurred, save the +** current state of the RBU update appliation to the RBU database. +** +** If an error has already occurred as part of an sqlite3rbu_step() +** or sqlite3rbu_open() call, or if one occurs within this function, an +** SQLite error code is returned. Additionally, if pzErrmsg is not NULL, +** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted +** English language error message. It is the responsibility of the caller to +** eventually free any such buffer using sqlite3_free(). +** +** Otherwise, if no error occurs, this function returns SQLITE_OK if the +** update has been partially applied, or SQLITE_DONE if it has been +** completely applied. +*/ +SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); + +/* +** Return the total number of key-value operations (inserts, deletes or +** updates) that have been performed on the target database since the +** current RBU update was started. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); + +/* +** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) +** progress indications for the two stages of an RBU update. This API may +** be useful for driving GUI progress indicators and similar. +** +** An RBU update is divided into two stages: +** +** * Stage 1, in which changes are accumulated in an oal/wal file, and +** * Stage 2, in which the contents of the wal file are copied into the +** main database. +** +** The update is visible to non-RBU clients during stage 2. During stage 1 +** non-RBU reader clients may see the original database. +** +** If this API is called during stage 2 of the update, output variable +** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo) +** to a value between 0 and 10000 to indicate the permyriadage progress of +** stage 2. A value of 5000 indicates that stage 2 is half finished, +** 9000 indicates that it is 90% finished, and so on. +** +** If this API is called during stage 1 of the update, output variable +** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The +** value to which (*pnOne) is set depends on whether or not the RBU +** database contains an "rbu_count" table. The rbu_count table, if it +** exists, must contain the same columns as the following: +** +** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; +** +** There must be one row in the table for each source (data_xxx) table within +** the RBU database. The 'tbl' column should contain the name of the source +** table. The 'cnt' column should contain the number of rows within the +** source table. +** +** If the rbu_count table is present and populated correctly and this +** API is called during stage 1, the *pnOne output variable is set to the +** permyriadage progress of the same stage. If the rbu_count table does +** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count +** table exists but is not correctly populated, the value of the *pnOne +** output variable during stage 1 is undefined. +*/ +SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo); + +/* +** Obtain an indication as to the current stage of an RBU update or vacuum. +** This function always returns one of the SQLITE_RBU_STATE_XXX constants +** defined in this file. Return values should be interpreted as follows: +** +** SQLITE_RBU_STATE_OAL: +** RBU is currently building a *-oal file. The next call to sqlite3rbu_step() +** may either add further data to the *-oal file, or compute data that will +** be added by a subsequent call. +** +** SQLITE_RBU_STATE_MOVE: +** RBU has finished building the *-oal file. The next call to sqlite3rbu_step() +** will move the *-oal file to the equivalent *-wal path. If the current +** operation is an RBU update, then the updated version of the database +** file will become visible to ordinary SQLite clients following the next +** call to sqlite3rbu_step(). +** +** SQLITE_RBU_STATE_CHECKPOINT: +** RBU is currently performing an incremental checkpoint. The next call to +** sqlite3rbu_step() will copy a page of data from the *-wal file into +** the target database file. +** +** SQLITE_RBU_STATE_DONE: +** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step() +** will immediately return SQLITE_DONE. +** +** SQLITE_RBU_STATE_ERROR: +** An error has occurred. Any subsequent calls to sqlite3rbu_step() will +** immediately return the SQLite error code associated with the error. +*/ +#define SQLITE_RBU_STATE_OAL 1 +#define SQLITE_RBU_STATE_MOVE 2 +#define SQLITE_RBU_STATE_CHECKPOINT 3 +#define SQLITE_RBU_STATE_DONE 4 +#define SQLITE_RBU_STATE_ERROR 5 + +SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); + +/* +** As part of applying an RBU update or performing an RBU vacuum operation, +** the system must at one point move the *-oal file to the equivalent *-wal +** path. Normally, it does this by invoking POSIX function rename(2) directly. +** Except on WINCE platforms, where it uses win32 API MoveFileW(). This +** function may be used to register a callback that the RBU module will invoke +** instead of one of these APIs. +** +** If a callback is registered with an RBU handle, it invokes it instead +** of rename(2) when it needs to move a file within the file-system. The +** first argument passed to the xRename() callback is a copy of the second +** argument (pArg) passed to this function. The second is the full path +** to the file to move and the third the full path to which it should be +** moved. The callback function should return SQLITE_OK to indicate +** success. If an error occurs, it should return an SQLite error code. +** In this case the RBU operation will be abandoned and the error returned +** to the RBU user. +** +** Passing a NULL pointer in place of the xRename argument to this function +** restores the default behaviour. +*/ +SQLITE_API void sqlite3rbu_rename_handler( + sqlite3rbu *pRbu, + void *pArg, + int (*xRename)(void *pArg, const char *zOld, const char *zNew) +); + + +/* +** Create an RBU VFS named zName that accesses the underlying file-system +** via existing VFS zParent. Or, if the zParent parameter is passed NULL, +** then the new RBU VFS uses the default system VFS to access the file-system. +** The new object is registered as a non-default VFS with SQLite before +** returning. +** +** Part of the RBU implementation uses a custom VFS object. Usually, this +** object is created and deleted automatically by RBU. +** +** The exception is for applications that also use zipvfs. In this case, +** the custom VFS must be explicitly created by the user before the RBU +** handle is opened. The RBU VFS should be installed so that the zipvfs +** VFS uses the RBU VFS, which in turn uses any other VFS layers in use +** (for example multiplexor) to access the file-system. For example, +** to assemble an RBU enabled VFS stack that uses both zipvfs and +** multiplexor (error checking omitted): +** +** // Create a VFS named "multiplex" (not the default). +** sqlite3_multiplex_initialize(0, 0); +** +** // Create an rbu VFS named "rbu" that uses multiplexor. If the +** // second argument were replaced with NULL, the "rbu" VFS would +** // access the file-system via the system default VFS, bypassing the +** // multiplexor. +** sqlite3rbu_create_vfs("rbu", "multiplex"); +** +** // Create a zipvfs VFS named "zipvfs" that uses rbu. +** zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector); +** +** // Make zipvfs the default VFS. +** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1); +** +** Because the default VFS created above includes a RBU functionality, it +** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack +** that does not include the RBU layer results in an error. +** +** The overhead of adding the "rbu" VFS to the system is negligible for +** non-RBU users. There is no harm in an application accessing the +** file-system via "rbu" all the time, even if it only uses RBU functionality +** occasionally. +*/ +SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent); + +/* +** Deregister and destroy an RBU vfs created by an earlier call to +** sqlite3rbu_create_vfs(). +** +** VFS objects are not reference counted. If a VFS object is destroyed +** before all database handles that use it have been closed, the results +** are undefined. +*/ +SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName); + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* _SQLITE3RBU_H */ + +/************** End of sqlite3rbu.h ******************************************/ +/************** Continuing where we left off in sqlite3rbu.c *****************/ + +#if defined(_WIN32_WCE) +/* #include "windows.h" */ +#endif + +/* Maximum number of prepared UPDATE statements held by this module */ +#define SQLITE_RBU_UPDATE_CACHESIZE 16 + +/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM +** to enable checksum verification. +*/ +#ifndef RBU_ENABLE_DELTA_CKSUM +# define RBU_ENABLE_DELTA_CKSUM 0 +#endif + +/* +** Swap two objects of type TYPE. +*/ +#if !defined(SQLITE_AMALGAMATION) +# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} +#endif + +/* +** Name of the URI option that causes RBU to take an exclusive lock as +** part of the incremental checkpoint operation. +*/ +#define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint" + + +/* +** The rbu_state table is used to save the state of a partially applied +** update so that it can be resumed later. The table consists of integer +** keys mapped to values as follows: +** +** RBU_STATE_STAGE: +** May be set to integer values 1, 2, 4 or 5. As follows: +** 1: the *-rbu file is currently under construction. +** 2: the *-rbu file has been constructed, but not yet moved +** to the *-wal path. +** 4: the checkpoint is underway. +** 5: the rbu update has been checkpointed. +** +** RBU_STATE_TBL: +** Only valid if STAGE==1. The target database name of the table +** currently being written. +** +** RBU_STATE_IDX: +** Only valid if STAGE==1. The target database name of the index +** currently being written, or NULL if the main table is currently being +** updated. +** +** RBU_STATE_ROW: +** Only valid if STAGE==1. Number of rows already processed for the current +** table/index. +** +** RBU_STATE_PROGRESS: +** Trbul number of sqlite3rbu_step() calls made so far as part of this +** rbu update. +** +** RBU_STATE_CKPT: +** Valid if STAGE==4. The 64-bit checksum associated with the wal-index +** header created by recovering the *-wal file. This is used to detect +** cases when another client appends frames to the *-wal file in the +** middle of an incremental checkpoint (an incremental checkpoint cannot +** be continued if this happens). +** +** RBU_STATE_COOKIE: +** Valid if STAGE==1. The current change-counter cookie value in the +** target db file. +** +** RBU_STATE_OALSZ: +** Valid if STAGE==1. The size in bytes of the *-oal file. +** +** RBU_STATE_DATATBL: +** Only valid if STAGE==1. The RBU database name of the table +** currently being read. +*/ +#define RBU_STATE_STAGE 1 +#define RBU_STATE_TBL 2 +#define RBU_STATE_IDX 3 +#define RBU_STATE_ROW 4 +#define RBU_STATE_PROGRESS 5 +#define RBU_STATE_CKPT 6 +#define RBU_STATE_COOKIE 7 +#define RBU_STATE_OALSZ 8 +#define RBU_STATE_PHASEONESTEP 9 +#define RBU_STATE_DATATBL 10 + +#define RBU_STAGE_OAL 1 +#define RBU_STAGE_MOVE 2 +#define RBU_STAGE_CAPTURE 3 +#define RBU_STAGE_CKPT 4 +#define RBU_STAGE_DONE 5 + + +#define RBU_CREATE_STATE \ + "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" + +typedef struct RbuFrame RbuFrame; +typedef struct RbuObjIter RbuObjIter; +typedef struct RbuState RbuState; +typedef struct RbuSpan RbuSpan; +typedef struct rbu_vfs rbu_vfs; +typedef struct rbu_file rbu_file; +typedef struct RbuUpdateStmt RbuUpdateStmt; + +#if !defined(SQLITE_AMALGAMATION) +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +typedef sqlite3_int64 i64; +#endif + +/* +** These values must match the values defined in wal.c for the equivalent +** locks. These are not magic numbers as they are part of the SQLite file +** format. +*/ +#define WAL_LOCK_WRITE 0 +#define WAL_LOCK_CKPT 1 +#define WAL_LOCK_READ0 3 + +#define SQLITE_FCNTL_RBUCNT 5149216 + +/* +** A structure to store values read from the rbu_state table in memory. +*/ +struct RbuState { + int eStage; + char *zTbl; + char *zDataTbl; + char *zIdx; + i64 iWalCksum; + int nRow; + i64 nProgress; + u32 iCookie; + i64 iOalSz; + i64 nPhaseOneStep; +}; + +struct RbuUpdateStmt { + char *zMask; /* Copy of update mask used with pUpdate */ + sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ + RbuUpdateStmt *pNext; +}; + +struct RbuSpan { + const char *zSpan; + int nSpan; +}; + +/* +** An iterator of this type is used to iterate through all objects in +** the target database that require updating. For each such table, the +** iterator visits, in order: +** +** * the table itself, +** * each index of the table (zero or more points to visit), and +** * a special "cleanup table" state. +** +** abIndexed: +** If the table has no indexes on it, abIndexed is set to NULL. Otherwise, +** it points to an array of flags nTblCol elements in size. The flag is +** set for each column that is either a part of the PK or a part of an +** index. Or clear otherwise. +** +** If there are one or more partial indexes on the table, all fields of +** this array set set to 1. This is because in that case, the module has +** no way to tell which fields will be required to add and remove entries +** from the partial indexes. +** +*/ +struct RbuObjIter { + sqlite3_stmt *pTblIter; /* Iterate through tables */ + sqlite3_stmt *pIdxIter; /* Index iterator */ + int nTblCol; /* Size of azTblCol[] array */ + char **azTblCol; /* Array of unquoted target column names */ + char **azTblType; /* Array of target column types */ + int *aiSrcOrder; /* src table col -> target table col */ + u8 *abTblPk; /* Array of flags, set on target PK columns */ + u8 *abNotNull; /* Array of flags, set on NOT NULL columns */ + u8 *abIndexed; /* Array of flags, set on indexed & PK cols */ + int eType; /* Table type - an RBU_PK_XXX value */ + + /* Output variables. zTbl==0 implies EOF. */ + int bCleanup; /* True in "cleanup" state */ + const char *zTbl; /* Name of target db table */ + const char *zDataTbl; /* Name of rbu db table (or null) */ + const char *zIdx; /* Name of target db index (or null) */ + int iTnum; /* Root page of current object */ + int iPkTnum; /* If eType==EXTERNAL, root of PK index */ + int bUnique; /* Current index is unique */ + int nIndex; /* Number of aux. indexes on table zTbl */ + + /* Statements created by rbuObjIterPrepareAll() */ + int nCol; /* Number of columns in current object */ + sqlite3_stmt *pSelect; /* Source data */ + sqlite3_stmt *pInsert; /* Statement for INSERT operations */ + sqlite3_stmt *pDelete; /* Statement for DELETE ops */ + sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ + int nIdxCol; + RbuSpan *aIdxCol; + char *zIdxSql; + + /* Last UPDATE used (for PK b-tree updates only), or NULL. */ + RbuUpdateStmt *pRbuUpdate; +}; + +/* +** Values for RbuObjIter.eType +** +** 0: Table does not exist (error) +** 1: Table has an implicit rowid. +** 2: Table has an explicit IPK column. +** 3: Table has an external PK index. +** 4: Table is WITHOUT ROWID. +** 5: Table is a virtual table. +*/ +#define RBU_PK_NOTABLE 0 +#define RBU_PK_NONE 1 +#define RBU_PK_IPK 2 +#define RBU_PK_EXTERNAL 3 +#define RBU_PK_WITHOUT_ROWID 4 +#define RBU_PK_VTAB 5 + + +/* +** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs +** one of the following operations. +*/ +#define RBU_INSERT 1 /* Insert on a main table b-tree */ +#define RBU_DELETE 2 /* Delete a row from a main table b-tree */ +#define RBU_REPLACE 3 /* Delete and then insert a row */ +#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */ +#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */ + +#define RBU_UPDATE 6 /* Update a row in a main table b-tree */ + +/* +** A single step of an incremental checkpoint - frame iWalFrame of the wal +** file should be copied to page iDbPage of the database file. +*/ +struct RbuFrame { + u32 iDbPage; + u32 iWalFrame; +}; + +/* +** RBU handle. +** +** nPhaseOneStep: +** If the RBU database contains an rbu_count table, this value is set to +** a running estimate of the number of b-tree operations required to +** finish populating the *-oal file. This allows the sqlite3_bp_progress() +** API to calculate the permyriadage progress of populating the *-oal file +** using the formula: +** +** permyriadage = (10000 * nProgress) / nPhaseOneStep +** +** nPhaseOneStep is initialized to the sum of: +** +** nRow * (nIndex + 1) +** +** for all source tables in the RBU database, where nRow is the number +** of rows in the source table and nIndex the number of indexes on the +** corresponding target database table. +** +** This estimate is accurate if the RBU update consists entirely of +** INSERT operations. However, it is inaccurate if: +** +** * the RBU update contains any UPDATE operations. If the PK specified +** for an UPDATE operation does not exist in the target table, then +** no b-tree operations are required on index b-trees. Or if the +** specified PK does exist, then (nIndex*2) such operations are +** required (one delete and one insert on each index b-tree). +** +** * the RBU update contains any DELETE operations for which the specified +** PK does not exist. In this case no operations are required on index +** b-trees. +** +** * the RBU update contains REPLACE operations. These are similar to +** UPDATE operations. +** +** nPhaseOneStep is updated to account for the conditions above during the +** first pass of each source table. The updated nPhaseOneStep value is +** stored in the rbu_state table if the RBU update is suspended. +*/ +struct sqlite3rbu { + int eStage; /* Value of RBU_STATE_STAGE field */ + sqlite3 *dbMain; /* target database handle */ + sqlite3 *dbRbu; /* rbu database handle */ + char *zTarget; /* Path to target db */ + char *zRbu; /* Path to rbu db */ + char *zState; /* Path to state db (or NULL if zRbu) */ + char zStateDb[5]; /* Db name for state ("stat" or "main") */ + int rc; /* Value returned by last rbu_step() call */ + char *zErrmsg; /* Error message if rc!=SQLITE_OK */ + int nStep; /* Rows processed for current object */ + int nProgress; /* Rows processed for all objects */ + RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ + const char *zVfsName; /* Name of automatically created rbu vfs */ + rbu_file *pTargetFd; /* File handle open on target db */ + int nPagePerSector; /* Pages per sector for pTargetFd */ + i64 iOalSz; + i64 nPhaseOneStep; + void *pRenameArg; + int (*xRename)(void*, const char*, const char*); + + /* The following state variables are used as part of the incremental + ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding + ** function rbuSetupCheckpoint() for details. */ + u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ + u32 mLock; + int nFrame; /* Entries in aFrame[] array */ + int nFrameAlloc; /* Allocated size of aFrame[] array */ + RbuFrame *aFrame; + int pgsz; + u8 *aBuf; + i64 iWalCksum; + i64 szTemp; /* Current size of all temp files in use */ + i64 szTempLimit; /* Total size limit for temp files */ + + /* Used in RBU vacuum mode only */ + int nRbu; /* Number of RBU VFS in the stack */ + rbu_file *pRbuFd; /* Fd for main db of dbRbu */ +}; + +/* +** An rbu VFS is implemented using an instance of this structure. +** +** Variable pRbu is only non-NULL for automatically created RBU VFS objects. +** It is NULL for RBU VFS objects created explicitly using +** sqlite3rbu_create_vfs(). It is used to track the total amount of temp +** space used by the RBU handle. +*/ +struct rbu_vfs { + sqlite3_vfs base; /* rbu VFS shim methods */ + sqlite3_vfs *pRealVfs; /* Underlying VFS */ + sqlite3_mutex *mutex; /* Mutex to protect pMain */ + sqlite3rbu *pRbu; /* Owner RBU object */ + rbu_file *pMain; /* List of main db files */ + rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */ +}; + +/* +** Each file opened by an rbu VFS is represented by an instance of +** the following structure. +** +** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable +** "sz" is set to the current size of the database file. +*/ +struct rbu_file { + sqlite3_file base; /* sqlite3_file methods */ + sqlite3_file *pReal; /* Underlying file handle */ + rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ + sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ + i64 sz; /* Size of file in bytes (temp only) */ + + int openFlags; /* Flags this file was opened with */ + u32 iCookie; /* Cookie value for main db files */ + u8 iWriteVer; /* "write-version" value for main db files */ + u8 bNolock; /* True to fail EXCLUSIVE locks */ + + int nShm; /* Number of entries in apShm[] array */ + char **apShm; /* Array of mmap'd *-shm regions */ + char *zDel; /* Delete this when closing file */ + + const char *zWal; /* Wal filename for this main db file */ + rbu_file *pWalFd; /* Wal file descriptor for this main db */ + rbu_file *pMainNext; /* Next MAIN_DB file */ + rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */ +}; + +/* +** True for an RBU vacuum handle, or false otherwise. +*/ +#define rbuIsVacuum(p) ((p)->zTarget==0) + + +/************************************************************************* +** The following three functions, found below: +** +** rbuDeltaGetInt() +** rbuDeltaChecksum() +** rbuDeltaApply() +** +** are lifted from the fossil source code (http://fossil-scm.org). They +** are used to implement the scalar SQL function rbu_fossil_delta(). +*/ + +/* +** Read bytes from *pz and convert them into a positive integer. When +** finished, leave *pz pointing to the first character past the end of +** the integer. The *pLen parameter holds the length of the string +** in *pz and is decremented once for each character in the integer. +*/ +static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ + static const signed char zValue[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36, + -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1, + }; + unsigned int v = 0; + int c; + unsigned char *z = (unsigned char*)*pz; + unsigned char *zStart = z; + while( (c = zValue[0x7f&*(z++)])>=0 ){ + v = (v<<6) + c; + } + z--; + *pLen -= z - zStart; + *pz = (char*)z; + return v; +} + +#if RBU_ENABLE_DELTA_CKSUM +/* +** Compute a 32-bit checksum on the N-byte buffer. Return the result. +*/ +static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){ + const unsigned char *z = (const unsigned char *)zIn; + unsigned sum0 = 0; + unsigned sum1 = 0; + unsigned sum2 = 0; + unsigned sum3 = 0; + while(N >= 16){ + sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); + sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); + sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); + sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]); + z += 16; + N -= 16; + } + while(N >= 4){ + sum0 += z[0]; + sum1 += z[1]; + sum2 += z[2]; + sum3 += z[3]; + z += 4; + N -= 4; + } + sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); + switch(N){ + case 3: sum3 += (z[2] << 8); + case 2: sum3 += (z[1] << 16); + case 1: sum3 += (z[0] << 24); + default: ; + } + return sum3; +} +#endif + +/* +** Apply a delta. +** +** The output buffer should be big enough to hold the whole output +** file and a NUL terminator at the end. The delta_output_size() +** routine will determine this size for you. +** +** The delta string should be null-terminated. But the delta string +** may contain embedded NUL characters (if the input and output are +** binary files) so we also have to pass in the length of the delta in +** the lenDelta parameter. +** +** This function returns the size of the output file in bytes (excluding +** the final NUL terminator character). Except, if the delta string is +** malformed or intended for use with a source file other than zSrc, +** then this routine returns -1. +** +** Refer to the delta_create() documentation above for a description +** of the delta file format. +*/ +static int rbuDeltaApply( + const char *zSrc, /* The source or pattern file */ + int lenSrc, /* Length of the source file */ + const char *zDelta, /* Delta to apply to the pattern */ + int lenDelta, /* Length of the delta */ + char *zOut /* Write the output into this preallocated buffer */ +){ + unsigned int limit; + unsigned int total = 0; +#if RBU_ENABLE_DELTA_CKSUM + char *zOrigOut = zOut; +#endif + + limit = rbuDeltaGetInt(&zDelta, &lenDelta); + if( *zDelta!='\n' ){ + /* ERROR: size integer not terminated by "\n" */ + return -1; + } + zDelta++; lenDelta--; + while( *zDelta && lenDelta>0 ){ + unsigned int cnt, ofst; + cnt = rbuDeltaGetInt(&zDelta, &lenDelta); + switch( zDelta[0] ){ + case '@': { + zDelta++; lenDelta--; + ofst = rbuDeltaGetInt(&zDelta, &lenDelta); + if( lenDelta>0 && zDelta[0]!=',' ){ + /* ERROR: copy command not terminated by ',' */ + return -1; + } + zDelta++; lenDelta--; + total += cnt; + if( total>limit ){ + /* ERROR: copy exceeds output file size */ + return -1; + } + if( (int)(ofst+cnt) > lenSrc ){ + /* ERROR: copy extends past end of input */ + return -1; + } + memcpy(zOut, &zSrc[ofst], cnt); + zOut += cnt; + break; + } + case ':': { + zDelta++; lenDelta--; + total += cnt; + if( total>limit ){ + /* ERROR: insert command gives an output larger than predicted */ + return -1; + } + if( (int)cnt>lenDelta ){ + /* ERROR: insert count exceeds size of delta */ + return -1; + } + memcpy(zOut, zDelta, cnt); + zOut += cnt; + zDelta += cnt; + lenDelta -= cnt; + break; + } + case ';': { + zDelta++; lenDelta--; + zOut[0] = 0; +#if RBU_ENABLE_DELTA_CKSUM + if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){ + /* ERROR: bad checksum */ + return -1; + } +#endif + if( total!=limit ){ + /* ERROR: generated size does not match predicted size */ + return -1; + } + return total; + } + default: { + /* ERROR: unknown delta operator */ + return -1; + } + } + } + /* ERROR: unterminated delta */ + return -1; +} + +static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ + int size; + size = rbuDeltaGetInt(&zDelta, &lenDelta); + if( *zDelta!='\n' ){ + /* ERROR: size integer not terminated by "\n" */ + return -1; + } + return size; +} + +/* +** End of code taken from fossil. +*************************************************************************/ + +/* +** Implementation of SQL scalar function rbu_fossil_delta(). +** +** This function applies a fossil delta patch to a blob. Exactly two +** arguments must be passed to this function. The first is the blob to +** patch and the second the patch to apply. If no error occurs, this +** function returns the patched blob. +*/ +static void rbuFossilDeltaFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *aDelta; + int nDelta; + const char *aOrig; + int nOrig; + + int nOut; + int nOut2; + char *aOut; + + assert( argc==2 ); + + nOrig = sqlite3_value_bytes(argv[0]); + aOrig = (const char*)sqlite3_value_blob(argv[0]); + nDelta = sqlite3_value_bytes(argv[1]); + aDelta = (const char*)sqlite3_value_blob(argv[1]); + + /* Figure out the size of the output */ + nOut = rbuDeltaOutputSize(aDelta, nDelta); + if( nOut<0 ){ + sqlite3_result_error(context, "corrupt fossil delta", -1); + return; + } + + aOut = sqlite3_malloc(nOut+1); + if( aOut==0 ){ + sqlite3_result_error_nomem(context); + }else{ + nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut); + if( nOut2!=nOut ){ + sqlite3_free(aOut); + sqlite3_result_error(context, "corrupt fossil delta", -1); + }else{ + sqlite3_result_blob(context, aOut, nOut, sqlite3_free); + } + } +} + + +/* +** Prepare the SQL statement in buffer zSql against database handle db. +** If successful, set *ppStmt to point to the new statement and return +** SQLITE_OK. +** +** Otherwise, if an error does occur, set *ppStmt to NULL and return +** an SQLite error code. Additionally, set output variable *pzErrmsg to +** point to a buffer containing an error message. It is the responsibility +** of the caller to (eventually) free this buffer using sqlite3_free(). +*/ +static int prepareAndCollectError( + sqlite3 *db, + sqlite3_stmt **ppStmt, + char **pzErrmsg, + const char *zSql +){ + int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); + if( rc!=SQLITE_OK ){ + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + *ppStmt = 0; + } + return rc; +} + +/* +** Reset the SQL statement passed as the first argument. Return a copy +** of the value returned by sqlite3_reset(). +** +** If an error has occurred, then set *pzErrmsg to point to a buffer +** containing an error message. It is the responsibility of the caller +** to eventually free this buffer using sqlite3_free(). +*/ +static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){ + int rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ){ + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt))); + } + return rc; +} + +/* +** Unless it is NULL, argument zSql points to a buffer allocated using +** sqlite3_malloc containing an SQL statement. This function prepares the SQL +** statement against database db and frees the buffer. If statement +** compilation is successful, *ppStmt is set to point to the new statement +** handle and SQLITE_OK is returned. +** +** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code +** returned. In this case, *pzErrmsg may also be set to point to an error +** message. It is the responsibility of the caller to free this error message +** buffer using sqlite3_free(). +** +** If argument zSql is NULL, this function assumes that an OOM has occurred. +** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL. +*/ +static int prepareFreeAndCollectError( + sqlite3 *db, + sqlite3_stmt **ppStmt, + char **pzErrmsg, + char *zSql +){ + int rc; + assert( *pzErrmsg==0 ); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + *ppStmt = 0; + }else{ + rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql); + sqlite3_free(zSql); + } + return rc; +} + +/* +** Free the RbuObjIter.azTblCol[] and RbuObjIter.abTblPk[] arrays allocated +** by an earlier call to rbuObjIterCacheTableInfo(). +*/ +static void rbuObjIterFreeCols(RbuObjIter *pIter){ + int i; + for(i=0; inTblCol; i++){ + sqlite3_free(pIter->azTblCol[i]); + sqlite3_free(pIter->azTblType[i]); + } + sqlite3_free(pIter->azTblCol); + pIter->azTblCol = 0; + pIter->azTblType = 0; + pIter->aiSrcOrder = 0; + pIter->abTblPk = 0; + pIter->abNotNull = 0; + pIter->nTblCol = 0; + pIter->eType = 0; /* Invalid value */ +} + +/* +** Finalize all statements and free all allocations that are specific to +** the current object (table/index pair). +*/ +static void rbuObjIterClearStatements(RbuObjIter *pIter){ + RbuUpdateStmt *pUp; + + sqlite3_finalize(pIter->pSelect); + sqlite3_finalize(pIter->pInsert); + sqlite3_finalize(pIter->pDelete); + sqlite3_finalize(pIter->pTmpInsert); + pUp = pIter->pRbuUpdate; + while( pUp ){ + RbuUpdateStmt *pTmp = pUp->pNext; + sqlite3_finalize(pUp->pUpdate); + sqlite3_free(pUp); + pUp = pTmp; + } + sqlite3_free(pIter->aIdxCol); + sqlite3_free(pIter->zIdxSql); + + pIter->pSelect = 0; + pIter->pInsert = 0; + pIter->pDelete = 0; + pIter->pRbuUpdate = 0; + pIter->pTmpInsert = 0; + pIter->nCol = 0; + pIter->nIdxCol = 0; + pIter->aIdxCol = 0; + pIter->zIdxSql = 0; +} + +/* +** Clean up any resources allocated as part of the iterator object passed +** as the only argument. +*/ +static void rbuObjIterFinalize(RbuObjIter *pIter){ + rbuObjIterClearStatements(pIter); + sqlite3_finalize(pIter->pTblIter); + sqlite3_finalize(pIter->pIdxIter); + rbuObjIterFreeCols(pIter); + memset(pIter, 0, sizeof(RbuObjIter)); +} + +/* +** Advance the iterator to the next position. +** +** If no error occurs, SQLITE_OK is returned and the iterator is left +** pointing to the next entry. Otherwise, an error code and message is +** left in the RBU handle passed as the first argument. A copy of the +** error code is returned. +*/ +static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ + int rc = p->rc; + if( rc==SQLITE_OK ){ + + /* Free any SQLite statements used while processing the previous object */ + rbuObjIterClearStatements(pIter); + if( pIter->zIdx==0 ){ + rc = sqlite3_exec(p->dbMain, + "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;" + "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;" + "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;" + "DROP TRIGGER IF EXISTS temp.rbu_delete_tr;" + , 0, 0, &p->zErrmsg + ); + } + + if( rc==SQLITE_OK ){ + if( pIter->bCleanup ){ + rbuObjIterFreeCols(pIter); + pIter->bCleanup = 0; + rc = sqlite3_step(pIter->pTblIter); + if( rc!=SQLITE_ROW ){ + rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); + pIter->zTbl = 0; + }else{ + pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); + pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); + rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM; + } + }else{ + if( pIter->zIdx==0 ){ + sqlite3_stmt *pIdx = pIter->pIdxIter; + rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_step(pIter->pIdxIter); + if( rc!=SQLITE_ROW ){ + rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg); + pIter->bCleanup = 1; + pIter->zIdx = 0; + }else{ + pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0); + pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1); + pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2); + rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM; + } + } + } + } + } + + if( rc!=SQLITE_OK ){ + rbuObjIterFinalize(pIter); + p->rc = rc; + } + return rc; +} + + +/* +** The implementation of the rbu_target_name() SQL function. This function +** accepts one or two arguments. The first argument is the name of a table - +** the name of a table in the RBU database. The second, if it is present, is 1 +** for a view or 0 for a table. +** +** For a non-vacuum RBU handle, if the table name matches the pattern: +** +** data[0-9]_ +** +** where is any sequence of 1 or more characters, is returned. +** Otherwise, if the only argument does not match the above pattern, an SQL +** NULL is returned. +** +** "data_t1" -> "t1" +** "data0123_t2" -> "t2" +** "dataAB_t3" -> NULL +** +** For an rbu vacuum handle, a copy of the first argument is returned if +** the second argument is either missing or 0 (not a view). +*/ +static void rbuTargetNameFunc( + sqlite3_context *pCtx, + int argc, + sqlite3_value **argv +){ + sqlite3rbu *p = sqlite3_user_data(pCtx); + const char *zIn; + assert( argc==1 || argc==2 ); + + zIn = (const char*)sqlite3_value_text(argv[0]); + if( zIn ){ + if( rbuIsVacuum(p) ){ + assert( argc==2 || argc==1 ); + if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ + sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); + } + }else{ + if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ + int i; + for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); + if( zIn[i]=='_' && zIn[i+1] ){ + sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC); + } + } + } + } +} + +/* +** Initialize the iterator structure passed as the second argument. +** +** If no error occurs, SQLITE_OK is returned and the iterator is left +** pointing to the first entry. Otherwise, an error code and message is +** left in the RBU handle passed as the first argument. A copy of the +** error code is returned. +*/ +static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ + int rc; + memset(pIter, 0, sizeof(RbuObjIter)); + + rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, + sqlite3_mprintf( + "SELECT rbu_target_name(name, type='view') AS target, name " + "FROM sqlite_schema " + "WHERE type IN ('table', 'view') AND target IS NOT NULL " + " %s " + "ORDER BY name" + , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : "")); + + if( rc==SQLITE_OK ){ + rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg, + "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' " + " FROM main.sqlite_schema " + " WHERE type='index' AND tbl_name = ?" + ); + } + + pIter->bCleanup = 1; + p->rc = rc; + return rbuObjIterNext(p, pIter); +} + +/* +** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, +** an error code is stored in the RBU handle passed as the first argument. +** +** If an error has already occurred (p->rc is already set to something other +** than SQLITE_OK), then this function returns NULL without modifying the +** stored error code. In this case it still calls sqlite3_free() on any +** printf() parameters associated with %z conversions. +*/ +static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){ + char *zSql = 0; + va_list ap; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zSql==0 ) p->rc = SQLITE_NOMEM; + }else{ + sqlite3_free(zSql); + zSql = 0; + } + va_end(ap); + return zSql; +} + +/* +** Argument zFmt is a sqlite3_mprintf() style format string. The trailing +** arguments are the usual subsitution values. This function performs +** the printf() style substitutions and executes the result as an SQL +** statement on the RBU handles database. +** +** If an error occurs, an error code and error message is stored in the +** RBU handle. If an error has already occurred when this function is +** called, it is a no-op. +*/ +static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){ + va_list ap; + char *zSql; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zSql==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg); + } + } + sqlite3_free(zSql); + va_end(ap); + return p->rc; +} + +/* +** Attempt to allocate and return a pointer to a zeroed block of nByte +** bytes. +** +** If an error (i.e. an OOM condition) occurs, return NULL and leave an +** error code in the rbu handle passed as the first argument. Or, if an +** error has already occurred when this function is called, return NULL +** immediately without attempting the allocation or modifying the stored +** error code. +*/ +static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){ + void *pRet = 0; + if( p->rc==SQLITE_OK ){ + assert( nByte>0 ); + pRet = sqlite3_malloc64(nByte); + if( pRet==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + memset(pRet, 0, nByte); + } + } + return pRet; +} + + +/* +** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that +** there is room for at least nCol elements. If an OOM occurs, store an +** error code in the RBU handle passed as the first argument. +*/ +static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){ + sqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; + char **azNew; + + azNew = (char**)rbuMalloc(p, nByte); + if( azNew ){ + pIter->azTblCol = azNew; + pIter->azTblType = &azNew[nCol]; + pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol]; + pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol]; + pIter->abNotNull = (u8*)&pIter->abTblPk[nCol]; + pIter->abIndexed = (u8*)&pIter->abNotNull[nCol]; + } +} + +/* +** The first argument must be a nul-terminated string. This function +** returns a copy of the string in memory obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free this memory +** using sqlite3_free(). +** +** If an OOM condition is encountered when attempting to allocate memory, +** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, +** if the allocation succeeds, (*pRc) is left unchanged. +*/ +static char *rbuStrndup(const char *zStr, int *pRc){ + char *zRet = 0; + + if( *pRc==SQLITE_OK ){ + if( zStr ){ + size_t nCopy = strlen(zStr) + 1; + zRet = (char*)sqlite3_malloc64(nCopy); + if( zRet ){ + memcpy(zRet, zStr, nCopy); + }else{ + *pRc = SQLITE_NOMEM; + } + } + } + + return zRet; +} + +/* +** Finalize the statement passed as the second argument. +** +** If the sqlite3_finalize() call indicates that an error occurs, and the +** rbu handle error code is not already set, set the error code and error +** message accordingly. +*/ +static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){ + sqlite3 *db = sqlite3_db_handle(pStmt); + int rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ + p->rc = rc; + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } +} + +/* Determine the type of a table. +** +** peType is of type (int*), a pointer to an output parameter of type +** (int). This call sets the output parameter as follows, depending +** on the type of the table specified by parameters dbName and zTbl. +** +** RBU_PK_NOTABLE: No such table. +** RBU_PK_NONE: Table has an implicit rowid. +** RBU_PK_IPK: Table has an explicit IPK column. +** RBU_PK_EXTERNAL: Table has an external PK index. +** RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID. +** RBU_PK_VTAB: Table is a virtual table. +** +** Argument *piPk is also of type (int*), and also points to an output +** parameter. Unless the table has an external primary key index +** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or, +** if the table does have an external primary key index, then *piPk +** is set to the root page number of the primary key index before +** returning. +** +** ALGORITHM: +** +** if( no entry exists in sqlite_schema ){ +** return RBU_PK_NOTABLE +** }else if( sql for the entry starts with "CREATE VIRTUAL" ){ +** return RBU_PK_VTAB +** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){ +** if( the index that is the pk exists in sqlite_schema ){ +** *piPK = rootpage of that index. +** return RBU_PK_EXTERNAL +** }else{ +** return RBU_PK_WITHOUT_ROWID +** } +** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){ +** return RBU_PK_IPK +** }else{ +** return RBU_PK_NONE +** } +*/ +static void rbuTableType( + sqlite3rbu *p, + const char *zTab, + int *peType, + int *piTnum, + int *piPk +){ + /* + ** 0) SELECT count(*) FROM sqlite_schema where name=%Q AND IsVirtual(%Q) + ** 1) PRAGMA index_list = ? + ** 2) SELECT count(*) FROM sqlite_schema where name=%Q + ** 3) PRAGMA table_info = ? + */ + sqlite3_stmt *aStmt[4] = {0, 0, 0, 0}; + + *peType = RBU_PK_NOTABLE; + *piPk = 0; + + assert( p->rc==SQLITE_OK ); + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, + sqlite3_mprintf( + "SELECT " + " (sql COLLATE nocase BETWEEN 'CREATE VIRTUAL' AND 'CREATE VIRTUAM')," + " rootpage" + " FROM sqlite_schema" + " WHERE name=%Q", zTab + )); + if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){ + /* Either an error, or no such table. */ + goto rbuTableType_end; + } + if( sqlite3_column_int(aStmt[0], 0) ){ + *peType = RBU_PK_VTAB; /* virtual table */ + goto rbuTableType_end; + } + *piTnum = sqlite3_column_int(aStmt[0], 1); + + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, + sqlite3_mprintf("PRAGMA index_list=%Q",zTab) + ); + if( p->rc ) goto rbuTableType_end; + while( sqlite3_step(aStmt[1])==SQLITE_ROW ){ + const u8 *zOrig = sqlite3_column_text(aStmt[1], 3); + const u8 *zIdx = sqlite3_column_text(aStmt[1], 1); + if( zOrig && zIdx && zOrig[0]=='p' ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, + sqlite3_mprintf( + "SELECT rootpage FROM sqlite_schema WHERE name = %Q", zIdx + )); + if( p->rc==SQLITE_OK ){ + if( sqlite3_step(aStmt[2])==SQLITE_ROW ){ + *piPk = sqlite3_column_int(aStmt[2], 0); + *peType = RBU_PK_EXTERNAL; + }else{ + *peType = RBU_PK_WITHOUT_ROWID; + } + } + goto rbuTableType_end; + } + } + + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, + sqlite3_mprintf("PRAGMA table_info=%Q",zTab) + ); + if( p->rc==SQLITE_OK ){ + while( sqlite3_step(aStmt[3])==SQLITE_ROW ){ + if( sqlite3_column_int(aStmt[3],5)>0 ){ + *peType = RBU_PK_IPK; /* explicit IPK column */ + goto rbuTableType_end; + } + } + *peType = RBU_PK_NONE; + } + +rbuTableType_end: { + unsigned int i; + for(i=0; iabIndexed[] array. +*/ +static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ + sqlite3_stmt *pList = 0; + int bIndex = 0; + + if( p->rc==SQLITE_OK ){ + memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); + p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + ); + } + + pIter->nIndex = 0; + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ + const char *zIdx = (const char*)sqlite3_column_text(pList, 1); + int bPartial = sqlite3_column_int(pList, 4); + sqlite3_stmt *pXInfo = 0; + if( zIdx==0 ) break; + if( bPartial ){ + memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); + } + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + if( iCid>=0 ) pIter->abIndexed[iCid] = 1; + if( iCid==-2 ){ + memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); + } + } + rbuFinalize(p, pXInfo); + bIndex = 1; + pIter->nIndex++; + } + + if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ + /* "PRAGMA index_list" includes the main PK b-tree */ + pIter->nIndex--; + } + + rbuFinalize(p, pList); + if( bIndex==0 ) pIter->abIndexed = 0; +} + + +/* +** If they are not already populated, populate the pIter->azTblCol[], +** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to +** the table (not index) that the iterator currently points to. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. If +** an error does occur, an error code and error message are also left in +** the RBU handle. +*/ +static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ + if( pIter->azTblCol==0 ){ + sqlite3_stmt *pStmt = 0; + int nCol = 0; + int i; /* for() loop iterator variable */ + int bRbuRowid = 0; /* If input table has column "rbu_rowid" */ + int iOrder = 0; + int iTnum = 0; + + /* Figure out the type of table this step will deal with. */ + assert( pIter->eType==0 ); + rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum); + if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl); + } + if( p->rc ) return p->rc; + if( pIter->zIdx==0 ) pIter->iTnum = iTnum; + + assert( pIter->eType==RBU_PK_NONE || pIter->eType==RBU_PK_IPK + || pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_WITHOUT_ROWID + || pIter->eType==RBU_PK_VTAB + ); + + /* Populate the azTblCol[] and nTblCol variables based on the columns + ** of the input table. Ignore any input table columns that begin with + ** "rbu_". */ + p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl) + ); + if( p->rc==SQLITE_OK ){ + nCol = sqlite3_column_count(pStmt); + rbuAllocateIterArrays(p, pIter, nCol); + } + for(i=0; p->rc==SQLITE_OK && irc); + pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol; + pIter->azTblCol[pIter->nTblCol++] = zCopy; + } + else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){ + bRbuRowid = 1; + } + } + sqlite3_finalize(pStmt); + pStmt = 0; + + if( p->rc==SQLITE_OK + && rbuIsVacuum(p)==0 + && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) + ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf( + "table %q %s rbu_rowid column", pIter->zDataTbl, + (bRbuRowid ? "may not have" : "requires") + ); + } + + /* Check that all non-HIDDEN columns in the destination table are also + ** present in the input table. Populate the abTblPk[], azTblType[] and + ** aiTblOrder[] arrays at the same time. */ + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, + sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) + ); + } + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zName = (const char*)sqlite3_column_text(pStmt, 1); + if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ + for(i=iOrder; inTblCol; i++){ + if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; + } + if( i==pIter->nTblCol ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("column missing from %q: %s", + pIter->zDataTbl, zName + ); + }else{ + int iPk = sqlite3_column_int(pStmt, 5); + int bNotNull = sqlite3_column_int(pStmt, 3); + const char *zType = (const char*)sqlite3_column_text(pStmt, 2); + + if( i!=iOrder ){ + SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]); + SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]); + } + + pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc); + assert( iPk>=0 ); + pIter->abTblPk[iOrder] = (u8)iPk; + pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0); + iOrder++; + } + } + + rbuFinalize(p, pStmt); + rbuObjIterCacheIndexedCols(p, pIter); + assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); + assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 ); + } + + return p->rc; +} + +/* +** This function constructs and returns a pointer to a nul-terminated +** string containing some SQL clause or list based on one or more of the +** column names currently stored in the pIter->azTblCol[] array. +*/ +static char *rbuObjIterGetCollist( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter /* Object iterator for column names */ +){ + char *zList = 0; + const char *zSep = ""; + int i; + for(i=0; inTblCol; i++){ + const char *z = pIter->azTblCol[i]; + zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z); + zSep = ", "; + } + return zList; +} + +/* +** Return a comma separated list of the quoted PRIMARY KEY column names, +** in order, for the current table. Before each column name, add the text +** zPre. After each column name, add the zPost text. Use zSeparator as +** the separator text (usually ", "). +*/ +static char *rbuObjIterGetPkList( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter, /* Object iterator for column names */ + const char *zPre, /* Before each quoted column name */ + const char *zSeparator, /* Separator to use between columns */ + const char *zPost /* After each quoted column name */ +){ + int iPk = 1; + char *zRet = 0; + const char *zSep = ""; + while( 1 ){ + int i; + for(i=0; inTblCol; i++){ + if( (int)pIter->abTblPk[i]==iPk ){ + const char *zCol = pIter->azTblCol[i]; + zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost); + zSep = zSeparator; + break; + } + } + if( i==pIter->nTblCol ) break; + iPk++; + } + return zRet; +} + +/* +** This function is called as part of restarting an RBU vacuum within +** stage 1 of the process (while the *-oal file is being built) while +** updating a table (not an index). The table may be a rowid table or +** a WITHOUT ROWID table. It queries the target database to find the +** largest key that has already been written to the target table and +** constructs a WHERE clause that can be used to extract the remaining +** rows from the source table. For a rowid table, the WHERE clause +** is of the form: +** +** "WHERE _rowid_ > ?" +** +** and for WITHOUT ROWID tables: +** +** "WHERE (key1, key2) > (?, ?)" +** +** Instead of "?" placeholders, the actual WHERE clauses created by +** this function contain literal SQL values. +*/ +static char *rbuVacuumTableStart( + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter, /* RBU iterator object */ + int bRowid, /* True for a rowid table */ + const char *zWrite /* Target table name prefix */ +){ + sqlite3_stmt *pMax = 0; + char *zRet = 0; + if( bRowid ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, + sqlite3_mprintf( + "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0); + zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax); + } + rbuFinalize(p, pMax); + }else{ + char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC"); + char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")"); + char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", ""); + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, + sqlite3_mprintf( + "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1", + zSelect, zWrite, pIter->zTbl, zOrder + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + const char *zVal = (const char*)sqlite3_column_text(pMax, 0); + zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal); + } + rbuFinalize(p, pMax); + } + + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zList); + } + return zRet; +} + +/* +** This function is called as part of restating an RBU vacuum when the +** current operation is writing content to an index. If possible, it +** queries the target index b-tree for the largest key already written to +** it, then composes and returns an expression that can be used in a WHERE +** clause to select the remaining required rows from the source table. +** It is only possible to return such an expression if: +** +** * The index contains no DESC columns, and +** * The last key written to the index before the operation was +** suspended does not contain any NULL values. +** +** The expression is of the form: +** +** (index-field1, index-field2, ...) > (?, ?, ...) +** +** except that the "?" placeholders are replaced with literal values. +** +** If the expression cannot be created, NULL is returned. In this case, +** the caller has to use an OFFSET clause to extract only the required +** rows from the sourct table, just as it does for an RBU update operation. +*/ +static char *rbuVacuumIndexStart( + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter /* RBU iterator object */ +){ + char *zOrder = 0; + char *zLhs = 0; + char *zSelect = 0; + char *zVector = 0; + char *zRet = 0; + int bFailed = 0; + const char *zSep = ""; + int iCol = 0; + sqlite3_stmt *pXInfo = 0; + + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + const char *zCol; + if( sqlite3_column_int(pXInfo, 3) ){ + bFailed = 1; + break; + } + + if( iCid<0 ){ + if( pIter->eType==RBU_PK_IPK ){ + int i; + for(i=0; pIter->abTblPk[i]==0; i++); + assert( inTblCol ); + zCol = pIter->azTblCol[i]; + }else{ + zCol = "_rowid_"; + } + }else{ + zCol = pIter->azTblCol[iCid]; + } + + zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q", + zLhs, zSep, zCol, zCollate + ); + zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC", + zOrder, zSep, iCol, zCol, zCollate + ); + zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")", + zSelect, zSep, iCol, zCol + ); + zSep = ", "; + iCol++; + } + rbuFinalize(p, pXInfo); + if( bFailed ) goto index_start_out; + + if( p->rc==SQLITE_OK ){ + sqlite3_stmt *pSel = 0; + + p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg, + sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", + zSelect, pIter->zTbl, zOrder + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){ + zSep = ""; + for(iCol=0; iColnCol; iCol++){ + const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol); + if( zQuoted==0 ){ + p->rc = SQLITE_NOMEM; + }else if( zQuoted[0]=='N' ){ + bFailed = 1; + break; + } + zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted); + zSep = ", "; + } + + if( !bFailed ){ + zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector); + } + } + rbuFinalize(p, pSel); + } + + index_start_out: + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zVector); + sqlite3_free(zLhs); + return zRet; +} + +/* +** This function is used to create a SELECT list (the list of SQL +** expressions that follows a SELECT keyword) for a SELECT statement +** used to read from an data_xxx or rbu_tmp_xxx table while updating the +** index object currently indicated by the iterator object passed as the +** second argument. A "PRAGMA index_xinfo = " statement is used +** to obtain the required information. +** +** If the index is of the following form: +** +** CREATE INDEX i1 ON t1(c, b COLLATE nocase); +** +** and "t1" is a table with an explicit INTEGER PRIMARY KEY column +** "ipk", the returned string is: +** +** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'" +** +** As well as the returned string, three other malloc'd strings are +** returned via output parameters. As follows: +** +** pzImposterCols: ... +** pzImposterPk: ... +** pzWhere: ... +*/ +static char *rbuObjIterGetIndexCols( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter, /* Object iterator for column names */ + char **pzImposterCols, /* OUT: Columns for imposter table */ + char **pzImposterPk, /* OUT: Imposter PK clause */ + char **pzWhere, /* OUT: WHERE clause */ + int *pnBind /* OUT: Trbul number of columns */ +){ + int rc = p->rc; /* Error code */ + int rc2; /* sqlite3_finalize() return code */ + char *zRet = 0; /* String to return */ + char *zImpCols = 0; /* String to return via *pzImposterCols */ + char *zImpPK = 0; /* String to return via *pzImposterPK */ + char *zWhere = 0; /* String to return via *pzWhere */ + int nBind = 0; /* Value to return via *pnBind */ + const char *zCom = ""; /* Set to ", " later on */ + const char *zAnd = ""; /* Set to " AND " later on */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */ + + if( rc==SQLITE_OK ){ + assert( p->zErrmsg==0 ); + rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + ); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + int bDesc = sqlite3_column_int(pXInfo, 3); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + const char *zCol = 0; + const char *zType; + + if( iCid==-2 ){ + int iSeq = sqlite3_column_int(pXInfo, 0); + zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom, + pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate + ); + zType = ""; + }else { + if( iCid<0 ){ + /* An integer primary key. If the table has an explicit IPK, use + ** its name. Otherwise, use "rbu_rowid". */ + if( pIter->eType==RBU_PK_IPK ){ + int i; + for(i=0; pIter->abTblPk[i]==0; i++); + assert( inTblCol ); + zCol = pIter->azTblCol[i]; + }else if( rbuIsVacuum(p) ){ + zCol = "_rowid_"; + }else{ + zCol = "rbu_rowid"; + } + zType = "INTEGER"; + }else{ + zCol = pIter->azTblCol[iCid]; + zType = pIter->azTblType[iCid]; + } + zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate); + } + + if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ + const char *zOrder = (bDesc ? " DESC" : ""); + zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", + zImpPK, zCom, nBind, zCol, zOrder + ); + } + zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", + zImpCols, zCom, nBind, zCol, zType, zCollate + ); + zWhere = sqlite3_mprintf( + "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol + ); + if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM; + zCom = ", "; + zAnd = " AND "; + nBind++; + } + + rc2 = sqlite3_finalize(pXInfo); + if( rc==SQLITE_OK ) rc = rc2; + + if( rc!=SQLITE_OK ){ + sqlite3_free(zRet); + sqlite3_free(zImpCols); + sqlite3_free(zImpPK); + sqlite3_free(zWhere); + zRet = 0; + zImpCols = 0; + zImpPK = 0; + zWhere = 0; + p->rc = rc; + } + + *pzImposterCols = zImpCols; + *pzImposterPk = zImpPK; + *pzWhere = zWhere; + *pnBind = nBind; + return zRet; +} + +/* +** Assuming the current table columns are "a", "b" and "c", and the zObj +** paramter is passed "old", return a string of the form: +** +** "old.a, old.b, old.b" +** +** With the column names escaped. +** +** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append +** the text ", old._rowid_" to the returned value. +*/ +static char *rbuObjIterGetOldlist( + sqlite3rbu *p, + RbuObjIter *pIter, + const char *zObj +){ + char *zList = 0; + if( p->rc==SQLITE_OK && pIter->abIndexed ){ + const char *zS = ""; + int i; + for(i=0; inTblCol; i++){ + if( pIter->abIndexed[i] ){ + const char *zCol = pIter->azTblCol[i]; + zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); + }else{ + zList = sqlite3_mprintf("%z%sNULL", zList, zS); + } + zS = ", "; + if( zList==0 ){ + p->rc = SQLITE_NOMEM; + break; + } + } + + /* For a table with implicit rowids, append "old._rowid_" to the list. */ + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + zList = rbuMPrintf(p, "%z, %s._rowid_", zList, zObj); + } + } + return zList; +} + +/* +** Return an expression that can be used in a WHERE clause to match the +** primary key of the current table. For example, if the table is: +** +** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)); +** +** Return the string: +** +** "b = ?1 AND c = ?2" +*/ +static char *rbuObjIterGetWhere( + sqlite3rbu *p, + RbuObjIter *pIter +){ + char *zList = 0; + if( pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE ){ + zList = rbuMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1); + }else if( pIter->eType==RBU_PK_EXTERNAL ){ + const char *zSep = ""; + int i; + for(i=0; inTblCol; i++){ + if( pIter->abTblPk[i] ){ + zList = rbuMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1); + zSep = " AND "; + } + } + zList = rbuMPrintf(p, + "_rowid_ = (SELECT id FROM rbu_imposter2 WHERE %z)", zList + ); + + }else{ + const char *zSep = ""; + int i; + for(i=0; inTblCol; i++){ + if( pIter->abTblPk[i] ){ + const char *zCol = pIter->azTblCol[i]; + zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1); + zSep = " AND "; + } + } + } + return zList; +} + +/* +** The SELECT statement iterating through the keys for the current object +** (p->objiter.pSelect) currently points to a valid row. However, there +** is something wrong with the rbu_control value in the rbu_control value +** stored in the (p->nCol+1)'th column. Set the error code and error message +** of the RBU handle to something reflecting this. +*/ +static void rbuBadControlError(sqlite3rbu *p){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("invalid rbu_control value"); +} + + +/* +** Return a nul-terminated string containing the comma separated list of +** assignments that should be included following the "SET" keyword of +** an UPDATE statement used to update the table object that the iterator +** passed as the second argument currently points to if the rbu_control +** column of the data_xxx table entry is set to zMask. +** +** The memory for the returned string is obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free it using +** sqlite3_free(). +** +** If an OOM error is encountered when allocating space for the new +** string, an error code is left in the rbu handle passed as the first +** argument and NULL is returned. Or, if an error has already occurred +** when this function is called, NULL is returned immediately, without +** attempting the allocation or modifying the stored error code. +*/ +static char *rbuObjIterGetSetlist( + sqlite3rbu *p, + RbuObjIter *pIter, + const char *zMask +){ + char *zList = 0; + if( p->rc==SQLITE_OK ){ + int i; + + if( (int)strlen(zMask)!=pIter->nTblCol ){ + rbuBadControlError(p); + }else{ + const char *zSep = ""; + for(i=0; inTblCol; i++){ + char c = zMask[pIter->aiSrcOrder[i]]; + if( c=='x' ){ + zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", + zList, zSep, pIter->azTblCol[i], i+1 + ); + zSep = ", "; + } + else if( c=='d' ){ + zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)", + zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 + ); + zSep = ", "; + } + else if( c=='f' ){ + zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)", + zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 + ); + zSep = ", "; + } + } + } + } + return zList; +} + +/* +** Return a nul-terminated string consisting of nByte comma separated +** "?" expressions. For example, if nByte is 3, return a pointer to +** a buffer containing the string "?,?,?". +** +** The memory for the returned string is obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free it using +** sqlite3_free(). +** +** If an OOM error is encountered when allocating space for the new +** string, an error code is left in the rbu handle passed as the first +** argument and NULL is returned. Or, if an error has already occurred +** when this function is called, NULL is returned immediately, without +** attempting the allocation or modifying the stored error code. +*/ +static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){ + char *zRet = 0; + sqlite3_int64 nByte = 2*(sqlite3_int64)nBind + 1; + + zRet = (char*)rbuMalloc(p, nByte); + if( zRet ){ + int i; + for(i=0; izIdx==0 ); + if( p->rc==SQLITE_OK ){ + const char *zSep = "PRIMARY KEY("; + sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = */ + + p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){ + const char *zOrig = (const char*)sqlite3_column_text(pXList,3); + if( zOrig && strcmp(zOrig, "pk")==0 ){ + const char *zIdx = (const char*)sqlite3_column_text(pXList,1); + if( zIdx ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + } + break; + } + } + rbuFinalize(p, pXList); + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + if( sqlite3_column_int(pXInfo, 5) ){ + /* int iCid = sqlite3_column_int(pXInfo, 0); */ + const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2); + const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : ""; + z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc); + zSep = ", "; + } + } + z = rbuMPrintf(p, "%z)", z); + rbuFinalize(p, pXInfo); + } + return z; +} + +/* +** This function creates the second imposter table used when writing to +** a table b-tree where the table has an external primary key. If the +** iterator passed as the second argument does not currently point to +** a table (not index) with an external primary key, this function is a +** no-op. +** +** Assuming the iterator does point to a table with an external PK, this +** function creates a WITHOUT ROWID imposter table named "rbu_imposter2" +** used to access that PK index. For example, if the target table is +** declared as follows: +** +** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c)); +** +** then the imposter table schema is: +** +** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID; +** +*/ +static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){ + if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){ + int tnum = pIter->iPkTnum; /* Root page of PK index */ + sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ + const char *zIdx = 0; /* Name of PK index */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ + const char *zComma = ""; + char *zCols = 0; /* Used to build up list of table cols */ + char *zPk = 0; /* Used to build up table PK declaration */ + + /* Figure out the name of the primary key index for the current table. + ** This is needed for the argument to "PRAGMA index_xinfo". Set + ** zIdx to point to a nul-terminated string containing this name. */ + p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg, + "SELECT name FROM sqlite_schema WHERE rootpage = ?" + ); + if( p->rc==SQLITE_OK ){ + sqlite3_bind_int(pQuery, 1, tnum); + if( SQLITE_ROW==sqlite3_step(pQuery) ){ + zIdx = (const char*)sqlite3_column_text(pQuery, 0); + } + } + if( zIdx ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + } + rbuFinalize(p, pQuery); + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int bKey = sqlite3_column_int(pXInfo, 5); + if( bKey ){ + int iCid = sqlite3_column_int(pXInfo, 1); + int bDesc = sqlite3_column_int(pXInfo, 3); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, + iCid, pIter->azTblType[iCid], zCollate + ); + zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); + zComma = ", "; + } + } + zCols = rbuMPrintf(p, "%z, id INTEGER", zCols); + rbuFinalize(p, pXInfo); + + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); + rbuMPrintfExec(p, p->dbMain, + "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", + zCols, zPk + ); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + } +} + +/* +** If an error has already occurred when this function is called, it +** immediately returns zero (without doing any work). Or, if an error +** occurs during the execution of this function, it sets the error code +** in the sqlite3rbu object indicated by the first argument and returns +** zero. +** +** The iterator passed as the second argument is guaranteed to point to +** a table (not an index) when this function is called. This function +** attempts to create any imposter table required to write to the main +** table b-tree of the table before returning. Non-zero is returned if +** an imposter table are created, or zero otherwise. +** +** An imposter table is required in all cases except RBU_PK_VTAB. Only +** virtual tables are written to directly. The imposter table has the +** same schema as the actual target table (less any UNIQUE constraints). +** More precisely, the "same schema" means the same columns, types, +** collation sequences. For tables that do not have an external PRIMARY +** KEY, it also means the same PRIMARY KEY declaration. +*/ +static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){ + if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){ + int tnum = pIter->iTnum; + const char *zComma = ""; + char *zSql = 0; + int iCol; + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); + + for(iCol=0; p->rc==SQLITE_OK && iColnTblCol; iCol++){ + const char *zPk = ""; + const char *zCol = pIter->azTblCol[iCol]; + const char *zColl = 0; + + p->rc = sqlite3_table_column_metadata( + p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0 + ); + + if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){ + /* If the target table column is an "INTEGER PRIMARY KEY", add + ** "PRIMARY KEY" to the imposter table column declaration. */ + zPk = "PRIMARY KEY "; + } + zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", + zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, + (pIter->abNotNull[iCol] ? " NOT NULL" : "") + ); + zComma = ", "; + } + + if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ + char *zPk = rbuWithoutRowidPK(p, pIter); + if( zPk ){ + zSql = rbuMPrintf(p, "%z, %z", zSql, zPk); + } + } + + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); + rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s", + pIter->zTbl, zSql, + (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") + ); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + } +} + +/* +** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table. +** Specifically a statement of the form: +** +** INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...); +** +** The number of bound variables is equal to the number of columns in +** the target table, plus one (for the rbu_control column), plus one more +** (for the rbu_rowid column) if the target table is an implicit IPK or +** virtual table. +*/ +static void rbuObjIterPrepareTmpInsert( + sqlite3rbu *p, + RbuObjIter *pIter, + const char *zCollist, + const char *zRbuRowid +){ + int bRbuRowid = (pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE); + char *zBind = rbuObjIterGetBindlist(p, pIter->nTblCol + 1 + bRbuRowid); + if( zBind ){ + assert( pIter->pTmpInsert==0 ); + p->rc = prepareFreeAndCollectError( + p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf( + "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)", + p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind + )); + } +} + +static void rbuTmpInsertFunc( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + sqlite3rbu *p = sqlite3_user_data(pCtx); + int rc = SQLITE_OK; + int i; + + assert( sqlite3_value_int(apVal[0])!=0 + || p->objiter.eType==RBU_PK_EXTERNAL + || p->objiter.eType==RBU_PK_NONE + ); + if( sqlite3_value_int(apVal[0])!=0 ){ + p->nPhaseOneStep += p->objiter.nIndex; + } + + for(i=0; rc==SQLITE_OK && iobjiter.pTmpInsert, i+1, apVal[i]); + } + if( rc==SQLITE_OK ){ + sqlite3_step(p->objiter.pTmpInsert); + rc = sqlite3_reset(p->objiter.pTmpInsert); + } + + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + } +} + +static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ + sqlite3_stmt *pStmt = 0; + int rc = p->rc; + char *zRet = 0; + + assert( pIter->zIdxSql==0 && pIter->nIdxCol==0 && pIter->aIdxCol==0 ); + + if( rc==SQLITE_OK ){ + rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, + "SELECT trim(sql) FROM sqlite_schema WHERE type='index' AND name=?" + ); + } + if( rc==SQLITE_OK ){ + int rc2; + rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + char *zSql = (char*)sqlite3_column_text(pStmt, 0); + if( zSql ){ + pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc); + } + if( zSql ){ + int nParen = 0; /* Number of open parenthesis */ + int i; + int iIdxCol = 0; + int nIdxAlloc = 0; + for(i=0; zSql[i]; i++){ + char c = zSql[i]; + + /* If necessary, grow the pIter->aIdxCol[] array */ + if( iIdxCol==nIdxAlloc ){ + RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc( + pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan) + ); + if( aIdxCol==0 ){ + rc = SQLITE_NOMEM; + break; + } + pIter->aIdxCol = aIdxCol; + nIdxAlloc += 16; + } + + if( c=='(' ){ + if( nParen==0 ){ + assert( iIdxCol==0 ); + pIter->aIdxCol[0].zSpan = &zSql[i+1]; + } + nParen++; + } + else if( c==')' ){ + nParen--; + if( nParen==0 ){ + int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + pIter->aIdxCol[iIdxCol++].nSpan = nSpan; + i++; + break; + } + }else if( c==',' && nParen==1 ){ + int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + pIter->aIdxCol[iIdxCol++].nSpan = nSpan; + pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; + }else if( c=='"' || c=='\'' || c=='`' ){ + for(i++; 1; i++){ + if( zSql[i]==c ){ + if( zSql[i+1]!=c ) break; + i++; + } + } + }else if( c=='[' ){ + for(i++; 1; i++){ + if( zSql[i]==']' ) break; + } + }else if( c=='-' && zSql[i+1]=='-' ){ + for(i=i+2; zSql[i] && zSql[i]!='\n'; i++); + if( zSql[i]=='\0' ) break; + }else if( c=='/' && zSql[i+1]=='*' ){ + for(i=i+2; zSql[i] && (zSql[i]!='*' || zSql[i+1]!='/'); i++); + if( zSql[i]=='\0' ) break; + i++; + } + } + if( zSql[i] ){ + zRet = rbuStrndup(&zSql[i], &rc); + } + pIter->nIdxCol = iIdxCol; + } + } + + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + } + + p->rc = rc; + return zRet; +} + +/* +** Ensure that the SQLite statement handles required to update the +** target database object currently indicated by the iterator passed +** as the second argument are available. +*/ +static int rbuObjIterPrepareAll( + sqlite3rbu *p, + RbuObjIter *pIter, + int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */ +){ + assert( pIter->bCleanup==0 ); + if( pIter->pSelect==0 && rbuObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){ + const int tnum = pIter->iTnum; + char *zCollist = 0; /* List of indexed columns */ + char **pz = &p->zErrmsg; + const char *zIdx = pIter->zIdx; + char *zLimit = 0; + + if( nOffset ){ + zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset); + if( !zLimit ) p->rc = SQLITE_NOMEM; + } + + if( zIdx ){ + const char *zTbl = pIter->zTbl; + char *zImposterCols = 0; /* Columns for imposter table */ + char *zImposterPK = 0; /* Primary key declaration for imposter */ + char *zWhere = 0; /* WHERE clause on PK columns */ + char *zBind = 0; + char *zPart = 0; + int nBind = 0; + + assert( pIter->eType!=RBU_PK_VTAB ); + zPart = rbuObjIterGetIndexWhere(p, pIter); + zCollist = rbuObjIterGetIndexCols( + p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind + ); + zBind = rbuObjIterGetBindlist(p, nBind); + + /* Create the imposter table used to write to this index. */ + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); + rbuMPrintfExec(p, p->dbMain, + "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", + zTbl, zImposterCols, zImposterPK + ); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + + /* Create the statement to insert index entries */ + pIter->nCol = nBind; + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError( + p->dbMain, &pIter->pInsert, &p->zErrmsg, + sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) + ); + } + + /* And to delete index entries */ + if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError( + p->dbMain, &pIter->pDelete, &p->zErrmsg, + sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) + ); + } + + /* Create the SELECT statement to read keys in sorted order */ + if( p->rc==SQLITE_OK ){ + char *zSql; + if( rbuIsVacuum(p) ){ + char *zStart = 0; + if( nOffset ){ + zStart = rbuVacuumIndexStart(p, pIter); + if( zStart ){ + sqlite3_free(zLimit); + zLimit = 0; + } + } + + zSql = sqlite3_mprintf( + "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s", + zCollist, + pIter->zDataTbl, + zPart, + (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart, + zCollist, zLimit + ); + sqlite3_free(zStart); + }else + + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + zSql = sqlite3_mprintf( + "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s", + zCollist, p->zStateDb, pIter->zDataTbl, + zPart, zCollist, zLimit + ); + }else{ + zSql = sqlite3_mprintf( + "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s " + "UNION ALL " + "SELECT %s, rbu_control FROM '%q' " + "%s %s typeof(rbu_control)='integer' AND rbu_control!=1 " + "ORDER BY %s%s", + zCollist, p->zStateDb, pIter->zDataTbl, zPart, + zCollist, pIter->zDataTbl, + zPart, + (zPart ? "AND" : "WHERE"), + zCollist, zLimit + ); + } + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql); + }else{ + sqlite3_free(zSql); + } + } + + sqlite3_free(zImposterCols); + sqlite3_free(zImposterPK); + sqlite3_free(zWhere); + sqlite3_free(zBind); + sqlite3_free(zPart); + }else{ + int bRbuRowid = (pIter->eType==RBU_PK_VTAB) + ||(pIter->eType==RBU_PK_NONE) + ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)); + const char *zTbl = pIter->zTbl; /* Table this step applies to */ + const char *zWrite; /* Imposter table name */ + + char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid); + char *zWhere = rbuObjIterGetWhere(p, pIter); + char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old"); + char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new"); + + zCollist = rbuObjIterGetCollist(p, pIter); + pIter->nCol = pIter->nTblCol; + + /* Create the imposter table or tables (if required). */ + rbuCreateImposterTable(p, pIter); + rbuCreateImposterTable2(p, pIter); + zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_"); + + /* Create the INSERT statement to write to the target PK b-tree */ + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz, + sqlite3_mprintf( + "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", + zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings + ) + ); + } + + /* Create the DELETE statement to write to the target PK b-tree. + ** Because it only performs INSERT operations, this is not required for + ** an rbu vacuum handle. */ + if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, + sqlite3_mprintf( + "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere + ) + ); + } + + if( rbuIsVacuum(p)==0 && pIter->abIndexed ){ + const char *zRbuRowid = ""; + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + zRbuRowid = ", rbu_rowid"; + } + + /* Create the rbu_tmp_xxx table and the triggers to populate it. */ + rbuMPrintfExec(p, p->dbRbu, + "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS " + "SELECT *%s FROM '%q' WHERE 0;" + , p->zStateDb, pIter->zDataTbl + , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") + , pIter->zDataTbl + ); + + rbuMPrintfExec(p, p->dbMain, + "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(3, %s);" + "END;" + + "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(3, %s);" + "END;" + + "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(4, %s);" + "END;", + zWrite, zTbl, zOldlist, + zWrite, zTbl, zOldlist, + zWrite, zTbl, zNewlist + ); + + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + rbuMPrintfExec(p, p->dbMain, + "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(0, %s);" + "END;", + zWrite, zTbl, zNewlist + ); + } + + rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid); + } + + /* Create the SELECT statement to read keys from data_xxx */ + if( p->rc==SQLITE_OK ){ + const char *zRbuRowid = ""; + char *zStart = 0; + char *zOrder = 0; + if( bRbuRowid ){ + zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid"; + } + + if( rbuIsVacuum(p) ){ + if( nOffset ){ + zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite); + if( zStart ){ + sqlite3_free(zLimit); + zLimit = 0; + } + } + if( bRbuRowid ){ + zOrder = rbuMPrintf(p, "_rowid_"); + }else{ + zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", ""); + } + } + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, + sqlite3_mprintf( + "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s", + zCollist, + (rbuIsVacuum(p) ? "0 AS " : ""), + zRbuRowid, + pIter->zDataTbl, (zStart ? zStart : ""), + (zOrder ? "ORDER BY" : ""), zOrder, + zLimit + ) + ); + } + sqlite3_free(zStart); + sqlite3_free(zOrder); + } + + sqlite3_free(zWhere); + sqlite3_free(zOldlist); + sqlite3_free(zNewlist); + sqlite3_free(zBindings); + } + sqlite3_free(zCollist); + sqlite3_free(zLimit); + } + + return p->rc; +} + +/* +** Set output variable *ppStmt to point to an UPDATE statement that may +** be used to update the imposter table for the main table b-tree of the +** table object that pIter currently points to, assuming that the +** rbu_control column of the data_xyz table contains zMask. +** +** If the zMask string does not specify any columns to update, then this +** is not an error. Output variable *ppStmt is set to NULL in this case. +*/ +static int rbuGetUpdateStmt( + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter, /* Object iterator */ + const char *zMask, /* rbu_control value ('x.x.') */ + sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ +){ + RbuUpdateStmt **pp; + RbuUpdateStmt *pUp = 0; + int nUp = 0; + + /* In case an error occurs */ + *ppStmt = 0; + + /* Search for an existing statement. If one is found, shift it to the front + ** of the LRU queue and return immediately. Otherwise, leave nUp pointing + ** to the number of statements currently in the cache and pUp to the + ** last object in the list. */ + for(pp=&pIter->pRbuUpdate; *pp; pp=&((*pp)->pNext)){ + pUp = *pp; + if( strcmp(pUp->zMask, zMask)==0 ){ + *pp = pUp->pNext; + pUp->pNext = pIter->pRbuUpdate; + pIter->pRbuUpdate = pUp; + *ppStmt = pUp->pUpdate; + return SQLITE_OK; + } + nUp++; + } + assert( pUp==0 || pUp->pNext==0 ); + + if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){ + for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext)); + *pp = 0; + sqlite3_finalize(pUp->pUpdate); + pUp->pUpdate = 0; + }else{ + pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1); + } + + if( pUp ){ + char *zWhere = rbuObjIterGetWhere(p, pIter); + char *zSet = rbuObjIterGetSetlist(p, pIter, zMask); + char *zUpdate = 0; + + pUp->zMask = (char*)&pUp[1]; + memcpy(pUp->zMask, zMask, pIter->nTblCol); + pUp->pNext = pIter->pRbuUpdate; + pIter->pRbuUpdate = pUp; + + if( zSet ){ + const char *zPrefix = ""; + + if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; + zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", + zPrefix, pIter->zTbl, zSet, zWhere + ); + p->rc = prepareFreeAndCollectError( + p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate + ); + *ppStmt = pUp->pUpdate; + } + sqlite3_free(zWhere); + sqlite3_free(zSet); + } + + return p->rc; +} + +static sqlite3 *rbuOpenDbhandle( + sqlite3rbu *p, + const char *zName, + int bUseVfs +){ + sqlite3 *db = 0; + if( p->rc==SQLITE_OK ){ + const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; + p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0); + if( p->rc ){ + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + sqlite3_close(db); + db = 0; + } + } + return db; +} + +/* +** Free an RbuState object allocated by rbuLoadState(). +*/ +static void rbuFreeState(RbuState *p){ + if( p ){ + sqlite3_free(p->zTbl); + sqlite3_free(p->zDataTbl); + sqlite3_free(p->zIdx); + sqlite3_free(p); + } +} + +/* +** Allocate an RbuState object and load the contents of the rbu_state +** table into it. Return a pointer to the new object. It is the +** responsibility of the caller to eventually free the object using +** sqlite3_free(). +** +** If an error occurs, leave an error code and message in the rbu handle +** and return NULL. +*/ +static RbuState *rbuLoadState(sqlite3rbu *p){ + RbuState *pRet = 0; + sqlite3_stmt *pStmt = 0; + int rc; + int rc2; + + pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState)); + if( pRet==0 ) return 0; + + rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + switch( sqlite3_column_int(pStmt, 0) ){ + case RBU_STATE_STAGE: + pRet->eStage = sqlite3_column_int(pStmt, 1); + if( pRet->eStage!=RBU_STAGE_OAL + && pRet->eStage!=RBU_STAGE_MOVE + && pRet->eStage!=RBU_STAGE_CKPT + ){ + p->rc = SQLITE_CORRUPT; + } + break; + + case RBU_STATE_TBL: + pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + case RBU_STATE_IDX: + pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + case RBU_STATE_ROW: + pRet->nRow = sqlite3_column_int(pStmt, 1); + break; + + case RBU_STATE_PROGRESS: + pRet->nProgress = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_CKPT: + pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_COOKIE: + pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_OALSZ: + pRet->iOalSz = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_PHASEONESTEP: + pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_DATATBL: + pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + default: + rc = SQLITE_CORRUPT; + break; + } + } + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + + p->rc = rc; + return pRet; +} + + +/* +** Open the database handle and attach the RBU database as "rbu". If an +** error occurs, leave an error code and message in the RBU handle. +** +** If argument dbMain is not NULL, then it is a database handle already +** open on the target database. Use this handle instead of opening a new +** one. +*/ +static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){ + assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); + assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); + assert( dbMain==0 || rbuIsVacuum(p)==0 ); + + /* Open the RBU database */ + p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); + p->dbMain = dbMain; + + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + if( p->zState==0 ){ + const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); + p->zState = rbuMPrintf(p, "file:///%s-vacuum?modeof=%s", zFile, zFile); + } + } + + /* If using separate RBU and state databases, attach the state database to + ** the RBU db handle now. */ + if( p->zState ){ + rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState); + memcpy(p->zStateDb, "stat", 4); + }else{ + memcpy(p->zStateDb, "main", 4); + } + +#if 0 + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0); + } +#endif + + /* If it has not already been created, create the rbu_state table */ + rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); + +#if 0 + if( rbuIsVacuum(p) ){ + if( p->rc==SQLITE_OK ){ + int rc2; + int bOk = 0; + sqlite3_stmt *pCnt = 0; + p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg, + "SELECT count(*) FROM stat.sqlite_schema" + ); + if( p->rc==SQLITE_OK + && sqlite3_step(pCnt)==SQLITE_ROW + && 1==sqlite3_column_int(pCnt, 0) + ){ + bOk = 1; + } + rc2 = sqlite3_finalize(pCnt); + if( p->rc==SQLITE_OK ) p->rc = rc2; + + if( p->rc==SQLITE_OK && bOk==0 ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("invalid state database"); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); + } + } + } +#endif + + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + int bOpen = 0; + int rc; + p->nRbu = 0; + p->pRbuFd = 0; + rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + if( rc!=SQLITE_NOTFOUND ) p->rc = rc; + if( p->eStage>=RBU_STAGE_MOVE ){ + bOpen = 1; + }else{ + RbuState *pState = rbuLoadState(p); + if( pState ){ + bOpen = (pState->eStage>=RBU_STAGE_MOVE); + rbuFreeState(pState); + } + } + if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1); + } + + p->eStage = 0; + if( p->rc==SQLITE_OK && p->dbMain==0 ){ + if( !rbuIsVacuum(p) ){ + p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); + }else if( p->pRbuFd->pWalFd ){ + if( pbRetry ){ + p->pRbuFd->bNolock = 0; + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); + p->dbMain = 0; + p->dbRbu = 0; + *pbRetry = 1; + return; + } + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); + }else{ + char *zTarget; + char *zExtra = 0; + if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){ + zExtra = &p->zRbu[5]; + while( *zExtra ){ + if( *zExtra++=='?' ) break; + } + if( *zExtra=='\0' ) zExtra = 0; + } + + zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", + sqlite3_db_filename(p->dbRbu, "main"), + (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra) + ); + + if( zTarget==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1); + sqlite3_free(zTarget); + } + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_create_function(p->dbMain, + "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_create_function(p->dbMain, + "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0 + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_create_function(p->dbRbu, + "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); + } + rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_schema"); + + /* Mark the database file just opened as an RBU target database. If + ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. + ** This is an error. */ + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); + } + + if( p->rc==SQLITE_NOTFOUND ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("rbu vfs not found"); + } +} + +/* +** This routine is a copy of the sqlite3FileSuffix3() routine from the core. +** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined. +** +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than +** three characters, then shorten the suffix on z[] to be the last three +** characters of the original suffix. +** +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always +** do the suffix shortening regardless of URI parameter. +** +** Examples: +** +** test.db-journal => test.nal +** test.db-wal => test.wal +** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa +*/ +static void rbuFileSuffix3(const char *zBase, char *z){ +#ifdef SQLITE_ENABLE_8_3_NAMES +#if SQLITE_ENABLE_8_3_NAMES<2 + if( sqlite3_uri_boolean(zBase, "8_3_names", 0) ) +#endif + { + int i, sz; + sz = (int)strlen(z)&0xffffff; + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); + } +#endif +} + +/* +** Return the current wal-index header checksum for the target database +** as a 64-bit integer. +** +** The checksum is store in the first page of xShmMap memory as an 8-byte +** blob starting at byte offset 40. +*/ +static i64 rbuShmChecksum(sqlite3rbu *p){ + i64 iRet = 0; + if( p->rc==SQLITE_OK ){ + sqlite3_file *pDb = p->pTargetFd->pReal; + u32 volatile *ptr; + p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); + if( p->rc==SQLITE_OK ){ + iRet = ((i64)ptr[10] << 32) + ptr[11]; + } + } + return iRet; +} + +/* +** This function is called as part of initializing or reinitializing an +** incremental checkpoint. +** +** It populates the sqlite3rbu.aFrame[] array with the set of +** (wal frame -> db page) copy operations required to checkpoint the +** current wal file, and obtains the set of shm locks required to safely +** perform the copy operations directly on the file-system. +** +** If argument pState is not NULL, then the incremental checkpoint is +** being resumed. In this case, if the checksum of the wal-index-header +** following recovery is not the same as the checksum saved in the RbuState +** object, then the rbu handle is set to DONE state. This occurs if some +** other client appends a transaction to the wal file in the middle of +** an incremental checkpoint. +*/ +static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ + + /* If pState is NULL, then the wal file may not have been opened and + ** recovered. Running a read-statement here to ensure that doing so + ** does not interfere with the "capture" process below. */ + if( pState==0 ){ + p->eStage = 0; + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_schema", 0, 0, 0); + } + } + + /* Assuming no error has occurred, run a "restart" checkpoint with the + ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following + ** special behaviour in the rbu VFS: + ** + ** * If the exclusive shm WRITER or READ0 lock cannot be obtained, + ** the checkpoint fails with SQLITE_BUSY (normally SQLite would + ** proceed with running a passive checkpoint instead of failing). + ** + ** * Attempts to read from the *-wal file or write to the database file + ** do not perform any IO. Instead, the frame/page combinations that + ** would be read/written are recorded in the sqlite3rbu.aFrame[] + ** array. + ** + ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, + ** READ0 and CHECKPOINT locks taken as part of the checkpoint are + ** no-ops. These locks will not be released until the connection + ** is closed. + ** + ** * Attempting to xSync() the database file causes an SQLITE_NOTICE + ** error. + ** + ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the + ** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[] + ** array populated with a set of (frame -> page) mappings. Because the + ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy + ** data from the wal file into the database file according to the + ** contents of aFrame[]. + */ + if( p->rc==SQLITE_OK ){ + int rc2; + p->eStage = RBU_STAGE_CAPTURE; + rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); + if( rc2!=SQLITE_NOTICE ) p->rc = rc2; + } + + if( p->rc==SQLITE_OK && p->nFrame>0 ){ + p->eStage = RBU_STAGE_CKPT; + p->nStep = (pState ? pState->nRow : 0); + p->aBuf = rbuMalloc(p, p->pgsz); + p->iWalCksum = rbuShmChecksum(p); + } + + if( p->rc==SQLITE_OK ){ + if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){ + p->rc = SQLITE_DONE; + p->eStage = RBU_STAGE_DONE; + }else{ + int nSectorSize; + sqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; + assert( p->nPagePerSector==0 ); + nSectorSize = pDb->pMethods->xSectorSize(pDb); + if( nSectorSize>p->pgsz ){ + p->nPagePerSector = nSectorSize / p->pgsz; + }else{ + p->nPagePerSector = 1; + } + + /* Call xSync() on the wal file. This causes SQLite to sync the + ** directory in which the target database and the wal file reside, in + ** case it has not been synced since the rename() call in + ** rbuMoveOalFile(). */ + p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL); + } + } +} + +/* +** Called when iAmt bytes are read from offset iOff of the wal file while +** the rbu object is in capture mode. Record the frame number of the frame +** being read in the aFrame[] array. +*/ +static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ + const u32 mReq = (1<mLock!=mReq ){ + pRbu->rc = SQLITE_BUSY; + return SQLITE_NOTICE_RBU; + } + + pRbu->pgsz = iAmt; + if( pRbu->nFrame==pRbu->nFrameAlloc ){ + int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; + RbuFrame *aNew; + aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame)); + if( aNew==0 ) return SQLITE_NOMEM; + pRbu->aFrame = aNew; + pRbu->nFrameAlloc = nNew; + } + + iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1; + if( pRbu->iMaxFrame