From b225097bcd0f439ed976e8481cecbae603a2b0cf Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Thu, 13 Aug 2026 18:56:04 -0400 Subject: [PATCH] import UBI nodejs-22.23.1-3.module+el8.10.0+24640+6eba5e6e --- ...0001-CVE-2026-25547-braces-expansion.patch | 102 - ...CVE-2026-69152-brace-expansion-2.1.4.patch | 391 + ...192-CVE-2026-54272-ip-address-10.4.0.patch | 1994 ++ SOURCES/0001-update-sqlite-to-3.53.4.patch | 21461 ++++++++++++++++ ...26-42338-npm-ip-address-security-fix.patch | 166 - ...49-brace-expansion-unbound-recursion.patch | 100 - SPECS/nodejs.spec | 26 +- 7 files changed, 23865 insertions(+), 375 deletions(-) delete mode 100644 SOURCES/0001-CVE-2026-25547-braces-expansion.patch create mode 100644 SOURCES/0001-CVE-2026-69152-brace-expansion-2.1.4.patch create mode 100644 SOURCES/0001-CVE-2026-69192-CVE-2026-54272-ip-address-10.4.0.patch create mode 100644 SOURCES/0001-update-sqlite-to-3.53.4.patch delete mode 100644 SOURCES/0002-CVE-2026-42338-npm-ip-address-security-fix.patch delete mode 100644 SOURCES/0004-CVE-2026-13149-brace-expansion-unbound-recursion.patch diff --git a/SOURCES/0001-CVE-2026-25547-braces-expansion.patch b/SOURCES/0001-CVE-2026-25547-braces-expansion.patch deleted file mode 100644 index 726ec71..0000000 --- a/SOURCES/0001-CVE-2026-25547-braces-expansion.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: tjuhasz -Date: Tue, 25 Feb 2026 14:21:26 +0100 -Subject: [PATCH] CVE-2026-25547: Fix brace expansion vulnerability - -Add expansion limit to prevent DoS attacks through excessive -brace expansion in the brace-expansion module. - ---- - deps/npm/node_modules/brace-expansion/index.js | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/deps/npm/node_modules/brace-expansion/index.js b/deps/npm/node_modules/brace-expansion/index.js ---- a/deps/npm/node_modules/brace-expansion/index.js 2026-01-12 23:55:24.000000000 +0100 -+++ b/deps/npm/node_modules/brace-expansion/index.js 2026-02-25 14:21:26.829483831 +0100 -@@ -8,6 +8,8 @@ - var escComma = '\0COMMA'+Math.random()+'\0'; - var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -+const EXPANSION_MAX = 100_000; -+ - function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) -@@ -61,9 +63,11 @@ - return parts; - } - --function expandTop(str) { -+function expandTop(str, options = {}) { - if (!str) - return []; -+ -+ const { max = EXPANSION_MAX } = options; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved -@@ -75,7 +79,7 @@ - str = '\\{\\}' + str.substr(2); - } - -- return expand(escapeBraces(str), true).map(unescapeBraces); -+ return expand(escapeBraces(str), max, true).map(unescapeBraces); - } - - function embrace(str) { -@@ -92,7 +96,7 @@ - return i >= y; - } - --function expand(str, isTop) { -+function expand(str, max, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); -@@ -101,11 +105,11 @@ - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length -- ? expand(m.post, false) -+ ? expand(m.post, max, false) - : ['']; - - if (/\$$/.test(m.pre)) { -- for (var k = 0; k < post.length; k++) { -+ for (var k = 0; k < post.length && k < max; k++) { - var expansion = pre+ '{' + m.body + '}' + post[k]; - expansions.push(expansion); - } -@@ -118,7 +122,7 @@ - // {a},b} - if (m.post.match(/,(?!,).*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; -- return expand(str); -+ return expand(str, max, true); - } - return [str]; - } -@@ -130,7 +134,7 @@ - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y -- n = expand(n[0], false).map(embrace); -+ n = expand(n[0], max, false).map(embrace); - if (n.length === 1) { - return post.map(function(p) { - return m.pre + n[0] + p; -@@ -185,12 +189,12 @@ - N = []; - - for (var j = 0; j < n.length; j++) { -- N.push.apply(N, expand(n[j], false)); -+ N.push.apply(N, expand(n[j], max, false)); - } - } - - for (var j = 0; j < N.length; j++) { -- for (var k = 0; k < post.length; k++) { -+ for (var k = 0; k < post.length && expansions.length < max; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); diff --git a/SOURCES/0001-CVE-2026-69152-brace-expansion-2.1.4.patch b/SOURCES/0001-CVE-2026-69152-brace-expansion-2.1.4.patch new file mode 100644 index 0000000..25110e2 --- /dev/null +++ b/SOURCES/0001-CVE-2026-69152-brace-expansion-2.1.4.patch @@ -0,0 +1,391 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tomas Juhasz +Date: Mon, 04 Aug 2026 00:00:00 +0000 +Subject: [PATCH] CVE-2026-14257: upgrade bundled brace-expansion to 2.1.4 + +Upgrade brace-expansion from 2.0.2 to 2.1.4 in npm's vendored +node_modules. The new version adds EXPANSION_MAX and EXPANSION_MAX_LENGTH +guards that cap the number and total size of expansions, preventing +memory exhaustion from crafted input (CVE-2026-14257). The expand() +function is rewritten to iterate instead of recurse, eliminating stack +overflow on deeply chained brace groups. + +Supersedes the earlier CVE-2026-13149 unbound-recursion patch. + +Upstream: https://github.com/juliangruber/brace-expansion/releases/tag/v2.1.4 +--- + .../npm/node_modules/brace-expansion/index.js | 297 +++++++++++++++----- + .../npm/node_modules/brace-expansion/package.json | 2 +- + 2 files changed, 217 insertions(+), 82 deletions(-) + +diff --git a/deps/npm/node_modules/brace-expansion/index.js b/deps/npm/node_modules/brace-expansion/index.js +--- a/deps/npm/node_modules/brace-expansion/index.js ++++ b/deps/npm/node_modules/brace-expansion/index.js +@@ -8,6 +8,20 @@ + var escComma = '\0COMMA'+Math.random()+'\0'; + var escPeriod = '\0PERIOD'+Math.random()+'\0'; + ++var EXPANSION_MAX = 100000 ++ ++// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An ++// input like `'{a,b}'.repeat(1500)` stays under that count - its output is ++// truncated to 100k results - while making every result ~1500 characters ++// long. The result set, and the intermediate arrays built while combining ++// brace sets, then grow large enough to exhaust memory and crash the process ++// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of ++// characters the accumulator may hold at any point, so memory stays flat no ++// matter how many brace groups are chained. The limit sits well above any ++// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M ++// characters) so legitimate input is unaffected. ++var EXPANSION_MAX_LENGTH = 4000000 ++ + function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) +@@ -61,10 +75,14 @@ + return parts; + } + +-function expandTop(str) { ++function expandTop(str, options) { + if (!str) + return []; + ++ options = options || {}; ++ var max = options.max == null ? EXPANSION_MAX : options.max; ++ var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength; ++ + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, +@@ -75,7 +93,7 @@ + str = '\\{\\}' + str.substr(2); + } + +- return expand(escapeBraces(str), true).map(unescapeBraces); ++ return expand(escapeBraces(str), max, maxLength, true).map(unescapeBraces); + } + + function embrace(str) { +@@ -92,24 +110,144 @@ + return i >= y; + } + +-function expand(str, isTop) { +- var expansions = []; ++// Build `{ acc[a] + pre + values[v] }` for every combination, capping the ++// number of results at `max` and the total number of characters at `maxLength`. ++// This is the one place output grows, so bounding it here keeps the single ++// accumulator - and therefore memory - flat regardless of how many brace groups ++// are combined (CVE-2026-14257). ++function combine( ++ acc, ++ pre, ++ values, ++ max, ++ maxLength, ++ dropEmpties ++) { ++ var out = [] ++ var length = 0 ++ for (var a = 0; a < acc.length; a++) { ++ for (var v = 0; v < values.length; v++) { ++ if (out.length >= max) return out ++ var expansion = acc[a] + pre + values[v] ++ // Bash drops empty results at the top level. Skip them before they count ++ // against `max`, so `max` bounds the number of *kept* results. ++ if (dropEmpties && !expansion) continue ++ if (length + expansion.length > maxLength) return out ++ out.push(expansion) ++ length += expansion.length ++ } ++ } ++ return out ++} + +- var m = balanced('{', '}', str); +- if (!m) return [str]; ++// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`) ++// sequence body. ++function expandSequence( ++ body, ++ isAlphaSequence, ++ max, ++ maxLength ++) { ++ var n = body.split(/\.\./) ++ var N = [] ++ // A sequence body always splits into two or three parts, but the compiler ++ // can't know that. ++ /* c8 ignore start */ ++ if (n[0] === undefined || n[1] === undefined) { ++ return N ++ } ++ /* c8 ignore stop */ ++ var x = numeric(n[0]) ++ var y = numeric(n[1]) ++ var width = Math.max(n[0].length, n[1].length) ++ var incr = ++ n.length === 3 && n[2] !== undefined ? ++ Math.max(Math.abs(numeric(n[2])), 1) ++ : 1 ++ var test = lte ++ var reverse = y < x ++ if (reverse) { ++ incr *= -1 ++ test = gte ++ } ++ var pad = n.some(isPadded) + +- // no need to expand pre, since it is guaranteed to be free of brace-sets +- var pre = m.pre; +- var post = m.post.length +- ? expand(m.post, false) +- : ['']; +- +- if (/\$$/.test(m.pre)) { +- for (var k = 0; k < post.length; k++) { +- var expansion = pre+ '{' + m.body + '}' + post[k]; +- expansions.push(expansion); ++ var length = 0 ++ for (var i = x; test(i, y) && N.length < max; i += incr) { ++ var c ++ if (isAlphaSequence) { ++ c = String.fromCharCode(i) ++ if (c === '\\') { ++ c = '' ++ } ++ } else { ++ c = String(i) ++ if (pad) { ++ var need = width - c.length ++ if (need > 0) { ++ var z = new Array(need + 1).join('0') ++ if (i < 0) { ++ c = '-' + z + c.slice(1) ++ } else { ++ c = z + c ++ } ++ } ++ } + } +- } else { ++ if (length + c.length > maxLength) break ++ N.push(c) ++ length += c.length ++ } ++ return N ++} ++ ++function expand( ++ str, ++ max, ++ maxLength, ++ isTop ++) { ++ // Consume the string's top-level brace groups left to right, threading a ++ // running set of combined prefixes (`acc`). Expanding the tail iteratively - ++ // rather than recursing on `m.post` once per group - keeps the native stack ++ // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no ++ // longer overflow the stack, and leaves a single accumulator whose size ++ // `maxLength` bounds directly (CVE-2026-14257). ++ var acc = [''] ++ ++ // Bash drops empty results, but only when the *first* top-level group is a ++ // comma set - a sequence like `{a..\}` may legitimately yield ''. The drop ++ // is on the final strings, so it is applied to whichever `combine` produces ++ // them (the one with no brace set left in the tail). ++ var dropEmpties = false ++ var firstGroup = true ++ ++ for (;;) { ++ const m = balanced('{', '}', str) ++ ++ // No brace set left: the rest of the string is literal. ++ if (!m) { ++ return combine(acc, str, [''], max, maxLength, dropEmpties) ++ } ++ ++ // no need to expand pre, since it is guaranteed to be free of brace-sets ++ const pre = m.pre ++ ++ if (/\$$/.test(pre)) { ++ acc = combine( ++ acc, ++ pre + '{' + m.body + '}', ++ [''], ++ max, ++ maxLength, ++ dropEmpties && !m.post.length ++ ) ++ firstGroup = false ++ if (!m.post.length) break ++ str = m.post ++ continue ++ } ++ + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; +@@ -118,86 +256,83 @@ + // {a},b} + if (m.post.match(/,(?!,).*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; +- return expand(str); ++ isTop = true; ++ continue; + } +- return [str]; ++ // Nothing here expands, so the whole remaining string is literal. ++ return combine( ++ acc, ++ pre + '{' + m.body + '}' + m.post, ++ [''], ++ max, ++ maxLength, ++ dropEmpties ++ ) + } + +- var n; ++ if (firstGroup) { ++ dropEmpties = isTop && !isSequence ++ firstGroup = false ++ } ++ ++ var values; + if (isSequence) { +- n = m.body.split(/\.\./); ++ values = expandSequence(m.body, isAlphaSequence, max, maxLength); + } else { +- n = parseCommaParts(m.body); +- if (n.length === 1) { ++ var n = parseCommaParts(m.body); ++ if (n.length === 1 && n[0] !== undefined) { + // x{{a,b}}y ==> x{a}y x{b}y +- n = expand(n[0], false).map(embrace); ++ n = expand(n[0], max, maxLength, false).map(embrace); ++ //XXX is this necessary? Can't seem to hit it in tests. ++ /* c8 ignore start */ + if (n.length === 1) { +- return post.map(function(p) { +- return m.pre + n[0] + p; +- }); ++ acc = combine( ++ acc, ++ pre + n[0], ++ [''], ++ max, ++ maxLength, ++ dropEmpties && !m.post.length ++ ) ++ if (!m.post.length) break ++ str = m.post ++ continue + } ++ /* c8 ignore stop */ + } +- } +- +- // at this point, n is the parts, and we know it's not a comma set +- // with a single entry. +- var N; + +- if (isSequence) { +- var x = numeric(n[0]); +- var y = numeric(n[1]); +- var width = Math.max(n[0].length, n[1].length) +- var incr = n.length == 3 +- ? Math.abs(numeric(n[2])) +- : 1; +- var test = lte; +- var reverse = y < x; +- if (reverse) { +- incr *= -1; +- test = gte; +- } +- var pad = n.some(isPadded); +- +- N = []; +- +- for (var i = x; test(i, y); i += incr) { +- var c; +- if (isAlphaSequence) { +- c = String.fromCharCode(i); +- if (c === '\\') +- c = ''; +- } else { +- c = String(i); +- if (pad) { +- var need = width - c.length; +- if (need > 0) { +- var z = new Array(need + 1).join('0'); +- if (i < 0) +- c = '-' + z + c.slice(1); +- else +- c = z + c; +- } +- } ++ // Values that `combine` is going to drop as empty produce no result, so ++ // they must not count against `max` - otherwise `{a,,b}` with `max: 2` ++ // would stop at `['a', '']` and yield one result instead of two. Skipping ++ // them outright keeps `values` bounded while leaving `max` a bound on ++ // *kept* results. ++ var dropsEmpties = dropEmpties && !m.post.length && !pre ++ for (var d = 0; dropsEmpties && d < acc.length; d++) { ++ if (acc[d]) { ++ dropsEmpties = false + } +- N.push(c); + } +- } else { +- N = []; + +- for (var j = 0; j < n.length; j++) { +- N.push.apply(N, expand(n[j], false)); ++ values = [] ++ var valuesLength = 0 ++ outer: for (var j = 0; j < n.length; j++) { ++ var expanded = expand(n[j], max, maxLength, false) ++ for (var k = 0; k < expanded.length; k++) { ++ var v = expanded[k] ++ if (dropsEmpties && !v) continue ++ if (values.length >= max || valuesLength + v.length > maxLength) { ++ break outer ++ } ++ values.push(v) ++ valuesLength += v.length ++ } + } + } + +- for (var j = 0; j < N.length; j++) { +- for (var k = 0; k < post.length; k++) { +- var expansion = pre + N[j] + post[k]; +- if (!isTop || isSequence || expansion) +- expansions.push(expansion); +- } +- } ++ acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length) ++ if (!m.post.length) break ++ str = m.post + } + +- return expansions; ++ return acc + } +- + +diff --git a/deps/npm/node_modules/brace-expansion/package.json b/deps/npm/node_modules/brace-expansion/package.json +--- a/deps/npm/node_modules/brace-expansion/package.json ++++ b/deps/npm/node_modules/brace-expansion/package.json +@@ -1,7 +1,7 @@ + { + "name": "brace-expansion", + "description": "Brace expansion as known from sh/bash", +- "version": "2.0.2", ++ "version": "2.1.4", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + diff --git a/SOURCES/0001-CVE-2026-69192-CVE-2026-54272-ip-address-10.4.0.patch b/SOURCES/0001-CVE-2026-69192-CVE-2026-54272-ip-address-10.4.0.patch new file mode 100644 index 0000000..c49ca99 --- /dev/null +++ b/SOURCES/0001-CVE-2026-69192-CVE-2026-54272-ip-address-10.4.0.patch @@ -0,0 +1,1994 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tomas Juhasz +Date: Mon, 04 Aug 2026 00:00:00 +0000 +Subject: [PATCH] CVE-2026-69192, CVE-2026-54272: upgrade bundled ip-address to + 10.4.0 + +Upgrade ip-address from 10.1.0 to 10.4.0 in npm's vendored node_modules. + +CVE-2026-69192: ip-address used isInSubnet for special-use classifiers +(isLoopback, isPrivate, isLinkLocal, getType), which checked the network +address rather than the host address. An attacker could bypass SSRF +filters by appending a CIDR suffix (e.g. 127.0.0.1/24) that shifted the +network address out of the blocked range. + +CVE-2026-54272: HTML entities in error messages were not escaped, +enabling XSS when parse errors were rendered in a browser. + +The new version introduces isHostInSubnet (host-only check used by all +classifiers), prefixLengthFromMask, assertByteArray, and escapes HTML in +AddressError messages. + +Upstream: https://github.com/beaugunderson/ip-address/releases/tag/v10.4.0 +--- + deps/npm/node_modules/ip-address/dist/common.js | 70 ++ + deps/npm/node_modules/ip-address/dist/ipv4.js | 287 ++++++--- + deps/npm/node_modules/ip-address/dist/ipv6.js | 665 +++++++++++++++----- + .../node_modules/ip-address/dist/v4/constants.js | 6 +- + .../node_modules/ip-address/dist/v6/constants.js | 10 +- + .../npm/node_modules/ip-address/dist/v6/helpers.js | 15 +- + deps/npm/node_modules/ip-address/package.json | 86 +-- + 7 files changed, 850 insertions(+), 289 deletions(-) + +diff --git a/deps/npm/node_modules/ip-address/dist/common.js b/deps/npm/node_modules/ip-address/dist/common.js +--- a/deps/npm/node_modules/ip-address/dist/common.js ++++ b/deps/npm/node_modules/ip-address/dist/common.js +@@ -1,21 +1,47 @@ + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.isInSubnet = isInSubnet; ++exports.isHostInSubnet = isHostInSubnet; + exports.isCorrect = isCorrect; ++exports.prefixLengthFromMask = prefixLengthFromMask; ++exports.assertByteArray = assertByteArray; + exports.numberToPaddedHex = numberToPaddedHex; + exports.stringToPaddedHex = stringToPaddedHex; + exports.testBit = testBit; ++const address_error_1 = require("./address-error"); ++/** ++ * Returns whether this address's *network* is contained within `address`, ++ * i.e. whether every address this one can represent also falls inside ++ * `address`. A network wider than `address` is not contained in it, so ++ * `10.0.0.0/8` is not in `10.0.0.0/16`. ++ * ++ * To ask whether the address itself falls inside a range, ignoring any CIDR ++ * suffix it was written with, use {@link isHostInSubnet} instead. That is the ++ * question the special-use classifiers ask. ++ */ + function isInSubnet(address) { + if (this.subnetMask < address.subnetMask) { + return false; + } +- if (this.mask(address.subnetMask) === address.mask()) { +- return true; +- } +- return false; ++ return isHostInSubnet.call(this, address); ++} ++/** ++ * Returns whether this address's host bits fall inside `address`, ignoring ++ * this address's own subnet mask. ++ * ++ * This is the primitive the special-use classifiers (`isLoopback`, ++ * `isPrivate`, `isLinkLocal`, `getType`, …) are built on: they answer a ++ * question about the address, so the answer must not change with the CIDR ++ * suffix the caller happened to write. Use this rather than ++ * {@link isInSubnet} when classifying a single address — notably when the ++ * address came from untrusted input and the result backs a trust-boundary ++ * decision such as an SSRF allow/deny filter. ++ */ ++function isHostInSubnet(address) { ++ return this.mask(address.subnetMask) === address.mask(); + } + function isCorrect(defaultBits) { +- return function () { ++ return function isCorrectForm() { + if (this.addressMinusSuffix !== this.correctForm()) { + return false; + } +@@ -25,6 +51,40 @@ + return this.parsedSubnet === String(this.subnetMask); + }; + } ++/** ++ * Returns the prefix length (number of leading 1 bits) of a contiguous ++ * subnet mask. Throws `AddressError` if the mask is non-contiguous (e.g. ++ * `255.0.255.0`). ++ */ ++function prefixLengthFromMask(value, totalBits) { ++ const binary = value.toString(2).padStart(totalBits, '0'); ++ if (binary.length > totalBits) { ++ throw new address_error_1.AddressError('Invalid subnet mask.'); ++ } ++ const firstZero = binary.indexOf('0'); ++ if (firstZero === -1) { ++ return totalBits; ++ } ++ if (binary.slice(firstZero).includes('1')) { ++ throw new address_error_1.AddressError('Invalid subnet mask.'); ++ } ++ return firstZero; ++} ++/** ++ * Throws `AddressError` unless `bytes` holds exactly `byteCount` integers, ++ * each from `minimum` to 255. Pass a `minimum` of `-128` where signed bytes ++ * are accepted and folded to unsigned, and `0` where they are not. ++ */ ++function assertByteArray(bytes, byteCount, family, minimum) { ++ if (bytes.length !== byteCount) { ++ throw new address_error_1.AddressError(`${family} addresses require exactly ${byteCount} bytes`); ++ } ++ for (let i = 0; i < bytes.length; i++) { ++ if (!Number.isInteger(bytes[i]) || bytes[i] < minimum || bytes[i] > 255) { ++ throw new address_error_1.AddressError(`All bytes must be integers between ${minimum} and 255`); ++ } ++ } ++} + function numberToPaddedHex(number) { + return number.toString(16).padStart(2, '0'); + } + +diff --git a/deps/npm/node_modules/ip-address/dist/ipv4.js b/deps/npm/node_modules/ip-address/dist/ipv4.js +--- a/deps/npm/node_modules/ip-address/dist/ipv4.js ++++ b/deps/npm/node_modules/ip-address/dist/ipv4.js +@@ -28,13 +28,14 @@ + const common = __importStar(require("./common")); + const constants = __importStar(require("./v4/constants")); + const address_error_1 = require("./address-error"); ++const isCorrect4 = common.isCorrect(constants.BITS); + /** + * Represents an IPv4 address +- * @class Address4 + * @param {string} address - An IPv4 address string + */ + class Address4 { + constructor(address) { ++ this.addressMinusSuffix = ''; + this.groups = constants.GROUPS; + this.parsedAddress = []; + this.parsedSubnet = ''; +@@ -43,18 +44,21 @@ + this.v4 = true; + /** + * Returns true if the address is correct, false otherwise +- * @memberof Address4 +- * @instance + * @returns {Boolean} + */ +- this.isCorrect = common.isCorrect(constants.BITS); ++ this.isCorrect = isCorrect4; + /** + * Returns true if the given address is in the subnet of the current address +- * @memberof Address4 +- * @instance + * @returns {boolean} + */ + this.isInSubnet = common.isInSubnet; ++ /** ++ * Returns true if this address's host bits fall inside the given subnet, ++ * ignoring this address's own subnet mask. See ++ * {@link common.isHostInSubnet}. ++ * @returns {boolean} ++ */ ++ this.isHostInSubnet = common.isHostInSubnet; + this.address = address; + const subnet = constants.RE_SUBNET_STRING.exec(address); + if (subnet) { +@@ -69,66 +73,145 @@ + this.addressMinusSuffix = address; + this.parsedAddress = this.parse(address); + } ++ /** ++ * Returns true if the given string is a valid IPv4 address (with optional ++ * CIDR subnet), false otherwise. Host bits in the subnet portion are ++ * allowed (e.g. `192.168.1.5/24` is valid); for strict network-address ++ * validation compare `correctForm()` to `startAddress().correctForm()`, ++ * or use `networkForm()`. ++ */ + static isValid(address) { + try { + // eslint-disable-next-line no-new + new Address4(address); + return true; + } +- catch (e) { ++ catch { + return false; + } + } +- /* +- * Parses a v4 address ++ /** ++ * Parses an IPv4 address string into its four octet groups and stores the ++ * result on `this.parsedAddress`. Called automatically by the constructor; ++ * you typically don't need to call it directly. Throws `AddressError` if ++ * the input is not a valid IPv4 address. + */ + parse(address) { + const groups = address.split('.'); ++ // Checked before the general match so the error names the actual problem. ++ // Address6 rejects the same notation on its v4-in-v6 path. ++ if (groups.some((group) => /^0\d/.test(group))) { ++ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes."); ++ } + if (!address.match(constants.RE_ADDRESS)) { + throw new address_error_1.AddressError('Invalid IPv4 address.'); + } + return groups; + } + /** +- * Returns the correct form of an address +- * @memberof Address4 +- * @instance +- * @returns {String} ++ * Returns the address in correct form: octets joined with `.` and any ++ * leading zeros stripped (e.g. `192.168.1.1`). For IPv4 this matches the ++ * canonical dotted-decimal representation. + */ + correctForm() { + return this.parsedAddress.map((part) => parseInt(part, 10)).join('.'); + } + /** +- * Converts a hex string to an IPv4 address object +- * @memberof Address4 +- * @static ++ * Construct an `Address4` from an address and a dotted-decimal subnet ++ * mask given as separate strings (e.g. as returned by Node's ++ * `os.networkInterfaces()`). Throws `AddressError` if the mask is ++ * non-contiguous (e.g. `255.0.255.0`). ++ * @example ++ * var address = Address4.fromAddressAndMask('192.168.1.1', '255.255.255.0'); ++ * address.subnetMask; // 24 ++ */ ++ static fromAddressAndMask(address, mask) { ++ const bits = common.prefixLengthFromMask(new Address4(mask).bigInt(), constants.BITS); ++ return new Address4(`${address}/${bits}`); ++ } ++ /** ++ * Construct an `Address4` from an address and a Cisco-style wildcard mask ++ * given as separate strings (e.g. `0.0.0.255` for a `/24`). The wildcard ++ * mask is the bitwise inverse of the subnet mask. Throws `AddressError` ++ * if the mask is non-contiguous (e.g. `0.255.0.255`). ++ * @example ++ * var address = Address4.fromAddressAndWildcardMask('10.0.0.1', '0.0.0.255'); ++ * address.subnetMask; // 24 ++ */ ++ static fromAddressAndWildcardMask(address, wildcardMask) { ++ const wildcard = new Address4(wildcardMask).bigInt(); ++ const allOnes = (BigInt(1) << BigInt(constants.BITS)) - BigInt(1); ++ const mask = wildcard ^ allOnes; ++ const bits = common.prefixLengthFromMask(mask, constants.BITS); ++ return new Address4(`${address}/${bits}`); ++ } ++ /** ++ * Construct an `Address4` from a wildcard pattern with trailing `*` ++ * octets. The number of trailing wildcards determines the prefix ++ * length: each `*` represents 8 bits. ++ * ++ * Only trailing whole-octet wildcards are supported. Partial-octet ++ * wildcards (e.g. `192.168.0.1*`) and interior wildcards (e.g. ++ * `192.*.0.1`) throw `AddressError`. ++ * @example ++ * Address4.fromWildcard('192.168.0.*').subnet; // '/24' ++ * Address4.fromWildcard('192.168.*.*').subnet; // '/16' ++ * Address4.fromWildcard('*.*.*.*').subnet; // '/0' ++ */ ++ static fromWildcard(input) { ++ const groups = input.split('.'); ++ if (groups.length !== constants.GROUPS) { ++ throw new address_error_1.AddressError('Wildcard pattern must have 4 octets'); ++ } ++ let firstWildcard = -1; ++ for (let i = 0; i < groups.length; i++) { ++ if (groups[i] === '*') { ++ if (firstWildcard === -1) { ++ firstWildcard = i; ++ } ++ } ++ else if (firstWildcard !== -1) { ++ throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing octets (e.g. `192.168.0.*`)'); ++ } ++ } ++ const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard; ++ const replaced = groups.map((g) => (g === '*' ? '0' : g)); ++ const subnetBits = constants.BITS - trailing * 8; ++ return new Address4(`${replaced.join('.')}/${subnetBits}`); ++ } ++ /** ++ * Converts a hex string to an IPv4 address object. Accepts 8 hex digits ++ * with optional `:` separators (e.g. `'7f000001'` or `'7f:00:00:01'`). ++ * Throws `AddressError` for any other length or for non-hex characters. + * @param {string} hex - a hex string to convert + * @returns {Address4} + */ + static fromHex(hex) { +- const padded = hex.replace(/:/g, '').padStart(8, '0'); ++ const stripped = hex.replace(/:/g, ''); ++ if (!/^[0-9a-fA-F]{8}$/.test(stripped)) { ++ throw new address_error_1.AddressError('IPv4 hex must be exactly 8 hex digits'); ++ } + const groups = []; +- let i; +- for (i = 0; i < 8; i += 2) { +- const h = padded.slice(i, i + 2); +- groups.push(parseInt(h, 16)); ++ for (let i = 0; i < 8; i += 2) { ++ groups.push(parseInt(stripped.slice(i, i + 2), 16)); + } + return new Address4(groups.join('.')); + } + /** +- * Converts an integer into a IPv4 address object +- * @memberof Address4 +- * @static ++ * Converts an integer into a IPv4 address object. The integer must be a ++ * non-negative safe integer in the range `[0, 2**32 - 1]`; otherwise ++ * `AddressError` is thrown. + * @param {integer} integer - a number to convert + * @returns {Address4} + */ + static fromInteger(integer) { +- return Address4.fromHex(integer.toString(16)); ++ if (!Number.isInteger(integer) || integer < 0 || integer > 0xffffffff) { ++ throw new address_error_1.AddressError('IPv4 integer must be in the range 0 to 2**32 - 1'); ++ } ++ return Address4.fromHex(integer.toString(16).padStart(8, '0')); + } + /** + * Return an address from in-addr.arpa form +- * @memberof Address4 +- * @static + * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address + * @returns {Adress4} + * @example +@@ -143,17 +226,15 @@ + } + /** + * Converts an IPv4 address object to a hex string +- * @memberof Address4 +- * @instance + * @returns {String} + */ + toHex() { + return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':'); + } + /** +- * Converts an IPv4 address object to an array of bytes +- * @memberof Address4 +- * @instance ++ * Converts an IPv4 address object to an array of bytes. ++ * ++ * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toArray())`. + * @returns {Array} + */ + toArray() { +@@ -161,8 +242,6 @@ + } + /** + * Converts an IPv4 address object to an IPv6 address group +- * @memberof Address4 +- * @instance + * @returns {String} + */ + toGroup6() { +@@ -175,8 +254,6 @@ + } + /** + * Returns the address as a `bigint` +- * @memberof Address4 +- * @instance + * @returns {bigint} + */ + bigInt() { +@@ -184,8 +261,6 @@ + } + /** + * Helper function getting start address. +- * @memberof Address4 +- * @instance + * @returns {bigint} + */ + _startAddress() { +@@ -194,8 +269,6 @@ + /** + * The first address in the range given by this address' subnet. + * Often referred to as the Network Address. +- * @memberof Address4 +- * @instance + * @returns {Address4} + */ + startAddress() { +@@ -204,8 +277,6 @@ + /** + * The first host address in the range given by this address's subnet ie + * the first address after the Network Address +- * @memberof Address4 +- * @instance + * @returns {Address4} + */ + startAddressExclusive() { +@@ -214,8 +285,6 @@ + } + /** + * Helper function getting end address. +- * @memberof Address4 +- * @instance + * @returns {bigint} + */ + _endAddress() { +@@ -224,8 +293,6 @@ + /** + * The last address in the range given by this address' subnet + * Often referred to as the Broadcast +- * @memberof Address4 +- * @instance + * @returns {Address4} + */ + endAddress() { +@@ -234,8 +301,6 @@ + /** + * The last host address in the range given by this address's subnet ie + * the last address prior to the Broadcast Address +- * @memberof Address4 +- * @instance + * @returns {Address4} + */ + endAddressExclusive() { +@@ -243,38 +308,56 @@ + return Address4.fromBigInt(this._endAddress() - adjust); + } + /** +- * Converts a BigInt to a v4 address object +- * @memberof Address4 +- * @static ++ * The dotted-decimal form of the subnet mask, e.g. `255.255.240.0` for ++ * a `/20`. Returns an `Address4`; call `.correctForm()` for the string. ++ * @returns {Address4} ++ */ ++ subnetMaskAddress() { ++ return Address4.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants.BITS - this.subnetMask)}`)); ++ } ++ /** ++ * The Cisco-style wildcard mask, e.g. `0.0.0.255` for a `/24`. This is ++ * the bitwise inverse of `subnetMaskAddress()`. Returns an `Address4`; ++ * call `.correctForm()` for the string. ++ * @returns {Address4} ++ */ ++ wildcardMask() { ++ return Address4.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants.BITS - this.subnetMask)}`)); ++ } ++ /** ++ * The network address in CIDR string form, e.g. `192.168.1.0/24` for ++ * `192.168.1.5/24`. For an address with no explicit subnet the prefix is ++ * `/32`, e.g. `networkForm()` on `192.168.1.5` returns `192.168.1.5/32`. ++ * @returns {string} ++ */ ++ networkForm() { ++ return `${this.startAddress().correctForm()}/${this.subnetMask}`; ++ } ++ /** ++ * Converts a BigInt to a v4 address object. The value must be in the ++ * range `[0, 2**32 - 1]`; otherwise `AddressError` is thrown. + * @param {bigint} bigInt - a BigInt to convert + * @returns {Address4} + */ + static fromBigInt(bigInt) { +- return Address4.fromHex(bigInt.toString(16)); ++ if (bigInt < BigInt(0) || bigInt > BigInt(0xffffffff)) { ++ throw new address_error_1.AddressError('IPv4 BigInt must be in the range 0 to 2**32 - 1'); ++ } ++ return Address4.fromHex(bigInt.toString(16).padStart(8, '0')); + } + /** +- * Convert a byte array to an Address4 object +- * @memberof Address4 +- * @static ++ * Convert a byte array to an Address4 object. ++ * ++ * To convert from a Node.js `Buffer`, spread it: `Address4.fromByteArray([...buf])`. + * @param {Array} bytes - an array of 4 bytes (0-255) + * @returns {Address4} + */ + static fromByteArray(bytes) { +- if (bytes.length !== 4) { +- throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes'); +- } +- // Validate that all bytes are within valid range (0-255) +- for (let i = 0; i < bytes.length; i++) { +- if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) { +- throw new address_error_1.AddressError('All bytes must be integers between 0 and 255'); +- } +- } ++ common.assertByteArray(bytes, 4, 'IPv4', 0); + return this.fromUnsignedByteArray(bytes); + } + /** + * Convert an unsigned byte array to an Address4 object +- * @memberof Address4 +- * @static + * @param {Array} bytes - an array of 4 unsigned bytes (0-255) + * @returns {Address4} + */ +@@ -288,8 +371,6 @@ + /** + * Returns the first n bits of the address, defaulting to the + * subnet mask +- * @memberof Address4 +- * @instance + * @returns {String} + */ + mask(mask) { +@@ -300,8 +381,6 @@ + } + /** + * Returns the bits in the given range as a base-2 string +- * @memberof Address4 +- * @instance + * @returns {string} + */ + getBitsBase2(start, end) { +@@ -309,10 +388,8 @@ + } + /** + * Return the reversed ip6.arpa form of the address +- * @memberof Address4 + * @param {Object} options + * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix +- * @instance + * @returns {String} + */ + reverseForm(options) { +@@ -327,21 +404,62 @@ + } + /** + * Returns true if the given address is a multicast address +- * @memberof Address4 +- * @instance + * @returns {boolean} + */ + isMulticast() { +- return this.isInSubnet(new Address4('224.0.0.0/4')); ++ return this.isHostInSubnet(MULTICAST_V4); ++ } ++ /** ++ * Returns true if the address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private address ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`). ++ * @returns {boolean} ++ */ ++ isPrivate() { ++ return PRIVATE_V4.some((subnet) => this.isHostInSubnet(subnet)); ++ } ++ /** ++ * Returns true if the address is in the loopback range `127.0.0.0/8` ([RFC 1122](https://datatracker.ietf.org/doc/html/rfc1122)). ++ * @returns {boolean} ++ */ ++ isLoopback() { ++ return this.isHostInSubnet(LOOPBACK_V4); ++ } ++ /** ++ * Returns true if the address is in the link-local range `169.254.0.0/16` ([RFC 3927](https://datatracker.ietf.org/doc/html/rfc3927)). ++ * @returns {boolean} ++ */ ++ isLinkLocal() { ++ return this.isHostInSubnet(LINK_LOCAL_V4); ++ } ++ /** ++ * Returns true if the address is the unspecified address `0.0.0.0`. ++ * @returns {boolean} ++ */ ++ isUnspecified() { ++ return this.isHostInSubnet(UNSPECIFIED_V4); ++ } ++ /** ++ * Returns true if the address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)). ++ * @returns {boolean} ++ */ ++ isBroadcast() { ++ return this.isHostInSubnet(BROADCAST_V4); ++ } ++ /** ++ * Returns true if the address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)). ++ * @returns {boolean} ++ */ ++ isCGNAT() { ++ return this.isHostInSubnet(CGNAT_V4); + } + /** + * Returns a zero-padded base-2 string representation of the address +- * @memberof Address4 +- * @instance + * @returns {string} + */ + binaryZeroPad() { +- return this.bigInt().toString(2).padStart(constants.BITS, '0'); ++ if (this._binaryZeroPad === undefined) { ++ this._binaryZeroPad = this.bigInt().toString(2).padStart(constants.BITS, '0'); ++ } ++ return this._binaryZeroPad; + } + /** + * Groups an IPv4 address for inclusion at the end of an IPv6 address +@@ -349,7 +467,7 @@ + */ + groupForV6() { + const segments = this.parsedAddress; +- return this.address.replace(constants.RE_ADDRESS, `${segments ++ return this.correctForm().replace(constants.RE_ADDRESS, `${segments + .slice(0, 2) + .join('.')}.${segments + .slice(2, 4) +@@ -357,4 +475,15 @@ + } + } + exports.Address4 = Address4; ++const MULTICAST_V4 = new Address4('224.0.0.0/4'); ++const PRIVATE_V4 = [ ++ new Address4('10.0.0.0/8'), ++ new Address4('172.16.0.0/12'), ++ new Address4('192.168.0.0/16'), ++]; ++const LOOPBACK_V4 = new Address4('127.0.0.0/8'); ++const LINK_LOCAL_V4 = new Address4('169.254.0.0/16'); ++const UNSPECIFIED_V4 = new Address4('0.0.0.0/32'); ++const BROADCAST_V4 = new Address4('255.255.255.255/32'); ++const CGNAT_V4 = new Address4('100.64.0.0/10'); + //# sourceMappingURL=ipv4.js.map +\ No newline at end of file + +diff --git a/deps/npm/node_modules/ip-address/dist/ipv6.js b/deps/npm/node_modules/ip-address/dist/ipv6.js +--- a/deps/npm/node_modules/ip-address/dist/ipv6.js ++++ b/deps/npm/node_modules/ip-address/dist/ipv6.js +@@ -34,6 +34,7 @@ + const regular_expressions_1 = require("./v6/regular-expressions"); + const address_error_1 = require("./address-error"); + const common_1 = require("./common"); ++const isCorrect6 = common.isCorrect(constants6.BITS); + function assert(condition) { + if (!condition) { + throw new Error('Assertion failed.'); +@@ -72,12 +73,10 @@ + return parseInt(octet, 16).toString(16).padStart(4, '0'); + } + function unsignByte(b) { +- // eslint-disable-next-line no-bitwise + return b & 0xff; + } + /** + * Represents an IPv6 address +- * @class Address6 + * @param {string} address - An IPv6 address string + * @param {number} [groups=8] - How many octets to parse + * @example +@@ -94,18 +93,21 @@ + // #region Attributes + /** + * Returns true if the given address is in the subnet of the current address +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + this.isInSubnet = common.isInSubnet; + /** ++ * Returns true if this address's host bits fall inside the given subnet, ++ * ignoring this address's own subnet mask. See ++ * {@link common.isHostInSubnet}. ++ * @returns {boolean} ++ */ ++ this.isHostInSubnet = common.isHostInSubnet; ++ /** + * Returns true if the address is correct, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ +- this.isCorrect = common.isCorrect(constants6.BITS); ++ this.isCorrect = isCorrect6; + if (optionalGroups === undefined) { + this.groups = constants6.GROUPS; + } +@@ -125,7 +127,10 @@ + } + address = address.replace(constants6.RE_SUBNET_STRING, ''); + } +- else if (/\//.test(address)) { ++ // RE_SUBNET_STRING anchors on the end of the address, so it strips only ++ // the trailing suffix. A second one left behind (`::/0/1`) is malformed ++ // and must be rejected rather than parsed as an address group. ++ if (/\//.test(address)) { + throw new address_error_1.AddressError('Invalid subnet mask.'); + } + const zone = constants6.RE_ZONE_STRING.exec(address); +@@ -136,20 +141,26 @@ + this.addressMinusSuffix = address; + this.parsedAddress = this.parse(this.addressMinusSuffix); + } ++ /** ++ * Returns true if the given string is a valid IPv6 address (with optional ++ * CIDR subnet and zone identifier), false otherwise. Host bits in the ++ * subnet portion are allowed (e.g. `2001:db8::1/32` is valid); for strict ++ * network-address validation compare `correctForm()` to ++ * `startAddress().correctForm()`, or use `networkForm()`. ++ */ + static isValid(address) { + try { + // eslint-disable-next-line no-new + new Address6(address); + return true; + } +- catch (e) { ++ catch { + return false; + } + } + /** +- * Convert a BigInt to a v6 address object +- * @memberof Address6 +- * @static ++ * Convert a BigInt to a v6 address object. The value must be in the ++ * range `[0, 2**128 - 1]`; otherwise `AddressError` is thrown. + * @param {bigint} bigInt - a BigInt to convert + * @returns {Address6} + * @example +@@ -158,31 +169,36 @@ + * address.correctForm(); // '::e8:d4a5:1000' + */ + static fromBigInt(bigInt) { ++ if (bigInt < BigInt(0) || bigInt > (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1)) { ++ throw new address_error_1.AddressError('IPv6 BigInt must be in the range 0 to 2**128 - 1'); ++ } + const hex = bigInt.toString(16).padStart(32, '0'); + const groups = []; +- let i; +- for (i = 0; i < constants6.GROUPS; i++) { ++ for (let i = 0; i < constants6.GROUPS; i++) { + groups.push(hex.slice(i * 4, (i + 1) * 4)); + } + return new Address6(groups.join(':')); + } + /** +- * Convert a URL (with optional port number) to an address object +- * @memberof Address6 +- * @static +- * @param {string} url - a URL with optional port number ++ * Parse a URL (with optional bracketed host and port) into an address and ++ * port. Returns either `{ address, port }` on success or ++ * `{ error, address: null, port: null }` if the URL could not be parsed. ++ * Ports are returned as numbers (or `null` if absent or out of range). + * @example + * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/'); + * addressAndPort.address.correctForm(); // 'ffff::' + * addressAndPort.port; // 8080 + */ + static fromURL(url) { ++ var _a; + let host; + let port = null; + let result; ++ // Remove the protocol prefix, if any ++ const stripped = url.replace(/^[a-z][a-z0-9+.-]*:\/\//i, ''); + // If we have brackets parse them and find a port +- if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) { +- result = constants6.RE_URL_WITH_PORT.exec(url); ++ if (stripped.indexOf('[') !== -1 && stripped.indexOf(']:') !== -1) { ++ result = constants6.RE_URL_WITH_PORT.exec(stripped); + if (result === null) { + return { + error: 'failed to parse address with port', +@@ -192,13 +208,9 @@ + } + host = result[1]; + port = result[2]; +- // If there's a URL extract the address + } +- else if (url.indexOf('/') !== -1) { +- // Remove the protocol prefix +- url = url.replace(/^[a-z0-9]+:\/\//, ''); +- // Parse the address +- result = constants6.RE_URL.exec(url); ++ else { ++ result = constants6.RE_URL.exec(stripped); + if (result === null) { + return { + error: 'failed to parse address from URL', +@@ -206,17 +218,13 @@ + port: null, + }; + } +- host = result[1]; +- // Otherwise just assign the URL to the host and let the library parse it +- } +- else { +- host = url; ++ host = (_a = result[1]) !== null && _a !== void 0 ? _a : result[2]; + } + // If there's a port convert it to an integer + if (port) { + port = parseInt(port, 10); +- // squelch out of range ports +- if (port < 0 || port > 65536) { ++ // squelch out of range ports (valid ports are 0-65535) ++ if (port < 0 || port > 65535) { + port = null; + } + } +@@ -230,9 +238,90 @@ + }; + } + /** ++ * Construct an `Address6` from an address and a hex subnet mask given as ++ * separate strings (e.g. as returned by Node's `os.networkInterfaces()`). ++ * Throws `AddressError` if the mask is non-contiguous (e.g. ++ * `ffff::ffff`). ++ * @example ++ * var address = Address6.fromAddressAndMask('fe80::1', 'ffff:ffff:ffff:ffff::'); ++ * address.subnetMask; // 64 ++ */ ++ static fromAddressAndMask(address, mask) { ++ const bits = common.prefixLengthFromMask(new Address6(mask).bigInt(), constants6.BITS); ++ return new Address6(`${address}/${bits}`); ++ } ++ /** ++ * Construct an `Address6` from an address and a Cisco-style wildcard mask ++ * given as separate strings (e.g. `::ffff:ffff:ffff:ffff` for a `/64`). ++ * The wildcard mask is the bitwise inverse of the subnet mask. Throws ++ * `AddressError` if the mask is non-contiguous. ++ * @example ++ * var address = Address6.fromAddressAndWildcardMask('fe80::1', '::ffff:ffff:ffff:ffff'); ++ * address.subnetMask; // 64 ++ */ ++ static fromAddressAndWildcardMask(address, wildcardMask) { ++ const wildcard = new Address6(wildcardMask).bigInt(); ++ const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1); ++ const mask = wildcard ^ allOnes; ++ const bits = common.prefixLengthFromMask(mask, constants6.BITS); ++ return new Address6(`${address}/${bits}`); ++ } ++ /** ++ * Construct an `Address6` from a wildcard pattern with trailing `*` ++ * groups. The number of trailing wildcards determines the prefix ++ * length: each `*` represents 16 bits. `::` is expanded to zero groups ++ * (not wildcards) before evaluating trailing wildcards. ++ * ++ * Only trailing whole-group wildcards are supported. Partial-group ++ * wildcards (e.g. `2001:db8::0*`) and interior wildcards (e.g. ++ * `*::1`) throw `AddressError`. ++ * @example ++ * Address6.fromWildcard('2001:db8:*:*:*:*:*:*').subnet; // '/32' ++ * Address6.fromWildcard('2001:db8::*').subnet; // '/112' ++ * Address6.fromWildcard('*:*:*:*:*:*:*:*').subnet; // '/0' ++ */ ++ static fromWildcard(input) { ++ if (input.includes('%') || input.includes('/')) { ++ throw new address_error_1.AddressError('Wildcard pattern must not include a zone or CIDR suffix'); ++ } ++ const halves = input.split('::'); ++ if (halves.length > 2) { ++ throw new address_error_1.AddressError("Wildcard pattern cannot contain more than one '::'"); ++ } ++ let groups; ++ if (halves.length === 2) { ++ const left = halves[0] === '' ? [] : halves[0].split(':'); ++ const right = halves[1] === '' ? [] : halves[1].split(':'); ++ const remaining = constants6.GROUPS - left.length - right.length; ++ if (remaining < 1) { ++ throw new address_error_1.AddressError("Wildcard pattern with '::' has too many groups"); ++ } ++ groups = [...left, ...new Array(remaining).fill('0'), ...right]; ++ } ++ else { ++ groups = input.split(':'); ++ } ++ if (groups.length !== constants6.GROUPS) { ++ throw new address_error_1.AddressError('Wildcard pattern must have 8 groups'); ++ } ++ let firstWildcard = -1; ++ for (let i = 0; i < groups.length; i++) { ++ if (groups[i] === '*') { ++ if (firstWildcard === -1) { ++ firstWildcard = i; ++ } ++ } ++ else if (firstWildcard !== -1) { ++ throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing groups (e.g. `2001:db8:*:*:*:*:*:*`)'); ++ } ++ } ++ const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard; ++ const replaced = groups.map((g) => (g === '*' ? '0' : g)); ++ const subnetBits = constants6.BITS - trailing * 16; ++ return new Address6(`${replaced.join(':')}/${subnetBits}`); ++ } ++ /** + * Create an IPv6-mapped address given an IPv4 address +- * @memberof Address6 +- * @static + * @param {string} address - An IPv4 address string + * @returns {Address6} + * @example +@@ -247,8 +336,6 @@ + } + /** + * Return an address from ip6.arpa form +- * @memberof Address6 +- * @static + * @param {string} arpaFormAddress - an 'ip6.arpa' form address + * @returns {Adress6} + * @example +@@ -273,8 +360,6 @@ + } + /** + * Return the Microsoft UNC transcription of the address +- * @memberof Address6 +- * @instance + * @returns {String} the Microsoft UNC transcription of the address + */ + microsoftTranscription() { +@@ -282,8 +367,6 @@ + } + /** + * Return the first n bits of the address, defaulting to the subnet mask +- * @memberof Address6 +- * @instance + * @param {number} [mask=subnet] - the number of bits to mask + * @returns {String} the first n bits of the address as a string + */ +@@ -292,8 +375,6 @@ + } + /** + * Return the number of possible subnets of a given size in the address +- * @memberof Address6 +- * @instance + * @param {number} [subnetSize=128] - the subnet size + * @returns {String} + */ +@@ -309,8 +390,6 @@ + } + /** + * Helper function getting start address. +- * @memberof Address6 +- * @instance + * @returns {bigint} + */ + _startAddress() { +@@ -319,8 +398,6 @@ + /** + * The first address in the range given by this address' subnet + * Often referred to as the Network Address. +- * @memberof Address6 +- * @instance + * @returns {Address6} + */ + startAddress() { +@@ -329,8 +406,6 @@ + /** + * The first host address in the range given by this address's subnet ie + * the first address after the Network Address +- * @memberof Address6 +- * @instance + * @returns {Address6} + */ + startAddressExclusive() { +@@ -339,8 +414,6 @@ + } + /** + * Helper function getting end address. +- * @memberof Address6 +- * @instance + * @returns {bigint} + */ + _endAddress() { +@@ -349,8 +422,6 @@ + /** + * The last address in the range given by this address' subnet + * Often referred to as the Broadcast +- * @memberof Address6 +- * @instance + * @returns {Address6} + */ + endAddress() { +@@ -359,8 +430,6 @@ + /** + * The last host address in the range given by this address's subnet ie + * the last address prior to the Broadcast Address +- * @memberof Address6 +- * @instance + * @returns {Address6} + */ + endAddressExclusive() { +@@ -368,36 +437,73 @@ + return Address6.fromBigInt(this._endAddress() - adjust); + } + /** +- * Return the scope of the address +- * @memberof Address6 +- * @instance ++ * The hex form of the subnet mask, e.g. `ffff:ffff:ffff:ffff::` for a ++ * `/64`. Returns an `Address6`; call `.correctForm()` for the string. ++ * @returns {Address6} ++ */ ++ subnetMaskAddress() { ++ return Address6.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants6.BITS - this.subnetMask)}`)); ++ } ++ /** ++ * The Cisco-style wildcard mask, e.g. `::ffff:ffff:ffff:ffff` for a ++ * `/64`. This is the bitwise inverse of `subnetMaskAddress()`. Returns ++ * an `Address6`; call `.correctForm()` for the string. ++ * @returns {Address6} ++ */ ++ wildcardMask() { ++ return Address6.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants6.BITS - this.subnetMask)}`)); ++ } ++ /** ++ * The network address in CIDR string form, e.g. `2001:db8::/32` for ++ * `2001:db8::1/32`. For an address with no explicit subnet the prefix ++ * is `/128`, e.g. `networkForm()` on `2001:db8::1` returns ++ * `2001:db8::1/128`. ++ * @returns {string} ++ */ ++ networkForm() { ++ return `${this.startAddress().correctForm()}/${this.subnetMask}`; ++ } ++ /** ++ * Return the scope of the address. The 4-bit scope field ++ * ([RFC 4291 §2.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.7)) ++ * is only defined for multicast addresses; for unicast addresses the scope ++ * is derived from the address type per ++ * [RFC 4007 §6](https://datatracker.ietf.org/doc/html/rfc4007#section-6). + * @returns {String} + */ + getScope() { +- let scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)]; +- if (this.getType() === 'Global unicast' && scope !== 'Link local') { +- scope = 'Global'; ++ const type = this.getType(); ++ if (type === 'Multicast' || type.startsWith('Multicast ')) { ++ const scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)]; ++ return scope || 'Unknown'; ++ } ++ // RFC 4291 §2.5.3: the loopback address is treated as having Link-Local ++ // scope. (Multicast scope 1, "Interface-Local", is a different concept ++ // used only for loopback transmission of multicast.) ++ if (type === 'Link-local unicast' || type === 'Loopback') { ++ return 'Link local'; ++ } ++ // RFC 4007 §6: the unspecified address has no scope. ++ if (type === 'Unspecified') { ++ return 'Unknown'; + } +- return scope || 'Unknown'; ++ return 'Global'; + } + /** + * Return the type of the address +- * @memberof Address6 +- * @instance + * @returns {String} + */ + getType() { +- for (const subnet of Object.keys(constants6.TYPES)) { +- if (this.isInSubnet(new Address6(subnet))) { +- return constants6.TYPES[subnet]; ++ for (let i = 0; i < TYPE_SUBNETS.length; i++) { ++ const entry = TYPE_SUBNETS[i]; ++ if (this.isHostInSubnet(entry[0])) { ++ return entry[1]; + } + } + return 'Global unicast'; + } + /** + * Return the bits in the given range as a BigInt +- * @memberof Address6 +- * @instance + * @returns {bigint} + */ + getBits(start, end) { +@@ -405,8 +511,6 @@ + } + /** + * Return the bits in the given range as a base-2 string +- * @memberof Address6 +- * @instance + * @returns {String} + */ + getBitsBase2(start, end) { +@@ -414,8 +518,6 @@ + } + /** + * Return the bits in the given range as a base-16 string +- * @memberof Address6 +- * @instance + * @returns {String} + */ + getBitsBase16(start, end) { +@@ -429,8 +531,6 @@ + } + /** + * Return the bits that are set past the subnet mask length +- * @memberof Address6 +- * @instance + * @returns {String} + */ + getBitsPastSubnet() { +@@ -438,10 +538,8 @@ + } + /** + * Return the reversed ip6.arpa form of the address +- * @memberof Address6 + * @param {Object} options + * @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix +- * @instance + * @returns {String} + */ + reverseForm(options) { +@@ -467,10 +565,10 @@ + return 'ip6.arpa.'; + } + /** +- * Return the correct form of the address +- * @memberof Address6 +- * @instance +- * @returns {String} ++ * Returns the address in correct form, per ++ * [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952): leading zeros ++ * stripped, the longest run of zero groups collapsed to `::`, and hex digits ++ * lowercased (e.g. `2001:db8::1`). This is the recommended form for display. + */ + correctForm() { + let i; +@@ -514,8 +612,6 @@ + } + /** + * Return a zero-padded base-2 string representation of the address +- * @memberof Address6 +- * @instance + * @returns {String} + * @example + * var address = new Address6('2001:4860:4001:803::1011'); +@@ -524,27 +620,58 @@ + * // 0000000000000000000000000000000000000000000000000001000000010001' + */ + binaryZeroPad() { +- return this.bigInt().toString(2).padStart(constants6.BITS, '0'); ++ if (this._binaryZeroPad === undefined) { ++ this._binaryZeroPad = this.bigInt().toString(2).padStart(constants6.BITS, '0'); ++ } ++ return this._binaryZeroPad; + } ++ /** ++ * Parses a v4-in-v6 string (e.g. `::ffff:192.168.0.1`) by extracting the ++ * trailing IPv4 address into `this.address4` / `this.parsedAddress4` and ++ * returning the address with the v4 portion converted to two v6 groups. ++ * Used internally by `parse()`. ++ */ + // TODO: Improve the semantics of this helper function + parse4in6(address) { ++ if (address.indexOf('.') === -1) { ++ return address; ++ } + const groups = address.split(':'); + const lastGroup = groups.slice(-1)[0]; ++ // RE_ADDRESS rejects octets with a leading zero, so a dotted-quad tail is ++ // matched permissively first: that way this notation still gets its own ++ // message with the offending octet highlighted, rather than falling ++ // through as an unrecognized group. ++ const v4Octets = lastGroup.split('.'); ++ if (v4Octets.length === constants4.GROUPS && ++ v4Octets.every((octet) => /^\d{1,3}$/.test(octet))) { ++ if (v4Octets.some((octet) => /^0\d/.test(octet))) { ++ // The prefix groups haven't been through the bad-character check ++ // yet, so escape them before including in the error HTML. ++ const highlighted = v4Octets.map(spanLeadingZeroes4).join('.'); ++ const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':'); ++ const separator = groups.length > 1 ? ':' : ''; ++ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`); ++ } ++ } + const address4 = lastGroup.match(constants4.RE_ADDRESS); + if (address4) { + this.parsedAddress4 = address4[0]; +- this.address4 = new ipv4_1.Address4(this.parsedAddress4); +- for (let i = 0; i < this.address4.groups; i++) { +- if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) { +- throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", address.replace(constants4.RE_ADDRESS, this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'))); +- } +- } ++ const v4Suffix = this.subnetMask >= 96 ? `/${this.subnetMask - 96}` : ''; ++ this.address4 = new ipv4_1.Address4(`${this.parsedAddress4}${v4Suffix}`); + this.v4 = true; + groups[groups.length - 1] = this.address4.toGroup6(); + address = groups.join(':'); + } + return address; + } ++ /** ++ * Parses an IPv6 address string into its 8 hexadecimal groups (expanding ++ * any `::` elision and any trailing v4-in-v6 portion) and stores the result ++ * on `this.parsedAddress`. Called automatically by the constructor; you ++ * typically don't need to call it directly. Throws `AddressError` if the ++ * input is malformed. ++ */ + // TODO: Make private? + parse(address) { + address = this.parse4in6(address); +@@ -594,18 +721,16 @@ + return groups; + } + /** +- * Return the canonical form of the address +- * @memberof Address6 +- * @instance +- * @returns {String} ++ * Returns the canonical (fully expanded) form of the address: all 8 groups, ++ * each padded to 4 hex digits, with no `::` collapsing ++ * (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and ++ * byte-exact comparison. + */ + canonicalForm() { + return this.parsedAddress.map(paddedHex).join(':'); + } + /** + * Return the decimal form of the address +- * @memberof Address6 +- * @instance + * @returns {String} + */ + decimal() { +@@ -613,17 +738,17 @@ + } + /** + * Return the address as a BigInt +- * @memberof Address6 +- * @instance + * @returns {bigint} + */ + bigInt() { + return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`); + } + /** +- * Return the last two groups of this address as an IPv4 address string +- * @memberof Address6 +- * @instance ++ * Return the last two groups of this address as an IPv4 address string. ++ * If this address carries a CIDR prefix that covers the trailing 32 bits ++ * (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the ++ * corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to ++ * `/32`. + * @returns {Address4} + * @example + * var address = new Address6('2001:4860:4001::1825:bf11'); +@@ -631,12 +756,21 @@ + */ + to4() { + const binary = this.binaryZeroPad().split(''); +- return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16)); ++ const hex = BigInt(`0b${binary.slice(96, 128).join('')}`) ++ .toString(16) ++ .padStart(8, '0'); ++ if (this.subnetMask >= 96) { ++ const v4Mask = this.subnetMask - 96; ++ const groups = []; ++ for (let i = 0; i < 8; i += 2) { ++ groups.push(parseInt(hex.slice(i, i + 2), 16)); ++ } ++ return new ipv4_1.Address4(`${groups.join('.')}/${v4Mask}`); ++ } ++ return ipv4_1.Address4.fromHex(hex); + } + /** + * Return the v4-in-v6 form of the address +- * @memberof Address6 +- * @instance + * @returns {String} + */ + to4in6() { +@@ -647,13 +781,13 @@ + if (!/:$/.test(correct)) { + infix = ':'; + } +- return correct + infix + address4.address; ++ return correct + infix + address4.correctForm(); + } + /** +- * Return an object containing the Teredo properties of the address +- * @memberof Address6 +- * @instance +- * @returns {Object} ++ * Decodes the Teredo tunneling fields embedded in this address. Returns the ++ * Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag, ++ * UDP port, and Microsoft-format flag breakdown (reserved, universal/local, ++ * group/individual, nonce). Only meaningful for addresses in `2001::/32`. + */ + inspectTeredo() { + /* +@@ -679,12 +813,10 @@ + */ + const prefix = this.getBitsBase16(0, 32); + const bitsForUdpPort = this.getBits(80, 96); +- // eslint-disable-next-line no-bitwise + const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString(); + const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64)); + const bitsForClient4 = this.getBits(96, 128); +- // eslint-disable-next-line no-bitwise +- const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16)); ++ const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16).padStart(8, '0')); + const flagsBase2 = this.getBitsBase2(64, 80); + const coneNat = (0, common_1.testBit)(flagsBase2, 15); + const reserved = (0, common_1.testBit)(flagsBase2, 14); +@@ -707,10 +839,9 @@ + }; + } + /** +- * Return an object containing the 6to4 properties of the address +- * @memberof Address6 +- * @instance +- * @returns {Object} ++ * Decodes the 6to4 tunneling fields embedded in this address. Returns the ++ * 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for ++ * addresses in `2002::/16`. + */ + inspect6to4() { + /* +@@ -726,8 +857,6 @@ + } + /** + * Return a v6 6to4 address from a v6 v4inv6 address +- * @memberof Address6 +- * @instance + * @returns {Address6} + */ + to6to4() { +@@ -744,15 +873,88 @@ + return new Address6(addr6to4); + } + /** +- * Return a byte array +- * @memberof Address6 +- * @instance ++ * Embed an IPv4 address into a NAT64 IPv6 address using the encoding ++ * defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). ++ * The default prefix is the well-known prefix `64:ff9b::/96`. The prefix ++ * length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter ++ * than /64 the IPv4 octets are split around the reserved bits 64–71. ++ * @example ++ * Address6.fromAddress4Nat64('192.0.2.33').correctForm(); // '64:ff9b::c000:221' ++ * Address6.fromAddress4Nat64('192.0.2.33', '2001:db8::/32').correctForm(); // '2001:db8:c000:221::' ++ */ ++ static fromAddress4Nat64(address, prefix = '64:ff9b::/96') { ++ const v4 = new ipv4_1.Address4(address); ++ const prefix6 = new Address6(prefix); ++ const pl = prefix6.subnetMask; ++ if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) { ++ throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96'); ++ } ++ const prefixBits = prefix6.binaryZeroPad(); ++ const v4Bits = v4.binaryZeroPad(); ++ let bits; ++ if (pl === 96) { ++ bits = prefixBits.slice(0, 96) + v4Bits; ++ } ++ else { ++ const beforeU = 64 - pl; ++ bits = [ ++ prefixBits.slice(0, pl), ++ v4Bits.slice(0, beforeU), ++ // Bits 64 to 71 are the reserved u octet and are always zero. ++ '00000000', ++ v4Bits.slice(beforeU), ++ '0'.repeat(128 - 72 - (32 - beforeU)), ++ ].join(''); ++ } ++ const hex = BigInt(`0b${bits}`).toString(16).padStart(32, '0'); ++ const groups = []; ++ for (let i = 0; i < 8; i++) { ++ groups.push(hex.slice(i * 4, (i + 1) * 4)); ++ } ++ return new Address6(groups.join(':')); ++ } ++ /** ++ * Extract the embedded IPv4 address from a NAT64 IPv6 address using the ++ * encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). ++ * The default prefix is the well-known prefix `64:ff9b::/96`. Returns ++ * `null` if this address is not contained within the given prefix. ++ * @example ++ * new Address6('64:ff9b::c000:221').toAddress4Nat64()!.correctForm(); // '192.0.2.33' ++ */ ++ toAddress4Nat64(prefix = '64:ff9b::/96') { ++ const prefix6 = new Address6(prefix); ++ const pl = prefix6.subnetMask; ++ if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) { ++ throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96'); ++ } ++ if (!this.isHostInSubnet(prefix6)) { ++ return null; ++ } ++ const bits = this.binaryZeroPad(); ++ let v4Bits; ++ if (pl === 96) { ++ v4Bits = bits.slice(96, 128); ++ } ++ else { ++ const beforeU = 64 - pl; ++ v4Bits = bits.slice(pl, pl + beforeU) + bits.slice(72, 72 + (32 - beforeU)); ++ } ++ const octets = []; ++ for (let i = 0; i < 4; i++) { ++ octets.push(parseInt(v4Bits.slice(i * 8, (i + 1) * 8), 2).toString()); ++ } ++ return new ipv4_1.Address4(octets.join('.')); ++ } ++ /** ++ * Return a byte array. ++ * ++ * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`. + * @returns {Array} + */ + toByteArray() { +- const valueWithoutPadding = this.bigInt().toString(16); +- const leadingPad = '0'.repeat(valueWithoutPadding.length % 2); +- const value = `${leadingPad}${valueWithoutPadding}`; ++ const value = this.bigInt() ++ .toString(16) ++ .padStart(constants6.BITS / 4, '0'); + const bytes = []; + for (let i = 0, length = value.length; i < length; i += 2) { + bytes.push(parseInt(value.substring(i, i + 2), 16)); +@@ -760,30 +962,45 @@ + return bytes; + } + /** +- * Return an unsigned byte array +- * @memberof Address6 +- * @instance ++ * Return an unsigned byte array. ++ * ++ * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`. + * @returns {Array} + */ + toUnsignedByteArray() { ++ // toByteArray() emits 0 to 255, so unsigning it is an identity mapping and ++ // the two methods return equal arrays. 11.0.0 keeps one of them and makes ++ // this a deprecated alias; test/common-test.ts fails at that version. + return this.toByteArray().map(unsignByte); + } + /** +- * Convert a byte array to an Address6 object +- * @memberof Address6 +- * @static ++ * Convert a byte array to an Address6 object. ++ * ++ * Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an ++ * `Int8Array` or a Java `byte[]` holds them), folding signed values to their ++ * unsigned equivalent. Throws `AddressError` unless given exactly 16 ++ * integers from -128 to 255. ++ * ++ * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`. + * @returns {Address6} + */ + static fromByteArray(bytes) { ++ // Address4.fromByteArray takes unsigned bytes only. 11.0.0 aligns this ++ // method with it, at which point the -128 floor here, unsignByte, and the ++ // mapping below all go; test/common-test.ts fails at that version. ++ common.assertByteArray(bytes, 16, 'IPv6', -128); + return this.fromUnsignedByteArray(bytes.map(unsignByte)); + } + /** +- * Convert an unsigned byte array to an Address6 object +- * @memberof Address6 +- * @static ++ * Convert an unsigned byte array to an Address6 object. ++ * ++ * Throws `AddressError` unless given exactly 16 integers from 0 to 255. ++ * ++ * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`. + * @returns {Address6} + */ + static fromUnsignedByteArray(bytes) { ++ common.assertByteArray(bytes, 16, 'IPv6', 0); + const BYTE_MAX = BigInt('256'); + let result = BigInt('0'); + let multiplier = BigInt('1'); +@@ -795,8 +1012,6 @@ + } + /** + * Returns true if the address is in the canonical form, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + isCanonical() { +@@ -804,12 +1019,14 @@ + } + /** + * Returns true if the address is a link local address, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + isLinkLocal() { +- // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10' ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isLinkLocal(); ++ } ++ // Zeroes are required, i.e. we can't check isHostInSubnet with 'fe80::/10' + if (this.getBitsBase2(0, 64) === + '1111111010000000000000000000000000000000000000000000000000000000') { + return true; +@@ -818,53 +1035,163 @@ + } + /** + * Returns true if the address is a multicast address, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + isMulticast() { +- return this.getType() === 'Multicast'; ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isMulticast(); ++ } ++ const type = this.getType(); ++ return type === 'Multicast' || type.startsWith('Multicast '); + } + /** +- * Returns true if the address is a v4-in-v6 address, false otherwise +- * @memberof Address6 +- * @instance ++ * Returns true if the address was written in v4-in-v6 dotted-quad notation ++ * (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag ++ * and does not reflect whether the address bits lie in the IPv4-mapped ++ * (`::ffff:0:0/96`) subnet — for that, see {@link isMapped4}. + * @returns {boolean} + */ + is4() { + return this.v4; + } + /** ++ * Returns true if the address is an IPv4-mapped IPv6 address in ++ * `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)), ++ * false otherwise. Unlike {@link is4}, this checks the underlying address ++ * bits rather than the textual notation, so `::ffff:127.0.0.1` and ++ * `::ffff:7f00:1` both return true. ++ * @returns {boolean} ++ */ ++ isMapped4() { ++ return this.isHostInSubnet(IPV4_MAPPED_SUBNET); ++ } ++ /** ++ * If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped ++ * (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`, ++ * [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that ++ * embedded address as an {@link Address4}; otherwise return null. ++ * ++ * The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`, ++ * `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and ++ * delegate to the embedded {@link Address4} when present, so a literal such as ++ * `::ffff:127.0.0.1` is classified by what it actually reaches (loopback) ++ * rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped). ++ * This matters wherever the checks back a trust-boundary decision (e.g. an ++ * SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`, ++ * `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as ++ * non-internal. ++ * @returns {Address4 | null} ++ */ ++ embeddedIPv4() { ++ if (this.isMapped4() || this.isHostInSubnet(NAT64_WELL_KNOWN_SUBNET)) { ++ return this.to4(); ++ } ++ return null; ++ } ++ /** + * Returns true if the address is a Teredo address, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + isTeredo() { +- return this.isInSubnet(new Address6('2001::/32')); ++ return this.isHostInSubnet(TEREDO_SUBNET); + } + /** + * Returns true if the address is a 6to4 address, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + is6to4() { +- return this.isInSubnet(new Address6('2002::/16')); ++ return this.isHostInSubnet(SIX_TO_FOUR_SUBNET); + } + /** + * Returns true if the address is a loopback address, false otherwise +- * @memberof Address6 +- * @instance + * @returns {boolean} + */ + isLoopback() { ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isLoopback(); ++ } + return this.getType() === 'Loopback'; + } ++ /** ++ * Returns true if the address is a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)). ULAs are the IPv6 equivalent of IPv4 [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private addresses. ++ * @returns {boolean} ++ */ ++ isULA() { ++ return this.isHostInSubnet(ULA_SUBNET); ++ } ++ /** ++ * Returns true if the address is private, i.e. a Unique Local Address in ++ * `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)) or an ++ * IPv4-mapped / NAT64 address whose embedded IPv4 address is in one of the ++ * [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private ranges ++ * (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to ++ * {@link Address4.isPrivate}; use it instead of {@link isULA} when you need to ++ * catch mapped RFC 1918 addresses as well as native ULAs. ++ * @returns {boolean} ++ */ ++ isPrivate() { ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isPrivate(); ++ } ++ return this.isULA(); ++ } ++ /** ++ * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded ++ * IPv4 address is in the carrier-grade NAT range `100.64.0.0/10` ++ * ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false ++ * otherwise. There is no native IPv6 CGNAT range, so this only ever returns ++ * true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`). ++ * @returns {boolean} ++ */ ++ isCGNAT() { ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isCGNAT(); ++ } ++ return false; ++ } ++ /** ++ * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded ++ * IPv4 address is the limited broadcast address `255.255.255.255` ++ * ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise. ++ * There is no IPv6 broadcast, so this only ever returns true for an embedded ++ * IPv4 address (e.g. `::ffff:255.255.255.255`). ++ * @returns {boolean} ++ */ ++ isBroadcast() { ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isBroadcast(); ++ } ++ return false; ++ } ++ /** ++ * Returns true if the address is the unspecified address `::`. ++ * @returns {boolean} ++ */ ++ isUnspecified() { ++ const embedded = this.embeddedIPv4(); ++ if (embedded) { ++ return embedded.isUnspecified(); ++ } ++ return this.getType() === 'Unspecified'; ++ } ++ /** ++ * Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)). ++ * @returns {boolean} ++ */ ++ isDocumentation() { ++ return this.isHostInSubnet(DOCUMENTATION_SUBNET); ++ } + // #endregion + // #region HTML + /** +- * @returns {String} the address in link form with a default port of 80 ++ * Returns the address as an HTTP URL with the host bracketed, e.g. ++ * `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended, ++ * e.g. `http://[2001:db8::1]:8080/`. + */ + href(optionalPort) { + if (optionalPort === undefined) { +@@ -876,7 +1203,12 @@ + return `http://[${this.correctForm()}]${optionalPort}/`; + } + /** +- * @returns {String} a link suitable for conveying the address via a URL hash ++ * Returns an HTML `` element whose `href` encodes the address in a URL ++ * hash fragment (default prefix `/#address=`). Useful for linking between ++ * pages of an address-inspector UI. ++ * @param options.className - CSS class for the rendered `` element ++ * @param options.prefix - hash prefix prepended to the address (default `/#address=`) ++ * @param options.v4 - when true, render the address in v4-in-v6 form + */ + link(options) { + if (!options) { +@@ -896,10 +1228,13 @@ + formFunction = this.to4in6; + } + const form = formFunction.call(this); ++ const safeHref = helpers.escapeHtml(`${options.prefix}${form}`); ++ const safeForm = helpers.escapeHtml(form); + if (options.className) { +- return `${form}`; ++ const safeClass = helpers.escapeHtml(options.className); ++ return `${safeForm}`; + } +- return `${form}`; ++ return `${safeForm}`; + } + /** + * Groups an address +@@ -908,13 +1243,13 @@ + group() { + if (this.elidedGroups === 0) { + // The simple case +- return helpers.simpleGroup(this.address).join(':'); ++ return helpers.simpleGroup(this.addressMinusSuffix).join(':'); + } + assert(typeof this.elidedGroups === 'number'); + assert(typeof this.elisionBegin === 'number'); + // The elided case + const output = []; +- const [left, right] = this.address.split('::'); ++ const [left, right] = this.addressMinusSuffix.split('::'); + if (left.length) { + output.push(...helpers.simpleGroup(left)); + } +@@ -944,8 +1279,6 @@ + /** + * Generate a regular expression string that can be used to find or validate + * all variations of this address +- * @memberof Address6 +- * @instance + * @param {boolean} substringSearch + * @returns {string} + */ +@@ -990,8 +1323,6 @@ + /** + * Generate a regular expression that can be used to find or validate all + * variations of this address. +- * @memberof Address6 +- * @instance + * @param {boolean} substringSearch + * @returns {RegExp} + */ +@@ -1000,4 +1331,14 @@ + } + } + exports.Address6 = Address6; ++const TYPE_SUBNETS = Object.keys(constants6.TYPES).map((subnet) => [ ++ new Address6(subnet), ++ constants6.TYPES[subnet], ++]); ++const TEREDO_SUBNET = new Address6('2001::/32'); ++const SIX_TO_FOUR_SUBNET = new Address6('2002::/16'); ++const ULA_SUBNET = new Address6('fc00::/7'); ++const DOCUMENTATION_SUBNET = new Address6('2001:db8::/32'); ++const IPV4_MAPPED_SUBNET = new Address6('::ffff:0:0/96'); ++const NAT64_WELL_KNOWN_SUBNET = new Address6('64:ff9b::/96'); + //# sourceMappingURL=ipv6.js.map +\ No newline at end of file + +diff --git a/deps/npm/node_modules/ip-address/dist/v4/constants.js b/deps/npm/node_modules/ip-address/dist/v4/constants.js +--- a/deps/npm/node_modules/ip-address/dist/v4/constants.js ++++ b/deps/npm/node_modules/ip-address/dist/v4/constants.js +@@ -3,6 +3,10 @@ + exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0; + exports.BITS = 32; + exports.GROUPS = 4; +-exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g; ++// Each octet is 0-255 written without a leading zero. A leading zero is ++// octal to the WHATWG URL parser, inet_aton, and getaddrinfo, but decimal to ++// parseInt(part, 10), so accepting the notation would make this library ++// disagree with the network stack about which host a string names. ++exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/g; + exports.RE_SUBNET_STRING = /\/\d{1,2}$/; + //# sourceMappingURL=constants.js.map +\ No newline at end of file + +diff --git a/deps/npm/node_modules/ip-address/dist/v6/constants.js b/deps/npm/node_modules/ip-address/dist/v6/constants.js +--- a/deps/npm/node_modules/ip-address/dist/v6/constants.js ++++ b/deps/npm/node_modules/ip-address/dist/v6/constants.js +@@ -44,8 +44,14 @@ + 'ff05::1:3/128': 'Multicast (All DHCP servers in this site)', + '::/128': 'Unspecified', + '::1/128': 'Loopback', ++ '::ffff:0:0/96': 'IPv4-mapped', + 'ff00::/8': 'Multicast', + 'fe80::/10': 'Link-local unicast', ++ 'fc00::/7': 'Unique local', ++ '2002::/16': '6to4', ++ '2001:db8::/32': 'Documentation', ++ '64:ff9b::/96': 'NAT64 (well-known)', ++ '64:ff9b:1::/48': 'NAT64 (local-use)', + }; + /** + * A regular expression that matches bad characters in an IPv6 address +@@ -71,6 +77,6 @@ + * @static + */ + exports.RE_ZONE_STRING = /%.*$/; +-exports.RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/; +-exports.RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/; ++exports.RE_URL = /^(?:\[([0-9a-f:.]+)\]|([0-9a-f:.]+))(?:[/?#].*)?$/i; ++exports.RE_URL_WITH_PORT = /^\[([0-9a-f:.]+)\]:([0-9]{1,5})(?:[/?#].*)?$/i; + //# sourceMappingURL=constants.js.map +\ No newline at end of file + +diff --git a/deps/npm/node_modules/ip-address/dist/v6/helpers.js b/deps/npm/node_modules/ip-address/dist/v6/helpers.js +--- a/deps/npm/node_modules/ip-address/dist/v6/helpers.js ++++ b/deps/npm/node_modules/ip-address/dist/v6/helpers.js +@@ -1,14 +1,23 @@ + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); ++exports.escapeHtml = escapeHtml; + exports.spanAllZeroes = spanAllZeroes; + exports.spanAll = spanAll; + exports.spanLeadingZeroes = spanLeadingZeroes; + exports.simpleGroup = simpleGroup; ++function escapeHtml(s) { ++ return s ++ .replace(/&/g, '&') ++ .replace(//g, '>') ++ .replace(/"/g, '"') ++ .replace(/'/g, '''); ++} + /** + * @returns {String} the string with all zeroes contained in a + */ + function spanAllZeroes(s) { +- return s.replace(/(0+)/g, '$1'); ++ return escapeHtml(s).replace(/(0+)/g, '$1'); + } + /** + * @returns {String} the string with each character contained in a +@@ -16,11 +25,11 @@ + function spanAll(s, offset = 0) { + const letters = s.split(''); + return letters +- .map((n, i) => `${spanAllZeroes(n)}`) ++ .map((n, i) => `${spanAllZeroes(n)}`) + .join(''); + } + function spanLeadingZeroesSimple(group) { +- return group.replace(/^(0+)/, '$1'); ++ return escapeHtml(group).replace(/^(0+)/, '$1'); + } + /** + * @returns {String} the string with leading zeroes contained in a + +diff --git a/deps/npm/node_modules/ip-address/package.json b/deps/npm/node_modules/ip-address/package.json +--- a/deps/npm/node_modules/ip-address/package.json ++++ b/deps/npm/node_modules/ip-address/package.json +@@ -2,77 +2,89 @@ + "name": "ip-address", + "description": "A library for parsing IPv4 and IPv6 IP addresses in node and the browser.", + "keywords": [ +- "ipv6", ++ "ip", + "ipv4", +- "browser", +- "validation" ++ "ipv6", ++ "address", ++ "cidr", ++ "subnet", ++ "netmask", ++ "validate", ++ "validation", ++ "parse", ++ "arpa", ++ "bigint", ++ "browser" + ], +- "version": "10.1.0", ++ "version": "10.4.0", + "author": "Beau Gunderson (https://beaugunderson.com/)", + "license": "MIT", + "main": "dist/ip-address.js", + "types": "dist/ip-address.d.ts", + "scripts": { +- "docs": "documentation build --github --output docs --format html ./ip-address.js", ++ "docs": "tsx scripts/build-readme.ts", + "build": "rm -rf dist; mkdir dist; tsc", +- "prepack": "npm run build", +- "release": "release-it", +- "test-ci": "nyc mocha", ++ "prepack": "npm run docs && npm run build", ++ "prepare": "git config core.hooksPath hooks || true", ++ "lint": "prettier --check . && eslint . --ext .ts,.js --max-warnings 0", ++ "lint:fix": "prettier --write . && eslint . --ext .ts,.js --max-warnings 0 --fix", ++ "test-ci": "c8 --experimental-monocart mocha", + "test": "mocha", + "watch": "mocha --watch" + }, +- "nyc": { +- "extension": [ +- ".ts" ++ "c8": { ++ "include": [ ++ "src/**/*.ts" + ], + "exclude": [ + "**/*.d.ts", +- ".eslintrc.js", +- "coverage/", +- "dist/", +- "test/", +- "tmp/" ++ "src/ip-address.ts", ++ "src/v4/constants.ts", ++ "src/v6/constants.ts" + ], + "reporter": [ + "html", + "lcov", + "text" +- ], +- "all": true ++ ] + }, + "engines": { + "node": ">= 12" + }, ++ "sideEffects": false, + "files": [ +- "src", + "dist" + ], + "repository": { + "type": "git", +- "url": "git://github.com/beaugunderson/ip-address.git" ++ "url": "https://github.com/beaugunderson/ip-address.git" ++ }, ++ "overrides": { ++ "diff": "^8.0.3", ++ "serialize-javascript": "^7.0.5", ++ "@eslint/plugin-kit": "^0.7.1" + }, + "devDependencies": { +- "@types/chai": "^5.0.0", +- "@types/mocha": "^10.0.8", +- "@typescript-eslint/eslint-plugin": "^8.8.0", +- "@typescript-eslint/parser": "^8.8.0", +- "chai": "^5.1.1", +- "documentation": "^14.0.3", +- "eslint": "^8.50.0", ++ "@types/chai": "^5.2.3", ++ "@types/mocha": "^10.0.10", ++ "@typescript-eslint/eslint-plugin": "^8.59.1", ++ "@typescript-eslint/parser": "^8.59.1", ++ "c8": "^11.0.0", ++ "chai": "^6.2.2", ++ "eslint": "^8.57.1", + "eslint_d": "^14.0.4", +- "eslint-config-airbnb": "^19.0.4", +- "eslint-config-prettier": "^9.1.0", ++ "eslint-config-airbnb-base": "^15.0.0", ++ "eslint-config-prettier": "^10.1.8", + "eslint-plugin-filenames": "^1.3.2", +- "eslint-plugin-import": "^2.30.0", +- "eslint-plugin-jsx-a11y": "^6.10.0", +- "eslint-plugin-prettier": "^5.2.1", ++ "eslint-plugin-import": "^2.32.0", ++ "eslint-plugin-prettier": "^5.5.5", + "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", +- "mocha": "^10.7.3", +- "nyc": "^17.1.0", +- "prettier": "^3.3.3", +- "release-it": "^17.6.0", ++ "mocha": "^11.7.5", ++ "monocart-coverage-reports": "^2.12.11", ++ "prettier": "^3.8.3", + "source-map-support": "^0.5.21", +- "tsx": "^4.19.1", ++ "tsx": "^4.21.0", ++ "typedoc": "^0.28.19", + "typescript": "<5.6.0" + } + } diff --git a/SOURCES/0001-update-sqlite-to-3.53.4.patch b/SOURCES/0001-update-sqlite-to-3.53.4.patch new file mode 100644 index 0000000..0351727 --- /dev/null +++ b/SOURCES/0001-update-sqlite-to-3.53.4.patch @@ -0,0 +1,21461 @@ +From d252d0db095204f4954e5858d61292930097da6c Mon Sep 17 00:00:00 2001 +From: Andrei Radchenko +Date: Fri, 31 Jul 2026 14:30:02 +0200 +Subject: [PATCH] deps: update sqlite to 3.53.4 + +Fixes: CVE-2026-11824, CVE-2026-11822 +--- + deps/sqlite/sqlite3.c | 12820 ++++++++++++++++++++++++------------- + deps/sqlite/sqlite3.h | 591 +- + deps/sqlite/sqlite3ext.h | 11 +- + 3 files changed, 8742 insertions(+), 4680 deletions(-) + +diff --git a/deps/sqlite/sqlite3.c b/deps/sqlite/sqlite3.c +index 851a2504..0644a39f 100644 +--- a/deps/sqlite/sqlite3.c ++++ b/deps/sqlite/sqlite3.c +@@ -1,6 +1,6 @@ + /****************************************************************************** + ** This file is an amalgamation of many separate C source files from SQLite +-** version 3.51.3. By combining all the individual C code files into this ++** version 3.53.4. By combining all the individual C code files into this + ** single large file, the entire code can be compiled as a single translation + ** unit. This allows many compilers to do optimizations that would not be + ** possible if the files were compiled separately. Performance improvements +@@ -18,7 +18,7 @@ + ** separate file. This file contains only code for the core SQLite library. + ** + ** The content in this amalgamation comes from Fossil check-in +-** 737ae4a34738ffa0c3ff7f9bb18df914dd1c with changes in files: ++** bf7c7f30031888f4e796e429ab3978879485 with changes in files: + ** + ** + */ +@@ -467,12 +467,12 @@ extern "C" { + ** [sqlite3_libversion_number()], [sqlite3_sourceid()], + ** [sqlite_version()] and [sqlite_source_id()]. + */ +-#define SQLITE_VERSION "3.51.3" +-#define SQLITE_VERSION_NUMBER 3051003 +-#define SQLITE_SOURCE_ID "2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618" +-#define SQLITE_SCM_BRANCH "branch-3.51" +-#define SQLITE_SCM_TAGS "release version-3.51.3" +-#define SQLITE_SCM_DATETIME "2026-03-13T10:38:09.694Z" ++#define SQLITE_VERSION "3.53.4" ++#define SQLITE_VERSION_NUMBER 3053004 ++#define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc" ++#define SQLITE_SCM_BRANCH "branch-3.53" ++#define SQLITE_SCM_TAGS "release version-3.53.4" ++#define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z" + + /* + ** CAPI3REF: Run-Time Library Version Numbers +@@ -899,7 +899,7 @@ SQLITE_API int sqlite3_exec( + #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) + #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) + #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) +-#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ ++#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */ + + /* + ** CAPI3REF: Flags For File Open Operations +@@ -1611,6 +1611,12 @@ struct sqlite3_io_methods { + #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE + #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + ++/* reserved file-control numbers: ++** 101 ++** 102 ++** 103 ++*/ ++ + + /* + ** CAPI3REF: Mutex Handle +@@ -1811,7 +1817,7 @@ typedef const char *sqlite3_filename; + ** greater and the function pointer is not NULL) and will fall back + ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. + ** +-** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces ++** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces + ** are not used by the SQLite core. These optional interfaces are provided + ** by some VFSes to facilitate testing of the VFS code. By overriding + ** system calls with functions under its control, a test program can +@@ -2032,7 +2038,8 @@ SQLITE_API int sqlite3_os_end(void); + ** are called "anytime configuration options". + ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before + ** [sqlite3_shutdown()] with a first argument that is not an anytime +-** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. ++** configuration option, then the sqlite3_config() call will ++** return SQLITE_MISUSE. + ** Note, however, that ^sqlite3_config() can be called as part of the + ** implementation of an application-defined [sqlite3_os_init()]. + ** +@@ -2598,9 +2605,10 @@ struct sqlite3_mem_methods { + ** is less than 8. The "sz" argument should be a multiple of 8 less than + ** 65536. If "sz" does not meet this constraint, it is reduced in size until + ** it does. +-**
  • The third argument ("cnt") is the number of slots. Lookaside is disabled +-** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so +-** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" ++**

  • The third argument ("cnt") is the number of slots. ++** Lookaside is disabled if "cnt"is less than 1. ++* The "cnt" value will be reduced, if necessary, so ++** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" + ** parameter is usually chosen so that the product of "sz" and "cnt" is less + ** than 1,000,000. + ** +@@ -2888,12 +2896,15 @@ struct sqlite3_mem_methods { + ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] + **

    SQLITE_DBCONFIG_STMT_SCANSTATUS
    + **
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in +-** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears +-** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() +-** statistics. For statistics to be collected, the flag must be set on +-** the database handle both when the SQL statement is prepared and when it +-** is stepped. The flag is set (collection of statistics is enabled) +-** by default.

    This option takes two arguments: an integer and a pointer to ++** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears ++** a flag that enables collection of run-time performance statistics ++** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] ++** columns of the [bytecode virtual table]. ++** For statistics to be collected, the flag must be set on ++** the database handle both when the SQL statement is ++** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. ++** The flag is set (collection of statistics is enabled) by default. ++**

    This option takes two arguments: an integer and a pointer to + ** an integer. The first argument is 1, 0, or -1 to enable, disable, or + ** leave unchanged the statement scanstatus option. If the second argument + ** is not NULL, then the value of the statement scanstatus setting after +@@ -2966,16 +2977,34 @@ struct sqlite3_mem_methods { + ** comments are allowed in SQL text after processing the first argument. + **

    + ** ++** [[SQLITE_DBCONFIG_FP_DIGITS]] ++**
    SQLITE_DBCONFIG_FP_DIGITS
    ++**
    The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines ++** the number of significant digits that SQLite will attempt to preserve when ++** converting floating point numbers (IEEE 754 "doubles") into text. The ++** default value 17, as of SQLite version 3.52.0. The value was 15 in all ++** prior versions.

    ++** This option takes two arguments which are an integer and a pointer ++** to an integer. The first argument is a small integer, between 3 and 23, or ++** zero. The FP_DIGITS setting is changed to that small integer, or left ++** unaltered if the first argument is zero or out of range. The second argument ++** is a pointer to an integer. If the pointer is not NULL, then the value of ++** the FP_DIGITS setting, after possibly being modified by the first ++** arguments, is written into the integer to which the second argument points. ++**

    ++** + ** + ** + ** [[DBCONFIG arguments]]

    Arguments To SQLITE_DBCONFIG Options

    + ** + **

    Most of the SQLITE_DBCONFIG options take two arguments, so that the + ** overall call to [sqlite3_db_config()] has a total of four parameters. +-** The first argument (the third parameter to sqlite3_db_config()) is an integer. +-** The second argument is a pointer to an integer. If the first argument is 1, +-** then the option becomes enabled. If the first integer argument is 0, then the +-** option is disabled. If the first argument is -1, then the option setting ++** The first argument (the third parameter to sqlite3_db_config()) is ++** an integer. ++** The second argument is a pointer to an integer. If the first argument is 1, ++** then the option becomes enabled. If the first integer argument is 0, ++** then the option is disabled. ++** If the first argument is -1, then the option setting + ** is unchanged. The second argument, the pointer to an integer, may be NULL. + ** If the second argument is not NULL, then a value of 0 or 1 is written into + ** the integer to which the second argument points, depending on whether the +@@ -2983,9 +3012,10 @@ struct sqlite3_mem_methods { + ** the first argument. + ** + **

    While most SQLITE_DBCONFIG options use the argument format +-** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME] +-** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the +-** documentation of those exceptional options for details. ++** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME], ++** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options ++** are different. See the documentation of those exceptional options for ++** details. + */ + #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ + #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +@@ -3010,7 +3040,8 @@ struct sqlite3_mem_methods { + #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ + #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ + #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ +-#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */ ++#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */ ++#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */ + + /* + ** CAPI3REF: Enable Or Disable Extended Result Codes +@@ -4492,6 +4523,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); + **

  • sqlite3_errmsg() + **
  • sqlite3_errmsg16() + **
  • sqlite3_error_offset() ++**
  • sqlite3_db_handle() + ** + ** + ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +@@ -4538,7 +4570,7 @@ SQLITE_API const char *sqlite3_errstr(int); + SQLITE_API int sqlite3_error_offset(sqlite3 *db); + + /* +-** CAPI3REF: Set Error Codes And Message ++** CAPI3REF: Set Error Code And Message + ** METHOD: sqlite3 + ** + ** Set the error code of the database handle passed as the first argument +@@ -4655,7 +4687,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + ** or in an ORDER BY or GROUP BY clause.)^ + ** + ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    +-**
    The maximum depth of the parse tree on any expression.
    )^ ++**
    The maximum depth of the parse tree on any expression and ++** the maximum nesting depth for subqueries and VIEWs
    )^ ++** ++** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(
    SQLITE_LIMIT_PARSER_DEPTH
    ++**
    The maximum depth of the LALR(1) parser stack used to analyze ++** input SQL statements.
    )^ + ** + ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    + **
    The maximum number of terms in a compound SELECT statement.
    )^ +@@ -4682,7 +4719,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + **
    The maximum index number of any [parameter] in an SQL statement.)^ + ** + ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    +-**
    The maximum depth of recursion for triggers.
    )^ ++**
    The maximum depth of recursion for triggers, and the maximum ++** nesting depth for separate triggers.
    )^ + ** + ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    + **
    The maximum number of auxiliary worker threads that a single +@@ -4701,6 +4739,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + #define SQLITE_LIMIT_VARIABLE_NUMBER 9 + #define SQLITE_LIMIT_TRIGGER_DEPTH 10 + #define SQLITE_LIMIT_WORKER_THREADS 11 ++#define SQLITE_LIMIT_PARSER_DEPTH 12 + + /* + ** CAPI3REF: Prepare Flags +@@ -4745,12 +4784,29 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + ** fails, the sqlite3_prepare_v3() call returns the same error indications + ** with or without this flag; it just omits the call to [sqlite3_log()] that + ** logs the error. ++** ++** [[SQLITE_PREPARE_FROM_DDL]]
    SQLITE_PREPARE_FROM_DDL
    ++**
    The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce ++** security constraints that would otherwise only be enforced when parsing ++** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag ++** causes the SQL compiler to treat the SQL statement being prepared as if ++** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and ++** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called ++** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only ++** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice ++** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that ++** is derived from parts of the database schema. In particular, virtual ++** table implementations that run SQL statements that are derived from ++** arguments to their CREATE VIRTUAL TABLE statement should always use ++** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to ++** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks. + ** + */ + #define SQLITE_PREPARE_PERSISTENT 0x01 + #define SQLITE_PREPARE_NORMALIZE 0x02 + #define SQLITE_PREPARE_NO_VTAB 0x04 + #define SQLITE_PREPARE_DONT_LOG 0x10 ++#define SQLITE_PREPARE_FROM_DDL 0x20 + + /* + ** CAPI3REF: Compiling An SQL Statement +@@ -4764,8 +4820,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + ** + ** The preferred routine to use is [sqlite3_prepare_v2()]. The + ** [sqlite3_prepare()] interface is legacy and should be avoided. +-** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used +-** for special purposes. ++** [sqlite3_prepare_v3()] has an extra ++** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes ++** needed for special purpose or to pass along security restrictions. + ** + ** The use of the UTF-8 interfaces is preferred, as SQLite currently + ** does all parsing using UTF-8. The UTF-16 interfaces are provided +@@ -5170,8 +5227,8 @@ typedef struct sqlite3_context sqlite3_context; + ** it should be a pointer to well-formed UTF16 text. + ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then + ** it should be a pointer to a well-formed unicode string that is +-** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 +-** otherwise. ++** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT, ++** or UTF16 otherwise. + ** + ** [[byte-order determination rules]] ^The byte-order of + ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) +@@ -5217,10 +5274,15 @@ typedef struct sqlite3_context sqlite3_context; + ** object and pointer to it must remain valid until then. ^SQLite will then + ** manage the lifetime of its private copy. + ** +-** ^The sixth argument to sqlite3_bind_text64() must be one of +-** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] +-** to specify the encoding of the text in the third parameter. If +-** the sixth argument to sqlite3_bind_text64() is not one of the ++** ^The sixth argument (the E argument) ++** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of ++** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], ++** or [SQLITE_UTF16LE] to specify the encoding of the text in the ++** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the ++** string argument is both UTF-8 encoded and is zero-terminated. In other ++** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at ++** least N+1 bytes and that the Z[N] byte is zero. If ++** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the + ** allowed values shown above, or if the text encoding is different + ** from the encoding specified by the sixth parameter, then the behavior + ** is undefined. +@@ -6087,6 +6149,52 @@ SQLITE_API int sqlite3_create_window_function( + ** + ** These constants define integer codes that represent the various + ** text encodings supported by SQLite. ++** ++**
    ++** [[SQLITE_UTF8]]
    SQLITE_UTF8
    Text is encoding as UTF-8
    ++** ++** [[SQLITE_UTF16LE]]
    SQLITE_UTF16LE
    Text is encoding as UTF-16 ++** with each code point being expressed "little endian" - the least significant ++** byte first. This is the usual encoding, for example on Windows.
    ++** ++** [[SQLITE_UTF16BE]]
    SQLITE_UTF16BE
    Text is encoding as UTF-16 ++** with each code point being expressed "big endian" - the most significant ++** byte first. This encoding is less common, but is still sometimes seen, ++** specially on older systems. ++** ++** [[SQLITE_UTF16]]
    SQLITE_UTF16
    Text is encoding as UTF-16 ++** with each code point being expressed either little endian or as big ++** endian, according to the native endianness of the host computer. ++** ++** [[SQLITE_ANY]]
    SQLITE_ANY
    This encoding value may only be used ++** to declare the preferred text for [application-defined SQL functions] ++** created using [sqlite3_create_function()] and similar. If the preferred ++** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep ++** parameter) is SQLITE_ANY, that indicates that the function does not have ++** a preference regarding the text encoding of its parameters and can take ++** any text encoding that the SQLite core find convenient to supply. This ++** option is deprecated. Please do not use it in new applications. ++** ++** [[SQLITE_UTF16_ALIGNED]]
    SQLITE_UTF16_ALIGNED
    This encoding ++** value may be used as the 3rd parameter (the eTextRep parameter) to ++** [sqlite3_create_collation()] and similar. This encoding value means ++** that the application-defined collating sequence created expects its ++** input strings to be in UTF16 in native byte order, and that the start ++** of the strings must be aligned to a 2-byte boundary. ++** ++** [[SQLITE_UTF8_ZT]]
    SQLITE_UTF8_ZT
    This option can only be ++** used to specify the text encoding to strings input to ++** [sqlite3_result_text64()] and [sqlite3_bind_text64()]. ++** The SQLITE_UTF8_ZT encoding means that the input string (call it "z") ++** is UTF-8 encoded and that it is zero-terminated. If the length parameter ++** (call it "n") is non-negative, this encoding option means that the caller ++** guarantees that z array contains at least n+1 bytes and that the z[n] ++** byte has a value of zero. ++** This option gives the same output as SQLITE_UTF8, but can be more efficient ++** by avoiding the need to make a copy of the input string, in some cases. ++** However, if z is allocated to hold fewer than n+1 bytes or if the ++** z[n] byte is not zero, undefined behavior may result. ++**
    + */ + #define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ + #define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +@@ -6094,6 +6202,7 @@ SQLITE_API int sqlite3_create_window_function( + #define SQLITE_UTF16 4 /* Use native byte order */ + #define SQLITE_ANY 5 /* Deprecated */ + #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ ++#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */ + + /* + ** CAPI3REF: Function Flags +@@ -6328,26 +6437,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 + ** the SQL function that supplied the [sqlite3_value*] parameters. + ** + ** As long as the input parameter is correct, these routines can only +-** fail if an out-of-memory error occurs during a format conversion. +-** Only the following subset of interfaces are subject to out-of-memory +-** errors: +-** +-**
      +-**
    • sqlite3_value_blob() +-**
    • sqlite3_value_text() +-**
    • sqlite3_value_text16() +-**
    • sqlite3_value_text16le() +-**
    • sqlite3_value_text16be() +-**
    • sqlite3_value_bytes() +-**
    • sqlite3_value_bytes16() +-**
    +-** ++** fail if an out-of-memory error occurs while trying to do a ++** UTF8→UTF16 or UTF16→UTF8 conversion. + ** If an out-of-memory error occurs, then the return value from these + ** routines is the same as if the column had contained an SQL NULL value. +-** Valid SQL NULL returns can be distinguished from out-of-memory errors +-** by invoking the [sqlite3_errcode()] immediately after the suspect ++** If the input sqlite3_value was not obtained from [sqlite3_value_dup()], ++** then valid SQL NULL returns can also be distinguished from ++** out-of-memory errors after extracting the value ++** by invoking the [sqlite3_errcode()] immediately after the suspicious + ** return value is obtained and before any + ** other SQLite interface is called on the same [database connection]. ++** If the input sqlite3_value was obtained from sqlite3_value_dup() then ++** it is disconnected from the database connection and so sqlite3_errcode() ++** will not work. ++** In that case, the only way to distinguish an out-of-memory ++** condition from a true SQL NULL is to invoke sqlite3_value_type() on the ++** input to see if it is NULL prior to trying to extract the value. + */ + SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); + SQLITE_API double sqlite3_value_double(sqlite3_value*); +@@ -6374,7 +6479,8 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value*); + ** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) + ** returns something other than SQLITE_TEXT, then the return value from + ** sqlite3_value_encoding(X) is meaningless. ^Calls to +-** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], ++** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], ++** [sqlite3_value_text16be(X)], + ** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or + ** [sqlite3_value_bytes16(X)] might change the encoding of the value X and + ** thus change the return from subsequent calls to sqlite3_value_encoding(X). +@@ -6505,17 +6611,17 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + ** query execution, under some circumstances the associated auxiliary data + ** might be preserved. An example of where this might be useful is in a + ** regular-expression matching function. The compiled version of the regular +-** expression can be stored as auxiliary data associated with the pattern string. +-** Then as long as the pattern string remains the same, ++** expression can be stored as auxiliary data associated with the pattern ++** string. Then as long as the pattern string remains the same, + ** the compiled regular expression can be reused on multiple + ** invocations of the same function. + ** +-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data +-** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument +-** value to the application-defined function. ^N is zero for the left-most +-** function argument. ^If there is no auxiliary data +-** associated with the function argument, the sqlite3_get_auxdata(C,N) interface +-** returns a NULL pointer. ++** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary ++** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the ++** Nth argument value to the application-defined function. ^N is zero ++** for the left-most function argument. ^If there is no auxiliary data ++** associated with the function argument, the sqlite3_get_auxdata(C,N) ++** interface returns a NULL pointer. + ** + ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the + ** N-th argument of the application-defined function. ^Subsequent +@@ -6599,10 +6705,14 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi + ** + ** There is no limit (other than available memory) on the number of different + ** client data pointers (with different names) that can be attached to a +-** single database connection. However, the implementation is optimized +-** for the case of having only one or two different client data names. +-** Applications and wrapper libraries are discouraged from using more than +-** one client data name each. ++** single database connection. However, the current implementation stores ++** the content on a linked list. Insert and retrieval performance will ++** be proportional to the number of entries. The design use case, and ++** the use case for which the implementation is optimized, is ++** that an application will store only small number of client data names, ++** typically just one or two. This interface is not intended to be a ++** generalized key/value store for thousands or millions of keys. It ++** will work for that, but performance might be disappointing. + ** + ** There is no way to enumerate the client data pointers + ** associated with a database connection. The N parameter can be thought +@@ -6710,10 +6820,14 @@ typedef void (*sqlite3_destructor_type)(void*); + ** set the return value of the application-defined function to be + ** a text string which is represented as UTF-8, UTF-16 native byte order, + ** UTF-16 little endian, or UTF-16 big endian, respectively. +-** ^The sqlite3_result_text64() interface sets the return value of an ++** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an + ** application-defined function to be a text string in an encoding +-** specified by the fifth (and last) parameter, which must be one +-** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ++** specified the E parameter, which must be one ++** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], ++** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that ++** the result text is both UTF-8 and zero-terminated. In other words, ++** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that ++** the Z[N] is zero. + ** ^SQLite takes the text result from the application from + ** the 2nd parameter of the sqlite3_result_text* interfaces. + ** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces +@@ -6800,7 +6914,7 @@ SQLITE_API void sqlite3_result_int(sqlite3_context*, int); + SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); + SQLITE_API void sqlite3_result_null(sqlite3_context*); + SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +-SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, ++SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n, + void(*)(void*), unsigned char encoding); + SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); + SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +@@ -7739,7 +7853,7 @@ SQLITE_API int sqlite3_table_column_metadata( + ** ^The sqlite3_load_extension() interface attempts to load an + ** [SQLite extension] library contained in the file zFile. If + ** the file cannot be loaded directly, attempts are made to load +-** with various operating-system specific extensions added. ++** with various operating-system specific filename extensions added. + ** So for example, if "samplelib" cannot be loaded, then names like + ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might + ** be tried also. +@@ -7747,10 +7861,10 @@ SQLITE_API int sqlite3_table_column_metadata( + ** ^The entry point is zProc. + ** ^(zProc may be 0, in which case SQLite will try to come up with an + ** entry point name on its own. It first tries "sqlite3_extension_init". +-** If that does not work, it constructs a name "sqlite3_X_init" where +-** X consists of the lower-case equivalent of all ASCII alphabetic +-** characters in the filename from the last "/" to the first following +-** "." and omitting any initial "lib".)^ ++** If that does not work, it tries names of the form "sqlite3_X_init" ++** where X consists of the lower-case equivalent of all ASCII alphabetic ++** characters or all ASCII alphanumeric characters in the filename from ++** the last "/" to the first following "." and omitting any initial "lib".)^ + ** ^The sqlite3_load_extension() interface returns + ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. + ** ^If an error occurs and pzErrMsg is not 0, then the +@@ -7824,7 +7938,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + **
    + **    int xEntryPoint(
    + **      sqlite3 *db,
    +-**      const char **pzErrMsg,
    ++**      char **pzErrMsg,
    + **      const struct sqlite3_api_routines *pThunk
    + **    );
    + ** 
    )^ +@@ -8574,13 +8688,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix + ** and Windows. + ** +-** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +-** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +-** implementation is included with the library. In this case the +-** application must supply a custom mutex implementation using the +-** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +-** before calling sqlite3_initialize() or any other public sqlite3_ +-** function that calls sqlite3_initialize(). + ** + ** ^The sqlite3_mutex_alloc() routine allocates a new + ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +@@ -8935,6 +9042,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); + #define SQLITE_TESTCTRL_TUNE 32 + #define SQLITE_TESTCTRL_LOGEST 33 + #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ ++#define SQLITE_TESTCTRL_ATOF 34 + #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ + + /* +@@ -9043,17 +9151,22 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); + ** pass the returned value to [sqlite3_free()] to avoid a memory leak. + ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any + ** errors were encountered during construction of the string. ^The +-** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the ++** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the + ** string in [sqlite3_str] object X is zero bytes long. ++** ++** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object ++** X and the string content it contains. Calling sqlite3_str_free(X) is ++** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). + */ + SQLITE_API char *sqlite3_str_finish(sqlite3_str*); ++SQLITE_API void sqlite3_str_free(sqlite3_str*); + + /* + ** CAPI3REF: Add Content To A Dynamic String + ** METHOD: sqlite3_str + ** +-** These interfaces add content to an sqlite3_str object previously obtained +-** from [sqlite3_str_new()]. ++** These interfaces add or remove content to an sqlite3_str object ++** previously obtained from [sqlite3_str_new()]. + ** + ** ^The [sqlite3_str_appendf(X,F,...)] and + ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] +@@ -9076,6 +9189,10 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); + ** ^The [sqlite3_str_reset(X)] method resets the string under construction + ** inside [sqlite3_str] object X back to zero bytes in length. + ** ++** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string ++** under construction to be N bytes or less. This routine is a no-op if ++** N is negative or if the string is already N bytes or smaller in size. ++** + ** These methods do not return a result code. ^If an error occurs, that fact + ** is recorded in the [sqlite3_str] object and can be recovered by a + ** subsequent call to [sqlite3_str_errcode(X)]. +@@ -9086,6 +9203,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); + SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); + SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); + SQLITE_API void sqlite3_str_reset(sqlite3_str*); ++SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); + + /* + ** CAPI3REF: Status Of A Dynamic String +@@ -10616,7 +10734,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + ** + ** sqlite3_vtab_distinct() return value + ** Rows are returned in aOrderBy order +-** Rows with the same value in all aOrderBy columns are adjacent ++** Rows with the same value in all aOrderBy columns are ++** adjacent + ** Duplicates over all colUsed columns may be omitted + ** 0yesyesno + ** 1noyesno +@@ -10625,8 +10744,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + ** + ** + ** ^For the purposes of comparing virtual table output values to see if the +-** values are the same value for sorting purposes, two NULL values are considered +-** to be the same. In other words, the comparison operator is "IS" ++** values are the same value for sorting purposes, two NULL values are ++** considered to be the same. In other words, the comparison operator is "IS" + ** (or "IS NOT DISTINCT FROM") and not "==". + ** + ** If a virtual table implementation is unable to meet the requirements +@@ -10919,9 +11038,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** + ** a variable pointed to by the "pOut" parameter. + ** + ** The "flags" parameter must be passed a mask of flags. At present only +-** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX ++** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX + ** is specified, then status information is available for all elements +-** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If ++** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If + ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements + ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of + ** the EXPLAIN QUERY PLAN output) are available. Invoking API +@@ -10935,7 +11054,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** + ** elements used to implement the statement - a non-zero value is returned and + ** the variable that pOut points to is unchanged. + ** +-** See also: [sqlite3_stmt_scanstatus_reset()] ++** See also: [sqlite3_stmt_scanstatus_reset()] and the ++** [nexec and ncycle] columns of the [bytecode virtual table]. + */ + SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ +@@ -11477,19 +11597,42 @@ SQLITE_API int sqlite3_deserialize( + /* + ** CAPI3REF: Bind array values to the CARRAY table-valued function + ** +-** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to +-** one of the first argument of the [carray() table-valued function]. The +-** S parameter is a pointer to the [prepared statement] that uses the carray() +-** functions. I is the parameter index to be bound. P is a pointer to the +-** array to be bound, and N is the number of eements in the array. The +-** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], +-** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to +-** indicate the datatype of the array being bound. The X argument is not a +-** NULL pointer, then SQLite will invoke the function X on the P parameter +-** after it has finished using P, even if the call to +-** sqlite3_carray_bind() fails. The special-case finalizer +-** SQLITE_TRANSIENT has no effect here. +-*/ ++** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to ++** parameter that is the first argument of the [carray() table-valued function]. ++** The S parameter is a pointer to the [prepared statement] that uses the ++** carray() functions. I is the parameter index to be bound. I must be the ++** index of the parameter that is the first argument to the carray() ++** table-valued function. P is a pointer to the array to be bound, and N ++** is the number of elements in the array. The F argument is one of ++** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], ++** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], ++** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P. ++** ++** If the X argument is not a NULL pointer or one of the special ++** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke ++** the function X with argument D when it is finished using the data in P. ++** The call to X(D) is a destructor for the array P. The destructor X(D) ++** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X ++** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes ++** that the data static and the destructor is never invoked. If the X ++** parameter is the special-case value [SQLITE_TRANSIENT], then ++** sqlite3_carray_bind_v2() makes its own private copy of the data prior ++** to returning and never invokes the destructor X. ++** ++** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2() ++** with a D parameter set to P. In other words, ++** sqlite3_carray_bind(S,I,P,N,F,X) is same as ++** sqlite3_carray_bind_v2(S,I,P,N,F,X,P). ++*/ ++SQLITE_API int sqlite3_carray_bind_v2( ++ sqlite3_stmt *pStmt, /* Statement to be bound */ ++ int i, /* Parameter index */ ++ void *aData, /* Pointer to array data */ ++ int nData, /* Number of data elements */ ++ int mFlags, /* CARRAY flags */ ++ void (*xDel)(void*), /* Destructor for aData */ ++ void *pDel /* Optional argument to xDel() */ ++); + SQLITE_API int sqlite3_carray_bind( + sqlite3_stmt *pStmt, /* Statement to be bound */ + int i, /* Parameter index */ +@@ -13033,11 +13176,23 @@ SQLITE_API int sqlite3changeset_apply_v3( + ** database behave as if they were declared with "ON UPDATE NO ACTION ON + ** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL + ** or SET DEFAULT. ++** ++**
    SQLITE_CHANGESETAPPLY_NOUPDATELOOP
    ++** Sometimes, a changeset contains two or more update statements such that ++** although after applying all updates the database will contain no ++** constraint violations, no single update can be applied before the others. ++** The simplest example of this is a pair of UPDATEs that have "swapped" ++** two column values with a UNIQUE constraint. ++**

    ++** Usually, sqlite3changeset_apply() and similar functions work hard to try ++** to find a way to apply such a changeset. However, if this flag is set, ++** then all such updates are considered CONSTRAINT conflicts. + */ + #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 + #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 + #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 + #define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 ++#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010 + + /* + ** CAPI3REF: Constants Passed To The Conflict Handler +@@ -13520,6 +13675,232 @@ SQLITE_API int sqlite3session_config(int op, void *pArg); + */ + #define SQLITE_SESSION_CONFIG_STRMSIZE 1 + ++/* ++** CAPI3REF: Configure a changegroup object ++** ++** Configure the changegroup object passed as the first argument. ++** At present the only valid value for the second parameter is ++** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET]. ++*/ ++SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg); ++ ++/* ++** CAPI3REF: Options for sqlite3changegroup_config(). ++** ++** The following values may be passed as the 2nd parameter to ++** sqlite3changegroup_config(). ++** ++**

    SQLITE_CHANGEGROUP_CONFIG_PATCHSET
    ++** A changegroup object generates either a changeset or patchset. Usually, ++** this is determined by whether the first call to sqlite3changegroup_add() ++** is passed a changeset or a patchset. Or, if the first changes are added ++** to the changegroup object using the sqlite3changegroup_change_xxx() ++** APIs, then this option may be used to configure whether the changegroup ++** object generates a changeset or patchset. ++** ++** When this option is invoked, parameter pArg must point to a value of ++** type int. If the changegroup currently contains zero changes, and the ++** value of the int variable is zero or greater than zero, then the ++** changegroup is configured to generate a changeset or patchset, ++** respectively. It is a no-op, not an error, if the changegroup is not ++** configured because it has already started accumulating changes. ++** ++** Before returning, the int variable is set to 0 if the changegroup is ++** configured to generate a changeset, or 1 if it is configured to generate ++** a patchset. ++*/ ++#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1 ++ ++ ++/* ++** CAPI3REF: Begin adding a change to a changegroup ++** ++** This API is used, in concert with other sqlite3changegroup_change_xxx() ++** APIs, to add changes to a changegroup object one at a time. To add a ++** single change, the caller must: ++** ++** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of ++** change (INSERT, UPDATE or DELETE), the affected table and whether ++** or not the change should be marked as indirect. ++** ++** 2. Invoke sqlite3changegroup_change_int64() or one of the other four ++** value functions - _null(), _double(), _text() or _blob() - one or ++** more times to specify old.* and new.* values for the change being ++** constructed. ++** ++** 3. Invoke sqlite3changegroup_change_finish() to either finish adding ++** the change to the group, or to discard the change altogether. ++** ++** The first argument to this function must be a pointer to the existing ++** changegroup object that the change will be added to. The second argument ++** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the ++** name of the table that the change affects, and the fourth is a boolean ++** flag specifying whether the change should be marked as "indirect" (if ++** bIndirect is non-zero) or not indirect (if bIndirect is zero). ++** ++** Following a successful call to this function, this function may not be ++** called again on the same changegroup object until after ++** sqlite3changegroup_change_finish() has been called. Doing so is an ++** SQLITE_MISUSE error. ++** ++** The changegroup object passed as the first argument must be already ++** configured with schema data for the specified table. It may be configured ++** either by calling sqlite3changegroup_schema() with a database that contains ++** the table, or sqlite3changegroup_add() with a changeset that contains the ++** table. If the changegroup object has not been configured with a schema for ++** the specified table when this function is called, SQLITE_ERROR is returned. ++** ++** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an ++** SQLite error code is returned. In this case, if argument pzErr is non-NULL, ++** then (*pzErr) may be set to point to a buffer containing a utf-8 formated, ++** nul-terminated, English language error message. It is the responsibility ++** of the caller to eventually free this buffer using sqlite3_free(). ++*/ ++SQLITE_API int sqlite3changegroup_change_begin( ++ sqlite3_changegroup*, ++ int eOp, ++ const char *zTab, ++ int bIndirect, ++ char **pzErr ++); ++ ++/* ++** CAPI3REF: Add a 64-bit integer to a changegroup ++** ++** This function may only be called between a successful call to ++** sqlite3changegroup_change_begin() and its matching ++** sqlite3changegroup_change_finish() call. If it is called at any ++** other time, it is an SQLITE_MISUSE error. Calling this function ++** specifies a 64-bit integer value to be used in the change currently being ++** added to the changegroup object passed as the first argument. ++** ++** The second parameter, bNew, specifies whether the value is to be part of ++** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of ++** the change under construction. If this does not match the type of change ++** specified by the preceding call to sqlite3changegroup_change_begin() (i.e. ++** an old.* value for an SQLITE_INSERT change, or a new.* value for an ++** SQLITE_DELETE), then SQLITE_ERROR is returned. ++** ++** The third parameter specifies the column of the old.* or new.* record that ++** the value will be a part of. If the specified table has an explicit primary ++** key, then this is the index of the table column, numbered from 0 in the order ++** specified within the CREATE TABLE statement. Or, if the table uses an ++** implicit rowid key, then the column 0 is the rowid and the explicit columns ++** are numbered starting from 1. If the iCol parameter is less than 0 or greater ++** than the index of the last column in the table, SQLITE_RANGE is returned. ++** ++** The fourth parameter is the integer value to use as part of the old.* or ++** new.* record. ++** ++** If this call is successful, SQLITE_OK is returned. Otherwise, if an ++** error occurs, an SQLite error code is returned. ++*/ ++SQLITE_API int sqlite3changegroup_change_int64( ++ sqlite3_changegroup*, ++ int bNew, ++ int iCol, ++ sqlite3_int64 iVal ++); ++ ++/* ++** CAPI3REF: Add a NULL to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). Except that ++** it configures the change currently under construction with a NULL value ++** instead of a 64-bit integer. ++*/ ++SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int); ++ ++/* ++** CAPI3REF: Add an double to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). Except that ++** it configures the change currently being constructed with a real value ++** instead of a 64-bit integer. ++*/ ++SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double); ++ ++/* ++** CAPI3REF: Add a text value to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). It configures ++** the currently accumulated change with a text value instead of a 64-bit ++** integer. Parameter pVal points to a buffer containing the text encoded using ++** utf-8. Parameter nVal may either be the size of the text value in bytes, or ++** else a negative value, in which case the buffer pVal points to is assumed to ++** be nul-terminated. ++*/ ++SQLITE_API int sqlite3changegroup_change_text( ++ sqlite3_changegroup*, int, int, const char *pVal, int nVal ++); ++ ++/* ++** CAPI3REF: Add a blob to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). It configures ++** the currently accumulated change with a blob value instead of a 64-bit ++** integer. Parameter pVal points to a buffer containing the blob. Parameter ++** nVal is the size of the blob in bytes. ++*/ ++SQLITE_API int sqlite3changegroup_change_blob( ++ sqlite3_changegroup*, int, int, const void *pVal, int nVal ++); ++ ++/* ++** CAPI3REF: Finish adding one-at-at-time changes to a changegroup ++** ++** This function may only be called following a successful call to ++** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error. ++** ++** If parameter bDiscard is non-zero, then the current change is simply ++** discarded. In this case this function is always successful and SQLITE_OK ++** returned. ++** ++** If parameter bDiscard is zero, then an attempt is made to add the current ++** change to the changegroup. Assuming the changegroup is configured to ++** produce a changeset (not a patchset), this requires that: ++** ++** * If the change is an INSERT or DELETE, then a value must be specified ++** for all columns of the new.* or old.* record, respectively. ++** ++** * If the change is an UPDATE record, then values must be provided for ++** the PRIMARY KEY columns of the old.* record, but must not be provided ++** for PRIMARY KEY columns of the new.* record. ++** ++** * If the change is an UPDATE record, then for each non-PRIMARY KEY ++** column in the old.* record for which a value has been provided, a ++** value must also be provided for the same column in the new.* record. ++** Similarly, for each non-PK column in the old.* record for which ++** a value is not provided, a value must not be provided for the same ++** column in the new.* record. ++** ++** * All values specified for PRIMARY KEY columns must be non-NULL. ++** ++** Otherwise, it is an error. ++** ++** If the changegroup already contains a change for the same row (identified ++** by PRIMARY KEY columns), then the current change is combined with the ++** existing change in the same way as for sqlite3changegroup_add(). ++** ++** For a patchset, all of the above rules apply except that it doesn't matter ++** whether or not values are provided for the non-PK old.* record columns ++** for an UPDATE or DELETE change. This means that code used to produce ++** a changeset using the sqlite3changegroup_change_xxx() APIs may also ++** be used to produce patchsets. ++** ++** If the call is successful, SQLITE_OK is returned. Otherwise, if an error ++** occurs, an SQLite error code is returned. If an error is returned and ++** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer ++** containing a nul-terminated, utf-8 encoded, English language error message. ++** It is the responsibility of the caller to eventually free any such error ++** message buffer using sqlite3_free(). ++*/ ++SQLITE_API int sqlite3changegroup_change_finish( ++ sqlite3_changegroup*, ++ int bDiscard, ++ char **pzErr ++); ++ + /* + ** Make sure we can call this stuff from C++. + */ +@@ -14390,21 +14771,42 @@ struct fts5_api { + ** It used to be the case that setting this value to zero would + ** turn the limit off. That is no longer true. It is not possible + ** to turn this limit off. ++** ++** The hard limit is the largest possible 32-bit signed integer less ++** 1024, or 2147482624. + */ + #ifndef SQLITE_MAX_SQL_LENGTH + # define SQLITE_MAX_SQL_LENGTH 1000000000 + #endif + + /* +-** The maximum depth of an expression tree. This is limited to +-** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +-** want to place more severe limits on the complexity of an +-** expression. A value of 0 means that there is no limit. ++** The maximum depth of an expression tree. The expression tree depth ++** is also limited indirectly by SQLITE_MAX_SQL_LENGTH and by ++** SQLITE_MAX_PARSER_DEPTH. Reducing the maximum complexity of ++** expressions can help prevent excess memory usage by hostile SQL. ++** ++** A value of 0 for this compile-time option causes all expression ++** depth limiting code to be omitted. + */ + #ifndef SQLITE_MAX_EXPR_DEPTH + # define SQLITE_MAX_EXPR_DEPTH 1000 + #endif + ++/* ++** The maximum depth of the LALR(1) stack used in the parser that ++** interprets SQL inputs. The parser stack depth can also be limited ++** indirectly by SQLITE_MAX_SQL_LENGTH. Limiting the parser stack ++** depth can help prevent excess memory usage and excess CPU stack ++** usage when processing hostile SQL. ++** ++** Prior to version 3.45.0 (2024-01-15), the parser stack was ++** hard-coded to 100 entries, and that worked fine for almost all ++** applications. So the upper bound on this limit need not be large. ++*/ ++#ifndef SQLITE_MAX_PARSER_DEPTH ++# define SQLITE_MAX_PARSER_DEPTH 2500 ++#endif ++ + /* + ** The maximum number of terms in a compound SELECT statement. + ** The code generator for compound SELECT statements does one +@@ -14520,6 +14922,10 @@ struct fts5_api { + # undef SQLITE_MAX_DEFAULT_PAGE_SIZE + # define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE + #endif ++#if SQLITE_MAX_DEFAULT_PAGE_SIZE +-#endif + #ifdef HAVE_INTTYPES_H + #include + #endif +@@ -15290,6 +15694,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); + # define float sqlite_int64 + # define fabs(X) ((X)<0?-(X):(X)) + # define sqlite3IsOverflow(X) 0 ++# define INFINITY (9223372036854775807LL) + # ifndef SQLITE_BIG_DBL + # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) + # endif +@@ -15397,6 +15802,13 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); + # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) + #endif + ++/* ++** sizeof64() is like sizeof(), but always returns a 64-bit value, even ++** on 32-bit builds. This can help to avoid overflow by ensuring 64-bit ++** arithmetic is used consistently in both 32-bit and 64-bit builds. ++*/ ++#define sizeof64(X) ((sqlite3_int64)sizeof(X)) ++ + /* + ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as + ** to avoid complaints from -fsanitize=strict-bounds. +@@ -15699,6 +16111,7 @@ typedef INT16_TYPE LogEst; + #else + # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) + #endif ++#define TWO_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&1)==0) + + /* + ** Disable MMAP on platforms where it is known to not work +@@ -16757,7 +17170,7 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); + + SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); + SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); +-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); ++SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree*, Btree*); + + SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); + +@@ -17157,6 +17570,7 @@ struct VdbeOp { + SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ + Table *pTab; /* Used when p4type is P4_TABLE */ + SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ ++ Index *pIdx; /* Used when p4type is P4_INDEX */ + #ifdef SQLITE_ENABLE_CURSOR_HINTS + Expr *pExpr; /* Used when p4type is P4_EXPR */ + #endif +@@ -17211,20 +17625,21 @@ typedef struct VdbeOpList VdbeOpList; + #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ + #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ + #define P4_TABLE (-5) /* P4 is a pointer to a Table structure */ ++#define P4_INDEX (-6) /* P4 is a pointer to an Index structure */ + /* Above do not own any resources. Must free those below */ +-#define P4_FREE_IF_LE (-6) +-#define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */ +-#define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */ +-#define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */ +-#define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */ +-#define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ +-#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ +-#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ +-#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ +-#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ +-#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ +-#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ +-#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ ++#define P4_FREE_IF_LE (-7) ++#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */ ++#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ ++#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ ++#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ ++#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ ++#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ ++#define P4_REAL (-13) /* P4 is a 64-bit floating point value */ ++#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ ++#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ ++#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ ++#define P4_TABLEREF (-17) /* Like P4_TABLE, but reference counted */ ++#define P4_SUBRTNSIG (-18) /* P4 is a SubrtnSig pointer */ + + /* Error message codes for OP_Halt */ + #define P5_ConstraintNotNull 1 +@@ -17313,10 +17728,10 @@ typedef struct VdbeOpList VdbeOpList; + #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ + #define OP_IdxLT 45 /* jump, synopsis: key=r[P3@P4] */ + #define OP_IdxGE 46 /* jump, synopsis: key=r[P3@P4] */ +-#define OP_RowSetRead 47 /* jump, synopsis: r[P3]=rowset(P1) */ +-#define OP_RowSetTest 48 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +-#define OP_Program 49 /* jump0 */ +-#define OP_FkIfZero 50 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ ++#define OP_IFindKey 47 /* jump */ ++#define OP_RowSetRead 48 /* jump, synopsis: r[P3]=rowset(P1) */ ++#define OP_RowSetTest 49 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ ++#define OP_Program 50 /* jump0 */ + #define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ + #define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ + #define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +@@ -17326,49 +17741,49 @@ typedef struct VdbeOpList VdbeOpList; + #define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ + #define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ +-#define OP_IfPos 60 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +-#define OP_IfNotZero 61 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +-#define OP_DecrJumpZero 62 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +-#define OP_IncrVacuum 63 /* jump */ +-#define OP_VNext 64 /* jump */ +-#define OP_Filter 65 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +-#define OP_PureFunc 66 /* synopsis: r[P3]=func(r[P2@NP]) */ +-#define OP_Function 67 /* synopsis: r[P3]=func(r[P2@NP]) */ +-#define OP_Return 68 +-#define OP_EndCoroutine 69 +-#define OP_HaltIfNull 70 /* synopsis: if r[P3]=null halt */ +-#define OP_Halt 71 +-#define OP_Integer 72 /* synopsis: r[P2]=P1 */ +-#define OP_Int64 73 /* synopsis: r[P2]=P4 */ +-#define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */ +-#define OP_BeginSubrtn 75 /* synopsis: r[P2]=NULL */ +-#define OP_Null 76 /* synopsis: r[P2..P3]=NULL */ +-#define OP_SoftNull 77 /* synopsis: r[P1]=NULL */ +-#define OP_Blob 78 /* synopsis: r[P2]=P4 (len=P1) */ +-#define OP_Variable 79 /* synopsis: r[P2]=parameter(P1) */ +-#define OP_Move 80 /* synopsis: r[P2@P3]=r[P1@P3] */ +-#define OP_Copy 81 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +-#define OP_SCopy 82 /* synopsis: r[P2]=r[P1] */ +-#define OP_IntCopy 83 /* synopsis: r[P2]=r[P1] */ +-#define OP_FkCheck 84 +-#define OP_ResultRow 85 /* synopsis: output=r[P1@P2] */ +-#define OP_CollSeq 86 +-#define OP_AddImm 87 /* synopsis: r[P1]=r[P1]+P2 */ +-#define OP_RealAffinity 88 +-#define OP_Cast 89 /* synopsis: affinity(r[P1]) */ +-#define OP_Permutation 90 +-#define OP_Compare 91 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +-#define OP_IsTrue 92 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +-#define OP_ZeroOrNull 93 /* synopsis: r[P2] = 0 OR NULL */ +-#define OP_Offset 94 /* synopsis: r[P3] = sqlite_offset(P1) */ +-#define OP_Column 95 /* synopsis: r[P3]=PX cursor P1 column P2 */ +-#define OP_TypeCheck 96 /* synopsis: typecheck(r[P1@P2]) */ +-#define OP_Affinity 97 /* synopsis: affinity(r[P1@P2]) */ +-#define OP_MakeRecord 98 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +-#define OP_Count 99 /* synopsis: r[P2]=count() */ +-#define OP_ReadCookie 100 +-#define OP_SetCookie 101 +-#define OP_ReopenIdx 102 /* synopsis: root=P2 iDb=P3 */ ++#define OP_FkIfZero 60 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ ++#define OP_IfPos 61 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ ++#define OP_IfNotZero 62 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ ++#define OP_DecrJumpZero 63 /* jump, synopsis: if (--r[P1])==0 goto P2 */ ++#define OP_IncrVacuum 64 /* jump */ ++#define OP_VNext 65 /* jump */ ++#define OP_Filter 66 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ ++#define OP_PureFunc 67 /* synopsis: r[P3]=func(r[P2@NP]) */ ++#define OP_Function 68 /* synopsis: r[P3]=func(r[P2@NP]) */ ++#define OP_Return 69 ++#define OP_EndCoroutine 70 ++#define OP_HaltIfNull 71 /* synopsis: if r[P3]=null halt */ ++#define OP_Halt 72 ++#define OP_Integer 73 /* synopsis: r[P2]=P1 */ ++#define OP_Int64 74 /* synopsis: r[P2]=P4 */ ++#define OP_String 75 /* synopsis: r[P2]='P4' (len=P1) */ ++#define OP_BeginSubrtn 76 /* synopsis: r[P2]=NULL */ ++#define OP_Null 77 /* synopsis: r[P2..P3]=NULL */ ++#define OP_SoftNull 78 /* synopsis: r[P1]=NULL */ ++#define OP_Blob 79 /* synopsis: r[P2]=P4 (len=P1) */ ++#define OP_Variable 80 /* synopsis: r[P2]=parameter(P1) */ ++#define OP_Move 81 /* synopsis: r[P2@P3]=r[P1@P3] */ ++#define OP_Copy 82 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ ++#define OP_SCopy 83 /* synopsis: r[P2]=r[P1] */ ++#define OP_IntCopy 84 /* synopsis: r[P2]=r[P1] */ ++#define OP_FkCheck 85 ++#define OP_ResultRow 86 /* synopsis: output=r[P1@P2] */ ++#define OP_CollSeq 87 ++#define OP_AddImm 88 /* synopsis: r[P1]=r[P1]+P2 */ ++#define OP_RealAffinity 89 ++#define OP_Cast 90 /* synopsis: affinity(r[P1]) */ ++#define OP_Permutation 91 ++#define OP_Compare 92 /* synopsis: r[P1@P3] <-> r[P2@P3] */ ++#define OP_IsTrue 93 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ ++#define OP_ZeroOrNull 94 /* synopsis: r[P2] = 0 OR NULL */ ++#define OP_Offset 95 /* synopsis: r[P3] = sqlite_offset(P1) */ ++#define OP_Column 96 /* synopsis: r[P3]=PX cursor P1 column P2 */ ++#define OP_TypeCheck 97 /* synopsis: typecheck(r[P1@P2]) */ ++#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */ ++#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ ++#define OP_Count 100 /* synopsis: r[P2]=count() */ ++#define OP_ReadCookie 101 ++#define OP_SetCookie 102 + #define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ + #define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ + #define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +-#define OP_AggInverse 162 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +-#define OP_AggStep 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +-#define OP_AggStep1 164 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +-#define OP_AggValue 165 /* synopsis: r[P3]=value N=P2 */ +-#define OP_AggFinal 166 /* synopsis: accum=r[P1] N=P2 */ +-#define OP_Expire 167 +-#define OP_CursorLock 168 +-#define OP_CursorUnlock 169 +-#define OP_TableLock 170 /* synopsis: iDb=P1 root=P2 write=P3 */ +-#define OP_VBegin 171 +-#define OP_VCreate 172 +-#define OP_VDestroy 173 +-#define OP_VOpen 174 +-#define OP_VCheck 175 +-#define OP_VInitIn 176 /* synopsis: r[P2]=ValueList(P1,P3) */ +-#define OP_VColumn 177 /* synopsis: r[P3]=vcolumn(P2) */ +-#define OP_VRename 178 +-#define OP_Pagecount 179 +-#define OP_MaxPgcnt 180 +-#define OP_ClrSubtype 181 /* synopsis: r[P1].subtype = 0 */ +-#define OP_GetSubtype 182 /* synopsis: r[P2] = r[P1].subtype */ +-#define OP_SetSubtype 183 /* synopsis: r[P2].subtype = r[P1] */ +-#define OP_FilterAdd 184 /* synopsis: filter(P1) += key(P3@P4) */ +-#define OP_Trace 185 +-#define OP_CursorHint 186 +-#define OP_ReleaseReg 187 /* synopsis: release r[P1@P2] mask P3 */ +-#define OP_Noop 188 +-#define OP_Explain 189 +-#define OP_Abortable 190 ++#define OP_DropIndex 155 ++#define OP_DropTrigger 156 ++#define OP_IntegrityCk 157 ++#define OP_RowSetAdd 158 /* synopsis: rowset(P1)=r[P2] */ ++#define OP_Param 159 ++#define OP_FkCounter 160 /* synopsis: fkctr[P1]+=P2 */ ++#define OP_MemMax 161 /* synopsis: r[P1]=max(r[P1],r[P2]) */ ++#define OP_OffsetLimit 162 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ ++#define OP_AggInverse 163 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ ++#define OP_AggStep 164 /* synopsis: accum=r[P3] step(r[P2@P5]) */ ++#define OP_AggStep1 165 /* synopsis: accum=r[P3] step(r[P2@P5]) */ ++#define OP_AggValue 166 /* synopsis: r[P3]=value N=P2 */ ++#define OP_AggFinal 167 /* synopsis: accum=r[P1] N=P2 */ ++#define OP_Expire 168 ++#define OP_CursorLock 169 ++#define OP_CursorUnlock 170 ++#define OP_TableLock 171 /* synopsis: iDb=P1 root=P2 write=P3 */ ++#define OP_VBegin 172 ++#define OP_VCreate 173 ++#define OP_VDestroy 174 ++#define OP_VOpen 175 ++#define OP_VCheck 176 ++#define OP_VInitIn 177 /* synopsis: r[P2]=ValueList(P1,P3) */ ++#define OP_VColumn 178 /* synopsis: r[P3]=vcolumn(P2) */ ++#define OP_VRename 179 ++#define OP_Pagecount 180 ++#define OP_MaxPgcnt 181 ++#define OP_ClrSubtype 182 /* synopsis: r[P1].subtype = 0 */ ++#define OP_GetSubtype 183 /* synopsis: r[P2] = r[P1].subtype */ ++#define OP_SetSubtype 184 /* synopsis: r[P2].subtype = r[P1] */ ++#define OP_FilterAdd 185 /* synopsis: filter(P1) += key(P3@P4) */ ++#define OP_Trace 186 ++#define OP_CursorHint 187 ++#define OP_ReleaseReg 188 /* synopsis: release r[P1@P2] mask P3 */ ++#define OP_Noop 189 ++#define OP_Explain 190 ++#define OP_Abortable 191 + + /* Properties such as "out2" or "jump" that are specified in + ** comments following the "case" for each opcode in the vdbe.c +@@ -17476,25 +17892,26 @@ typedef struct VdbeOpList VdbeOpList; + /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ + /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ + /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x01, 0x41,\ +-/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x41, 0x23,\ +-/* 48 */ 0x0b, 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ +-/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01,\ +-/* 64 */ 0x41, 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00,\ +-/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\ +-/* 80 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02,\ +-/* 88 */ 0x02, 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40,\ +-/* 96 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26,\ ++/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x41, 0x09,\ ++/* 48 */ 0x23, 0x0b, 0x81, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ ++/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x01, 0x03, 0x03, 0x03,\ ++/* 64 */ 0x01, 0x41, 0x01, 0x00, 0x00, 0x02, 0x02, 0x08,\ ++/* 72 */ 0x00, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10,\ ++/* 80 */ 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\ ++/* 88 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20,\ ++/* 96 */ 0x40, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x26,\ + /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ +-/* 112 */ 0x26, 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40,\ +-/* 120 */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10,\ +-/* 128 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,\ +-/* 136 */ 0x50, 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50,\ +-/* 144 */ 0x40, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ +-/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00,\ +-/* 160 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +-/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10,\ +-/* 176 */ 0x50, 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12,\ +-/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} ++/* 112 */ 0x26, 0x40, 0x40, 0x12, 0x00, 0x40, 0x10, 0x40,\ ++/* 120 */ 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40,\ ++/* 128 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,\ ++/* 136 */ 0x00, 0x50, 0x00, 0x40, 0x04, 0x04, 0x00, 0x40,\ ++/* 144 */ 0x50, 0x40, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00,\ ++/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x10,\ ++/* 160 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\ ++/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,\ ++/* 176 */ 0x10, 0x50, 0x40, 0x00, 0x10, 0x10, 0x02, 0x12,\ ++/* 184 */ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ ++} + + /* The resolve3P2Values() routine is able to run faster if it knows + ** the value of the largest JUMP opcode. The smaller the maximum +@@ -17502,7 +17919,7 @@ typedef struct VdbeOpList VdbeOpList; + ** generated this include file strives to group all JUMP opcodes + ** together near the beginning of the list. + */ +-#define SQLITE_MX_JUMP_OPCODE 65 /* Maximum JUMP opcode */ ++#define SQLITE_MX_JUMP_OPCODE 66 /* Maximum JUMP opcode */ + + /************** End of opcodes.h *********************************************/ + /************** Continuing where we left off in vdbe.h ***********************/ +@@ -17511,7 +17928,7 @@ typedef struct VdbeOpList VdbeOpList; + ** Additional non-public SQLITE_PREPARE_* flags + */ + #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ +-#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */ ++#define SQLITE_PREPARE_MASK 0x3f /* Mask of public flags */ + + /* + ** Prototypes for the VDBE interface. See comments on the implementation +@@ -17793,10 +18210,10 @@ struct PgHdr { + PCache *pCache; /* PRIVATE: Cache that owns this page */ + PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ + Pager *pPager; /* The pager this page is part of */ +- Pgno pgno; /* Page number for this page */ + #ifdef SQLITE_CHECK_PAGES +- u32 pageHash; /* Hash of page content */ ++ u64 pageHash; /* Hash of page content */ + #endif ++ Pgno pgno; /* Page number for this page */ + u16 flags; /* PGHDR flags defined below */ + + /********************************************************************** +@@ -18136,7 +18553,7 @@ struct Schema { + ** The number of different kinds of things that can be limited + ** using the sqlite3_limit() interface. + */ +-#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) ++#define SQLITE_N_LIMIT (SQLITE_LIMIT_PARSER_DEPTH+1) + + /* + ** Lookaside malloc is a set of fixed-size buffers that can be used +@@ -18290,6 +18707,7 @@ struct sqlite3 { + u8 noSharedCache; /* True if no shared-cache backends */ + u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ + u8 eOpenState; /* Current condition of the connection */ ++ u8 nFpDigit; /* Significant digits to keep on double->text */ + int nextPagesize; /* Pagesize after VACUUM if >0 */ + i64 nChange; /* Value returned by sqlite3_changes() */ + i64 nTotalChange; /* Value returned by sqlite3_total_changes() */ +@@ -20184,19 +20602,6 @@ struct Upsert { + /* + ** An instance of the following structure contains all information + ** needed to generate code for a single SELECT statement. +-** +-** See the header comment on the computeLimitRegisters() routine for a +-** detailed description of the meaning of the iLimit and iOffset fields. +-** +-** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes. +-** These addresses must be stored so that we can go back and fill in +-** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor +-** the number of columns in P2 can be computed at the same time +-** as the OP_OpenEphm instruction is coded because not +-** enough information about the compound query is known at that point. +-** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences +-** for the result set. The KeyInfo for addrOpenEphm[2] contains collating +-** sequences for the ORDER BY clause. + */ + struct Select { + u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ +@@ -20204,7 +20609,6 @@ struct Select { + u32 selFlags; /* Various SF_* values */ + int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ + u32 selId; /* Unique identifier number for this SELECT */ +- int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ + ExprList *pEList; /* The fields of the result */ + SrcList *pSrc; /* The FROM clause */ + Expr *pWhere; /* The WHERE clause */ +@@ -20236,7 +20640,7 @@ struct Select { + #define SF_Resolved 0x0000004 /* Identifiers have been resolved */ + #define SF_Aggregate 0x0000008 /* Contains agg functions or a GROUP BY */ + #define SF_HasAgg 0x0000010 /* Contains aggregate functions */ +-#define SF_UsesEphemeral 0x0000020 /* Uses the OpenEphemeral opcode */ ++#define SF_ClonedRhsIn 0x0000020 /* Cloned RHS of an IN operator */ + #define SF_Expanded 0x0000040 /* sqlite3SelectExpand() called on this */ + #define SF_HasTypeInfo 0x0000080 /* FROM subqueries have Table metadata */ + #define SF_Compound 0x0000100 /* Part of a compound query */ +@@ -20246,14 +20650,14 @@ struct Select { + #define SF_MinMaxAgg 0x0001000 /* Aggregate containing min() or max() */ + #define SF_Recursive 0x0002000 /* The recursive part of a recursive CTE */ + #define SF_FixedLimit 0x0004000 /* nSelectRow set by a constant LIMIT */ +-#define SF_MaybeConvert 0x0008000 /* Need convertCompoundSelectToSubquery() */ ++/* 0x0008000 // available for reuse */ + #define SF_Converted 0x0010000 /* By convertCompoundSelectToSubquery() */ + #define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */ + #define SF_ComplexResult 0x0040000 /* Result contains subquery or function */ + #define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ + #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ + #define SF_View 0x0200000 /* SELECT statement is a view */ +-#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ ++/* 0x0400000 // available for reuse */ + #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ + #define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ + #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ +@@ -20273,11 +20677,6 @@ struct Select { + ** by one of the following macros. The "SRT" prefix means "SELECT Result + ** Type". + ** +-** SRT_Union Store results as a key in a temporary index +-** identified by pDest->iSDParm. +-** +-** SRT_Except Remove results from the temporary index pDest->iSDParm. +-** + ** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result + ** set is not empty. + ** +@@ -20341,30 +20740,28 @@ struct Select { + ** table. (pDest->iSDParm) is the number of key columns in + ** each index record in this case. + */ +-#define SRT_Union 1 /* Store result as keys in an index */ +-#define SRT_Except 2 /* Remove result from a UNION index */ +-#define SRT_Exists 3 /* Store 1 if the result is not empty */ +-#define SRT_Discard 4 /* Do not save the results anywhere */ +-#define SRT_DistFifo 5 /* Like SRT_Fifo, but unique results only */ +-#define SRT_DistQueue 6 /* Like SRT_Queue, but unique results only */ ++#define SRT_Exists 1 /* Store 1 if the result is not empty */ ++#define SRT_Discard 2 /* Do not save the results anywhere */ ++#define SRT_DistFifo 3 /* Like SRT_Fifo, but unique results only */ ++#define SRT_DistQueue 4 /* Like SRT_Queue, but unique results only */ + + /* The DISTINCT clause is ignored for all of the above. Not that + ** IgnorableDistinct() implies IgnorableOrderby() */ + #define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue) + +-#define SRT_Queue 7 /* Store result in an queue */ +-#define SRT_Fifo 8 /* Store result as data with an automatic rowid */ ++#define SRT_Queue 5 /* Store result in an queue */ ++#define SRT_Fifo 6 /* Store result as data with an automatic rowid */ + + /* The ORDER BY clause is ignored for all of the above */ + #define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo) + +-#define SRT_Output 9 /* Output each row of result */ +-#define SRT_Mem 10 /* Store result in a memory cell */ +-#define SRT_Set 11 /* Store results as keys in an index */ +-#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */ +-#define SRT_Coroutine 13 /* Generate a single row of result */ +-#define SRT_Table 14 /* Store result as data with an automatic rowid */ +-#define SRT_Upfrom 15 /* Store result as data with rowid */ ++#define SRT_Output 7 /* Output each row of result */ ++#define SRT_Mem 8 /* Store result in a memory cell */ ++#define SRT_Set 9 /* Store results as keys in an index */ ++#define SRT_EphemTab 10 /* Create transient tab and store like SRT_Table */ ++#define SRT_Coroutine 11 /* Generate a single row of result */ ++#define SRT_Table 12 /* Store result as data with an automatic rowid */ ++#define SRT_Upfrom 13 /* Store result as data with rowid */ + + /* + ** An instance of this object describes where to put of the results of +@@ -20500,17 +20897,12 @@ struct Parse { + u8 nested; /* Number of nested calls to the parser/code generator */ + u8 nTempReg; /* Number of temporary registers in aTempReg[] */ + u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ +- u8 mayAbort; /* True if statement may throw an ABORT exception */ +- u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ + u8 disableLookaside; /* Number of times lookaside has been disabled */ + u8 prepFlags; /* SQLITE_PREPARE_* flags */ + u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ +- u8 bHasExists; /* Has a correlated "EXISTS (SELECT ....)" expression */ + u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ + u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ +- u8 bReturning; /* Coding a RETURNING trigger */ + u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ +- u8 disableTriggers; /* True to disable triggers */ + #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ + #endif +@@ -20519,10 +20911,15 @@ struct Parse { + u8 isCreate; /* CREATE TABLE, INDEX, or VIEW (but not TRIGGER) + ** and ALTER TABLE ADD COLUMN. */ + #endif +- bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */ +- bft bHasWith :1; /* True if statement contains WITH */ +- bft okConstFactor :1; /* OK to factor out constants */ +- bft checkSchema :1; /* Causes schema cookie check after an error */ ++ bft disableTriggers:1; /* True to disable triggers */ ++ bft mayAbort :1; /* True if statement may throw an ABORT exception */ ++ bft hasCompound :1; /* Need to invoke convertCompoundSelectToSubquery() */ ++ bft bReturning :1; /* Coding a RETURNING trigger */ ++ bft bHasExists :1; /* Has a correlated "EXISTS (SELECT ....)" expression */ ++ bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */ ++ bft bHasWith :1; /* True if statement contains WITH */ ++ bft okConstFactor:1; /* OK to factor out constants */ ++ bft checkSchema :1; /* Causes schema cookie check after an error */ + int nRangeReg; /* Size of the temporary register block */ + int iRangeReg; /* First register in temporary register block */ + int nErr; /* Number of errors seen */ +@@ -20531,6 +20928,7 @@ struct Parse { + int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ + int iSelfTab; /* Table associated with an index on expr, or negative + ** of the base register during check-constraint eval */ ++ int nNestSel; /* Number of nested SELECT statements and/or VIEWs */ + int nLabel; /* The *negative* of the number of labels used */ + int nLabelAlloc; /* Number of slots in aLabel */ + int *aLabel; /* Space to hold the labels */ +@@ -20751,19 +21149,19 @@ struct Trigger { + ** orconf -> stores the ON CONFLICT algorithm + ** pSelect -> The content to be inserted - either a SELECT statement or + ** a VALUES clause. +-** zTarget -> Dequoted name of the table to insert into. ++** pSrc -> Table to insert into. + ** pIdList -> If this is an INSERT INTO ... () VALUES ... + ** statement, then this stores the column-names to be + ** inserted into. + ** pUpsert -> The ON CONFLICT clauses for an Upsert + ** + ** (op == TK_DELETE) +-** zTarget -> Dequoted name of the table to delete from. ++** pSrc -> Table to delete from + ** pWhere -> The WHERE clause of the DELETE statement if one is specified. + ** Otherwise NULL. + ** + ** (op == TK_UPDATE) +-** zTarget -> Dequoted name of the table to update. ++** pSrc -> Table to update, followed by any FROM clause tables. + ** pWhere -> The WHERE clause of the UPDATE statement if one is specified. + ** Otherwise NULL. + ** pExprList -> A list of the columns to update and the expressions to update +@@ -20783,8 +21181,7 @@ struct TriggerStep { + u8 orconf; /* OE_Rollback etc. */ + Trigger *pTrig; /* The trigger that this step is a part of */ + Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ +- char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ +- SrcList *pFrom; /* FROM clause for UPDATE statement (if any) */ ++ SrcList *pSrc; /* Table to insert/update/delete */ + Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ + ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */ + IdList *pIdList; /* Column names for INSERT */ +@@ -20867,10 +21264,11 @@ typedef struct { + /* + ** Allowed values for mInitFlags + */ +-#define INITFLAG_AlterMask 0x0003 /* Types of ALTER */ ++#define INITFLAG_AlterMask 0x0007 /* Types of ALTER */ + #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ + #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ + #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ ++#define INITFLAG_AlterDropCons 0x0004 /* Reparse after an ADD COLUMN */ + + /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled + ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning +@@ -21000,6 +21398,7 @@ struct Walker { + NameContext *pNC; /* Naming context */ + int n; /* A counter */ + int iCur; /* A cursor number */ ++ int sz; /* String literal length */ + SrcList *pSrcList; /* FROM clause */ + struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ + struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ +@@ -21404,7 +21803,20 @@ SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*); + SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); + SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); + +-#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) ++ ++/* The SQLITE_THREAD_MISUSE_WARNINGS compile-time option used to be called ++** SQLITE_ENABLE_MULTITHREADED_CHECKS. Keep that older macro for backwards ++** compatibility, at least for a while... */ ++#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS ++# define SQLITE_THREAD_MISUSE_WARNINGS 1 ++#endif ++ ++/* SQLITE_THREAD_MISUSE_ABORT implies SQLITE_THREAD_MISUSE_WARNINGS */ ++#ifdef SQLITE_THREAD_MISUSE_ABORT ++# define SQLITE_THREAD_MISUSE_WARNINGS 1 ++#endif ++ ++#if defined(SQLITE_THREAD_MISUSE_WARNINGS) && !defined(SQLITE_MUTEX_OMIT) + SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); + #else + # define sqlite3MutexWarnOnContention(x) +@@ -21433,17 +21845,22 @@ struct PrintfArguments { + sqlite3_value **apArg; /* The argument values */ + }; + ++/* ++** Maxium number of base-10 digits in an unsigned 64-bit integer ++*/ ++#define SQLITE_U64_DIGITS 20 ++ + /* + ** An instance of this object receives the decoding of a floating point + ** value into an approximate decimal representation. + */ + struct FpDecode { +- char sign; /* '+' or '-' */ +- char isSpecial; /* 1: Infinity 2: NaN */ +- int n; /* Significant digits in the decode */ +- int iDP; /* Location of the decimal point */ +- char *z; /* Start of significant digits */ +- char zBuf[24]; /* Storage for significant digits */ ++ int n; /* Significant digits in the decode */ ++ int iDP; /* Location of the decimal point */ ++ char *z; /* Start of significant digits */ ++ char zBuf[SQLITE_U64_DIGITS+1]; /* Storage for significant digits */ ++ char sign; /* '+' or '-' */ ++ char isSpecial; /* 1: Infinity 2: NaN */ + }; + + SQLITE_PRIVATE void sqlite3FpDecode(FpDecode*,double,int,int); +@@ -21532,6 +21949,7 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); + #endif + SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); + SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); ++SQLITE_PRIVATE Expr *sqlite3ExprInt32(sqlite3*,int); + SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); + SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); + SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); +@@ -21783,6 +22201,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); + SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); + SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); + SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); ++SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr*); + SQLITE_PRIVATE int sqlite3IsRowid(const char*); + SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); + SQLITE_PRIVATE void sqlite3GenerateRowDelete( +@@ -21851,17 +22270,16 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, i + SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); + SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, + const char*,const char*); +-SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, ++SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,SrcList*, IdList*, + Select*,u8,Upsert*, + const char*,const char*); +-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,SrcList*,ExprList*, ++SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,SrcList*,SrcList*,ExprList*, + Expr*, u8, const char*,const char*); +-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, ++SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,SrcList*, Expr*, + const char*,const char*); + SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); + SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); + SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); +-SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*); + # define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) + # define sqlite3IsToplevel(p) ((p)->pToplevel==0) + #else +@@ -21875,7 +22293,6 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*); + # define sqlite3ParseToplevel(p) p + # define sqlite3IsToplevel(p) 1 + # define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0 +-# define sqlite3TriggerStepSrc(A,B) 0 + #endif + + SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); +@@ -21908,7 +22325,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); + SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); + SQLITE_PRIVATE i64 sqlite3RealToI64(double); + SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); +-SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); ++SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*); + SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); + SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); + SQLITE_PRIVATE int sqlite3Atoi(const char*); +@@ -22052,10 +22469,21 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); + SQLITE_PRIVATE void sqlite3AlterFunctions(void); + SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); + SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); ++SQLITE_PRIVATE void sqlite3AlterDropConstraint(Parse*,SrcList*,Token*,Token*); ++SQLITE_PRIVATE void sqlite3AlterAddConstraint( ++ Parse *pParse, /* Parse context */ ++ SrcList *pSrc, /* Table to add constraint to */ ++ Token *pFirst, /* First token of new constraint */ ++ Token *pName, /* Name of new constraint. NULL if name omitted. */ ++ const char *zExpr, /* Text of CHECK expression */ ++ int nExpr, /* Size of pExpr in bytes */ ++ Expr *pExpr /* The parsed CHECK expression */ ++); ++SQLITE_PRIVATE void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*); + SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *); + SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); + SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); +-SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int); ++SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int); + SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); + SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); + SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); +@@ -22128,6 +22556,7 @@ SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64); + + SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); + SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); ++SQLITE_PRIVATE int sqlite3StrAccumEnlargeIfNeeded(StrAccum*, i64); + SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); + SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); + SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); +@@ -23355,6 +23784,9 @@ static const char * const sqlite3azCompileOpt[] = { + #ifdef SQLITE_STMTJRNL_SPILL + "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL), + #endif ++#ifdef SQLITE_STRICT_SUBTYPE ++ "STRICT_SUBTYPE", ++#endif + #ifdef SQLITE_SUBSTR_COMPATIBILITY + "SUBSTR_COMPATIBILITY", + #endif +@@ -24470,6 +24902,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); + SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); + SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); + SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*)); ++SQLITE_PRIVATE int sqlite3VdbeMemSetText(Mem*, const char*, i64, void(*)(void*)); + SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); + #ifdef SQLITE_OMIT_FLOATING_POINT + # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 +@@ -24488,13 +24921,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int); + SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); + #endif + SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); +-SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem*); ++SQLITE_PRIVATE int sqlite3VdbeMemZeroTerminateIfAble(Mem*); + SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); + SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); + SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); + SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*); + SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); + SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); ++SQLITE_PRIVATE int sqlite3MemRealValueRC(Mem*, double*); + SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); + SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); + SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); +@@ -24525,6 +24959,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( + Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int); + #endif + SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); ++SQLITE_PRIVATE int sqlite3VdbeFindIndexKey(BtCursor*, Index*, UnpackedRecord*, int*, int); + + SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); + SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); +@@ -25454,7 +25889,7 @@ static int parseDateOrTime( + return 0; + }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ + return setDateTimeToCurrent(context, p); +- }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ ++ }else if( sqlite3AtoF(zDate, &r)>0 ){ + setRawDateNumber(p, r); + return 0; + }else if( (sqlite3StrICmp(zDate,"subsec")==0 +@@ -25900,7 +26335,7 @@ static int parseModifier( + ** date is already on the appropriate weekday, this is a no-op. + */ + if( sqlite3_strnicmp(z, "weekday ", 8)==0 +- && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 ++ && sqlite3AtoF(&z[8], &r)>0 + && r>=0.0 && r<7.0 && (n=(int)r)==r ){ + sqlite3_int64 Z; + computeYMD_HMS(p); +@@ -25971,9 +26406,11 @@ static int parseModifier( + case '8': + case '9': { + double rRounder; +- int i; ++ int i, rx; + int Y,M,D,h,m,x; + const char *z2 = z; ++ char *zCopy; ++ sqlite3 *db = sqlite3_context_db_handle(pCtx); + char z0 = z[0]; + for(n=1; z[n]; n++){ + if( z[n]==':' ) break; +@@ -25983,7 +26420,11 @@ static int parseModifier( + if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; + } + } +- if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ ++ zCopy = sqlite3DbStrNDup(db, z, n); ++ if( zCopy==0 ) break; ++ rx = sqlite3AtoF(zCopy, &r)<=0; ++ sqlite3DbFree(db, zCopy); ++ if( rx ){ + assert( rc==1 ); + break; + } +@@ -26803,7 +27244,7 @@ static void datedebugFunc( + char *zJson; + zJson = sqlite3_mprintf( + "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d," +- "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d," ++ "s:%.3f,validJD:%d,validYMD:%d,validHMS:%d," + "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d," + "isUtc:%d,isLocal:%d}", + x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz, +@@ -27150,7 +27591,7 @@ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p + }else{ + double r; + rc = pVfs->xCurrentTime(pVfs, &r); +- *pTimeOut = (sqlite3_int64)(r*86400000.0); ++ *pTimeOut = sqlite3RealToI64(r*86400000.0); + } + return rc; + } +@@ -29582,23 +30023,28 @@ static SQLITE_WSD int mutexIsInit = 0; + + #ifndef SQLITE_MUTEX_OMIT + +-#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS ++#ifdef SQLITE_THREAD_MISUSE_WARNINGS + /* +-** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains ++** This block (enclosed by SQLITE_THREAD_MISUSE_WARNINGS) contains + ** the implementation of a wrapper around the system default mutex + ** implementation (sqlite3DefaultMutex()). + ** + ** Most calls are passed directly through to the underlying default + ** mutex implementation. Except, if a mutex is configured by calling + ** sqlite3MutexWarnOnContention() on it, then if contention is ever +-** encountered within xMutexEnter() a warning is emitted via sqlite3_log(). ++** encountered within xMutexEnter() then a warning is emitted via ++** sqlite3_log(). Furthermore, if SQLITE_THREAD_MISUSE_ABORT is ++** defined then abort() is called after the sqlite3_log() warning. + ** +-** This type of mutex is used as the database handle mutex when testing +-** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. ++** This type of mutex is used on the database handle mutex when testing ++** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. A failure ++** indicates that the app ought to be using SQLITE_OPEN_FULLMUTEX or ++** similar because it is trying to use the same database handle from ++** two different connections at the same time. + */ + + /* +-** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS ++** Type for all mutexes used when SQLITE_THREAD_MISUSE_WARNINGS + ** is defined. Variable CheckMutex.mutex is a pointer to the real mutex + ** allocated by the system mutex implementation. Variable iType is usually set + ** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST +@@ -29634,11 +30080,12 @@ static int checkMutexNotheld(sqlite3_mutex *p){ + */ + static int checkMutexInit(void){ + pGlobalMutexMethods = sqlite3DefaultMutex(); +- return SQLITE_OK; ++ return pGlobalMutexMethods->xMutexInit(); + } + static int checkMutexEnd(void){ ++ int rc = pGlobalMutexMethods->xMutexEnd(); + pGlobalMutexMethods = 0; +- return SQLITE_OK; ++ return rc; + } + + /* +@@ -29715,6 +30162,9 @@ static void checkMutexEnter(sqlite3_mutex *p){ + sqlite3_log(SQLITE_MISUSE, + "illegal multi-threaded access to database connection" + ); ++#if SQLITE_THREAD_MISUSE_ABORT ++ abort(); ++#endif + } + pGlobalMutexMethods->xMutexEnter(pCheck->mutex); + } +@@ -29766,7 +30216,7 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){ + pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION; + } + } +-#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */ ++#endif /* ifdef SQLITE_THREAD_MISUSE_WARNINGS */ + + /* + ** Initialize the mutex system. +@@ -29783,7 +30233,7 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){ + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; + + if( sqlite3GlobalConfig.bCoreMutex ){ +-#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS ++#ifdef SQLITE_THREAD_MISUSE_WARNINGS + pFrom = multiThreadedCheckMutex(); + #else + pFrom = sqlite3DefaultMutex(); +@@ -30631,14 +31081,6 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + # define SQLITE_OS_WINCE 0 + #endif + +-/* +-** Determine if we are dealing with WinRT, which provides only a subset of +-** the full Win32 API. +-*/ +-#if !defined(SQLITE_OS_WINRT) +-# define SQLITE_OS_WINRT 0 +-#endif +- + /* + ** For WinCE, some API function parameters do not appear to be declared as + ** volatile. +@@ -30653,7 +31095,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + ** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() + ** functions are not available (e.g. those not using MSVC, Cygwin, etc). + */ +-#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ ++#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && \ + SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) + # define SQLITE_OS_WIN_THREADS 1 + #else +@@ -30770,11 +31212,7 @@ static int winMutexInit(void){ + if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ + int i; + for(i=0; itrace = 1; + #endif + #endif +-#if SQLITE_OS_WINRT +- InitializeCriticalSectionEx(&p->mutex, 0, 0); +-#else + InitializeCriticalSection(&p->mutex); +-#endif + } + break; + } +@@ -32109,7 +32543,7 @@ static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ + sqlite3StrAccumSetError(pAccum, SQLITE_TOOBIG); + return 0; + } +- z = sqlite3DbMallocRaw(pAccum->db, n); ++ z = sqlite3_malloc(n); + if( z==0 ){ + sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); + } +@@ -32440,9 +32874,11 @@ SQLITE_API void sqlite3_str_vappendf( + }while( longvalue>0 ); + } + length = (int)(&zOut[nOut-1]-bufpt); +- while( precision>length ){ +- *(--bufpt) = '0'; /* Zero pad */ +- length++; ++ if( precision>length ){ /* zero pad */ ++ int nn = precision-length; ++ bufpt -= nn; ++ memset(bufpt,'0',nn); ++ length = precision; + } + if( cThousand ){ + int nn = (length - 1)/3; /* Number of "," to insert */ +@@ -32473,6 +32909,7 @@ SQLITE_API void sqlite3_str_vappendf( + FpDecode s; + int iRound; + int j; ++ i64 szBufNeeded; /* Size needed to hold the output */ + + if( bArgList ){ + realvalue = getDoubleArg(pArgList); +@@ -32493,7 +32930,7 @@ SQLITE_API void sqlite3_str_vappendf( + }else{ + iRound = precision+1; + } +- sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16); ++ sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 20 : 16); + if( s.isSpecial ){ + if( s.isSpecial==2 ){ + bufpt = flag_zeropad ? "null" : "NaN"; +@@ -32561,17 +32998,31 @@ SQLITE_API void sqlite3_str_vappendf( + }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; ++ ++ szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+10; ++ if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; ++ if( szBufNeeded + pAccum->nChar >= pAccum->nAlloc ){ ++ if( pAccum->mxAlloc==0 && pAccum->accError==0 ){ ++ /* Unable to allocate space in pAccum, perhaps because it ++ ** is coming from sqlite3_snprintf() or similar. We'll have ++ ** to render into temporary space and the memcpy() it over. */ ++ bufpt = sqlite3_malloc(szBufNeeded); ++ if( bufpt==0 ){ ++ sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); ++ return; ++ } ++ zExtra = bufpt; ++ }else if( sqlite3StrAccumEnlarge(pAccum, szBufNeeded)zText + pAccum->nChar; + } ++ }else{ ++ bufpt = pAccum->zText + pAccum->nChar; + } + zOut = bufpt; ++ + flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; + /* The sign in front of the number */ + if( prefix ){ +@@ -32579,12 +33030,24 @@ SQLITE_API void sqlite3_str_vappendf( + } + /* Digits prior to the decimal point */ + j = 0; ++ assert( s.n>0 ); + if( e2<0 ){ + *(bufpt++) = '0'; +- }else{ ++ }else if( cThousand ){ + for(; e2>=0; e2--){ + *(bufpt++) = j1 ) *(bufpt++) = ','; ++ if( (e2%3)==0 && e2>1 ) *(bufpt++) = ','; ++ } ++ }else{ ++ j = e2+1; ++ if( j>s.n ) j = s.n; ++ memcpy(bufpt, s.z, j); ++ bufpt += j; ++ e2 -= j; ++ if( e2>=0 ){ ++ memset(bufpt, '0', e2+1); ++ bufpt += e2+1; ++ e2 = -1; + } + } + /* The decimal point */ +@@ -32593,12 +33056,26 @@ SQLITE_API void sqlite3_str_vappendf( + } + /* "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'; ++ if( e2<(-1) && precision>0 ){ ++ int nn = -1-e2; ++ if( nn>precision ) nn = precision; ++ memset(bufpt, '0', nn); ++ bufpt += nn; ++ precision -= nn; + } + /* Significant digits after the decimal point */ +- while( (precision--)>0 ){ +- *(bufpt++) = j0 ){ ++ int nn = s.n - j; ++ if( NEVER(nn>precision) ) nn = precision; ++ if( nn>0 ){ ++ memcpy(bufpt, s.z+j, nn); ++ bufpt += nn; ++ precision -= nn; ++ } ++ if( precision>0 && !flag_rtz ){ ++ memset(bufpt, '0', precision); ++ bufpt += precision; ++ } + } + /* Remove trailing zeros and the "." if no digits follow the "." */ + if( flag_rtz && flag_dp ){ +@@ -32628,27 +33105,39 @@ SQLITE_API void sqlite3_str_vappendf( + *(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]; ++ assert( length <= szBufNeeded ); ++ if( lengthnChar += length; ++ zOut[length] = 0; ++ continue; ++ }else{ ++ /* We were unable to render directly into pAccum because we ++ ** couldn't allocate sufficient memory. We need to memcpy() ++ ** the rendering (or some prefix thereof) into the output ++ ** buffer. */ ++ bufpt[0] = 0; ++ bufpt = zExtra; ++ break; ++ } + } + case etSIZE: + if( !bArgList ){ +@@ -32692,10 +33181,9 @@ SQLITE_API void sqlite3_str_vappendf( + i64 nCopyBytes; + if( nPrior > precision-1 ) nPrior = precision - 1; + nCopyBytes = length*nPrior; +- if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){ +- sqlite3StrAccumEnlarge(pAccum, nCopyBytes); ++ if( sqlite3StrAccumEnlargeIfNeeded(pAccum, nCopyBytes) ){ ++ break; + } +- if( pAccum->accError ) break; + sqlite3_str_append(pAccum, + &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); + precision -= nPrior; +@@ -32799,8 +33287,8 @@ SQLITE_API void sqlite3_str_vappendf( + ** all control characters, and for backslash itself. + ** For %#Q, do the same but only if there is at least + ** one control character. */ +- u32 nBack = 0; +- u32 nCtrl = 0; ++ i64 nBack = 0; ++ i64 nCtrl = 0; + for(k=0; knChar >= p->nAlloc ){ ++ sqlite3StrAccumEnlarge(p, N); ++ } ++ return p->accError; ++} ++ + /* + ** Append N copies of character c to the given string buffer. + */ +@@ -33172,6 +33667,14 @@ SQLITE_API int sqlite3_str_length(sqlite3_str *p){ + return p ? p->nChar : 0; + } + ++/* Truncate the text of the string to be no more than N bytes. */ ++SQLITE_API void sqlite3_str_truncate(sqlite3_str *p, int N){ ++ if( p!=0 && N>=0 && (u32)NnChar ){ ++ p->nChar = N; ++ p->zText[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; +@@ -33192,6 +33695,17 @@ SQLITE_API void sqlite3_str_reset(StrAccum *p){ + p->zText = 0; + } + ++/* ++** Destroy a dynamically allocate sqlite3_str object and all ++** of its content, all in one call. ++*/ ++SQLITE_API void sqlite3_str_free(sqlite3_str *p){ ++ if( p!=0 && p!=&sqlite3OomStr ){ ++ sqlite3_str_reset(p); ++ sqlite3_free(p); ++ } ++} ++ + /* + ** Initialize a string accumulator. + ** +@@ -34805,7 +35319,13 @@ SQLITE_PRIVATE void sqlite3TreeViewTrigger( + 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 sqlite3ShowSrcList(const SrcList *p){ ++ TreeView *pView = 0; ++ sqlite3TreeViewPush(&pView, 0); ++ sqlite3TreeViewLine(pView, "SRCLIST"); ++ sqlite3TreeViewSrcList(pView,p); ++ sqlite3TreeViewPop(&pView); ++} + 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); } +@@ -35186,6 +35706,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + rc = sqlite3Win32Wait((HANDLE)p->tid); + assert( rc!=WAIT_IO_COMPLETION ); + bRc = CloseHandle((HANDLE)p->tid); ++ (void)bRc; /* Prevent warning when assert() is a no-op */ + assert( bRc ); + } + if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; +@@ -36325,266 +36846,618 @@ SQLITE_PRIVATE u8 sqlite3StrIHash(const char *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. ++#if !defined(SQLITE_DISABLE_INTRINSIC) \ ++ && (defined(__GNUC__) || defined(__clang__)) \ ++ && (defined(__x86_64__) || defined(__aarch64__) || \ ++ (defined(__riscv) && defined(__riscv_xlen) && (__riscv_xlen>32))) ++#define SQLITE_USE_UINT128 ++#endif ++ ++/* ++** Two inputs are multiplied to get a 128-bit result. Write the ++** lower 64-bits of the result into *pLo, and return the high-order ++** 64 bits. + */ +-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; ++static u64 sqlite3Multiply128(u64 a, u64 b, u64 *pLo){ ++#if defined(SQLITE_USE_UINT128) ++ __uint128_t r = (__uint128_t)a * b; ++ *pLo = (u64)r; ++ return (u64)(r>>64); ++#elif defined(_WIN64) && !defined(SQLITE_DISABLE_INTRINSIC) ++ *pLo = a*b; ++ return __umulh(a, b); ++#else ++ u64 a0 = (u32)a; ++ u64 a1 = a >> 32; ++ u64 b0 = (u32)b; ++ u64 b1 = b >> 32; ++ u64 a0b0 = a0 * b0; ++ u64 a1b1 = a1 * b1; ++ u64 a0b1 = a0 * b1; ++ u64 a1b0 = a1 * b0; ++ u64 t = (a0b0 >> 32) + (u32)a0b1 + (u32)a1b0; ++ *pLo = (a0b0 & UINT64_C(0xffffffff)) | (t << 32); ++ return a1b1 + (a0b1>>32) + (a1b0>>32) + (t>>32); ++#endif ++} ++ ++/* ++** A is an unsigned 96-bit integer formed by (a<<32)+aLo. ++** B is an unsigned 64-bit integer. ++** ++** Compute the upper 96 bits of 160-bit result of A*B. ++** ++** Write ((A*B)>>64 & 0xffffffff) (the middle 32 bits of A*B) ++** into *pLo. Return the upper 64 bits of A*B. ++** ++** The lower 64 bits of A*B are discarded. ++*/ ++static u64 sqlite3Multiply160(u64 a, u32 aLo, u64 b, u32 *pLo){ ++#if defined(SQLITE_USE_UINT128) ++ __uint128_t r = (__uint128_t)a * b; ++ r += ((__uint128_t)aLo * b) >> 32; ++ *pLo = (r>>32)&0xffffffff; ++ return r>>64; ++#elif defined(_WIN64) && !defined(SQLITE_DISABLE_INTRINSIC) ++ u64 r1_hi = __umulh(a,b); ++ u64 r1_lo = a*b; ++ u64 r2 = (__umulh((u64)aLo,b)<<32) + ((aLo*b)>>32); ++ u64 t = r1_lo + r2; ++ if( t>32; ++ return r1_hi; ++#else ++ u64 x2 = a>>32; ++ u64 x1 = a&0xffffffff; ++ u64 x0 = aLo; ++ u64 y1 = b>>32; ++ u64 y0 = b&0xffffffff; ++ u64 x2y1 = x2*y1; ++ u64 r4 = x2y1>>32; ++ u64 x2y0 = x2*y0; ++ u64 x1y1 = x1*y1; ++ u64 r3 = (x2y1 & 0xffffffff) + (x2y0 >>32) + (x1y1 >>32); ++ u64 x1y0 = x1*y0; ++ u64 x0y1 = x0*y1; ++ u64 r2 = (x2y0 & 0xffffffff) + (x1y1 & 0xffffffff) + ++ (x1y0 >>32) + (x0y1>>32); ++ u64 x0y0 = x0*y0; ++ u64 r1 = (x1y0 & 0xffffffff) + (x0y1 & 0xffffffff) + ++ (x0y0 >>32); ++ r2 += r1>>32; ++ r3 += r2>>32; ++ *pLo = r2&0xffffffff; ++ return (r4<<32) + r3; ++#endif + } + ++#undef SQLITE_USE_UINT128 ++ + /* +-** The string z[] is an text representation of a real number. +-** Convert this string to a double and write it into *pResult. ++** Return a u64 with the N-th bit set. ++*/ ++#define U64_BIT(N) (((u64)1)<<(N)) ++ ++/* ++** Range of powers of 10 that we need to deal with when converting ++** IEEE754 doubles to and from decimal. ++*/ ++#define POWERSOF10_FIRST (-348) ++#define POWERSOF10_LAST (+347) ++ ++/* ++** For any p between -348 and +347, return the integer part of + ** +-** The string z[] is length bytes in length (bytes, not characters) and +-** uses the encoding enc. The string is not necessarily zero-terminated. ++** pow(10,p) * pow(2,63-pow10to2(p)) + ** +-** 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 ++** Or, in other words, for any p in range, return the most significant ++** 64 bits of pow(10,p). The pow(10,p) value is shifted left or right, ++** as appropriate so the most significant 64 bits fit exactly into a ++** 64-bit unsigned integer. + ** +-** Valid numbers are in one of these formats: ++** Write into *pLo the next 32 significant bits of the answer after ++** the first 64. + ** +-** [+-]digits[E[+-]digits] +-** [+-]digits.[digits][E[+-]digits] +-** [+-].digits[E[+-]digits] ++** Algorithm: + ** +-** Leading and trailing whitespace is ignored for the purpose of determining +-** validity. ++** (1) For p between 0 and 26, return the value directly from the aBase[] ++** lookup table. ++** ++** (2) For p outside the range 0 to 26, use aScale[] for the initial value ++** then refine that result (if necessary) by a single multiplication ++** against aBase[]. ++** ++** The constant tables aBase[], aScale[], and aScaleLo[] are generated ++** by the C program at ../tool/mkfptab.c run with the --round option. ++*/ ++static u64 powerOfTen(int p, u32 *pLo){ ++ static const u64 aBase[] = { ++ UINT64_C(0x8000000000000000), /* 0: 1.0e+0 << 63 */ ++ UINT64_C(0xa000000000000000), /* 1: 1.0e+1 << 60 */ ++ UINT64_C(0xc800000000000000), /* 2: 1.0e+2 << 57 */ ++ UINT64_C(0xfa00000000000000), /* 3: 1.0e+3 << 54 */ ++ UINT64_C(0x9c40000000000000), /* 4: 1.0e+4 << 50 */ ++ UINT64_C(0xc350000000000000), /* 5: 1.0e+5 << 47 */ ++ UINT64_C(0xf424000000000000), /* 6: 1.0e+6 << 44 */ ++ UINT64_C(0x9896800000000000), /* 7: 1.0e+7 << 40 */ ++ UINT64_C(0xbebc200000000000), /* 8: 1.0e+8 << 37 */ ++ UINT64_C(0xee6b280000000000), /* 9: 1.0e+9 << 34 */ ++ UINT64_C(0x9502f90000000000), /* 10: 1.0e+10 << 30 */ ++ UINT64_C(0xba43b74000000000), /* 11: 1.0e+11 << 27 */ ++ UINT64_C(0xe8d4a51000000000), /* 12: 1.0e+12 << 24 */ ++ UINT64_C(0x9184e72a00000000), /* 13: 1.0e+13 << 20 */ ++ UINT64_C(0xb5e620f480000000), /* 14: 1.0e+14 << 17 */ ++ UINT64_C(0xe35fa931a0000000), /* 15: 1.0e+15 << 14 */ ++ UINT64_C(0x8e1bc9bf04000000), /* 16: 1.0e+16 << 10 */ ++ UINT64_C(0xb1a2bc2ec5000000), /* 17: 1.0e+17 << 7 */ ++ UINT64_C(0xde0b6b3a76400000), /* 18: 1.0e+18 << 4 */ ++ UINT64_C(0x8ac7230489e80000), /* 19: 1.0e+19 >> 0 */ ++ UINT64_C(0xad78ebc5ac620000), /* 20: 1.0e+20 >> 3 */ ++ UINT64_C(0xd8d726b7177a8000), /* 21: 1.0e+21 >> 6 */ ++ UINT64_C(0x878678326eac9000), /* 22: 1.0e+22 >> 10 */ ++ UINT64_C(0xa968163f0a57b400), /* 23: 1.0e+23 >> 13 */ ++ UINT64_C(0xd3c21bcecceda100), /* 24: 1.0e+24 >> 16 */ ++ UINT64_C(0x84595161401484a0), /* 25: 1.0e+25 >> 20 */ ++ UINT64_C(0xa56fa5b99019a5c8), /* 26: 1.0e+26 >> 23 */ ++ }; ++ static const u64 aScale[] = { ++ UINT64_C(0x8049a4ac0c5811ae), /* 0: 1.0e-351 << 1229 */ ++ UINT64_C(0xcf42894a5dce35ea), /* 1: 1.0e-324 << 1140 */ ++ UINT64_C(0xa76c582338ed2621), /* 2: 1.0e-297 << 1050 */ ++ UINT64_C(0x873e4f75e2224e68), /* 3: 1.0e-270 << 960 */ ++ UINT64_C(0xda7f5bf590966848), /* 4: 1.0e-243 << 871 */ ++ UINT64_C(0xb080392cc4349dec), /* 5: 1.0e-216 << 781 */ ++ UINT64_C(0x8e938662882af53e), /* 6: 1.0e-189 << 691 */ ++ UINT64_C(0xe65829b3046b0afa), /* 7: 1.0e-162 << 602 */ ++ UINT64_C(0xba121a4650e4ddeb), /* 8: 1.0e-135 << 512 */ ++ UINT64_C(0x964e858c91ba2655), /* 9: 1.0e-108 << 422 */ ++ UINT64_C(0xf2d56790ab41c2a2), /* 10: 1.0e-81 << 333 */ ++ UINT64_C(0xc428d05aa4751e4c), /* 11: 1.0e-54 << 243 */ ++ UINT64_C(0x9e74d1b791e07e48), /* 12: 1.0e-27 << 153 */ ++ UINT64_C(0xcccccccccccccccc), /* 13: 1.0e-1 << 67 (special case) */ ++ UINT64_C(0xcecb8f27f4200f3a), /* 14: 1.0e+27 >> 26 */ ++ UINT64_C(0xa70c3c40a64e6c51), /* 15: 1.0e+54 >> 116 */ ++ UINT64_C(0x86f0ac99b4e8dafd), /* 16: 1.0e+81 >> 206 */ ++ UINT64_C(0xda01ee641a708de9), /* 17: 1.0e+108 >> 295 */ ++ UINT64_C(0xb01ae745b101e9e4), /* 18: 1.0e+135 >> 385 */ ++ UINT64_C(0x8e41ade9fbebc27d), /* 19: 1.0e+162 >> 475 */ ++ UINT64_C(0xe5d3ef282a242e81), /* 20: 1.0e+189 >> 564 */ ++ UINT64_C(0xb9a74a0637ce2ee1), /* 21: 1.0e+216 >> 654 */ ++ UINT64_C(0x95f83d0a1fb69cd9), /* 22: 1.0e+243 >> 744 */ ++ UINT64_C(0xf24a01a73cf2dccf), /* 23: 1.0e+270 >> 833 */ ++ UINT64_C(0xc3b8358109e84f07), /* 24: 1.0e+297 >> 923 */ ++ UINT64_C(0x9e19db92b4e31ba9), /* 25: 1.0e+324 >> 1013 */ ++ }; ++ static const unsigned int aScaleLo[] = { ++ 0x205b896d, /* 0: 1.0e-351 << 1229 */ ++ 0x52064cad, /* 1: 1.0e-324 << 1140 */ ++ 0xaf2af2b8, /* 2: 1.0e-297 << 1050 */ ++ 0x5a7744a7, /* 3: 1.0e-270 << 960 */ ++ 0xaf39a475, /* 4: 1.0e-243 << 871 */ ++ 0xbd8d794e, /* 5: 1.0e-216 << 781 */ ++ 0x547eb47b, /* 6: 1.0e-189 << 691 */ ++ 0x0cb4a5a3, /* 7: 1.0e-162 << 602 */ ++ 0x92f34d62, /* 8: 1.0e-135 << 512 */ ++ 0x3a6a07f9, /* 9: 1.0e-108 << 422 */ ++ 0xfae27299, /* 10: 1.0e-81 << 333 */ ++ 0xaa97e14c, /* 11: 1.0e-54 << 243 */ ++ 0x775ea265, /* 12: 1.0e-27 << 153 */ ++ 0xcccccccc, /* 13: 1.0e-1 << 67 (special case) */ ++ 0x00000000, /* 14: 1.0e+27 >> 26 */ ++ 0x999090b6, /* 15: 1.0e+54 >> 116 */ ++ 0x69a028bb, /* 16: 1.0e+81 >> 206 */ ++ 0xe80e6f48, /* 17: 1.0e+108 >> 295 */ ++ 0x5ec05dd0, /* 18: 1.0e+135 >> 385 */ ++ 0x14588f14, /* 19: 1.0e+162 >> 475 */ ++ 0x8f1668c9, /* 20: 1.0e+189 >> 564 */ ++ 0x6d953e2c, /* 21: 1.0e+216 >> 654 */ ++ 0x4abdaf10, /* 22: 1.0e+243 >> 744 */ ++ 0xbc633b39, /* 23: 1.0e+270 >> 833 */ ++ 0x0a862f81, /* 24: 1.0e+297 >> 923 */ ++ 0x6c07a2c2, /* 25: 1.0e+324 >> 1013 */ ++ }; ++ int g, n; ++ u64 s, x; ++ u32 lo; ++ ++ assert( p>=POWERSOF10_FIRST && p<=POWERSOF10_LAST ); ++ if( p<0 ){ ++ if( p==(-1) ){ ++ *pLo = aScaleLo[13]; ++ return aScale[13]; ++ } ++ g = p/27; ++ n = p%27; ++ if( n ){ ++ g--; ++ n += 27; ++ } ++ }else if( p<27 ){ ++ *pLo = 0; ++ return aBase[p]; ++ }else{ ++ g = p/27; ++ n = p%27; ++ } ++ s = aScale[g+13]; ++ if( n==0 ){ ++ *pLo = aScaleLo[g+13]; ++ return s; ++ } ++ x = sqlite3Multiply160(s,aScaleLo[g+13],aBase[n],&lo); ++ if( (U64_BIT(63) & x)==0 ){ ++ x = x<<1 | ((lo>>31)&1); ++ lo = (lo<<1) | 1; ++ } ++ *pLo = lo; ++ return x; ++} ++ ++/* ++** pow10to2(x) computes floor(log2(pow(10,x))). ++** pow2to10(y) computes floor(log10(pow(2,y))). ++** ++** Conceptually, pow10to2(p) converts a base-10 exponent p into ++** a corresponding base-2 exponent, and pow2to10(e) converts a base-2 ++** exponent into a base-10 exponent. + ** +-** 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. ++** The conversions are based on the observation that: ++** ++** ln(10.0)/ln(2.0) == 108853/32768 (approximately) ++** ln(2.0)/ln(10.0) == 78913/262144 (approximately) ++** ++** These ratios are approximate, but they are accurate to 5 digits, ++** which is close enough for the usage here. Right-shift is used ++** for division so that rounding of negative numbers happens in the ++** right direction. + */ +-#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 */ +- u64 s2; /* round-tripped significand */ +- double rr[2]; ++static int pwr10to2(int p){ return (p*108853) >> 15; } ++static int pwr2to10(int p){ return (p*78913) >> 18; } + +- 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; ++/* ++** Count leading zeros for a 64-bit unsigned integer. ++*/ ++static int countLeadingZeros(u64 m){ ++#if (defined(__GNUC__) || defined(__clang__)) \ ++ && !defined(SQLITE_DISABLE_INTRINSIC) ++ return __builtin_clzll(m); ++#else ++ int n = 0; ++ if( m <= 0x00000000ffffffffULL) { n += 32; m <<= 32; } ++ if( m <= 0x0000ffffffffffffULL) { n += 16; m <<= 16; } ++ if( m <= 0x00ffffffffffffffULL) { n += 8; m <<= 8; } ++ if( m <= 0x0fffffffffffffffULL) { n += 4; m <<= 4; } ++ if( m <= 0x3fffffffffffffffULL) { n += 2; m <<= 2; } ++ if( m <= 0x7fffffffffffffffULL) { n += 1; } ++ return n; ++#endif ++} + +- if( enc==SQLITE_UTF8 ){ +- incr = 1; +- zEnd = z + length; ++/* ++** Given m and e, which represent a quantity r == m*pow(2,e), ++** return values *pD and *pP such that r == (*pD)*pow(10,*pP), ++** approximately. *pD should contain at least n significant digits. ++** ++** The input m is required to have its highest bit set. In other words, ++** m should be left-shifted, and e decremented, to maximize the value of m. ++*/ ++static void sqlite3Fp2Convert10(u64 m, int e, int n, u64 *pD, int *pP){ ++ int p; ++ u64 h, d1; ++ u32 d2; ++ assert( n>=1 && n<=18 ); ++ p = n - 1 - pwr2to10(e+63); ++ h = sqlite3Multiply128(m, powerOfTen(p,&d2), &d1); ++ assert( -(e + pwr10to2(p) + 2) >= 0 ); ++ assert( -(e + pwr10to2(p) + 1) <= 63 ); ++ if( n==18 ){ ++ h >>= -(e + pwr10to2(p) + 2); ++ *pD = (h + ((h<<1)&2))>>1; + }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> -(e + pwr10to2(p) + 1); + } ++ *pP = -p; ++} + +- /* skip leading spaces */ +- while( z=zEnd ) return 0; +- +- /* get sign of significand */ +- if( *z=='-' ){ +- sign = -1; +- z+=incr; +- }else if( *z=='+' ){ +- z+=incr; +- } ++/* ++** Return an IEEE754 floating point value that approximates d*pow(10,p). ++** ++** The (current) algorithm is adapted from the work of Ross Cox at ++** https://github.com/rsc/fpfmt ++*/ ++static double sqlite3Fp10Convert2(u64 d, int p){ ++ int b, lp, e, adj, s; ++ u32 pwr10l, mid1; ++ u64 pwr10h, x, hi, lo, sticky, u, m; ++ double r; ++ if( pPOWERSOF10_LAST ) return INFINITY; ++ b = 64 - countLeadingZeros(d); ++ lp = pwr10to2(p); ++ e = 53 - b - lp; ++ if( e > 1074 ){ ++ if( e>=1130 ) return 0.0; ++ e = 1074; ++ } ++ s = -(e-(64-b) + lp + 3); ++ pwr10h = powerOfTen(p, &pwr10l); ++ if( pwr10l!=0 ){ ++ pwr10h++; ++ pwr10l = ~pwr10l; ++ } ++ x = d<<(64-b); ++ hi = sqlite3Multiply128(x,pwr10h,&lo); ++ mid1 = lo>>32; ++ sticky = 1; ++ if( (hi & (U64_BIT(s)-1))==0 ) { ++ u32 mid2 = sqlite3Multiply128(x,((u64)pwr10l)<<32,&lo)>>32; ++ sticky = (mid1-mid2 > 1); ++ hi -= mid1 < mid2; ++ } ++ u = (hi>>s) | sticky; ++ adj = (u >= U64_BIT(55)-2); ++ if( adj ){ ++ u = (u>>adj) | (u&1); ++ e -= adj; ++ } ++ m = (u + 1 + ((u>>2)&1)) >> 2; ++ if( e<=(-972) ) return INFINITY; ++ if((m & U64_BIT(52)) != 0){ ++ m = (m & ~U64_BIT(52)) | ((u64)(1075-e)<<52); ++ } ++ memcpy(&r,&m,8); ++ return r; ++} + +- /* 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 Set if any prefix of the input is valid. Clear if ++** there is no prefix of the input that can be seen as ++** a valid floating point number. ++** bit 1 => Set if the input contains a decimal point or eNNN ++** clause. Zero if the input is an integer. ++** bit 2 => The input is exactly 0.0, not an underflow from ++** some value near zero. ++** bit 3 => Set if there are more than about 19 significant ++** digits in the input. ++** ++** If the input contains a syntax error but begins with text that might ++** be a valid number of some kind, then the result is negative. The ++** result is only zero if no prefix of the input could be interpreted as ++** a number. ++** ++** Leading and trailing whitespace is ignored. Valid numbers are in ++** one of the formats below: ++** ++** [+-]digits[E[+-]digits] ++** [+-]digits.[digits][E[+-]digits] ++** [+-].digits[E[+-]digits] ++** ++** Algorithm sketch: Compute an unsigned 64-bit integer s and a base-10 ++** exponent d such that the value encoding by the input is s*pow(10,d). ++** Then invoke sqlite3Fp10Convert2() to calculated the closest possible ++** IEEE754 double. The sign is added back afterwards, if the input string ++** starts with a "-". The use of an unsigned 64-bit s mantissa means that ++** only about the first 19 significant digits of the input can contribute ++** to the result. This can result in suboptimal rounding decisions when ++** correct rounding requires more than 19 input digits. For example, ++** this routine renders "3500000000000000.2500001" as ++** 3500000000000000.0 instead of 3500000000000000.5 because the decision ++** to round up instead of using banker's rounding to round down is determined ++** by the 23rd significant digit, which this routine ignores. It is not ++** possible to do better without some kind of BigNum. ++*/ ++SQLITE_PRIVATE int sqlite3AtoF(const char *zIn, double *pResult){ ++#ifndef SQLITE_OMIT_FLOATING_POINT ++ const unsigned char *z = (const unsigned char*)zIn; ++ int neg = 0; /* True for a negative value */ ++ u64 s = 0; /* mantissa */ ++ int d = 0; /* Value is s * pow(10,d) */ ++ int mState = 0; /* 1: digit seen 2: fp 4: hard-zero */ ++ unsigned v; /* Value of a single digit */ ++ ++ start_of_text: ++ if( (v = (unsigned)z[0] - '0')<10 ){ ++ parse_integer_part: ++ mState = 1; ++ s = v; ++ z++; ++ while( (v = (unsigned)z[0] - '0')<10 ){ ++ s = s*10 + v; ++ z++; ++ if( s>=(LARGEST_UINT64-9)/10 ){ ++ mState = 9; ++ while( sqlite3Isdigit(z[0]) ){ z++; d++; } ++ break; ++ } + } ++ }else if( z[0]=='-' ){ ++ neg = 1; ++ z++; ++ if( (v = (unsigned)z[0] - '0')<10 ) goto parse_integer_part; ++ }else if( z[0]=='+' ){ ++ z++; ++ if( (v = (unsigned)z[0] - '0')<10 ) goto parse_integer_part; ++ }else if( sqlite3Isspace(z[0]) ){ ++ do{ z++; }while( sqlite3Isspace(z[0]) ); ++ goto start_of_text; ++ }else{ ++ s = 0; + } +- if( 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*/ ++ int esign; ++ z++; + + /* get sign of exponent */ + if( *z=='-' ){ + esign = -1; +- z+=incr; +- }else if( *z=='+' ){ +- z+=incr; ++ z++; ++ }else{ ++ esign = +1; ++ if( *z=='+' ){ ++ z++; ++ } + } + /* copy digits to exponent */ +- while( z0 && s<((LARGEST_UINT64-0x7ff)/10) ){ +- s *= 10; +- e--; +- } +- while( e<0 && (s%10)==0 ){ +- s /= 10; +- e++; +- } +- +- rr[0] = (double)s; +- assert( sizeof(s2)==sizeof(rr[0]) ); +-#ifdef SQLITE_DEBUG +- rr[1] = 18446744073709549568.0; +- memcpy(&s2, &rr[1], sizeof(s2)); +- assert( s2==0x43efffffffffffffLL ); +-#endif +- /* Largest double that can be safely converted to u64 +- ** vvvvvvvvvvvvvvvvvvvvvv */ +- if( rr[0]<=18446744073709549568.0 ){ +- s2 = (u64)rr[0]; +- rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); ++ *pResult = 0.0; ++ mState |= 4; + }else{ +- rr[1] = 0.0; ++ *pResult = sqlite3Fp10Convert2(s,d); + } +- assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ +- +- 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; ++ if( neg ) *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; ++ if( z[0]==0 ){ ++ return mState; + } ++ if( sqlite3Isspace(z[0]) ){ ++ do{ z++; }while( sqlite3Isspace(*z) ); ++ if( z[0]==0 ){ ++ return mState; ++ } ++ } ++ return 0xfffffff0 | mState; + #else +- return !sqlite3Atoi64(z, pResult, length, enc); ++ return sqlite3Atoi64(z, pResult, strlen(z), SQLITE_UTF8)==0; + #endif /* SQLITE_OMIT_FLOATING_POINT */ + } +-#if defined(_MSC_VER) +-#pragma warning(default : 4756) ++ ++/* ++** Digit pairs used to convert a U64 or I64 into text, two digits ++** at a time. ++*/ ++static const union { ++ char a[201]; ++ short int forceAlignment; ++} sqlite3DigitPairs = { ++ "00010203040506070809" ++ "10111213141516171819" ++ "20212223242526272829" ++ "30313233343536373839" ++ "40414243444546474849" ++ "50515253545556575859" ++ "60616263646566676869" ++ "70717273747576777879" ++ "80818283848586878889" ++ "90919293949596979899" ++}; ++ ++/* ++** ARMv6, ARMv7, PPC32 are known to not support hardware u64 division. ++*/ ++#if (defined(__arm__) && !defined(__aarch64__)) || \ ++ (defined(__ppc__) && !defined(__ppc64__)) ++# define SQLITE_AVOID_U64_DIVIDE 1 + #endif + ++#ifdef SQLITE_AVOID_U64_DIVIDE ++/* ++** Render an unsigned 64-bit integer as text onto the end of a 2-byte ++** aligned buffer that is SQLITE_U64_DIGIT+1 bytes long. The last byte ++** of the buffer will be filled with a \000 byte. ++** ++** Return the index into the buffer of the first byte. ++** ++** This routine is used on platforms where u64-division is slow because ++** it is not available in hardware and has to be emulated in software. ++** It seeks to minimize the number of u64 divisions and use u32 divisions ++** instead. It is slower on platforms that have hardware u64 division, ++** but much faster on platforms that do not. ++*/ ++static int sqlite3UInt64ToText(u64 v, char *zOut){ ++ u32 x32, kk; ++ int i; ++ zOut[SQLITE_U64_DIGITS] = 0; ++ i = SQLITE_U64_DIGITS; ++ assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[0]) ); ++ assert( TWO_BYTE_ALIGNMENT(zOut) ); ++ while( (v>>32)!=0 ){ ++ u32 y, x0, x1, y0, y1; ++ x32 = v % 100000000; ++ v = v / 100000000; ++ y = x32 % 10000; ++ x32 /= 10000; ++ x1 = x32 / 100; ++ x0 = x32 % 100; ++ y1 = y / 100; ++ y0 = y % 100; ++ assert( i>=8 ); ++ i -= 8; ++ *(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[x1*2]; ++ *(u16*)(&zOut[i+2]) = *(u16*)&sqlite3DigitPairs.a[x0*2]; ++ *(u16*)(&zOut[i+4]) = *(u16*)&sqlite3DigitPairs.a[y1*2]; ++ *(u16*)(&zOut[i+6]) = *(u16*)&sqlite3DigitPairs.a[y0*2]; ++ } ++ x32 = v; ++ while( x32>=10 ){ ++ kk = x32 % 100; ++ x32 = x32 / 100; ++ assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk*2]) ); ++ assert( i>=2 ); ++ i -= 2; ++ assert( TWO_BYTE_ALIGNMENT(&zOut[i]) ); ++ *(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[kk*2]; ++ } ++ if( x32 ){ ++ assert( i>0 ); ++ zOut[--i] = x32 + '0'; ++ } ++ return i; ++} ++#endif /* defined(SQLITE_AVOID_U64_DIVIDE) */ ++ + /* + ** 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 +@@ -36596,23 +37469,39 @@ atof_return: + 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{ ++ union { ++ char a[SQLITE_U64_DIGITS+1]; ++ u16 forceAlignment; ++ } u; ++ if( v>0 ){ + x = v; ++ }else if( v==0 ){ ++ zOut[0] = '0'; ++ zOut[1] = 0; ++ return 1; ++ }else{ ++ x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-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; ++#ifdef SQLITE_AVOID_U64_DIVIDE ++ i = sqlite3UInt64ToText(x, u.a); ++#else ++ i = sizeof(u.a)-1; ++ u.a[i] = 0; ++ while( x>=10 ){ ++ int kk = (x%100)*2; ++ assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) ); ++ assert( TWO_BYTE_ALIGNMENT(&u.a[i-2]) ); ++ *(u16*)(&u.a[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk]; ++ i -= 2; ++ x /= 100; ++ } ++ if( x ){ ++ u.a[--i] = x + '0'; ++ } ++#endif /* SQLITE_AVOID_U64_DIVIDE */ ++ if( v<0 ) u.a[--i] = '-'; ++ memcpy(zOut, &u.a[i], sizeof(u.a)-i); ++ return sizeof(u.a)-1-i; + } + + /* +@@ -36666,8 +37555,8 @@ 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 i, j; ++ unsigned int c = 0; + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ + int rc; /* Baseline return code */ + const char *zStart; +@@ -36695,8 +37584,8 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc + } + zStart = zNum; + while( zNum='0' && c<='9'; i+=incr){ +- u = u*10 + c - '0'; ++ for(i=0; &zNum[i]19*incr ? 1 : compare2pow63(zNum, incr); +- if( c<0 ){ ++ j = i>19*incr ? 1 : compare2pow63(zNum, incr); ++ if( j<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 ){ ++ if( j>0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 2; + }else{ +@@ -36869,7 +37758,7 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ + ** representation. + ** + ** If iRound<=0 then round to -iRound significant digits to the +-** the left of the decimal point, or to a maximum of mxRound total ++** the right of the decimal point, or to a maximum of mxRound total + ** significant digits. + ** + ** If iRound>0 round to min(iRound,mxRound) significant digits total. +@@ -36882,13 +37771,14 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ + ** 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; +- double rr[2]; ++ int i; /* Index into zBuf[] where to put next character */ ++ int n; /* Number of digits */ ++ u64 v; /* mantissa */ ++ int e, exp = 0; /* Base-2 and base-10 exponent */ ++ char *zBuf; /* Local alias for p->zBuf */ ++ char *z; /* Local alias for p->z */ + + p->isSpecial = 0; +- p->z = p->zBuf; + assert( mxRound>0 ); + + /* Convert negative numbers to positive. Deal with Infinity, 0.0, and +@@ -36906,78 +37796,100 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou + p->sign = '+'; + } + memcpy(&v,&r,8); +- e = v>>52; +- if( (e&0x7ff)==0x7ff ){ ++ e = (v>>52)&0x7ff; ++ if( e==0x7ff ){ + p->isSpecial = 1 + (v!=0x7ff0000000000000LL); + p->n = 0; + p->iDP = 0; ++ p->z = p->zBuf; + return; + } +- +- /* Multiply r by powers of ten until it lands somewhere in between +- ** 1.0e+19 and 1.0e+17. +- ** +- ** 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))); +- */ +- 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); +- } ++ v &= 0x000fffffffffffffULL; ++ if( e==0 ){ ++ int nn = countLeadingZeros(v); ++ v <<= nn; ++ e = -1074 - nn; + }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 = (v<<11) | U64_BIT(63); ++ e -= 1086; + } +- v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; ++ sqlite3Fp2Convert10(v, e, (iRound<=0||iRound>=18)?18:iRound+1, &v, &exp); + +- /* Extract significant digits. */ +- i = sizeof(p->zBuf)-1; ++ /* Extract significant digits, start at the right-most slot in p->zBuf ++ ** and working back to the right. "i" keeps track of the next slot in ++ ** which to store a digit. */ ++ assert( sizeof(p->zBuf)==SQLITE_U64_DIGITS+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; ++ zBuf = p->zBuf; ++#ifdef SQLITE_AVOID_U64_DIVIDE ++ i = sqlite3UInt64ToText(v, zBuf); ++#else ++ i = SQLITE_U64_DIGITS; ++ while( v>=10 ){ ++ int kk = (v%100)*2; ++ assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) ); ++ assert( TWO_BYTE_ALIGNMENT(&zBuf[i]) ); ++ assert( i-2>=0 ); ++ *(u16*)(&zBuf[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk]; ++ i -= 2; ++ v /= 100; ++ } ++ if( v ){ ++ assert( v<10 ); ++ assert( i>0 ); ++ zBuf[--i] = v + '0'; ++ } ++#endif /* SQLITE_AVOID_U64_DIVIDE */ ++ assert( i>=0 && i0 ); ++ assert( n<=SQLITE_U64_DIGITS ); ++ p->iDP = n + exp; + if( iRound<=0 ){ + iRound = p->iDP - iRound; +- if( iRound==0 && p->zBuf[i+1]>='5' ){ ++ if( iRound==0 && zBuf[i]>='5' ){ + iRound = 1; +- p->zBuf[i--] = '0'; +- p->n++; ++ zBuf[--i] = '0'; ++ n++; + p->iDP++; + } + } +- if( iRound>0 && (iRoundn || p->n>mxRound) ){ +- char *z = &p->zBuf[i+1]; ++ z = &zBuf[i]; /* z points to the first digit */ ++ if( iRound>0 && (iRoundmxRound) ){ + if( iRound>mxRound ) iRound = mxRound; +- p->n = iRound; ++ if( iRound==17 ){ ++ /* If the precision is exactly 17, which only happens with the "!" ++ ** flag (ex: "%!.17g") then try to reduce the precision if that ++ ** yields text that will round-trip to the original floating-point. ++ ** value. Thus, for exaple, 49.47 will render as 49.47, rather than ++ ** as 49.469999999999999. */ ++ if( z[15]=='9' && z[14]=='9' ){ ++ int jj, kk; ++ u64 v2; ++ for(jj=14; jj>0 && z[jj-1]=='9'; jj--){} ++ if( jj==0 ){ ++ v2 = 1; ++ }else{ ++ v2 = z[0] - '0'; ++ for(kk=1; kkiDP>=n || (z[15]=='0' && z[14]=='0' && z[13]=='0') ){ ++ int jj, kk; ++ u64 v2; ++ assert( z[0]!='0' ); ++ for(jj=13; z[jj-1]=='0'; jj--){} ++ v2 = z[0] - '0'; ++ for(kk=1; kk='5' ){ + int j = iRound-1; + while( 1 /*exit-by-break*/ ){ +@@ -36985,8 +37897,9 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou + if( z[j]<='9' ) break; + z[j] = '0'; + if( j==0 ){ +- p->z[i--] = '1'; +- p->n++; ++ z--; ++ z[0] = '1'; ++ n++; + p->iDP++; + break; + }else{ +@@ -36995,13 +37908,13 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou + } + } + } +- p->z = &p->zBuf[i+1]; +- assert( i+p->n < sizeof(p->zBuf) ); +- assert( p->n>0 ); +- while( p->z[p->n-1]=='0' ){ +- p->n--; +- assert( p->n>0 ); ++ assert( n>0 ); ++ while( z[n-1]=='0' ){ ++ n--; ++ assert( n>0 ); + } ++ p->n = n; ++ p->z = z; + } + + /* +@@ -38066,10 +38979,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), + /* 45 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 46 */ "IdxGE" OpHelp("key=r[P3@P4]"), +- /* 47 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), +- /* 48 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), +- /* 49 */ "Program" OpHelp(""), +- /* 50 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), ++ /* 47 */ "IFindKey" OpHelp(""), ++ /* 48 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), ++ /* 49 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), ++ /* 50 */ "Program" OpHelp(""), + /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), +@@ -38079,49 +38992,49 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + /* 57 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 59 */ "ElseEq" OpHelp(""), +- /* 60 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), +- /* 61 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), +- /* 62 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), +- /* 63 */ "IncrVacuum" OpHelp(""), +- /* 64 */ "VNext" OpHelp(""), +- /* 65 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), +- /* 66 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), +- /* 67 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), +- /* 68 */ "Return" OpHelp(""), +- /* 69 */ "EndCoroutine" OpHelp(""), +- /* 70 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), +- /* 71 */ "Halt" OpHelp(""), +- /* 72 */ "Integer" OpHelp("r[P2]=P1"), +- /* 73 */ "Int64" OpHelp("r[P2]=P4"), +- /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"), +- /* 75 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), +- /* 76 */ "Null" OpHelp("r[P2..P3]=NULL"), +- /* 77 */ "SoftNull" OpHelp("r[P1]=NULL"), +- /* 78 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), +- /* 79 */ "Variable" OpHelp("r[P2]=parameter(P1)"), +- /* 80 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), +- /* 81 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), +- /* 82 */ "SCopy" OpHelp("r[P2]=r[P1]"), +- /* 83 */ "IntCopy" OpHelp("r[P2]=r[P1]"), +- /* 84 */ "FkCheck" OpHelp(""), +- /* 85 */ "ResultRow" OpHelp("output=r[P1@P2]"), +- /* 86 */ "CollSeq" OpHelp(""), +- /* 87 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), +- /* 88 */ "RealAffinity" OpHelp(""), +- /* 89 */ "Cast" OpHelp("affinity(r[P1])"), +- /* 90 */ "Permutation" OpHelp(""), +- /* 91 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), +- /* 92 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), +- /* 93 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), +- /* 94 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), +- /* 95 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), +- /* 96 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), +- /* 97 */ "Affinity" OpHelp("affinity(r[P1@P2])"), +- /* 98 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), +- /* 99 */ "Count" OpHelp("r[P2]=count()"), +- /* 100 */ "ReadCookie" OpHelp(""), +- /* 101 */ "SetCookie" OpHelp(""), +- /* 102 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), ++ /* 60 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), ++ /* 61 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), ++ /* 62 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), ++ /* 63 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), ++ /* 64 */ "IncrVacuum" OpHelp(""), ++ /* 65 */ "VNext" OpHelp(""), ++ /* 66 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), ++ /* 67 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), ++ /* 68 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), ++ /* 69 */ "Return" OpHelp(""), ++ /* 70 */ "EndCoroutine" OpHelp(""), ++ /* 71 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), ++ /* 72 */ "Halt" OpHelp(""), ++ /* 73 */ "Integer" OpHelp("r[P2]=P1"), ++ /* 74 */ "Int64" OpHelp("r[P2]=P4"), ++ /* 75 */ "String" OpHelp("r[P2]='P4' (len=P1)"), ++ /* 76 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), ++ /* 77 */ "Null" OpHelp("r[P2..P3]=NULL"), ++ /* 78 */ "SoftNull" OpHelp("r[P1]=NULL"), ++ /* 79 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), ++ /* 80 */ "Variable" OpHelp("r[P2]=parameter(P1)"), ++ /* 81 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), ++ /* 82 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), ++ /* 83 */ "SCopy" OpHelp("r[P2]=r[P1]"), ++ /* 84 */ "IntCopy" OpHelp("r[P2]=r[P1]"), ++ /* 85 */ "FkCheck" OpHelp(""), ++ /* 86 */ "ResultRow" OpHelp("output=r[P1@P2]"), ++ /* 87 */ "CollSeq" OpHelp(""), ++ /* 88 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), ++ /* 89 */ "RealAffinity" OpHelp(""), ++ /* 90 */ "Cast" OpHelp("affinity(r[P1])"), ++ /* 91 */ "Permutation" OpHelp(""), ++ /* 92 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), ++ /* 93 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), ++ /* 94 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), ++ /* 95 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), ++ /* 96 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), ++ /* 97 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), ++ /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"), ++ /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), ++ /* 100 */ "Count" OpHelp("r[P2]=count()"), ++ /* 101 */ "ReadCookie" OpHelp(""), ++ /* 102 */ "SetCookie" OpHelp(""), + /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), +- /* 162 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), +- /* 163 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), +- /* 164 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), +- /* 165 */ "AggValue" OpHelp("r[P3]=value N=P2"), +- /* 166 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), +- /* 167 */ "Expire" OpHelp(""), +- /* 168 */ "CursorLock" OpHelp(""), +- /* 169 */ "CursorUnlock" OpHelp(""), +- /* 170 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), +- /* 171 */ "VBegin" OpHelp(""), +- /* 172 */ "VCreate" OpHelp(""), +- /* 173 */ "VDestroy" OpHelp(""), +- /* 174 */ "VOpen" OpHelp(""), +- /* 175 */ "VCheck" OpHelp(""), +- /* 176 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), +- /* 177 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), +- /* 178 */ "VRename" OpHelp(""), +- /* 179 */ "Pagecount" OpHelp(""), +- /* 180 */ "MaxPgcnt" OpHelp(""), +- /* 181 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), +- /* 182 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), +- /* 183 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), +- /* 184 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), +- /* 185 */ "Trace" OpHelp(""), +- /* 186 */ "CursorHint" OpHelp(""), +- /* 187 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), +- /* 188 */ "Noop" OpHelp(""), +- /* 189 */ "Explain" OpHelp(""), +- /* 190 */ "Abortable" OpHelp(""), ++ /* 155 */ "DropIndex" OpHelp(""), ++ /* 156 */ "DropTrigger" OpHelp(""), ++ /* 157 */ "IntegrityCk" OpHelp(""), ++ /* 158 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), ++ /* 159 */ "Param" OpHelp(""), ++ /* 160 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), ++ /* 161 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), ++ /* 162 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), ++ /* 163 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), ++ /* 164 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), ++ /* 165 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), ++ /* 166 */ "AggValue" OpHelp("r[P3]=value N=P2"), ++ /* 167 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), ++ /* 168 */ "Expire" OpHelp(""), ++ /* 169 */ "CursorLock" OpHelp(""), ++ /* 170 */ "CursorUnlock" OpHelp(""), ++ /* 171 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), ++ /* 172 */ "VBegin" OpHelp(""), ++ /* 173 */ "VCreate" OpHelp(""), ++ /* 174 */ "VDestroy" OpHelp(""), ++ /* 175 */ "VOpen" OpHelp(""), ++ /* 176 */ "VCheck" OpHelp(""), ++ /* 177 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), ++ /* 178 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), ++ /* 179 */ "VRename" OpHelp(""), ++ /* 180 */ "Pagecount" OpHelp(""), ++ /* 181 */ "MaxPgcnt" OpHelp(""), ++ /* 182 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), ++ /* 183 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), ++ /* 184 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), ++ /* 185 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), ++ /* 186 */ "Trace" OpHelp(""), ++ /* 187 */ "CursorHint" OpHelp(""), ++ /* 188 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), ++ /* 189 */ "Noop" OpHelp(""), ++ /* 190 */ "Explain" OpHelp(""), ++ /* 191 */ "Abortable" OpHelp(""), + }; + return azName[i]; + } +@@ -38240,7 +39154,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + ** Debugging logic + */ + +-/* SQLITE_KV_TRACE() is used for tracing calls to kvstorage routines. */ ++/* SQLITE_KV_TRACE() is used for tracing calls to kvrecord routines. */ + #if 0 + #define SQLITE_KV_TRACE(X) printf X + #else +@@ -38254,7 +39168,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + #define SQLITE_KV_LOG(X) + #endif + +- + /* + ** Forward declaration of objects used by this VFS implementation + */ +@@ -38262,6 +39175,11 @@ typedef struct KVVfsFile KVVfsFile; + + /* A single open file. There are only two files represented by this + ** VFS - the database and the rollback journal. ++** ++** Maintenance reminder: if this struct changes in any way, the JSON ++** rendering of its structure must be updated in ++** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary ++** compatibility concerns, so it does not need an iVersion member. + */ + struct KVVfsFile { + sqlite3_file base; /* IO methods */ +@@ -38311,7 +39229,7 @@ static int kvvfsCurrentTime(sqlite3_vfs*, double*); + static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + + static sqlite3_vfs sqlite3OsKvvfsObject = { +- 1, /* iVersion */ ++ 2, /* iVersion */ + sizeof(KVVfsFile), /* szOsFile */ + 1024, /* mxPathname */ + 0, /* pNext */ +@@ -38387,23 +39305,37 @@ static sqlite3_io_methods kvvfs_jrnl_io_methods = { + + /* 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 ++#ifndef SQLITE_WASM ++/* In WASM builds these are implemented in JS. */ ++static int kvrecordWrite(const char*, const char *zKey, const char *zData); ++static int kvrecordDelete(const char*, const char *zKey); ++static int kvrecordRead(const char*, const char *zKey, char *zBuf, int nBuf); ++#endif ++#ifndef KVRECORD_KEY_SZ ++#define KVRECORD_KEY_SZ 32 ++#endif + + /* Expand the key name with an appropriate prefix and put the result + ** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least +-** KVSTORAGE_KEY_SZ bytes. ++** KVRECORD_KEY_SZ bytes. + */ +-static void kvstorageMakeKey( ++static void kvrecordMakeKey( + const char *zClass, + const char *zKeyIn, + char *zKeyOut + ){ +- sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); ++ assert( zKeyIn ); ++ assert( zKeyOut ); ++ assert( zClass ); ++ sqlite3_snprintf(KVRECORD_KEY_SZ, zKeyOut, "kvvfs-%s-%s", ++ zClass, zKeyIn); + } + ++#ifndef SQLITE_WASM ++/* In WASM builds do not define APIs which use fopen(), fwrite(), ++** and the like because those APIs are a portability issue for ++** WASM. ++*/ + /* Write content into a key. zClass is the particular namespace of the + ** underlying key/value store to use - either "local" or "session". + ** +@@ -38411,14 +39343,14 @@ static void kvstorageMakeKey( + ** + ** Return the number of errors. + */ +-static int kvstorageWrite( ++static int kvrecordWrite( + const char *zClass, + const char *zKey, + const char *zData + ){ + FILE *fd; +- char zXKey[KVSTORAGE_KEY_SZ]; +- kvstorageMakeKey(zClass, zKey, zXKey); ++ char zXKey[KVRECORD_KEY_SZ]; ++ kvrecordMakeKey(zClass, zKey, zXKey); + fd = fopen(zXKey, "wb"); + if( fd ){ + SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, +@@ -38436,9 +39368,9 @@ static int kvstorageWrite( + ** 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); ++static int kvrecordDelete(const char *zClass, const char *zKey){ ++ char zXKey[KVRECORD_KEY_SZ]; ++ kvrecordMakeKey(zClass, zKey, zXKey); + unlink(zXKey); + SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); + return 0; +@@ -38459,7 +39391,7 @@ static int kvstorageDelete(const char *zClass, const char *zKey){ + ** zero-terminates zBuf at zBuf[0] and returns the size of the data + ** without reading it. + */ +-static int kvstorageRead( ++static int kvrecordRead( + const char *zClass, + const char *zKey, + char *zBuf, +@@ -38467,8 +39399,8 @@ static int kvstorageRead( + ){ + FILE *fd; + struct stat buf; +- char zXKey[KVSTORAGE_KEY_SZ]; +- kvstorageMakeKey(zClass, zKey, zXKey); ++ char zXKey[KVRECORD_KEY_SZ]; ++ kvrecordMakeKey(zClass, zKey, zXKey); + if( access(zXKey, R_OK)!=0 + || stat(zXKey, &buf)!=0 + || !S_ISREG(buf.st_mode) +@@ -38500,6 +39432,8 @@ static int kvstorageRead( + return (int)n; + } + } ++#endif /* #ifndef SQLITE_WASM */ ++ + + /* + ** An internal level of indirection which enables us to replace the +@@ -38507,17 +39441,27 @@ static int kvstorageRead( + ** Maintenance reminder: if this struct changes in any way, the JSON + ** rendering of its structure must be updated in + ** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary +-** compatibility concerns, so it does not need an iVersion +-** member. ++** compatibility concerns, so it does not need an iVersion member. + */ + 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); ++ int (*xRcrdRead)(const char*, const char *zKey, char *zBuf, int nBuf); ++ int (*xRcrdWrite)(const char*, const char *zKey, const char *zData); ++ int (*xRcrdDelete)(const char*, const char *zKey); + const int nKeySize; ++ const int nBufferSize; ++#ifndef SQLITE_WASM ++# define MAYBE_CONST const ++#else ++# define MAYBE_CONST ++#endif ++ MAYBE_CONST sqlite3_vfs * pVfs; ++ MAYBE_CONST sqlite3_io_methods *pIoDb; ++ MAYBE_CONST sqlite3_io_methods *pIoJrnl; ++#undef MAYBE_CONST + }; + ++ + /* + ** This object holds the kvvfs I/O methods which may be swapped out + ** for JavaScript-side implementations in WASM builds. In such builds +@@ -38532,10 +39476,20 @@ struct sqlite3_kvvfs_methods { + const + #endif + SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { +-kvstorageRead, +-kvstorageWrite, +-kvstorageDelete, +-KVSTORAGE_KEY_SZ ++#ifndef SQLITE_WASM ++ .xRcrdRead = kvrecordRead, ++ .xRcrdWrite = kvrecordWrite, ++ .xRcrdDelete = kvrecordDelete, ++#else ++ .xRcrdRead = 0, ++ .xRcrdWrite = 0, ++ .xRcrdDelete = 0, ++#endif ++ .nKeySize = KVRECORD_KEY_SZ, ++ .nBufferSize = SQLITE_KVOS_SZ, ++ .pVfs = &sqlite3OsKvvfsObject, ++ .pIoDb = &kvvfs_db_io_methods, ++ .pIoJrnl = &kvvfs_jrnl_io_methods + }; + + /****** Utility subroutines ************************************************/ +@@ -38562,7 +39516,10 @@ KVSTORAGE_KEY_SZ + ** 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){ ++#ifndef SQLITE_WASM ++static ++#endif ++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='a' && c<='z' ){ + n += (c - 'a')*mult; ++ if( n>nOut ) return -1 /* oversized/malformed input */; + mult *= 26; + c = aIn[++i]; + } +- if( j+n>nOut ) return -1; ++ if( j+n>nOut ) return -1 /* oversized/malformed input */; + 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; ++ if( c<0 ) return -1 /* hex bytes are always in pairs */; + aOut[j++] += c; + i++; + } +@@ -38669,7 +39631,7 @@ static void kvvfsDecodeJournal( + i = 0; + mult = 1; + while( (c = zTxt[i++])>='a' && c<='z' ){ +- n += (zTxt[i] - 'a')*mult; ++ n += (c - 'a')*mult; + mult *= 26; + } + sqlite3_free(pFile->aJrnl); +@@ -38693,13 +39655,14 @@ static void kvvfsDecodeJournal( + static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ + char zData[50]; + zData[0] = 0; +- sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1); ++ sqlite3KvvfsMethods.xRcrdRead(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); ++ return sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, "sz", zData); + } + + /****** sqlite3_io_methods methods ******************************************/ +@@ -38714,6 +39677,7 @@ static int kvvfsClose(sqlite3_file *pProtoFile){ + pFile->isJournal ? "journal" : "db")); + sqlite3_free(pFile->aJrnl); + sqlite3_free(pFile->aData); ++ memset(pFile, 0, sizeof(*pFile)); + return SQLITE_OK; + } + +@@ -38730,16 +39694,23 @@ static int kvvfsReadJrnl( + 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); ++ int rc; ++ int szTxt = sqlite3KvvfsMethods.xRcrdRead(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); ++ rc = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "jrnl", ++ aTxt, szTxt+1); ++ if( rc>=0 ){ ++ kvvfsDecodeJournal(pFile, aTxt, szTxt); ++ rc = 0; ++ } + sqlite3_free(aTxt); ++ if( rc ) return rc; + if( pFile->aJrnl==0 ) return SQLITE_IOERR; + } + if( iOfst+iAmt>pFile->nJrnl ){ +@@ -38779,8 +39750,8 @@ static int kvvfsReadDb( + pgno = 1; + } + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); +- got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, +- aData, SQLITE_KVOS_SZ-1); ++ got = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, zKey, ++ aData, SQLITE_KVOS_SZ-1); + if( got<0 ){ + n = 0; + }else{ +@@ -38848,6 +39819,7 @@ static int kvvfsWriteDb( + unsigned int pgno; + char zKey[30]; + char *aData = pFile->aData; ++ int rc; + SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + assert( iAmt>=512 && iAmt<=65536 ); + assert( (iAmt & (iAmt-1))==0 ); +@@ -38856,13 +39828,13 @@ static int kvvfsWriteDb( + 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; ++ rc = sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, zKey, aData); ++ if( 0==rc ){ ++ if( iOfst+iAmt > pFile->szDb ){ ++ pFile->szDb = iOfst + iAmt; ++ } + } +- return SQLITE_OK; ++ return rc; + } + + /* +@@ -38872,7 +39844,7 @@ 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"); ++ sqlite3KvvfsMethods.xRcrdDelete(pFile->zClass, "jrnl"); + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = 0; + pFile->nJrnl = 0; +@@ -38891,7 +39863,7 @@ static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ + pgnoMax = 2 + pFile->szDb/pFile->szPage; + while( pgno<=pgnoMax ){ + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); +- sqlite3KvvfsMethods.xDelete(pFile->zClass, zKey); ++ sqlite3KvvfsMethods.xRcrdDelete(pFile->zClass, zKey); + pgno++; + } + pFile->szDb = size; +@@ -38923,7 +39895,7 @@ static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ + }while( n>0 ); + zOut[i++] = ' '; + kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); +- i = sqlite3KvvfsMethods.xWrite(pFile->zClass, "jrnl", zOut); ++ i = sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, "jrnl", zOut); + sqlite3_free(zOut); + return i ? SQLITE_IOERR : SQLITE_OK; + } +@@ -39037,33 +40009,32 @@ static int kvvfsOpen( + 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 +- ){ ++ assert(!pFile->zClass); ++ assert(!pFile->aData); ++ assert(!pFile->aJrnl); ++ assert(!pFile->nJrnl); ++ assert(!pFile->base.pMethods); ++ pFile->szPage = -1; ++ pFile->szDb = -1; ++ if( 0==sqlite3_strglob("*-journal", zName) ){ + pFile->isJournal = 1; + pFile->base.pMethods = &kvvfs_jrnl_io_methods; ++ if( 0==strcmp("session-journal",zName) ){ ++ pFile->zClass = "session"; ++ }else if( 0==strcmp("local-journal",zName) ){ ++ pFile->zClass = "local"; ++ } + }else{ +- return SQLITE_CANTOPEN; ++ pFile->isJournal = 0; ++ pFile->base.pMethods = &kvvfs_db_io_methods; + } +- if( zName[0]=='s' ){ +- pFile->zClass = "session"; +- }else{ +- pFile->zClass = "local"; ++ if( !pFile->zClass ){ ++ pFile->zClass = zName; + } + 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; + } + +@@ -39073,13 +40044,17 @@ static int kvvfsOpen( + ** returning. + */ + static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ ++ int rc /* The JS impl can fail with OOM in argument conversion */; + if( strcmp(zPath, "local-journal")==0 ){ +- sqlite3KvvfsMethods.xDelete("local", "jrnl"); ++ rc = sqlite3KvvfsMethods.xRcrdDelete("local", "jrnl"); + }else + if( strcmp(zPath, "session-journal")==0 ){ +- sqlite3KvvfsMethods.xDelete("session", "jrnl"); ++ rc = sqlite3KvvfsMethods.xRcrdDelete("session", "jrnl"); + } +- return SQLITE_OK; ++ else{ ++ rc = 0; ++ } ++ return rc; + } + + /* +@@ -39093,21 +40068,42 @@ static int kvvfsAccess( + int *pResOut + ){ + SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); ++#if 0 && defined(SQLITE_WASM) ++ /* ++ ** This is not having the desired effect in the JS bindings. ++ ** It's ostensibly the same logic as the #else block, but ++ ** it's not behaving that way. ++ ** ++ ** In JS we map all zPaths to Storage objects, and -journal files ++ ** are mapped to the storage for the main db (which is is exactly ++ ** what the mapping of "local-journal" -> "local" is doing). ++ */ ++ const char *zKey = (0==sqlite3_strglob("*-journal", zPath)) ++ ? "jrnl" : "sz"; ++ *pResOut = ++ sqlite3KvvfsMethods.xRcrdRead(zPath, zKey, 0, 0)>0; ++#else + if( strcmp(zPath, "local-journal")==0 ){ +- *pResOut = sqlite3KvvfsMethods.xRead("local", "jrnl", 0, 0)>0; ++ *pResOut = ++ sqlite3KvvfsMethods.xRcrdRead("local", "jrnl", 0, 0)>0; + }else + if( strcmp(zPath, "session-journal")==0 ){ +- *pResOut = sqlite3KvvfsMethods.xRead("session", "jrnl", 0, 0)>0; ++ *pResOut = ++ sqlite3KvvfsMethods.xRcrdRead("session", "jrnl", 0, 0)>0; + }else + if( strcmp(zPath, "local")==0 ){ +- *pResOut = sqlite3KvvfsMethods.xRead("local", "sz", 0, 0)>0; ++ *pResOut = ++ sqlite3KvvfsMethods.xRcrdRead("local", "sz", 0, 0)>0; + }else + if( strcmp(zPath, "session")==0 ){ +- *pResOut = sqlite3KvvfsMethods.xRead("session", "sz", 0, 0)>0; ++ *pResOut = ++ sqlite3KvvfsMethods.xRcrdRead("session", "sz", 0, 0)>0; + }else + { + *pResOut = 0; + } ++ /*all current JS tests avoid triggering: assert( *pResOut == 0 ); */ ++#endif + SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); + return SQLITE_OK; + } +@@ -44341,9 +45337,9 @@ static int unixShmMap( + nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; + + if( pShmNode->nRegionszRegion = szRegion; + +@@ -44374,7 +45370,7 @@ static int unixShmMap( + */ + else{ + static const int pgsz = 4096; +- int iPg; ++ i64 iPg; + + /* Write to the last byte of each newly allocated or extended page */ + assert( (nByte % pgsz)==0 ); +@@ -44391,7 +45387,7 @@ static int unixShmMap( + } + + /* Map the requested memory region into this processes address space. */ +- apNew = (char **)sqlite3_realloc( ++ apNew = (char **)sqlite3_realloc64( + pShmNode->apRegion, nReqRegion*sizeof(char *) + ); + if( !apNew ){ +@@ -44400,8 +45396,8 @@ static int unixShmMap( + } + pShmNode->apRegion = apNew; + while( pShmNode->nRegionhShm>=0 ){ + pMem = osMmap(0, nMap, +@@ -47836,7 +48832,7 @@ SQLITE_API int sqlite3_os_end(void){ + ** 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) ++#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_ANSI) + # define SQLITE_WIN32_HAS_ANSI + #endif + +@@ -47844,7 +48840,7 @@ SQLITE_API int sqlite3_os_end(void){ + ** 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) && \ ++#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT) && \ + !defined(SQLITE_WIN32_NO_WIDE) + # define SQLITE_WIN32_HAS_WIDE + #endif +@@ -47983,16 +48979,7 @@ SQLITE_API int sqlite3_os_end(void){ + */ + #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); +@@ -48004,7 +48991,6 @@ WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ + #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. +@@ -48295,7 +49281,7 @@ static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; + ** This function is not available on Windows CE or WinRT. + */ + +-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT ++#if SQLITE_OS_WINCE + # define osAreFileApisANSI() 1 + #endif + +@@ -48310,7 +49296,7 @@ static struct win_syscall { + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ + } aSyscall[] = { +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT ++#if !SQLITE_OS_WINCE + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, + #else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +@@ -48349,7 +49335,7 @@ static struct win_syscall { + #define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) ++#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, + #else + { "CreateFileW", (SYSCALL)0, 0 }, +@@ -48358,7 +49344,7 @@ static struct win_syscall { + #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ ++#if defined(SQLITE_WIN32_HAS_ANSI) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ + SQLITE_WIN32_CREATEFILEMAPPINGA + { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, +@@ -48369,8 +49355,8 @@ static struct win_syscall { + #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)) ++#if (SQLITE_OS_WINCE || defined(SQLITE_WIN32_HAS_WIDE)) && \ ++ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, + #else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +@@ -48379,7 +49365,7 @@ static struct win_syscall { + #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) ++#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, + #else + { "CreateMutexW", (SYSCALL)0, 0 }, +@@ -48465,7 +49451,7 @@ static struct win_syscall { + #define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) ++#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, + #else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +@@ -48482,7 +49468,7 @@ static struct win_syscall { + + #define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) ++#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, + #else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +@@ -48499,11 +49485,7 @@ static struct win_syscall { + #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) + +@@ -48516,7 +49498,7 @@ static struct win_syscall { + #define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) ++#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, + #else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +@@ -48551,16 +49533,10 @@ static struct win_syscall { + #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 +@@ -48580,7 +49556,7 @@ static struct win_syscall { + + #define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) ++#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, + #else + { "GetTempPathW", (SYSCALL)0, 0 }, +@@ -48588,11 +49564,7 @@ static struct win_syscall { + + #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) + +@@ -48605,7 +49577,7 @@ static struct win_syscall { + #define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ ++#if defined(SQLITE_WIN32_HAS_WIDE) && \ + SQLITE_WIN32_GETVERSIONEX + { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, + #else +@@ -48620,20 +49592,12 @@ static struct win_syscall { + #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) + +@@ -48651,16 +49615,12 @@ static struct win_syscall { + #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 ++#if !SQLITE_OS_WINCE + { "HeapCompact", (SYSCALL)HeapCompact, 0 }, + #else + { "HeapCompact", (SYSCALL)0, 0 }, +@@ -48676,7 +49636,7 @@ static struct win_syscall { + + #define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) + +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ ++#if defined(SQLITE_WIN32_HAS_WIDE) && \ + !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, + #else +@@ -48685,15 +49645,11 @@ static struct win_syscall { + + #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 ++#if !SQLITE_OS_WINCE + { "LockFile", (SYSCALL)LockFile, 0 }, + #else + { "LockFile", (SYSCALL)0, 0 }, +@@ -48715,8 +49671,7 @@ static struct win_syscall { + LPOVERLAPPED))aSyscall[48].pCurrent) + #endif + +-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \ +- (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) ++#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, + #else + { "MapViewOfFile", (SYSCALL)0, 0 }, +@@ -48744,20 +49699,12 @@ static struct win_syscall { + + #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) + +@@ -48766,7 +49713,7 @@ static struct win_syscall { + #define osSystemTimeToFileTime ((BOOL(WINAPI*)(const SYSTEMTIME*, \ + LPFILETIME))aSyscall[56].pCurrent) + +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT ++#if !SQLITE_OS_WINCE + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, + #else + { "UnlockFile", (SYSCALL)0, 0 }, +@@ -48804,15 +49751,6 @@ static struct win_syscall { + #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) +- + /* + ** For WaitForSingleObject(), MSDN says: + ** +@@ -48822,7 +49760,7 @@ static struct win_syscall { + { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, + + #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ +- DWORD))aSyscall[63].pCurrent) ++ DWORD))aSyscall[62].pCurrent) + + #if !SQLITE_OS_WINCE + { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, +@@ -48831,69 +49769,10 @@ static struct win_syscall { + #endif + + #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ +- BOOL))aSyscall[64].pCurrent) ++ BOOL))aSyscall[63].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) ++ /* ^^^^^^^^^^^^^^^^^^^----------------^------- placeholder only */ + + #if defined(SQLITE_WIN32_HAS_ANSI) + { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, +@@ -48901,7 +49780,7 @@ static struct win_syscall { + { "OutputDebugStringA", (SYSCALL)0, 0 }, + #endif + +-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent) ++#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[65].pCurrent) + + #if defined(SQLITE_WIN32_HAS_WIDE) + { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, +@@ -48909,20 +49788,11 @@ static struct win_syscall { + { "OutputDebugStringW", (SYSCALL)0, 0 }, + #endif + +-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent) ++#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[66].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) ++#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[67].pCurrent) + + /* + ** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" +@@ -48937,25 +49807,25 @@ static struct win_syscall { + { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, + + #define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ +- SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) ++ SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[68].pCurrent) + #endif /* defined(InterlockedCompareExchange) */ + +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID ++#if !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID + { "UuidCreate", (SYSCALL)UuidCreate, 0 }, + #else + { "UuidCreate", (SYSCALL)0, 0 }, + #endif + +-#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent) ++#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[69].pCurrent) + +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID ++#if !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID + { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, + #else + { "UuidCreateSequential", (SYSCALL)0, 0 }, + #endif + + #define osUuidCreateSequential \ +- ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent) ++ ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[70].pCurrent) + + #if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 + { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, +@@ -48964,7 +49834,7 @@ static struct win_syscall { + #endif + + #define osFlushViewOfFile \ +- ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) ++ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[71].pCurrent) + + /* + ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CreateEvent() +@@ -48981,7 +49851,7 @@ static struct win_syscall { + + #define osCreateEvent ( \ + (HANDLE(WINAPI*) (LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)) \ +- aSyscall[80].pCurrent \ ++ aSyscall[72].pCurrent \ + ) + + /* +@@ -48998,7 +49868,7 @@ static struct win_syscall { + { "CancelIo", (SYSCALL)0, 0 }, + #endif + +-#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[81].pCurrent) ++#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[73].pCurrent) + + #if defined(SQLITE_WIN32_HAS_WIDE) && defined(_WIN32) + { "GetModuleHandleW", (SYSCALL)GetModuleHandleW, 0 }, +@@ -49006,7 +49876,7 @@ static struct win_syscall { + { "GetModuleHandleW", (SYSCALL)0, 0 }, + #endif + +-#define osGetModuleHandleW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[82].pCurrent) ++#define osGetModuleHandleW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[74].pCurrent) + + #ifndef _WIN32 + { "getenv", (SYSCALL)getenv, 0 }, +@@ -49014,7 +49884,7 @@ static struct win_syscall { + { "getenv", (SYSCALL)0, 0 }, + #endif + +-#define osGetenv ((const char *(*)(const char *))aSyscall[83].pCurrent) ++#define osGetenv ((const char *(*)(const char *))aSyscall[75].pCurrent) + + #ifndef _WIN32 + { "getcwd", (SYSCALL)getcwd, 0 }, +@@ -49022,7 +49892,7 @@ static struct win_syscall { + { "getcwd", (SYSCALL)0, 0 }, + #endif + +-#define osGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent) ++#define osGetcwd ((char*(*)(char*,size_t))aSyscall[76].pCurrent) + + #ifndef _WIN32 + { "readlink", (SYSCALL)readlink, 0 }, +@@ -49030,7 +49900,7 @@ static struct win_syscall { + { "readlink", (SYSCALL)0, 0 }, + #endif + +-#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[85].pCurrent) ++#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[77].pCurrent) + + #ifndef _WIN32 + { "lstat", (SYSCALL)lstat, 0 }, +@@ -49038,7 +49908,7 @@ static struct win_syscall { + { "lstat", (SYSCALL)0, 0 }, + #endif + +-#define osLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent) ++#define osLstat ((int(*)(const char*,struct stat*))aSyscall[78].pCurrent) + + #ifndef _WIN32 + { "__errno", (SYSCALL)__errno, 0 }, +@@ -49046,7 +49916,7 @@ static struct win_syscall { + { "__errno", (SYSCALL)0, 0 }, + #endif + +-#define osErrno (*((int*(*)(void))aSyscall[87].pCurrent)()) ++#define osErrno (*((int*(*)(void))aSyscall[79].pCurrent)()) + + #ifndef _WIN32 + { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, +@@ -49055,7 +49925,7 @@ static struct win_syscall { + #endif + + #define osCygwin_conv_path ((size_t(*)(unsigned int, \ +- const void *, void *, size_t))aSyscall[88].pCurrent) ++ const void *, void *, size_t))aSyscall[80].pCurrent) + + }; /* End of the overrideable system calls */ + +@@ -49159,10 +50029,10 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){ + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + #endif +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT ++#if !SQLITE_OS_WINCE + if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){ + DWORD lastErrno = osGetLastError(); + if( lastErrno==NO_ERROR ){ +@@ -49275,28 +50145,11 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ + } + #endif /* _WIN32 */ + +-/* +-** 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 && \ ++#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && \ + SQLITE_THREADSAFE>0 + SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ + DWORD rc; +@@ -49320,7 +50173,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ + + #if !SQLITE_WIN32_GETVERSIONEX + # define osIsNT() (1) +-#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) ++#elif SQLITE_OS_WINCE || !defined(SQLITE_WIN32_HAS_ANSI) + # define osIsNT() (1) + #elif !defined(SQLITE_WIN32_HAS_WIDE) + # define osIsNT() (0) +@@ -49333,13 +50186,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ + ** 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 SQLITE_WIN32_GETVERSIONEX + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ + #if defined(SQLITE_WIN32_HAS_ANSI) + OSVERSIONINFOA sInfo; +@@ -49381,7 +50228,7 @@ static void *winMemMalloc(int nBytes){ + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + #endif + assert( nBytes>=0 ); +@@ -49403,7 +50250,7 @@ static void winMemFree(void *pPrior){ + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); + #endif + if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ +@@ -49424,7 +50271,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){ + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); + #endif + assert( nBytes>=0 ); +@@ -49452,7 +50299,7 @@ static int winMemSize(void *p){ + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) ); + #endif + if( !p ) return 0; +@@ -49482,7 +50329,7 @@ static int winMemInit(void *pAppData){ + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + +-#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE ++#if SQLITE_WIN32_HEAP_CREATE + if( !pWinMemData->hHeap ){ + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; +@@ -49515,7 +50362,7 @@ static int winMemInit(void *pAppData){ + #endif + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + #endif + return SQLITE_OK; +@@ -49533,7 +50380,7 @@ static void winMemShutdown(void *pAppData){ + + if( pWinMemData->hHeap ){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) ++#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + #endif + if( pWinMemData->bOwned ){ +@@ -49914,17 +50761,6 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ + 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 | +@@ -49935,16 +50771,13 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ + (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 +@@ -50605,7 +51438,6 @@ static int winHandleUnlock(HANDLE h, int iOff, int nByte){ + static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ + int rc = SQLITE_OK; /* Return value */ + +-#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() */ +@@ -50627,20 +51459,7 @@ static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ + rc = SQLITE_IOERR_SEEK; + } + } +-#else +- /* This implementation works for WinRT. */ +- LARGE_INTEGER x; /* The new offset */ +- BOOL bRet; /* Value returned by SetFilePointerEx() */ +- +- x.QuadPart = iOffset; +- bRet = osSetFilePointerEx(h, x, 0, FILE_BEGIN); +- +- if(!bRet){ +- rc = SQLITE_IOERR_SEEK; +- } +-#endif +- +- OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset, sqlite3ErrName(rc))); ++ OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset,sqlite3ErrName(rc))); + return rc; + } + +@@ -50941,17 +51760,6 @@ static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){ + */ + static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ + int rc = SQLITE_OK; +- +-#if SQLITE_OS_WINRT +- FILE_STANDARD_INFO info; +- BOOL b; +- b = osGetFileInformationByHandleEx(h, FileStandardInfo, &info, sizeof(info)); +- if( b ){ +- *pnByte = info.EndOfFile.QuadPart; +- }else{ +- rc = SQLITE_IOERR_FSTAT; +- } +-#else + DWORD upperBits = 0; + DWORD lowerBits = 0; + +@@ -50961,8 +51769,6 @@ static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ + if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ + rc = SQLITE_IOERR_FSTAT; + } +-#endif +- + return rc; + } + +@@ -51161,20 +51967,6 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ + 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; +@@ -51189,7 +51981,6 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ + "winFileSize", pFile->zPath); + } + } +-#endif + OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", + pFile->h, pSize, *pSize, sqlite3ErrName(rc))); + return rc; +@@ -52151,20 +52942,6 @@ static int winHandleOpen( + ** TODO: retry-on-ioerr. + */ + if( osIsNT() ){ +-#if SQLITE_OS_WINRT +- CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; +- memset(&extendedParameters, 0, sizeof(extendedParameters)); +- extendedParameters.dwSize = sizeof(extendedParameters); +- extendedParameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; +- extendedParameters.dwFileFlags = flag_overlapped; +- extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; +- h = osCreateFile2((LPCWSTR)zConverted, +- (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)),/* dwDesiredAccess */ +- FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ +- OPEN_ALWAYS, /* dwCreationDisposition */ +- &extendedParameters +- ); +-#else + h = osCreateFileW((LPCWSTR)zConverted, /* lpFileName */ + (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ +@@ -52173,7 +52950,6 @@ static int winHandleOpen( + FILE_ATTRIBUTE_NORMAL|flag_overlapped, + NULL + ); +-#endif + }else{ + /* Due to pre-processor directives earlier in this file, + ** SQLITE_WIN32_HAS_ANSI is always defined if osIsNT() is false. */ +@@ -52251,11 +53027,29 @@ SQLITE_API int sqlite3_win_test_unc_locking = 0; + + /* + ** Return true if the string passed as the only argument is likely +-** to be a UNC path. In other words, if it starts with "\\". ++** to be a UNC path. Return false if note. ++** ++** Return true if: ++** ++** (1) The name begins with "\\" ++** (2) But does not begin with "\\?\C:\" where C can be any alphabetic ++** character. ++** ++** For testing, also return true in all cases if the global variable ++** sqlite3_win_test_unc_locking is true. + */ + static int winIsUNCPath(const char *zFile){ + if( zFile[0]=='\\' && zFile[1]=='\\' ){ +- return 1; ++ if( zFile[2]=='?' ++ && zFile[3]=='\\' ++ && sqlite3Isalpha(zFile[4]) ++ && zFile[5]==':' ++ && winIsDirSep(zFile[6]) ++ ){ ++ return sqlite3_win_test_unc_locking; ++ }else{ ++ return 1; ++ } + } + return sqlite3_win_test_unc_locking; + } +@@ -52593,7 +53387,7 @@ static int winShmMap( + if( pShmNode->nRegion<=iRegion ){ + HANDLE hShared = pShmNode->hSharedShm; + struct ShmRegion *apNew; /* New aRegion[] array */ +- int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ ++ i64 nByte = ((i64)iRegion+1)*(i64)szRegion; /* Minimum file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; +@@ -52624,7 +53418,7 @@ static int winShmMap( + + /* Map the requested memory region into this processes address space. */ + apNew = (struct ShmRegion*)sqlite3_realloc64( +- pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) ++ pShmNode->aRegion, ((i64)iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM_BKPT; +@@ -52641,29 +53435,20 @@ static int winShmMap( + HANDLE hMap = NULL; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + +-#if SQLITE_OS_WINRT +- hMap = osCreateFileMappingFromApp(hShared, NULL, protect, nByte, NULL); +-#elif defined(SQLITE_WIN32_HAS_WIDE) ++#if defined(SQLITE_WIN32_HAS_WIDE) + hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); + #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA + hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL); + #endif +- +- OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", ++ OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%lld, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, nByte, + hMap ? "ok" : "failed")); + if( hMap ){ +- int iOffset = pShmNode->nRegion*szRegion; ++ i64 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 ++ 0, iOffset - iOffsetShift, (i64)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")); +@@ -52684,7 +53469,7 @@ static int winShmMap( + + shmpage_out: + if( pShmNode->nRegion>iRegion ){ +- int iOffset = iRegion*szRegion; ++ i64 iOffset = (i64)iRegion*(i64)szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iOffsetShift]; +@@ -52796,9 +53581,7 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ + flags |= FILE_MAP_WRITE; + } + #endif +-#if SQLITE_OS_WINRT +- pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); +-#elif defined(SQLITE_WIN32_HAS_WIDE) ++#if defined(SQLITE_WIN32_HAS_WIDE) + pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +@@ -52818,11 +53601,7 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ + } + 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; +@@ -53157,7 +53936,6 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ + } + #endif + +-#if !SQLITE_OS_WINRT && defined(_WIN32) + else if( osIsNT() ){ + char *zMulti; + LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) ); +@@ -53211,7 +53989,6 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ + } + } + #endif /* SQLITE_WIN32_HAS_ANSI */ +-#endif /* !SQLITE_OS_WINRT */ + + /* + ** Check to make sure the temporary directory ends with an appropriate +@@ -53386,13 +54163,6 @@ static int winOpen( + 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 + */ +@@ -53475,31 +54245,6 @@ static int winOpen( + #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; +- sqlite3BeginBenignMalloc(); +- rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); +- sqlite3EndBenignMalloc(); +- if( rc2==SQLITE_OK && isRO ) break; +- } +- }while( winRetryIoerr(&cnt, &lastErrno) ); +-#else + do{ + h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, +@@ -53516,7 +54261,6 @@ static int winOpen( + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); +-#endif + } + #ifdef SQLITE_WIN32_HAS_ANSI + else{ +@@ -53653,25 +54397,7 @@ static int winDelete( + } + 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 +@@ -53794,6 +54520,7 @@ static int winAccess( + attr = sAttrData.dwFileAttributes; + } + }else{ ++ if( noRetry ) lastErrno = osGetLastError(); + winLogIoerr(cnt, __LINE__); + if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ + sqlite3_free(zConverted); +@@ -53962,7 +54689,7 @@ static int winFullPathnameNoMutex( + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ + ){ +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT ++#if !SQLITE_OS_WINCE + int nByte; + void *zConverted; + char *zOut; +@@ -54051,7 +54778,7 @@ static int winFullPathnameNoMutex( + } + #endif /* __CYGWIN__ */ + +-#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) ++#if SQLITE_OS_WINCE && defined(_WIN32) + 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. */ +@@ -54070,7 +54797,7 @@ static int winFullPathnameNoMutex( + return SQLITE_OK; + #endif + +-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT ++#if !SQLITE_OS_WINCE + #if defined(_WIN32) + /* 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 +@@ -54202,11 +54929,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ + 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{ +@@ -54288,23 +55011,16 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + 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 ++#if !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID + { + UUID id; + memset(&id, 0, sizeof(UUID)); +@@ -54314,7 +55030,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + osUuidCreateSequential(&id); + xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + } +-#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ ++#endif /* !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID */ + return e.nXor>nBuf ? nBuf : e.nXor; + #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ + } +@@ -54545,15 +55261,16 @@ SQLITE_API int sqlite3_os_init(void){ + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ +- assert( ArraySize(aSyscall)==89 ); ++ assert( ArraySize(aSyscall)==81 ); ++ assert( strcmp(aSyscall[0].zName,"AreFileApisANSI")==0 ); ++ assert( strcmp(aSyscall[20].zName,"GetFileAttributesA")==0 ); ++ assert( strcmp(aSyscall[40].zName,"HeapReAlloc")==0 ); ++ assert( strcmp(aSyscall[60].zName,"WideCharToMultiByte")==0 ); ++ assert( strcmp(aSyscall[80].zName,"cygwin_conv_path")==0 ); + + /* 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 ); + +@@ -54577,17 +55294,9 @@ SQLITE_API int sqlite3_os_init(void){ + } + + 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; + } + +@@ -55356,7 +56065,7 @@ SQLITE_API unsigned char *sqlite3_serialize( + sqlite3_int64 sz; + int szPage = 0; + sqlite3_stmt *pStmt = 0; +- unsigned char *pOut; ++ unsigned char *pOut = 0; + char *zSql; + int rc; + +@@ -55366,12 +56075,13 @@ SQLITE_API unsigned char *sqlite3_serialize( + return 0; + } + #endif ++ sqlite3_mutex_enter(db->mutex); + + 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( iDb<0 ) goto serialize_out; + if( p ){ + MemStore *pStore = p->pStore; + assert( pStore->pMutex==0 ); +@@ -55382,19 +56092,17 @@ SQLITE_API unsigned char *sqlite3_serialize( + pOut = sqlite3_malloc64( pStore->sz ); + if( pOut ) memcpy(pOut, pStore->aData, pStore->sz); + } +- return pOut; ++ goto serialize_out; + } + pBt = db->aDb[iDb].pBt; +- if( pBt==0 ) return 0; ++ if( pBt==0 ) goto serialize_out; + 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; ++ if( rc ) goto serialize_out; + rc = sqlite3_step(pStmt); +- if( rc!=SQLITE_ROW ){ +- pOut = 0; +- }else{ ++ if( rc==SQLITE_ROW ){ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + if( sz==0 ){ + sqlite3_reset(pStmt); +@@ -55428,6 +56136,9 @@ SQLITE_API unsigned char *sqlite3_serialize( + } + } + sqlite3_finalize(pStmt); ++ ++ serialize_out: ++ sqlite3_mutex_leave(db->mutex); + return pOut; + } + +@@ -55473,10 +56184,10 @@ SQLITE_API int sqlite3_deserialize( + if( rc ) goto end_deserialize; + db->init.iDb = (u8)iDb; + db->init.reopenMemdb = 1; +- rc = sqlite3_step(pStmt); ++ sqlite3_step(pStmt); + db->init.reopenMemdb = 0; +- if( rc!=SQLITE_DONE ){ +- rc = SQLITE_ERROR; ++ rc = sqlite3_finalize(pStmt); ++ if( rc!=SQLITE_OK ){ + goto end_deserialize; + } + p = memdbFromDbSchema(db, zSchema); +@@ -55497,7 +56208,6 @@ SQLITE_API int sqlite3_deserialize( + } + + end_deserialize: +- sqlite3_finalize(pStmt); + if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ + sqlite3_free(pData); + } +@@ -57282,22 +57992,24 @@ static int pcache1InitBulk(PCache1 *pCache){ + 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 = (u8*)pX + ROUND8(sizeof(*pX)); +- assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); +- 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 ); ++ if( szBulk>=pCache->szAlloc ){ ++ 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 = (u8*)pX + ROUND8(sizeof(*pX)); ++ assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); ++ 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; + } +@@ -59736,6 +60448,8 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ + (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + if( iRead ) return 0; /* Case (4) */ + } ++#else ++ UNUSED_PARAMETER(pgno); + #endif + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) +@@ -60156,17 +60870,17 @@ static int jrnlBufferSize(Pager *pPager){ + */ + #ifdef SQLITE_CHECK_PAGES + /* +-** Return a 32-bit hash of the page data for pPage. ++** Return a 64-bit hash of the page data for pPage. + */ +-static u32 pager_datahash(int nByte, unsigned char *pData){ +- u32 hash = 0; ++static u64 pager_datahash(int nByte, unsigned char *pData){ ++ u64 hash = 0; + int i; + for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); + } + static void pager_set_pagehash(PgHdr *pPage){ +@@ -60193,39 +60907,43 @@ static void checkPage(PgHdr *pPg){ + #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. ++** Free a buffer allocated by the readSuperJournal() function. ++*/ ++static void freeSuperJournal(char *zSuper){ ++ if( zSuper ){ ++ sqlite3_free(&zSuper[-4]); ++ } ++} ++ ++/* ++** Parameter pJrnl is a file-handle open on a journal file. This function ++** attempts to read a super-journal file name from the end of the journal ++** file. If successful, it sets output parameter (*pzSuper) to point to a ++** buffer containing the super-journal name as a nul-terminated string. ++** The caller is responsible for freeing the buffer using freeSuperJournal(). + ** +-** 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. ++** Refer to comments above writeSuperJournal() for the format used to store ++** a super-journal file name at the end of a journal file. + ** +-** If it is determined that no super-journal file name is present +-** zSuper[0] is set to 0 and SQLITE_OK returned. ++** Parameter nSuper is passed the maximum allowable size of the super journal ++** name in bytes. 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 an error occurs while reading from the journal file, an SQLite +-** error code is returned. ++** If there is no super-journal name at the end of pJrnl, (*pzSuper) is ++** set to 0 and SQLITE_OK is returned. Or, if an error occurs while reading ++** the super-journal name, an SQLite error code is returned and (*pzSuper) ++** is set to 0. + */ +-static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){ ++static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){ + 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'; ++ char *zOut = 0; + ++ *pzSuper = 0; + if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) + || szJ<16 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) +@@ -60235,27 +60953,34 @@ static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){ + || 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; uzJournal */ ++ ++ /* Check if this looks like a real super-journal name. If it does not, ++ ** return SQLITE_OK without attempting to delete it. This is to limit ++ ** the degree to which a crafted journal file can be used to cause ++ ** SQLite to delete arbitrary files. */ ++ if( pagerIsSuperJrnlName(zSuper)==0 ){ ++ return SQLITE_OK; ++ } + + /* Allocate space for both the pJournal and pSuper file descriptors. + ** If successful, open the super-journal file for reading. +@@ -61485,9 +62251,8 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ + */ + rc = sqlite3OsFileSize(pSuper, &nSuperJournal); + if( rc!=SQLITE_OK ) goto delsuper_out; +- nSuperPtr = 1 + (i64)pVfs->mxPathname; +- assert( nSuperJournal>=0 && nSuperPtr>0 ); +- zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); ++ assert( nSuperJournal>=0 ); ++ zFree = sqlite3Malloc(4 + nSuperJournal + 2); + if( !zFree ){ + rc = SQLITE_NOMEM_BKPT; + goto delsuper_out; +@@ -61496,7 +62261,6 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ + } + 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; +@@ -61504,43 +62268,56 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ + + zJournal = zSuperJournal; + while( (zJournal-zSuperJournal)zJournal)==0 ){ ++ bSeen = 1; ++ }else{ ++ int exists; ++ rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); + if( rc!=SQLITE_OK ){ + goto delsuper_out; + } ++ if( exists ){ ++ char *zSuperPtr = 0; + +- rc = readSuperJournal(pJournal, zSuperPtr, nSuperPtr); +- sqlite3OsClose(pJournal); +- if( rc!=SQLITE_OK ){ +- goto delsuper_out; +- } ++ /* One of the journals pointed to by the super-journal exists. ++ ** Open it and check if it points at the super-journal. If ++ ** so, return without deleting the super-journal file. ++ ** NB: zJournal is really a MAIN_JOURNAL. But call it a ++ ** SUPER_JOURNAL here so that the VFS will not send the zJournal ++ ** name into sqlite3_database_file_object(). ++ */ ++ int c; ++ int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); ++ rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); ++ if( rc!=SQLITE_OK ){ ++ goto delsuper_out; ++ } + +- c = zSuperPtr[0]!=0 && strcmp(zSuperPtr, zSuper)==0; +- if( c ){ +- /* We have a match. Do not delete the super-journal file. */ +- goto delsuper_out; ++ rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr); ++ sqlite3OsClose(pJournal); ++ if( rc!=SQLITE_OK ){ ++ assert( zSuperPtr==0 ); ++ goto delsuper_out; ++ } ++ ++ c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0; ++ freeSuperJournal(zSuperPtr); ++ if( c ){ ++ /* We have a match. Do not delete the super-journal file. */ ++ goto delsuper_out; ++ } + } + } + zJournal += (sqlite3Strlen30(zJournal)+1); + } + + sqlite3OsClose(pSuper); +- rc = sqlite3OsDelete(pVfs, zSuper, 0); ++ if( bSeen ){ ++ /* Only delete the super-journal if bSeen is true - indicating that ++ ** the super-journal contained a pointer to this database's journal ++ ** file. */ ++ rc = sqlite3OsDelete(pVfs, zSuper, 0); ++ } + + delsuper_out: + sqlite3_free(zFree); +@@ -61745,19 +62522,11 @@ static int pager_playback(Pager *pPager, int isHot){ + ** 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, 1+(i64)pPager->pVfs->mxPathname); +- if( rc==SQLITE_OK && zSuper[0] ){ ++ rc = readSuperJournal(pPager->jfd, 1+(i64)pPager->pVfs->mxPathname, &zSuper); ++ if( rc==SQLITE_OK && zSuper ){ + rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); + } +- zSuper = 0; + if( rc!=SQLITE_OK || !res ){ + goto end_playback; + } +@@ -61886,30 +62655,20 @@ end_playback: + */ + 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, 1+(i64)pPager->pVfs->mxPathname); +- 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); ++ rc = pager_end_transaction(pPager, zSuper!=0, 0); + testcase( rc!=SQLITE_OK ); + } +- if( rc==SQLITE_OK && zSuper[0] && res ){ ++ if( rc==SQLITE_OK && zSuper && 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); ++ assert( memcmp(&zSuper[-4], "\0\0\0\0", 4)==0 ); + rc = pager_delsuper(pPager, zSuper); + testcase( rc!=SQLITE_OK ); + } +@@ -61922,6 +62681,7 @@ end_playback: + ** back a journal created by a process with a different sector size + ** value. Reset it to the correct value for this process. + */ ++ freeSuperJournal(zSuper); + setSectorSize(pPager); + return rc; + } +@@ -63115,6 +63875,8 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ + sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + pPager->pWal = 0; + } ++#else ++ UNUSED_PARAMETER(db); + #endif + pager_reset(pPager); + if( MEMDB ){ +@@ -67779,6 +68541,12 @@ static int walDecodeFrame( + return 0; + } + ++ /* Need a valid page size ++ */ ++ if( !pWal->szPage ){ ++ 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 +@@ -67882,7 +68650,7 @@ static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ + + /* + ** Compute a hash on a page number. The resulting hash value must land +-** between 0 and (HASHTABLE_NSLOT-1). The walHashNext() function advances ++** between 0 and (HASHTABLE_NSLOT-1). The walNextHash() function advances + ** the hash to the next value in the event of a collision. + */ + static int walHash(u32 iPage){ +@@ -68090,7 +68858,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ + for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ + if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; + } +- sLoc.aPgno[idx-1] = iPage; ++ sLoc.aPgno[(idx-1)&(HASHTABLE_NPAGE-1)] = iPage; + AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx); + + #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT +@@ -69633,7 +70401,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ + + /* Allocate a buffer to read frames into */ + assert( (pWal->szPage & (pWal->szPage-1))==0 ); +- assert( pWal->szPage>=512 && pWal->szPage<=65536 ); ++ assert( (pWal->szPage>=512 && pWal->szPage<=65536) || pWal->szPage==0 ); + szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame); + if( aFrame==0 ){ +@@ -70338,7 +71106,10 @@ static int walFindFrame( + 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 ){ ++ if( iFrame<=iLast ++ && iFrame>=pWal->minFrame ++ && sLoc.aPgno[(iH-1)&(HASHTABLE_NPAGE-1)]==pgno ++ ){ + assert( iFrame>iRead || CORRUPT_DB ); + iRead = iFrame; + } +@@ -72128,6 +72899,9 @@ struct IntegrityCk { + u32 *heap; /* Min-heap used for analyzing cell coverage */ + sqlite3 *db; /* Database connection running the check */ + i64 nRow; /* Number of rows visited in current tree */ ++#ifdef SQLITE_DEBUG ++ u32 mxHeap; /* Maximum number of entries in the Min-heap */ ++#endif + }; + + /* +@@ -73713,7 +74487,7 @@ static void btreeParseCellPtr( + CellInfo *pInfo /* Fill in this structure */ + ){ + u8 *pIter; /* For scanning through pCell */ +- u32 nPayload; /* Number of bytes of cell payload */ ++ u64 nPayload; /* Number of bytes of cell payload */ + u64 iKey; /* Extracted Key value */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); +@@ -73735,6 +74509,7 @@ static void btreeParseCellPtr( + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( (*pIter)>=0x80 && pIternKey = *(i64*)&iKey; +- pInfo->nPayload = nPayload; ++ pInfo->nPayload = (u32)nPayload; + pInfo->pPayload = pIter; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); +- assert( nPayload>=0 ); + assert( pPage->maxLocal <= BT_MAX_LOCAL ); + if( nPayload<=pPage->maxLocal ){ + /* This is the (easy) common case where the entire payload fits +@@ -74589,8 +75363,12 @@ static int btreeComputeFreeSpace(MemPage *pPage){ + } + next = get2byte(&data[pc]); + size = get2byte(&data[pc+2]); ++ if( size<4 ){ ++ /* Minimum freeblock size is 4 */ ++ return SQLITE_CORRUPT_PAGE(pPage); ++ } + nFree = nFree + size; +- if( next<=pc+size+3 ) break; ++ if( next0 ){ +@@ -76124,6 +76902,30 @@ static SQLITE_NOINLINE int btreeBeginTrans( + } + #endif + ++#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114 ++ /* If both a read and write transaction will be opened by this call, ++ ** then issue a file-control as if the following pragma command had ++ ** been evaluated: ++ ** ++ ** PRAGMA experimental_pragma_20251114 = 1|2 ++ ** ++ ** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag ++ ** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS. ++ ** ++ ** WARNING: This code will likely remain part of SQLite only temporarily - ++ ** it exists to allow users to experiment with certain types of blocking ++ ** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */ ++ if( pBt->pPage1==0 && wrflag ){ ++ sqlite3_file *fd = sqlite3PagerFile(pPager); ++ char *aFcntl[3] = {0,0,0}; ++ aFcntl[1] = "experimental_pragma_20251114"; ++ assert( wrflag==1 || wrflag==2 ); ++ aFcntl[2] = (wrflag==1 ? "1" : "2"); ++ sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); ++ sqlite3_free(aFcntl[0]); ++ } ++#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 +@@ -77612,7 +78414,9 @@ static int accessPayload( + ** 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; ++ i64 nOvfl = pCur->info.nPayload; ++ testcase( nOvfl - pCur->info.nLocal + ovflSize - 1 > 0xffffffffU ); ++ nOvfl = (nOvfl - pCur->info.nLocal + ovflSize-1)/ovflSize; + if( pCur->aOverflow==0 + || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) + ){ +@@ -77717,6 +78521,12 @@ static int accessPayload( + (eOp==0 ? PAGER_GET_READONLY : 0) + ); + if( rc==SQLITE_OK ){ ++ if( eOp!=0 ++ && (sqlite3PagerPageRefcount(pDbPage)!=1 ++ || NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit)) ){ ++ sqlite3PagerUnref(pDbPage); ++ return SQLITE_CORRUPT_PAGE(pPage); ++ } + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); +@@ -78128,7 +78938,7 @@ SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes){ + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); +- if( pCur->eState==CURSOR_VALID ){ ++ if( NEVER(pCur->eState==CURSOR_VALID) ){ + *pRes = 0; + return SQLITE_OK; + } +@@ -78391,14 +79201,14 @@ static int indexCellCompare( + /* 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 ); ++ if( pCell + nCell >= pPage->aDataEnd ) return 99; + 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 ); ++ if( pCell + nCell >= pPage->aDataEnd ) return 99; + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* If the record extends into overflow pages, do not attempt +@@ -78560,14 +79370,17 @@ bypass_moveto_root: + /* 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 ); ++ if( pCell + nCell >= pPage->aDataEnd ){ ++ rc = SQLITE_CORRUPT_PAGE(pPage); ++ goto moveto_index_finish; ++ } + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ++ && pCell + nCell < pPage->aDataEnd + ){ + /* 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 +@@ -82209,7 +83022,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ +- Pgno pgnoNew; ++ Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */ + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); +@@ -83432,6 +84245,7 @@ static int checkTreePage( + } + }else{ + /* Populate the coverage-checking heap for leaf pages */ ++ assert( heap[0] < pCheck->mxHeap ); + btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); + } + } +@@ -83451,6 +84265,7 @@ static int checkTreePage( + u32 size; + pc = get2byteAligned(&data[cellStart+i*2]); + size = pPage->xCellSize(pPage, &data[pc]); ++ assert( heap[0] < pCheck->mxHeap ); + btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); + } + } +@@ -83467,6 +84282,7 @@ static int checkTreePage( + assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ + size = get2byte(&data[i+2]); + assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */ ++ assert( heap[0] < pCheck->mxHeap ); + 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 +@@ -83601,6 +84417,9 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( + goto integrity_ck_cleanup; + } + sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); ++#ifdef SQLITE_DEBUG ++ sCheck.mxHeap = pBt->pageSize/4 - 1; ++#endif + if( sCheck.heap==0 ){ + checkOom(&sCheck); + goto integrity_ck_cleanup; +@@ -84018,6 +84837,7 @@ SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ + */ + struct sqlite3_backup { + sqlite3* pDestDb; /* Destination database handle */ ++ char *zDestDb; + Btree *pDest; /* Destination b-tree file */ + u32 iDestSchema; /* Original schema cookie in destination */ + int bDestLocked; /* True once a write-transaction is open on pDest */ +@@ -84107,10 +84927,8 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ + ** 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; ++static int setDestPgsz(Btree *pDest, Btree *pSrc){ ++ return sqlite3BtreeSetPageSize(pDest, sqlite3BtreeGetPageSize(pSrc), 0, 0); + } + + /* +@@ -84167,27 +84985,37 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( + ); + p = 0; + }else { ++ int nDest = sqlite3Strlen30(zDestDb); ++ + /* 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)); ++ p = (sqlite3_backup*)sqlite3MallocZero(sizeof(sqlite3_backup)+nDest+1); + if( !p ){ + sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); ++ }else{ ++ p->zDestDb = (char*)&p[1]; ++ memcpy(p->zDestDb, zDestDb, nDest); + } + } + + /* If the allocation succeeded, populate the new object. */ + if( p ){ ++ /* Do not store the pointer to the destination b-tree at this point. ++ ** This is because there is nothing preventing it from being detached ++ ** or otherwise freed before the first call to sqlite3_backup_step() ++ ** on this object. The source b-tree does not have this problem, as ++ ** incrementing Btree.nBackup (see below) effectively locks the object. */ ++ Btree *pDest = findBtree(pDestDb, pDestDb, zDestDb); + 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 ++ if( 0==p->pSrc || 0==pDest ++ || checkReadTransaction(pDestDb, 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 +@@ -84311,7 +85139,7 @@ static void attachBackupObject(sqlite3_backup *p){ + */ + SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + int rc; +- int destMode; /* Destination journal mode */ ++ int destMode = 0; /* Destination journal mode */ + int pgszSrc = 0; /* Source page size */ + int pgszDest = 0; /* Destination page size */ + +@@ -84327,7 +85155,8 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + rc = p->rc; + if( !isFatalError(rc) ){ + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ +- Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ ++ Btree * pDest = 0; /* Dest btree */ ++ Pager * pDestPager = 0; /* Dest pager */ + int ii; /* Iterator variable */ + int nSrcPage = -1; /* Size of source db in pages */ + int bCloseTrans = 0; /* True if src db requires unlocking */ +@@ -84341,6 +85170,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + 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. +@@ -84350,34 +85180,48 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + bCloseTrans = 1; + } + ++ /* Locate the destination btree and pager. */ ++ if( (pDest = p->pDest)==0 ){ ++ pDest = findBtree(p->pDestDb, p->pDestDb, p->zDestDb); ++ } ++ if( pDest==0 ){ ++ rc = SQLITE_ERROR; ++ }else{ ++ pDestPager = sqlite3BtreePager(pDest); ++ } ++ + /* 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 ){ ++ if( p->bDestLocked==0 && rc==SQLITE_OK ++ && setDestPgsz(pDest, p->pSrc)==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, ++ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(pDest, 2, + (int*)&p->iDestSchema)) + ){ + p->bDestLocked = 1; ++ p->pDest = pDest; + } + + /* 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; ++ if( rc==SQLITE_OK ){ ++ pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); ++ pgszDest = sqlite3BtreeGetPageSize(p->pDest); ++ destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); ++ if( (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) ++ && pgszSrc!=pgszDest ++ ){ ++ rc = SQLITE_READONLY; ++ } + } + + /* Now that there is a read-lock on the source database, query the +@@ -84595,7 +85439,9 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ + } + + /* If a transaction is still open on the Btree, roll it back. */ +- sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); ++ if( p->pDest ){ ++ sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); ++ } + + /* Set the error code of the destination database handle. */ + rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; +@@ -84875,21 +85721,27 @@ 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 */ ++ if( p->flags & (MEM_Int|MEM_IntReal) ){ ++#if GCC_VERSION>=7000000 && GCC_VERSION<15000000 && defined(__i386__) ++ /* Work-around for GCC bug or bugs: ++ ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 ++ ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659 ++ ** The problem appears to be fixed in GCC 15 */ + i64 x; +- assert( (p->flags&MEM_Int)*2==sizeof(x) ); +- memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); ++ assert( (MEM_Str&~p->flags)*4==sizeof(x) ); ++ memcpy(&x, (char*)&p->u, (MEM_Str&~p->flags)*4); + p->n = sqlite3Int64ToText(x, zBuf); + #else + p->n = sqlite3Int64ToText(p->u.i, zBuf); + #endif ++ if( p->flags & MEM_IntReal ){ ++ memcpy(zBuf+p->n,".0", 3); ++ p->n += 2; ++ } + }else{ + sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); +- sqlite3_str_appendf(&acc, "%!.15g", +- (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); ++ sqlite3_str_appendf(&acc, "%!.*g", ++ (p->db ? p->db->nFpDigit : 17), p->u.r); + assert( acc.zText==zBuf && acc.mxAlloc<=0 ); + zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ + p->n = acc.nChar; +@@ -84938,6 +85790,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ + 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; ++ if( p->db==0 ){ ++ return 1; /* db->nFpDigit required to validate p->z[] */ ++ } + memcpy(&tmp, p, sizeof(tmp)); + vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); + z = p->z; +@@ -85088,13 +85943,16 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ + ** + ** This is an optimization. Correct operation continues even if + ** this routine is a no-op. ++** ++** Return true if the strig is zero-terminated after this routine is ++** called and false if it is not. + */ +-SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ ++SQLITE_PRIVATE int 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; ++ return 0; + } +- if( pMem->enc!=SQLITE_UTF8 ) return; ++ if( pMem->enc!=SQLITE_UTF8 ) return 0; + assert( pMem->z!=0 ); + if( pMem->flags & MEM_Dyn ){ + if( pMem->xDel==sqlite3_free +@@ -85102,18 +85960,19 @@ SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ + ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; +- return; ++ return 1; + } + if( pMem->xDel==sqlite3RCStrUnref ){ + /* Blindly assume that all RCStr objects are zero-terminated */ + pMem->flags |= MEM_Term; +- return; ++ return 1; + } + }else if( pMem->szMalloc >= pMem->n+1 ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; +- return; ++ return 1; + } ++ return 0; + } + + /* +@@ -85411,18 +86270,117 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ + } + } + ++/* ++** This routine implements the uncommon and slower path for ++** sqlite3MemRealValueRC() that has to deal with input strings ++** that are not UTF8 or that are not zero-terminated. It is ++** broken out into a separate no-inline routine so that the ++** main sqlite3MemRealValueRC() routine can avoid unnecessary ++** stack pushes. ++** ++** A text->float translation of pMem->z is written into *pValue. ++** ++** Result code invariants: ++** ++** rc==0 => ERROR: Input string not well-formed, or OOM ++** rc<0 => Some prefix of the input is well-formed ++** rc>0 => All of the input is well-formed ++** (rc&2)==0 => The number is expressed as an integer, with no ++** decimal point or eNNN suffix. ++*/ ++static SQLITE_NOINLINE int sqlite3MemRealValueRCSlowPath( ++ Mem *pMem, ++ double *pValue ++){ ++ int rc = SQLITE_OK; ++ *pValue = 0.0; ++ if( pMem->enc==SQLITE_UTF8 ){ ++ char *zCopy = sqlite3DbStrNDup(pMem->db, pMem->z, pMem->n); ++ if( zCopy ){ ++ rc = sqlite3AtoF(zCopy, pValue); ++ sqlite3DbFree(pMem->db, zCopy); ++ } ++ return rc; ++ }else{ ++ int n, i, j; ++ char *zCopy; ++ const char *z; ++ ++ n = pMem->n & ~1; ++ zCopy = sqlite3DbMallocRaw(pMem->db, n/2 + 2); ++ if( zCopy ){ ++ z = pMem->z; ++ if( pMem->enc==SQLITE_UTF16LE ){ ++ for(i=j=0; idb, zCopy); ++ } ++ return rc; ++ } ++} ++ ++/* ++** Invoke sqlite3AtoF() on the text value of pMem. Write the ++** translation of the text input into *pValue. ++** ++** The caller must ensure that pMem->db!=0 and that pMem is in ++** mode MEM_Str or MEM_Blob. ++** ++** Result code invariants: ++** ++** rc==0 => ERROR: Input string not well-formed, or OOM ++** rc<0 => Some prefix of the input is well-formed ++** rc>0 => All of the input is well-formed ++** (rc&2)==0 => The number is expressed as an integer, with no ++** decimal point or eNNN suffix. ++*/ ++SQLITE_PRIVATE int sqlite3MemRealValueRC(Mem *pMem, double *pValue){ ++ testcase( pMem->db==0 ); ++ assert( pMem->flags & (MEM_Str|MEM_Blob) ); ++ if( pMem->z==0 ){ ++ *pValue = 0.0; ++ return 0; ++ }else if( pMem->enc==SQLITE_UTF8 ++ && ((pMem->flags & MEM_Term)!=0 || sqlite3VdbeMemZeroTerminateIfAble(pMem)) ++ ){ ++ return sqlite3AtoF(pMem->z, pValue); ++ }else if( pMem->n==0 ){ ++ *pValue = 0.0; ++ return 0; ++ }else{ ++ return sqlite3MemRealValueRCSlowPath(pMem, pValue); ++ } ++} ++ ++/* ++** This routine acts as a bridge from sqlite3VdbeRealValue() to ++** sqlite3VdbeRealValueRC, allowing sqlite3VdbeRealValue() to avoid ++** stuffing values onto the stack. ++*/ ++static SQLITE_NOINLINE double sqlite3MemRealValueNoRC(Mem *pMem){ ++ double r; ++ (void)sqlite3MemRealValueRC(pMem, &r); ++ return r; ++} ++ + /* + ** 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) ); +@@ -85433,7 +86391,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ + testcase( pMem->flags & MEM_IntReal ); + return (double)pMem->u.i; + }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ +- return memRealValue(pMem); ++ return sqlite3MemRealValueNoRC(pMem); + }else{ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + return (double)0; +@@ -85557,8 +86515,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ + 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) ++ rc = sqlite3MemRealValueRC(pMem, &pMem->u.r); ++ if( ((rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<2) + || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) + ){ + pMem->u.i = ix; +@@ -86022,6 +86980,84 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( + return SQLITE_OK; + } + ++/* Like sqlite3VdbeMemSetStr() except: ++** ++** enc is always SQLITE_UTF8 ++** pMem->db is always non-NULL ++*/ ++SQLITE_PRIVATE int sqlite3VdbeMemSetText( ++ Mem *pMem, /* Memory cell to set to string value */ ++ const char *z, /* String pointer */ ++ i64 n, /* Bytes in string, or negative */ ++ void (*xDel)(void*) /* Destructor function */ ++){ ++ i64 nByte = n; /* New value for pMem->n */ ++ u16 flags; ++ ++ assert( pMem!=0 ); ++ assert( pMem->db!=0 ); ++ assert( sqlite3_mutex_held(pMem->db->mutex) ); ++ assert( !sqlite3VdbeMemIsRowSet(pMem) ); ++ ++ /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ ++ if( !z ){ ++ sqlite3VdbeMemSetNull(pMem); ++ return SQLITE_OK; ++ } ++ ++ if( nByte<0 ){ ++ nByte = strlen(z); ++ flags = MEM_Str|MEM_Term; ++ }else{ ++ flags = MEM_Str; ++ } ++ if( nByte>(i64)pMem->db->aLimit[SQLITE_LIMIT_LENGTH] ){ ++ 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 + 1; ++ testcase( nAlloc==31 ); ++ testcase( nAlloc==32 ); ++ if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ ++ return SQLITE_NOMEM_BKPT; ++ } ++ assert( pMem->z!=0 ); ++ memcpy(pMem->z, z, nByte); ++ pMem->z[nByte] = 0; ++ }else{ ++ sqlite3VdbeMemRelease(pMem); ++ pMem->z = (char *)z; ++ if( xDel==SQLITE_DYNAMIC ){ ++ pMem->zMalloc = pMem->z; ++ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); ++ pMem->xDel = 0; ++ }else if( xDel==SQLITE_STATIC ){ ++ pMem->xDel = xDel; ++ flags |= MEM_Static; ++ }else{ ++ pMem->xDel = xDel; ++ flags |= MEM_Dyn; ++ } ++ } ++ pMem->flags = flags; ++ pMem->n = (int)(nByte & 0x7fffffff); ++ pMem->enc = SQLITE_UTF8; ++ 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 +@@ -86450,7 +87486,7 @@ static int valueFromExpr( + if( affinity==SQLITE_AFF_BLOB ){ + if( op==TK_FLOAT ){ + assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) ); +- sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8); ++ sqlite3AtoF(pVal->z, &pVal->u.r); + pVal->flags = MEM_Real; + }else if( op==TK_INTEGER ){ + /* This case is required by -9223372036854775808 and other strings +@@ -86718,6 +87754,11 @@ SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( + ** + ** If *ppVal is initially NULL then the caller is responsible for + ** ensuring that the value written into *ppVal is eventually freed. ++** ++** If the buffer does not contain a well-formed record, this routine may ++** read several bytes past the end of the buffer. Callers must therefore ++** ensure that any buffer which may contain a corrupt record is padded ++** with at least 8 bytes of addressable memory. + */ + SQLITE_PRIVATE int sqlite3Stat4Column( + sqlite3 *db, /* Database handle */ +@@ -88836,6 +89877,10 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ + zP4 = pOp->p4.pTab->zName; + break; + } ++ case P4_INDEX: { ++ zP4 = pOp->p4.pIdx->zName; ++ break; ++ } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = pOp->p4.pSubrtnSig; + sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); +@@ -89734,7 +90779,7 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName( + } + assert( p->aColName!=0 ); + pColName = &(p->aColName[idx+var*p->nResAlloc]); +- rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); ++ rc = sqlite3VdbeMemSetText(pColName, zName, -1, xDel); + assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); + return rc; + } +@@ -92226,6 +93271,223 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ + } + } + ++/* ++** Helper function for vdbeIsMatchingIndexKey(). Return true if column ++** iCol should be ignored when comparing a record with a record from ++** an index on disk. The field should be ignored if: ++** ++** * the corresponding bit in mask is set, and ++** * either: ++** - bIntegrity is false, or ++** - the two Mem values are both real values that differ by ++** BTREE_ULPDISTORTION or fewer ULPs. ++*/ ++static int vdbeSkipField( ++ Bitmask mask, /* Mask of indexed expression fields */ ++ int iCol, /* Column of index being considered */ ++ Mem *pMem1, /* Expected index value */ ++ Mem *pMem2, /* Actual indexed value */ ++ int bIntegrity /* True if running PRAGMA integrity_check */ ++){ ++#define BTREE_ULPDISTORTION 2 ++ if( iCol>=BMS || (mask & MASKBIT(iCol))==0 ) return 0; ++ if( bIntegrity==0 ) return 1; ++ if( (pMem1->flags & MEM_Real) && (pMem2->flags & MEM_Real) ){ ++ u64 m1, m2; ++ memcpy(&m1,&pMem1->u.r,8); ++ memcpy(&m2,&pMem2->u.r,8); ++ if( (m1pKeyInfo->enc; ++ mem.db = p->pKeyInfo->db; ++ nRec = sqlite3BtreePayloadSize(pCur); ++ if( nRec>0x7fffffff ){ ++ return SQLITE_CORRUPT_BKPT; ++ } ++ ++ /* Allocate 5 extra bytes at the end of the buffer. This allows the ++ ** getVarint32() call below to read slightly past the end of the buffer ++ ** if the record is corrupt. */ ++ aRec = sqlite3MallocZero(nRec+5); ++ if( aRec==0 ){ ++ rc = SQLITE_NOMEM_BKPT; ++ }else{ ++ rc = sqlite3BtreePayload(pCur, 0, nRec, aRec); ++ } ++ ++ if( rc==SQLITE_OK ){ ++ u32 szHdr = 0; /* Size of record header in bytes */ ++ u32 idxHdr = 0; /* Current index in header */ ++ ++ idxHdr = getVarint32(aRec, szHdr); ++ if( szHdr>98307 ){ ++ rc = SQLITE_CORRUPT; ++ }else{ ++ int res = 0; /* Result of this function call */ ++ u32 idxRec = szHdr; /* Index of next field in record body */ ++ int ii = 0; /* Iterator variable */ ++ ++ int nCol = p->pKeyInfo->nAllField; ++ for(ii=0; ii=szHdr ){ ++ rc = SQLITE_CORRUPT_BKPT; ++ break; ++ } ++ idxHdr += getVarint32(&aRec[idxHdr], iSerial); ++ nSerial = sqlite3VdbeSerialTypeLen(iSerial); ++ if( (idxRec+nSerial)>nRec ){ ++ rc = SQLITE_CORRUPT_BKPT; ++ }else{ ++ sqlite3VdbeSerialGet(&aRec[idxRec], iSerial, &mem); ++ if( vdbeSkipField(mask, ii, &p->aMem[ii], &mem, bInt)==0 ){ ++ res = sqlite3MemCompare(&mem, &p->aMem[ii], p->pKeyInfo->aColl[ii]); ++ if( res!=0 ) break; ++ } ++ } ++ idxRec += sqlite3VdbeSerialTypeLen(iSerial); ++ } ++ ++ *piRes = res; ++ } ++ } ++ ++ sqlite3_free(aRec); ++ return rc; ++} ++ ++/* ++** This is called when the record in (*p) should be found in the index ++** opened by cursor pCur, but was not. This may happen as part of a DELETE ++** operation or an integrity check. ++** ++** One reason that an exact match was not found may be the EIIB bug - that ++** a text-to-float conversion may have caused a real value in record (*p) ++** to be slightly different from its counterpart on disk. This function ++** attempts to find the right index record. If it does find the right ++** record, it leaves *pCur pointing to it and sets (*pRes) to 0 before ++** returning. Otherwise, (*pRes) is set to non-zero and an SQLite error ++** code returned. ++** ++** The algorithm used to find the correct record is: ++** ++** * Scan up to BTREE_FDK_RANGE entries either side of the current entry. ++** If parameter bIntegrity is false, then all fields that are indexed ++** expressions or virtual table columns are omitted from the comparison. ++** If bIntegrity is true, then small differences in real values in ++** such fields are overlooked, but they are not omitted from the comparison ++** altogether. ++** ++** * If the above fails to find an entry and bIntegrity is false, search ++** the entire index. ++*/ ++SQLITE_PRIVATE int sqlite3VdbeFindIndexKey( ++ BtCursor *pCur, ++ Index *pIdx, ++ UnpackedRecord *p, ++ int *pRes, ++ int bIntegrity ++){ ++#define BTREE_FDK_RANGE 10 ++ int nStep = 0; ++ int res = 1; ++ int rc = SQLITE_OK; ++ int ii = 0; ++ ++ /* Calculate a mask based on the first 64 columns of the index. The mask ++ ** bit is set if the corresponding index field is either an expression ++ ** or a virtual column of the table. */ ++ Bitmask mask = 0; ++ for(ii=0; iinColumn, BMS); ii++){ ++ int iCol = pIdx->aiColumn[ii]; ++ if( (iCol==XN_EXPR) ++ || (iCol>=0 && (pIdx->pTable->aCol[iCol].colFlags & COLFLAG_VIRTUAL)) ++ ){ ++ mask |= MASKBIT(ii); ++ } ++ } ++ ++ /* If the mask is 0 at this point, then the index contains no expressions ++ ** or virtual columns. So do not search for a match - return so that the ++ ** caller may declare the db corrupt immediately. Or, if mask is non-zero, ++ ** proceed. */ ++ if( mask!=0 ){ ++ ++ /* Move the cursor back BTREE_FDK_RANGE entries. If this hits an EOF, ++ ** position the cursor at the first entry in the index and set nStep ++ ** to -1 so that the first loop below scans the entire index. Otherwise, ++ ** set nStep to BTREE_FDK_RANGE*2 so that the first loop below scans ++ ** just that many entries. */ ++ for(ii=0; sqlite3BtreeEof(pCur)==0 && ii=0), or the entire index if (nStep<0). */ ++ while( sqlite3BtreeCursorIsValidNN(pCur) ){ ++ for(ii=0; rc==SQLITE_OK && (iiexpired; ++ int iRet = 1; ++ if( pStmt ){ ++ Vdbe *p = (Vdbe*)pStmt; ++ sqlite3_mutex_enter(p->db->mutex); ++ iRet = p->expired; ++ sqlite3_mutex_leave(p->db->mutex); ++ } ++ return iRet; + } + #endif + +@@ -92812,7 +94080,23 @@ static void setResultStrOrError( + void (*xDel)(void*) /* Destructor function */ + ){ + Mem *pOut = pCtx->pOut; +- int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); ++ int rc; ++ if( enc==SQLITE_UTF8 ){ ++ rc = sqlite3VdbeMemSetText(pOut, z, n, xDel); ++ }else if( enc==SQLITE_UTF8_ZT ){ ++ /* It is usually considered improper to assert() on an input. However, ++ ** the following assert() is checking for inputs that are documented ++ ** to result in undefined behavior. */ ++ assert( z==0 ++ || n<0 ++ || n>pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ++ || z[n]==0 ++ ); ++ rc = sqlite3VdbeMemSetText(pOut, z, n, xDel); ++ pOut->flags |= MEM_Term; ++ }else{ ++ rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); ++ } + if( rc ){ + if( rc==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); +@@ -93005,7 +94289,7 @@ SQLITE_API void sqlite3_result_text64( + #endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); +- if( enc!=SQLITE_UTF8 ){ ++ if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + n &= ~(u64)1; + } +@@ -93156,6 +94440,8 @@ static int doWalCallbacks(sqlite3 *db){ + } + } + } ++#else ++ UNUSED_PARAMETER(db); + #endif + return rc; + } +@@ -94112,13 +95398,25 @@ static int bindText( + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ + if( zData!=0 ){ + pVar = &p->aVar[i-1]; +- rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); +- if( rc==SQLITE_OK ){ +- if( encoding==0 ){ +- pVar->enc = ENC(p->db); +- }else{ +- rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); +- } ++ if( encoding==SQLITE_UTF8 ){ ++ rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel); ++ }else if( encoding==SQLITE_UTF8_ZT ){ ++ /* It is usually consider improper to assert() on an input. ++ ** However, the following assert() is checking for inputs ++ ** that are documented to result in undefined behavior. */ ++ assert( zData==0 ++ || nData<0 ++ || nData>pVar->db->aLimit[SQLITE_LIMIT_LENGTH] ++ || ((u8*)zData)[nData]==0 ++ ); ++ rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel); ++ pVar->flags |= MEM_Term; ++ }else{ ++ rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); ++ if( encoding==0 ) pVar->enc = ENC(p->db); ++ } ++ if( rc==SQLITE_OK && encoding!=0 ){ ++ rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + } + if( rc ){ + sqlite3Error(p->db, rc); +@@ -94230,7 +95528,7 @@ SQLITE_API int sqlite3_bind_text64( + unsigned char enc + ){ + assert( xDel!=SQLITE_DYNAMIC ); +- if( enc!=SQLITE_UTF8 ){ ++ if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + nData &= ~(u64)1; + } +@@ -95267,17 +96565,19 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( + #ifndef SQLITE_HWTIME_H + #define SQLITE_HWTIME_H + +-/* +-** The following routine only works on Pentium-class (or newer) processors. +-** It uses the RDTSC opcode to read the cycle count value out of the +-** processor and returns that value. This can be used for high-res +-** profiling. +-*/ +-#if !defined(__STRICT_ANSI__) && \ +- (defined(__GNUC__) || defined(_MSC_VER)) && \ +- (defined(i386) || defined(__i386__) || defined(_M_IX86)) ++#if defined(_MSC_VER) && defined(_WIN32) ++ ++/* #include "windows.h" */ ++ #include + +- #if defined(__GNUC__) ++ __inline sqlite3_uint64 sqlite3Hwtime(void){ ++ LARGE_INTEGER tm; ++ QueryPerformanceCounter(&tm); ++ return (sqlite3_uint64)tm.QuadPart; ++ } ++ ++#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \ ++ (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; +@@ -95285,17 +96585,6 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( + return (sqlite_uint64)hi << 32 | lo; + } + +- #elif defined(_MSC_VER) +- +- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ +- __asm { +- rdtsc +- ret ; return value at EDX:EAX +- } +- } +- +- #endif +- + #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ +@@ -95304,6 +96593,14 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( + return (sqlite_uint64)hi << 32 | lo; + } + ++#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__) ++ ++ __inline__ sqlite_uint64 sqlite3Hwtime(void){ ++ sqlite3_uint64 cnt; ++ __asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt)); ++ return cnt; ++ } ++ + #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ +@@ -95662,12 +96959,11 @@ static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ + */ + 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); ++ rc = sqlite3MemRealValueRC(pRec, &rValue); + if( rc<=0 ) return; +- if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ ++ if( (rc&2)==0 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ + pRec->flags |= MEM_Int; + }else{ + pRec->u.r = rValue; +@@ -95747,7 +97043,10 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ + int eType = sqlite3_value_type(pVal); + if( eType==SQLITE_TEXT ){ + Mem *pMem = (Mem*)pVal; ++ assert( pMem->db!=0 ); ++ sqlite3_mutex_enter(pMem->db->mutex); + applyNumericAffinity(pMem, 0); ++ sqlite3_mutex_leave(pMem->db->mutex); + eType = sqlite3_value_type(pVal); + } + return eType; +@@ -95780,15 +97079,15 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ + pMem->u.i = 0; + return MEM_Int; + } +- rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); ++ rc = sqlite3MemRealValueRC(pMem, &pMem->u.r); + if( rc<=0 ){ +- if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ ++ if( (rc&2)==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 ){ ++ }else if( (rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ + pMem->u.i = ix; + return MEM_Int; + } +@@ -101929,20 +103228,17 @@ case OP_SorterInsert: { /* in2 */ + break; + } + +-/* Opcode: IdxDelete P1 P2 P3 * P5 ++/* Opcode: IdxDelete P1 P2 P3 P4 * + ** 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. ++** P4 is a pointer to an Index structure. ++** ++** Raise an SQLITE_CORRUPT_INDEX error if no matching index entry is found ++** and not in writable_schema mode. + */ + case OP_IdxDelete: { + VdbeCursor *pC; +@@ -101965,13 +103261,22 @@ case OP_IdxDelete: { + 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; ++ if( res!=0 ){ ++ rc = sqlite3VdbeFindIndexKey(pCrsr, pOp->p4.pIdx, &r, &res, 0); ++ if( rc!=SQLITE_OK ) goto abort_due_to_error; ++ if( res!=0 ){ ++ if( !sqlite3WritableSchema(db) ){ ++ rc = sqlite3ReportError( ++ SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); ++ goto abort_due_to_error; ++ } ++ pC->cacheStatus = CACHE_STALE; ++ pC->seekResult = 0; ++ break; ++ } + } ++ rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); ++ if( rc ) goto abort_due_to_error; + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; +@@ -102598,6 +103903,58 @@ case OP_IntegrityCk: { + sqlite3VdbeChangeEncoding(pIn1, encoding); + goto check_for_interrupt; + } ++ ++/* Opcode: IFindKey P1 P2 P3 P4 * ++** ++** This instruction always follows an OP_Found with the same P1, P2 and P3 ++** values as this instruction and a non-zero P4 value. The P4 value to ++** this opcode is of type P4_INDEX and contains a pointer to the Index ++** object of for the index being searched. ++** ++** This opcode uses sqlite3VdbeFindIndexKey() to search around the current ++** cursor location for an index key that exactly matches all fields that ++** are not indexed expressions or references to VIRTUAL generated columns, ++** and either exactly match or are real numbers that are within 2 ULPs of ++** each other if the don't match. ++** ++** To put it another way, this opcode looks for nearby index entries that ++** are very close to the search key, but which might have small differences ++** in floating-point values that come via an expression. ++** ++** If no nearby alternative entry is found in cursor P1, then jump to P2. ++** But if a close match is found, fall through. ++** ++** This opcode is used by PRAGMA integrity_check to help distinguish ++** between truely corrupt indexes and expression indexes that are holding ++** floating-point values that are off by one or two ULPs. ++*/ ++case OP_IFindKey: { /* jump, in3 */ ++ VdbeCursor *pC; ++ int res; ++ UnpackedRecord r; ++ ++ assert( pOp[-1].opcode==OP_Found ); ++ assert( pOp[-1].p1==pOp->p1 ); ++ assert( pOp[-1].p3==pOp->p3 ); ++ pC = p->apCsr[pOp->p1]; ++ assert( pOp->p4type==P4_INDEX ); ++ assert( pC->eCurType==CURTYPE_BTREE ); ++ assert( pC->uc.pCursor!=0 ); ++ assert( pC->isTable==0 ); ++ ++ memset(&r, 0, sizeof(r)); ++ r.aMem = &aMem[pOp->p3]; ++ r.nField = pOp->p4.pIdx->nColumn; ++ r.pKeyInfo = pC->pKeyInfo; ++ ++ rc = sqlite3VdbeFindIndexKey(pC->uc.pCursor, pOp->p4.pIdx, &r, &res, 1); ++ if( rc || res!=0 ){ ++ rc = SQLITE_OK; ++ goto jump_to_p2; ++ } ++ pC->nullRow = 0; ++ break; ++}; + #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + + /* Opcode: RowSetAdd P1 P2 * * * +@@ -109900,6 +111257,7 @@ static int lookupName( + pExpr->op = TK_FUNCTION; + pExpr->u.zToken = "coalesce"; + pExpr->x.pList = pFJMatch; ++ pExpr->affExpr = SQLITE_AFF_DEFER; + cnt = 1; + goto lookupname_end; + }else{ +@@ -110062,12 +111420,41 @@ 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); ++ sqlite3AtoF(p->u.zToken, &r); + assert( r>=0.0 ); + if( r>1.0 ) return -1; + return (int)(r*134217728.0); + } + ++/* ++** Set the EP_SubtArg property on every expression inside of ++** pList. If any subexpression is actually a subquery, then ++** also set the EP_SubtArg property on the first result-set ++** column of that subquery. ++*/ ++static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){ ++ int nn, ii; ++ nn = pList ? pList->nExpr : 0; ++ for(ii=0; iia[ii].pExpr; ++ while( 1 /*exit-by-break*/ ){ ++ ExprSetProperty(pExpr, EP_SubtArg); ++ if( pExpr->op==TK_SELECT ){ ++ assert( ExprUseXSelect(pExpr) ); ++ assert( pExpr->x.pSelect!=0 ); ++ resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList); ++ break; ++ } ++ if( pExpr->op==TK_UPLUS ){ ++ pExpr = pExpr->pLeft; ++ assert( pExpr!=0 ); ++ }else{ ++ break; ++ } ++ } ++ } ++} ++ + /* + ** This routine is callback for sqlite3WalkExpr(). + ** +@@ -110312,10 +111699,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + if( (pDef->funcFlags & SQLITE_SUBTYPE) + || ExprHasProperty(pExpr, EP_SubtArg) + ){ +- int ii; +- for(ii=0; iia[ii].pExpr, EP_SubtArg); +- } ++ resolveSetExprSubtypeArg(pList); + } + + if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ +@@ -110782,10 +112166,8 @@ static int resolveCompoundOrderBy( + /* 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); ++ Expr *pNew = sqlite3ExprInt32(db, iCol); + if( pNew==0 ) return 1; +- pNew->flags |= EP_IntValue; +- pNew->u.iValue = iCol; + if( pItem->pExpr==pE ){ + pItem->pExpr = pNew; + }else{ +@@ -111139,10 +112521,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ + } + #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 +@@ -112389,34 +113767,22 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( + int dequote /* True to dequote */ + ){ + Expr *pNew; +- int nExtra = 0; +- int iValue = 0; ++ int nExtra = pToken ? pToken->n+1 : 0; + + assert( db!=0 ); +- if( pToken ){ +- if( op!=TK_INTEGER || pToken->z==0 +- || sqlite3GetInt32(pToken->z, &iValue)==0 ){ +- nExtra = pToken->n+1; /* tag-20240227-a */ +- 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( nExtra ){ ++ assert( pToken!=0 ); ++ 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 +@@ -112441,6 +113807,24 @@ SQLITE_PRIVATE Expr *sqlite3Expr( + return sqlite3ExprAlloc(db, op, &x, 0); + } + ++/* ++** Allocate an expression for a 32-bit signed integer literal. ++*/ ++SQLITE_PRIVATE Expr *sqlite3ExprInt32(sqlite3 *db, int iVal){ ++ Expr *pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)); ++ if( pNew ){ ++ memset(pNew, 0, sizeof(Expr)); ++ pNew->op = TK_INTEGER; ++ pNew->iAgg = -1; ++ pNew->flags = EP_IntValue|EP_Leaf|(iVal?EP_IsTrue:EP_IsFalse); ++ pNew->u.iValue = iVal; ++#if SQLITE_MAX_EXPR_DEPTH>0 ++ pNew->nHeight = 1; ++#endif ++ } ++ return pNew; ++} ++ + /* + ** Attach subtrees pLeft and pRight to the Expr node pRoot. + ** +@@ -112603,7 +113987,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ + ){ + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); +- return sqlite3Expr(db, TK_INTEGER, "0"); ++ return sqlite3ExprInt32(db, 0); + }else{ + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); + } +@@ -112728,7 +114112,9 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable( + ){ + assert( !IN_RENAME_OBJECT ); + assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); +- if( ExprHasProperty(pExpr, EP_FromDDL) ){ ++ if( ExprHasProperty(pExpr, EP_FromDDL) ++ || pParse->prepFlags & SQLITE_PREPARE_FROM_DDL ++ ){ + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + || (pParse->db->flags & SQLITE_TrustedSchema)==0 + ){ +@@ -113424,9 +114810,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); + pNew->iLimit = 0; + pNew->iOffset = 0; +- pNew->selFlags = p->selFlags & ~(u32)SF_UsesEphemeral; +- pNew->addrOpenEphm[0] = -1; +- pNew->addrOpenEphm[1] = -1; ++ pNew->selFlags = p->selFlags; + pNew->nSelectRow = p->nSelectRow; + pNew->pWith = sqlite3WithDup(db, p->pWith); + #ifndef SQLITE_OMIT_WINDOWFUNC +@@ -114078,7 +115462,7 @@ static int exprIsConst(Parse *pParse, Expr *p, int initFlag){ + + /* + ** Walk an expression tree. Return non-zero if the expression is constant +-** and 0 if it involves variables or function calls. ++** or return zero if the expression 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 +@@ -114868,6 +116252,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( + */ + u32 savedNQueryLoop = pParse->nQueryLoop; + int rMayHaveNull = 0; ++ int bloomOk = (inFlags & IN_INDEX_MEMBERSHIP)!=0; + eType = IN_INDEX_EPH; + if( inFlags & IN_INDEX_LOOP ){ + pParse->nQueryLoop = 0; +@@ -114875,7 +116260,13 @@ SQLITE_PRIVATE int sqlite3FindInIndex( + *prRhsHasNull = rMayHaveNull = ++pParse->nMem; + } + assert( pX->op==TK_IN ); +- sqlite3CodeRhsOfIN(pParse, pX, iTab); ++ if( !bloomOk ++ && ExprUseXSelect(pX) ++ && (pX->x.pSelect->selFlags & SF_ClonedRhsIn)!=0 ++ ){ ++ bloomOk = 1; ++ } ++ sqlite3CodeRhsOfIN(pParse, pX, iTab, bloomOk); + if( rMayHaveNull ){ + sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); + } +@@ -115033,7 +116424,8 @@ static int findCompatibleInRhsSubrtn( + SQLITE_PRIVATE void sqlite3CodeRhsOfIN( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The IN operator */ +- int iTab /* Use this cursor number */ ++ int iTab, /* Use this cursor number */ ++ int allowBloom /* True to allow the use of a Bloom filter */ + ){ + int addrOnce = 0; /* Address of the OP_Once instruction at top */ + int addr; /* Address of OP_OpenEphemeral instruction */ +@@ -115155,7 +116547,10 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( + sqlite3SelectDestInit(&dest, SRT_Set, iTab); + dest.zAffSdst = exprINAffinity(pParse, pExpr); + pSelect->iLimit = 0; +- if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ ++ if( addrOnce ++ && allowBloom ++ && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ++ ){ + int regBloom = ++pParse->nMem; + addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); + VdbeComment((v, "Bloom filter")); +@@ -115376,7 +116771,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + || (pLeft->u.iValue!=1 && pLeft->u.iValue!=0) + ){ + sqlite3 *db = pParse->db; +- pLimit = sqlite3Expr(db, TK_INTEGER, "0"); ++ pLimit = sqlite3ExprInt32(db, 0); + if( pLimit ){ + pLimit->affExpr = SQLITE_AFF_NUMERIC; + pLimit = sqlite3PExpr(pParse, TK_NE, +@@ -115387,7 +116782,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + } + }else{ + /* If there is no pre-existing limit add a limit of 1 */ +- pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); ++ pLimit = sqlite3ExprInt32(pParse->db, 1); + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + } + pSel->iLimit = 0; +@@ -115625,7 +117020,7 @@ static void sqlite3ExprCodeIN( + Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i); + if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; + if( sqlite3ExprCanBeNull(p) ){ +- sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); ++ sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+aiMap[i], destStep2); + VdbeCoverage(v); + } + } +@@ -115648,8 +117043,9 @@ static void sqlite3ExprCodeIN( + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); + assert( pOp->opcode==OP_Once || pParse->nErr ); +- if( pOp->opcode==OP_Once && pOp->p3>0 ){ /* tag-202407032019 */ +- assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); ++ if( pOp->p3>0 ){ /* tag-202407032019 */ ++ assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ++ || pParse->nErr ); + sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + } +@@ -115698,9 +117094,18 @@ static void sqlite3ExprCodeIN( + CollSeq *pColl; + int r3 = sqlite3GetTempReg(pParse); + p = sqlite3VectorFieldSubexpr(pLeft, i); +- pColl = sqlite3ExprCollSeq(pParse, p); +- sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3); +- sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3, ++ if( ExprUseXSelect(pExpr) ){ ++ Expr *pRhs = pExpr->x.pSelect->pEList->a[i].pExpr; ++ pColl = sqlite3BinaryCompareCollSeq(pParse, p, pRhs); ++ }else{ ++ /* If the RHS of the IN(...) expression are scalar expressions, do ++ ** not consider their collation sequences. The documentation says ++ ** "The collating sequence used for expressions of the form "x IN (y, z, ++ ** ...)" is the collating sequence of x.". */ ++ pColl = sqlite3ExprCollSeq(pParse, p); ++ } ++ sqlite3VdbeAddOp3(v, OP_Column, iTab, aiMap[i], r3); ++ sqlite3VdbeAddOp4(v, OP_Ne, rLhs+aiMap[i], destNotNull, r3, + (void*)pColl, P4_COLLSEQ); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, r3); +@@ -115739,7 +117144,7 @@ sqlite3ExprCodeIN_oom_error: + 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); ++ sqlite3AtoF(z, &value); + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + if( negateFlag ) value = -value; + sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); +@@ -116121,26 +117526,37 @@ static int exprCodeInlineFunction( + } + + /* +-** Expression Node callback for sqlite3ExprCanReturnSubtype(). ++** Expression Node callback for sqlite3ExprCanReturnSubtype(). If ++** pExpr is able to return a subtype, set pWalker->eCode and abort ++** the search. If pExpr can never return a subtype, prune search. ++** ++** The only expressions that can return a subtype are: ++** ++** 1. A function ++** 2. The no-op "+" operator ++** 3. A CASE...END expression ++** 4. A CAST() expression ++** 5. A "expr COLLATE colseq" expression. + ** +-** Only a function call is able to return a subtype. So if the node +-** is not a function call, return WRC_Prune immediately. ++** For any other kind of expression, prune the search. + ** +-** A function call is able to return a subtype if it has the +-** SQLITE_RESULT_SUBTYPE property. ++** For case 1, the expression can yield a subtype if the function has ++** the SQLITE_RESULT_SUBTYPE property. Functions can also return ++** a subtype (via sqlite3_result_value()) if any of the arguments can ++** return a subtype. + ** +-** Assume that every function is able to pass-through a subtype from +-** one of its argument (using sqlite3_result_value()). Most functions +-** are not this way, but we don't have a mechanism to distinguish those +-** that are from those that are not, so assume they all work this way. +-** That means that if one of its arguments is another function and that +-** other function is able to return a subtype, then this function is +-** able to return a subtype. ++** In all cases 1 through 5, the expression might also return a subtype ++** if any operand can return a subtype. + */ + static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + int n; + FuncDef *pDef; + sqlite3 *db; ++ if( pExpr->op==TK_CASE || pExpr->op==TK_UPLUS ++ || pExpr->op==TK_COLLATE || pExpr->op==TK_CAST ++ ){ ++ return WRC_Continue; ++ } + if( pExpr->op!=TK_FUNCTION ){ + return WRC_Prune; + } +@@ -116150,7 +117566,7 @@ static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + pWalker->eCode = 1; +- return WRC_Prune; ++ return WRC_Abort; + } + return WRC_Continue; + } +@@ -116598,7 +118014,7 @@ expr_code_doover: + case TK_ISNOT: + op = (op==TK_IS) ? TK_EQ : TK_NE; + p5 = SQLITE_NULLEQ; +- /* fall-through */ ++ /* no break */ deliberate_fall_through + case TK_LT: + case TK_LE: + case TK_GT: +@@ -118840,7 +120256,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + if( pIEpr==0 ) break; + if( NEVER(!ExprUseYTab(pExpr)) ) break; + for(i=0; inSrc; i++){ +- if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; ++ if( pSrcList->a[i].iCursor==pIEpr->iDataCur ){ ++ testcase( i>0 ); ++ break; ++ } + } + if( i>=pSrcList->nSrc ) break; + if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ +@@ -119629,7 +121048,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); +- if( db->mallocFailed ) goto exit_begin_add_column; ++ if( NEVER(db->mallocFailed) ) goto exit_begin_add_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_begin_add_column; + +@@ -119701,7 +121120,7 @@ exit_begin_add_column: + ** 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){ ++static int isRealTable(Parse *pParse, Table *pTab, int iOp){ + const char *zType = 0; + #ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ +@@ -119714,9 +121133,12 @@ static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ + } + #endif + if( zType ){ ++ const char *azMsg[] = { ++ "rename columns of", "drop column from", "edit constraints of" ++ }; ++ assert( iOp>=0 && iOpzName ++ azMsg[iOp], zType, pTab->zName + ); + return 1; + } +@@ -120187,6 +121609,25 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ + return pBest; + } + ++/* ++** Set the error message of the context passed as the first argument to ++** the result of formatting zFmt using printf() style formatting. ++*/ ++static void errorMPrintf(sqlite3_context *pCtx, const char *zFmt, ...){ ++ sqlite3 *db = sqlite3_context_db_handle(pCtx); ++ char *zErr = 0; ++ va_list ap; ++ va_start(ap, zFmt); ++ zErr = sqlite3VMPrintf(db, zFmt, ap); ++ va_end(ap); ++ if( zErr ){ ++ sqlite3_result_error(pCtx, zErr, -1); ++ sqlite3DbFree(db, zErr); ++ }else{ ++ sqlite3_result_error_nomem(pCtx); ++ } ++} ++ + /* + ** An error occurred while parsing or otherwise processing a database + ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an +@@ -120484,8 +121925,8 @@ static int renameResolveTrigger(Parse *pParse){ + sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); + if( pParse->nErr ) rc = pParse->rc; + } +- if( rc==SQLITE_OK && pStep->zTarget ){ +- SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep); ++ if( rc==SQLITE_OK && pStep->pSrc ){ ++ SrcList *pSrc = sqlite3SrcListDup(db, pStep->pSrc, 0); + if( pSrc ){ + Select *pSel = sqlite3SelectNew( + pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0 +@@ -120513,10 +121954,10 @@ static int renameResolveTrigger(Parse *pParse){ + pSel->pSrc = 0; + sqlite3SelectDelete(db, pSel); + } +- if( pStep->pFrom ){ ++ if( ALWAYS(pStep->pSrc) ){ + int i; +- for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){ +- SrcItem *p = &pStep->pFrom->a[i]; ++ for(i=0; ipSrc->nSrc && rc==SQLITE_OK; i++){ ++ SrcItem *p = &pStep->pSrc->a[i]; + if( p->fg.isSubquery ){ + assert( p->u4.pSubq!=0 ); + sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); +@@ -120585,13 +122026,13 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ + sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); + } +- if( pStep->pFrom ){ ++ if( pStep->pSrc ){ + int i; +- SrcList *pFrom = pStep->pFrom; +- for(i=0; inSrc; i++){ +- if( pFrom->a[i].fg.isSubquery ){ +- assert( pFrom->a[i].u4.pSubq!=0 ); +- sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); ++ SrcList *pSrc = pStep->pSrc; ++ for(i=0; inSrc; i++){ ++ if( pSrc->a[i].fg.isSubquery ){ ++ assert( pSrc->a[i].u4.pSubq!=0 ); ++ sqlite3WalkSelect(pWalker, pSrc->a[i].u4.pSubq->pSelect); + } + } + } +@@ -120762,8 +122203,8 @@ static void renameColumnFunc( + 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( pStep->pSrc ){ ++ Table *pTarget = sqlite3LocateTableItem(&sParse, 0, &pStep->pSrc->a[0]); + if( pTarget==pTab ){ + if( pStep->pUpsert ){ + ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; +@@ -120775,7 +122216,6 @@ static void renameColumnFunc( + } + } + +- + /* Find tokens to edit in UPDATE OF clause */ + if( sParse.pTriggerTab==pTab ){ + renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); +@@ -120977,13 +122417,10 @@ static void renameTableFunc( + 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 ){ ++ if( pStep->pSrc ){ + int i; +- for(i=0; ipFrom->nSrc; i++){ +- SrcItem *pItem = &pStep->pFrom->a[i]; ++ for(i=0; ipSrc->nSrc; i++){ ++ SrcItem *pItem = &pStep->pSrc->a[i]; + if( 0==sqlite3_stricmp(pItem->zName, zOld) ){ + renameTokenFind(&sParse, &sCtx, pItem->zName); + } +@@ -121230,6 +122667,57 @@ static void renameTableTest( + #endif + } + ++ ++/* ++** Return the number of bytes until the end of the next non-whitespace and ++** non-comment token. For the purpose of this function, a "(" token includes ++** all of the bytes through and including the matching ")", or until the ++** first illegal token, whichever comes first. ++** ++** Write the token type into *piToken. ++** ++** The value returned is the number of bytes in the token itself plus ++** the number of bytes of leading whitespace and comments skipped plus ++** all bytes through the next matching ")" if the token is TK_LP. ++** ++** Example: (Note: '.' used in place of '*' in the example z[] text) ++** ++** ,--------- *piToken := TK_RP ++** v ++** z[] = " /.comment./ --comment\n (two three four) five" ++** | | ++** |<-------------------------------------->| ++** | ++** `--- return value ++*/ ++static int getConstraintToken(const u8 *z, int *piToken){ ++ int iOff = 0; ++ int t = 0; ++ do { ++ iOff += sqlite3GetToken(&z[iOff], &t); ++ }while( t==TK_SPACE || t==TK_COMMENT ); ++ ++ *piToken = t; ++ ++ if( t==TK_LP ){ ++ int nNest = 1; ++ while( nNest>0 ){ ++ iOff += sqlite3GetToken(&z[iOff], &t); ++ if( t==TK_LP ){ ++ nNest++; ++ }else if( t==TK_RP ){ ++ t = TK_LP; ++ nNest--; ++ }else if( t==TK_ILLEGAL ){ ++ break; ++ } ++ } ++ } ++ ++ *piToken = t; ++ return iOff; ++} ++ + /* + ** The implementation of internal UDF sqlite_drop_column(). + ** +@@ -121274,15 +122762,24 @@ static void dropColumnFunc( + goto drop_column_done; + } + +- pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); + if( iColnCol-1 ){ + RenameToken *pEnd; ++ pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); + zEnd = (const char*)pEnd->t.z; + }else{ ++ int eTok; + assert( IsOrdinaryTable(pTab) ); ++ assert( iCol!=0 ); ++ /* Point pCol->t.z at the "," immediately preceding the definition of ++ ** the column being dropped. To do this, start at the name of the ++ ** previous column, and tokenize until the next ",". */ ++ pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol-1].zCnName); ++ do { ++ pCol->t.z += getConstraintToken((const u8*)pCol->t.z, &eTok); ++ }while( eTok!=TK_COMMA ); ++ pCol->t.z--; + 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); +@@ -121451,6 +122948,665 @@ exit_drop_column: + sqlite3SrcListDelete(db, pSrc); + } + ++/* ++** Return the number of bytes of leading whitespace/comments in string z[]. ++*/ ++static int getWhitespace(const u8 *z){ ++ int nRet = 0; ++ while( 1 ){ ++ int t = 0; ++ int n = sqlite3GetToken(&z[nRet], &t); ++ if( t!=TK_SPACE && t!=TK_COMMENT ) break; ++ nRet += n; ++ } ++ return nRet; ++} ++ ++ ++/* ++** Argument z points into the body of a constraint - specifically the ++** second token of the constraint definition. For a named constraint, ++** z points to the first token past the CONSTRAINT keyword. For an ++** unnamed NOT NULL constraint, z points to the first byte past the NOT ++** keyword. ++** ++** Return the number of bytes until the end of the constraint. ++*/ ++static int getConstraint(const u8 *z){ ++ int iOff = 0; ++ int t = 0; ++ ++ /* Now, the current constraint proceeds until the next occurence of one ++ ** of the following tokens: ++ ** ++ ** CONSTRAINT, PRIMARY, NOT, UNIQUE, CHECK, DEFAULT, ++ ** COLLATE, REFERENCES, FOREIGN, GENERATED, AS, RP, or COMMA ++ ** ++ ** Also exit the loop if ILLEGAL turns up. ++ */ ++ while( 1 ){ ++ int n = getConstraintToken(&z[iOff], &t); ++ if( t==TK_CONSTRAINT || t==TK_PRIMARY || t==TK_NOT || t==TK_UNIQUE ++ || t==TK_CHECK || t==TK_DEFAULT || t==TK_COLLATE || t==TK_REFERENCES ++ || t==TK_FOREIGN || t==TK_RP || t==TK_COMMA || t==TK_ILLEGAL ++ || t==TK_AS || t==TK_GENERATED ++ ){ ++ break; ++ } ++ iOff += n; ++ } ++ ++ return iOff; ++} ++ ++/* ++** Compare two constraint names. ++** ++** Summary: *pRes := zQuote != zCmp ++** ++** Details: ++** Compare the (possibly quoted) constraint name zQuote[0..nQuote-1] ++** against zCmp[]. Write zero into *pRes if they are the same and ++** non-zero if they differ. Normally return SQLITE_OK, except if there ++** is an OOM, set the OOM error condition on ctx and return SQLITE_NOMEM. ++*/ ++static int quotedCompare( ++ sqlite3_context *ctx, /* Function context on which to report errors */ ++ int t, /* Token type */ ++ const u8 *zQuote, /* Possibly quoted text. Not zero-terminated. */ ++ int nQuote, /* Length of zQuote in bytes */ ++ const u8 *zCmp, /* Zero-terminated, unquoted name to compare against */ ++ int *pRes /* OUT: Set to 0 if equal, non-zero if unequal */ ++){ ++ char *zCopy = 0; /* De-quoted, zero-terminated copy of zQuote[] */ ++ ++ if( t==TK_ILLEGAL ){ ++ *pRes = 1; ++ return SQLITE_OK; ++ } ++ zCopy = sqlite3MallocZero(nQuote+1); ++ if( zCopy==0 ){ ++ sqlite3_result_error_nomem(ctx); ++ return SQLITE_NOMEM_BKPT; ++ } ++ memcpy(zCopy, zQuote, nQuote); ++ sqlite3Dequote(zCopy); ++ *pRes = sqlite3_stricmp((const char*)zCopy, (const char*)zCmp); ++ sqlite3_free(zCopy); ++ return SQLITE_OK; ++} ++ ++/* ++** zSql[] is a CREATE TABLE statement, supposedly. Find the offset ++** into zSql[] of the first character past the first "(" and write ++** that offset into *piOff and return SQLITE_OK. Or, if not found, ++** set the SQLITE_CORRUPT error code and return SQLITE_ERROR. ++*/ ++static int skipCreateTable(sqlite3_context *ctx, const u8 *zSql, int *piOff){ ++ int iOff = 0; ++ ++ if( zSql==0 ) return SQLITE_ERROR; ++ ++ /* Jump past the "CREATE TABLE" bit. */ ++ while( 1 ){ ++ int t = 0; ++ iOff += sqlite3GetToken(&zSql[iOff], &t); ++ if( t==TK_LP ) break; ++ if( t==TK_ILLEGAL ){ ++ sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT); ++ return SQLITE_ERROR; ++ } ++ } ++ ++ *piOff = iOff; ++ return SQLITE_OK; ++} ++ ++/* ++** Internal SQL function sqlite3_drop_constraint(): Given an input ++** CREATE TABLE statement, return a revised CREATE TABLE statement ++** with a constraint removed. Two forms, depending on the datatype ++** of argv[2]: ++** ++** sqlite_drop_constraint(SQL, INT) -- Omit NOT NULL from the INT-th column ++** sqlite_drop_constraint(SQL, TEXT) -- OMIT constraint with name TEXT ++** ++** In the first case, the left-most column is 0. ++*/ ++static void dropConstraintFunc( ++ sqlite3_context *ctx, ++ int NotUsed, ++ sqlite3_value **argv ++){ ++ const u8 *zSql = sqlite3_value_text(argv[0]); ++ const u8 *zCons = 0; ++ int iNotNull = -1; ++ int ii; ++ int iOff = 0; ++ int iStart = 0; ++ int iEnd = 0; ++ char *zNew = 0; ++ int t = 0; ++ sqlite3 *db; ++ UNUSED_PARAMETER(NotUsed); ++ ++ if( zSql==0 ) return; ++ ++ /* Jump past the "CREATE TABLE" bit. */ ++ if( skipCreateTable(ctx, zSql, &iOff) ) return; ++ ++ if( sqlite3_value_type(argv[1])==SQLITE_INTEGER ){ ++ iNotNull = sqlite3_value_int(argv[1]); ++ }else{ ++ zCons = sqlite3_value_text(argv[1]); ++ } ++ ++ /* Search for the named constraint within column definitions. */ ++ for(ii=0; iEnd==0; ii++){ ++ ++ /* Now parse the column or table constraint definition. Search ++ ** for the token CONSTRAINT if this is a DROP CONSTRAINT command, or ++ ** NOT in the right column if this is a DROP NOT NULL. */ ++ while( 1 ){ ++ iStart = iOff; ++ iOff += getConstraintToken(&zSql[iOff], &t); ++ if( t==TK_CONSTRAINT && (zCons || iNotNull==ii) ){ ++ /* Check if this is the constraint we are searching for. */ ++ int nTok = 0; ++ int cmp = 1; ++ ++ /* Skip past any whitespace. */ ++ iOff += getWhitespace(&zSql[iOff]); ++ ++ /* Compare the next token - which may be quoted - with the name of ++ ** the constraint being dropped. */ ++ nTok = getConstraintToken(&zSql[iOff], &t); ++ if( zCons ){ ++ if( quotedCompare(ctx, t, &zSql[iOff], nTok, zCons, &cmp) ) return; ++ } ++ iOff += nTok; ++ ++ /* The next token is usually the first token of the constraint ++ ** definition. This is enough to tell the type of the constraint - ++ ** TK_NOT means it is a NOT NULL, TK_CHECK a CHECK constraint etc. ++ ** ++ ** There is also the chance that the next token is TK_CONSTRAINT ++ ** (or TK_DEFAULT or TK_COLLATE), for example if a table has been ++ ** created as follows: ++ ** ++ ** CREATE TABLE t1(cols, CONSTRAINT one CONSTRAINT two NOT NULL); ++ ** ++ ** In this case, allow the "CONSTRAINT one" bit to be dropped by ++ ** this command if that is what is requested, or to advance to ++ ** the next iteration of the loop with &zSql[iOff] still pointing ++ ** to the CONSTRAINT keyword. */ ++ nTok = getConstraintToken(&zSql[iOff], &t); ++ if( t==TK_CONSTRAINT || t==TK_DEFAULT || t==TK_COLLATE ++ || t==TK_COMMA || t==TK_RP || t==TK_GENERATED || t==TK_AS ++ ){ ++ t = TK_CHECK; ++ }else{ ++ iOff += nTok; ++ iOff += getConstraint(&zSql[iOff]); ++ } ++ ++ if( cmp==0 || (iNotNull>=0 && t==TK_NOT) ){ ++ if( t!=TK_NOT && t!=TK_CHECK ){ ++ errorMPrintf(ctx, "constraint may not be dropped: %s", zCons); ++ return; ++ } ++ iEnd = iOff; ++ break; ++ } ++ ++ }else if( t==TK_NOT && iNotNull==ii ){ ++ iEnd = iOff + getConstraint(&zSql[iOff]); ++ break; ++ }else if( t==TK_RP || t==TK_ILLEGAL ){ ++ iEnd = -1; ++ break; ++ }else if( t==TK_COMMA ){ ++ break; ++ } ++ } ++ } ++ ++ /* If the constraint has not been found it is an error. */ ++ if( iEnd<=0 ){ ++ if( zCons ){ ++ errorMPrintf(ctx, "no such constraint: %s", zCons); ++ }else{ ++ /* SQLite follows postgres in that a DROP NOT NULL on a column that is ++ ** not NOT NULL is not an error. So just return the original SQL here. */ ++ sqlite3_result_text(ctx, (const char*)zSql, -1, SQLITE_TRANSIENT); ++ } ++ }else{ ++ ++ /* Figure out if an extra space should be inserted after the constraint ++ ** is removed. And if an additional comma preceding the constraint ++ ** should be removed. */ ++ const char *zSpace = " "; ++ iEnd += getWhitespace(&zSql[iEnd]); ++ sqlite3GetToken(&zSql[iEnd], &t); ++ if( t==TK_RP || t==TK_COMMA ){ ++ zSpace = ""; ++ if( zSql[iStart-1]==',' ) iStart--; ++ } ++ ++ db = sqlite3_context_db_handle(ctx); ++ zNew = sqlite3MPrintf(db, "%.*s%s%s", iStart, zSql, zSpace, &zSql[iEnd]); ++ sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC); ++ } ++} ++ ++/* ++** Internal SQL function: ++** ++** sqlite_add_constraint(SQL, CONSTRAINT-TEXT, ICOL) ++** ++** SQL is a CREATE TABLE statement. Return a modified version of ++** SQL that adds CONSTRAINT-TEXT at the end of the ICOL-th column ++** definition. (The left-most column defintion is 0.) ++*/ ++static void addConstraintFunc( ++ sqlite3_context *ctx, ++ int NotUsed, ++ sqlite3_value **argv ++){ ++ const u8 *zSql = sqlite3_value_text(argv[0]); ++ const char *zCons = (const char*)sqlite3_value_text(argv[1]); ++ int iCol = sqlite3_value_int(argv[2]); ++ int iOff = 0; ++ int ii; ++ char *zNew = 0; ++ int t = 0; ++ sqlite3 *db; ++ UNUSED_PARAMETER(NotUsed); ++ ++ if( skipCreateTable(ctx, zSql, &iOff) ) return; ++ ++ for(ii=0; ii<=iCol || (iCol<0 && t!=TK_RP); ii++){ ++ iOff += getConstraintToken(&zSql[iOff], &t); ++ while( 1 ){ ++ int nTok = getConstraintToken(&zSql[iOff], &t); ++ if( t==TK_COMMA || t==TK_RP ) break; ++ if( t==TK_ILLEGAL ){ ++ sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT); ++ return; ++ } ++ iOff += nTok; ++ } ++ } ++ ++ iOff += getWhitespace(&zSql[iOff]); ++ ++ db = sqlite3_context_db_handle(ctx); ++ if( iCol<0 ){ ++ zNew = sqlite3MPrintf(db, "%.*s, %s%s", iOff, zSql, zCons, &zSql[iOff]); ++ }else{ ++ zNew = sqlite3MPrintf(db, "%.*s %s%s", iOff, zSql, zCons, &zSql[iOff]); ++ } ++ sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC); ++} ++ ++/* ++** Find a column named pCol in table pTab. If successful, set output ++** parameter *piCol to the index of the column in the table and return ++** SQLITE_OK. Otherwise, set *piCol to -1 and return an SQLite error ++** code. ++*/ ++static int alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol){ ++ sqlite3 *db = pParse->db; ++ char *zName = sqlite3NameFromToken(db, pCol); ++ int rc = SQLITE_NOMEM; ++ int iCol = -1; ++ ++ if( zName ){ ++ iCol = sqlite3ColumnIndex(pTab, zName); ++ if( iCol<0 ){ ++ sqlite3ErrorMsg(pParse, "no such column: %s", zName); ++ rc = SQLITE_ERROR; ++ }else{ ++ rc = SQLITE_OK; ++ } ++ } ++ ++#ifndef SQLITE_OMIT_AUTHORIZATION ++ if( rc==SQLITE_OK ){ ++ const char *zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; ++ const char *zCol = pTab->aCol[iCol].zCnName; ++ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ ++ pTab = 0; ++ } ++ } ++#endif ++ ++ sqlite3DbFree(db, zName); ++ *piCol = iCol; ++ return rc; ++} ++ ++ ++/* ++** Find the table named by the first entry in source list pSrc. If successful, ++** return a pointer to the Table structure and set output variable (*pzDb) ++** to point to the name of the database containin the table (i.e. "main", ++** "temp" or the name of an attached database). ++** ++** If the table cannot be located, return NULL. The value of the two output ++** parameters is undefined in this case. ++*/ ++static Table *alterFindTable( ++ Parse *pParse, /* Parsing context */ ++ SrcList *pSrc, /* Name of the table to look for */ ++ int *piDb, /* OUT: write the iDb here */ ++ const char **pzDb, /* OUT: write name of schema here */ ++ int bAuth /* Do ALTER TABLE authorization checks if true */ ++){ ++ sqlite3 *db = pParse->db; ++ Table *pTab = 0; ++ assert( sqlite3BtreeHoldsAllMutexes(db) ); ++ pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); ++ if( pTab ){ ++ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); ++ *pzDb = db->aDb[iDb].zDbSName; ++ *piDb = iDb; ++ ++ if( SQLITE_OK!=isRealTable(pParse, pTab, 2) ++ || SQLITE_OK!=isAlterableTable(pParse, pTab) ++ ){ ++ pTab = 0; ++ } ++ } ++#ifndef SQLITE_OMIT_AUTHORIZATION ++ if( pTab && bAuth ){ ++ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, *pzDb, pTab->zName, 0) ){ ++ pTab = 0; ++ } ++ } ++#endif ++ sqlite3SrcListDelete(db, pSrc); ++ return pTab; ++} ++ ++/* ++** Generate bytecode for one of: ++** ++** (1) ALTER TABLE pSrc DROP CONSTRAINT pCons ++** (2) ALTER TABLE pSrc ALTER pCol DROP NOT NULL ++** ++** One of pCons and pCol must be NULL and the other non-null. ++*/ ++SQLITE_PRIVATE void sqlite3AlterDropConstraint( ++ Parse *pParse, /* Parsing context */ ++ SrcList *pSrc, /* The table being altered */ ++ Token *pCons, /* Name of the constraint to drop */ ++ Token *pCol /* Name of the column from which to remove the NOT NULL */ ++){ ++ sqlite3 *db = pParse->db; ++ Table *pTab = 0; ++ int iDb = 0; ++ const char *zDb = 0; ++ char *zArg = 0; ++ ++ assert( (pCol==0)!=(pCons==0) ); ++ assert( pSrc->nSrc==1 ); ++ pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, pCons!=0); ++ if( !pTab ) return; ++ ++ if( pCons ){ ++ char *z = sqlite3NameFromToken(db, pCons); ++ zArg = sqlite3MPrintf(db, "%Q", z); ++ sqlite3DbFree(db, z); ++ }else{ ++ int iCol; ++ if( alterFindCol(pParse, pTab, pCol, &iCol) ) return; ++ zArg = sqlite3MPrintf(db, "%d", iCol); ++ } ++ ++ /* Edit the SQL for the named table. */ ++ sqlite3NestedParse(pParse, ++ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " ++ "sql = sqlite_drop_constraint(sql, %s) " ++ "WHERE type='table' AND tbl_name=%Q COLLATE nocase" ++ , zDb, zArg, pTab->zName ++ ); ++ sqlite3DbFree(db, zArg); ++ ++ /* Finally, reload the database schema. */ ++ renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); ++} ++ ++/* ++** The implementation of SQL function sqlite_fail(MSG). This takes a single ++** argument, and returns it as an error message with the error code set to ++** SQLITE_CONSTRAINT. ++*/ ++static void failConstraintFunc( ++ sqlite3_context *ctx, ++ int NotUsed, ++ sqlite3_value **argv ++){ ++ const char *zText = (const char*)sqlite3_value_text(argv[0]); ++ int err = sqlite3_value_int(argv[1]); ++ (void)NotUsed; ++ sqlite3_result_error(ctx, zText, -1); ++ sqlite3_result_error_code(ctx, err); ++} ++ ++/* ++** Buffer pCons, which is nCons bytes in size, contains the text of a ++** NOT NULL or CHECK constraint that will be inserted into a CREATE TABLE ++** statement. If successful, this function returns the size of the buffer in ++** bytes not including any trailing whitespace or "--" style comments. Or, ++** if an OOM occurs, it returns 0 and sets db->mallocFailed to true. ++** ++** C-style comments at the end are preserved. "--" style comments are ++** removed because the comment terminator might be \000, and we are about ++** to insert the pCons[] text into the middle of a larger string, and that ++** will have the effect of removing the comment terminator and messing up ++** the syntax. ++*/ ++static int alterRtrimConstraint( ++ sqlite3 *db, /* used to record OOM error */ ++ const char *pCons, /* Buffer containing constraint */ ++ int nCons /* Size of pCons in bytes */ ++){ ++ u8 *zTmp = (u8*)sqlite3MPrintf(db, "%.*s", nCons, pCons); ++ int iOff = 0; ++ int iEnd = 0; ++ ++ if( zTmp==0 ) return 0; ++ ++ while( 1 ){ ++ int t = 0; ++ int nToken = sqlite3GetToken(&zTmp[iOff], &t); ++ if( t==TK_ILLEGAL ) break; ++ if( t!=TK_SPACE && (t!=TK_COMMENT || zTmp[iOff]!='-') ){ ++ iEnd = iOff+nToken; ++ } ++ iOff += nToken; ++ } ++ ++ sqlite3DbFree(db, zTmp); ++ return iEnd; ++} ++ ++/* ++** Prepare a statement of the form: ++** ++** ALTER TABLE pSrc ALTER pCol SET NOT NULL ++*/ ++SQLITE_PRIVATE void sqlite3AlterSetNotNull( ++ Parse *pParse, /* Parsing context */ ++ SrcList *pSrc, /* Name of the table being altered */ ++ Token *pCol, /* Name of the column to add a NOT NULL constraint to */ ++ Token *pFirst /* The NOT token of the NOT NULL constraint text */ ++){ ++ Table *pTab = 0; ++ int iCol = 0; ++ int iDb = 0; ++ const char *zDb = 0; ++ const char *pCons = 0; ++ int nCons = 0; ++ ++ /* Look up the table being altered. */ ++ assert( pSrc->nSrc==1 ); ++ pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 0); ++ if( !pTab ) return; ++ ++ /* Find the column being altered. */ ++ if( alterFindCol(pParse, pTab, pCol, &iCol) ){ ++ return; ++ } ++ ++ /* Find the length in bytes of the constraint definition */ ++ pCons = pFirst->z; ++ nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); ++ ++ /* Search for a constraint violation. Throw an exception if one is found. */ ++ sqlite3NestedParse(pParse, ++ "SELECT sqlite_fail('constraint failed', %d) " ++ "FROM %Q.%Q AS x WHERE x.%.*s IS NULL", ++ SQLITE_CONSTRAINT, zDb, pTab->zName, (int)pCol->n, pCol->z ++ ); ++ ++ /* Edit the SQL for the named table. */ ++ sqlite3NestedParse(pParse, ++ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " ++ "sql = sqlite_add_constraint(sqlite_drop_constraint(sql, %d), %.*Q, %d) " ++ "WHERE type='table' AND tbl_name=%Q COLLATE nocase" ++ , zDb, iCol, nCons, pCons, iCol, pTab->zName ++ ); ++ ++ /* Finally, reload the database schema. */ ++ renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); ++} ++ ++/* ++** Implementation of internal SQL function: ++** ++** sqlite_find_constraint(SQL, CONSTRAINT-NAME) ++** ++** This function returns true if the SQL passed as the first argument is a ++** CREATE TABLE that contains a constraint with the name CONSTRAINT-NAME, ++** or false otherwise. ++*/ ++static void findConstraintFunc( ++ sqlite3_context *ctx, ++ int NotUsed, ++ sqlite3_value **argv ++){ ++ const u8 *zSql = 0; ++ const u8 *zCons = 0; ++ int iOff = 0; ++ int t = 0; ++ ++ (void)NotUsed; ++ zSql = sqlite3_value_text(argv[0]); ++ zCons = sqlite3_value_text(argv[1]); ++ ++ if( zSql==0 || zCons==0 ) return; ++ while( t!=TK_LP && t!=TK_ILLEGAL ){ ++ iOff += sqlite3GetToken(&zSql[iOff], &t); ++ } ++ ++ while( 1 ){ ++ iOff += getConstraintToken(&zSql[iOff], &t); ++ if( t==TK_CONSTRAINT ){ ++ int nTok = 0; ++ int cmp = 0; ++ iOff += getWhitespace(&zSql[iOff]); ++ nTok = getConstraintToken(&zSql[iOff], &t); ++ if( quotedCompare(ctx, t, &zSql[iOff], nTok, zCons, &cmp) ) return; ++ if( cmp==0 ){ ++ sqlite3_result_int(ctx, 1); ++ return; ++ } ++ }else if( t==TK_ILLEGAL ){ ++ break; ++ } ++ } ++ ++ sqlite3_result_int(ctx, 0); ++} ++ ++/* ++** Generate bytecode to implement: ++** ++** ALTER TABLE pSrc ADD [CONSTRAINT pName] CHECK(pExpr) ++** ++** Any "ON CONFLICT" text that occurs after the "CHECK(...)", up ++** until pParse->sLastToken, is included as part of the new constraint. ++*/ ++SQLITE_PRIVATE void sqlite3AlterAddConstraint( ++ Parse *pParse, /* Parse context */ ++ SrcList *pSrc, /* Table to add constraint to */ ++ Token *pFirst, /* First token of new constraint */ ++ Token *pName, /* Name of new constraint. NULL if name omitted. */ ++ const char *zExpr, /* Text of CHECK expression */ ++ int nExpr, /* Size of pExpr in bytes */ ++ Expr *pExpr /* The parsed CHECK expression */ ++){ ++ Table *pTab = 0; /* Table identified by pSrc */ ++ int iDb = 0; /* Which schema does pTab live in */ ++ const char *zDb = 0; /* Name of the schema in which pTab lives */ ++ const char *pCons = 0; /* Text of the constraint */ ++ int nCons; /* Bytes of text to use from pCons[] */ ++ int rc; /* Result from error checking pExpr */ ++ ++ /* Look up the table being altered. */ ++ assert( pSrc->nSrc==1 ); ++ pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1); ++ if( !pTab ){ ++ sqlite3ExprDelete(pParse->db, pExpr); ++ return; ++ } ++ ++ /* Verify that the new CHECK constraint does not contain any ++ ** internal-use-only function. Forum post 2026-05-10T01:11:28Z ++ */ ++ rc = sqlite3ResolveSelfReference(pParse, pTab, NC_IsCheck, pExpr, 0); ++ sqlite3ExprDelete(pParse->db, pExpr); ++ if( rc ) return; ++ ++ /* If this new constraint has a name, check that it is not a duplicate of ++ ** an existing constraint. It is an error if it is. */ ++ if( pName ){ ++ char *zName = sqlite3NameFromToken(pParse->db, pName); ++ ++ sqlite3NestedParse(pParse, ++ "SELECT sqlite_fail('constraint %q already exists', %d) " ++ "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " ++ "WHERE type='table' AND tbl_name=%Q COLLATE nocase " ++ "AND sqlite_find_constraint(sql, %Q)", ++ zName, SQLITE_ERROR, zDb, pTab->zName, zName ++ ); ++ sqlite3DbFree(pParse->db, zName); ++ } ++ ++ /* Search for a constraint violation. Throw an exception if one is found. */ ++ sqlite3NestedParse(pParse, ++ "SELECT sqlite_fail('constraint failed', %d) " ++ "FROM %Q.%Q WHERE (%.*s) IS NOT TRUE", ++ SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, zExpr ++ ); ++ ++ /* Edit the SQL for the named table. */ ++ pCons = pFirst->z; ++ nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); ++ ++ sqlite3NestedParse(pParse, ++ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " ++ "sql = sqlite_add_constraint(sql, %.*Q, -1) " ++ "WHERE type='table' AND tbl_name=%Q COLLATE nocase" ++ , zDb, nCons, pCons, pTab->zName ++ ); ++ ++ /* Finally, reload the database schema. */ ++ renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); ++} ++ + /* + ** Register built-in functions used to help implement ALTER TABLE + */ +@@ -121461,6 +123617,10 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void){ + INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), + INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc), ++ INTERNAL_FUNCTION(sqlite_drop_constraint,2, dropConstraintFunc), ++ INTERNAL_FUNCTION(sqlite_fail, 2, failConstraintFunc), ++ INTERNAL_FUNCTION(sqlite_add_constraint, 3, addConstraintFunc), ++ INTERNAL_FUNCTION(sqlite_find_constraint,2, findConstraintFunc), + }; + sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); + } +@@ -123284,9 +125444,9 @@ static int loadStatTbl( + } + pIdx->nSampleCol = nIdxCol; + pIdx->mxSample = nSample; +- nByte = ROUND8(sizeof(IndexSample) * nSample); +- nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; +- nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ ++ nByte = ROUND8(sizeof64(IndexSample) * nSample); ++ nByte += sizeof64(tRowcnt) * nIdxCol * 3 * nSample; ++ nByte += nIdxCol * sizeof64(tRowcnt); /* Space for Index.aAvgEq[] */ + + pIdx->aSample = sqlite3DbMallocZero(db, nByte); + if( pIdx->aSample==0 ){ +@@ -123294,7 +125454,7 @@ static int loadStatTbl( + return SQLITE_NOMEM_BKPT; + } + pPtr = (u8*)pIdx->aSample; +- pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); ++ pPtr += ROUND8(nSample*sizeof64(pIdx->aSample[0])); + pSpace = (tRowcnt*)pPtr; + assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); + pIdx->aAvgEq = pSpace; pSpace += nIdxCol; +@@ -123591,6 +125751,16 @@ static void attachFunc( + ** from sqlite3_deserialize() to close database db->init.iDb and + ** reopen it as a MemDB */ + Btree *pNewBt = 0; ++ ++ pNew = &db->aDb[db->init.iDb]; ++ assert( pNew->pBt!=0 ); ++ if( sqlite3BtreeTxnState(pNew->pBt)!=SQLITE_TXN_NONE ++ || sqlite3BtreeIsInBackup(pNew->pBt) ++ ){ ++ rc = SQLITE_BUSY; ++ goto attach_error; ++ } ++ + pVfs = sqlite3_vfs_find("memdb"); + if( pVfs==0 ) return; + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); +@@ -123600,8 +125770,7 @@ static void attachFunc( + /* 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); ++ sqlite3BtreeClose(pNew->pBt); + pNew->pBt = pNewBt; + pNew->pSchema = pNewSchema; + }else{ +@@ -124081,7 +126250,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( + if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) + || sqlite3WalkExpr(&pFix->w, pStep->pWhere) + || sqlite3WalkExprList(&pFix->w, pStep->pExprList) +- || sqlite3FixSrcList(pFix, pStep->pFrom) ++ || sqlite3FixSrcList(pFix, pStep->pSrc) + ){ + return 1; + } +@@ -124188,7 +126357,7 @@ SQLITE_API int sqlite3_set_authorizer( + sqlite3_mutex_enter(db->mutex); + db->xAuth = (sqlite3_xauth)xAuth; + db->pAuthArg = pArg; +- if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1); ++ sqlite3ExpirePreparedStatements(db, 1); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } +@@ -124859,6 +127028,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( + const char *zDb; + if( p->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); ++ assert( iDb>=0 && iDbdb->nDb ); + zDb = pParse->db->aDb[iDb].zDbSName; + }else{ + assert( !p->fg.isSubquery ); +@@ -126432,8 +128602,8 @@ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ + ** The estimate is conservative. It might be larger that what is + ** really needed. + */ +-static int identLength(const char *z){ +- int n; ++static i64 identLength(const char *z){ ++ i64 n; + for(n=0; *z; n++, z++){ + if( *z=='"' ){ n++; } + } +@@ -126866,9 +129036,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + if( !hasColumn(pPk->aiColumn, j, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 + ){ ++ const char *zColl = sqlite3ColumnColl(&pTab->aCol[i]); + assert( jnColumn ); + pPk->aiColumn[j] = i; +- pPk->azColl[j] = sqlite3StrBINARY; ++ pPk->azColl[j] = zColl ? zColl : sqlite3StrBINARY; + j++; + } + } +@@ -126943,13 +129114,14 @@ SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){ + ** 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 */ ++ const char *zTail; /* Pointer to the last "_" in zName */ + Table *pTab; /* Table that zName is a shadow of */ ++ char *zCopy; + zTail = strrchr(zName, '_'); + if( zTail==0 ) return 0; +- *zTail = 0; +- pTab = sqlite3FindTable(db, zName, 0); +- *zTail = '_'; ++ zCopy = sqlite3DbStrNDup(db, zName, (int)(zTail-zName)); ++ pTab = zCopy ? sqlite3FindTable(db, zCopy, 0) : 0; ++ sqlite3DbFree(db, zCopy); + if( pTab==0 ) return 0; + if( !IsVirtual(pTab) ) return 0; + return sqlite3IsShadowTableOf(db, pTab, zName); +@@ -127102,6 +129274,7 @@ SQLITE_PRIVATE void sqlite3EndTable( + convertToWithoutRowidTable(pParse, p); + } + iDb = sqlite3SchemaToIndex(db, p->pSchema); ++ assert( iDb>=0 && iDb<=db->nDb ); + + #ifndef SQLITE_OMIT_CHECK + /* Resolve names in all CHECK constraint expressions. +@@ -127397,6 +129570,7 @@ SQLITE_PRIVATE void sqlite3CreateView( + + sqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3SchemaToIndex(db, p->pSchema); ++ assert( iDb>=0 && iDbnDb ); + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); + if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; + +@@ -128993,6 +131167,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists + goto exit_drop_index; + } + iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); ++ assert( iDb>=0 && iDbnDb ); + #ifndef SQLITE_OMIT_AUTHORIZATION + { + int code = SQLITE_DROP_INDEX; +@@ -129890,8 +132065,7 @@ SQLITE_PRIVATE void sqlite3RowidConstraint( + } + + /* +-** Check to see if pIndex uses the collating sequence pColl. Return +-** true if it does and false if it does not. ++** Return true if any column of pIndex uses the zColl collation + */ + #ifndef SQLITE_OMIT_REINDEX + static int collationMatch(const char *zColl, Index *pIndex){ +@@ -129899,8 +132073,8 @@ static int collationMatch(const char *zColl, Index *pIndex){ + 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) ){ ++ assert( z!=0 ); ++ if( 0==sqlite3StrICmp(z, zColl) ){ + return 1; + } + } +@@ -129908,73 +132082,39 @@ static int collationMatch(const char *zColl, Index *pIndex){ + } + #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 ++** REINDEX ?.? -- 3 ++** REINDEX ?.? -- 4 ++** REINDEX EXPRESSIONS -- 5 + ** +-** Form 1 causes all indices in all attached databases to be rebuilt. +-** Form 2 rebuilds all indices in all databases that use the named ++** Form 1 causes all indexes in all attached databases to be rebuilt. ++** Form 2 rebuilds all indexes 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. ++** indexes associated with the named table, respectively. Form 5 ++** rebuilds all expression indexes in addition to all collations, ++** indexes, or tables named "EXPRESSIONS". ++** ++** If the name is ambiguous such that it matches two or more of ++** forms 2 through 5, then rebuild the union of all matching indexes, ++** taken care to avoid rebuilding the same index more than once. + */ + #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 */ ++ char *z = 0; /* Name of a table or index or collation */ ++ const char *zDb = 0; /* Name of the database */ ++ int iReDb = -1; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ ++ int bMatch = 0; /* At least one name match */ ++ const char *zColl = 0; /* Rebuild indexes using this collation */ ++ Table *pReTab = 0; /* Rebuild all indexes of this table */ ++ Index *pReIndex = 0; /* Rebuild this index */ ++ int isExprIdx = 0; /* Rebuild all expression indexes */ ++ int bAll = 0; /* Rebuild all indexes */ + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ +@@ -129983,41 +132123,66 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + } + + if( pName1==0 ){ +- reindexDatabases(pParse, 0); +- return; ++ /* rebuild all indexes */ ++ bMatch = 1; ++ bAll = 1; + }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; ++ z = sqlite3NameFromToken(pParse->db, pName1); ++ if( z==0 ) return; ++ }else{ ++ iReDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); ++ if( iReDb<0 ) return; ++ z = sqlite3NameFromToken(db, pObjName); ++ if( z==0 ) return; ++ zDb = db->aDb[iReDb].zDbSName; ++ } ++ if( !bAll ){ ++ if( zDb==0 && sqlite3StrICmp(z, "expressions")==0 ){ ++ isExprIdx = 1; ++ bMatch = 1; ++ } ++ if( zDb==0 && sqlite3FindCollSeq(db, ENC(db), z, 0)!=0 ){ ++ zColl = z; ++ bMatch = 1; ++ } ++ if( zColl==0 && (pReTab = sqlite3FindTable(db, z, zDb))!=0 ){ ++ bMatch = 1; ++ } ++ if( zColl==0 && (pReIndex = sqlite3FindIndex(db, z, zDb))!=0 ){ ++ bMatch = 1; + } +- 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; ++ if( bMatch ){ ++ int iDb; ++ HashElem *k; ++ Table *pTab; ++ Index *pIdx; ++ Db *pDb; ++ for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ ++ assert( pDb!=0 ); ++ if( iReDb>=0 && iReDb!=iDb ) continue; ++ for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ ++ pTab = (Table*)sqliteHashData(k); ++ if( IsVirtual(pTab) ) continue; ++ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ ++ if( bAll ++ || pTab==pReTab ++ || pIdx==pReIndex ++ || (isExprIdx && pIdx->bHasExpr) ++ || (zColl!=0 && collationMatch(zColl,pIdx)) ++ ){ ++ sqlite3BeginWriteOperation(pParse, 0, iDb); ++ sqlite3RefillIndex(pParse, pIdx, -1); ++ } ++ } /* End loop over indexes of pTab */ ++ } /* End loop over tables of iDb */ ++ } /* End loop over databases */ ++ }else{ ++ sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); + } +- 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"); ++ return; + } + #endif + +@@ -130827,7 +132992,7 @@ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS + ** virtual tables if PRAGMA trusted_schema=ON. + */ +- if( pParse->pToplevel!=0 ++ if( (pParse->pToplevel!=0 || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL)) + && pTab->u.vtab.p->eVtabRisk > + ((pParse->db->flags & SQLITE_TrustedSchema)!=0) + ){ +@@ -131664,8 +133829,9 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( + 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 */ ++ pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn ++ ); ++ sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + pPrior = pIdx; + } +@@ -132100,9 +134266,18 @@ static void printfFunc( + 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); ++ if( str.accError==SQLITE_OK ){ ++ n = str.nChar; ++ sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, ++ SQLITE_DYNAMIC); ++ }else{ ++ if( str.accError==SQLITE_NOMEM ){ ++ sqlite3_result_error_nomem(context); ++ }else{ ++ sqlite3_result_error_toobig(context); ++ } ++ sqlite3_str_reset(&str); ++ } + } + } + +@@ -132240,7 +134415,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + sqlite3_result_error_nomem(context); + return; + } +- sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); ++ sqlite3AtoF(zBuf, &r); + sqlite3_free(zBuf); + } + sqlite3_result_double(context, r); +@@ -132872,18 +135047,11 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int + + 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); +- } +- } ++ /* ,--- Show infinity as 9.0e+999 ++ ** | ++ ** | ,--- 17 precision guarantees round-trip ++ ** v v */ ++ sqlite3_str_appendf(pStr, "%!0.17g", sqlite3_value_double(pValue)); + break; + } + case SQLITE_INTEGER: { +@@ -132975,7 +135143,7 @@ static void unistrFunc( + } + i = j = 0; + while( icnt>0 ); + p->cnt--; + if( !p->approx ){ +- if( sqlite3SubInt64(&p->iSum, sqlite3_value_int64(argv[0])) ){ +- p->ovrfl = 1; +- p->approx = 1; ++ i64 x = p->iSum; ++ if( sqlite3SubInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ ++ p->iSum = x; ++ return; + } +- }else if( type==SQLITE_INTEGER ){ ++ p->ovrfl = 1; ++ p->approx = 1; ++ kahanBabuskaNeumaierInit(p, p->iSum); ++ } ++ if( type==SQLITE_INTEGER ){ + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal!=SMALLEST_INT64 ){ + kahanBabuskaNeumaierStepInt64(p, -iVal); +@@ -134138,6 +136311,8 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) + sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, + 0, 0, 0, 0, 0); + pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); ++ assert( pDef!=0 ); /* The sqlite3CreateFunc() call above cannot fail ++ ** because the "like" SQL-function already exists */ + pDef->funcFlags |= flags; + pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; + } +@@ -134722,47 +136897,46 @@ static void percentSort(double *a, unsigned int n){ + int i; /* Loop counter */ + double rPivot; /* The pivot value */ + +- assert( n>=2 ); +- if( a[0]>a[n-1] ){ +- SWAP_DOUBLE(a[0],a[n-1]) +- } +- if( n==2 ) return; +- iGt = n-1; +- i = n/2; +- if( a[0]>a[i] ){ +- SWAP_DOUBLE(a[0],a[i]) +- }else if( a[i]>a[iGt] ){ +- SWAP_DOUBLE(a[i],a[iGt]) +- } +- if( n==3 ) return; +- rPivot = a[i]; +- iLt = i = 1; +- do{ +- if( a[i]iLt ) SWAP_DOUBLE(a[i],a[iLt]) +- iLt++; +- i++; +- }else if( a[i]>rPivot ){ +- do{ +- iGt--; +- }while( iGt>i && a[iGt]>rPivot ); ++ while( n>=2 ){ ++ if( a[0]>a[n-1] ){ ++ SWAP_DOUBLE(a[0],a[n-1]) ++ } ++ if( n==2 ) return; ++ iGt = n-1; ++ i = n/2; ++ if( a[0]>a[i] ){ ++ SWAP_DOUBLE(a[0],a[i]) ++ }else if( a[i]>a[iGt] ){ + SWAP_DOUBLE(a[i],a[iGt]) ++ } ++ if( n==3 ) return; ++ rPivot = a[i]; ++ iLt = i = 1; ++ do{ ++ if( a[i]iLt ) SWAP_DOUBLE(a[i],a[iLt]) ++ iLt++; ++ i++; ++ }else if( a[i]>rPivot ){ ++ do{ ++ iGt--; ++ }while( iGt>i && a[iGt]>rPivot ); ++ SWAP_DOUBLE(a[i],a[iGt]) ++ }else{ ++ i++; ++ } ++ }while( i(int)(n/2) ){ ++ if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); ++ n = iLt; + }else{ +- i++; ++ if( iLt>=2 ) percentSort(a, iLt); ++ a += iGt; ++ n -= iGt; + } +- }while( i=2 ) percentSort(a, iLt); +- if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); +- +-/* Uncomment for testing */ +-#if 0 +- for(i=0; istep_list; ++ sqlite3SrcListDelete(dbMem, pStep->pSrc); + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); +@@ -136145,6 +138320,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( + if( !IsOrdinaryTable(pTab) ) return; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); ++ assert( iDb>=00 && iDbnDb ); + zDb = db->aDb[iDb].zDbSName; + + /* Loop through all the foreign key constraints for which pTab is the +@@ -136562,7 +138738,6 @@ static Trigger *fkActionTrigger( + nFrom = sqlite3Strlen30(zFrom); + + if( action==OE_Restrict ){ +- int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + SrcList *pSrc; + Expr *pRaise; + +@@ -136573,10 +138748,10 @@ static Trigger *fkActionTrigger( + } + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc ){ +- assert( pSrc->nSrc==1 ); +- pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); +- assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); +- pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); ++ SrcItem *pItem = &pSrc->a[0]; ++ pItem->zName = sqlite3DbStrDup(db, zFrom); ++ pItem->fg.fixedSchema = 1; ++ pItem->u4.pSchema = pTab->pSchema; + } + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), +@@ -136592,14 +138767,17 @@ static Trigger *fkActionTrigger( + + pTrigger = (Trigger *)sqlite3DbMallocZero(db, + sizeof(Trigger) + /* struct Trigger */ +- sizeof(TriggerStep) + /* Single step in trigger program */ +- nFrom + 1 /* Space for pStep->zTarget */ ++ sizeof(TriggerStep) /* Single step in trigger program */ + ); + if( pTrigger ){ + pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; +- pStep->zTarget = (char *)&pStep[1]; +- memcpy((char *)pStep->zTarget, zFrom, nFrom); +- ++ pStep->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); ++ if( pStep->pSrc ){ ++ SrcItem *pItem = &pStep->pSrc->a[0]; ++ pItem->zName = sqlite3DbStrNDup(db, zFrom, nFrom); ++ pItem->u4.pSchema = pTab->pSchema; ++ pItem->fg.fixedSchema = 1; ++ } + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); +@@ -140656,7 +142834,11 @@ struct sqlite3_api_routines { + /* Version 3.51.0 and later */ + int (*set_errmsg)(sqlite3*,int,const char*); + int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); +- ++ /* Version 3.52.0 and later */ ++ void (*str_truncate)(sqlite3_str*,int); ++ void (*str_free)(sqlite3_str*); ++ int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*)); ++ int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*); + }; + + /* +@@ -140995,6 +143177,11 @@ typedef int (*sqlite3_loadext_entry)( + /* Version 3.51.0 and later */ + #define sqlite3_set_errmsg sqlite3_api->set_errmsg + #define sqlite3_db_status64 sqlite3_api->db_status64 ++/* Version 3.52.0 and later */ ++#define sqlite3_str_truncate sqlite3_api->str_truncate ++#define sqlite3_str_free sqlite3_api->str_free ++#define sqlite3_carray_bind sqlite3_api->carray_bind ++#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2 + #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + + #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) +@@ -141521,7 +143708,17 @@ static const sqlite3_api_routines sqlite3Apis = { + sqlite3_setlk_timeout, + /* Version 3.51.0 and later */ + sqlite3_set_errmsg, +- sqlite3_db_status64 ++ sqlite3_db_status64, ++ /* Version 3.52.0 and later */ ++ sqlite3_str_truncate, ++ sqlite3_str_free, ++#ifdef SQLITE_ENABLE_CARRAY ++ sqlite3_carray_bind, ++ sqlite3_carray_bind_v2 ++#else ++ 0, ++ 0 ++#endif + }; + + /* True if x is the directory separator character +@@ -141623,33 +143820,42 @@ static int sqlite3LoadExtension( + ** entry point name "sqlite3_extension_init" was not found, then + ** construct an entry point name "sqlite3_X_init" where the X is + ** replaced by the lowercase value of every ASCII alphabetic +- ** character in the filename after the last "/" upto the first ".", +- ** and eliding the first three characters if they are "lib". ++ ** character in the filename after the last "/" up to the first ".", ++ ** and skipping the first three characters if they are "lib". + ** Examples: + ** + ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init ++ ** ++ ** If that still finds no entry point, repeat a second time but this ++ ** time include both alphabetic and numeric characters up to the first ++ ** ".". Example: ++ ** ++ ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example5_init + */ + if( xInit==0 && zProc==0 ){ + int iFile, iEntry, c; + int ncFile = sqlite3Strlen30(zFile); ++ int cnt = 0; + 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]; ++ do{ ++ 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) || (cnt && sqlite3Isdigit(c)) ){ ++ zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; ++ } + } +- } +- memcpy(zAltEntry+iEntry, "_init", 6); +- zEntry = zAltEntry; +- xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); ++ memcpy(zAltEntry+iEntry, "_init", 6); ++ zEntry = zAltEntry; ++ xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); ++ }while( xInit==0 && (++cnt)<2 ); + } + if( xInit==0 ){ + if( pzErrMsg ){ +@@ -144659,8 +146865,20 @@ SQLITE_PRIVATE void sqlite3Pragma( + 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, ++ sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + pIdx->nColumn); VdbeCoverage(v); ++ jmp2 = sqlite3VdbeAddOp3(v, OP_IFindKey, iIdxCur+j, ckUniq, r1); ++ VdbeCoverage(v); ++ sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX); ++ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, ++ sqlite3MPrintf(db, "index %s stores an imprecise floating-point " ++ "value for row ", pIdx->zName), ++ P4_DYNAMIC); ++ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); ++ integrityCheckResultRow(v); ++ sqlite3VdbeAddOp2(v, OP_Goto, 0, ckUniq); ++ ++ sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " missing from index "); +@@ -144668,7 +146886,7 @@ SQLITE_PRIVATE void sqlite3Pragma( + jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp4 = integrityCheckResultRow(v); +- sqlite3VdbeJumpHere(v, jmp2); ++ sqlite3VdbeResolveLabel(v, ckUniq); + + /* The OP_IdxRowid opcode is an optimized version of OP_Column + ** that extracts the rowid off the end of the index record. +@@ -145721,7 +147939,8 @@ static void corruptSchema( + static const char *azAlterType[] = { + "rename", + "drop column", +- "add column" ++ "add column", ++ "drop constraint" + }; + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], +@@ -146804,7 +149023,7 @@ SQLITE_API int sqlite3_prepare16_v3( + */ + typedef struct DistinctCtx DistinctCtx; + struct DistinctCtx { +- u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */ ++ u8 isTnct; /* 0: Not distinct. 1: DISTINCT 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 */ +@@ -146934,8 +149153,6 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( + 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, SZ_SRCLIST_1); + pNew->pSrc = pSrc; +@@ -147444,6 +149661,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ + pRight->fg.isOn = 1; + p->selFlags |= SF_OnToWhere; + } ++ ++ if( IsVirtual(pRightTab) && joinType==EP_OuterON && pRight->u1.pFuncArg ){ ++ p->selFlags |= SF_OnToWhere; ++ } + } + return 0; + } +@@ -148083,29 +150304,6 @@ static void selectInnerLoop( + } + + 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: +@@ -149218,8 +151416,8 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( + } + } + if( zType ){ +- const i64 k = sqlite3Strlen30(zType); +- n = sqlite3Strlen30(pCol->zCnName); ++ const i64 k = strlen(zType); ++ n = strlen(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2); + pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); + if( pCol->zCnName ){ +@@ -149245,6 +151443,13 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c + sqlite3 *db = pParse->db; + u64 savedFlags; + ++ pParse->nNestSel++; ++#if SQLITE_MAX_EXPR_DEPTH>0 ++ if( pParse->nNestSel >= db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){ ++ sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep"); ++ return 0; ++ } ++#endif + savedFlags = db->flags; + db->flags &= ~(u64)SQLITE_FullColNames; + db->flags |= SQLITE_ShortColNames; +@@ -149266,6 +151471,8 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c + sqlite3DeleteTable(db, pTab); + return 0; + } ++ pParse->nNestSel--; ++ assert( pParse->nNestSel>=0 ); + return pTab; + } + +@@ -149392,9 +151599,9 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ + ** function is responsible for ensuring that this structure is eventually + ** freed. + */ +-static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ ++static KeyInfo *multiSelectByMergeKeyInfo(Parse *pParse, Select *p, int nExtra){ + ExprList *pOrderBy = p->pOrderBy; +- int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0; ++ int nOrderBy = (pOrderBy!=0) ? pOrderBy->nExpr : 0; + sqlite3 *db = pParse->db; + KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); + if( pRet ){ +@@ -149527,7 +151734,7 @@ static void generateWithRecursiveQuery( + regCurrent = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + if( pOrderBy ){ +- KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); ++ KeyInfo *pKeyInfo = multiSelectByMergeKeyInfo(pParse, p, 1); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, + (char*)pKeyInfo, P4_KEYINFO); + destQueue.pOrderBy = pOrderBy; +@@ -149536,8 +151743,28 @@ static void generateWithRecursiveQuery( + } + VdbeComment((v, "Queue table")); + if( iDistinct ){ +- p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); +- p->selFlags |= SF_UsesEphemeral; ++ /* Generate an ephemeral table used to enforce distinctness on the ++ ** output of the recursive part of the CTE. ++ */ ++ KeyInfo *pKeyInfo; /* Collating sequence for the result set */ ++ CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ ++ ++ assert( p->pNext==0 ); ++ assert( p->pEList!=0 ); ++ nCol = p->pEList->nExpr; ++ pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nCol, 1); ++ if( pKeyInfo ){ ++ for(i=0, apColl=pKeyInfo->aColl; idb->pDfltColl; ++ } ++ } ++ sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iDistinct, nCol, 0, ++ (void*)pKeyInfo, P4_KEYINFO); ++ }else{ ++ assert( pParse->nErr>0 ); ++ } + } + + /* Detach the ORDER BY clause from the compound SELECT */ +@@ -149612,7 +151839,7 @@ end_of_recursive_query: + #endif /* SQLITE_OMIT_CTE */ + + /* Forward references */ +-static int multiSelectOrderBy( ++static int multiSelectByMerge( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +@@ -149761,12 +151988,26 @@ static int multiSelect( + 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{ ++ /* If the compound has an ORDER BY clause, then always use the merge ++ ** algorithm. */ ++ return multiSelectByMerge(pParse, p, pDest); ++ }else if( p->op!=TK_ALL ){ ++ /* If the compound is EXCEPT, INTERSECT, or UNION (anything other than ++ ** UNION ALL) then also always use the merge algorithm. However, the ++ ** multiSelectByMerge() routine requires that the compound have an ++ ** ORDER BY clause, and it doesn't right now. So invent one first. */ ++ Expr *pOne = sqlite3ExprInt32(db, 1); ++ p->pOrderBy = sqlite3ExprListAppend(pParse, 0, pOne); ++ if( pParse->nErr ) goto multi_select_end; ++ assert( p->pOrderBy!=0 ); ++ p->pOrderBy->a[0].u.x.iOrderByCol = 1; ++ return multiSelectByMerge(pParse, p, pDest); ++ }else{ ++ /* For a UNION ALL compound without ORDER BY, simply run the left ++ ** query, then run the right query */ ++ int addr = 0; ++ int nLimit = 0; /* Initialize to suppress harmless compiler warning */ + + #ifndef SQLITE_OMIT_EXPLAIN + if( pPrior->pPrior==0 ){ +@@ -149774,300 +152015,49 @@ static int multiSelect( + 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, pParse) +- && 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; +- int emptyBypass = 0; /* IfEmpty opcode to bypass RHS */ +- 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; +- emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, unionTab); +- VdbeCoverage(v); +- }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); +- } +- if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass); +- 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, iLimit, iOffset; +- SelectDest intersectdest; +- int r1; +- int emptyBypass; +- +- /* 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; +- } +- +- /* Initialize LIMIT counters before checking to see if the LHS +- ** is empty, in case the jump is taken */ +- iBreak = sqlite3VdbeMakeLabel(pParse); +- computeLimitRegisters(pParse, p, iBreak); +- emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v); +- +- /* Code the current SELECT into temporary table "tab2" +- */ +- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); +- assert( p->addrOpenEphm[1] == -1 ); +- p->addrOpenEphm[1] = addr; +- +- /* Disable prior SELECTs and the LIMIT counters during the computation +- ** of the RHS select */ +- pLimit = p->pLimit; +- iLimit = p->iLimit; +- iOffset = p->iOffset; +- p->pPrior = 0; +- p->pLimit = 0; +- p->iLimit = 0; +- p->iOffset = 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); +- +- /* Reinstate the LIMIT counters prior to running the final intersect */ +- p->pLimit = pLimit; +- p->iLimit = iLimit; +- p->iOffset = iOffset; +- +- /* Generate code to take the intersection of the two temporary +- ** tables. +- */ +- if( rc ) break; +- assert( p->pEList ); +- sqlite3VdbeAddOp1(v, OP_Rewind, tab1); +- r1 = sqlite3GetTempReg(pParse); +- iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); +- iCont = sqlite3VdbeMakeLabel(pParse); +- 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); +- sqlite3VdbeJumpHere(v, emptyBypass); +- 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; ++ assert( !pPrior->pLimit ); ++ pPrior->iLimit = p->iLimit; ++ pPrior->iOffset = p->iOffset; ++ pPrior->pLimit = sqlite3ExprDup(db, p->pLimit, 0); ++ TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); ++ rc = sqlite3Select(pParse, pPrior, &dest); ++ sqlite3ExprDelete(db, pPrior->pLimit); ++ pPrior->pLimit = 0; ++ if( rc ){ + goto multi_select_end; + } +- for(i=0, apColl=pKeyInfo->aColl; ipDfltColl; +- } ++ 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, pParse) ++ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ++ ){ ++ p->nSelectRow = sqlite3LogEst((u64)nLimit); + } +- +- 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; +- } ++ if( addr ){ ++ sqlite3VdbeJumpHere(v, addr); ++ } ++#ifndef SQLITE_OMIT_EXPLAIN ++ if( p->pNext==0 ){ ++ ExplainQueryPlanPop(pParse); + } +- sqlite3KeyInfoUnref(pKeyInfo); ++#endif + } + + multi_select_end: +@@ -150099,8 +152089,8 @@ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ + ** 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 ++** The data to be output is contained in an array of pIn->nSdst registers ++** starting at register pIn->iSdst. pDest is where the output should + ** be sent. + ** + ** regReturn is the number of the register holding the subroutine +@@ -150129,6 +152119,8 @@ static int generateOutputSubroutine( + int iContinue; + int addr; + ++ assert( pIn->eDest==SRT_Coroutine ); ++ + addr = sqlite3VdbeCurrentAddr(v); + iContinue = sqlite3VdbeMakeLabel(pParse); + +@@ -150150,23 +152142,60 @@ static int generateOutputSubroutine( + */ + 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_Fifo: ++ case SRT_DistFifo: ++ case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); ++ int iParm = pDest->iSDParm; ++ testcase( pDest->eDest==SRT_Table ); ++ testcase( pDest->eDest==SRT_EphemTab ); ++ testcase( pDest->eDest==SRT_Fifo ); ++ testcase( pDest->eDest==SRT_DistFifo ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); +- sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); +- sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); ++#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( pDest->eDest==SRT_Table && pDest->iSDParm2 ){ ++ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); ++ } ++#endif ++#ifndef SQLITE_OMIT_CTE ++ if( pDest->eDest==SRT_DistFifo ){ ++ /* If the destination is DistFifo, then cursor (iParm+1) is open ++ ** on an ephemeral index that is used to enforce uniqueness on the ++ ** total result. At this point, we are processing the setup portion ++ ** of the recursive CTE using the merge algorithm, so the results are ++ ** guaranteed to be unique anyhow. But we still need to populate the ++ ** (iParm+1) cursor for use by the subsequent recursive phase. ++ */ ++ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1, ++ pIn->iSdst, pIn->nSdst); ++ } ++#endif ++ sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); ++ sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + 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, pDest->iSDParm); ++ /* The LIMIT clause will terminate the loop for us */ ++ break; ++ } ++ + #ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)". + */ +@@ -150213,9 +152242,51 @@ static int generateOutputSubroutine( + 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, ii; ++ ExprList *pSO; ++ int iParm = pDest->iSDParm; ++ pSO = pDest->pOrderBy; ++ assert( pSO ); ++ nKey = pSO->nExpr; ++ r1 = sqlite3GetTempReg(pParse); ++ r2 = sqlite3GetTempRange(pParse, nKey+2); ++ r3 = r2+nKey+1; ++ ++ sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r3); ++ if( pDest->eDest==SRT_DistQueue ){ ++ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); ++ } ++ for(ii=0; iiiSdst + pSO->a[ii].u.x.iOrderByCol - 1, ++ r2+ii); ++ } ++ sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); ++ sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); ++ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); ++ sqlite3ReleaseTempReg(pParse, r1); ++ sqlite3ReleaseTempRange(pParse, r2, nKey+2); ++ break; ++ } ++#endif /* SQLITE_OMIT_CTE */ ++ ++ /* Ignore the output */ ++ case SRT_Discard: { ++ 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. ++ ** 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 +@@ -150243,8 +152314,9 @@ static int generateOutputSubroutine( + } + + /* +-** Alternative compound select code generator for cases when there +-** is an ORDER BY clause. ++** Generate code for a compound SELECT statement using a merge ++** algorithm. The compound must have an ORDER BY clause for this ++** to work. + ** + ** We assume a query of the following form: + ** +@@ -150261,7 +152333,7 @@ static int generateOutputSubroutine( + ** + ** 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 ++** UNION ALL. EXCEPT and INTERSECT never output a row that + ** appears only in B.) + ** + ** AltB: Called when there is data from both coroutines and Au.x.iOrderByCol==i ) break; + } + if( j==nOrderBy ){ +- Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); ++ Expr *pNew = sqlite3ExprInt32(db, i); + 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; + } +@@ -150411,26 +152479,29 @@ static int multiSelectOrderBy( + } + + /* 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. ++ ** the permutation to determine if the next row of results comes ++ ** from selectA or selectB. Also add literal collations to the ++ ** ORDER BY clause terms so that when selectA and selectB are ++ ** evaluated, they use the correct collation. + */ + aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1)); + if( aPermute ){ + struct ExprList_item *pItem; ++ int bKeep = 0; + 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; ++ if( aPermute[i]!=(u32)i-1 ) bKeep = 1; ++ } ++ if( bKeep==0 ){ ++ sqlite3DbFreeNN(db, aPermute); ++ aPermute = 0; + } +- pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); +- }else{ +- pKeyMerge = 0; + } ++ pKeyMerge = multiSelectByMergeKeyInfo(pParse, p, 1); + + /* Allocate a range of temporary registers and the KeyInfo needed + ** for the logic that removes duplicate result rows when the +@@ -150509,7 +152580,7 @@ static int multiSelectOrderBy( + */ + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); +- VdbeComment((v, "left SELECT")); ++ VdbeComment((v, "SUBR: next-A")); + pPrior->iLimit = regLimitA; + ExplainQueryPlan((pParse, 1, "LEFT")); + sqlite3Select(pParse, pPrior, &destA); +@@ -150521,7 +152592,7 @@ static int multiSelectOrderBy( + */ + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); +- VdbeComment((v, "right SELECT")); ++ VdbeComment((v, "SUBR: next-B")); + savedLimit = p->iLimit; + savedOffset = p->iOffset; + p->iLimit = regLimitB; +@@ -150535,7 +152606,7 @@ static int multiSelectOrderBy( + /* 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")); ++ VdbeNoopComment((v, "SUBR: out-A")); + addrOutA = generateOutputSubroutine(pParse, + p, &destA, pDest, regOutA, + regPrev, pKeyDup, labelEnd); +@@ -150544,7 +152615,7 @@ static int multiSelectOrderBy( + ** select as the next output row of the compound select. + */ + if( op==TK_ALL || op==TK_UNION ){ +- VdbeNoopComment((v, "Output routine for B")); ++ VdbeNoopComment((v, "SUBR: out-B")); + addrOutB = generateOutputSubroutine(pParse, + p, &destB, pDest, regOutB, + regPrev, pKeyDup, labelEnd); +@@ -150557,10 +152628,12 @@ static int multiSelectOrderBy( + if( op==TK_EXCEPT || op==TK_INTERSECT ){ + addrEofA_noB = addrEofA = labelEnd; + }else{ +- VdbeNoopComment((v, "eof-A subroutine")); ++ VdbeNoopComment((v, "SUBR: eof-A")); + addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); ++ VdbeComment((v, "out-B")); + addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); + VdbeCoverage(v); ++ VdbeComment((v, "next-B")); + sqlite3VdbeGoto(v, addrEofA); + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + } +@@ -150572,17 +152645,20 @@ static int multiSelectOrderBy( + addrEofB = addrEofA; + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + }else{ +- VdbeNoopComment((v, "eof-B subroutine")); ++ VdbeNoopComment((v, "SUBR: eof-B")); + addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); ++ VdbeComment((v, "out-A")); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); ++ VdbeComment((v, "next-A")); + 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); ++ VdbeComment((v, "out-B")); ++ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); ++ VdbeComment((v, "next-B")); ++ sqlite3VdbeGoto(v, labelCmpr); ++ }else{ ++ addrAgtB++; /* Just do next-B. Might as well use the next-B call ++ ** in the next code block */ + } +- 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); ++ VdbeComment((v, "next-A")); ++ /* v--- Also the A>B case for EXCEPT and INTERSECT */ + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); ++ VdbeComment((v, "next-B")); + + /* Implement the main merge loop + */ ++ if( aPermute!=0 ){ ++ sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); ++ } + 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); ++ if( aPermute!=0 ){ ++ sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); ++ } ++ sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); ++ VdbeCoverageIf(v, op==TK_ALL); ++ VdbeCoverageIf(v, op==TK_UNION); ++ VdbeCoverageIf(v, op==TK_EXCEPT); ++ VdbeCoverageIf(v, op==TK_INTERSECT); + + /* Jump to the this point in order to terminate the query. + */ +@@ -151539,7 +153627,7 @@ static int flattenSubquery( + } + pSubitem->fg.jointype |= jointype; + +- /* Now begin substituting subquery result set expressions for ++ /* Begin substituting subquery result set expressions for + ** references to the iParent in the outer query. + ** + ** Example: +@@ -151551,7 +153639,7 @@ static int flattenSubquery( + ** 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 ){ ++ if( pSub->pOrderBy ){ + /* 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 +@@ -151559,9 +153647,9 @@ static int flattenSubquery( + ** 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]. */ ++ ** function attempts to flatten a compound sub-query into pParent. ++ ** See ticket [d11a6e908f]. ++ */ + ExprList *pOrderBy = pSub->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; +@@ -152179,6 +154267,16 @@ static int pushDownWhereTerms( + x.pEList = pSubq->pEList; + x.pCList = findLeftmostExprlist(pSubq); + pNew = substExpr(&x, pNew); ++ assert( pNew!=0 || pParse->nErr!=0 ); ++ if( pParse->nErr==0 && pNew->op==TK_IN && ExprUseXSelect(pNew) ){ ++ assert( pNew->x.pSelect!=0 ); ++ pNew->x.pSelect->selFlags |= SF_ClonedRhsIn; ++ assert( pWhere!=0 ); ++ assert( pWhere->op==TK_IN ); ++ assert( ExprUseXSelect(pWhere) ); ++ assert( pWhere->x.pSelect!=0 ); ++ pWhere->x.pSelect->selFlags |= SF_ClonedRhsIn; ++ } + #ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ + /* Restriction 6c has prevented push-down in this case */ +@@ -152413,14 +154511,14 @@ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ + ** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) + ** ORDER BY ... COLLATE ... + ** +-** This transformation is necessary because the multiSelectOrderBy() routine ++** This transformation is necessary because the multiSelectByMerge() 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://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 ++** The UNION ALL operator works fine with multiSelectByMerge() even when + ** there are COLLATE terms in the ORDER BY. + */ + static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ +@@ -152966,7 +155064,7 @@ static int selectExpander(Walker *pWalker, Select *p){ + } + #ifndef SQLITE_OMIT_VIRTUALTABLE + else if( ALWAYS(IsVirtual(pTab)) +- && pFrom->fg.fromDDL ++ && (pFrom->fg.fromDDL || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL)) + && ALWAYS(pTab->u.vtab.p!=0) + && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + ){ +@@ -153919,7 +156017,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ + && pExpr->pAggInfo==0 + ){ + sqlite3 *db = pWalker->pParse->db; +- Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); ++ Expr *pNew = sqlite3ExprInt32(db, 1); + if( pNew ){ + Expr *pWhere = pS->pWhere; + SWAP(Expr, *pNew, *pExpr); +@@ -154237,6 +156335,7 @@ static SQLITE_NOINLINE void existsToJoin( + && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) + && ALWAYS(p->pSrc!=0) + && p->pSrc->nSrcpLimit==0 || p->pLimit->pRight==0) + ){ + if( pWhere->op==TK_AND ){ + Expr *pRight = pWhere->pRight; +@@ -154270,7 +156369,6 @@ static SQLITE_NOINLINE void existsToJoin( + ExprSetProperty(pWhere, EP_IntValue); + assert( p->pWhere!=0 ); + pSub->pSrc->a[0].fg.fromExists = 1; +- pSub->pSrc->a[0].fg.jointype |= JT_CROSS; + p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); + if( pSubWhere ){ + p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere); +@@ -154285,7 +156383,6 @@ static SQLITE_NOINLINE void existsToJoin( + sqlite3TreeViewSelect(0, p, 0); + } + #endif +- existsToJoin(pParse, p, pSubWhere); + } + } + } +@@ -154298,6 +156395,7 @@ typedef struct CheckOnCtx CheckOnCtx; + struct CheckOnCtx { + SrcList *pSrc; /* SrcList for this context */ + int iJoin; /* Cursor numbers must be =< than this */ ++ int bFuncArg; /* True for table-function arg */ + CheckOnCtx *pParent; /* Parent context */ + }; + +@@ -154345,11 +156443,16 @@ static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){ + ** does not refer to a table to the right of CheckOnCtx.iJoin. */ + do { + SrcList *pSrc = pCtx->pSrc; ++ int nSrc = pSrc->nSrc; + int iTab = pExpr->iTable; +- if( iTab>=pSrc->a[0].iCursor && iTab<=pSrc->a[pSrc->nSrc-1].iCursor ){ ++ int ii; ++ for(ii=0; iia[ii].iCursor!=iTab; ii++){} ++ if( iiiJoin && iTab>pCtx->iJoin ){ + sqlite3ErrorMsg(pWalker->pParse, +- "ON clause references tables to its right"); ++ "%s references tables to its right", ++ (pCtx->bFuncArg ? "table-function argument" : "ON clause") ++ ); + return WRC_Abort; + } + break; +@@ -154387,6 +156490,7 @@ static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){ + SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect){ + Walker w; + CheckOnCtx sCtx; ++ int ii; + assert( pSelect->selFlags & SF_OnToWhere ); + assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 ); + memset(&w, 0, sizeof(w)); +@@ -154396,8 +156500,46 @@ SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect){ + w.u.pCheckOnCtx = &sCtx; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.pSrc = pSelect->pSrc; +- sqlite3WalkExprNN(&w, pSelect->pWhere); ++ sqlite3WalkExpr(&w, pSelect->pWhere); + pSelect->selFlags &= ~SF_OnToWhere; ++ ++ /* Check for any table-function args that are attached to virtual tables ++ ** on the RHS of an outer join. They are subject to the same constraints ++ ** as ON clauses. */ ++ sCtx.bFuncArg = 1; ++ for(ii=0; iipSrc->nSrc; ii++){ ++ SrcItem *pItem = &pSelect->pSrc->a[ii]; ++ if( pItem->fg.isTabFunc ++ && (pItem->fg.jointype & JT_OUTER) ++ ){ ++ sCtx.iJoin = pItem->iCursor; ++ sqlite3WalkExprList(&w, pItem->u1.pFuncArg); ++ } ++ } ++} ++ ++/* ++** If p2 exists and p1 and p2 have the same number of terms, then change ++** every term of p1 to have the same sort order as p2 and return true. ++** ++** If p2 is NULL or p1 and p2 are different lengths, then make no changes ++** and return false. ++** ++** p1 must be non-NULL. ++*/ ++static int sqlite3CopySortOrder(ExprList *p1, ExprList *p2){ ++ assert( p1 ); ++ if( p2 && p1->nExpr==p2->nExpr ){ ++ int ii; ++ for(ii=0; iinExpr; ii++){ ++ u8 sortFlags; ++ sortFlags = p2->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; ++ p1->a[ii].fg.sortFlags = sortFlags; ++ } ++ return 1; ++ }else{ ++ return 0; ++ } + } + + /* +@@ -154495,8 +156637,7 @@ SQLITE_PRIVATE int sqlite3Select( + 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 || ++ assert(pDest->eDest==SRT_Exists || 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 ){ +@@ -154512,7 +156653,6 @@ SQLITE_PRIVATE int sqlite3Select( + p->pOrderBy = 0; + } + p->selFlags &= ~(u32)SF_Distinct; +- p->selFlags |= SF_NoopOrderBy; + } + sqlite3SelectPrep(pParse, p, 0); + if( pParse->nErr ){ +@@ -155040,7 +157180,8 @@ SQLITE_PRIVATE int sqlite3Select( + ** 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 ++ && sqlite3CopySortOrder(pEList, sSort.pOrderBy) ++ && sqlite3ExprListCompare(pEList, sSort.pOrderBy, -1)==0 + && OptimizationEnabled(db, SQLITE_GroupByOrder) + #ifndef SQLITE_OMIT_WINDOWFUNC + && p->pWin==0 +@@ -155254,21 +157395,10 @@ SQLITE_PRIVATE int sqlite3Select( + ** 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; +- } ++ if( sqlite3CopySortOrder(pGroupBy, sSort.pOrderBy) ++ && sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ++ ){ ++ orderByGrp = 1; + } + }else{ + assert( 0==sqlite3LogEst(1) ); +@@ -156078,7 +158208,7 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS + sqlite3SelectDelete(db, pTmp->pSelect); + sqlite3IdListDelete(db, pTmp->pIdList); + sqlite3UpsertDelete(db, pTmp->pUpsert); +- sqlite3SrcListDelete(db, pTmp->pFrom); ++ sqlite3SrcListDelete(db, pTmp->pSrc); + sqlite3DbFree(db, pTmp->zSpan); + + sqlite3DbFree(db, pTmp); +@@ -156267,11 +158397,16 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( + } + } + ++ /* NB: The SQLITE_ALLOW_TRIGGERS_ON_SYSTEM_TABLES compile-time option is ++ ** experimental and unsupported. Do not use it unless understand the ++ ** implications and you cannot get by without this capability. */ ++#if !defined(SQLITE_ALLOW_TRIGGERS_ON_SYSTEM_TABLES) /* Experimental */ + /* 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; + } ++#endif + + /* INSTEAD of triggers are only for views and views only support INSTEAD + ** of triggers. +@@ -156383,6 +158518,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( + if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; + zName = pTrig->zName; + iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); ++ assert( iDb>=00 && iDbnDb ); + pTrig->step_list = pStepList; + while( pStepList ){ + pStepList->pTrig = pTrig; +@@ -156417,12 +158553,12 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( + if( sqlite3ReadOnlyShadowTables(db) ){ + TriggerStep *pStep; + for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ +- if( pStep->zTarget!=0 +- && sqlite3ShadowTableName(db, pStep->zTarget) ++ if( pStep->pSrc!=0 ++ && sqlite3ShadowTableName(db, pStep->pSrc->a[0].zName) + ){ + sqlite3ErrorMsg(pParse, + "trigger \"%s\" may not write to shadow table \"%s\"", +- pTrig->zName, pStep->zTarget); ++ pTrig->zName, pStep->pSrc->a[0].zName); + goto triggerfinish_cleanup; + } + } +@@ -156513,26 +158649,39 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( + static TriggerStep *triggerStepAllocate( + Parse *pParse, /* Parser context */ + u8 op, /* Trigger opcode */ +- Token *pName, /* The target name */ ++ SrcList *pTabList, /* Target table */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ + ){ ++ Trigger *pNew = pParse->pNewTrigger; + sqlite3 *db = pParse->db; +- TriggerStep *pTriggerStep; ++ TriggerStep *pTriggerStep = 0; + +- 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); ++ if( pParse->nErr==0 ){ ++ if( pNew ++ && pNew->pSchema!=db->aDb[1].pSchema ++ && pTabList->a[0].u4.zDatabase ++ ){ ++ sqlite3ErrorMsg(pParse, ++ "qualified table names are not allowed on INSERT, UPDATE, and DELETE " ++ "statements within triggers"); ++ }else{ ++ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); ++ if( pTriggerStep ){ ++ pTriggerStep->pSrc = sqlite3SrcListDup(db, pTabList, EXPRDUP_REDUCE); ++ pTriggerStep->op = op; ++ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); ++ if( pTriggerStep->pSrc && IN_RENAME_OBJECT ){ ++ sqlite3RenameTokenRemap(pParse, ++ pTriggerStep->pSrc->a[0].zName, ++ pTabList->a[0].zName ++ ); ++ } ++ } + } + } ++ ++ sqlite3SrcListDelete(db, pTabList); + return pTriggerStep; + } + +@@ -156545,7 +158694,7 @@ static TriggerStep *triggerStepAllocate( + */ + SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( + Parse *pParse, /* Parser */ +- Token *pTableName, /* Name of the table into which we insert */ ++ SrcList *pTabList, /* Table to INSERT into */ + 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.) */ +@@ -156558,7 +158707,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( + + assert(pSelect != 0 || db->mallocFailed); + +- pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); ++ pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTabList, zStart, zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pSelect = pSelect; +@@ -156590,7 +158739,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( + */ + SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( + Parse *pParse, /* Parser */ +- Token *pTableName, /* Name of the table to be updated */ ++ SrcList *pTabList, /* 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 */ +@@ -156601,21 +158750,36 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + +- pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); ++ pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTabList, zStart, zEnd); + if( pTriggerStep ){ ++ SrcList *pFromDup = 0; + if( IN_RENAME_OBJECT ){ + pTriggerStep->pExprList = pEList; + pTriggerStep->pWhere = pWhere; +- pTriggerStep->pFrom = pFrom; ++ pFromDup = 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); ++ pFromDup = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE); + } + pTriggerStep->orconf = orconf; ++ ++ if( pFromDup && !IN_RENAME_OBJECT){ ++ Select *pSub; ++ Token as = {0, 0}; ++ pSub = sqlite3SelectNew(pParse, 0, pFromDup, 0,0,0,0, SF_NestedFrom, 0); ++ pFromDup = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &as, pSub ,0); ++ } ++ if( pFromDup && pTriggerStep->pSrc ){ ++ pTriggerStep->pSrc = sqlite3SrcListAppendList( ++ pParse, pTriggerStep->pSrc, pFromDup ++ ); ++ }else{ ++ sqlite3SrcListDelete(db, pFromDup); ++ } + } + sqlite3ExprListDelete(db, pEList); + sqlite3ExprDelete(db, pWhere); +@@ -156630,7 +158794,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( + */ + SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( + Parse *pParse, /* Parser */ +- Token *pTableName, /* The table from which rows are deleted */ ++ SrcList *pTabList, /* 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 */ +@@ -156638,7 +158802,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + +- pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); ++ pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTabList, zStart, zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pWhere = pWhere; +@@ -156838,6 +159002,7 @@ static SQLITE_NOINLINE Trigger *triggersReallyExist( + p = pList; + if( (pParse->db->flags & SQLITE_EnableTrigger)==0 + && pTab->pTrigger!=0 ++ && sqlite3SchemaToIndex(pParse->db, pTab->pTrigger->pSchema)!=1 + ){ + /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that + ** only TEMP triggers are allowed. Truncate the pList so that it +@@ -156900,52 +159065,6 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist( + 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 ){ +- assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); +- pSrc->a[0].u4.pSchema = pSchema; +- pSrc->a[0].fg.fixedSchema = 1; +- } +- 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 +@@ -157211,7 +159330,7 @@ static int codeTriggerProgram( + switch( pStep->op ){ + case TK_UPDATE: { + sqlite3Update(pParse, +- sqlite3TriggerStepSrc(pParse, pStep), ++ sqlite3SrcListDup(db, pStep->pSrc, 0), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), + pParse->eOrconf, 0, 0, 0 +@@ -157221,7 +159340,7 @@ static int codeTriggerProgram( + } + case TK_INSERT: { + sqlite3Insert(pParse, +- sqlite3TriggerStepSrc(pParse, pStep), ++ sqlite3SrcListDup(db, pStep->pSrc, 0), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), + pParse->eOrconf, +@@ -157232,7 +159351,7 @@ static int codeTriggerProgram( + } + case TK_DELETE: { + sqlite3DeleteFrom(pParse, +- sqlite3TriggerStepSrc(pParse, pStep), ++ sqlite3SrcListDup(db, pStep->pSrc, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); +@@ -157297,7 +159416,7 @@ static TriggerPrg *codeRowTrigger( + Table *pTab, /* The table pTrigger is attached to */ + int orconf /* ON CONFLICT policy to code trigger program with */ + ){ +- Parse *pTop = sqlite3ParseToplevel(pParse); ++ Parse *pTop; /* Top level Parse object */ + sqlite3 *db = pParse->db; /* Database handle */ + TriggerPrg *pPrg; /* Value to return */ + Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ +@@ -157306,10 +159425,24 @@ static TriggerPrg *codeRowTrigger( + 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 */ ++ int nDepth; /* Trigger depth */ + ++ /* Ensure that triggers are not chained too deep. This test is linear ++ ** in the chaining depth, but sensible code ought not be chaining ++ ** triggers excessively, so that shouldn't be a problem. ++ */ ++ pTop = pParse; ++ for(nDepth=0; pTop->pOuterParse; pTop = pTop->pOuterParse, nDepth++){} ++ if( nDepth>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ ++ sqlite3ErrorMsg(pParse, "triggers nested too deep"); ++ return 0; ++ } ++ ++ pTop = sqlite3ParseToplevel(pParse); + 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. */ +@@ -159310,7 +161443,8 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( + /* 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); ++ int iStorage = pTop->regData + sqlite3TableColumnToStorage(pTab, i); ++ sqlite3VdbeAddOp1(v, OP_RealAffinity, iStorage); + } + } + sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), +@@ -159554,9 +161688,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( + pDb = &db->aDb[nDb]; + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); + pTemp = pDb->pBt; ++ nRes = sqlite3BtreeGetRequestedReserve(pMain); + if( pOut ){ + sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); + i64 sz = 0; ++ const char *zFilename; + if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ + rc = SQLITE_ERROR; + sqlite3SetString(pzErrMsg, db, "output file already exists"); +@@ -159568,8 +161704,16 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( + ** 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); ++ ++ /* If the VACUUM INTO target file is a URI filename and if the ++ ** "reserve=N" query parameter is present, reset the reserve to the ++ ** amount specified, if the amount is within range */ ++ zFilename = sqlite3BtreeGetFilename(pTemp); ++ if( ALWAYS(zFilename) ){ ++ int nNew = (int)sqlite3_uri_int64(zFilename, "reserve", nRes); ++ if( nNew>=0 && nNew<=255 ) nRes = nNew; ++ } + } +- nRes = sqlite3BtreeGetRequestedReserve(pMain); + + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); + sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); +@@ -159888,6 +162032,7 @@ SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ + #ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + #endif ++ sqlite3_mutex_enter(db->mutex); + for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ + Module *pMod = (Module*)sqliteHashData(pThis); + pNext = sqliteHashNext(pThis); +@@ -159898,6 +162043,7 @@ SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ + } + createModule(db, pMod->zName, 0, 0, 0); + } ++ sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } + +@@ -163374,7 +165520,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ + int iTab = pParse->nTab++; + int iCache = ++pParse->nMem; +- sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab); ++ sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab, 0); + sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); + }else{ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); +@@ -164098,7 +166244,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + ** 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 ){ ++ if( pWInfo->nLevel>1 || pTabItem->fg.fromExists ){ + int nNotReady; /* The number of notReady tables */ + SrcItem *origSrc; /* Original list of tables */ + nNotReady = pWInfo->nLevel - iLevel - 1; +@@ -164111,6 +166257,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + for(k=1; k<=nNotReady; k++){ + memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); + } ++ ++ /* Clear the fromExists flag on the OR-optimized table entry so that ++ ** the calls to sqlite3WhereEnd() do not code early-exits after the ++ ** first row is visited. The early exit applies to this table's ++ ** overall loop - including the multiple OR branches and any WHERE ++ ** conditions not passed to the sub-loops - not to the sub-loops. */ ++ pOrTab->a[0].fg.fromExists = 0; + }else{ + pOrTab = pWInfo->pTabList; + } +@@ -164354,7 +166507,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + assert( pLevel->op==OP_Return ); + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + +- if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } ++ if( pWInfo->pTabList!=pOrTab ){ sqlite3DbFreeNN(db, pOrTab); } + if( !untestedTerms ) disableTerm(pLevel, pTerm); + }else + #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ +@@ -164511,6 +166664,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + WO_EQ|WO_IN|WO_IS, 0); + if( pAlt==0 ) continue; + if( pAlt->wtFlags & (TERM_CODED) ) continue; ++ if( ExprHasProperty(pAlt->pExpr, EP_Collate) ) continue; + if( (pAlt->eOperator & WO_IN) + && ExprUseXSelect(pAlt->pExpr) + && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) +@@ -165042,13 +167196,14 @@ static int isLikeOrGlob( + ){ + int isNum; + double rDummy; +- isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); ++ assert( zNew[iTo]==0 ); ++ isNum = sqlite3AtoF(zNew, &rDummy); + if( isNum<=0 ){ + if( iTo==1 && zNew[0]=='-' ){ + isNum = +1; + }else{ + zNew[iTo-1]++; +- isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); ++ isNum = sqlite3AtoF(zNew, &rDummy); + zNew[iTo-1]--; + } + } +@@ -165091,6 +167246,34 @@ static int isLikeOrGlob( + } + #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + ++/* ++** If pExpr is one of "like", "glob", "match", or "regexp", then ++** return the corresponding SQLITE_INDEX_CONSTRAINT_xxxx value. ++** If not, return 0. ++** ++** pExpr is guaranteed to be a TK_FUNCTION. ++*/ ++SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr *pExpr){ ++ static const struct { ++ const char *zOp; ++ unsigned char eOp; ++ } aOp[] = { ++ { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, ++ { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, ++ { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, ++ { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } ++ }; ++ int i; ++ assert( pExpr->op==TK_FUNCTION ); ++ assert( !ExprHasProperty(pExpr, EP_IntValue) ); ++ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ ++ return aOp[i].eOp; ++ } ++ } ++ return 0; ++} ++ + + #ifndef SQLITE_OMIT_VIRTUALTABLE + /* +@@ -165127,15 +167310,6 @@ static int isAuxiliaryVtabOperator( + 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; +@@ -165155,16 +167329,11 @@ static int isAuxiliaryVtabOperator( + */ + 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; +- } +- } ++ if( ExprIsVtab(pCol) && (i = sqlite3ExprIsLikeOperator(pExpr))!=0 ){ ++ *peOp2 = i; ++ *ppRight = pList->a[0].pExpr; ++ *ppLeft = pCol; ++ return 1; + } + + /* We can also match against the first column of overloaded +@@ -165249,7 +167418,10 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ + static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ + pWC->a[iChild].iParent = iParent; + pWC->a[iChild].truthProb = pWC->a[iParent].truthProb; ++ assert( pWC->a[iParent].nChild < UMXV(pWC->a[0].nChild) ); + pWC->a[iParent].nChild++; ++ testcase( pWC->a[iParent].nChild == UMXV(pWC->a[0].nChild) ); ++ + } + + /* +@@ -165298,16 +167470,22 @@ static void whereCombineDisjuncts( + Expr *pNew; /* New virtual expression */ + int op; /* Operator for the combined expression */ + int idxNew; /* Index in pWC of the next virtual term */ ++ Expr *pA, *pB; /* Expressions associated with pOne and pTwo */ + + 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; ++ pA = pOne->pExpr; ++ pB = pTwo->pExpr; ++ assert( pA->pLeft!=0 && pA->pRight!=0 ); ++ assert( pB->pLeft!=0 && pB->pRight!=0 ); ++ if( sqlite3ExprCompare(0,pA->pLeft, pB->pLeft, -1) ) return; ++ if( sqlite3ExprCompare(0,pA->pRight, pB->pRight,-1) ) return; ++ if( ExprHasProperty(pA,EP_Commuted)!=ExprHasProperty(pB,EP_Commuted) ){ ++ 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) ){ +@@ -165318,7 +167496,7 @@ static void whereCombineDisjuncts( + } + } + db = pWC->pWInfo->pParse->db; +- pNew = sqlite3ExprDup(db, pOne->pExpr, 0); ++ pNew = sqlite3ExprDup(db, pA, 0); + if( pNew==0 ) return; + for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; +@@ -165682,8 +167860,8 @@ static void exprAnalyzeOrTerm( + ** 3. Not originating in the ON clause of an OUTER JOIN + ** 4. The operator is not IS or else the query does not contain RIGHT JOIN + ** 5. The affinities of A and B must be compatible +-** 6a. Both operands use the same collating sequence OR +-** 6b. The overall collating sequence is BINARY ++** 6. Both operands use the same collating sequence, and they must not ++** use explicit COLLATE clauses. + ** 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 +@@ -165691,10 +167869,9 @@ static void exprAnalyzeOrTerm( + */ + static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ + char aff1, aff2; +- CollSeq *pColl; + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ +- if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ ++ if( ExprHasProperty(pExpr, EP_OuterON|EP_Collate) ) return 0; /* (3) */ + assert( pSrc!=0 ); + if( pExpr->op==TK_IS + && pSrc->nSrc>=2 +@@ -165709,10 +167886,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ + ){ + return 0; /* (5) */ + } +- pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); +- if( !sqlite3IsBinary(pColl) +- && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) +- ){ ++ if( !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) ){ + return 0; /* (6) */ + } + return 1; +@@ -166024,6 +168198,7 @@ static void exprAnalyze( + pList = pExpr->x.pList; + assert( pList!=0 ); + assert( pList->nExpr==2 ); ++ assert( pWC->a[idxTerm].nChild==0 ); + for(i=0; i<2; i++){ + Expr *pNewExpr; + int idxNew; +@@ -166044,7 +168219,7 @@ static void exprAnalyze( + /* Analyze a term that is composed of two or more subterms connected by + ** an OR operator. + */ +- else if( pExpr->op==TK_OR ){ ++ else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){ + assert( pWC->op==TK_AND ); + exprAnalyzeOrTerm(pSrc, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; +@@ -166234,8 +168409,11 @@ static void exprAnalyze( + && pExpr->x.pSelect->pWin==0 + #endif + && pWC->op==TK_AND ++ && pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild) ++ /* ^-- See bug 2026-06-04T10:00:49Z */ + ){ + int i; ++ assert( pTerm->nChild==0 ); + for(i=0; ipLeft); i++){ + int idxNew; + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); +@@ -166358,13 +168536,11 @@ static void whereAddLimitExpr( + int iVal = 0; + + if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ +- Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); ++ Expr *pVal = sqlite3ExprInt32(db, iVal); + 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); ++ Expr *pVal = sqlite3ExprAlloc(db, TK_REGISTER, 0, 0); + if( pVal==0 ) return; + pVal->iTable = iReg; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); +@@ -168191,11 +170367,14 @@ static sqlite3_index_info *allocateIndexInfo( + break; + } + if( i==n ){ ++ int bSortByGroup = (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0; + nOrderBy = n; + if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){ +- eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); ++ eDistinct = 2 + bSortByGroup; + }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ +- eDistinct = 1; ++ eDistinct = 1 - bSortByGroup; ++ }else if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ ++ eDistinct = 3; + } + } + } +@@ -169123,11 +171302,16 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ + SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ + WhereInfo *pWInfo; + if( pWC ){ ++ int nb; ++ SrcItem *pItem; ++ Table *pTab; ++ Bitmask mAll; ++ + pWInfo = pWC->pWInfo; +- int nb = 1+(pWInfo->pTabList->nSrc+3)/4; +- SrcItem *pItem = pWInfo->pTabList->a + p->iTab; +- Table *pTab = pItem->pSTab; +- Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; ++ nb = 1+(pWInfo->pTabList->nSrc+3)/4; ++ pItem = pWInfo->pTabList->a + p->iTab; ++ pTab = pItem->pSTab; ++ 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", +@@ -169606,6 +171790,67 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ + return rc; + } + ++/* ++** Callback for estLikePatternLength(). ++** ++** If this node is a string literal that is longer pWalker->sz, then set ++** pWalker->sz to the byte length of that string literal. ++** ++** pWalker->eCode indicates how to count characters: ++** ++** eCode==0 Count as a GLOB pattern ++** eCode==1 Count as a LIKE pattern ++*/ ++static int exprNodePatternLengthEst(Walker *pWalker, Expr *pExpr){ ++ if( pExpr->op==TK_STRING ){ ++ int sz = 0; /* Pattern size in bytes */ ++ u8 *z = (u8*)pExpr->u.zToken; /* The pattern */ ++ u8 c; /* Next character of the pattern */ ++ u8 c1, c2, c3; /* Wildcards */ ++ if( pWalker->eCode ){ ++ c1 = '%'; ++ c2 = '_'; ++ c3 = 0; ++ }else{ ++ c1 = '*'; ++ c2 = '?'; ++ c3 = '['; ++ } ++ while( (c = *(z++))!=0 ){ ++ if( c==c3 ){ ++ if( *z ) z++; ++ while( *z && *z!=']' ) z++; ++ }else if( c!=c1 && c!=c2 ){ ++ sz++; ++ } ++ } ++ if( sz>pWalker->u.sz ) pWalker->u.sz = sz; ++ } ++ return WRC_Continue; ++} ++ ++/* ++** Return the length of the longest string literal in the given ++** expression. ++** ++** eCode indicates how to count characters: ++** ++** eCode==0 Count as a GLOB pattern ++** eCode==1 Count as a LIKE pattern ++*/ ++static int estLikePatternLength(Expr *p, u16 eCode){ ++ Walker w; ++ w.u.sz = 0; ++ w.eCode = eCode; ++ w.xExprCallback = exprNodePatternLengthEst; ++ w.xSelectCallback = sqlite3SelectWalkFail; ++#ifdef SQLITE_DEBUG ++ w.xSelectCallback2 = sqlite3SelectWalkAssert2; ++#endif ++ sqlite3WalkExpr(&w, p); ++ return w.u.sz; ++} ++ + /* + ** 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 +@@ -169634,6 +171879,13 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ + ** "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. ++** ++** Heuristic 3: If there is a LIKE or GLOB (or REGEXP or MATCH) operator ++** with a large constant pattern, then reduce the size of the search ++** space according to the length of the pattern, under the theory that ++** longer patterns are less likely to match. This heuristic was added ++** to give better output-row count estimates when preparing queries for ++** the Join-Order Benchmarks. See forum thread 2026-01-30T09:57:54z + */ + static void whereLoopOutputAdjust( + WhereClause *pWC, /* The WHERE clause */ +@@ -169683,13 +171935,14 @@ static void whereLoopOutputAdjust( + }else{ + /* In the absence of explicit truth probabilities, use heuristics to + ** guess a reasonable truth probability. */ ++ Expr *pOpExpr = pTerm->pExpr; + pLoop->nOut--; + if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 + && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ + ){ +- Expr *pRight = pTerm->pExpr->pRight; ++ Expr *pRight = pOpExpr->pRight; + int k = 0; +- testcase( pTerm->pExpr->op==TK_IS ); ++ testcase( pOpExpr->op==TK_IS ); + if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ + k = 10; + }else{ +@@ -169699,6 +171952,23 @@ static void whereLoopOutputAdjust( + pTerm->wtFlags |= TERM_HEURTRUTH; + iReduce = k; + } ++ }else ++ if( ExprHasProperty(pOpExpr, EP_InfixFunc) ++ && pOpExpr->op==TK_FUNCTION ++ ){ ++ int eOp; ++ assert( ExprUseXList(pOpExpr) ); ++ assert( pOpExpr->x.pList->nExpr>=2 ); ++ eOp = sqlite3ExprIsLikeOperator(pOpExpr); ++ if( ALWAYS(eOp>0) ){ ++ int szPattern; ++ Expr *pRHS = pOpExpr->x.pList->a[0].pExpr; ++ eOp = eOp==SQLITE_INDEX_CONSTRAINT_LIKE; ++ szPattern = estLikePatternLength(pRHS, eOp); ++ if( szPattern>0 ){ ++ pLoop->nOut -= szPattern*2; ++ } ++ } + } + } + } +@@ -169770,6 +172040,7 @@ static int whereRangeVectorLen( + idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); + if( aff!=idxaff ) break; + ++ if( ExprHasProperty(pTerm->pExpr, EP_Commuted) ) SWAP(Expr*, pRhs, pLhs); + pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + if( pColl==0 ) break; + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; +@@ -170159,6 +172430,7 @@ static int whereLoopAddBtreeIndex( + pNew->rRun += nInMul + nIn; + pNew->nOut += nInMul + nIn; + whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); ++ if( pSrc->fg.fromExists ) pNew->nOut = 0; + rc = whereLoopInsert(pBuilder, pNew); + + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ +@@ -170754,7 +173026,14 @@ static int whereLoopAddBtree( + whereLoopOutputAdjust(pWC, pNew, rSize); + if( pSrc->fg.isSubquery ){ + if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; +- pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; ++ /* Do not set btree.pOrderBy for a recursive CTE. In this case ++ ** the ORDER BY clause does not determine the overall order that ++ ** rows are emitted from the CTE in. */ ++ if( (pSrc->u4.pSubq->pSelect->selFlags & SF_Recursive)==0 ){ ++ pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; ++ } ++ }else if( pSrc->fg.fromExists ){ ++ pNew->nOut = 0; + } + rc = whereLoopInsert(pBuilder, pNew); + pNew->nOut = rSize; +@@ -170857,6 +173136,7 @@ static int whereLoopAddBtree( + ** positioned to the correct row during the right-join no-match + ** loop. */ + }else{ ++ if( pSrc->fg.fromExists ) pNew->nOut = 0; + rc = whereLoopInsert(pBuilder, pNew); + } + pNew->nOut = rSize; +@@ -171519,7 +173799,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ + sqlite3 *db = pWInfo->pParse->db; + int rc = SQLITE_OK; + int bFirstPastRJ = 0; +- int hasRightJoin = 0; ++ int hasRightCrossJoin = 0; + WhereLoop *pNew; + + +@@ -171546,15 +173826,34 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ + ** 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. ++ ** The hasRightCrossJoin flag prevent FROM-clause terms from moving ++ ** from the right side of a LEFT JOIN or CROSS JOIN over to the ++ ** left side of that same join. This is a required restriction in ++ ** the case of LEFT JOIN - an incorrect answer may results if it is ++ ** not enforced. This restriction is not required for CROSS JOIN. ++ ** It is provided merely as a means of controlling join order, under ++ ** the theory that no real-world queries that care about performance ++ ** actually use the CROSS JOIN syntax. + */ +- if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; ++ if( pItem->fg.jointype & (JT_LTORJ|JT_CROSS) ){ ++ testcase( pItem->fg.jointype & JT_LTORJ ); ++ testcase( pItem->fg.jointype & JT_CROSS ); ++ hasRightCrossJoin = 1; ++ } + mPrereq |= mPrior; + bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; +- }else if( !hasRightJoin ){ ++ }else if( pItem->fg.fromExists ){ ++ /* joins that result from the EXISTS-to-JOIN optimization should not ++ ** be moved to the left of any of their dependencies */ ++ WhereClause *pWC = &pWInfo->sWC; ++ WhereTerm *pTerm; ++ int i; ++ for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ ++ if( (pNew->maskSelf & pTerm->prereqAll)!=0 ){ ++ mPrereq |= (pTerm->prereqAll & (pNew->maskSelf-1)); ++ } ++ } ++ }else if( !hasRightCrossJoin ){ + mPrereq = 0; + } + #ifndef SQLITE_OMIT_VIRTUALTABLE +@@ -171777,9 +174076,7 @@ static i8 wherePathSatisfiesOrderBy( + pLoop = pLast; + } + if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ +- if( pLoop->u.vtab.isOrdered +- && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) +- ){ ++ if( pLoop->u.vtab.isOrdered && pWInfo->pOrderBy==pOrderBy ){ + obSat = obDone; + }else{ + /* No further ORDER BY terms may be matched. So this call should +@@ -172155,12 +174452,21 @@ static LogEst whereSortingCost( + ** 12 otherwise + ** + ** For the purposes of this heuristic, a star-query is defined as a query +-** with a large central table that is joined using an INNER JOIN, +-** not CROSS or OUTER JOINs, against four or more smaller tables. +-** The central table is called the "fact" table. The smaller tables +-** that get joined are "dimension tables". Also, any table that is +-** self-joined cannot be a dimension table; we assume that dimension +-** tables may only be joined against fact tables. ++** with a central "fact" table that is joined against multiple ++** "dimension" tables, subject to the following constraints: ++** ++** (aa) Only a five-way or larger join is considered for this ++** optimization. If there are fewer than four terms in the FROM ++** clause, this heuristic does not apply. ++** ++** (bb) The join between the fact table and the dimension tables must ++** be an INNER join. CROSS and OUTER JOINs do not qualify. ++** ++** (cc) A table must have 3 or more dimension tables in order to be ++** considered a fact table. (Was 4 prior to 2026-02-10.) ++** ++** (dd) A table that is a self-join cannot be a dimension table. ++** Dimension tables are joined against fact tables. + ** + ** SIDE EFFECT: (and really the whole point of this subroutine) + ** +@@ -172213,7 +174519,7 @@ static int computeMxChoice(WhereInfo *pWInfo){ + } + #endif /* SQLITE_DEBUG */ + +- if( nLoop>=5 ++ if( nLoop>=4 /* Constraint (aa) */ + && !pWInfo->bStarDone + && OptimizationEnabled(pWInfo->pParse->db, SQLITE_StarQuery) + ){ +@@ -172225,7 +174531,7 @@ static int computeMxChoice(WhereInfo *pWInfo){ + + pWInfo->bStarDone = 1; /* Only do this computation once */ + +- /* Look for fact tables with four or more dimensions where the ++ /* Look for fact tables with three or more dimensions where the + ** dimension tables are not separately from the fact tables by an outer + ** or cross join. Adjust cost weights if found. + */ +@@ -172242,18 +174548,17 @@ static int computeMxChoice(WhereInfo *pWInfo){ + if( (pFactTab->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ + /* If the candidate fact-table is the right table of an outer join + ** restrict the search for dimension-tables to be tables to the right +- ** of the fact-table. */ +- if( iFromIdx+4 > nLoop ) break; /* Impossible to reach nDep>=4 */ ++ ** of the fact-table. Constraint (bb) */ ++ if( iFromIdx+3 > nLoop ){ ++ break; /* ^-- Impossible to reach nDep>=2 - Constraint (cc) */ ++ } + while( pStart && pStart->iTab<=iFromIdx ){ + pStart = pStart->pNextLoop; + } + } + for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( (aFromTabs[pWLoop->iTab].fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ +- /* Fact-tables and dimension-tables cannot be separated by an +- ** outer join (at least for the definition of fact- and dimension- +- ** used by this heuristic). */ +- break; ++ break; /* Constraint (bb) */ + } + if( (pWLoop->prereq & m)!=0 /* pWInfo depends on iFromIdx */ + && (pWLoop->maskSelf & mSeen)==0 /* pWInfo not already a dependency */ +@@ -172267,7 +174572,9 @@ static int computeMxChoice(WhereInfo *pWInfo){ + } + } + } +- if( nDep<=3 ) continue; ++ if( nDep<=2 ){ ++ continue; /* Constraint (cc) */ ++ } + + /* If we reach this point, it means that pFactTab is a fact table + ** with four or more dimensions connected by inner joins. Proceed +@@ -172280,6 +174587,23 @@ static int computeMxChoice(WhereInfo *pWInfo){ + pWLoop->rStarDelta = 0; + } + } ++#endif ++#ifdef WHERETRACE_ENABLED /* 0x80000 */ ++ if( sqlite3WhereTrace & 0x80000 ){ ++ Bitmask mShow = mSeen; ++ sqlite3DebugPrintf("Fact table %s(%d), dimensions:", ++ pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName, ++ iFromIdx); ++ for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ ++ if( mShow & pWLoop->maskSelf ){ ++ SrcItem *pDim = aFromTabs + pWLoop->iTab; ++ mShow &= ~pWLoop->maskSelf; ++ sqlite3DebugPrintf(" %s(%d)", ++ pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab); ++ } ++ } ++ sqlite3DebugPrintf("\n"); ++ } + #endif + pWInfo->bStarUsed = 1; + +@@ -172303,10 +174627,8 @@ static int computeMxChoice(WhereInfo *pWInfo){ + if( sqlite3WhereTrace & 0x80000 ){ + SrcItem *pDim = aFromTabs + pWLoop->iTab; + sqlite3DebugPrintf( +- "Increase SCAN cost of dimension %s(%d) of fact %s(%d) to %d\n", +- pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab, +- pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName, +- iFromIdx, mxRun ++ "Increase SCAN cost of %s to %d\n", ++ pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, mxRun + ); + } + pWLoop->rStarDelta = mxRun - pWLoop->rRun; +@@ -173120,6 +175442,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + pTerm->wtFlags |= TERM_CODED; ++ pTerm->prereqAll = 0; + } + } + if( i!=pWInfo->nLevel-1 ){ +@@ -174095,6 +176418,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ + ){ + int r1 = pParse->nMem+1; + int j, op; ++ int addrIfNull = 0; /* Init to avoid false-positive compiler warning */ ++ if( pLevel->iLeftJoin ){ ++ addrIfNull = sqlite3VdbeAddOp2(v, OP_IfNullRow, pLevel->iIdxCur, r1); ++ } + for(j=0; jiIdxCur, j, r1+j); + } +@@ -174104,25 +176431,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ + VdbeCoverageIf(v, op==OP_SeekLT); + VdbeCoverageIf(v, op==OP_SeekGT); + sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); ++ if( pLevel->iLeftJoin ){ ++ sqlite3VdbeJumpHere(v, addrIfNull); ++ } + } + #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ + } +- if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){ +- /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS +- ** loop(s) will be the inner-most loops of the join. There might be +- ** multiple EXISTS loops, but they will all be nested, and the join +- ** order will not have been changed by the query planner. If the +- ** inner-most EXISTS loop sees a single successful row, it should +- ** break out of *all* EXISTS loops. But only the inner-most of the +- ** nested EXISTS loops should do this breakout. */ +- int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */ +- while( nOutera[pLevel[-nOuter-1].iFrom].fg.fromExists ) break; +- nOuter++; +- } +- testcase( nOuter>0 ); +- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk); +- VdbeComment((v, "EXISTS break")); ++ if( pTabList->a[pLevel->iFrom].fg.fromExists ){ ++ /* This is an EXISTS-to-JOIN optimization loop. If this loop sees a ++ ** successful row, it should break out of itself. */ ++ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); ++ VdbeComment((v, "EXISTS break %d", i)); + } + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + if( pLevel->op!=OP_Noop ){ +@@ -174644,7 +176963,7 @@ static void nth_valueStepFunc( + break; + case SQLITE_FLOAT: { + double fVal = sqlite3_value_double(apArg[1]); +- if( ((i64)fVal)!=fVal ) goto error_out; ++ if( sqlite3RealToI64(fVal)!=fVal ) goto error_out; + iVal = (i64)fVal; + break; + } +@@ -175139,7 +177458,7 @@ SQLITE_PRIVATE void sqlite3WindowUpdate( + pWin->eEnd = aUp[i].eEnd; + pWin->eExclude = 0; + if( pWin->eStart==TK_FOLLOWING ){ +- pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1"); ++ pWin->pStart = sqlite3ExprInt32(db, 1); + } + break; + } +@@ -175484,9 +177803,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ + ** keep everything legal in this case. + */ + if( pSublist==0 ){ +- pSublist = sqlite3ExprListAppend(pParse, 0, +- sqlite3Expr(db, TK_INTEGER, "0") +- ); ++ pSublist = sqlite3ExprListAppend(pParse, 0, sqlite3ExprInt32(db, 0)); + } + + pSub = sqlite3SelectNew( +@@ -177710,8 +180027,23 @@ static void updateDeleteLimitError( + ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate + ** testing. + */ +- static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){ +- return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); ++ static void *parserStackRealloc( ++ void *pOld, /* Prior allocation */ ++ sqlite3_uint64 newSize, /* Requested new alloation size */ ++ Parse *pParse /* Parsing context */ ++ ){ ++ void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); ++ if( p==0 ) sqlite3OomFault(pParse->db); ++ return p; ++ } ++ static void parserStackFree(void *pOld, Parse *pParse){ ++ (void)pParse; ++ sqlite3_free(pOld); ++ } ++ ++ /* Return an integer that is the maximum allowed stack size */ ++ static int parserStackSizeLimit(Parse *pParse){ ++ return pParse->db->aLimit[SQLITE_LIMIT_PARSER_DEPTH]; + } + + +@@ -177750,15 +180082,46 @@ static void updateDeleteLimitError( + } + + +- /* 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; ++ /* Create a TK_ISNULL or TK_NOTNULL expression, perhaps optimized to ++ ** to TK_TRUEFALSE, if possible */ ++ static Expr *sqlite3PExprIsNull( ++ Parse *pParse, /* Parsing context */ ++ int op, /* TK_ISNULL or TK_NOTNULL */ ++ Expr *pLeft /* Operand */ ++ ){ ++ Expr *p = pLeft; ++ assert( op==TK_ISNULL || op==TK_NOTNULL ); ++ assert( pLeft!=0 ); ++ while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ ++ p = p->pLeft; ++ assert( p!=0 ); + } ++ switch( p->op ){ ++ case TK_INTEGER: ++ case TK_STRING: ++ case TK_FLOAT: ++ case TK_BLOB: ++ sqlite3ExprDeferredDelete(pParse, pLeft); ++ return sqlite3ExprInt32(pParse->db, op==TK_NOTNULL); ++ default: ++ break; ++ } ++ return sqlite3PExpr(pParse, op, pLeft, 0); ++ } ++ ++ /* Create a TK_IS or TK_ISNOT operator, perhaps optimized to ++ ** TK_ISNULL or TK_NOTNULL or TK_TRUEFALSE. */ ++ static Expr *sqlite3PExprIs( ++ Parse *pParse, /* Parsing context */ ++ int op, /* TK_IS or TK_ISNOT */ ++ Expr *pLeft, /* Left operand */ ++ Expr *pRight /* Right operand */ ++ ){ ++ if( pRight && pRight->op==TK_NULL ){ ++ sqlite3ExprDeferredDelete(pParse, pRight); ++ return sqlite3PExprIsNull(pParse, op==TK_IS ? TK_ISNULL : TK_NOTNULL, pLeft); ++ } ++ return sqlite3PExpr(pParse, op, pLeft, pRight); + } + + /* Add a single new term to an ExprList that is used to store a +@@ -178041,63 +180404,72 @@ static void updateDeleteLimitError( + #endif + /************* Begin control #defines *****************************************/ + #define YYCODETYPE unsigned short int +-#define YYNOCODE 323 ++#define YYNOCODE 322 + #define YYACTIONTYPE unsigned short int + #define YYWILDCARD 102 + #define sqlite3ParserTOKENTYPE Token + typedef union { + int yyinit; + sqlite3ParserTOKENTYPE yy0; +- u32 yy9; +- struct TrigEvent yy28; +- With* yy125; +- IdList* yy204; +- struct FrameBound yy205; +- TriggerStep* yy319; +- const char* yy342; +- Cte* yy361; +- ExprList* yy402; +- Upsert* yy403; +- OnOrUsing yy421; +- u8 yy444; +- struct {int value; int mask;} yy481; +- Window* yy483; +- int yy502; +- SrcList* yy563; +- Expr* yy590; +- Select* yy637; ++ ExprList* yy14; ++ With* yy59; ++ Cte* yy67; ++ Upsert* yy122; ++ IdList* yy132; ++ int yy144; ++ const char* yy168; ++ SrcList* yy203; ++ Window* yy211; ++ OnOrUsing yy269; ++ struct TrigEvent yy286; ++ struct {int value; int mask;} yy383; ++ u32 yy391; ++ TriggerStep* yy427; ++ Expr* yy454; ++ u8 yy462; ++ struct FrameBound yy509; ++ Select* yy555; + } YYMINORTYPE; + #ifndef YYSTACKDEPTH +-#define YYSTACKDEPTH 100 ++#define YYSTACKDEPTH 50 + #endif + #define sqlite3ParserARG_SDECL + #define sqlite3ParserARG_PDECL + #define sqlite3ParserARG_PARAM + #define sqlite3ParserARG_FETCH + #define sqlite3ParserARG_STORE ++#undef YYREALLOC + #define YYREALLOC parserStackRealloc +-#define YYFREE sqlite3_free ++#undef YYFREE ++#define YYFREE parserStackFree ++#undef YYDYNSTACK + #define YYDYNSTACK 1 ++#undef YYSIZELIMIT ++#define YYSIZELIMIT parserStackSizeLimit ++#define sqlite3ParserCTX(P) ((P)->pParse) + #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; ++#undef YYERRORSYMBOL ++#undef YYERRSYMDT ++#undef YYFALLBACK + #define YYFALLBACK 1 +-#define YYNSTATE 583 +-#define YYNRULE 409 +-#define YYNRULE_WITH_ACTION 344 ++#define YYNSTATE 600 ++#define YYNRULE 412 ++#define YYNRULE_WITH_ACTION 348 + #define YYNTOKEN 187 +-#define YY_MAX_SHIFT 582 +-#define YY_MIN_SHIFTREDUCE 845 +-#define YY_MAX_SHIFTREDUCE 1253 +-#define YY_ERROR_ACTION 1254 +-#define YY_ACCEPT_ACTION 1255 +-#define YY_NO_ACTION 1256 +-#define YY_MIN_REDUCE 1257 +-#define YY_MAX_REDUCE 1665 ++#define YY_MAX_SHIFT 599 ++#define YY_MIN_SHIFTREDUCE 867 ++#define YY_MAX_SHIFTREDUCE 1278 ++#define YY_ERROR_ACTION 1279 ++#define YY_ACCEPT_ACTION 1280 ++#define YY_NO_ACTION 1281 ++#define YY_MIN_REDUCE 1282 ++#define YY_MAX_REDUCE 1693 + #define YY_MIN_DSTRCTR 206 +-#define YY_MAX_DSTRCTR 320 ++#define YY_MAX_DSTRCTR 319 + /************* End control #defines *******************************************/ + #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) + +@@ -178180,643 +180552,680 @@ typedef union { + ** yy_default[] Default action for each state. + ** + *********** Begin parsing tables **********************************************/ +-#define YY_ACTTAB_COUNT (2207) ++#define YY_ACTTAB_COUNT (2379) + static const YYACTIONTYPE yy_action[] = { +- /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289, +- /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413, +- /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82, +- /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984, +- /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, +- /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, +- /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, +- /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, +- /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, +- /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, +- /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, +- /* 110 */ 132, 132, 131, 128, 451, 451, 1050, 1050, 1064, 1067, +- /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174, +- /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 481, 1341, +- /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132, +- /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 498, 1228, +- /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, +- /* 170 */ 136, 1204, 862, 1281, 288, 288, 283, 288, 288, 523, +- /* 180 */ 523, 1250, 139, 578, 7, 578, 1345, 573, 1169, 562, +- /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 573, 547, +- /* 200 */ 562, 1169, 245, 1541, 1169, 245, 133, 133, 132, 132, +- /* 210 */ 132, 131, 128, 451, 302, 134, 134, 134, 134, 133, +- /* 220 */ 133, 132, 132, 132, 131, 128, 451, 1575, 1204, 1205, +- /* 230 */ 1204, 7, 470, 550, 455, 413, 550, 455, 130, 127, +- /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, +- /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 483, 137, +- /* 260 */ 138, 91, 1019, 1228, 1228, 1063, 1066, 1053, 1053, 135, +- /* 270 */ 135, 136, 136, 136, 136, 1085, 576, 1204, 132, 132, +- /* 280 */ 132, 131, 128, 451, 93, 214, 134, 134, 134, 134, +- /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 401, 19, +- /* 300 */ 19, 134, 134, 134, 134, 133, 133, 132, 132, 132, +- /* 310 */ 131, 128, 451, 1498, 426, 267, 344, 467, 332, 134, +- /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, +- /* 330 */ 451, 1281, 576, 6, 1204, 1205, 1204, 257, 576, 413, +- /* 340 */ 511, 508, 507, 1279, 94, 1019, 464, 1204, 551, 551, +- /* 350 */ 506, 1224, 1571, 44, 38, 51, 51, 411, 576, 413, +- /* 360 */ 45, 51, 51, 137, 138, 91, 530, 1228, 1228, 1063, +- /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 398, +- /* 380 */ 1148, 82, 82, 137, 138, 91, 39, 1228, 1228, 1063, +- /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 344, +- /* 400 */ 44, 288, 288, 375, 1204, 1205, 1204, 209, 1204, 1224, +- /* 410 */ 320, 567, 471, 576, 573, 576, 562, 576, 316, 264, +- /* 420 */ 231, 46, 160, 134, 134, 134, 134, 133, 133, 132, +- /* 430 */ 132, 132, 131, 128, 451, 303, 82, 82, 82, 82, +- /* 440 */ 82, 82, 442, 134, 134, 134, 134, 133, 133, 132, +- /* 450 */ 132, 132, 131, 128, 451, 1582, 544, 320, 567, 1250, +- /* 460 */ 874, 1582, 380, 382, 413, 1204, 1205, 1204, 360, 182, +- /* 470 */ 288, 288, 1576, 557, 1339, 557, 7, 557, 1277, 472, +- /* 480 */ 346, 526, 531, 573, 556, 562, 439, 1511, 137, 138, +- /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, +- /* 500 */ 136, 136, 136, 136, 465, 1511, 1513, 532, 413, 288, +- /* 510 */ 288, 423, 512, 288, 288, 411, 288, 288, 874, 130, +- /* 520 */ 127, 234, 573, 1107, 562, 1204, 573, 1107, 562, 573, +- /* 530 */ 560, 562, 137, 138, 91, 1293, 1228, 1228, 1063, 1066, +- /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134, +- /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, +- /* 560 */ 493, 503, 1292, 1204, 257, 288, 288, 511, 508, 507, +- /* 570 */ 1204, 1628, 1169, 123, 568, 275, 4, 506, 573, 1511, +- /* 580 */ 562, 331, 1204, 1205, 1204, 1169, 548, 548, 1169, 261, +- /* 590 */ 571, 7, 134, 134, 134, 134, 133, 133, 132, 132, +- /* 600 */ 132, 131, 128, 451, 108, 533, 130, 127, 234, 1204, +- /* 610 */ 448, 447, 413, 1451, 452, 983, 886, 96, 1598, 1233, +- /* 620 */ 1204, 1205, 1204, 984, 1235, 1450, 565, 1204, 1205, 1204, +- /* 630 */ 229, 522, 1234, 534, 1333, 1333, 137, 138, 91, 1449, +- /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, +- /* 650 */ 136, 136, 373, 1595, 971, 1040, 413, 1236, 418, 1236, +- /* 660 */ 879, 121, 121, 948, 373, 1595, 1204, 1205, 1204, 122, +- /* 670 */ 1204, 452, 577, 452, 363, 417, 1028, 882, 373, 1595, +- /* 680 */ 137, 138, 91, 462, 1228, 1228, 1063, 1066, 1053, 1053, +- /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, +- /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028, +- /* 710 */ 1030, 1031, 35, 570, 570, 570, 197, 423, 1040, 198, +- /* 720 */ 1204, 123, 568, 1204, 4, 320, 567, 1204, 1205, 1204, +- /* 730 */ 40, 388, 576, 384, 882, 1029, 423, 1188, 571, 1028, +- /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, +- /* 750 */ 128, 451, 529, 1568, 1204, 19, 19, 1204, 575, 492, +- /* 760 */ 413, 157, 452, 489, 1187, 1331, 1331, 5, 1204, 949, +- /* 770 */ 431, 1028, 1028, 1030, 565, 22, 22, 1204, 1205, 1204, +- /* 780 */ 1204, 1205, 1204, 477, 137, 138, 91, 212, 1228, 1228, +- /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, +- /* 800 */ 1188, 48, 111, 1040, 413, 1204, 213, 970, 1041, 121, +- /* 810 */ 121, 1204, 1205, 1204, 1204, 1205, 1204, 122, 221, 452, +- /* 820 */ 577, 452, 44, 487, 1028, 1204, 1205, 1204, 137, 138, +- /* 830 */ 91, 378, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, +- /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, +- /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031, +- /* 860 */ 35, 461, 1204, 1205, 1204, 1569, 1040, 377, 214, 1149, +- /* 870 */ 1657, 535, 1657, 437, 902, 320, 567, 1568, 364, 320, +- /* 880 */ 567, 412, 329, 1029, 519, 1188, 3, 1028, 134, 134, +- /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, +- /* 900 */ 1659, 399, 1169, 307, 893, 307, 515, 576, 413, 214, +- /* 910 */ 498, 944, 1024, 540, 903, 1169, 943, 392, 1169, 1028, +- /* 920 */ 1028, 1030, 406, 298, 1204, 50, 1149, 1658, 413, 1658, +- /* 930 */ 145, 145, 137, 138, 91, 293, 1228, 1228, 1063, 1066, +- /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 1188, 1147, +- /* 950 */ 514, 1568, 137, 138, 91, 1505, 1228, 1228, 1063, 1066, +- /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 323, +- /* 970 */ 435, 539, 111, 1506, 274, 291, 372, 517, 367, 516, +- /* 980 */ 262, 1204, 1205, 1204, 1574, 481, 363, 576, 7, 1569, +- /* 990 */ 1568, 377, 134, 134, 134, 134, 133, 133, 132, 132, +- /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 576, 232, 576, +- /* 1010 */ 19, 19, 134, 134, 134, 134, 133, 133, 132, 132, +- /* 1020 */ 132, 131, 128, 451, 1169, 433, 576, 1207, 19, 19, +- /* 1030 */ 19, 19, 19, 19, 1627, 576, 911, 1169, 47, 120, +- /* 1040 */ 1169, 117, 413, 306, 498, 438, 1125, 206, 336, 19, +- /* 1050 */ 19, 1435, 49, 449, 449, 449, 1368, 315, 81, 81, +- /* 1060 */ 576, 304, 413, 1570, 207, 377, 137, 138, 91, 115, +- /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, +- /* 1080 */ 136, 136, 576, 82, 82, 1207, 137, 138, 91, 1340, +- /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, +- /* 1100 */ 136, 136, 1569, 386, 377, 82, 82, 463, 1126, 1552, +- /* 1110 */ 333, 463, 335, 131, 128, 451, 1569, 161, 377, 16, +- /* 1120 */ 317, 387, 428, 1127, 448, 447, 134, 134, 134, 134, +- /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576, +- /* 1140 */ 1105, 10, 445, 267, 576, 1554, 134, 134, 134, 134, +- /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 532, 576, +- /* 1160 */ 922, 576, 19, 19, 576, 1573, 576, 147, 147, 7, +- /* 1170 */ 923, 1236, 498, 1236, 576, 487, 413, 552, 285, 1224, +- /* 1180 */ 969, 215, 82, 82, 66, 66, 1435, 67, 67, 21, +- /* 1190 */ 21, 1110, 1110, 495, 334, 297, 413, 53, 53, 297, +- /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053, +- /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 1336, 1311, 446, +- /* 1220 */ 137, 138, 91, 227, 1228, 1228, 1063, 1066, 1053, 1053, +- /* 1230 */ 135, 135, 136, 136, 136, 136, 574, 1224, 936, 936, +- /* 1240 */ 137, 126, 91, 141, 1228, 1228, 1063, 1066, 1053, 1053, +- /* 1250 */ 135, 135, 136, 136, 136, 136, 533, 429, 472, 346, +- /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, +- /* 1270 */ 128, 451, 576, 457, 233, 343, 1435, 403, 498, 1550, +- /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, +- /* 1290 */ 128, 451, 576, 324, 576, 82, 82, 487, 576, 969, +- /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, +- /* 1310 */ 128, 451, 288, 288, 546, 68, 68, 54, 54, 553, +- /* 1320 */ 413, 69, 69, 351, 6, 573, 944, 562, 410, 409, +- /* 1330 */ 1435, 943, 450, 545, 260, 259, 258, 576, 158, 576, +- /* 1340 */ 413, 222, 1180, 479, 969, 138, 91, 430, 1228, 1228, +- /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, +- /* 1360 */ 70, 70, 71, 71, 576, 1126, 91, 576, 1228, 1228, +- /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, +- /* 1380 */ 1127, 166, 850, 851, 852, 1282, 419, 72, 72, 108, +- /* 1390 */ 73, 73, 1310, 358, 1180, 1128, 576, 305, 576, 123, +- /* 1400 */ 568, 494, 4, 488, 134, 134, 134, 134, 133, 133, +- /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 55, +- /* 1420 */ 55, 56, 56, 576, 134, 134, 134, 134, 133, 133, +- /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 1104, 233, 1104, +- /* 1440 */ 452, 1602, 582, 2, 1259, 576, 57, 57, 576, 321, +- /* 1450 */ 576, 155, 565, 1435, 485, 353, 576, 356, 1341, 59, +- /* 1460 */ 59, 576, 44, 969, 569, 419, 576, 238, 60, 60, +- /* 1470 */ 261, 74, 74, 75, 75, 287, 231, 576, 1366, 76, +- /* 1480 */ 76, 1040, 420, 184, 20, 20, 576, 121, 121, 77, +- /* 1490 */ 77, 97, 218, 288, 288, 122, 125, 452, 577, 452, +- /* 1500 */ 143, 143, 1028, 576, 520, 576, 573, 576, 562, 144, +- /* 1510 */ 144, 474, 227, 1244, 478, 123, 568, 576, 4, 320, +- /* 1520 */ 567, 245, 411, 576, 443, 411, 78, 78, 62, 62, +- /* 1530 */ 79, 79, 571, 319, 1028, 1028, 1030, 1031, 35, 418, +- /* 1540 */ 63, 63, 576, 290, 411, 9, 80, 80, 1144, 576, +- /* 1550 */ 400, 576, 486, 455, 576, 1223, 452, 576, 325, 342, +- /* 1560 */ 576, 111, 576, 1188, 242, 64, 64, 473, 565, 576, +- /* 1570 */ 23, 576, 170, 170, 171, 171, 576, 87, 87, 328, +- /* 1580 */ 65, 65, 542, 83, 83, 146, 146, 541, 123, 568, +- /* 1590 */ 341, 4, 84, 84, 168, 168, 576, 1040, 576, 148, +- /* 1600 */ 148, 576, 1380, 121, 121, 571, 1021, 576, 266, 576, +- /* 1610 */ 424, 122, 576, 452, 577, 452, 576, 553, 1028, 142, +- /* 1620 */ 142, 169, 169, 576, 162, 162, 528, 889, 371, 452, +- /* 1630 */ 152, 152, 151, 151, 1379, 149, 149, 109, 370, 150, +- /* 1640 */ 150, 565, 576, 480, 576, 266, 86, 86, 576, 1092, +- /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 482, 576, 266, 466, +- /* 1660 */ 543, 123, 568, 1616, 4, 88, 88, 85, 85, 475, +- /* 1670 */ 1040, 52, 52, 222, 901, 900, 121, 121, 571, 1188, +- /* 1680 */ 58, 58, 244, 1032, 122, 889, 452, 577, 452, 908, +- /* 1690 */ 909, 1028, 300, 347, 504, 111, 263, 361, 165, 111, +- /* 1700 */ 111, 1088, 452, 263, 974, 1153, 266, 1092, 986, 987, +- /* 1710 */ 942, 939, 125, 125, 565, 1103, 872, 1103, 159, 941, +- /* 1720 */ 1309, 125, 1557, 1028, 1028, 1030, 1031, 35, 542, 337, +- /* 1730 */ 1530, 205, 1529, 541, 499, 1589, 490, 348, 1376, 352, +- /* 1740 */ 355, 1032, 357, 1040, 359, 1324, 1308, 366, 563, 121, +- /* 1750 */ 121, 376, 1188, 1389, 1434, 1362, 280, 122, 1374, 452, +- /* 1760 */ 577, 452, 167, 1439, 1028, 1289, 1280, 1268, 1267, 1269, +- /* 1770 */ 1609, 1359, 312, 313, 314, 397, 12, 237, 224, 1421, +- /* 1780 */ 295, 1416, 1409, 1426, 339, 484, 340, 509, 1371, 1612, +- /* 1790 */ 1372, 1425, 1244, 404, 301, 228, 1028, 1028, 1030, 1031, +- /* 1800 */ 35, 1601, 1192, 454, 345, 1307, 292, 369, 1502, 1501, +- /* 1810 */ 270, 396, 396, 395, 277, 393, 1370, 1369, 859, 1549, +- /* 1820 */ 186, 123, 568, 235, 4, 1188, 391, 210, 211, 223, +- /* 1830 */ 1547, 239, 1241, 327, 422, 96, 220, 195, 571, 180, +- /* 1840 */ 188, 326, 468, 469, 190, 191, 502, 192, 193, 566, +- /* 1850 */ 247, 109, 1430, 491, 199, 251, 102, 281, 402, 476, +- /* 1860 */ 405, 1496, 452, 497, 253, 1422, 13, 1428, 14, 1427, +- /* 1870 */ 203, 1507, 241, 500, 565, 354, 407, 92, 95, 1270, +- /* 1880 */ 175, 254, 518, 43, 1327, 255, 1326, 1325, 436, 1518, +- /* 1890 */ 350, 1318, 104, 229, 893, 1626, 440, 441, 1625, 408, +- /* 1900 */ 240, 1296, 268, 1040, 310, 269, 1297, 527, 444, 121, +- /* 1910 */ 121, 368, 1295, 1594, 1624, 311, 1394, 122, 1317, 452, +- /* 1920 */ 577, 452, 374, 1580, 1028, 1393, 140, 553, 11, 90, +- /* 1930 */ 568, 385, 4, 116, 318, 414, 1579, 110, 1483, 537, +- /* 1940 */ 320, 567, 1350, 555, 42, 579, 571, 1349, 1198, 383, +- /* 1950 */ 276, 390, 216, 389, 278, 279, 1028, 1028, 1030, 1031, +- /* 1960 */ 35, 172, 580, 1265, 458, 1260, 415, 416, 185, 156, +- /* 1970 */ 452, 1534, 1535, 173, 1533, 1532, 89, 308, 225, 226, +- /* 1980 */ 846, 174, 565, 453, 217, 1188, 322, 236, 1102, 154, +- /* 1990 */ 1100, 330, 187, 176, 1223, 243, 189, 925, 338, 246, +- /* 2000 */ 1116, 194, 177, 425, 178, 427, 98, 196, 99, 100, +- /* 2010 */ 101, 1040, 179, 1119, 1115, 248, 249, 121, 121, 163, +- /* 2020 */ 24, 250, 349, 1238, 496, 122, 1108, 452, 577, 452, +- /* 2030 */ 1192, 454, 1028, 266, 292, 200, 252, 201, 861, 396, +- /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256, +- /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239, +- /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326, +- /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309, +- /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155, +- /* 2090 */ 17, 1154, 230, 1188, 284, 286, 265, 204, 125, 1171, +- /* 2100 */ 241, 28, 978, 972, 29, 41, 1175, 1179, 175, 1173, +- /* 2110 */ 30, 43, 31, 8, 241, 1178, 32, 1160, 208, 549, +- /* 2120 */ 33, 111, 175, 1083, 1070, 43, 1068, 1072, 240, 113, +- /* 2130 */ 114, 34, 561, 118, 1124, 271, 1073, 36, 18, 572, +- /* 2140 */ 1033, 873, 240, 124, 37, 935, 272, 273, 1617, 183, +- /* 2150 */ 153, 394, 1194, 1193, 1256, 1256, 1256, 1256, 1256, 1256, +- /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567, +- /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256, +- /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256, +- /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256, +- /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458, ++ /* 0 */ 134, 131, 238, 290, 290, 1353, 593, 1332, 478, 1606, ++ /* 10 */ 593, 1315, 593, 7, 593, 1353, 590, 593, 579, 424, ++ /* 20 */ 1566, 134, 131, 238, 1318, 541, 478, 477, 575, 84, ++ /* 30 */ 84, 1005, 303, 84, 84, 51, 51, 63, 63, 1006, ++ /* 40 */ 84, 84, 498, 141, 142, 93, 442, 1254, 1254, 1085, ++ /* 50 */ 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, 424, ++ /* 60 */ 296, 296, 498, 296, 296, 567, 553, 296, 296, 1306, ++ /* 70 */ 574, 1358, 1358, 590, 542, 579, 590, 574, 579, 548, ++ /* 80 */ 590, 1304, 579, 141, 142, 93, 576, 1254, 1254, 1085, ++ /* 90 */ 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, 399, ++ /* 100 */ 478, 395, 6, 138, 138, 138, 138, 137, 137, 136, ++ /* 110 */ 136, 136, 135, 132, 463, 44, 342, 593, 305, 1127, ++ /* 120 */ 1280, 1, 1, 599, 2, 1284, 598, 1200, 1284, 1200, ++ /* 130 */ 330, 424, 158, 330, 1613, 158, 390, 116, 308, 1366, ++ /* 140 */ 51, 51, 1366, 138, 138, 138, 138, 137, 137, 136, ++ /* 150 */ 136, 136, 135, 132, 463, 141, 142, 93, 515, 1254, ++ /* 160 */ 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, ++ /* 170 */ 140, 1230, 329, 584, 296, 296, 212, 296, 296, 568, ++ /* 180 */ 568, 488, 143, 1072, 1072, 1086, 1089, 590, 1195, 579, ++ /* 190 */ 590, 340, 579, 140, 140, 140, 140, 133, 392, 564, ++ /* 200 */ 536, 1195, 250, 425, 1195, 250, 137, 137, 136, 136, ++ /* 210 */ 136, 135, 132, 463, 291, 138, 138, 138, 138, 137, ++ /* 220 */ 137, 136, 136, 136, 135, 132, 463, 966, 1230, 1231, ++ /* 230 */ 1230, 412, 965, 467, 412, 424, 467, 489, 357, 1611, ++ /* 240 */ 391, 138, 138, 138, 138, 137, 137, 136, 136, 136, ++ /* 250 */ 135, 132, 463, 463, 134, 131, 238, 555, 1076, 141, ++ /* 260 */ 142, 93, 593, 1254, 1254, 1085, 1088, 1075, 1075, 139, ++ /* 270 */ 139, 140, 140, 140, 140, 1317, 134, 131, 238, 424, ++ /* 280 */ 549, 1597, 1531, 333, 97, 83, 83, 140, 140, 140, ++ /* 290 */ 140, 138, 138, 138, 138, 137, 137, 136, 136, 136, ++ /* 300 */ 135, 132, 463, 141, 142, 93, 1657, 1254, 1254, 1085, ++ /* 310 */ 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, 138, ++ /* 320 */ 138, 138, 138, 137, 137, 136, 136, 136, 135, 132, ++ /* 330 */ 463, 591, 1230, 958, 958, 138, 138, 138, 138, 137, ++ /* 340 */ 137, 136, 136, 136, 135, 132, 463, 44, 398, 547, ++ /* 350 */ 1306, 136, 136, 136, 135, 132, 463, 386, 593, 442, ++ /* 360 */ 595, 145, 595, 138, 138, 138, 138, 137, 137, 136, ++ /* 370 */ 136, 136, 135, 132, 463, 500, 1230, 112, 550, 460, ++ /* 380 */ 459, 51, 51, 424, 296, 296, 479, 334, 1259, 1230, ++ /* 390 */ 1231, 1230, 1599, 1261, 388, 312, 444, 590, 246, 579, ++ /* 400 */ 546, 1260, 271, 235, 329, 584, 551, 141, 142, 93, ++ /* 410 */ 429, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, ++ /* 420 */ 140, 140, 140, 22, 22, 1230, 1262, 424, 1262, 216, ++ /* 430 */ 296, 296, 98, 1230, 1231, 1230, 264, 884, 45, 528, ++ /* 440 */ 525, 524, 1041, 590, 1269, 579, 421, 420, 393, 523, ++ /* 450 */ 44, 141, 142, 93, 498, 1254, 1254, 1085, 1088, 1075, ++ /* 460 */ 1075, 139, 139, 140, 140, 140, 140, 138, 138, 138, ++ /* 470 */ 138, 137, 137, 136, 136, 136, 135, 132, 463, 593, ++ /* 480 */ 1611, 561, 1230, 1231, 1230, 23, 264, 515, 200, 528, ++ /* 490 */ 525, 524, 127, 585, 509, 4, 355, 487, 506, 523, ++ /* 500 */ 593, 498, 84, 84, 134, 131, 238, 329, 584, 588, ++ /* 510 */ 1627, 138, 138, 138, 138, 137, 137, 136, 136, 136, ++ /* 520 */ 135, 132, 463, 19, 19, 435, 1230, 1460, 297, 297, ++ /* 530 */ 311, 424, 1565, 464, 1631, 599, 2, 1284, 437, 574, ++ /* 540 */ 1107, 590, 330, 579, 158, 582, 489, 357, 573, 593, ++ /* 550 */ 592, 1366, 409, 1274, 1230, 141, 142, 93, 1364, 1254, ++ /* 560 */ 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, ++ /* 570 */ 140, 389, 84, 84, 1062, 567, 1230, 313, 1523, 593, ++ /* 580 */ 125, 125, 970, 1230, 1231, 1230, 296, 296, 126, 46, ++ /* 590 */ 464, 594, 464, 296, 296, 1050, 1230, 218, 439, 590, ++ /* 600 */ 1604, 579, 84, 84, 7, 403, 590, 515, 579, 325, ++ /* 610 */ 417, 1230, 1231, 1230, 250, 138, 138, 138, 138, 137, ++ /* 620 */ 137, 136, 136, 136, 135, 132, 463, 1050, 1050, 1052, ++ /* 630 */ 1053, 35, 1275, 1230, 1231, 1230, 424, 1370, 993, 574, ++ /* 640 */ 371, 414, 274, 412, 1597, 467, 1302, 552, 451, 590, ++ /* 650 */ 543, 579, 1530, 1230, 1231, 1230, 1214, 201, 409, 1174, ++ /* 660 */ 141, 142, 93, 223, 1254, 1254, 1085, 1088, 1075, 1075, ++ /* 670 */ 139, 139, 140, 140, 140, 140, 296, 296, 1250, 593, ++ /* 680 */ 424, 296, 296, 236, 529, 296, 296, 515, 100, 590, ++ /* 690 */ 1600, 579, 48, 1605, 590, 1230, 579, 7, 590, 577, ++ /* 700 */ 579, 904, 84, 84, 141, 142, 93, 496, 1254, 1254, ++ /* 710 */ 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, ++ /* 720 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135, ++ /* 730 */ 132, 463, 1365, 1230, 296, 296, 1250, 115, 1275, 326, ++ /* 740 */ 233, 539, 1062, 40, 282, 127, 585, 590, 4, 579, ++ /* 750 */ 329, 584, 1230, 1231, 1230, 1598, 593, 388, 904, 1051, ++ /* 760 */ 1356, 1356, 588, 1050, 138, 138, 138, 138, 137, 137, ++ /* 770 */ 136, 136, 136, 135, 132, 463, 185, 593, 1230, 19, ++ /* 780 */ 19, 1230, 971, 1597, 424, 1651, 464, 129, 908, 1195, ++ /* 790 */ 1230, 1231, 1230, 1325, 443, 1050, 1050, 1052, 582, 1603, ++ /* 800 */ 149, 149, 1195, 7, 5, 1195, 1687, 410, 141, 142, ++ /* 810 */ 93, 1536, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, ++ /* 820 */ 140, 140, 140, 140, 1214, 397, 593, 1062, 424, 1536, ++ /* 830 */ 1538, 50, 901, 125, 125, 1230, 1231, 1230, 1230, 1231, ++ /* 840 */ 1230, 126, 1230, 464, 594, 464, 515, 1230, 1050, 84, ++ /* 850 */ 84, 3, 141, 142, 93, 924, 1254, 1254, 1085, 1088, ++ /* 860 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 138, 138, ++ /* 870 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 463, ++ /* 880 */ 1050, 1050, 1052, 1053, 35, 442, 457, 532, 433, 1230, ++ /* 890 */ 1062, 1361, 540, 540, 1598, 925, 388, 7, 1129, 1230, ++ /* 900 */ 1231, 1230, 1129, 1536, 1230, 1231, 1230, 1051, 570, 1214, ++ /* 910 */ 593, 1050, 138, 138, 138, 138, 137, 137, 136, 136, ++ /* 920 */ 136, 135, 132, 463, 6, 185, 1195, 1230, 231, 593, ++ /* 930 */ 382, 992, 424, 151, 151, 510, 1213, 557, 482, 1195, ++ /* 940 */ 381, 160, 1195, 1050, 1050, 1052, 1230, 1231, 1230, 422, ++ /* 950 */ 593, 447, 84, 84, 593, 217, 141, 142, 93, 593, ++ /* 960 */ 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, ++ /* 970 */ 140, 140, 1214, 19, 19, 593, 424, 19, 19, 442, ++ /* 980 */ 1063, 442, 19, 19, 1230, 1231, 1230, 515, 445, 458, ++ /* 990 */ 1597, 386, 315, 1175, 1685, 556, 1685, 450, 84, 84, ++ /* 1000 */ 141, 142, 93, 505, 1254, 1254, 1085, 1088, 1075, 1075, ++ /* 1010 */ 139, 139, 140, 140, 140, 140, 138, 138, 138, 138, ++ /* 1020 */ 137, 137, 136, 136, 136, 135, 132, 463, 442, 1147, ++ /* 1030 */ 454, 1597, 362, 1041, 593, 462, 1460, 1233, 47, 1393, ++ /* 1040 */ 324, 565, 565, 115, 1148, 449, 7, 460, 459, 307, ++ /* 1050 */ 375, 354, 593, 113, 593, 329, 584, 19, 19, 1149, ++ /* 1060 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135, ++ /* 1070 */ 132, 463, 209, 1173, 563, 19, 19, 19, 19, 49, ++ /* 1080 */ 424, 944, 1175, 1686, 1046, 1686, 218, 355, 484, 343, ++ /* 1090 */ 210, 945, 569, 562, 1262, 1233, 1262, 490, 314, 423, ++ /* 1100 */ 424, 1598, 1206, 388, 141, 142, 93, 440, 1254, 1254, ++ /* 1110 */ 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, ++ /* 1120 */ 352, 316, 531, 316, 141, 142, 93, 549, 1254, 1254, ++ /* 1130 */ 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, ++ /* 1140 */ 446, 10, 1598, 274, 388, 915, 281, 299, 383, 534, ++ /* 1150 */ 378, 533, 269, 593, 1206, 587, 587, 587, 374, 293, ++ /* 1160 */ 1579, 991, 1173, 302, 138, 138, 138, 138, 137, 137, ++ /* 1170 */ 136, 136, 136, 135, 132, 463, 53, 53, 520, 1250, ++ /* 1180 */ 593, 1147, 1576, 431, 138, 138, 138, 138, 137, 137, ++ /* 1190 */ 136, 136, 136, 135, 132, 463, 1148, 301, 593, 1577, ++ /* 1200 */ 593, 1307, 431, 54, 54, 593, 268, 593, 461, 461, ++ /* 1210 */ 461, 1149, 347, 492, 424, 135, 132, 463, 1146, 1195, ++ /* 1220 */ 474, 68, 68, 69, 69, 550, 332, 287, 21, 21, ++ /* 1230 */ 55, 55, 1195, 581, 424, 1195, 309, 1250, 141, 142, ++ /* 1240 */ 93, 119, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, ++ /* 1250 */ 140, 140, 140, 140, 593, 237, 480, 1476, 141, 142, ++ /* 1260 */ 93, 593, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, ++ /* 1270 */ 140, 140, 140, 140, 344, 430, 346, 70, 70, 494, ++ /* 1280 */ 991, 1132, 1132, 512, 56, 56, 1269, 593, 268, 593, ++ /* 1290 */ 369, 374, 593, 481, 215, 384, 1624, 481, 138, 138, ++ /* 1300 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 463, ++ /* 1310 */ 71, 71, 72, 72, 225, 73, 73, 593, 138, 138, ++ /* 1320 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 463, ++ /* 1330 */ 586, 431, 593, 872, 873, 874, 593, 911, 593, 1602, ++ /* 1340 */ 74, 74, 593, 7, 1460, 242, 593, 306, 424, 1578, ++ /* 1350 */ 472, 306, 364, 219, 367, 75, 75, 430, 345, 57, ++ /* 1360 */ 57, 58, 58, 432, 187, 59, 59, 593, 424, 61, ++ /* 1370 */ 61, 1475, 141, 142, 93, 123, 1254, 1254, 1085, 1088, ++ /* 1380 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 424, 570, ++ /* 1390 */ 62, 62, 141, 142, 93, 911, 1254, 1254, 1085, 1088, ++ /* 1400 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 161, 384, ++ /* 1410 */ 1624, 1474, 141, 130, 93, 441, 1254, 1254, 1085, 1088, ++ /* 1420 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 267, 266, ++ /* 1430 */ 265, 1460, 138, 138, 138, 138, 137, 137, 136, 136, ++ /* 1440 */ 136, 135, 132, 463, 593, 1336, 593, 1269, 1460, 384, ++ /* 1450 */ 1624, 231, 138, 138, 138, 138, 137, 137, 136, 136, ++ /* 1460 */ 136, 135, 132, 463, 593, 163, 593, 76, 76, 77, ++ /* 1470 */ 77, 593, 138, 138, 138, 138, 137, 137, 136, 136, ++ /* 1480 */ 136, 135, 132, 463, 475, 593, 483, 78, 78, 20, ++ /* 1490 */ 20, 1249, 424, 491, 79, 79, 495, 422, 295, 235, ++ /* 1500 */ 1574, 38, 511, 896, 422, 335, 240, 422, 147, 147, ++ /* 1510 */ 112, 593, 424, 593, 101, 222, 991, 142, 93, 455, ++ /* 1520 */ 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, ++ /* 1530 */ 140, 140, 593, 39, 148, 148, 80, 80, 93, 551, ++ /* 1540 */ 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, ++ /* 1550 */ 140, 140, 328, 923, 922, 64, 64, 502, 1656, 1005, ++ /* 1560 */ 933, 896, 124, 422, 121, 254, 593, 1006, 593, 226, ++ /* 1570 */ 593, 127, 585, 164, 4, 16, 138, 138, 138, 138, ++ /* 1580 */ 137, 137, 136, 136, 136, 135, 132, 463, 588, 81, ++ /* 1590 */ 81, 65, 65, 82, 82, 593, 138, 138, 138, 138, ++ /* 1600 */ 137, 137, 136, 136, 136, 135, 132, 463, 593, 226, ++ /* 1610 */ 237, 966, 464, 593, 298, 593, 965, 593, 66, 66, ++ /* 1620 */ 593, 1170, 593, 411, 582, 353, 469, 115, 593, 471, ++ /* 1630 */ 169, 173, 173, 593, 44, 991, 174, 174, 89, 89, ++ /* 1640 */ 67, 67, 593, 85, 85, 150, 150, 1114, 1043, 593, ++ /* 1650 */ 273, 86, 86, 1062, 593, 503, 171, 171, 593, 125, ++ /* 1660 */ 125, 497, 593, 273, 336, 152, 152, 126, 1335, 464, ++ /* 1670 */ 594, 464, 146, 146, 1050, 593, 545, 172, 172, 593, ++ /* 1680 */ 1054, 165, 165, 256, 339, 156, 156, 127, 585, 1586, ++ /* 1690 */ 4, 329, 584, 499, 358, 273, 115, 348, 155, 155, ++ /* 1700 */ 930, 931, 153, 153, 588, 1114, 1050, 1050, 1052, 1053, ++ /* 1710 */ 35, 1554, 521, 593, 270, 1008, 1009, 9, 593, 372, ++ /* 1720 */ 593, 115, 593, 168, 593, 115, 593, 1110, 464, 270, ++ /* 1730 */ 996, 964, 273, 129, 1645, 1214, 154, 154, 1054, 1404, ++ /* 1740 */ 582, 88, 88, 90, 90, 87, 87, 52, 52, 60, ++ /* 1750 */ 60, 1405, 504, 537, 559, 1179, 961, 507, 129, 558, ++ /* 1760 */ 127, 585, 1126, 4, 1126, 1125, 894, 1125, 162, 1062, ++ /* 1770 */ 963, 359, 129, 1401, 363, 125, 125, 588, 366, 368, ++ /* 1780 */ 370, 1349, 1334, 126, 1333, 464, 594, 464, 377, 387, ++ /* 1790 */ 1050, 1391, 1414, 1618, 1459, 1387, 1399, 208, 580, 1464, ++ /* 1800 */ 1314, 464, 243, 516, 1305, 1293, 1384, 1292, 1294, 1638, ++ /* 1810 */ 288, 170, 228, 582, 12, 408, 321, 322, 241, 323, ++ /* 1820 */ 245, 1446, 1050, 1050, 1052, 1053, 35, 559, 304, 350, ++ /* 1830 */ 351, 501, 560, 127, 585, 1441, 4, 1451, 1434, 310, ++ /* 1840 */ 1450, 526, 1062, 1332, 415, 380, 232, 1527, 125, 125, ++ /* 1850 */ 588, 1214, 1396, 356, 1526, 583, 126, 1397, 464, 594, ++ /* 1860 */ 464, 1641, 535, 1050, 1581, 1395, 1269, 1583, 1582, 213, ++ /* 1870 */ 402, 277, 214, 227, 464, 1573, 239, 1571, 1266, 1394, ++ /* 1880 */ 434, 198, 100, 224, 96, 183, 582, 191, 485, 193, ++ /* 1890 */ 486, 194, 195, 196, 519, 1050, 1050, 1052, 1053, 35, ++ /* 1900 */ 559, 113, 252, 413, 1447, 558, 493, 13, 1455, 416, ++ /* 1910 */ 1453, 1452, 14, 202, 1521, 1062, 1532, 508, 258, 106, ++ /* 1920 */ 514, 125, 125, 99, 1214, 1543, 289, 260, 206, 126, ++ /* 1930 */ 365, 464, 594, 464, 361, 517, 1050, 261, 448, 1295, ++ /* 1940 */ 262, 418, 1352, 1351, 108, 1350, 1655, 1654, 1343, 915, ++ /* 1950 */ 419, 1322, 233, 452, 319, 379, 1321, 453, 1623, 320, ++ /* 1960 */ 1320, 275, 1653, 544, 276, 1609, 1608, 1342, 1050, 1050, ++ /* 1970 */ 1052, 1053, 35, 1630, 1218, 466, 385, 456, 300, 1419, ++ /* 1980 */ 144, 1418, 570, 407, 407, 406, 284, 404, 11, 1508, ++ /* 1990 */ 881, 396, 120, 127, 585, 394, 4, 1214, 327, 114, ++ /* 2000 */ 1375, 1374, 220, 247, 400, 338, 401, 554, 42, 1224, ++ /* 2010 */ 588, 596, 283, 337, 285, 286, 188, 597, 1290, 1285, ++ /* 2020 */ 175, 1558, 176, 1559, 1557, 1556, 159, 317, 229, 177, ++ /* 2030 */ 868, 230, 91, 465, 464, 221, 331, 468, 1165, 470, ++ /* 2040 */ 473, 94, 244, 95, 249, 189, 582, 1124, 1122, 341, ++ /* 2050 */ 427, 190, 178, 1249, 179, 43, 192, 947, 349, 428, ++ /* 2060 */ 1138, 197, 251, 180, 181, 436, 102, 182, 438, 103, ++ /* 2070 */ 104, 199, 248, 1140, 253, 1062, 105, 255, 1137, 166, ++ /* 2080 */ 24, 125, 125, 257, 1264, 273, 360, 513, 259, 126, ++ /* 2090 */ 15, 464, 594, 464, 204, 883, 1050, 518, 263, 373, ++ /* 2100 */ 381, 92, 585, 1130, 4, 203, 205, 426, 107, 522, ++ /* 2110 */ 25, 26, 329, 584, 913, 572, 527, 376, 588, 926, ++ /* 2120 */ 530, 109, 184, 318, 167, 110, 27, 538, 1050, 1050, ++ /* 2130 */ 1052, 1053, 35, 1211, 1091, 17, 476, 111, 1181, 234, ++ /* 2140 */ 292, 1180, 464, 294, 207, 994, 129, 1201, 272, 1000, ++ /* 2150 */ 28, 1197, 29, 30, 582, 1199, 1205, 1214, 31, 1204, ++ /* 2160 */ 32, 1186, 41, 566, 33, 1105, 211, 8, 115, 1092, ++ /* 2170 */ 1090, 1094, 34, 278, 578, 1095, 117, 122, 118, 1145, ++ /* 2180 */ 36, 18, 128, 1062, 1055, 895, 957, 37, 589, 125, ++ /* 2190 */ 125, 279, 186, 280, 1646, 157, 405, 126, 1220, 464, ++ /* 2200 */ 594, 464, 1218, 466, 1050, 1219, 300, 1281, 1281, 1281, ++ /* 2210 */ 1281, 407, 407, 406, 284, 404, 1281, 1281, 881, 1281, ++ /* 2220 */ 300, 1281, 1281, 571, 1281, 407, 407, 406, 284, 404, ++ /* 2230 */ 1281, 247, 881, 338, 1281, 1281, 1050, 1050, 1052, 1053, ++ /* 2240 */ 35, 337, 1281, 1281, 1281, 247, 1281, 338, 1281, 1281, ++ /* 2250 */ 1281, 1281, 1281, 1281, 1281, 337, 1281, 1281, 1281, 1281, ++ /* 2260 */ 1281, 1281, 1281, 1281, 1281, 1214, 1281, 1281, 1281, 1281, ++ /* 2270 */ 1281, 1281, 249, 1281, 1281, 1281, 1281, 1281, 1281, 1281, ++ /* 2280 */ 178, 1281, 1281, 43, 1281, 1281, 249, 1281, 1281, 1281, ++ /* 2290 */ 1281, 1281, 1281, 1281, 178, 1281, 1281, 43, 1281, 1281, ++ /* 2300 */ 248, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, ++ /* 2310 */ 1281, 1281, 1281, 1281, 248, 1281, 1281, 1281, 1281, 1281, ++ /* 2320 */ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, ++ /* 2330 */ 1281, 1281, 1281, 1281, 1281, 426, 1281, 1281, 1281, 1281, ++ /* 2340 */ 329, 584, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 426, ++ /* 2350 */ 1281, 1281, 1281, 1281, 329, 584, 1281, 1281, 1281, 1281, ++ /* 2360 */ 1281, 1281, 1281, 1281, 476, 1281, 1281, 1281, 1281, 1281, ++ /* 2370 */ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 476, + }; + static const YYCODETYPE yy_lookahead[] = { +- /* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 241, +- /* 10 */ 242, 195, 217, 221, 195, 235, 254, 195, 256, 19, +- /* 20 */ 225, 298, 254, 195, 256, 206, 213, 214, 206, 218, +- /* 30 */ 219, 31, 206, 195, 218, 219, 195, 218, 219, 39, +- /* 40 */ 218, 219, 313, 43, 44, 45, 317, 47, 48, 49, ++ /* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 312, ++ /* 10 */ 195, 218, 195, 316, 195, 235, 254, 195, 256, 19, ++ /* 20 */ 297, 277, 278, 279, 218, 206, 213, 214, 206, 218, ++ /* 30 */ 219, 31, 206, 218, 219, 218, 219, 218, 219, 39, ++ /* 40 */ 218, 219, 195, 43, 44, 45, 195, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, +- /* 60 */ 241, 242, 195, 241, 242, 195, 255, 241, 242, 277, +- /* 70 */ 278, 279, 234, 254, 255, 256, 254, 255, 256, 218, +- /* 80 */ 254, 240, 256, 43, 44, 45, 264, 47, 48, 49, +- /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 271, +- /* 100 */ 287, 22, 23, 103, 104, 105, 106, 107, 108, 109, +- /* 110 */ 110, 111, 112, 113, 114, 114, 47, 48, 49, 50, ++ /* 60 */ 241, 242, 195, 241, 242, 195, 255, 241, 242, 195, ++ /* 70 */ 255, 237, 238, 254, 255, 256, 254, 255, 256, 264, ++ /* 80 */ 254, 207, 256, 43, 44, 45, 264, 47, 48, 49, ++ /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 251, ++ /* 100 */ 287, 253, 215, 103, 104, 105, 106, 107, 108, 109, ++ /* 110 */ 110, 111, 112, 113, 114, 82, 265, 195, 271, 11, + /* 120 */ 187, 188, 189, 190, 191, 192, 190, 87, 192, 89, +- /* 130 */ 197, 19, 199, 197, 318, 199, 320, 25, 195, 206, +- /* 140 */ 299, 271, 206, 103, 104, 105, 106, 107, 108, 109, ++ /* 130 */ 197, 19, 199, 197, 317, 199, 319, 25, 271, 206, ++ /* 140 */ 218, 219, 206, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 195, 47, + /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, +- /* 170 */ 58, 60, 21, 195, 241, 242, 215, 241, 242, 312, +- /* 180 */ 313, 102, 70, 205, 317, 207, 242, 254, 77, 256, +- /* 190 */ 254, 122, 256, 55, 56, 57, 58, 59, 254, 88, +- /* 200 */ 256, 90, 269, 240, 93, 269, 107, 108, 109, 110, +- /* 210 */ 111, 112, 113, 114, 271, 103, 104, 105, 106, 107, +- /* 220 */ 108, 109, 110, 111, 112, 113, 114, 313, 117, 118, +- /* 230 */ 119, 317, 81, 195, 301, 19, 195, 301, 277, 278, +- /* 240 */ 279, 103, 104, 105, 106, 107, 108, 109, 110, 111, +- /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 195, 43, +- /* 260 */ 44, 45, 74, 47, 48, 49, 50, 51, 52, 53, +- /* 270 */ 54, 55, 56, 57, 58, 124, 195, 60, 109, 110, +- /* 280 */ 111, 112, 113, 114, 68, 195, 103, 104, 105, 106, +- /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 208, 218, +- /* 300 */ 219, 103, 104, 105, 106, 107, 108, 109, 110, 111, +- /* 310 */ 112, 113, 114, 162, 233, 24, 128, 129, 130, 103, ++ /* 170 */ 58, 60, 139, 140, 241, 242, 289, 241, 242, 309, ++ /* 180 */ 310, 294, 70, 47, 48, 49, 50, 254, 77, 256, ++ /* 190 */ 254, 195, 256, 55, 56, 57, 58, 59, 221, 88, ++ /* 200 */ 109, 90, 269, 240, 93, 269, 107, 108, 109, 110, ++ /* 210 */ 111, 112, 113, 114, 215, 103, 104, 105, 106, 107, ++ /* 220 */ 108, 109, 110, 111, 112, 113, 114, 136, 117, 118, ++ /* 230 */ 119, 298, 141, 300, 298, 19, 300, 129, 130, 317, ++ /* 240 */ 318, 103, 104, 105, 106, 107, 108, 109, 110, 111, ++ /* 250 */ 112, 113, 114, 114, 277, 278, 279, 146, 122, 43, ++ /* 260 */ 44, 45, 195, 47, 48, 49, 50, 51, 52, 53, ++ /* 270 */ 54, 55, 56, 57, 58, 218, 277, 278, 279, 19, ++ /* 280 */ 19, 195, 286, 23, 68, 218, 219, 55, 56, 57, ++ /* 290 */ 58, 103, 104, 105, 106, 107, 108, 109, 110, 111, ++ /* 300 */ 112, 113, 114, 43, 44, 45, 232, 47, 48, 49, ++ /* 310 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 103, + /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, +- /* 330 */ 114, 195, 195, 215, 117, 118, 119, 120, 195, 19, +- /* 340 */ 123, 124, 125, 207, 24, 74, 246, 60, 310, 311, +- /* 350 */ 133, 60, 311, 82, 22, 218, 219, 257, 195, 19, +- /* 360 */ 73, 218, 219, 43, 44, 45, 206, 47, 48, 49, +- /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 22, +- /* 380 */ 23, 218, 219, 43, 44, 45, 54, 47, 48, 49, +- /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 128, +- /* 400 */ 82, 241, 242, 195, 117, 118, 119, 289, 60, 118, +- /* 410 */ 139, 140, 294, 195, 254, 195, 256, 195, 255, 259, +- /* 420 */ 260, 73, 22, 103, 104, 105, 106, 107, 108, 109, +- /* 430 */ 110, 111, 112, 113, 114, 206, 218, 219, 218, 219, +- /* 440 */ 218, 219, 234, 103, 104, 105, 106, 107, 108, 109, +- /* 450 */ 110, 111, 112, 113, 114, 318, 319, 139, 140, 102, +- /* 460 */ 60, 318, 319, 221, 19, 117, 118, 119, 23, 195, +- /* 470 */ 241, 242, 313, 255, 206, 255, 317, 255, 206, 129, +- /* 480 */ 130, 206, 264, 254, 264, 256, 264, 195, 43, 44, +- /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, +- /* 500 */ 55, 56, 57, 58, 246, 213, 214, 19, 19, 241, +- /* 510 */ 242, 195, 23, 241, 242, 257, 241, 242, 118, 277, +- /* 520 */ 278, 279, 254, 29, 256, 60, 254, 33, 256, 254, +- /* 530 */ 206, 256, 43, 44, 45, 218, 47, 48, 49, 50, +- /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, +- /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, +- /* 560 */ 66, 19, 218, 60, 120, 241, 242, 123, 124, 125, +- /* 570 */ 60, 232, 77, 19, 20, 26, 22, 133, 254, 287, +- /* 580 */ 256, 265, 117, 118, 119, 90, 312, 313, 93, 47, +- /* 590 */ 36, 317, 103, 104, 105, 106, 107, 108, 109, 110, +- /* 600 */ 111, 112, 113, 114, 116, 117, 277, 278, 279, 60, +- /* 610 */ 107, 108, 19, 276, 60, 31, 23, 152, 195, 116, +- /* 620 */ 117, 118, 119, 39, 121, 276, 72, 117, 118, 119, +- /* 630 */ 166, 167, 129, 145, 237, 238, 43, 44, 45, 276, +- /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, +- /* 650 */ 57, 58, 315, 316, 144, 101, 19, 154, 116, 156, +- /* 660 */ 23, 107, 108, 109, 315, 316, 117, 118, 119, 115, +- /* 670 */ 60, 117, 118, 119, 132, 200, 122, 60, 315, 316, +- /* 680 */ 43, 44, 45, 272, 47, 48, 49, 50, 51, 52, +- /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, +- /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, +- /* 710 */ 156, 157, 158, 212, 213, 214, 22, 195, 101, 22, +- /* 720 */ 60, 19, 20, 60, 22, 139, 140, 117, 118, 119, +- /* 730 */ 22, 251, 195, 253, 117, 118, 195, 183, 36, 122, +- /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, +- /* 750 */ 113, 114, 195, 195, 60, 218, 219, 60, 195, 284, +- /* 760 */ 19, 25, 60, 288, 23, 237, 238, 22, 60, 109, +- /* 770 */ 233, 154, 155, 156, 72, 218, 219, 117, 118, 119, +- /* 780 */ 117, 118, 119, 116, 43, 44, 45, 265, 47, 48, +- /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, +- /* 800 */ 183, 243, 25, 101, 19, 60, 265, 144, 23, 107, +- /* 810 */ 108, 117, 118, 119, 117, 118, 119, 115, 151, 117, +- /* 820 */ 118, 119, 82, 195, 122, 117, 118, 119, 43, 44, +- /* 830 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, +- /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, +- /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, +- /* 860 */ 158, 121, 117, 118, 119, 307, 101, 309, 195, 22, +- /* 870 */ 23, 195, 25, 19, 35, 139, 140, 195, 24, 139, +- /* 880 */ 140, 208, 195, 118, 109, 183, 22, 122, 103, 104, +- /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, +- /* 900 */ 304, 305, 77, 230, 127, 232, 67, 195, 19, 195, +- /* 910 */ 195, 136, 23, 88, 75, 90, 141, 203, 93, 154, +- /* 920 */ 155, 156, 208, 295, 60, 243, 22, 23, 19, 25, +- /* 930 */ 218, 219, 43, 44, 45, 100, 47, 48, 49, 50, +- /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 183, 102, +- /* 950 */ 96, 195, 43, 44, 45, 240, 47, 48, 49, 50, +- /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 134, +- /* 970 */ 131, 146, 25, 286, 120, 121, 122, 123, 124, 125, +- /* 980 */ 126, 117, 118, 119, 313, 195, 132, 195, 317, 307, +- /* 990 */ 195, 309, 103, 104, 105, 106, 107, 108, 109, 110, +- /* 1000 */ 111, 112, 113, 114, 195, 195, 102, 195, 195, 195, +- /* 1010 */ 218, 219, 103, 104, 105, 106, 107, 108, 109, 110, +- /* 1020 */ 111, 112, 113, 114, 77, 233, 195, 60, 218, 219, +- /* 1030 */ 218, 219, 218, 219, 23, 195, 25, 90, 243, 159, +- /* 1040 */ 93, 161, 19, 233, 195, 233, 23, 233, 16, 218, +- /* 1050 */ 219, 195, 243, 212, 213, 214, 262, 263, 218, 219, +- /* 1060 */ 195, 271, 19, 307, 233, 309, 43, 44, 45, 160, +- /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, +- /* 1080 */ 57, 58, 195, 218, 219, 118, 43, 44, 45, 240, +- /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, +- /* 1100 */ 57, 58, 307, 195, 309, 218, 219, 263, 12, 195, +- /* 1110 */ 78, 267, 80, 112, 113, 114, 307, 22, 309, 24, +- /* 1120 */ 255, 281, 266, 27, 107, 108, 103, 104, 105, 106, +- /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 195, +- /* 1140 */ 11, 22, 255, 24, 195, 195, 103, 104, 105, 106, +- /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 19, 195, +- /* 1160 */ 64, 195, 218, 219, 195, 313, 195, 218, 219, 317, +- /* 1170 */ 74, 154, 195, 156, 195, 195, 19, 233, 23, 60, +- /* 1180 */ 25, 24, 218, 219, 218, 219, 195, 218, 219, 218, +- /* 1190 */ 219, 128, 129, 130, 162, 263, 19, 218, 219, 267, +- /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, +- /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 240, 228, 255, +- /* 1220 */ 43, 44, 45, 25, 47, 48, 49, 50, 51, 52, +- /* 1230 */ 53, 54, 55, 56, 57, 58, 135, 118, 137, 138, +- /* 1240 */ 43, 44, 45, 22, 47, 48, 49, 50, 51, 52, +- /* 1250 */ 53, 54, 55, 56, 57, 58, 117, 266, 129, 130, +- /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, +- /* 1270 */ 113, 114, 195, 195, 119, 295, 195, 206, 195, 195, +- /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, +- /* 1290 */ 113, 114, 195, 195, 195, 218, 219, 195, 195, 144, +- /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, +- /* 1310 */ 113, 114, 241, 242, 67, 218, 219, 218, 219, 146, +- /* 1320 */ 19, 218, 219, 240, 215, 254, 136, 256, 107, 108, +- /* 1330 */ 195, 141, 255, 86, 128, 129, 130, 195, 165, 195, +- /* 1340 */ 19, 143, 95, 272, 25, 44, 45, 266, 47, 48, +- /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, +- /* 1360 */ 218, 219, 218, 219, 195, 12, 45, 195, 47, 48, +- /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, +- /* 1380 */ 27, 23, 7, 8, 9, 210, 211, 218, 219, 116, +- /* 1390 */ 218, 219, 228, 16, 147, 42, 195, 295, 195, 19, +- /* 1400 */ 20, 266, 22, 294, 103, 104, 105, 106, 107, 108, +- /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 218, +- /* 1420 */ 219, 218, 219, 195, 103, 104, 105, 106, 107, 108, +- /* 1430 */ 109, 110, 111, 112, 113, 114, 195, 154, 119, 156, +- /* 1440 */ 60, 189, 190, 191, 192, 195, 218, 219, 195, 197, +- /* 1450 */ 195, 199, 72, 195, 19, 78, 195, 80, 206, 218, +- /* 1460 */ 219, 195, 82, 144, 210, 211, 195, 15, 218, 219, +- /* 1470 */ 47, 218, 219, 218, 219, 259, 260, 195, 261, 218, +- /* 1480 */ 219, 101, 302, 303, 218, 219, 195, 107, 108, 218, +- /* 1490 */ 219, 150, 151, 241, 242, 115, 25, 117, 118, 119, +- /* 1500 */ 218, 219, 122, 195, 146, 195, 254, 195, 256, 218, +- /* 1510 */ 219, 246, 25, 61, 246, 19, 20, 195, 22, 139, +- /* 1520 */ 140, 269, 257, 195, 266, 257, 218, 219, 218, 219, +- /* 1530 */ 218, 219, 36, 246, 154, 155, 156, 157, 158, 116, +- /* 1540 */ 218, 219, 195, 22, 257, 49, 218, 219, 23, 195, +- /* 1550 */ 25, 195, 117, 301, 195, 25, 60, 195, 195, 23, +- /* 1560 */ 195, 25, 195, 183, 24, 218, 219, 130, 72, 195, +- /* 1570 */ 22, 195, 218, 219, 218, 219, 195, 218, 219, 195, +- /* 1580 */ 218, 219, 86, 218, 219, 218, 219, 91, 19, 20, +- /* 1590 */ 153, 22, 218, 219, 218, 219, 195, 101, 195, 218, +- /* 1600 */ 219, 195, 195, 107, 108, 36, 23, 195, 25, 195, +- /* 1610 */ 62, 115, 195, 117, 118, 119, 195, 146, 122, 218, +- /* 1620 */ 219, 218, 219, 195, 218, 219, 19, 60, 122, 60, +- /* 1630 */ 218, 219, 218, 219, 195, 218, 219, 150, 132, 218, +- /* 1640 */ 219, 72, 195, 23, 195, 25, 218, 219, 195, 60, +- /* 1650 */ 154, 155, 156, 157, 158, 86, 23, 195, 25, 195, +- /* 1660 */ 91, 19, 20, 142, 22, 218, 219, 218, 219, 130, +- /* 1670 */ 101, 218, 219, 143, 121, 122, 107, 108, 36, 183, +- /* 1680 */ 218, 219, 142, 60, 115, 118, 117, 118, 119, 7, +- /* 1690 */ 8, 122, 153, 23, 23, 25, 25, 23, 23, 25, +- /* 1700 */ 25, 23, 60, 25, 23, 98, 25, 118, 84, 85, +- /* 1710 */ 23, 23, 25, 25, 72, 154, 23, 156, 25, 23, +- /* 1720 */ 228, 25, 195, 154, 155, 156, 157, 158, 86, 195, +- /* 1730 */ 195, 258, 195, 91, 291, 322, 195, 195, 195, 195, +- /* 1740 */ 195, 118, 195, 101, 195, 195, 195, 195, 238, 107, +- /* 1750 */ 108, 195, 183, 195, 195, 195, 290, 115, 195, 117, +- /* 1760 */ 118, 119, 244, 195, 122, 195, 195, 195, 195, 195, +- /* 1770 */ 195, 258, 258, 258, 258, 193, 245, 300, 216, 274, +- /* 1780 */ 247, 270, 270, 274, 296, 296, 248, 222, 262, 198, +- /* 1790 */ 262, 274, 61, 274, 248, 231, 154, 155, 156, 157, +- /* 1800 */ 158, 0, 1, 2, 247, 227, 5, 221, 221, 221, +- /* 1810 */ 142, 10, 11, 12, 13, 14, 262, 262, 17, 202, +- /* 1820 */ 300, 19, 20, 300, 22, 183, 247, 251, 251, 245, +- /* 1830 */ 202, 30, 38, 32, 202, 152, 151, 22, 36, 43, +- /* 1840 */ 236, 40, 18, 202, 239, 239, 18, 239, 239, 283, +- /* 1850 */ 201, 150, 236, 202, 236, 201, 159, 202, 248, 248, +- /* 1860 */ 248, 248, 60, 63, 201, 275, 273, 275, 273, 275, +- /* 1870 */ 22, 286, 71, 223, 72, 202, 223, 297, 297, 202, +- /* 1880 */ 79, 201, 116, 82, 220, 201, 220, 220, 65, 293, +- /* 1890 */ 292, 229, 22, 166, 127, 226, 24, 114, 226, 223, +- /* 1900 */ 99, 222, 202, 101, 285, 92, 220, 308, 83, 107, +- /* 1910 */ 108, 220, 220, 316, 220, 285, 268, 115, 229, 117, +- /* 1920 */ 118, 119, 223, 321, 122, 268, 149, 146, 22, 19, +- /* 1930 */ 20, 202, 22, 159, 282, 134, 321, 148, 280, 147, +- /* 1940 */ 139, 140, 252, 141, 25, 204, 36, 252, 13, 251, +- /* 1950 */ 196, 248, 250, 249, 196, 6, 154, 155, 156, 157, +- /* 1960 */ 158, 209, 194, 194, 163, 194, 306, 306, 303, 224, +- /* 1970 */ 60, 215, 215, 209, 215, 215, 215, 224, 216, 216, +- /* 1980 */ 4, 209, 72, 3, 22, 183, 164, 15, 23, 16, +- /* 1990 */ 23, 140, 152, 131, 25, 24, 143, 20, 16, 145, +- /* 2000 */ 1, 143, 131, 62, 131, 37, 54, 152, 54, 54, +- /* 2010 */ 54, 101, 131, 117, 1, 34, 142, 107, 108, 5, +- /* 2020 */ 22, 116, 162, 76, 41, 115, 69, 117, 118, 119, +- /* 2030 */ 1, 2, 122, 25, 5, 69, 142, 116, 20, 10, +- /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126, +- /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30, +- /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40, +- /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68, +- /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23, +- /* 2090 */ 22, 98, 142, 183, 23, 23, 34, 22, 25, 89, +- /* 2100 */ 71, 34, 117, 144, 34, 22, 76, 76, 79, 87, +- /* 2110 */ 34, 82, 34, 44, 71, 94, 34, 23, 25, 24, +- /* 2120 */ 34, 25, 79, 23, 23, 82, 23, 23, 99, 143, +- /* 2130 */ 143, 22, 25, 25, 23, 22, 11, 22, 22, 25, +- /* 2140 */ 23, 23, 99, 22, 22, 136, 142, 142, 142, 25, +- /* 2150 */ 23, 15, 1, 1, 323, 323, 323, 323, 323, 323, +- /* 2160 */ 323, 323, 323, 134, 323, 323, 323, 323, 139, 140, +- /* 2170 */ 323, 323, 323, 323, 323, 323, 323, 134, 323, 323, +- /* 2180 */ 323, 323, 139, 140, 323, 323, 323, 323, 323, 323, +- /* 2190 */ 323, 323, 163, 323, 323, 323, 323, 323, 323, 323, +- /* 2200 */ 323, 323, 323, 323, 323, 323, 163, 323, 323, 323, +- /* 2210 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2220 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2230 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2240 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2250 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2260 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2270 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2280 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2290 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2300 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2310 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2320 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2330 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, +- /* 2340 */ 323, 187, 187, 187, 187, 187, 187, 187, 187, 187, +- /* 2350 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +- /* 2360 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +- /* 2370 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +- /* 2380 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +- /* 2390 */ 187, 187, 187, 187, ++ /* 330 */ 114, 135, 60, 137, 138, 103, 104, 105, 106, 107, ++ /* 340 */ 108, 109, 110, 111, 112, 113, 114, 82, 281, 206, ++ /* 350 */ 195, 109, 110, 111, 112, 113, 114, 195, 195, 195, ++ /* 360 */ 205, 22, 207, 103, 104, 105, 106, 107, 108, 109, ++ /* 370 */ 110, 111, 112, 113, 114, 195, 60, 116, 117, 107, ++ /* 380 */ 108, 218, 219, 19, 241, 242, 121, 23, 116, 117, ++ /* 390 */ 118, 119, 306, 121, 308, 206, 234, 254, 15, 256, ++ /* 400 */ 195, 129, 259, 260, 139, 140, 145, 43, 44, 45, ++ /* 410 */ 200, 47, 48, 49, 50, 51, 52, 53, 54, 55, ++ /* 420 */ 56, 57, 58, 218, 219, 60, 154, 19, 156, 265, ++ /* 430 */ 241, 242, 24, 117, 118, 119, 120, 21, 73, 123, ++ /* 440 */ 124, 125, 74, 254, 61, 256, 107, 108, 221, 133, ++ /* 450 */ 82, 43, 44, 45, 195, 47, 48, 49, 50, 51, ++ /* 460 */ 52, 53, 54, 55, 56, 57, 58, 103, 104, 105, ++ /* 470 */ 106, 107, 108, 109, 110, 111, 112, 113, 114, 195, ++ /* 480 */ 317, 318, 117, 118, 119, 22, 120, 195, 22, 123, ++ /* 490 */ 124, 125, 19, 20, 284, 22, 128, 81, 288, 133, ++ /* 500 */ 195, 195, 218, 219, 277, 278, 279, 139, 140, 36, ++ /* 510 */ 195, 103, 104, 105, 106, 107, 108, 109, 110, 111, ++ /* 520 */ 112, 113, 114, 218, 219, 62, 60, 195, 241, 242, ++ /* 530 */ 271, 19, 240, 60, 189, 190, 191, 192, 233, 255, ++ /* 540 */ 124, 254, 197, 256, 199, 72, 129, 130, 264, 195, ++ /* 550 */ 195, 206, 22, 23, 60, 43, 44, 45, 206, 47, ++ /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, ++ /* 570 */ 58, 195, 218, 219, 101, 195, 60, 271, 162, 195, ++ /* 580 */ 107, 108, 109, 117, 118, 119, 241, 242, 115, 73, ++ /* 590 */ 117, 118, 119, 241, 242, 122, 60, 195, 266, 254, ++ /* 600 */ 312, 256, 218, 219, 316, 203, 254, 195, 256, 255, ++ /* 610 */ 208, 117, 118, 119, 269, 103, 104, 105, 106, 107, ++ /* 620 */ 108, 109, 110, 111, 112, 113, 114, 154, 155, 156, ++ /* 630 */ 157, 158, 102, 117, 118, 119, 19, 242, 144, 255, ++ /* 640 */ 23, 206, 24, 298, 195, 300, 206, 195, 264, 254, ++ /* 650 */ 206, 256, 240, 117, 118, 119, 183, 22, 22, 23, ++ /* 660 */ 43, 44, 45, 151, 47, 48, 49, 50, 51, 52, ++ /* 670 */ 53, 54, 55, 56, 57, 58, 241, 242, 60, 195, ++ /* 680 */ 19, 241, 242, 195, 23, 241, 242, 195, 152, 254, ++ /* 690 */ 310, 256, 243, 312, 254, 60, 256, 316, 254, 206, ++ /* 700 */ 256, 60, 218, 219, 43, 44, 45, 272, 47, 48, ++ /* 710 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, ++ /* 720 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, ++ /* 730 */ 113, 114, 240, 60, 241, 242, 118, 25, 102, 255, ++ /* 740 */ 166, 167, 101, 22, 26, 19, 20, 254, 22, 256, ++ /* 750 */ 139, 140, 117, 118, 119, 306, 195, 308, 117, 118, ++ /* 760 */ 237, 238, 36, 122, 103, 104, 105, 106, 107, 108, ++ /* 770 */ 109, 110, 111, 112, 113, 114, 195, 195, 60, 218, ++ /* 780 */ 219, 60, 109, 195, 19, 217, 60, 25, 23, 77, ++ /* 790 */ 117, 118, 119, 225, 233, 154, 155, 156, 72, 312, ++ /* 800 */ 218, 219, 90, 316, 22, 93, 303, 304, 43, 44, ++ /* 810 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, ++ /* 820 */ 55, 56, 57, 58, 183, 195, 195, 101, 19, 213, ++ /* 830 */ 214, 243, 23, 107, 108, 117, 118, 119, 117, 118, ++ /* 840 */ 119, 115, 60, 117, 118, 119, 195, 60, 122, 218, ++ /* 850 */ 219, 22, 43, 44, 45, 35, 47, 48, 49, 50, ++ /* 860 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, ++ /* 870 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, ++ /* 880 */ 154, 155, 156, 157, 158, 195, 255, 67, 195, 60, ++ /* 890 */ 101, 240, 311, 312, 306, 75, 308, 316, 29, 117, ++ /* 900 */ 118, 119, 33, 287, 117, 118, 119, 118, 146, 183, ++ /* 910 */ 195, 122, 103, 104, 105, 106, 107, 108, 109, 110, ++ /* 920 */ 111, 112, 113, 114, 215, 195, 77, 60, 25, 195, ++ /* 930 */ 122, 144, 19, 218, 219, 66, 23, 88, 246, 90, ++ /* 940 */ 132, 25, 93, 154, 155, 156, 117, 118, 119, 257, ++ /* 950 */ 195, 131, 218, 219, 195, 265, 43, 44, 45, 195, ++ /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, ++ /* 970 */ 57, 58, 183, 218, 219, 195, 19, 218, 219, 195, ++ /* 980 */ 23, 195, 218, 219, 117, 118, 119, 195, 233, 255, ++ /* 990 */ 195, 195, 233, 22, 23, 146, 25, 233, 218, 219, ++ /* 1000 */ 43, 44, 45, 294, 47, 48, 49, 50, 51, 52, ++ /* 1010 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, ++ /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 12, ++ /* 1030 */ 234, 195, 240, 74, 195, 255, 195, 60, 243, 262, ++ /* 1040 */ 263, 311, 312, 25, 27, 19, 316, 107, 108, 265, ++ /* 1050 */ 24, 265, 195, 150, 195, 139, 140, 218, 219, 42, ++ /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, ++ /* 1070 */ 113, 114, 233, 102, 67, 218, 219, 218, 219, 243, ++ /* 1080 */ 19, 64, 22, 23, 23, 25, 195, 128, 129, 130, ++ /* 1090 */ 233, 74, 233, 86, 154, 118, 156, 130, 265, 208, ++ /* 1100 */ 19, 306, 95, 308, 43, 44, 45, 266, 47, 48, ++ /* 1110 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, ++ /* 1120 */ 153, 230, 96, 232, 43, 44, 45, 19, 47, 48, ++ /* 1130 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, ++ /* 1140 */ 114, 22, 306, 24, 308, 127, 120, 121, 122, 123, ++ /* 1150 */ 124, 125, 126, 195, 147, 212, 213, 214, 132, 23, ++ /* 1160 */ 195, 25, 102, 100, 103, 104, 105, 106, 107, 108, ++ /* 1170 */ 109, 110, 111, 112, 113, 114, 218, 219, 19, 60, ++ /* 1180 */ 195, 12, 210, 211, 103, 104, 105, 106, 107, 108, ++ /* 1190 */ 109, 110, 111, 112, 113, 114, 27, 134, 195, 195, ++ /* 1200 */ 195, 210, 211, 218, 219, 195, 47, 195, 212, 213, ++ /* 1210 */ 214, 42, 16, 130, 19, 112, 113, 114, 23, 77, ++ /* 1220 */ 195, 218, 219, 218, 219, 117, 163, 164, 218, 219, ++ /* 1230 */ 218, 219, 90, 64, 19, 93, 153, 118, 43, 44, ++ /* 1240 */ 45, 160, 47, 48, 49, 50, 51, 52, 53, 54, ++ /* 1250 */ 55, 56, 57, 58, 195, 119, 272, 276, 43, 44, ++ /* 1260 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, ++ /* 1270 */ 55, 56, 57, 58, 78, 116, 80, 218, 219, 116, ++ /* 1280 */ 144, 128, 129, 130, 218, 219, 61, 195, 47, 195, ++ /* 1290 */ 16, 132, 195, 263, 195, 314, 315, 267, 103, 104, ++ /* 1300 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, ++ /* 1310 */ 218, 219, 218, 219, 151, 218, 219, 195, 103, 104, ++ /* 1320 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, ++ /* 1330 */ 210, 211, 195, 7, 8, 9, 195, 60, 195, 312, ++ /* 1340 */ 218, 219, 195, 316, 195, 120, 195, 263, 19, 195, ++ /* 1350 */ 125, 267, 78, 24, 80, 218, 219, 116, 162, 218, ++ /* 1360 */ 219, 218, 219, 301, 302, 218, 219, 195, 19, 218, ++ /* 1370 */ 219, 276, 43, 44, 45, 160, 47, 48, 49, 50, ++ /* 1380 */ 51, 52, 53, 54, 55, 56, 57, 58, 19, 146, ++ /* 1390 */ 218, 219, 43, 44, 45, 118, 47, 48, 49, 50, ++ /* 1400 */ 51, 52, 53, 54, 55, 56, 57, 58, 165, 314, ++ /* 1410 */ 315, 276, 43, 44, 45, 266, 47, 48, 49, 50, ++ /* 1420 */ 51, 52, 53, 54, 55, 56, 57, 58, 128, 129, ++ /* 1430 */ 130, 195, 103, 104, 105, 106, 107, 108, 109, 110, ++ /* 1440 */ 111, 112, 113, 114, 195, 228, 195, 61, 195, 314, ++ /* 1450 */ 315, 25, 103, 104, 105, 106, 107, 108, 109, 110, ++ /* 1460 */ 111, 112, 113, 114, 195, 22, 195, 218, 219, 218, ++ /* 1470 */ 219, 195, 103, 104, 105, 106, 107, 108, 109, 110, ++ /* 1480 */ 111, 112, 113, 114, 195, 195, 246, 218, 219, 218, ++ /* 1490 */ 219, 25, 19, 246, 218, 219, 246, 257, 259, 260, ++ /* 1500 */ 195, 22, 266, 60, 257, 195, 120, 257, 218, 219, ++ /* 1510 */ 116, 195, 19, 195, 150, 151, 25, 44, 45, 266, ++ /* 1520 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, ++ /* 1530 */ 57, 58, 195, 54, 218, 219, 218, 219, 45, 145, ++ /* 1540 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, ++ /* 1550 */ 57, 58, 246, 121, 122, 218, 219, 19, 23, 31, ++ /* 1560 */ 25, 118, 159, 257, 161, 24, 195, 39, 195, 143, ++ /* 1570 */ 195, 19, 20, 22, 22, 24, 103, 104, 105, 106, ++ /* 1580 */ 107, 108, 109, 110, 111, 112, 113, 114, 36, 218, ++ /* 1590 */ 219, 218, 219, 218, 219, 195, 103, 104, 105, 106, ++ /* 1600 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 143, ++ /* 1610 */ 119, 136, 60, 195, 22, 195, 141, 195, 218, 219, ++ /* 1620 */ 195, 23, 195, 25, 72, 23, 131, 25, 195, 134, ++ /* 1630 */ 23, 218, 219, 195, 82, 144, 218, 219, 218, 219, ++ /* 1640 */ 218, 219, 195, 218, 219, 218, 219, 60, 23, 195, ++ /* 1650 */ 25, 218, 219, 101, 195, 117, 218, 219, 195, 107, ++ /* 1660 */ 108, 23, 195, 25, 195, 218, 219, 115, 228, 117, ++ /* 1670 */ 118, 119, 218, 219, 122, 195, 19, 218, 219, 195, ++ /* 1680 */ 60, 218, 219, 142, 195, 218, 219, 19, 20, 195, ++ /* 1690 */ 22, 139, 140, 23, 23, 25, 25, 195, 218, 219, ++ /* 1700 */ 7, 8, 218, 219, 36, 118, 154, 155, 156, 157, ++ /* 1710 */ 158, 195, 23, 195, 25, 84, 85, 49, 195, 23, ++ /* 1720 */ 195, 25, 195, 23, 195, 25, 195, 23, 60, 25, ++ /* 1730 */ 23, 23, 25, 25, 142, 183, 218, 219, 118, 195, ++ /* 1740 */ 72, 218, 219, 218, 219, 218, 219, 218, 219, 218, ++ /* 1750 */ 219, 195, 195, 146, 86, 98, 23, 195, 25, 91, ++ /* 1760 */ 19, 20, 154, 22, 156, 154, 23, 156, 25, 101, ++ /* 1770 */ 23, 195, 25, 195, 195, 107, 108, 36, 195, 195, ++ /* 1780 */ 195, 195, 228, 115, 195, 117, 118, 119, 195, 195, ++ /* 1790 */ 122, 261, 195, 321, 195, 195, 195, 258, 238, 195, ++ /* 1800 */ 195, 60, 299, 291, 195, 195, 258, 195, 195, 195, ++ /* 1810 */ 290, 244, 216, 72, 245, 193, 258, 258, 299, 258, ++ /* 1820 */ 299, 274, 154, 155, 156, 157, 158, 86, 247, 295, ++ /* 1830 */ 248, 295, 91, 19, 20, 270, 22, 274, 270, 248, ++ /* 1840 */ 274, 222, 101, 227, 274, 221, 231, 221, 107, 108, ++ /* 1850 */ 36, 183, 262, 247, 221, 283, 115, 262, 117, 118, ++ /* 1860 */ 119, 198, 116, 122, 220, 262, 61, 220, 220, 251, ++ /* 1870 */ 247, 142, 251, 245, 60, 202, 299, 202, 38, 262, ++ /* 1880 */ 202, 22, 152, 151, 296, 43, 72, 236, 18, 239, ++ /* 1890 */ 202, 239, 239, 239, 18, 154, 155, 156, 157, 158, ++ /* 1900 */ 86, 150, 201, 248, 275, 91, 248, 273, 236, 248, ++ /* 1910 */ 275, 275, 273, 236, 248, 101, 286, 202, 201, 159, ++ /* 1920 */ 63, 107, 108, 296, 183, 293, 202, 201, 22, 115, ++ /* 1930 */ 202, 117, 118, 119, 292, 223, 122, 201, 65, 202, ++ /* 1940 */ 201, 223, 220, 220, 22, 220, 226, 226, 229, 127, ++ /* 1950 */ 223, 220, 166, 24, 285, 220, 222, 114, 315, 285, ++ /* 1960 */ 220, 202, 220, 307, 92, 320, 320, 229, 154, 155, ++ /* 1970 */ 156, 157, 158, 0, 1, 2, 223, 83, 5, 268, ++ /* 1980 */ 149, 268, 146, 10, 11, 12, 13, 14, 22, 280, ++ /* 1990 */ 17, 202, 159, 19, 20, 251, 22, 183, 282, 148, ++ /* 2000 */ 252, 252, 250, 30, 249, 32, 248, 147, 25, 13, ++ /* 2010 */ 36, 204, 196, 40, 196, 6, 302, 194, 194, 194, ++ /* 2020 */ 209, 215, 209, 215, 215, 215, 224, 224, 216, 209, ++ /* 2030 */ 4, 216, 215, 3, 60, 22, 122, 19, 122, 19, ++ /* 2040 */ 125, 22, 15, 22, 71, 16, 72, 23, 23, 140, ++ /* 2050 */ 305, 152, 79, 25, 131, 82, 143, 20, 16, 305, ++ /* 2060 */ 1, 143, 145, 131, 131, 62, 54, 131, 37, 54, ++ /* 2070 */ 54, 152, 99, 117, 34, 101, 54, 24, 1, 5, ++ /* 2080 */ 22, 107, 108, 116, 76, 25, 162, 41, 142, 115, ++ /* 2090 */ 24, 117, 118, 119, 116, 20, 122, 19, 126, 23, ++ /* 2100 */ 132, 19, 20, 69, 22, 69, 22, 134, 22, 68, ++ /* 2110 */ 22, 22, 139, 140, 60, 141, 68, 24, 36, 28, ++ /* 2120 */ 97, 22, 37, 68, 23, 150, 34, 22, 154, 155, ++ /* 2130 */ 156, 157, 158, 23, 23, 22, 163, 25, 23, 142, ++ /* 2140 */ 23, 98, 60, 23, 22, 144, 25, 76, 34, 117, ++ /* 2150 */ 34, 89, 34, 34, 72, 87, 76, 183, 34, 94, ++ /* 2160 */ 34, 23, 22, 24, 34, 23, 25, 44, 25, 23, ++ /* 2170 */ 23, 23, 22, 22, 25, 11, 143, 25, 143, 23, ++ /* 2180 */ 22, 22, 22, 101, 23, 23, 136, 22, 25, 107, ++ /* 2190 */ 108, 142, 25, 142, 142, 23, 15, 115, 1, 117, ++ /* 2200 */ 118, 119, 1, 2, 122, 1, 5, 322, 322, 322, ++ /* 2210 */ 322, 10, 11, 12, 13, 14, 322, 322, 17, 322, ++ /* 2220 */ 5, 322, 322, 141, 322, 10, 11, 12, 13, 14, ++ /* 2230 */ 322, 30, 17, 32, 322, 322, 154, 155, 156, 157, ++ /* 2240 */ 158, 40, 322, 322, 322, 30, 322, 32, 322, 322, ++ /* 2250 */ 322, 322, 322, 322, 322, 40, 322, 322, 322, 322, ++ /* 2260 */ 322, 322, 322, 322, 322, 183, 322, 322, 322, 322, ++ /* 2270 */ 322, 322, 71, 322, 322, 322, 322, 322, 322, 322, ++ /* 2280 */ 79, 322, 322, 82, 322, 322, 71, 322, 322, 322, ++ /* 2290 */ 322, 322, 322, 322, 79, 322, 322, 82, 322, 322, ++ /* 2300 */ 99, 322, 322, 322, 322, 322, 322, 322, 322, 322, ++ /* 2310 */ 322, 322, 322, 322, 99, 322, 322, 322, 322, 322, ++ /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, ++ /* 2330 */ 322, 322, 322, 322, 322, 134, 322, 322, 322, 322, ++ /* 2340 */ 139, 140, 322, 322, 322, 322, 322, 322, 322, 134, ++ /* 2350 */ 322, 322, 322, 322, 139, 140, 322, 322, 322, 322, ++ /* 2360 */ 322, 322, 322, 322, 163, 322, 322, 322, 322, 322, ++ /* 2370 */ 322, 322, 322, 322, 322, 322, 322, 322, 163, 322, ++ /* 2380 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, ++ /* 2390 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, ++ /* 2400 */ 322, 322, 322, 322, 322, 322, 322, 322, 187, 187, ++ /* 2410 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2420 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2430 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2440 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2450 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2460 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2470 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2480 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2490 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2500 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2510 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2520 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2530 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2540 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2550 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, ++ /* 2560 */ 187, 187, 187, 187, 187, 187, + }; +-#define YY_SHIFT_COUNT (582) ++#define YY_SHIFT_COUNT (599) + #define YY_SHIFT_MIN (0) +-#define YY_SHIFT_MAX (2152) ++#define YY_SHIFT_MAX (2215) + static const unsigned short int yy_shift_ofst[] = { +- /* 0 */ 2029, 1801, 2043, 1380, 1380, 318, 271, 1496, 1569, 1642, +- /* 10 */ 702, 702, 702, 740, 318, 318, 318, 318, 318, 0, +- /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, +- /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 503, 503, +- /* 40 */ 111, 111, 217, 287, 348, 610, 610, 736, 736, 736, +- /* 50 */ 736, 40, 112, 320, 340, 445, 489, 593, 637, 741, +- /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, +- /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, +- /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, +- /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, +- /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, +- /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, +- /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, +- /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, +- /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, +- /* 150 */ 183, 99, 169, 549, 610, 151, 542, 610, 610, 1017, +- /* 160 */ 1017, 610, 1001, 350, 464, 464, 464, 586, 1, 1, +- /* 170 */ 2207, 2207, 854, 854, 854, 465, 694, 694, 694, 694, +- /* 180 */ 1096, 1096, 825, 549, 847, 904, 610, 610, 610, 610, +- /* 190 */ 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, +- /* 200 */ 610, 610, 610, 610, 610, 488, 947, 947, 610, 1129, +- /* 210 */ 495, 495, 1139, 1139, 967, 967, 1173, 2207, 2207, 2207, +- /* 220 */ 2207, 2207, 2207, 2207, 617, 765, 765, 697, 444, 708, +- /* 230 */ 660, 745, 510, 663, 864, 610, 610, 610, 610, 610, +- /* 240 */ 610, 610, 610, 610, 610, 188, 610, 610, 610, 610, +- /* 250 */ 610, 610, 610, 610, 610, 610, 610, 610, 839, 839, +- /* 260 */ 839, 610, 610, 610, 1155, 610, 610, 610, 1119, 1247, +- /* 270 */ 610, 1353, 610, 610, 610, 610, 610, 610, 610, 610, +- /* 280 */ 1063, 494, 1101, 291, 291, 291, 291, 1319, 1101, 1101, +- /* 290 */ 775, 1221, 1375, 1452, 667, 1341, 1198, 1341, 1435, 1487, +- /* 300 */ 667, 667, 1487, 667, 1198, 1435, 777, 1011, 1423, 584, +- /* 310 */ 584, 584, 1273, 1273, 1273, 1273, 1471, 1471, 880, 1530, +- /* 320 */ 1190, 1095, 1731, 1731, 1668, 1668, 1794, 1794, 1668, 1683, +- /* 330 */ 1685, 1815, 1796, 1824, 1824, 1824, 1824, 1668, 1828, 1701, +- /* 340 */ 1685, 1685, 1701, 1815, 1796, 1701, 1796, 1701, 1668, 1828, +- /* 350 */ 1697, 1800, 1668, 1828, 1848, 1668, 1828, 1668, 1828, 1848, +- /* 360 */ 1766, 1766, 1766, 1823, 1870, 1870, 1848, 1766, 1767, 1766, +- /* 370 */ 1823, 1766, 1766, 1727, 1872, 1783, 1783, 1848, 1668, 1813, +- /* 380 */ 1813, 1825, 1825, 1777, 1781, 1906, 1668, 1774, 1777, 1789, +- /* 390 */ 1792, 1701, 1919, 1935, 1935, 1949, 1949, 1949, 2207, 2207, +- /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, +- /* 410 */ 2207, 2207, 2207, 69, 1032, 79, 357, 1377, 1206, 400, +- /* 420 */ 1525, 835, 332, 1540, 1437, 1539, 1536, 1548, 1583, 1620, +- /* 430 */ 1633, 1670, 1671, 1674, 1567, 1553, 1682, 1506, 1675, 1358, +- /* 440 */ 1607, 1589, 1678, 1681, 1624, 1687, 1688, 1283, 1561, 1693, +- /* 450 */ 1696, 1623, 1521, 1976, 1980, 1962, 1822, 1972, 1973, 1965, +- /* 460 */ 1967, 1851, 1840, 1862, 1969, 1969, 1971, 1853, 1977, 1854, +- /* 470 */ 1982, 1999, 1858, 1871, 1969, 1873, 1941, 1968, 1969, 1855, +- /* 480 */ 1952, 1954, 1955, 1956, 1881, 1896, 1981, 1874, 2013, 2014, +- /* 490 */ 1998, 1905, 1860, 1957, 2008, 1966, 1947, 1983, 1894, 1921, +- /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047, +- /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057, +- /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1950, +- /* 530 */ 2071, 2072, 1985, 2062, 2075, 1959, 2073, 2067, 2070, 2076, +- /* 540 */ 2078, 2010, 2030, 2022, 2069, 2031, 2021, 2082, 2094, 2083, +- /* 550 */ 2095, 2093, 2096, 2086, 1986, 1987, 2100, 2073, 2101, 2103, +- /* 560 */ 2104, 2109, 2107, 2108, 2111, 2113, 2125, 2115, 2116, 2117, +- /* 570 */ 2118, 2121, 2122, 2114, 2009, 2004, 2005, 2006, 2124, 2127, +- /* 580 */ 2136, 2151, 2152, ++ /* 0 */ 2201, 1973, 2215, 1552, 1552, 33, 368, 1668, 1741, 1814, ++ /* 10 */ 726, 726, 726, 265, 33, 33, 33, 33, 33, 0, ++ /* 20 */ 0, 216, 1349, 726, 726, 726, 726, 726, 726, 726, ++ /* 30 */ 726, 726, 726, 726, 726, 726, 726, 726, 272, 272, ++ /* 40 */ 111, 111, 316, 365, 516, 867, 867, 916, 916, 916, ++ /* 50 */ 916, 40, 112, 260, 364, 408, 512, 617, 661, 765, ++ /* 60 */ 809, 913, 957, 1061, 1081, 1195, 1215, 1329, 1349, 1349, ++ /* 70 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, ++ /* 80 */ 1349, 1349, 1349, 1349, 1349, 1349, 1369, 1349, 1473, 1493, ++ /* 90 */ 1493, 473, 1974, 2082, 726, 726, 726, 726, 726, 726, ++ /* 100 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, ++ /* 110 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, ++ /* 120 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, ++ /* 130 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, ++ /* 140 */ 726, 726, 726, 726, 726, 726, 138, 232, 232, 232, ++ /* 150 */ 232, 232, 232, 232, 188, 99, 242, 718, 416, 1159, ++ /* 160 */ 867, 867, 940, 940, 867, 1103, 417, 574, 574, 574, ++ /* 170 */ 611, 139, 139, 2379, 2379, 1026, 1026, 1026, 536, 466, ++ /* 180 */ 466, 466, 466, 1017, 1017, 849, 718, 971, 1060, 867, ++ /* 190 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, ++ /* 200 */ 867, 867, 867, 867, 867, 867, 867, 867, 261, 712, ++ /* 210 */ 712, 867, 108, 1142, 1142, 977, 1108, 1108, 977, 977, ++ /* 220 */ 1243, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 641, 789, ++ /* 230 */ 789, 635, 366, 721, 673, 782, 494, 787, 829, 867, ++ /* 240 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, ++ /* 250 */ 959, 867, 867, 867, 867, 867, 867, 867, 867, 867, ++ /* 260 */ 867, 867, 867, 867, 867, 820, 820, 820, 867, 867, ++ /* 270 */ 867, 1136, 867, 867, 867, 1119, 1007, 867, 1169, 867, ++ /* 280 */ 867, 867, 867, 867, 867, 867, 867, 1225, 1153, 869, ++ /* 290 */ 196, 618, 618, 618, 618, 1491, 196, 196, 91, 339, ++ /* 300 */ 1326, 1386, 383, 1163, 1364, 1426, 1364, 1538, 903, 1163, ++ /* 310 */ 1163, 903, 1163, 1426, 1538, 1018, 1535, 1241, 1528, 1528, ++ /* 320 */ 1528, 1394, 1394, 1394, 1394, 762, 762, 1403, 1466, 1475, ++ /* 330 */ 1551, 1746, 1805, 1746, 1746, 1729, 1729, 1840, 1840, 1729, ++ /* 340 */ 1730, 1732, 1859, 1842, 1870, 1870, 1870, 1870, 1729, 1876, ++ /* 350 */ 1751, 1732, 1732, 1751, 1859, 1842, 1751, 1842, 1751, 1729, ++ /* 360 */ 1876, 1760, 1857, 1729, 1876, 1906, 1729, 1876, 1729, 1876, ++ /* 370 */ 1906, 1746, 1746, 1746, 1873, 1922, 1922, 1906, 1746, 1822, ++ /* 380 */ 1746, 1873, 1746, 1746, 1786, 1929, 1843, 1843, 1906, 1729, ++ /* 390 */ 1872, 1872, 1894, 1894, 1831, 1836, 1966, 1729, 1833, 1831, ++ /* 400 */ 1851, 1860, 1751, 1983, 1996, 1996, 2009, 2009, 2009, 2379, ++ /* 410 */ 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, ++ /* 420 */ 2379, 2379, 2379, 2379, 136, 1063, 1196, 530, 636, 1274, ++ /* 430 */ 1300, 1443, 1598, 1495, 1479, 967, 1083, 1602, 463, 1625, ++ /* 440 */ 1638, 1670, 1541, 1671, 1689, 1696, 1277, 1432, 1693, 808, ++ /* 450 */ 1700, 1607, 1657, 1587, 1704, 1707, 1631, 1708, 1733, 1608, ++ /* 460 */ 1611, 1743, 1747, 1620, 1592, 2026, 2030, 2013, 1914, 2018, ++ /* 470 */ 1916, 2020, 2019, 2021, 1915, 2027, 2029, 2024, 2025, 1909, ++ /* 480 */ 1899, 1923, 2028, 2028, 1913, 2037, 1917, 2042, 2059, 1918, ++ /* 490 */ 1932, 2028, 1933, 2003, 2031, 2028, 1919, 2012, 2015, 2016, ++ /* 500 */ 2022, 1936, 1956, 2040, 2053, 2077, 2074, 2058, 1967, 1924, ++ /* 510 */ 2034, 2060, 2036, 2008, 2046, 1946, 1978, 2066, 2075, 2078, ++ /* 520 */ 1968, 1972, 2084, 2041, 2086, 2088, 2076, 2089, 2048, 2054, ++ /* 530 */ 2093, 2023, 2091, 2099, 2055, 2085, 2101, 2092, 1975, 2105, ++ /* 540 */ 2110, 2111, 2112, 2115, 2113, 2043, 1997, 2117, 2120, 2032, ++ /* 550 */ 2114, 2122, 2001, 2121, 2116, 2118, 2119, 2124, 2062, 2071, ++ /* 560 */ 2068, 2123, 2080, 2065, 2126, 2138, 2140, 2139, 2141, 2143, ++ /* 570 */ 2130, 2033, 2035, 2142, 2121, 2146, 2147, 2148, 2150, 2149, ++ /* 580 */ 2152, 2156, 2151, 2164, 2158, 2159, 2161, 2162, 2160, 2165, ++ /* 590 */ 2163, 2050, 2049, 2051, 2052, 2167, 2172, 2181, 2197, 2204, + }; +-#define YY_REDUCE_COUNT (412) +-#define YY_REDUCE_MIN (-277) +-#define YY_REDUCE_MAX (1772) ++#define YY_REDUCE_COUNT (423) ++#define YY_REDUCE_MIN (-303) ++#define YY_REDUCE_MAX (1825) + static const short yy_reduce_ofst[] = { +- /* 0 */ -67, 1252, -64, -178, -181, 160, 1071, 143, -184, 137, +- /* 10 */ 218, 220, 222, -174, 229, 268, 272, 275, 324, -208, +- /* 20 */ 242, -277, -39, 81, 537, 792, 810, 812, -189, 814, +- /* 30 */ 831, 163, 865, 944, 887, 840, 964, 1077, -187, 292, +- /* 40 */ -133, 274, 673, 558, 682, 795, 809, -238, -232, -238, +- /* 50 */ -232, 329, 329, 329, 329, 329, 329, 329, 329, 329, +- /* 60 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, +- /* 70 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, +- /* 80 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 557, +- /* 90 */ 712, 949, 966, 969, 971, 979, 1097, 1099, 1103, 1142, +- /* 100 */ 1144, 1169, 1172, 1201, 1203, 1228, 1241, 1250, 1253, 1255, +- /* 110 */ 1261, 1266, 1271, 1282, 1291, 1308, 1310, 1312, 1322, 1328, +- /* 120 */ 1347, 1354, 1356, 1359, 1362, 1365, 1367, 1374, 1376, 1381, +- /* 130 */ 1401, 1403, 1406, 1412, 1414, 1417, 1421, 1428, 1447, 1449, +- /* 140 */ 1453, 1462, 329, 329, 329, 329, 329, 329, 329, 329, +- /* 150 */ 329, 329, 329, -22, -159, 475, -220, 756, 38, 501, +- /* 160 */ 841, 714, 329, 118, 337, 349, 363, -56, 329, 329, +- /* 170 */ 329, 329, -205, -205, -205, 687, -172, -130, -57, 790, +- /* 180 */ 397, 528, -271, 136, 596, 596, 90, 316, 522, 541, +- /* 190 */ -37, 715, 849, 977, 628, 856, 980, 991, 1081, 1102, +- /* 200 */ 1135, 1083, -162, 208, 1258, 794, -86, 159, 41, 1109, +- /* 210 */ 671, 852, 844, 932, 1175, 1254, 480, 1180, 100, 258, +- /* 220 */ 1265, 1268, 1216, 1287, -139, 317, 344, 63, 339, 423, +- /* 230 */ 563, 636, 676, 813, 908, 914, 950, 1078, 1084, 1098, +- /* 240 */ 1363, 1384, 1407, 1439, 1464, 411, 1527, 1534, 1535, 1537, +- /* 250 */ 1541, 1542, 1543, 1544, 1545, 1547, 1549, 1550, 990, 1164, +- /* 260 */ 1492, 1551, 1552, 1556, 1217, 1558, 1559, 1560, 1473, 1413, +- /* 270 */ 1563, 1510, 1568, 563, 1570, 1571, 1572, 1573, 1574, 1575, +- /* 280 */ 1443, 1466, 1518, 1513, 1514, 1515, 1516, 1217, 1518, 1518, +- /* 290 */ 1531, 1562, 1582, 1477, 1505, 1511, 1533, 1512, 1488, 1538, +- /* 300 */ 1509, 1517, 1546, 1519, 1557, 1489, 1565, 1564, 1578, 1586, +- /* 310 */ 1587, 1588, 1526, 1528, 1554, 1555, 1576, 1577, 1566, 1579, +- /* 320 */ 1584, 1591, 1520, 1523, 1617, 1628, 1580, 1581, 1632, 1585, +- /* 330 */ 1590, 1593, 1604, 1605, 1606, 1608, 1609, 1641, 1649, 1610, +- /* 340 */ 1592, 1594, 1611, 1595, 1616, 1612, 1618, 1613, 1651, 1654, +- /* 350 */ 1596, 1598, 1655, 1663, 1650, 1673, 1680, 1677, 1684, 1653, +- /* 360 */ 1664, 1666, 1667, 1662, 1669, 1672, 1676, 1686, 1679, 1691, +- /* 370 */ 1689, 1692, 1694, 1597, 1599, 1619, 1630, 1699, 1700, 1602, +- /* 380 */ 1615, 1648, 1657, 1690, 1698, 1658, 1729, 1652, 1695, 1702, +- /* 390 */ 1704, 1703, 1741, 1754, 1758, 1768, 1769, 1771, 1660, 1661, +- /* 400 */ 1665, 1752, 1756, 1757, 1759, 1760, 1764, 1745, 1753, 1762, +- /* 410 */ 1763, 1761, 1772, ++ /* 0 */ -67, 345, -64, -178, -181, 143, 435, -78, -183, 163, ++ /* 10 */ -185, 284, 384, -174, 189, 352, 440, 444, 493, -23, ++ /* 20 */ 227, -277, -1, 305, 561, 755, 759, 764, -189, 839, ++ /* 30 */ 857, 354, 484, 859, 631, 67, 734, 780, -187, 616, ++ /* 40 */ 581, 730, 891, 449, 588, 795, 836, -238, 287, -238, ++ /* 50 */ 287, -256, -256, -256, -256, -256, -256, -256, -256, -256, ++ /* 60 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, ++ /* 70 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, ++ /* 80 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, ++ /* 90 */ -256, 205, 582, 715, 958, 985, 1003, 1005, 1010, 1012, ++ /* 100 */ 1059, 1066, 1092, 1094, 1097, 1122, 1137, 1141, 1143, 1147, ++ /* 110 */ 1151, 1172, 1249, 1251, 1269, 1271, 1276, 1290, 1316, 1318, ++ /* 120 */ 1337, 1371, 1373, 1375, 1400, 1413, 1418, 1420, 1422, 1425, ++ /* 130 */ 1427, 1433, 1438, 1447, 1454, 1459, 1463, 1467, 1480, 1484, ++ /* 140 */ 1518, 1523, 1525, 1527, 1529, 1531, -256, -256, -256, -256, ++ /* 150 */ -256, -256, -256, -256, -256, -256, -256, 155, 210, -220, ++ /* 160 */ 86, -130, 943, 996, 402, -256, -113, 981, 1095, 1135, ++ /* 170 */ 395, -256, -256, -256, -256, 568, 568, 568, -4, -153, ++ /* 180 */ -133, 259, 306, -166, 523, -303, -126, 503, 503, -37, ++ /* 190 */ -149, 164, 690, 292, 412, 492, 651, 784, 332, 786, ++ /* 200 */ 841, 1149, 833, 1236, 792, 162, 796, 1253, 777, 288, ++ /* 210 */ 381, 380, 709, 487, 1027, 972, 1030, 1084, 991, 1120, ++ /* 220 */ -152, 1062, 692, 1240, 1247, 1250, 1239, 1306, -207, -194, ++ /* 230 */ 57, 180, 74, 315, 355, 376, 452, 488, 630, 693, ++ /* 240 */ 965, 1004, 1025, 1099, 1154, 1289, 1305, 1310, 1469, 1489, ++ /* 250 */ 984, 1494, 1502, 1516, 1544, 1556, 1557, 1562, 1576, 1578, ++ /* 260 */ 1579, 1583, 1584, 1585, 1586, 1217, 1440, 1554, 1589, 1593, ++ /* 270 */ 1594, 1530, 1597, 1599, 1600, 1539, 1472, 1601, 1560, 1604, ++ /* 280 */ 355, 1605, 1609, 1610, 1612, 1613, 1614, 1503, 1512, 1520, ++ /* 290 */ 1567, 1548, 1558, 1559, 1561, 1530, 1567, 1567, 1569, 1596, ++ /* 300 */ 1622, 1519, 1521, 1547, 1565, 1581, 1568, 1534, 1582, 1563, ++ /* 310 */ 1566, 1591, 1570, 1606, 1536, 1619, 1615, 1616, 1624, 1626, ++ /* 320 */ 1633, 1590, 1595, 1603, 1617, 1618, 1621, 1572, 1623, 1628, ++ /* 330 */ 1663, 1644, 1577, 1647, 1648, 1673, 1675, 1588, 1627, 1678, ++ /* 340 */ 1630, 1629, 1634, 1651, 1650, 1652, 1653, 1654, 1688, 1701, ++ /* 350 */ 1655, 1635, 1636, 1658, 1639, 1672, 1661, 1677, 1666, 1715, ++ /* 360 */ 1717, 1632, 1642, 1724, 1726, 1712, 1728, 1736, 1737, 1739, ++ /* 370 */ 1718, 1722, 1723, 1725, 1719, 1720, 1721, 1727, 1731, 1734, ++ /* 380 */ 1735, 1738, 1740, 1742, 1643, 1656, 1669, 1674, 1753, 1759, ++ /* 390 */ 1645, 1646, 1711, 1713, 1748, 1744, 1709, 1789, 1716, 1749, ++ /* 400 */ 1752, 1755, 1758, 1807, 1816, 1818, 1823, 1824, 1825, 1745, ++ /* 410 */ 1754, 1714, 1811, 1806, 1808, 1809, 1810, 1813, 1802, 1803, ++ /* 420 */ 1812, 1815, 1817, 1820, + }; + static const YYACTIONTYPE yy_default[] = { +- /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, +- /* 10 */ 1491, 1491, 1491, 1254, 1254, 1254, 1254, 1254, 1254, 1397, +- /* 20 */ 1397, 1544, 1287, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, +- /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, +- /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, +- /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420, +- /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, +- /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, +- /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, +- /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, +- /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, +- /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, +- /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, +- /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, +- /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, +- /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, +- /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, +- /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, +- /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, +- /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, +- /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, +- /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, +- /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, +- /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, +- /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, +- /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, +- /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, +- /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, +- /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, +- /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, +- /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, +- /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, +- /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, +- /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, +- /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, +- /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, +- /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, +- /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, +- /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, +- /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, +- /* 580 */ 1266, 1254, 1254, ++ /* 0 */ 1691, 1691, 1691, 1516, 1279, 1392, 1279, 1279, 1279, 1279, ++ /* 10 */ 1516, 1516, 1516, 1279, 1279, 1279, 1279, 1279, 1279, 1422, ++ /* 20 */ 1422, 1568, 1312, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 30 */ 1279, 1279, 1279, 1279, 1279, 1515, 1279, 1279, 1279, 1279, ++ /* 40 */ 1607, 1607, 1279, 1279, 1279, 1279, 1279, 1592, 1591, 1279, ++ /* 50 */ 1279, 1279, 1431, 1279, 1279, 1279, 1438, 1279, 1279, 1279, ++ /* 60 */ 1279, 1279, 1517, 1518, 1279, 1279, 1279, 1279, 1567, 1569, ++ /* 70 */ 1533, 1445, 1444, 1443, 1442, 1551, 1410, 1436, 1429, 1433, ++ /* 80 */ 1512, 1513, 1511, 1670, 1518, 1517, 1279, 1432, 1480, 1496, ++ /* 90 */ 1479, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 100 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 110 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 120 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 130 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 140 */ 1279, 1279, 1279, 1279, 1279, 1279, 1488, 1495, 1494, 1493, ++ /* 150 */ 1502, 1492, 1489, 1482, 1481, 1483, 1484, 1303, 1300, 1354, ++ /* 160 */ 1279, 1279, 1279, 1279, 1279, 1485, 1312, 1473, 1472, 1471, ++ /* 170 */ 1279, 1499, 1486, 1498, 1497, 1575, 1644, 1643, 1534, 1279, ++ /* 180 */ 1279, 1279, 1279, 1279, 1279, 1607, 1279, 1279, 1279, 1279, ++ /* 190 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 200 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1412, 1607, ++ /* 210 */ 1607, 1279, 1312, 1607, 1607, 1308, 1413, 1413, 1308, 1308, ++ /* 220 */ 1416, 1587, 1383, 1383, 1383, 1383, 1392, 1383, 1279, 1279, ++ /* 230 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 240 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1572, 1570, 1279, ++ /* 250 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 260 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 270 */ 1279, 1279, 1279, 1279, 1279, 1388, 1279, 1279, 1279, 1279, ++ /* 280 */ 1279, 1279, 1279, 1279, 1279, 1279, 1637, 1683, 1279, 1546, ++ /* 290 */ 1368, 1388, 1388, 1388, 1388, 1390, 1369, 1367, 1382, 1313, ++ /* 300 */ 1286, 1683, 1683, 1448, 1437, 1389, 1437, 1680, 1435, 1448, ++ /* 310 */ 1448, 1435, 1448, 1389, 1680, 1329, 1659, 1324, 1422, 1422, ++ /* 320 */ 1422, 1412, 1412, 1412, 1412, 1416, 1416, 1514, 1389, 1382, ++ /* 330 */ 1279, 1355, 1683, 1355, 1355, 1398, 1398, 1682, 1682, 1398, ++ /* 340 */ 1534, 1667, 1457, 1357, 1363, 1363, 1363, 1363, 1398, 1297, ++ /* 350 */ 1435, 1667, 1667, 1435, 1457, 1357, 1435, 1357, 1435, 1398, ++ /* 360 */ 1297, 1550, 1678, 1398, 1297, 1524, 1398, 1297, 1398, 1297, ++ /* 370 */ 1524, 1355, 1355, 1355, 1344, 1279, 1279, 1524, 1355, 1329, ++ /* 380 */ 1355, 1344, 1355, 1355, 1625, 1279, 1528, 1528, 1524, 1398, ++ /* 390 */ 1617, 1617, 1425, 1425, 1430, 1416, 1519, 1398, 1279, 1430, ++ /* 400 */ 1428, 1426, 1435, 1347, 1640, 1640, 1636, 1636, 1636, 1688, ++ /* 410 */ 1688, 1587, 1652, 1312, 1312, 1312, 1312, 1652, 1331, 1331, ++ /* 420 */ 1313, 1313, 1312, 1652, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 430 */ 1279, 1647, 1279, 1279, 1535, 1279, 1279, 1279, 1279, 1279, ++ /* 440 */ 1279, 1279, 1402, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 450 */ 1279, 1279, 1593, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 460 */ 1279, 1279, 1279, 1279, 1462, 1279, 1282, 1584, 1279, 1279, ++ /* 470 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 480 */ 1279, 1279, 1439, 1440, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 490 */ 1279, 1454, 1279, 1279, 1279, 1449, 1279, 1279, 1279, 1279, ++ /* 500 */ 1279, 1279, 1279, 1279, 1403, 1279, 1279, 1279, 1279, 1279, ++ /* 510 */ 1279, 1549, 1548, 1279, 1279, 1400, 1279, 1279, 1279, 1279, ++ /* 520 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1327, ++ /* 530 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 540 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 550 */ 1279, 1279, 1279, 1427, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 560 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1622, 1417, ++ /* 570 */ 1279, 1279, 1279, 1279, 1671, 1279, 1279, 1279, 1279, 1377, ++ /* 580 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, ++ /* 590 */ 1663, 1371, 1463, 1279, 1466, 1301, 1279, 1291, 1279, 1279, + }; + /********** End of lemon-generated parsing tables *****************************/ + +@@ -179401,34 +181810,33 @@ static const char *const yyTokenName[] = { + /* 292 */ "foreach_clause", + /* 293 */ "when_clause", + /* 294 */ "trigger_cmd", +- /* 295 */ "trnm", +- /* 296 */ "tridxby", +- /* 297 */ "database_kw_opt", +- /* 298 */ "key_opt", +- /* 299 */ "add_column_fullname", +- /* 300 */ "kwcolumn_opt", +- /* 301 */ "create_vtab", +- /* 302 */ "vtabarglist", +- /* 303 */ "vtabarg", +- /* 304 */ "vtabargtoken", +- /* 305 */ "lp", +- /* 306 */ "anylist", +- /* 307 */ "wqitem", +- /* 308 */ "wqas", +- /* 309 */ "withnm", +- /* 310 */ "windowdefn_list", +- /* 311 */ "windowdefn", +- /* 312 */ "window", +- /* 313 */ "frame_opt", +- /* 314 */ "part_opt", +- /* 315 */ "filter_clause", +- /* 316 */ "over_clause", +- /* 317 */ "range_or_rows", +- /* 318 */ "frame_bound", +- /* 319 */ "frame_bound_s", +- /* 320 */ "frame_bound_e", +- /* 321 */ "frame_exclude_opt", +- /* 322 */ "frame_exclude", ++ /* 295 */ "tridxby", ++ /* 296 */ "database_kw_opt", ++ /* 297 */ "key_opt", ++ /* 298 */ "alter_add", ++ /* 299 */ "kwcolumn_opt", ++ /* 300 */ "create_vtab", ++ /* 301 */ "vtabarglist", ++ /* 302 */ "vtabarg", ++ /* 303 */ "vtabargtoken", ++ /* 304 */ "lp", ++ /* 305 */ "anylist", ++ /* 306 */ "wqitem", ++ /* 307 */ "wqas", ++ /* 308 */ "withnm", ++ /* 309 */ "windowdefn_list", ++ /* 310 */ "windowdefn", ++ /* 311 */ "window", ++ /* 312 */ "frame_opt", ++ /* 313 */ "part_opt", ++ /* 314 */ "filter_clause", ++ /* 315 */ "over_clause", ++ /* 316 */ "range_or_rows", ++ /* 317 */ "frame_bound", ++ /* 318 */ "frame_bound_s", ++ /* 319 */ "frame_bound_e", ++ /* 320 */ "frame_exclude_opt", ++ /* 321 */ "frame_exclude", + }; + #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ + +@@ -179558,8 +181966,8 @@ static const char *const yyRuleName[] = { + /* 119 */ "fullname ::= nm DOT nm", + /* 120 */ "xfullname ::= nm", + /* 121 */ "xfullname ::= nm DOT nm", +- /* 122 */ "xfullname ::= nm DOT nm AS nm", +- /* 123 */ "xfullname ::= nm AS nm", ++ /* 122 */ "xfullname ::= nm AS nm", ++ /* 123 */ "xfullname ::= nm DOT nm AS nm", + /* 124 */ "joinop ::= COMMA|JOIN", + /* 125 */ "joinop ::= JOIN_KW JOIN", + /* 126 */ "joinop ::= JOIN_KW nm JOIN", +@@ -179708,143 +182116,146 @@ static const char *const yyRuleName[] = { + /* 269 */ "when_clause ::= WHEN expr", + /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI", +- /* 272 */ "trnm ::= nm DOT nm", +- /* 273 */ "tridxby ::= INDEXED BY nm", +- /* 274 */ "tridxby ::= NOT INDEXED", +- /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", +- /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", +- /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", +- /* 278 */ "trigger_cmd ::= scanpt select scanpt", +- /* 279 */ "expr ::= RAISE LP IGNORE RP", +- /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", +- /* 281 */ "raisetype ::= ROLLBACK", +- /* 282 */ "raisetype ::= ABORT", +- /* 283 */ "raisetype ::= FAIL", +- /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", +- /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", +- /* 286 */ "cmd ::= DETACH database_kw_opt expr", +- /* 287 */ "key_opt ::=", +- /* 288 */ "key_opt ::= KEY expr", +- /* 289 */ "cmd ::= REINDEX", +- /* 290 */ "cmd ::= REINDEX nm dbnm", +- /* 291 */ "cmd ::= ANALYZE", +- /* 292 */ "cmd ::= ANALYZE nm dbnm", +- /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", +- /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", ++ /* 272 */ "tridxby ::= INDEXED BY nm", ++ /* 273 */ "tridxby ::= NOT INDEXED", ++ /* 274 */ "trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt", ++ /* 275 */ "trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt", ++ /* 276 */ "trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt", ++ /* 277 */ "trigger_cmd ::= scanpt select scanpt", ++ /* 278 */ "expr ::= RAISE LP IGNORE RP", ++ /* 279 */ "expr ::= RAISE LP raisetype COMMA expr RP", ++ /* 280 */ "raisetype ::= ROLLBACK", ++ /* 281 */ "raisetype ::= ABORT", ++ /* 282 */ "raisetype ::= FAIL", ++ /* 283 */ "cmd ::= DROP TRIGGER ifexists fullname", ++ /* 284 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", ++ /* 285 */ "cmd ::= DETACH database_kw_opt expr", ++ /* 286 */ "key_opt ::=", ++ /* 287 */ "key_opt ::= KEY expr", ++ /* 288 */ "cmd ::= REINDEX", ++ /* 289 */ "cmd ::= REINDEX nm dbnm", ++ /* 290 */ "cmd ::= ANALYZE", ++ /* 291 */ "cmd ::= ANALYZE nm dbnm", ++ /* 292 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", ++ /* 293 */ "cmd ::= alter_add carglist", ++ /* 294 */ "alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken", + /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", +- /* 296 */ "add_column_fullname ::= fullname", +- /* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", +- /* 298 */ "cmd ::= create_vtab", +- /* 299 */ "cmd ::= create_vtab LP vtabarglist RP", +- /* 300 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", +- /* 301 */ "vtabarg ::=", +- /* 302 */ "vtabargtoken ::= ANY", +- /* 303 */ "vtabargtoken ::= lp anylist RP", +- /* 304 */ "lp ::= LP", +- /* 305 */ "with ::= WITH wqlist", +- /* 306 */ "with ::= WITH RECURSIVE wqlist", +- /* 307 */ "wqas ::= AS", +- /* 308 */ "wqas ::= AS MATERIALIZED", +- /* 309 */ "wqas ::= AS NOT MATERIALIZED", +- /* 310 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", +- /* 311 */ "withnm ::= nm", +- /* 312 */ "wqlist ::= wqitem", +- /* 313 */ "wqlist ::= wqlist COMMA wqitem", +- /* 314 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", +- /* 315 */ "windowdefn ::= nm AS LP window RP", +- /* 316 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", +- /* 317 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", +- /* 318 */ "window ::= ORDER BY sortlist frame_opt", +- /* 319 */ "window ::= nm ORDER BY sortlist frame_opt", +- /* 320 */ "window ::= nm frame_opt", +- /* 321 */ "frame_opt ::=", +- /* 322 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", +- /* 323 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", +- /* 324 */ "range_or_rows ::= RANGE|ROWS|GROUPS", +- /* 325 */ "frame_bound_s ::= frame_bound", +- /* 326 */ "frame_bound_s ::= UNBOUNDED PRECEDING", +- /* 327 */ "frame_bound_e ::= frame_bound", +- /* 328 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", +- /* 329 */ "frame_bound ::= expr PRECEDING|FOLLOWING", +- /* 330 */ "frame_bound ::= CURRENT ROW", +- /* 331 */ "frame_exclude_opt ::=", +- /* 332 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", +- /* 333 */ "frame_exclude ::= NO OTHERS", +- /* 334 */ "frame_exclude ::= CURRENT ROW", +- /* 335 */ "frame_exclude ::= GROUP|TIES", +- /* 336 */ "window_clause ::= WINDOW windowdefn_list", +- /* 337 */ "filter_over ::= filter_clause over_clause", +- /* 338 */ "filter_over ::= over_clause", +- /* 339 */ "filter_over ::= filter_clause", +- /* 340 */ "over_clause ::= OVER LP window RP", +- /* 341 */ "over_clause ::= OVER nm", +- /* 342 */ "filter_clause ::= FILTER LP WHERE expr RP", +- /* 343 */ "term ::= QNUMBER", +- /* 344 */ "input ::= cmdlist", +- /* 345 */ "cmdlist ::= cmdlist ecmd", +- /* 346 */ "cmdlist ::= ecmd", +- /* 347 */ "ecmd ::= SEMI", +- /* 348 */ "ecmd ::= cmdx SEMI", +- /* 349 */ "ecmd ::= explain cmdx SEMI", +- /* 350 */ "trans_opt ::=", +- /* 351 */ "trans_opt ::= TRANSACTION", +- /* 352 */ "trans_opt ::= TRANSACTION nm", +- /* 353 */ "savepoint_opt ::= SAVEPOINT", +- /* 354 */ "savepoint_opt ::=", +- /* 355 */ "cmd ::= create_table create_table_args", +- /* 356 */ "table_option_set ::= table_option", +- /* 357 */ "columnlist ::= columnlist COMMA columnname carglist", +- /* 358 */ "columnlist ::= columnname carglist", +- /* 359 */ "nm ::= ID|INDEXED|JOIN_KW", +- /* 360 */ "nm ::= STRING", +- /* 361 */ "typetoken ::= typename", +- /* 362 */ "typename ::= ID|STRING", +- /* 363 */ "signed ::= plus_num", +- /* 364 */ "signed ::= minus_num", +- /* 365 */ "carglist ::= carglist ccons", +- /* 366 */ "carglist ::=", +- /* 367 */ "ccons ::= NULL onconf", +- /* 368 */ "ccons ::= GENERATED ALWAYS AS generated", +- /* 369 */ "ccons ::= AS generated", +- /* 370 */ "conslist_opt ::= COMMA conslist", +- /* 371 */ "conslist ::= conslist tconscomma tcons", +- /* 372 */ "conslist ::= tcons", +- /* 373 */ "tconscomma ::=", +- /* 374 */ "defer_subclause_opt ::= defer_subclause", +- /* 375 */ "resolvetype ::= raisetype", +- /* 376 */ "selectnowith ::= oneselect", +- /* 377 */ "oneselect ::= values", +- /* 378 */ "sclp ::= selcollist COMMA", +- /* 379 */ "as ::= ID|STRING", +- /* 380 */ "indexed_opt ::= indexed_by", +- /* 381 */ "returning ::=", +- /* 382 */ "expr ::= term", +- /* 383 */ "likeop ::= LIKE_KW|MATCH", +- /* 384 */ "case_operand ::= expr", +- /* 385 */ "exprlist ::= nexprlist", +- /* 386 */ "nmnum ::= plus_num", +- /* 387 */ "nmnum ::= nm", +- /* 388 */ "nmnum ::= ON", +- /* 389 */ "nmnum ::= DELETE", +- /* 390 */ "nmnum ::= DEFAULT", +- /* 391 */ "plus_num ::= INTEGER|FLOAT", +- /* 392 */ "foreach_clause ::=", +- /* 393 */ "foreach_clause ::= FOR EACH ROW", +- /* 394 */ "trnm ::= nm", +- /* 395 */ "tridxby ::=", +- /* 396 */ "database_kw_opt ::= DATABASE", +- /* 397 */ "database_kw_opt ::=", +- /* 398 */ "kwcolumn_opt ::=", +- /* 399 */ "kwcolumn_opt ::= COLUMNKW", +- /* 400 */ "vtabarglist ::= vtabarg", +- /* 401 */ "vtabarglist ::= vtabarglist COMMA vtabarg", +- /* 402 */ "vtabarg ::= vtabarg vtabargtoken", +- /* 403 */ "anylist ::=", +- /* 404 */ "anylist ::= anylist LP anylist RP", +- /* 405 */ "anylist ::= anylist ANY", +- /* 406 */ "with ::=", +- /* 407 */ "windowdefn_list ::= windowdefn", +- /* 408 */ "window ::= frame_opt", ++ /* 296 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", ++ /* 297 */ "cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm", ++ /* 298 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL", ++ /* 299 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf", ++ /* 300 */ "cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf", ++ /* 301 */ "cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf", ++ /* 302 */ "cmd ::= create_vtab", ++ /* 303 */ "cmd ::= create_vtab LP vtabarglist RP", ++ /* 304 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", ++ /* 305 */ "vtabarg ::=", ++ /* 306 */ "vtabargtoken ::= ANY", ++ /* 307 */ "vtabargtoken ::= lp anylist RP", ++ /* 308 */ "lp ::= LP", ++ /* 309 */ "with ::= WITH wqlist", ++ /* 310 */ "with ::= WITH RECURSIVE wqlist", ++ /* 311 */ "wqas ::= AS", ++ /* 312 */ "wqas ::= AS MATERIALIZED", ++ /* 313 */ "wqas ::= AS NOT MATERIALIZED", ++ /* 314 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", ++ /* 315 */ "withnm ::= nm", ++ /* 316 */ "wqlist ::= wqitem", ++ /* 317 */ "wqlist ::= wqlist COMMA wqitem", ++ /* 318 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", ++ /* 319 */ "windowdefn ::= nm AS LP window RP", ++ /* 320 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", ++ /* 321 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", ++ /* 322 */ "window ::= ORDER BY sortlist frame_opt", ++ /* 323 */ "window ::= nm ORDER BY sortlist frame_opt", ++ /* 324 */ "window ::= nm frame_opt", ++ /* 325 */ "frame_opt ::=", ++ /* 326 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", ++ /* 327 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", ++ /* 328 */ "range_or_rows ::= RANGE|ROWS|GROUPS", ++ /* 329 */ "frame_bound_s ::= frame_bound", ++ /* 330 */ "frame_bound_s ::= UNBOUNDED PRECEDING", ++ /* 331 */ "frame_bound_e ::= frame_bound", ++ /* 332 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", ++ /* 333 */ "frame_bound ::= expr PRECEDING|FOLLOWING", ++ /* 334 */ "frame_bound ::= CURRENT ROW", ++ /* 335 */ "frame_exclude_opt ::=", ++ /* 336 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", ++ /* 337 */ "frame_exclude ::= NO OTHERS", ++ /* 338 */ "frame_exclude ::= CURRENT ROW", ++ /* 339 */ "frame_exclude ::= GROUP|TIES", ++ /* 340 */ "window_clause ::= WINDOW windowdefn_list", ++ /* 341 */ "filter_over ::= filter_clause over_clause", ++ /* 342 */ "filter_over ::= over_clause", ++ /* 343 */ "filter_over ::= filter_clause", ++ /* 344 */ "over_clause ::= OVER LP window RP", ++ /* 345 */ "over_clause ::= OVER nm", ++ /* 346 */ "filter_clause ::= FILTER LP WHERE expr RP", ++ /* 347 */ "term ::= QNUMBER", ++ /* 348 */ "input ::= cmdlist", ++ /* 349 */ "cmdlist ::= cmdlist ecmd", ++ /* 350 */ "cmdlist ::= ecmd", ++ /* 351 */ "ecmd ::= SEMI", ++ /* 352 */ "ecmd ::= cmdx SEMI", ++ /* 353 */ "ecmd ::= explain cmdx SEMI", ++ /* 354 */ "trans_opt ::=", ++ /* 355 */ "trans_opt ::= TRANSACTION", ++ /* 356 */ "trans_opt ::= TRANSACTION nm", ++ /* 357 */ "savepoint_opt ::= SAVEPOINT", ++ /* 358 */ "savepoint_opt ::=", ++ /* 359 */ "cmd ::= create_table create_table_args", ++ /* 360 */ "table_option_set ::= table_option", ++ /* 361 */ "columnlist ::= columnlist COMMA columnname carglist", ++ /* 362 */ "columnlist ::= columnname carglist", ++ /* 363 */ "nm ::= ID|INDEXED|JOIN_KW", ++ /* 364 */ "nm ::= STRING", ++ /* 365 */ "typetoken ::= typename", ++ /* 366 */ "typename ::= ID|STRING", ++ /* 367 */ "signed ::= plus_num", ++ /* 368 */ "signed ::= minus_num", ++ /* 369 */ "carglist ::= carglist ccons", ++ /* 370 */ "carglist ::=", ++ /* 371 */ "ccons ::= NULL onconf", ++ /* 372 */ "ccons ::= GENERATED ALWAYS AS generated", ++ /* 373 */ "ccons ::= AS generated", ++ /* 374 */ "conslist_opt ::= COMMA conslist", ++ /* 375 */ "conslist ::= conslist tconscomma tcons", ++ /* 376 */ "conslist ::= tcons", ++ /* 377 */ "tconscomma ::=", ++ /* 378 */ "defer_subclause_opt ::= defer_subclause", ++ /* 379 */ "resolvetype ::= raisetype", ++ /* 380 */ "selectnowith ::= oneselect", ++ /* 381 */ "oneselect ::= values", ++ /* 382 */ "sclp ::= selcollist COMMA", ++ /* 383 */ "as ::= ID|STRING", ++ /* 384 */ "indexed_opt ::= indexed_by", ++ /* 385 */ "returning ::=", ++ /* 386 */ "expr ::= term", ++ /* 387 */ "likeop ::= LIKE_KW|MATCH", ++ /* 388 */ "case_operand ::= expr", ++ /* 389 */ "exprlist ::= nexprlist", ++ /* 390 */ "nmnum ::= plus_num", ++ /* 391 */ "nmnum ::= nm", ++ /* 392 */ "nmnum ::= ON", ++ /* 393 */ "nmnum ::= DELETE", ++ /* 394 */ "nmnum ::= DEFAULT", ++ /* 395 */ "plus_num ::= INTEGER|FLOAT", ++ /* 396 */ "foreach_clause ::=", ++ /* 397 */ "foreach_clause ::= FOR EACH ROW", ++ /* 398 */ "tridxby ::=", ++ /* 399 */ "database_kw_opt ::= DATABASE", ++ /* 400 */ "database_kw_opt ::=", ++ /* 401 */ "kwcolumn_opt ::=", ++ /* 402 */ "kwcolumn_opt ::= COLUMNKW", ++ /* 403 */ "vtabarglist ::= vtabarg", ++ /* 404 */ "vtabarglist ::= vtabarglist COMMA vtabarg", ++ /* 405 */ "vtabarg ::= vtabarg vtabargtoken", ++ /* 406 */ "anylist ::=", ++ /* 407 */ "anylist ::= anylist LP anylist RP", ++ /* 408 */ "anylist ::= anylist ANY", ++ /* 409 */ "with ::=", ++ /* 410 */ "windowdefn_list ::= windowdefn", ++ /* 411 */ "window ::= frame_opt", + }; + #endif /* NDEBUG */ + +@@ -179859,15 +182270,24 @@ static int yyGrowStack(yyParser *p){ + int newSize; + int idx; + yyStackEntry *pNew; ++#ifdef YYSIZELIMIT ++ int nLimit = YYSIZELIMIT(sqlite3ParserCTX(p)); ++#endif + + newSize = oldSize*2 + 100; ++#ifdef YYSIZELIMIT ++ if( newSize>nLimit ){ ++ newSize = nLimit; ++ if( newSize<=oldSize ) return 1; ++ } ++#endif + idx = (int)(p->yytos - p->yystack); + if( p->yystack==p->yystk0 ){ +- pNew = YYREALLOC(0, newSize*sizeof(pNew[0])); ++ pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p)); + if( pNew==0 ) return 1; + memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); + }else{ +- pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0])); ++ pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p)); + if( pNew==0 ) return 1; + } + p->yystack = pNew; +@@ -179974,7 +182394,7 @@ static void yy_destructor( + case 254: /* values */ + case 256: /* mvalues */ + { +-sqlite3SelectDelete(pParse->db, (yypminor->yy637)); ++sqlite3SelectDelete(pParse->db, (yypminor->yy555)); + } + break; + case 218: /* term */ +@@ -179986,10 +182406,10 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy637)); + case 283: /* case_else */ + case 286: /* vinto */ + case 293: /* when_clause */ +- case 298: /* key_opt */ +- case 315: /* filter_clause */ ++ case 297: /* key_opt */ ++ case 314: /* filter_clause */ + { +-sqlite3ExprDelete(pParse->db, (yypminor->yy590)); ++sqlite3ExprDelete(pParse->db, (yypminor->yy454)); + } + break; + case 223: /* eidlist_opt */ +@@ -180004,9 +182424,9 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy590)); + case 271: /* setlist */ + case 280: /* paren_exprlist */ + case 282: /* case_exprlist */ +- case 314: /* part_opt */ ++ case 313: /* part_opt */ + { +-sqlite3ExprListDelete(pParse->db, (yypminor->yy402)); ++sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); + } + break; + case 240: /* fullname */ +@@ -180015,51 +182435,51 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy402)); + case 260: /* stl_prefix */ + case 265: /* xfullname */ + { +-sqlite3SrcListDelete(pParse->db, (yypminor->yy563)); ++sqlite3SrcListDelete(pParse->db, (yypminor->yy203)); + } + break; + case 243: /* wqlist */ + { +-sqlite3WithDelete(pParse->db, (yypminor->yy125)); ++sqlite3WithDelete(pParse->db, (yypminor->yy59)); + } + break; + case 253: /* window_clause */ +- case 310: /* windowdefn_list */ ++ case 309: /* windowdefn_list */ + { +-sqlite3WindowListDelete(pParse->db, (yypminor->yy483)); ++sqlite3WindowListDelete(pParse->db, (yypminor->yy211)); + } + break; + case 266: /* idlist */ + case 273: /* idlist_opt */ + { +-sqlite3IdListDelete(pParse->db, (yypminor->yy204)); ++sqlite3IdListDelete(pParse->db, (yypminor->yy132)); + } + break; + case 276: /* filter_over */ +- case 311: /* windowdefn */ +- case 312: /* window */ +- case 313: /* frame_opt */ +- case 316: /* over_clause */ ++ case 310: /* windowdefn */ ++ case 311: /* window */ ++ case 312: /* frame_opt */ ++ case 315: /* over_clause */ + { +-sqlite3WindowDelete(pParse->db, (yypminor->yy483)); ++sqlite3WindowDelete(pParse->db, (yypminor->yy211)); + } + break; + case 289: /* trigger_cmd_list */ + case 294: /* trigger_cmd */ + { +-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy319)); ++sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427)); + } + break; + case 291: /* trigger_event */ + { +-sqlite3IdListDelete(pParse->db, (yypminor->yy28).b); ++sqlite3IdListDelete(pParse->db, (yypminor->yy286).b); + } + break; +- case 318: /* frame_bound */ +- case 319: /* frame_bound_s */ +- case 320: /* frame_bound_e */ ++ case 317: /* frame_bound */ ++ case 318: /* frame_bound_s */ ++ case 319: /* frame_bound_e */ + { +-sqlite3ExprDelete(pParse->db, (yypminor->yy205).pExpr); ++sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr); + } + break; + /********* End destructor definitions *****************************************/ +@@ -180112,7 +182532,9 @@ SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ + } + + #if YYGROWABLESTACK +- if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); ++ if( pParser->yystack!=pParser->yystk0 ){ ++ YYFREE(pParser->yystack, sqlite3ParserCTX(pParser)); ++ } + #endif + } + +@@ -180295,7 +182717,7 @@ static void yyStackOverflow(yyParser *yypParser){ + ** stack every overflows */ + /******** Begin %stack_overflow code ******************************************/ + +- sqlite3OomFault(pParse->db); ++ if( pParse->nErr==0 ) sqlite3ErrorMsg(pParse, "Recursion limit"); + /******** End %stack_overflow code ********************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ + sqlite3ParserCTX_STORE +@@ -180483,8 +182905,8 @@ static const YYCODETYPE yyRuleInfoLhs[] = { + 240, /* (119) fullname ::= nm DOT nm */ + 265, /* (120) xfullname ::= nm */ + 265, /* (121) xfullname ::= nm DOT nm */ +- 265, /* (122) xfullname ::= nm DOT nm AS nm */ +- 265, /* (123) xfullname ::= nm AS nm */ ++ 265, /* (122) xfullname ::= nm AS nm */ ++ 265, /* (123) xfullname ::= nm DOT nm AS nm */ + 261, /* (124) joinop ::= COMMA|JOIN */ + 261, /* (125) joinop ::= JOIN_KW JOIN */ + 261, /* (126) joinop ::= JOIN_KW nm JOIN */ +@@ -180633,143 +183055,146 @@ static const YYCODETYPE yyRuleInfoLhs[] = { + 293, /* (269) when_clause ::= WHEN expr */ + 289, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 289, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ +- 295, /* (272) trnm ::= nm DOT nm */ +- 296, /* (273) tridxby ::= INDEXED BY nm */ +- 296, /* (274) tridxby ::= NOT INDEXED */ +- 294, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +- 294, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ +- 294, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +- 294, /* (278) trigger_cmd ::= scanpt select scanpt */ +- 219, /* (279) expr ::= RAISE LP IGNORE RP */ +- 219, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ +- 238, /* (281) raisetype ::= ROLLBACK */ +- 238, /* (282) raisetype ::= ABORT */ +- 238, /* (283) raisetype ::= FAIL */ +- 192, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ +- 192, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +- 192, /* (286) cmd ::= DETACH database_kw_opt expr */ +- 298, /* (287) key_opt ::= */ +- 298, /* (288) key_opt ::= KEY expr */ +- 192, /* (289) cmd ::= REINDEX */ +- 192, /* (290) cmd ::= REINDEX nm dbnm */ +- 192, /* (291) cmd ::= ANALYZE */ +- 192, /* (292) cmd ::= ANALYZE nm dbnm */ +- 192, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ +- 192, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ ++ 295, /* (272) tridxby ::= INDEXED BY nm */ ++ 295, /* (273) tridxby ::= NOT INDEXED */ ++ 294, /* (274) trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ ++ 294, /* (275) trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ ++ 294, /* (276) trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ ++ 294, /* (277) trigger_cmd ::= scanpt select scanpt */ ++ 219, /* (278) expr ::= RAISE LP IGNORE RP */ ++ 219, /* (279) expr ::= RAISE LP raisetype COMMA expr RP */ ++ 238, /* (280) raisetype ::= ROLLBACK */ ++ 238, /* (281) raisetype ::= ABORT */ ++ 238, /* (282) raisetype ::= FAIL */ ++ 192, /* (283) cmd ::= DROP TRIGGER ifexists fullname */ ++ 192, /* (284) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ ++ 192, /* (285) cmd ::= DETACH database_kw_opt expr */ ++ 297, /* (286) key_opt ::= */ ++ 297, /* (287) key_opt ::= KEY expr */ ++ 192, /* (288) cmd ::= REINDEX */ ++ 192, /* (289) cmd ::= REINDEX nm dbnm */ ++ 192, /* (290) cmd ::= ANALYZE */ ++ 192, /* (291) cmd ::= ANALYZE nm dbnm */ ++ 192, /* (292) cmd ::= ALTER TABLE fullname RENAME TO nm */ ++ 192, /* (293) cmd ::= alter_add carglist */ ++ 298, /* (294) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ + 192, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +- 299, /* (296) add_column_fullname ::= fullname */ +- 192, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ +- 192, /* (298) cmd ::= create_vtab */ +- 192, /* (299) cmd ::= create_vtab LP vtabarglist RP */ +- 301, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ +- 303, /* (301) vtabarg ::= */ +- 304, /* (302) vtabargtoken ::= ANY */ +- 304, /* (303) vtabargtoken ::= lp anylist RP */ +- 305, /* (304) lp ::= LP */ +- 269, /* (305) with ::= WITH wqlist */ +- 269, /* (306) with ::= WITH RECURSIVE wqlist */ +- 308, /* (307) wqas ::= AS */ +- 308, /* (308) wqas ::= AS MATERIALIZED */ +- 308, /* (309) wqas ::= AS NOT MATERIALIZED */ +- 307, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ +- 309, /* (311) withnm ::= nm */ +- 243, /* (312) wqlist ::= wqitem */ +- 243, /* (313) wqlist ::= wqlist COMMA wqitem */ +- 310, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ +- 311, /* (315) windowdefn ::= nm AS LP window RP */ +- 312, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ +- 312, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ +- 312, /* (318) window ::= ORDER BY sortlist frame_opt */ +- 312, /* (319) window ::= nm ORDER BY sortlist frame_opt */ +- 312, /* (320) window ::= nm frame_opt */ +- 313, /* (321) frame_opt ::= */ +- 313, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ +- 313, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ +- 317, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ +- 319, /* (325) frame_bound_s ::= frame_bound */ +- 319, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ +- 320, /* (327) frame_bound_e ::= frame_bound */ +- 320, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ +- 318, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ +- 318, /* (330) frame_bound ::= CURRENT ROW */ +- 321, /* (331) frame_exclude_opt ::= */ +- 321, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ +- 322, /* (333) frame_exclude ::= NO OTHERS */ +- 322, /* (334) frame_exclude ::= CURRENT ROW */ +- 322, /* (335) frame_exclude ::= GROUP|TIES */ +- 253, /* (336) window_clause ::= WINDOW windowdefn_list */ +- 276, /* (337) filter_over ::= filter_clause over_clause */ +- 276, /* (338) filter_over ::= over_clause */ +- 276, /* (339) filter_over ::= filter_clause */ +- 316, /* (340) over_clause ::= OVER LP window RP */ +- 316, /* (341) over_clause ::= OVER nm */ +- 315, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ +- 218, /* (343) term ::= QNUMBER */ +- 187, /* (344) input ::= cmdlist */ +- 188, /* (345) cmdlist ::= cmdlist ecmd */ +- 188, /* (346) cmdlist ::= ecmd */ +- 189, /* (347) ecmd ::= SEMI */ +- 189, /* (348) ecmd ::= cmdx SEMI */ +- 189, /* (349) ecmd ::= explain cmdx SEMI */ +- 194, /* (350) trans_opt ::= */ +- 194, /* (351) trans_opt ::= TRANSACTION */ +- 194, /* (352) trans_opt ::= TRANSACTION nm */ +- 196, /* (353) savepoint_opt ::= SAVEPOINT */ +- 196, /* (354) savepoint_opt ::= */ +- 192, /* (355) cmd ::= create_table create_table_args */ +- 205, /* (356) table_option_set ::= table_option */ +- 203, /* (357) columnlist ::= columnlist COMMA columnname carglist */ +- 203, /* (358) columnlist ::= columnname carglist */ +- 195, /* (359) nm ::= ID|INDEXED|JOIN_KW */ +- 195, /* (360) nm ::= STRING */ +- 210, /* (361) typetoken ::= typename */ +- 211, /* (362) typename ::= ID|STRING */ +- 212, /* (363) signed ::= plus_num */ +- 212, /* (364) signed ::= minus_num */ +- 209, /* (365) carglist ::= carglist ccons */ +- 209, /* (366) carglist ::= */ +- 217, /* (367) ccons ::= NULL onconf */ +- 217, /* (368) ccons ::= GENERATED ALWAYS AS generated */ +- 217, /* (369) ccons ::= AS generated */ +- 204, /* (370) conslist_opt ::= COMMA conslist */ +- 230, /* (371) conslist ::= conslist tconscomma tcons */ +- 230, /* (372) conslist ::= tcons */ +- 231, /* (373) tconscomma ::= */ +- 235, /* (374) defer_subclause_opt ::= defer_subclause */ +- 237, /* (375) resolvetype ::= raisetype */ +- 241, /* (376) selectnowith ::= oneselect */ +- 242, /* (377) oneselect ::= values */ +- 257, /* (378) sclp ::= selcollist COMMA */ +- 258, /* (379) as ::= ID|STRING */ +- 267, /* (380) indexed_opt ::= indexed_by */ +- 275, /* (381) returning ::= */ +- 219, /* (382) expr ::= term */ +- 277, /* (383) likeop ::= LIKE_KW|MATCH */ +- 281, /* (384) case_operand ::= expr */ +- 264, /* (385) exprlist ::= nexprlist */ +- 287, /* (386) nmnum ::= plus_num */ +- 287, /* (387) nmnum ::= nm */ +- 287, /* (388) nmnum ::= ON */ +- 287, /* (389) nmnum ::= DELETE */ +- 287, /* (390) nmnum ::= DEFAULT */ +- 213, /* (391) plus_num ::= INTEGER|FLOAT */ +- 292, /* (392) foreach_clause ::= */ +- 292, /* (393) foreach_clause ::= FOR EACH ROW */ +- 295, /* (394) trnm ::= nm */ +- 296, /* (395) tridxby ::= */ +- 297, /* (396) database_kw_opt ::= DATABASE */ +- 297, /* (397) database_kw_opt ::= */ +- 300, /* (398) kwcolumn_opt ::= */ +- 300, /* (399) kwcolumn_opt ::= COLUMNKW */ +- 302, /* (400) vtabarglist ::= vtabarg */ +- 302, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ +- 303, /* (402) vtabarg ::= vtabarg vtabargtoken */ +- 306, /* (403) anylist ::= */ +- 306, /* (404) anylist ::= anylist LP anylist RP */ +- 306, /* (405) anylist ::= anylist ANY */ +- 269, /* (406) with ::= */ +- 310, /* (407) windowdefn_list ::= windowdefn */ +- 312, /* (408) window ::= frame_opt */ ++ 192, /* (296) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ ++ 192, /* (297) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ ++ 192, /* (298) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ ++ 192, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ ++ 192, /* (300) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ ++ 192, /* (301) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ ++ 192, /* (302) cmd ::= create_vtab */ ++ 192, /* (303) cmd ::= create_vtab LP vtabarglist RP */ ++ 300, /* (304) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ ++ 302, /* (305) vtabarg ::= */ ++ 303, /* (306) vtabargtoken ::= ANY */ ++ 303, /* (307) vtabargtoken ::= lp anylist RP */ ++ 304, /* (308) lp ::= LP */ ++ 269, /* (309) with ::= WITH wqlist */ ++ 269, /* (310) with ::= WITH RECURSIVE wqlist */ ++ 307, /* (311) wqas ::= AS */ ++ 307, /* (312) wqas ::= AS MATERIALIZED */ ++ 307, /* (313) wqas ::= AS NOT MATERIALIZED */ ++ 306, /* (314) wqitem ::= withnm eidlist_opt wqas LP select RP */ ++ 308, /* (315) withnm ::= nm */ ++ 243, /* (316) wqlist ::= wqitem */ ++ 243, /* (317) wqlist ::= wqlist COMMA wqitem */ ++ 309, /* (318) windowdefn_list ::= windowdefn_list COMMA windowdefn */ ++ 310, /* (319) windowdefn ::= nm AS LP window RP */ ++ 311, /* (320) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ ++ 311, /* (321) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ ++ 311, /* (322) window ::= ORDER BY sortlist frame_opt */ ++ 311, /* (323) window ::= nm ORDER BY sortlist frame_opt */ ++ 311, /* (324) window ::= nm frame_opt */ ++ 312, /* (325) frame_opt ::= */ ++ 312, /* (326) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ ++ 312, /* (327) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ ++ 316, /* (328) range_or_rows ::= RANGE|ROWS|GROUPS */ ++ 318, /* (329) frame_bound_s ::= frame_bound */ ++ 318, /* (330) frame_bound_s ::= UNBOUNDED PRECEDING */ ++ 319, /* (331) frame_bound_e ::= frame_bound */ ++ 319, /* (332) frame_bound_e ::= UNBOUNDED FOLLOWING */ ++ 317, /* (333) frame_bound ::= expr PRECEDING|FOLLOWING */ ++ 317, /* (334) frame_bound ::= CURRENT ROW */ ++ 320, /* (335) frame_exclude_opt ::= */ ++ 320, /* (336) frame_exclude_opt ::= EXCLUDE frame_exclude */ ++ 321, /* (337) frame_exclude ::= NO OTHERS */ ++ 321, /* (338) frame_exclude ::= CURRENT ROW */ ++ 321, /* (339) frame_exclude ::= GROUP|TIES */ ++ 253, /* (340) window_clause ::= WINDOW windowdefn_list */ ++ 276, /* (341) filter_over ::= filter_clause over_clause */ ++ 276, /* (342) filter_over ::= over_clause */ ++ 276, /* (343) filter_over ::= filter_clause */ ++ 315, /* (344) over_clause ::= OVER LP window RP */ ++ 315, /* (345) over_clause ::= OVER nm */ ++ 314, /* (346) filter_clause ::= FILTER LP WHERE expr RP */ ++ 218, /* (347) term ::= QNUMBER */ ++ 187, /* (348) input ::= cmdlist */ ++ 188, /* (349) cmdlist ::= cmdlist ecmd */ ++ 188, /* (350) cmdlist ::= ecmd */ ++ 189, /* (351) ecmd ::= SEMI */ ++ 189, /* (352) ecmd ::= cmdx SEMI */ ++ 189, /* (353) ecmd ::= explain cmdx SEMI */ ++ 194, /* (354) trans_opt ::= */ ++ 194, /* (355) trans_opt ::= TRANSACTION */ ++ 194, /* (356) trans_opt ::= TRANSACTION nm */ ++ 196, /* (357) savepoint_opt ::= SAVEPOINT */ ++ 196, /* (358) savepoint_opt ::= */ ++ 192, /* (359) cmd ::= create_table create_table_args */ ++ 205, /* (360) table_option_set ::= table_option */ ++ 203, /* (361) columnlist ::= columnlist COMMA columnname carglist */ ++ 203, /* (362) columnlist ::= columnname carglist */ ++ 195, /* (363) nm ::= ID|INDEXED|JOIN_KW */ ++ 195, /* (364) nm ::= STRING */ ++ 210, /* (365) typetoken ::= typename */ ++ 211, /* (366) typename ::= ID|STRING */ ++ 212, /* (367) signed ::= plus_num */ ++ 212, /* (368) signed ::= minus_num */ ++ 209, /* (369) carglist ::= carglist ccons */ ++ 209, /* (370) carglist ::= */ ++ 217, /* (371) ccons ::= NULL onconf */ ++ 217, /* (372) ccons ::= GENERATED ALWAYS AS generated */ ++ 217, /* (373) ccons ::= AS generated */ ++ 204, /* (374) conslist_opt ::= COMMA conslist */ ++ 230, /* (375) conslist ::= conslist tconscomma tcons */ ++ 230, /* (376) conslist ::= tcons */ ++ 231, /* (377) tconscomma ::= */ ++ 235, /* (378) defer_subclause_opt ::= defer_subclause */ ++ 237, /* (379) resolvetype ::= raisetype */ ++ 241, /* (380) selectnowith ::= oneselect */ ++ 242, /* (381) oneselect ::= values */ ++ 257, /* (382) sclp ::= selcollist COMMA */ ++ 258, /* (383) as ::= ID|STRING */ ++ 267, /* (384) indexed_opt ::= indexed_by */ ++ 275, /* (385) returning ::= */ ++ 219, /* (386) expr ::= term */ ++ 277, /* (387) likeop ::= LIKE_KW|MATCH */ ++ 281, /* (388) case_operand ::= expr */ ++ 264, /* (389) exprlist ::= nexprlist */ ++ 287, /* (390) nmnum ::= plus_num */ ++ 287, /* (391) nmnum ::= nm */ ++ 287, /* (392) nmnum ::= ON */ ++ 287, /* (393) nmnum ::= DELETE */ ++ 287, /* (394) nmnum ::= DEFAULT */ ++ 213, /* (395) plus_num ::= INTEGER|FLOAT */ ++ 292, /* (396) foreach_clause ::= */ ++ 292, /* (397) foreach_clause ::= FOR EACH ROW */ ++ 295, /* (398) tridxby ::= */ ++ 296, /* (399) database_kw_opt ::= DATABASE */ ++ 296, /* (400) database_kw_opt ::= */ ++ 299, /* (401) kwcolumn_opt ::= */ ++ 299, /* (402) kwcolumn_opt ::= COLUMNKW */ ++ 301, /* (403) vtabarglist ::= vtabarg */ ++ 301, /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ ++ 302, /* (405) vtabarg ::= vtabarg vtabargtoken */ ++ 305, /* (406) anylist ::= */ ++ 305, /* (407) anylist ::= anylist LP anylist RP */ ++ 305, /* (408) anylist ::= anylist ANY */ ++ 269, /* (409) with ::= */ ++ 309, /* (410) windowdefn_list ::= windowdefn */ ++ 311, /* (411) window ::= frame_opt */ + }; + + /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number +@@ -180897,8 +183322,8 @@ static const signed char yyRuleInfoNRhs[] = { + -3, /* (119) fullname ::= nm DOT nm */ + -1, /* (120) xfullname ::= nm */ + -3, /* (121) xfullname ::= nm DOT nm */ +- -5, /* (122) xfullname ::= nm DOT nm AS nm */ +- -3, /* (123) xfullname ::= nm AS nm */ ++ -3, /* (122) xfullname ::= nm AS nm */ ++ -5, /* (123) xfullname ::= nm DOT nm AS nm */ + -1, /* (124) joinop ::= COMMA|JOIN */ + -2, /* (125) joinop ::= JOIN_KW JOIN */ + -3, /* (126) joinop ::= JOIN_KW nm JOIN */ +@@ -181047,143 +183472,146 @@ static const signed char yyRuleInfoNRhs[] = { + -2, /* (269) when_clause ::= WHEN expr */ + -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ +- -3, /* (272) trnm ::= nm DOT nm */ +- -3, /* (273) tridxby ::= INDEXED BY nm */ +- -2, /* (274) tridxby ::= NOT INDEXED */ +- -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +- -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ +- -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +- -3, /* (278) trigger_cmd ::= scanpt select scanpt */ +- -4, /* (279) expr ::= RAISE LP IGNORE RP */ +- -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ +- -1, /* (281) raisetype ::= ROLLBACK */ +- -1, /* (282) raisetype ::= ABORT */ +- -1, /* (283) raisetype ::= FAIL */ +- -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ +- -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +- -3, /* (286) cmd ::= DETACH database_kw_opt expr */ +- 0, /* (287) key_opt ::= */ +- -2, /* (288) key_opt ::= KEY expr */ +- -1, /* (289) cmd ::= REINDEX */ +- -3, /* (290) cmd ::= REINDEX nm dbnm */ +- -1, /* (291) cmd ::= ANALYZE */ +- -3, /* (292) cmd ::= ANALYZE nm dbnm */ +- -6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ +- -7, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ ++ -3, /* (272) tridxby ::= INDEXED BY nm */ ++ -2, /* (273) tridxby ::= NOT INDEXED */ ++ -9, /* (274) trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ ++ -8, /* (275) trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ ++ -6, /* (276) trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ ++ -3, /* (277) trigger_cmd ::= scanpt select scanpt */ ++ -4, /* (278) expr ::= RAISE LP IGNORE RP */ ++ -6, /* (279) expr ::= RAISE LP raisetype COMMA expr RP */ ++ -1, /* (280) raisetype ::= ROLLBACK */ ++ -1, /* (281) raisetype ::= ABORT */ ++ -1, /* (282) raisetype ::= FAIL */ ++ -4, /* (283) cmd ::= DROP TRIGGER ifexists fullname */ ++ -6, /* (284) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ ++ -3, /* (285) cmd ::= DETACH database_kw_opt expr */ ++ 0, /* (286) key_opt ::= */ ++ -2, /* (287) key_opt ::= KEY expr */ ++ -1, /* (288) cmd ::= REINDEX */ ++ -3, /* (289) cmd ::= REINDEX nm dbnm */ ++ -1, /* (290) cmd ::= ANALYZE */ ++ -3, /* (291) cmd ::= ANALYZE nm dbnm */ ++ -6, /* (292) cmd ::= ALTER TABLE fullname RENAME TO nm */ ++ -2, /* (293) cmd ::= alter_add carglist */ ++ -7, /* (294) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ + -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +- -1, /* (296) add_column_fullname ::= fullname */ +- -8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ +- -1, /* (298) cmd ::= create_vtab */ +- -4, /* (299) cmd ::= create_vtab LP vtabarglist RP */ +- -8, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ +- 0, /* (301) vtabarg ::= */ +- -1, /* (302) vtabargtoken ::= ANY */ +- -3, /* (303) vtabargtoken ::= lp anylist RP */ +- -1, /* (304) lp ::= LP */ +- -2, /* (305) with ::= WITH wqlist */ +- -3, /* (306) with ::= WITH RECURSIVE wqlist */ +- -1, /* (307) wqas ::= AS */ +- -2, /* (308) wqas ::= AS MATERIALIZED */ +- -3, /* (309) wqas ::= AS NOT MATERIALIZED */ +- -6, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ +- -1, /* (311) withnm ::= nm */ +- -1, /* (312) wqlist ::= wqitem */ +- -3, /* (313) wqlist ::= wqlist COMMA wqitem */ +- -3, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ +- -5, /* (315) windowdefn ::= nm AS LP window RP */ +- -5, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ +- -6, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ +- -4, /* (318) window ::= ORDER BY sortlist frame_opt */ +- -5, /* (319) window ::= nm ORDER BY sortlist frame_opt */ +- -2, /* (320) window ::= nm frame_opt */ +- 0, /* (321) frame_opt ::= */ +- -3, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ +- -6, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ +- -1, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ +- -1, /* (325) frame_bound_s ::= frame_bound */ +- -2, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ +- -1, /* (327) frame_bound_e ::= frame_bound */ +- -2, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ +- -2, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ +- -2, /* (330) frame_bound ::= CURRENT ROW */ +- 0, /* (331) frame_exclude_opt ::= */ +- -2, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ +- -2, /* (333) frame_exclude ::= NO OTHERS */ +- -2, /* (334) frame_exclude ::= CURRENT ROW */ +- -1, /* (335) frame_exclude ::= GROUP|TIES */ +- -2, /* (336) window_clause ::= WINDOW windowdefn_list */ +- -2, /* (337) filter_over ::= filter_clause over_clause */ +- -1, /* (338) filter_over ::= over_clause */ +- -1, /* (339) filter_over ::= filter_clause */ +- -4, /* (340) over_clause ::= OVER LP window RP */ +- -2, /* (341) over_clause ::= OVER nm */ +- -5, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ +- -1, /* (343) term ::= QNUMBER */ +- -1, /* (344) input ::= cmdlist */ +- -2, /* (345) cmdlist ::= cmdlist ecmd */ +- -1, /* (346) cmdlist ::= ecmd */ +- -1, /* (347) ecmd ::= SEMI */ +- -2, /* (348) ecmd ::= cmdx SEMI */ +- -3, /* (349) ecmd ::= explain cmdx SEMI */ +- 0, /* (350) trans_opt ::= */ +- -1, /* (351) trans_opt ::= TRANSACTION */ +- -2, /* (352) trans_opt ::= TRANSACTION nm */ +- -1, /* (353) savepoint_opt ::= SAVEPOINT */ +- 0, /* (354) savepoint_opt ::= */ +- -2, /* (355) cmd ::= create_table create_table_args */ +- -1, /* (356) table_option_set ::= table_option */ +- -4, /* (357) columnlist ::= columnlist COMMA columnname carglist */ +- -2, /* (358) columnlist ::= columnname carglist */ +- -1, /* (359) nm ::= ID|INDEXED|JOIN_KW */ +- -1, /* (360) nm ::= STRING */ +- -1, /* (361) typetoken ::= typename */ +- -1, /* (362) typename ::= ID|STRING */ +- -1, /* (363) signed ::= plus_num */ +- -1, /* (364) signed ::= minus_num */ +- -2, /* (365) carglist ::= carglist ccons */ +- 0, /* (366) carglist ::= */ +- -2, /* (367) ccons ::= NULL onconf */ +- -4, /* (368) ccons ::= GENERATED ALWAYS AS generated */ +- -2, /* (369) ccons ::= AS generated */ +- -2, /* (370) conslist_opt ::= COMMA conslist */ +- -3, /* (371) conslist ::= conslist tconscomma tcons */ +- -1, /* (372) conslist ::= tcons */ +- 0, /* (373) tconscomma ::= */ +- -1, /* (374) defer_subclause_opt ::= defer_subclause */ +- -1, /* (375) resolvetype ::= raisetype */ +- -1, /* (376) selectnowith ::= oneselect */ +- -1, /* (377) oneselect ::= values */ +- -2, /* (378) sclp ::= selcollist COMMA */ +- -1, /* (379) as ::= ID|STRING */ +- -1, /* (380) indexed_opt ::= indexed_by */ +- 0, /* (381) returning ::= */ +- -1, /* (382) expr ::= term */ +- -1, /* (383) likeop ::= LIKE_KW|MATCH */ +- -1, /* (384) case_operand ::= expr */ +- -1, /* (385) exprlist ::= nexprlist */ +- -1, /* (386) nmnum ::= plus_num */ +- -1, /* (387) nmnum ::= nm */ +- -1, /* (388) nmnum ::= ON */ +- -1, /* (389) nmnum ::= DELETE */ +- -1, /* (390) nmnum ::= DEFAULT */ +- -1, /* (391) plus_num ::= INTEGER|FLOAT */ +- 0, /* (392) foreach_clause ::= */ +- -3, /* (393) foreach_clause ::= FOR EACH ROW */ +- -1, /* (394) trnm ::= nm */ +- 0, /* (395) tridxby ::= */ +- -1, /* (396) database_kw_opt ::= DATABASE */ +- 0, /* (397) database_kw_opt ::= */ +- 0, /* (398) kwcolumn_opt ::= */ +- -1, /* (399) kwcolumn_opt ::= COLUMNKW */ +- -1, /* (400) vtabarglist ::= vtabarg */ +- -3, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ +- -2, /* (402) vtabarg ::= vtabarg vtabargtoken */ +- 0, /* (403) anylist ::= */ +- -4, /* (404) anylist ::= anylist LP anylist RP */ +- -2, /* (405) anylist ::= anylist ANY */ +- 0, /* (406) with ::= */ +- -1, /* (407) windowdefn_list ::= windowdefn */ +- -1, /* (408) window ::= frame_opt */ ++ -8, /* (296) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ ++ -6, /* (297) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ ++ -9, /* (298) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ ++ -10, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ ++ -11, /* (300) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ ++ -9, /* (301) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ ++ -1, /* (302) cmd ::= create_vtab */ ++ -4, /* (303) cmd ::= create_vtab LP vtabarglist RP */ ++ -8, /* (304) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ ++ 0, /* (305) vtabarg ::= */ ++ -1, /* (306) vtabargtoken ::= ANY */ ++ -3, /* (307) vtabargtoken ::= lp anylist RP */ ++ -1, /* (308) lp ::= LP */ ++ -2, /* (309) with ::= WITH wqlist */ ++ -3, /* (310) with ::= WITH RECURSIVE wqlist */ ++ -1, /* (311) wqas ::= AS */ ++ -2, /* (312) wqas ::= AS MATERIALIZED */ ++ -3, /* (313) wqas ::= AS NOT MATERIALIZED */ ++ -6, /* (314) wqitem ::= withnm eidlist_opt wqas LP select RP */ ++ -1, /* (315) withnm ::= nm */ ++ -1, /* (316) wqlist ::= wqitem */ ++ -3, /* (317) wqlist ::= wqlist COMMA wqitem */ ++ -3, /* (318) windowdefn_list ::= windowdefn_list COMMA windowdefn */ ++ -5, /* (319) windowdefn ::= nm AS LP window RP */ ++ -5, /* (320) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ ++ -6, /* (321) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ ++ -4, /* (322) window ::= ORDER BY sortlist frame_opt */ ++ -5, /* (323) window ::= nm ORDER BY sortlist frame_opt */ ++ -2, /* (324) window ::= nm frame_opt */ ++ 0, /* (325) frame_opt ::= */ ++ -3, /* (326) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ ++ -6, /* (327) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ ++ -1, /* (328) range_or_rows ::= RANGE|ROWS|GROUPS */ ++ -1, /* (329) frame_bound_s ::= frame_bound */ ++ -2, /* (330) frame_bound_s ::= UNBOUNDED PRECEDING */ ++ -1, /* (331) frame_bound_e ::= frame_bound */ ++ -2, /* (332) frame_bound_e ::= UNBOUNDED FOLLOWING */ ++ -2, /* (333) frame_bound ::= expr PRECEDING|FOLLOWING */ ++ -2, /* (334) frame_bound ::= CURRENT ROW */ ++ 0, /* (335) frame_exclude_opt ::= */ ++ -2, /* (336) frame_exclude_opt ::= EXCLUDE frame_exclude */ ++ -2, /* (337) frame_exclude ::= NO OTHERS */ ++ -2, /* (338) frame_exclude ::= CURRENT ROW */ ++ -1, /* (339) frame_exclude ::= GROUP|TIES */ ++ -2, /* (340) window_clause ::= WINDOW windowdefn_list */ ++ -2, /* (341) filter_over ::= filter_clause over_clause */ ++ -1, /* (342) filter_over ::= over_clause */ ++ -1, /* (343) filter_over ::= filter_clause */ ++ -4, /* (344) over_clause ::= OVER LP window RP */ ++ -2, /* (345) over_clause ::= OVER nm */ ++ -5, /* (346) filter_clause ::= FILTER LP WHERE expr RP */ ++ -1, /* (347) term ::= QNUMBER */ ++ -1, /* (348) input ::= cmdlist */ ++ -2, /* (349) cmdlist ::= cmdlist ecmd */ ++ -1, /* (350) cmdlist ::= ecmd */ ++ -1, /* (351) ecmd ::= SEMI */ ++ -2, /* (352) ecmd ::= cmdx SEMI */ ++ -3, /* (353) ecmd ::= explain cmdx SEMI */ ++ 0, /* (354) trans_opt ::= */ ++ -1, /* (355) trans_opt ::= TRANSACTION */ ++ -2, /* (356) trans_opt ::= TRANSACTION nm */ ++ -1, /* (357) savepoint_opt ::= SAVEPOINT */ ++ 0, /* (358) savepoint_opt ::= */ ++ -2, /* (359) cmd ::= create_table create_table_args */ ++ -1, /* (360) table_option_set ::= table_option */ ++ -4, /* (361) columnlist ::= columnlist COMMA columnname carglist */ ++ -2, /* (362) columnlist ::= columnname carglist */ ++ -1, /* (363) nm ::= ID|INDEXED|JOIN_KW */ ++ -1, /* (364) nm ::= STRING */ ++ -1, /* (365) typetoken ::= typename */ ++ -1, /* (366) typename ::= ID|STRING */ ++ -1, /* (367) signed ::= plus_num */ ++ -1, /* (368) signed ::= minus_num */ ++ -2, /* (369) carglist ::= carglist ccons */ ++ 0, /* (370) carglist ::= */ ++ -2, /* (371) ccons ::= NULL onconf */ ++ -4, /* (372) ccons ::= GENERATED ALWAYS AS generated */ ++ -2, /* (373) ccons ::= AS generated */ ++ -2, /* (374) conslist_opt ::= COMMA conslist */ ++ -3, /* (375) conslist ::= conslist tconscomma tcons */ ++ -1, /* (376) conslist ::= tcons */ ++ 0, /* (377) tconscomma ::= */ ++ -1, /* (378) defer_subclause_opt ::= defer_subclause */ ++ -1, /* (379) resolvetype ::= raisetype */ ++ -1, /* (380) selectnowith ::= oneselect */ ++ -1, /* (381) oneselect ::= values */ ++ -2, /* (382) sclp ::= selcollist COMMA */ ++ -1, /* (383) as ::= ID|STRING */ ++ -1, /* (384) indexed_opt ::= indexed_by */ ++ 0, /* (385) returning ::= */ ++ -1, /* (386) expr ::= term */ ++ -1, /* (387) likeop ::= LIKE_KW|MATCH */ ++ -1, /* (388) case_operand ::= expr */ ++ -1, /* (389) exprlist ::= nexprlist */ ++ -1, /* (390) nmnum ::= plus_num */ ++ -1, /* (391) nmnum ::= nm */ ++ -1, /* (392) nmnum ::= ON */ ++ -1, /* (393) nmnum ::= DELETE */ ++ -1, /* (394) nmnum ::= DEFAULT */ ++ -1, /* (395) plus_num ::= INTEGER|FLOAT */ ++ 0, /* (396) foreach_clause ::= */ ++ -3, /* (397) foreach_clause ::= FOR EACH ROW */ ++ 0, /* (398) tridxby ::= */ ++ -1, /* (399) database_kw_opt ::= DATABASE */ ++ 0, /* (400) database_kw_opt ::= */ ++ 0, /* (401) kwcolumn_opt ::= */ ++ -1, /* (402) kwcolumn_opt ::= COLUMNKW */ ++ -1, /* (403) vtabarglist ::= vtabarg */ ++ -3, /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ ++ -2, /* (405) vtabarg ::= vtabarg vtabargtoken */ ++ 0, /* (406) anylist ::= */ ++ -4, /* (407) anylist ::= anylist LP anylist RP */ ++ -2, /* (408) anylist ::= anylist ANY */ ++ 0, /* (409) with ::= */ ++ -1, /* (410) windowdefn_list ::= windowdefn */ ++ -1, /* (411) window ::= frame_opt */ + }; + + static void yy_accept(yyParser*); /* Forward Declaration */ +@@ -181235,16 +183663,16 @@ static YYACTIONTYPE yy_reduce( + { sqlite3FinishCoding(pParse); } + break; + case 3: /* cmd ::= BEGIN transtype trans_opt */ +-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy502);} ++{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);} + break; + case 4: /* transtype ::= */ +-{yymsp[1].minor.yy502 = TK_DEFERRED;} ++{yymsp[1].minor.yy144 = TK_DEFERRED;} + break; + case 5: /* transtype ::= DEFERRED */ + case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); + case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); +- case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324); +-{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/} ++ case 328: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==328); ++{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/} + break; + case 8: /* cmd ::= COMMIT|END trans_opt */ + case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); +@@ -181267,7 +183695,7 @@ static YYACTIONTYPE yy_reduce( + break; + case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + { +- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy502,0,0,yymsp[-2].minor.yy502); ++ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144); + } + break; + case 14: /* createkw ::= CREATE */ +@@ -181283,38 +183711,38 @@ static YYACTIONTYPE yy_reduce( + case 81: /* ifexists ::= */ yytestcase(yyruleno==81); + case 100: /* distinct ::= */ yytestcase(yyruleno==100); + case 246: /* collate ::= */ yytestcase(yyruleno==246); +-{yymsp[1].minor.yy502 = 0;} ++{yymsp[1].minor.yy144 = 0;} + break; + case 16: /* ifnotexists ::= IF NOT EXISTS */ +-{yymsp[-2].minor.yy502 = 1;} ++{yymsp[-2].minor.yy144 = 1;} + break; + case 17: /* temp ::= TEMP */ +-{yymsp[0].minor.yy502 = pParse->db->init.busy==0;} ++{yymsp[0].minor.yy144 = 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.yy9,0); ++ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0); + } + break; + case 20: /* create_table_args ::= AS select */ + { +- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy637); +- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637); ++ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555); ++ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); + } + break; + case 21: /* table_option_set ::= */ +-{yymsp[1].minor.yy9 = 0;} ++{yymsp[1].minor.yy391 = 0;} + break; + case 22: /* table_option_set ::= table_option_set COMMA table_option */ +-{yylhsminor.yy9 = yymsp[-2].minor.yy9|yymsp[0].minor.yy9;} +- yymsp[-2].minor.yy9 = yylhsminor.yy9; ++{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;} ++ yymsp[-2].minor.yy391 = yylhsminor.yy391; + 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.yy9 = TF_WithoutRowid | TF_NoVisibleRowid; ++ yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid; + }else{ +- yymsp[-1].minor.yy9 = 0; ++ yymsp[-1].minor.yy391 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } + } +@@ -181322,13 +183750,13 @@ static YYACTIONTYPE yy_reduce( + case 24: /* table_option ::= nm */ + { + if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ +- yylhsminor.yy9 = TF_Strict; ++ yylhsminor.yy391 = TF_Strict; + }else{ +- yylhsminor.yy9 = 0; ++ yylhsminor.yy391 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } + } +- yymsp[0].minor.yy9 = yylhsminor.yy9; ++ yymsp[0].minor.yy391 = yylhsminor.yy391; + break; + case 25: /* columnname ::= nm typetoken */ + {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} +@@ -181354,7 +183782,7 @@ static YYACTIONTYPE yy_reduce( + case 30: /* scanpt ::= */ + { + assert( yyLookahead!=YYNOCODE ); +- yymsp[1].minor.yy342 = yyLookaheadToken.z; ++ yymsp[1].minor.yy168 = yyLookaheadToken.z; + } + break; + case 31: /* scantok ::= */ +@@ -181368,17 +183796,17 @@ static YYACTIONTYPE yy_reduce( + {ASSERT_IS_CREATE; pParse->u1.cr.constraintName = yymsp[0].minor.yy0;} + break; + case 33: /* ccons ::= DEFAULT scantok term */ +-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} ++{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,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.yy590,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} ++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} + break; + case 35: /* ccons ::= DEFAULT PLUS scantok term */ +-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} ++{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,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.yy590, 0); ++ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0); + sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); + } + break; +@@ -181393,133 +183821,133 @@ static YYACTIONTYPE yy_reduce( + } + break; + case 38: /* ccons ::= NOT NULL onconf */ +-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy502);} ++{sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);} + break; + case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy502,yymsp[0].minor.yy502,yymsp[-2].minor.yy502);} ++{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);} + break; + case 40: /* ccons ::= UNIQUE onconf */ +-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy502,0,0,0,0, ++{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} + break; + case 41: /* ccons ::= CHECK LP expr RP */ +-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} ++{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,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.yy402,yymsp[0].minor.yy502);} ++{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);} + break; + case 43: /* ccons ::= defer_subclause */ +-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy502);} ++{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);} + 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.yy590,0);} ++{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);} + break; + case 46: /* generated ::= LP expr RP ID */ +-{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy590,&yymsp[0].minor.yy0);} ++{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);} + break; + case 48: /* autoinc ::= AUTOINCR */ +-{yymsp[0].minor.yy502 = 1;} ++{yymsp[0].minor.yy144 = 1;} + break; + case 49: /* refargs ::= */ +-{ yymsp[1].minor.yy502 = OE_None*0x0101; /* EV: R-19803-45884 */} ++{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */} + break; + case 50: /* refargs ::= refargs refarg */ +-{ yymsp[-1].minor.yy502 = (yymsp[-1].minor.yy502 & ~yymsp[0].minor.yy481.mask) | yymsp[0].minor.yy481.value; } ++{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; } + break; + case 51: /* refarg ::= MATCH nm */ +-{ yymsp[-1].minor.yy481.value = 0; yymsp[-1].minor.yy481.mask = 0x000000; } ++{ yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; } + break; + case 52: /* refarg ::= ON INSERT refact */ +-{ yymsp[-2].minor.yy481.value = 0; yymsp[-2].minor.yy481.mask = 0x000000; } ++{ yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; } + break; + case 53: /* refarg ::= ON DELETE refact */ +-{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502; yymsp[-2].minor.yy481.mask = 0x0000ff; } ++{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; } + break; + case 54: /* refarg ::= ON UPDATE refact */ +-{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502<<8; yymsp[-2].minor.yy481.mask = 0x00ff00; } ++{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; } + break; + case 55: /* refact ::= SET NULL */ +-{ yymsp[-1].minor.yy502 = OE_SetNull; /* EV: R-33326-45252 */} ++{ yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */} + break; + case 56: /* refact ::= SET DEFAULT */ +-{ yymsp[-1].minor.yy502 = OE_SetDflt; /* EV: R-33326-45252 */} ++{ yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */} + break; + case 57: /* refact ::= CASCADE */ +-{ yymsp[0].minor.yy502 = OE_Cascade; /* EV: R-33326-45252 */} ++{ yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */} + break; + case 58: /* refact ::= RESTRICT */ +-{ yymsp[0].minor.yy502 = OE_Restrict; /* EV: R-33326-45252 */} ++{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */} + break; + case 59: /* refact ::= NO ACTION */ +-{ yymsp[-1].minor.yy502 = OE_None; /* EV: R-33326-45252 */} ++{ yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */} + break; + case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ +-{yymsp[-2].minor.yy502 = 0;} ++{yymsp[-2].minor.yy144 = 0;} + break; + case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); + case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173); +-{yymsp[-1].minor.yy502 = yymsp[0].minor.yy502;} ++{yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;} + break; + case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ + case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); + case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); + case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); + case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); +-{yymsp[-1].minor.yy502 = 1;} ++{yymsp[-1].minor.yy144 = 1;} + break; + case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ +-{yymsp[-1].minor.yy502 = 0;} ++{yymsp[-1].minor.yy144 = 0;} + break; + case 66: /* tconscomma ::= COMMA */ + {ASSERT_IS_CREATE; pParse->u1.cr.constraintName.n = 0;} + break; + case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ +-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy402,yymsp[0].minor.yy502,yymsp[-2].minor.yy502,0);} ++{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);} + break; + case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ +-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy402,yymsp[0].minor.yy502,0,0,0,0, ++{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} + break; + case 70: /* tcons ::= CHECK LP expr RP onconf */ +-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy590,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} ++{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,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.yy402, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[-1].minor.yy502); +- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy502); ++ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144); ++ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144); + } + break; + case 73: /* onconf ::= */ + case 75: /* orconf ::= */ yytestcase(yyruleno==75); +-{yymsp[1].minor.yy502 = OE_Default;} ++{yymsp[1].minor.yy144 = OE_Default;} + break; + case 74: /* onconf ::= ON CONFLICT resolvetype */ +-{yymsp[-2].minor.yy502 = yymsp[0].minor.yy502;} ++{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;} + break; + case 77: /* resolvetype ::= IGNORE */ +-{yymsp[0].minor.yy502 = OE_Ignore;} ++{yymsp[0].minor.yy144 = OE_Ignore;} + break; + case 78: /* resolvetype ::= REPLACE */ + case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174); +-{yymsp[0].minor.yy502 = OE_Replace;} ++{yymsp[0].minor.yy144 = OE_Replace;} + break; + case 79: /* cmd ::= DROP TABLE ifexists fullname */ + { +- sqlite3DropTable(pParse, yymsp[0].minor.yy563, 0, yymsp[-1].minor.yy502); ++ sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144); + } + 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.yy402, yymsp[0].minor.yy637, yymsp[-7].minor.yy502, yymsp[-5].minor.yy502); ++ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144); + } + break; + case 83: /* cmd ::= DROP VIEW ifexists fullname */ + { +- sqlite3DropTable(pParse, yymsp[0].minor.yy563, 1, yymsp[-1].minor.yy502); ++ sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144); + } + break; + case 84: /* cmd ::= select */ +@@ -181528,20 +183956,20 @@ static YYACTIONTYPE yy_reduce( + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ +- sqlite3Select(pParse, yymsp[0].minor.yy637, &dest); ++ sqlite3Select(pParse, yymsp[0].minor.yy555, &dest); + } +- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637); ++ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); + } + break; + case 85: /* select ::= WITH wqlist selectnowith */ +-{yymsp[-2].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);} ++{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} + break; + case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ +-{yymsp[-3].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);} ++{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} + break; + case 87: /* select ::= selectnowith */ + { +- Select *p = yymsp[0].minor.yy637; ++ Select *p = yymsp[0].minor.yy555; + if( p ){ + parserDoubleLinkSelect(pParse, p); + } +@@ -181549,8 +183977,8 @@ static YYACTIONTYPE yy_reduce( + break; + case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ + { +- Select *pRhs = yymsp[0].minor.yy637; +- Select *pLhs = yymsp[-2].minor.yy637; ++ Select *pRhs = yymsp[0].minor.yy555; ++ Select *pLhs = yymsp[-2].minor.yy555; + if( pRhs && pRhs->pPrior ){ + SrcList *pFrom; + Token x; +@@ -181560,60 +183988,60 @@ static YYACTIONTYPE yy_reduce( + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); + } + if( pRhs ){ +- pRhs->op = (u8)yymsp[-1].minor.yy502; ++ pRhs->op = (u8)yymsp[-1].minor.yy144; + pRhs->pPrior = pLhs; + if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; + pRhs->selFlags &= ~(u32)SF_MultiValue; +- if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1; ++ if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1; + }else{ + sqlite3SelectDelete(pParse->db, pLhs); + } +- yymsp[-2].minor.yy637 = pRhs; ++ yymsp[-2].minor.yy555 = pRhs; + } + break; + case 89: /* multiselect_op ::= UNION */ + case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); +-{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-OP*/} ++{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/} + break; + case 90: /* multiselect_op ::= UNION ALL */ +-{yymsp[-1].minor.yy502 = TK_ALL;} ++{yymsp[-1].minor.yy144 = TK_ALL;} + break; + case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + { +- yymsp[-8].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy402,yymsp[-5].minor.yy563,yymsp[-4].minor.yy590,yymsp[-3].minor.yy402,yymsp[-2].minor.yy590,yymsp[-1].minor.yy402,yymsp[-7].minor.yy502,yymsp[0].minor.yy590); ++ yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454); + } + break; + case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + { +- yymsp[-9].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy402,yymsp[-6].minor.yy563,yymsp[-5].minor.yy590,yymsp[-4].minor.yy402,yymsp[-3].minor.yy590,yymsp[-1].minor.yy402,yymsp[-8].minor.yy502,yymsp[0].minor.yy590); +- if( yymsp[-9].minor.yy637 ){ +- yymsp[-9].minor.yy637->pWinDefn = yymsp[-2].minor.yy483; ++ yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454); ++ if( yymsp[-9].minor.yy555 ){ ++ yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211; + }else{ +- sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy483); ++ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211); + } + } + break; + case 94: /* values ::= VALUES LP nexprlist RP */ + { +- yymsp[-3].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy402,0,0,0,0,0,SF_Values,0); ++ yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0); + } + break; + case 95: /* oneselect ::= mvalues */ + { +- sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy637); ++ sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555); + } + break; + case 96: /* mvalues ::= values COMMA LP nexprlist RP */ + case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97); + { +- yymsp[-4].minor.yy637 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy637, yymsp[-1].minor.yy402); ++ yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14); + } + break; + case 98: /* distinct ::= DISTINCT */ +-{yymsp[0].minor.yy502 = SF_Distinct;} ++{yymsp[0].minor.yy144 = SF_Distinct;} + break; + case 99: /* distinct ::= ALL */ +-{yymsp[0].minor.yy502 = SF_All;} ++{yymsp[0].minor.yy144 = SF_All;} + break; + case 101: /* sclp ::= */ + case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134); +@@ -181621,20 +184049,20 @@ static YYACTIONTYPE yy_reduce( + case 234: /* exprlist ::= */ yytestcase(yyruleno==234); + case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237); + case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242); +-{yymsp[1].minor.yy402 = 0;} ++{yymsp[1].minor.yy14 = 0;} + break; + case 102: /* selcollist ::= sclp scanpt expr scanpt as */ + { +- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[-2].minor.yy590); +- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[0].minor.yy0, 1); +- sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy402,yymsp[-3].minor.yy342,yymsp[-1].minor.yy342); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); ++ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1); ++ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168); + } + break; + case 103: /* 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.yy402 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy402, p); ++ yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p); + } + break; + case 104: /* selcollist ::= sclp scanpt nm DOT STAR */ +@@ -181644,7 +184072,7 @@ static YYACTIONTYPE yy_reduce( + 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.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, pDot); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot); + } + break; + case 105: /* as ::= AS nm */ +@@ -181655,50 +184083,50 @@ static YYACTIONTYPE yy_reduce( + break; + case 107: /* from ::= */ + case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110); +-{yymsp[1].minor.yy563 = 0;} ++{yymsp[1].minor.yy203 = 0;} + break; + case 108: /* from ::= FROM seltablist */ + { +- yymsp[-1].minor.yy563 = yymsp[0].minor.yy563; +- sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy563); ++ yymsp[-1].minor.yy203 = yymsp[0].minor.yy203; ++ sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203); + } + break; + case 109: /* stl_prefix ::= seltablist joinop */ + { +- if( ALWAYS(yymsp[-1].minor.yy563 && yymsp[-1].minor.yy563->nSrc>0) ) yymsp[-1].minor.yy563->a[yymsp[-1].minor.yy563->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy502; ++ if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144; + } + break; + case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */ + { +- yymsp[-4].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy563,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421); ++ yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + } + break; + case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + { +- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy421); +- sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-1].minor.yy0); ++ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269); ++ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0); + } + break; + case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + { +- yymsp[-7].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy563,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421); +- sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy563, yymsp[-3].minor.yy402); ++ yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); ++ sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14); + } + break; + case 114: /* seltablist ::= stl_prefix LP select RP as on_using */ + { +- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy637,&yymsp[0].minor.yy421); ++ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269); + } + break; + case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ + { +- if( yymsp[-5].minor.yy563==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy421.pOn==0 && yymsp[0].minor.yy421.pUsing==0 ){ +- yymsp[-5].minor.yy563 = yymsp[-3].minor.yy563; +- }else if( ALWAYS(yymsp[-3].minor.yy563!=0) && yymsp[-3].minor.yy563->nSrc==1 ){ +- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421); +- if( yymsp[-5].minor.yy563 ){ +- SrcItem *pNew = &yymsp[-5].minor.yy563->a[yymsp[-5].minor.yy563->nSrc-1]; +- SrcItem *pOld = yymsp[-3].minor.yy563->a; ++ if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ ++ yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; ++ }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ ++ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); ++ if( yymsp[-5].minor.yy203 ){ ++ SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; ++ SrcItem *pOld = yymsp[-3].minor.yy203->a; + assert( pOld->fg.fixedSchema==0 ); + pNew->zName = pOld->zName; + assert( pOld->fg.fixedSchema==0 ); +@@ -181723,12 +184151,12 @@ static YYACTIONTYPE yy_reduce( + } + pOld->zName = 0; + } +- sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy563); ++ sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); + }else{ + Select *pSubquery; +- sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy563); +- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy563,0,0,0,0,SF_NestedFrom,0); +- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy421); ++ sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); ++ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0); ++ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269); + } + } + break; +@@ -181737,57 +184165,67 @@ static YYACTIONTYPE yy_reduce( + {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} + break; + case 118: /* fullname ::= nm */ ++ case 120: /* xfullname ::= nm */ yytestcase(yyruleno==120); + { +- yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); +- if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0); ++ yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); ++ if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); + } +- yymsp[0].minor.yy563 = yylhsminor.yy563; ++ yymsp[0].minor.yy203 = yylhsminor.yy203; + break; + case 119: /* fullname ::= nm DOT nm */ ++ case 121: /* xfullname ::= nm DOT nm */ yytestcase(yyruleno==121); + { +- yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); +- if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0); ++ yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); ++ if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); + } +- yymsp[-2].minor.yy563 = yylhsminor.yy563; +- break; +- case 120: /* xfullname ::= nm */ +-{yymsp[0].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +- break; +- case 121: /* xfullname ::= nm DOT nm */ +-{yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} ++ yymsp[-2].minor.yy203 = yylhsminor.yy203; + break; +- case 122: /* xfullname ::= nm DOT nm AS nm */ ++ case 122: /* xfullname ::= nm AS nm */ + { +- yymsp[-4].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ +- if( yymsp[-4].minor.yy563 ) yymsp[-4].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); ++ yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); ++ if( yylhsminor.yy203 ){ ++ if( IN_RENAME_OBJECT ){ ++ sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[-2].minor.yy0); ++ }else{ ++ yylhsminor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); ++ } ++ } + } ++ yymsp[-2].minor.yy203 = yylhsminor.yy203; + break; +- case 123: /* xfullname ::= nm AS nm */ ++ case 123: /* xfullname ::= nm DOT nm AS nm */ + { +- yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ +- if( yymsp[-2].minor.yy563 ) yymsp[-2].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); ++ yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); ++ if( yylhsminor.yy203 ){ ++ if( IN_RENAME_OBJECT ){ ++ sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[-2].minor.yy0); ++ }else{ ++ yylhsminor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); ++ } ++ } + } ++ yymsp[-4].minor.yy203 = yylhsminor.yy203; + break; + case 124: /* joinop ::= COMMA|JOIN */ +-{ yymsp[0].minor.yy502 = JT_INNER; } ++{ yymsp[0].minor.yy144 = JT_INNER; } + break; + case 125: /* joinop ::= JOIN_KW JOIN */ +-{yymsp[-1].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} ++{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + break; + case 126: /* joinop ::= JOIN_KW nm JOIN */ +-{yymsp[-2].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} ++{yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + break; + case 127: /* joinop ::= JOIN_KW nm nm JOIN */ +-{yymsp[-3].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} ++{yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + break; + case 128: /* on_using ::= ON expr */ +-{yymsp[-1].minor.yy421.pOn = yymsp[0].minor.yy590; yymsp[-1].minor.yy421.pUsing = 0;} ++{yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;} + break; + case 129: /* on_using ::= USING LP idlist RP */ +-{yymsp[-3].minor.yy421.pOn = 0; yymsp[-3].minor.yy421.pUsing = yymsp[-1].minor.yy204;} ++{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;} + break; + case 130: /* on_using ::= */ +-{yymsp[1].minor.yy421.pOn = 0; yymsp[1].minor.yy421.pUsing = 0;} ++{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;} + break; + case 132: /* indexed_by ::= INDEXED BY nm */ + {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} +@@ -181797,35 +184235,35 @@ static YYACTIONTYPE yy_reduce( + break; + case 135: /* orderby_opt ::= ORDER BY sortlist */ + case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145); +-{yymsp[-2].minor.yy402 = yymsp[0].minor.yy402;} ++{yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;} + break; + case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */ + { +- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402,yymsp[-2].minor.yy590); +- sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454); ++ sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); + } + break; + case 137: /* sortlist ::= expr sortorder nulls */ + { +- yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy590); /*A-overwrites-Y*/ +- sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502); ++ yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/ ++ sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); + } + break; + case 138: /* sortorder ::= ASC */ +-{yymsp[0].minor.yy502 = SQLITE_SO_ASC;} ++{yymsp[0].minor.yy144 = SQLITE_SO_ASC;} + break; + case 139: /* sortorder ::= DESC */ +-{yymsp[0].minor.yy502 = SQLITE_SO_DESC;} ++{yymsp[0].minor.yy144 = SQLITE_SO_DESC;} + break; + case 140: /* sortorder ::= */ + case 143: /* nulls ::= */ yytestcase(yyruleno==143); +-{yymsp[1].minor.yy502 = SQLITE_SO_UNDEFINED;} ++{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;} + break; + case 141: /* nulls ::= NULLS FIRST */ +-{yymsp[-1].minor.yy502 = SQLITE_SO_ASC;} ++{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;} + break; + case 142: /* nulls ::= NULLS LAST */ +-{yymsp[-1].minor.yy502 = SQLITE_SO_DESC;} ++{yymsp[-1].minor.yy144 = SQLITE_SO_DESC;} + break; + case 146: /* having_opt ::= */ + case 148: /* limit_opt ::= */ yytestcase(yyruleno==148); +@@ -181834,42 +184272,42 @@ static YYACTIONTYPE yy_reduce( + case 232: /* case_else ::= */ yytestcase(yyruleno==232); + case 233: /* case_operand ::= */ yytestcase(yyruleno==233); + case 252: /* vinto ::= */ yytestcase(yyruleno==252); +-{yymsp[1].minor.yy590 = 0;} ++{yymsp[1].minor.yy454 = 0;} + break; + case 147: /* having_opt ::= HAVING expr */ + case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154); + case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156); + case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); + case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251); +-{yymsp[-1].minor.yy590 = yymsp[0].minor.yy590;} ++{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;} + break; + case 149: /* limit_opt ::= LIMIT expr */ +-{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,0);} ++{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);} + break; + case 150: /* limit_opt ::= LIMIT expr OFFSET expr */ +-{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);} ++{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} + break; + case 151: /* limit_opt ::= LIMIT expr COMMA expr */ +-{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,yymsp[-2].minor.yy590);} ++{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);} + break; + case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + { +- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy563, &yymsp[-1].minor.yy0); +- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy563,yymsp[0].minor.yy590,0,0); ++ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0); ++ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0); + } + break; + case 157: /* where_opt_ret ::= RETURNING selcollist */ +-{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-1].minor.yy590 = 0;} ++{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;} + break; + case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +-{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-3].minor.yy590 = yymsp[-2].minor.yy590;} ++{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;} + break; + case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + { +- sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-4].minor.yy0); +- sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy402,"set list"); +- if( yymsp[-1].minor.yy563 ){ +- SrcList *pFromClause = yymsp[-1].minor.yy563; ++ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0); ++ sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list"); ++ if( yymsp[-1].minor.yy203 ){ ++ SrcList *pFromClause = yymsp[-1].minor.yy203; + if( pFromClause->nSrc>1 ){ + Select *pSubquery; + Token as; +@@ -181878,90 +184316,90 @@ static YYACTIONTYPE yy_reduce( + as.z = 0; + pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); + } +- yymsp[-5].minor.yy563 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy563, pFromClause); ++ yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause); + } +- sqlite3Update(pParse,yymsp[-5].minor.yy563,yymsp[-2].minor.yy402,yymsp[0].minor.yy590,yymsp[-6].minor.yy502,0,0,0); ++ sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0); + } + break; + case 160: /* setlist ::= setlist COMMA nm EQ expr */ + { +- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[0].minor.yy590); +- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, 1); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454); ++ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1); + } + break; + case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + { +- yymsp[-6].minor.yy402 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy402, yymsp[-3].minor.yy204, yymsp[0].minor.yy590); ++ yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); + } + break; + case 162: /* setlist ::= nm EQ expr */ + { +- yylhsminor.yy402 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy590); +- sqlite3ExprListSetName(pParse, yylhsminor.yy402, &yymsp[-2].minor.yy0, 1); ++ yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454); ++ sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1); + } +- yymsp[-2].minor.yy402 = yylhsminor.yy402; ++ yymsp[-2].minor.yy14 = yylhsminor.yy14; + break; + case 163: /* setlist ::= LP idlist RP EQ expr */ + { +- yymsp[-4].minor.yy402 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy204, yymsp[0].minor.yy590); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); + } + break; + case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + { +- sqlite3Insert(pParse, yymsp[-3].minor.yy563, yymsp[-1].minor.yy637, yymsp[-2].minor.yy204, yymsp[-5].minor.yy502, yymsp[0].minor.yy403); ++ sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122); + } + break; + case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + { +- sqlite3Insert(pParse, yymsp[-4].minor.yy563, 0, yymsp[-3].minor.yy204, yymsp[-6].minor.yy502, 0); ++ sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0); + } + break; + case 166: /* upsert ::= */ +-{ yymsp[1].minor.yy403 = 0; } ++{ yymsp[1].minor.yy122 = 0; } + break; + case 167: /* upsert ::= RETURNING selcollist */ +-{ yymsp[-1].minor.yy403 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy402); } ++{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); } + break; + case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +-{ yymsp[-11].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy402,yymsp[-6].minor.yy590,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,yymsp[0].minor.yy403);} ++{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);} + break; + case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +-{ yymsp[-8].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy402,yymsp[-3].minor.yy590,0,0,yymsp[0].minor.yy403); } ++{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); } + break; + case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */ +-{ yymsp[-4].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } ++{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } + break; + case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +-{ yymsp[-7].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,0);} ++{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);} + break; + case 172: /* returning ::= RETURNING selcollist */ +-{sqlite3AddReturning(pParse,yymsp[0].minor.yy402);} ++{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);} + break; + case 175: /* idlist_opt ::= */ +-{yymsp[1].minor.yy204 = 0;} ++{yymsp[1].minor.yy132 = 0;} + break; + case 176: /* idlist_opt ::= LP idlist RP */ +-{yymsp[-2].minor.yy204 = yymsp[-1].minor.yy204;} ++{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;} + break; + case 177: /* idlist ::= idlist COMMA nm */ +-{yymsp[-2].minor.yy204 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy204,&yymsp[0].minor.yy0);} ++{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);} + break; + case 178: /* idlist ::= nm */ +-{yymsp[0].minor.yy204 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} ++{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + break; + case 179: /* expr ::= LP expr RP */ +-{yymsp[-2].minor.yy590 = yymsp[-1].minor.yy590;} ++{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;} + break; + case 180: /* expr ::= ID|INDEXED|JOIN_KW */ +-{yymsp[0].minor.yy590=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} ++{yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 181: /* 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.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); ++ yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + } +- yymsp[-2].minor.yy590 = yylhsminor.yy590; ++ yymsp[-2].minor.yy454 = yylhsminor.yy454; + break; + case 182: /* expr ::= nm DOT nm DOT nm */ + { +@@ -181972,27 +184410,32 @@ static YYACTIONTYPE yy_reduce( + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, temp1); + } +- yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); ++ yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + } +- yymsp[-4].minor.yy590 = yylhsminor.yy590; ++ yymsp[-4].minor.yy454 = yylhsminor.yy454; + break; + case 183: /* term ::= NULL|FLOAT|BLOB */ + case 184: /* term ::= STRING */ yytestcase(yyruleno==184); +-{yymsp[0].minor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} ++{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 185: /* term ::= INTEGER */ + { +- yylhsminor.yy590 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); +- if( yylhsminor.yy590 ) yylhsminor.yy590->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); ++ int iValue; ++ if( sqlite3GetInt32(yymsp[0].minor.yy0.z, &iValue)==0 ){ ++ yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 0); ++ }else{ ++ yylhsminor.yy454 = sqlite3ExprInt32(pParse->db, iValue); ++ } ++ if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); + } +- yymsp[0].minor.yy590 = yylhsminor.yy590; ++ yymsp[0].minor.yy454 = yylhsminor.yy454; + break; + case 186: /* 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.yy590 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); +- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy590, n); ++ yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); ++ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, 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 +@@ -182001,80 +184444,82 @@ static YYACTIONTYPE yy_reduce( + assert( t.n>=2 ); + if( pParse->nested==0 ){ + parserSyntaxError(pParse, &t); +- yymsp[0].minor.yy590 = 0; ++ yymsp[0].minor.yy454 = 0; + }else{ +- yymsp[0].minor.yy590 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); +- if( yymsp[0].minor.yy590 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy590->iTable); ++ yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); ++ if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable); + } + } + } + break; + case 187: /* expr ::= expr COLLATE ID|STRING */ + { +- yymsp[-2].minor.yy590 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy590, &yymsp[0].minor.yy0, 1); ++ yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1); + } + break; + case 188: /* expr ::= CAST LP expr AS typetoken RP */ + { +- yymsp[-5].minor.yy590 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); +- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy590, yymsp[-3].minor.yy590, 0); ++ yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); ++ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0); + } + break; + case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy502); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144); + } +- yymsp[-4].minor.yy590 = yylhsminor.yy590; ++ yymsp[-4].minor.yy454 = yylhsminor.yy454; + break; + case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy402, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy502); +- sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-1].minor.yy402); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144); ++ sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14); + } +- yymsp[-7].minor.yy590 = yylhsminor.yy590; ++ yymsp[-7].minor.yy454 = yylhsminor.yy454; + break; + case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + } +- yymsp[-3].minor.yy590 = yylhsminor.yy590; ++ yymsp[-3].minor.yy454 = yylhsminor.yy454; + break; + case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy402, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy502); +- sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144); ++ sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); + } +- yymsp[-5].minor.yy590 = yylhsminor.yy590; ++ yymsp[-5].minor.yy454 = yylhsminor.yy454; + break; + case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy402, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy502); +- sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483); +- sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-2].minor.yy402); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144); ++ sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); ++ sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14); + } +- yymsp[-8].minor.yy590 = yylhsminor.yy590; ++ yymsp[-8].minor.yy454 = yylhsminor.yy454; + break; + case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); +- sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); ++ sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); + } +- yymsp[-4].minor.yy590 = yylhsminor.yy590; ++ yymsp[-4].minor.yy454 = yylhsminor.yy454; + break; + case 195: /* term ::= CTIME_KW */ + { +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + } +- yymsp[0].minor.yy590 = yylhsminor.yy590; ++ yymsp[0].minor.yy454 = yylhsminor.yy454; + break; + case 196: /* expr ::= LP nexprlist COMMA expr RP */ + { +- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590); +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); +- if( yymsp[-4].minor.yy590 ){ +- yymsp[-4].minor.yy590->x.pList = pList; +- if( ALWAYS(pList->nExpr) ){ +- yymsp[-4].minor.yy590->flags |= pList->a[0].pExpr->flags & EP_Propagate; ++ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); ++ if( yymsp[-4].minor.yy454 ){ ++ int i; ++ yymsp[-4].minor.yy454->x.pList = pList; ++ for(i=0; inExpr; i++){ ++ assert( pList->a[i].pExpr!=0 ); ++ yymsp[-4].minor.yy454->flags |= pList->a[i].pExpr->flags & EP_Propagate; + } + }else{ + sqlite3ExprListDelete(pParse->db, pList); +@@ -182082,7 +184527,7 @@ static YYACTIONTYPE yy_reduce( + } + break; + case 197: /* expr ::= expr AND expr */ +-{yymsp[-2].minor.yy590=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);} ++{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} + break; + case 198: /* expr ::= expr OR expr */ + case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); +@@ -182091,7 +184536,7 @@ static YYACTIONTYPE yy_reduce( + case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); +-{yymsp[-2].minor.yy590=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);} ++{yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} + break; + case 205: /* 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*/} +@@ -182101,11 +184546,11 @@ static YYACTIONTYPE yy_reduce( + ExprList *pList; + int bNot = yymsp[-1].minor.yy0.n & 0x80000000; + yymsp[-1].minor.yy0.n &= 0x7fffffff; +- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy590); +- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy590); +- yymsp[-2].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); +- if( bNot ) yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy590, 0); +- if( yymsp[-2].minor.yy590 ) yymsp[-2].minor.yy590->flags |= EP_InfixFunc; ++ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454); ++ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454); ++ yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); ++ if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0); ++ if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc; + } + break; + case 207: /* expr ::= expr likeop expr ESCAPE expr */ +@@ -182113,91 +184558,88 @@ static YYACTIONTYPE yy_reduce( + ExprList *pList; + int bNot = yymsp[-3].minor.yy0.n & 0x80000000; + yymsp[-3].minor.yy0.n &= 0x7fffffff; +- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590); +- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy590); +- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590); +- yymsp[-4].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); +- if( bNot ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); +- if( yymsp[-4].minor.yy590 ) yymsp[-4].minor.yy590->flags |= EP_InfixFunc; ++ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); ++ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454); ++ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); ++ yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); ++ if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); ++ if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc; + } + break; + case 208: /* expr ::= expr ISNULL|NOTNULL */ +-{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy590,0);} ++{yymsp[-1].minor.yy454 = sqlite3PExprIsNull(pParse,yymsp[0].major,yymsp[-1].minor.yy454);} + break; + case 209: /* expr ::= expr NOT NULL */ +-{yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy590,0);} ++{yymsp[-2].minor.yy454 = sqlite3PExprIsNull(pParse,TK_NOTNULL,yymsp[-2].minor.yy454);} + break; + case 210: /* expr ::= expr IS expr */ + { +- yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy590,yymsp[0].minor.yy590); +- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-2].minor.yy590, TK_ISNULL); ++ yymsp[-2].minor.yy454 = sqlite3PExprIs(pParse, TK_IS, yymsp[-2].minor.yy454, yymsp[0].minor.yy454); + } + break; + case 211: /* expr ::= expr IS NOT expr */ + { +- yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy590,yymsp[0].minor.yy590); +- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-3].minor.yy590, TK_NOTNULL); ++ yymsp[-3].minor.yy454 = sqlite3PExprIs(pParse, TK_ISNOT, yymsp[-3].minor.yy454, yymsp[0].minor.yy454); + } + break; + case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */ + { +- yymsp[-5].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy590,yymsp[0].minor.yy590); +- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-5].minor.yy590, TK_ISNULL); ++ yymsp[-5].minor.yy454 = sqlite3PExprIs(pParse, TK_IS, yymsp[-5].minor.yy454, yymsp[0].minor.yy454); + } + break; + case 213: /* expr ::= expr IS DISTINCT FROM expr */ + { +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy590,yymsp[0].minor.yy590); +- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-4].minor.yy590, TK_NOTNULL); ++ yymsp[-4].minor.yy454 = sqlite3PExprIs(pParse, TK_ISNOT, yymsp[-4].minor.yy454, yymsp[0].minor.yy454); + } + break; + case 214: /* expr ::= NOT expr */ + case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); +-{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy590, 0);/*A-overwrites-B*/} ++{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/} + break; + case 216: /* expr ::= PLUS|MINUS expr */ + { +- Expr *p = yymsp[0].minor.yy590; ++ Expr *p = yymsp[0].minor.yy454; + u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS); + assert( TK_UPLUS>TK_PLUS ); + assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) ); + if( p && p->op==TK_UPLUS ){ + p->op = op; +- yymsp[-1].minor.yy590 = p; ++ yymsp[-1].minor.yy454 = p; + }else{ +- yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, op, p, 0); ++ yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0); + /*A-overwrites-B*/ + } + } + break; + case 217: /* expr ::= expr PTR expr */ + { +- ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy590); +- pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy590); +- yylhsminor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); ++ ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454); ++ pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454); ++ yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + } +- yymsp[-2].minor.yy590 = yylhsminor.yy590; ++ yymsp[-2].minor.yy454 = yylhsminor.yy454; + break; + case 218: /* between_op ::= BETWEEN */ + case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); +-{yymsp[0].minor.yy502 = 0;} ++{yymsp[0].minor.yy144 = 0;} + break; + case 220: /* expr ::= expr between_op expr AND expr */ + { +- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590); +- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590); +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy590, 0); +- if( yymsp[-4].minor.yy590 ){ +- yymsp[-4].minor.yy590->x.pList = pList; ++ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); ++ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0); ++ if( yymsp[-4].minor.yy454 ){ ++ yymsp[-4].minor.yy454->x.pList = pList; ++ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } +- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); ++ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + break; + case 223: /* expr ::= expr in_op LP exprlist RP */ + { +- if( yymsp[-1].minor.yy402==0 ){ ++ if( yymsp[-1].minor.yy14==0 ){ + /* Expressions of the form + ** + ** expr1 IN () +@@ -182210,145 +184652,145 @@ static YYACTIONTYPE yy_reduce( + ** it is or not) and if it is an aggregate, that could change the meaning + ** of the whole query. + */ +- Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); ++ Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "true" : "false"); + if( pB ) sqlite3ExprIdToTrueFalse(pB); +- if( !ExprHasProperty(yymsp[-4].minor.yy590, EP_HasFunc) ){ +- sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); +- yymsp[-4].minor.yy590 = pB; ++ if( !ExprHasProperty(yymsp[-4].minor.yy454, EP_HasFunc) ){ ++ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy454); ++ yymsp[-4].minor.yy454 = pB; + }else{ +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy590); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, yymsp[-3].minor.yy144 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy454); + } + }else{ +- Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr; +- if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){ +- yymsp[-1].minor.yy402->a[0].pExpr = 0; +- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); ++ Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; ++ if( yymsp[-1].minor.yy14->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy454->op!=TK_VECTOR ){ ++ yymsp[-1].minor.yy14->a[0].pExpr = 0; ++ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy590, pRHS); +- }else if( yymsp[-1].minor.yy402->nExpr==1 && pRHS->op==TK_SELECT ){ +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); +- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pRHS->x.pSelect); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS); ++ }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){ ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); ++ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect); + pRHS->x.pSelect = 0; +- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); ++ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + }else{ +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); +- if( yymsp[-4].minor.yy590==0 ){ +- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); +- }else if( yymsp[-4].minor.yy590->pLeft->op==TK_VECTOR ){ +- int nExpr = yymsp[-4].minor.yy590->pLeft->x.pList->nExpr; +- Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy402); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); ++ if( yymsp[-4].minor.yy454==0 ){ ++ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); ++ }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){ ++ int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr; ++ Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14); + if( pSelectRHS ){ + parserDoubleLinkSelect(pParse, pSelectRHS); +- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelectRHS); ++ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS); + } + }else{ +- yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy402; +- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590); ++ yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14; ++ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); + } + } +- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); ++ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + } + break; + case 224: /* expr ::= LP select RP */ + { +- yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); +- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy590, yymsp[-1].minor.yy637); ++ yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); ++ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555); + } + break; + case 225: /* expr ::= expr in_op LP select RP */ + { +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); +- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, yymsp[-1].minor.yy637); +- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); ++ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555); ++ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + break; + case 226: /* 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.yy402 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy402); +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); +- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelect); +- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); ++ if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); ++ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect); ++ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + break; + case 227: /* expr ::= EXISTS LP select RP */ + { + Expr *p; +- p = yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); +- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy637); ++ p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); ++ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555); + } + break; + case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ + { +- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy590, 0); +- if( yymsp[-4].minor.yy590 ){ +- yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy590 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590) : yymsp[-2].minor.yy402; +- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590); ++ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0); ++ if( yymsp[-4].minor.yy454 ){ ++ yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14; ++ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); + }else{ +- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy402); +- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590); ++ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); ++ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); + } + } + break; + case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + { +- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[-2].minor.yy590); +- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[0].minor.yy590); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); ++ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454); + } + break; + case 230: /* case_exprlist ::= WHEN expr THEN expr */ + { +- yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590); +- yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy402, yymsp[0].minor.yy590); ++ yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); ++ yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454); + } + break; + case 235: /* nexprlist ::= nexprlist COMMA expr */ +-{yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[0].minor.yy590);} ++{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);} + break; + case 236: /* nexprlist ::= expr */ +-{yymsp[0].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy590); /*A-overwrites-Y*/} ++{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/} + break; + case 238: /* paren_exprlist ::= LP exprlist RP */ + case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243); +-{yymsp[-2].minor.yy402 = yymsp[-1].minor.yy402;} ++{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;} + break; + case 239: /* 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.yy402, yymsp[-10].minor.yy502, +- &yymsp[-11].minor.yy0, yymsp[0].minor.yy590, SQLITE_SO_ASC, yymsp[-8].minor.yy502, SQLITE_IDXTYPE_APPDEF); ++ sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144, ++ &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF); + if( IN_RENAME_OBJECT && pParse->pNewIndex ){ + sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); + } + } + break; + case 240: /* uniqueflag ::= UNIQUE */ +- case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282); +-{yymsp[0].minor.yy502 = OE_Abort;} ++ case 281: /* raisetype ::= ABORT */ yytestcase(yyruleno==281); ++{yymsp[0].minor.yy144 = OE_Abort;} + break; + case 241: /* uniqueflag ::= */ +-{yymsp[1].minor.yy502 = OE_None;} ++{yymsp[1].minor.yy144 = OE_None;} + break; + case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */ + { +- yymsp[-4].minor.yy402 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); ++ yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); + } + break; + case 245: /* eidlist ::= nm collate sortorder */ + { +- yymsp[-2].minor.yy402 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); /*A-overwrites-Y*/ ++ yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/ + } + break; + case 248: /* cmd ::= DROP INDEX ifexists fullname */ +-{sqlite3DropIndex(pParse, yymsp[0].minor.yy563, yymsp[-1].minor.yy502);} ++{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);} + break; + case 249: /* cmd ::= VACUUM vinto */ +-{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy590);} ++{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);} + break; + case 250: /* cmd ::= VACUUM nm vinto */ +-{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy590);} ++{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);} + break; + case 253: /* cmd ::= PRAGMA nm dbnm */ + {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} +@@ -182370,12 +184812,12 @@ static YYACTIONTYPE yy_reduce( + 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.yy319, &all); ++ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all); + } + break; + case 261: /* 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.yy502, yymsp[-4].minor.yy28.a, yymsp[-4].minor.yy28.b, yymsp[-2].minor.yy563, yymsp[0].minor.yy590, yymsp[-10].minor.yy502, yymsp[-8].minor.yy502); ++ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144); + yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ + #ifdef SQLITE_DEBUG + assert( pParse->isCreate ); /* Set by createkw reduce action */ +@@ -182384,421 +184826,437 @@ static YYACTIONTYPE yy_reduce( + } + break; + case 262: /* trigger_time ::= BEFORE|AFTER */ +-{ yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/ } ++{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ } + break; + case 263: /* trigger_time ::= INSTEAD OF */ +-{ yymsp[-1].minor.yy502 = TK_INSTEAD;} ++{ yymsp[-1].minor.yy144 = TK_INSTEAD;} + break; + case 264: /* trigger_time ::= */ +-{ yymsp[1].minor.yy502 = TK_BEFORE; } ++{ yymsp[1].minor.yy144 = TK_BEFORE; } + break; + case 265: /* trigger_event ::= DELETE|INSERT */ + case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266); +-{yymsp[0].minor.yy28.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy28.b = 0;} ++{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;} + break; + case 267: /* trigger_event ::= UPDATE OF idlist */ +-{yymsp[-2].minor.yy28.a = TK_UPDATE; yymsp[-2].minor.yy28.b = yymsp[0].minor.yy204;} ++{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;} + break; + case 268: /* when_clause ::= */ +- case 287: /* key_opt ::= */ yytestcase(yyruleno==287); +-{ yymsp[1].minor.yy590 = 0; } ++ case 286: /* key_opt ::= */ yytestcase(yyruleno==286); ++{ yymsp[1].minor.yy454 = 0; } + break; + case 269: /* when_clause ::= WHEN expr */ +- case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288); +-{ yymsp[-1].minor.yy590 = yymsp[0].minor.yy590; } ++ case 287: /* key_opt ::= KEY expr */ yytestcase(yyruleno==287); ++{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; } + break; + case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + { +- assert( yymsp[-2].minor.yy319!=0 ); +- yymsp[-2].minor.yy319->pLast->pNext = yymsp[-1].minor.yy319; +- yymsp[-2].minor.yy319->pLast = yymsp[-1].minor.yy319; ++ yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427; ++ yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427; + } + break; + case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */ + { +- assert( yymsp[-1].minor.yy319!=0 ); +- yymsp[-1].minor.yy319->pLast = yymsp[-1].minor.yy319; +-} +- break; +- case 272: /* 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"); ++ yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427; + } + break; +- case 273: /* tridxby ::= INDEXED BY nm */ ++ case 272: /* tridxby ::= INDEXED BY nm */ + { + sqlite3ErrorMsg(pParse, + "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " + "within triggers"); + } + break; +- case 274: /* tridxby ::= NOT INDEXED */ ++ case 273: /* tridxby ::= NOT INDEXED */ + { + sqlite3ErrorMsg(pParse, + "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " + "within triggers"); + } + break; +- case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +-{yylhsminor.yy319 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy563, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590, yymsp[-7].minor.yy502, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy342);} +- yymsp[-8].minor.yy319 = yylhsminor.yy319; ++ case 274: /* trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ ++{yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, yymsp[-6].minor.yy203, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);} ++ yymsp[-8].minor.yy427 = yylhsminor.yy427; + break; +- case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ ++ case 275: /* trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ + { +- yylhsminor.yy319 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy204,yymsp[-2].minor.yy637,yymsp[-6].minor.yy502,yymsp[-1].minor.yy403,yymsp[-7].minor.yy342,yymsp[0].minor.yy342);/*yylhsminor.yy319-overwrites-yymsp[-6].minor.yy502*/ ++ yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,yymsp[-4].minor.yy203,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/ + } +- yymsp[-7].minor.yy319 = yylhsminor.yy319; ++ yymsp[-7].minor.yy427 = yylhsminor.yy427; + break; +- case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +-{yylhsminor.yy319 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy590, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy342);} +- yymsp[-5].minor.yy319 = yylhsminor.yy319; ++ case 276: /* trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ ++{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);} ++ yymsp[-5].minor.yy427 = yylhsminor.yy427; + break; +- case 278: /* trigger_cmd ::= scanpt select scanpt */ +-{yylhsminor.yy319 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy637, yymsp[-2].minor.yy342, yymsp[0].minor.yy342); /*yylhsminor.yy319-overwrites-yymsp[-1].minor.yy637*/} +- yymsp[-2].minor.yy319 = yylhsminor.yy319; ++ case 277: /* trigger_cmd ::= scanpt select scanpt */ ++{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/} ++ yymsp[-2].minor.yy427 = yylhsminor.yy427; + break; +- case 279: /* expr ::= RAISE LP IGNORE RP */ ++ case 278: /* expr ::= RAISE LP IGNORE RP */ + { +- yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); +- if( yymsp[-3].minor.yy590 ){ +- yymsp[-3].minor.yy590->affExpr = OE_Ignore; ++ yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); ++ if( yymsp[-3].minor.yy454 ){ ++ yymsp[-3].minor.yy454->affExpr = OE_Ignore; + } + } + break; +- case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ ++ case 279: /* expr ::= RAISE LP raisetype COMMA expr RP */ + { +- yymsp[-5].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy590, 0); +- if( yymsp[-5].minor.yy590 ) { +- yymsp[-5].minor.yy590->affExpr = (char)yymsp[-3].minor.yy502; ++ yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); ++ if( yymsp[-5].minor.yy454 ) { ++ yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; + } + } + break; +- case 281: /* raisetype ::= ROLLBACK */ +-{yymsp[0].minor.yy502 = OE_Rollback;} ++ case 280: /* raisetype ::= ROLLBACK */ ++{yymsp[0].minor.yy144 = OE_Rollback;} + break; +- case 283: /* raisetype ::= FAIL */ +-{yymsp[0].minor.yy502 = OE_Fail;} ++ case 282: /* raisetype ::= FAIL */ ++{yymsp[0].minor.yy144 = OE_Fail;} + break; +- case 284: /* cmd ::= DROP TRIGGER ifexists fullname */ ++ case 283: /* cmd ::= DROP TRIGGER ifexists fullname */ + { +- sqlite3DropTrigger(pParse,yymsp[0].minor.yy563,yymsp[-1].minor.yy502); ++ sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144); + } + break; +- case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ ++ case 284: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + { +- sqlite3Attach(pParse, yymsp[-3].minor.yy590, yymsp[-1].minor.yy590, yymsp[0].minor.yy590); ++ sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454); + } + break; +- case 286: /* cmd ::= DETACH database_kw_opt expr */ ++ case 285: /* cmd ::= DETACH database_kw_opt expr */ + { +- sqlite3Detach(pParse, yymsp[0].minor.yy590); ++ sqlite3Detach(pParse, yymsp[0].minor.yy454); + } + break; +- case 289: /* cmd ::= REINDEX */ ++ case 288: /* cmd ::= REINDEX */ + {sqlite3Reindex(pParse, 0, 0);} + break; +- case 290: /* cmd ::= REINDEX nm dbnm */ ++ case 289: /* cmd ::= REINDEX nm dbnm */ + {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; +- case 291: /* cmd ::= ANALYZE */ ++ case 290: /* cmd ::= ANALYZE */ + {sqlite3Analyze(pParse, 0, 0);} + break; +- case 292: /* cmd ::= ANALYZE nm dbnm */ ++ case 291: /* cmd ::= ANALYZE nm dbnm */ + {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; +- case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ ++ case 292: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + { +- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy563,&yymsp[0].minor.yy0); ++ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0); + } + break; +- case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ ++ case 293: /* cmd ::= alter_add 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 294: /* alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ ++{ ++ disableLookaside(pParse); ++ sqlite3AlterBeginAddColumn(pParse, yymsp[-4].minor.yy203); ++ sqlite3AddColumn(pParse, yymsp[-1].minor.yy0, yymsp[0].minor.yy0); ++ yymsp[-6].minor.yy0 = yymsp[-1].minor.yy0; + } + break; + case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + { +- sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy563, &yymsp[0].minor.yy0); ++ sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0); + } + break; +- case 296: /* add_column_fullname ::= fullname */ ++ case 296: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + { +- disableLookaside(pParse); +- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy563); ++ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); ++} ++ break; ++ case 297: /* cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ ++{ ++ sqlite3AlterDropConstraint(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0, 0); ++} ++ break; ++ case 298: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ ++{ ++ sqlite3AlterDropConstraint(pParse, yymsp[-6].minor.yy203, 0, &yymsp[-3].minor.yy0); ++} ++ break; ++ case 299: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ ++{ ++ sqlite3AlterSetNotNull(pParse, yymsp[-7].minor.yy203, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0); ++} ++ break; ++ case 300: /* cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ ++{ ++ sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); + } + break; +- case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ ++ case 301: /* cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ + { +- sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy563, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); ++ sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); + } + break; +- case 298: /* cmd ::= create_vtab */ ++ case 302: /* cmd ::= create_vtab */ + {sqlite3VtabFinishParse(pParse,0);} + break; +- case 299: /* cmd ::= create_vtab LP vtabarglist RP */ ++ case 303: /* cmd ::= create_vtab LP vtabarglist RP */ + {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} + break; +- case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ ++ case 304: /* 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.yy502); ++ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144); + } + break; +- case 301: /* vtabarg ::= */ ++ case 305: /* vtabarg ::= */ + {sqlite3VtabArgInit(pParse);} + break; +- case 302: /* vtabargtoken ::= ANY */ +- case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303); +- case 304: /* lp ::= LP */ yytestcase(yyruleno==304); ++ case 306: /* vtabargtoken ::= ANY */ ++ case 307: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==307); ++ case 308: /* lp ::= LP */ yytestcase(yyruleno==308); + {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} + break; +- case 305: /* with ::= WITH wqlist */ +- case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306); +-{ sqlite3WithPush(pParse, yymsp[0].minor.yy125, 1); } ++ case 309: /* with ::= WITH wqlist */ ++ case 310: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==310); ++{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); } + break; +- case 307: /* wqas ::= AS */ +-{yymsp[0].minor.yy444 = M10d_Any;} ++ case 311: /* wqas ::= AS */ ++{yymsp[0].minor.yy462 = M10d_Any;} + break; +- case 308: /* wqas ::= AS MATERIALIZED */ +-{yymsp[-1].minor.yy444 = M10d_Yes;} ++ case 312: /* wqas ::= AS MATERIALIZED */ ++{yymsp[-1].minor.yy462 = M10d_Yes;} + break; +- case 309: /* wqas ::= AS NOT MATERIALIZED */ +-{yymsp[-2].minor.yy444 = M10d_No;} ++ case 313: /* wqas ::= AS NOT MATERIALIZED */ ++{yymsp[-2].minor.yy462 = M10d_No;} + break; +- case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ ++ case 314: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ + { +- yymsp[-5].minor.yy361 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy402, yymsp[-1].minor.yy637, yymsp[-3].minor.yy444); /*A-overwrites-X*/ ++ yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/ + } + break; +- case 311: /* withnm ::= nm */ ++ case 315: /* withnm ::= nm */ + {pParse->bHasWith = 1;} + break; +- case 312: /* wqlist ::= wqitem */ ++ case 316: /* wqlist ::= wqitem */ + { +- yymsp[0].minor.yy125 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy361); /*A-overwrites-X*/ ++ yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/ + } + break; +- case 313: /* wqlist ::= wqlist COMMA wqitem */ ++ case 317: /* wqlist ::= wqlist COMMA wqitem */ + { +- yymsp[-2].minor.yy125 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy125, yymsp[0].minor.yy361); ++ yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67); + } + break; +- case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ ++ case 318: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + { +- assert( yymsp[0].minor.yy483!=0 ); +- sqlite3WindowChain(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy483); +- yymsp[0].minor.yy483->pNextWin = yymsp[-2].minor.yy483; +- yylhsminor.yy483 = yymsp[0].minor.yy483; ++ assert( yymsp[0].minor.yy211!=0 ); ++ sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211); ++ yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211; ++ yylhsminor.yy211 = yymsp[0].minor.yy211; + } +- yymsp[-2].minor.yy483 = yylhsminor.yy483; ++ yymsp[-2].minor.yy211 = yylhsminor.yy211; + break; +- case 315: /* windowdefn ::= nm AS LP window RP */ ++ case 319: /* windowdefn ::= nm AS LP window RP */ + { +- if( ALWAYS(yymsp[-1].minor.yy483) ){ +- yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); ++ if( ALWAYS(yymsp[-1].minor.yy211) ){ ++ yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + } +- yylhsminor.yy483 = yymsp[-1].minor.yy483; ++ yylhsminor.yy211 = yymsp[-1].minor.yy211; + } +- yymsp[-4].minor.yy483 = yylhsminor.yy483; ++ yymsp[-4].minor.yy211 = yylhsminor.yy211; + break; +- case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ ++ case 320: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + { +- yymsp[-4].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, 0); ++ yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0); + } + break; +- case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ ++ case 321: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + { +- yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, &yymsp[-5].minor.yy0); ++ yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0); + } +- yymsp[-5].minor.yy483 = yylhsminor.yy483; ++ yymsp[-5].minor.yy211 = yylhsminor.yy211; + break; +- case 318: /* window ::= ORDER BY sortlist frame_opt */ ++ case 322: /* window ::= ORDER BY sortlist frame_opt */ + { +- yymsp[-3].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, 0); ++ yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0); + } + break; +- case 319: /* window ::= nm ORDER BY sortlist frame_opt */ ++ case 323: /* window ::= nm ORDER BY sortlist frame_opt */ + { +- yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0); ++ yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); + } +- yymsp[-4].minor.yy483 = yylhsminor.yy483; ++ yymsp[-4].minor.yy211 = yylhsminor.yy211; + break; +- case 320: /* window ::= nm frame_opt */ ++ case 324: /* window ::= nm frame_opt */ + { +- yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, 0, &yymsp[-1].minor.yy0); ++ yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0); + } +- yymsp[-1].minor.yy483 = yylhsminor.yy483; ++ yymsp[-1].minor.yy211 = yylhsminor.yy211; + break; +- case 321: /* frame_opt ::= */ ++ case 325: /* frame_opt ::= */ + { +- yymsp[1].minor.yy483 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); ++ yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + } + break; +- case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ ++ case 326: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + { +- yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy502, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy444); ++ yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462); + } +- yymsp[-2].minor.yy483 = yylhsminor.yy483; ++ yymsp[-2].minor.yy211 = yylhsminor.yy211; + break; +- case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ ++ case 327: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + { +- yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy502, yymsp[-3].minor.yy205.eType, yymsp[-3].minor.yy205.pExpr, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, yymsp[0].minor.yy444); ++ yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462); + } +- yymsp[-5].minor.yy483 = yylhsminor.yy483; ++ yymsp[-5].minor.yy211 = yylhsminor.yy211; + break; +- case 325: /* frame_bound_s ::= frame_bound */ +- case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327); +-{yylhsminor.yy205 = yymsp[0].minor.yy205;} +- yymsp[0].minor.yy205 = yylhsminor.yy205; ++ case 329: /* frame_bound_s ::= frame_bound */ ++ case 331: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==331); ++{yylhsminor.yy509 = yymsp[0].minor.yy509;} ++ yymsp[0].minor.yy509 = yylhsminor.yy509; + break; +- case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */ +- case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328); +- case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330); +-{yylhsminor.yy205.eType = yymsp[-1].major; yylhsminor.yy205.pExpr = 0;} +- yymsp[-1].minor.yy205 = yylhsminor.yy205; ++ case 330: /* frame_bound_s ::= UNBOUNDED PRECEDING */ ++ case 332: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==332); ++ case 334: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==334); ++{yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;} ++ yymsp[-1].minor.yy509 = yylhsminor.yy509; + break; +- case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +-{yylhsminor.yy205.eType = yymsp[0].major; yylhsminor.yy205.pExpr = yymsp[-1].minor.yy590;} +- yymsp[-1].minor.yy205 = yylhsminor.yy205; ++ case 333: /* frame_bound ::= expr PRECEDING|FOLLOWING */ ++{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;} ++ yymsp[-1].minor.yy509 = yylhsminor.yy509; + break; +- case 331: /* frame_exclude_opt ::= */ +-{yymsp[1].minor.yy444 = 0;} ++ case 335: /* frame_exclude_opt ::= */ ++{yymsp[1].minor.yy462 = 0;} + break; +- case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +-{yymsp[-1].minor.yy444 = yymsp[0].minor.yy444;} ++ case 336: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ ++{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;} + break; +- case 333: /* frame_exclude ::= NO OTHERS */ +- case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334); +-{yymsp[-1].minor.yy444 = yymsp[-1].major; /*A-overwrites-X*/} ++ case 337: /* frame_exclude ::= NO OTHERS */ ++ case 338: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==338); ++{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/} + break; +- case 335: /* frame_exclude ::= GROUP|TIES */ +-{yymsp[0].minor.yy444 = yymsp[0].major; /*A-overwrites-X*/} ++ case 339: /* frame_exclude ::= GROUP|TIES */ ++{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/} + break; +- case 336: /* window_clause ::= WINDOW windowdefn_list */ +-{ yymsp[-1].minor.yy483 = yymsp[0].minor.yy483; } ++ case 340: /* window_clause ::= WINDOW windowdefn_list */ ++{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; } + break; +- case 337: /* filter_over ::= filter_clause over_clause */ ++ case 341: /* filter_over ::= filter_clause over_clause */ + { +- if( yymsp[0].minor.yy483 ){ +- yymsp[0].minor.yy483->pFilter = yymsp[-1].minor.yy590; ++ if( yymsp[0].minor.yy211 ){ ++ yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454; + }else{ +- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590); ++ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); + } +- yylhsminor.yy483 = yymsp[0].minor.yy483; ++ yylhsminor.yy211 = yymsp[0].minor.yy211; + } +- yymsp[-1].minor.yy483 = yylhsminor.yy483; ++ yymsp[-1].minor.yy211 = yylhsminor.yy211; + break; +- case 338: /* filter_over ::= over_clause */ ++ case 342: /* filter_over ::= over_clause */ + { +- yylhsminor.yy483 = yymsp[0].minor.yy483; ++ yylhsminor.yy211 = yymsp[0].minor.yy211; + } +- yymsp[0].minor.yy483 = yylhsminor.yy483; ++ yymsp[0].minor.yy211 = yylhsminor.yy211; + break; +- case 339: /* filter_over ::= filter_clause */ ++ case 343: /* filter_over ::= filter_clause */ + { +- yylhsminor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); +- if( yylhsminor.yy483 ){ +- yylhsminor.yy483->eFrmType = TK_FILTER; +- yylhsminor.yy483->pFilter = yymsp[0].minor.yy590; ++ yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); ++ if( yylhsminor.yy211 ){ ++ yylhsminor.yy211->eFrmType = TK_FILTER; ++ yylhsminor.yy211->pFilter = yymsp[0].minor.yy454; + }else{ +- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy590); ++ sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454); + } + } +- yymsp[0].minor.yy483 = yylhsminor.yy483; ++ yymsp[0].minor.yy211 = yylhsminor.yy211; + break; +- case 340: /* over_clause ::= OVER LP window RP */ ++ case 344: /* over_clause ::= OVER LP window RP */ + { +- yymsp[-3].minor.yy483 = yymsp[-1].minor.yy483; +- assert( yymsp[-3].minor.yy483!=0 ); ++ yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211; ++ assert( yymsp[-3].minor.yy211!=0 ); + } + break; +- case 341: /* over_clause ::= OVER nm */ ++ case 345: /* over_clause ::= OVER nm */ + { +- yymsp[-1].minor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); +- if( yymsp[-1].minor.yy483 ){ +- yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); ++ yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); ++ if( yymsp[-1].minor.yy211 ){ ++ yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + } + } + break; +- case 342: /* filter_clause ::= FILTER LP WHERE expr RP */ +-{ yymsp[-4].minor.yy590 = yymsp[-1].minor.yy590; } ++ case 346: /* filter_clause ::= FILTER LP WHERE expr RP */ ++{ yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; } + break; +- case 343: /* term ::= QNUMBER */ ++ case 347: /* term ::= QNUMBER */ + { +- yylhsminor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); +- sqlite3DequoteNumber(pParse, yylhsminor.yy590); ++ yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); ++ sqlite3DequoteNumber(pParse, yylhsminor.yy454); + } +- yymsp[0].minor.yy590 = yylhsminor.yy590; ++ yymsp[0].minor.yy454 = yylhsminor.yy454; + break; + default: +- /* (344) input ::= cmdlist */ yytestcase(yyruleno==344); +- /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345); +- /* (346) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=346); +- /* (347) ecmd ::= SEMI */ yytestcase(yyruleno==347); +- /* (348) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==348); +- /* (349) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=349); +- /* (350) trans_opt ::= */ yytestcase(yyruleno==350); +- /* (351) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==351); +- /* (352) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==352); +- /* (353) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==353); +- /* (354) savepoint_opt ::= */ yytestcase(yyruleno==354); +- /* (355) cmd ::= create_table create_table_args */ yytestcase(yyruleno==355); +- /* (356) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=356); +- /* (357) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==357); +- /* (358) columnlist ::= columnname carglist */ yytestcase(yyruleno==358); +- /* (359) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==359); +- /* (360) nm ::= STRING */ yytestcase(yyruleno==360); +- /* (361) typetoken ::= typename */ yytestcase(yyruleno==361); +- /* (362) typename ::= ID|STRING */ yytestcase(yyruleno==362); +- /* (363) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=363); +- /* (364) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); +- /* (365) carglist ::= carglist ccons */ yytestcase(yyruleno==365); +- /* (366) carglist ::= */ yytestcase(yyruleno==366); +- /* (367) ccons ::= NULL onconf */ yytestcase(yyruleno==367); +- /* (368) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==368); +- /* (369) ccons ::= AS generated */ yytestcase(yyruleno==369); +- /* (370) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==370); +- /* (371) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==371); +- /* (372) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=372); +- /* (373) tconscomma ::= */ yytestcase(yyruleno==373); +- /* (374) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=374); +- /* (375) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=375); +- /* (376) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=376); +- /* (377) oneselect ::= values */ yytestcase(yyruleno==377); +- /* (378) sclp ::= selcollist COMMA */ yytestcase(yyruleno==378); +- /* (379) as ::= ID|STRING */ yytestcase(yyruleno==379); +- /* (380) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=380); +- /* (381) returning ::= */ yytestcase(yyruleno==381); +- /* (382) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=382); +- /* (383) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==383); +- /* (384) case_operand ::= expr */ yytestcase(yyruleno==384); +- /* (385) exprlist ::= nexprlist */ yytestcase(yyruleno==385); +- /* (386) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=386); +- /* (387) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=387); +- /* (388) nmnum ::= ON */ yytestcase(yyruleno==388); +- /* (389) nmnum ::= DELETE */ yytestcase(yyruleno==389); +- /* (390) nmnum ::= DEFAULT */ yytestcase(yyruleno==390); +- /* (391) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==391); +- /* (392) foreach_clause ::= */ yytestcase(yyruleno==392); +- /* (393) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==393); +- /* (394) trnm ::= nm */ yytestcase(yyruleno==394); +- /* (395) tridxby ::= */ yytestcase(yyruleno==395); +- /* (396) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==396); +- /* (397) database_kw_opt ::= */ yytestcase(yyruleno==397); +- /* (398) kwcolumn_opt ::= */ yytestcase(yyruleno==398); +- /* (399) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==399); +- /* (400) vtabarglist ::= vtabarg */ yytestcase(yyruleno==400); +- /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==401); +- /* (402) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==402); +- /* (403) anylist ::= */ yytestcase(yyruleno==403); +- /* (404) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==404); +- /* (405) anylist ::= anylist ANY */ yytestcase(yyruleno==405); +- /* (406) with ::= */ yytestcase(yyruleno==406); +- /* (407) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=407); +- /* (408) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=408); ++ /* (348) input ::= cmdlist */ yytestcase(yyruleno==348); ++ /* (349) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==349); ++ /* (350) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=350); ++ /* (351) ecmd ::= SEMI */ yytestcase(yyruleno==351); ++ /* (352) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==352); ++ /* (353) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=353); ++ /* (354) trans_opt ::= */ yytestcase(yyruleno==354); ++ /* (355) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==355); ++ /* (356) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==356); ++ /* (357) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==357); ++ /* (358) savepoint_opt ::= */ yytestcase(yyruleno==358); ++ /* (359) cmd ::= create_table create_table_args */ yytestcase(yyruleno==359); ++ /* (360) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=360); ++ /* (361) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==361); ++ /* (362) columnlist ::= columnname carglist */ yytestcase(yyruleno==362); ++ /* (363) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==363); ++ /* (364) nm ::= STRING */ yytestcase(yyruleno==364); ++ /* (365) typetoken ::= typename */ yytestcase(yyruleno==365); ++ /* (366) typename ::= ID|STRING */ yytestcase(yyruleno==366); ++ /* (367) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=367); ++ /* (368) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=368); ++ /* (369) carglist ::= carglist ccons */ yytestcase(yyruleno==369); ++ /* (370) carglist ::= */ yytestcase(yyruleno==370); ++ /* (371) ccons ::= NULL onconf */ yytestcase(yyruleno==371); ++ /* (372) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==372); ++ /* (373) ccons ::= AS generated */ yytestcase(yyruleno==373); ++ /* (374) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==374); ++ /* (375) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==375); ++ /* (376) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=376); ++ /* (377) tconscomma ::= */ yytestcase(yyruleno==377); ++ /* (378) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=378); ++ /* (379) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=379); ++ /* (380) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=380); ++ /* (381) oneselect ::= values */ yytestcase(yyruleno==381); ++ /* (382) sclp ::= selcollist COMMA */ yytestcase(yyruleno==382); ++ /* (383) as ::= ID|STRING */ yytestcase(yyruleno==383); ++ /* (384) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=384); ++ /* (385) returning ::= */ yytestcase(yyruleno==385); ++ /* (386) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=386); ++ /* (387) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==387); ++ /* (388) case_operand ::= expr */ yytestcase(yyruleno==388); ++ /* (389) exprlist ::= nexprlist */ yytestcase(yyruleno==389); ++ /* (390) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=390); ++ /* (391) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=391); ++ /* (392) nmnum ::= ON */ yytestcase(yyruleno==392); ++ /* (393) nmnum ::= DELETE */ yytestcase(yyruleno==393); ++ /* (394) nmnum ::= DEFAULT */ yytestcase(yyruleno==394); ++ /* (395) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==395); ++ /* (396) foreach_clause ::= */ yytestcase(yyruleno==396); ++ /* (397) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==397); ++ /* (398) tridxby ::= */ yytestcase(yyruleno==398); ++ /* (399) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==399); ++ /* (400) database_kw_opt ::= */ yytestcase(yyruleno==400); ++ /* (401) kwcolumn_opt ::= */ yytestcase(yyruleno==401); ++ /* (402) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==402); ++ /* (403) vtabarglist ::= vtabarg */ yytestcase(yyruleno==403); ++ /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==404); ++ /* (405) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==405); ++ /* (406) anylist ::= */ yytestcase(yyruleno==406); ++ /* (407) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==407); ++ /* (408) anylist ::= anylist ANY */ yytestcase(yyruleno==408); ++ /* (409) with ::= */ yytestcase(yyruleno==409); ++ /* (410) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=410); ++ /* (411) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=411); + break; + /********** End reduce actions ************************************************/ + }; +@@ -183577,8 +186035,8 @@ static const unsigned char aKWCode[148] = {0, + /* 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; ++static i64 keywordCode(const char *z, i64 n, int *pType){ ++ i64 i, j; + const char *zKW; + assert( n>=2 ); + i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; +@@ -184132,7 +186590,7 @@ SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *z, int *tokenType){ + } + case CC_DOLLAR: + case CC_VARALPHA: { +- int n = 0; ++ i64 n = 0; + testcase( z[0]=='$' ); testcase( z[0]=='@' ); + testcase( z[0]==':' ); testcase( z[0]=='#' ); + *tokenType = TK_VARIABLE; +@@ -184228,7 +186686,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ + 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 */ ++ i64 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 */ +@@ -184358,7 +186816,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ + } + if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){ + if( pParse->zErrMsg==0 ){ +- pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); ++ pParse->zErrMsg = sqlite3DbStrDup(db, sqlite3ErrStr(pParse->rc)); + } + if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); +@@ -184439,7 +186897,7 @@ SQLITE_PRIVATE char *sqlite3Normalize( + sqlite3_str_append(pStr, " NULL", 5); + break; + } +- /* Fall through */ ++ /* no break */ deliberate_fall_through + } + case TK_STRING: + case TK_INTEGER: +@@ -184503,7 +186961,7 @@ SQLITE_PRIVATE char *sqlite3Normalize( + } + case TK_SELECT: { + iStartIN = 0; +- /* fall through */ ++ /* no break */ deliberate_fall_through + } + default: { + if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); +@@ -185884,6 +188342,14 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ + rc = setupLookaside(db, pBuf, sz, cnt); + break; + } ++ case SQLITE_DBCONFIG_FP_DIGITS: { ++ int nIn = va_arg(ap, int); ++ int *pOut = va_arg(ap, int*); ++ if( nIn>3 && nIn<24 ) db->nFpDigit = (u8)nIn; ++ if( pOut ) *pOut = db->nFpDigit; ++ rc = SQLITE_OK; ++ break; ++ } + default: { + static const struct { + int op; /* The opcode */ +@@ -186016,13 +188482,17 @@ static int nocaseCollatingFunc( + ** Return the ROWID of the most recent insert + */ + SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ ++ i64 iRet; + #ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } + #endif +- return db->lastRowid; ++ sqlite3_mutex_enter(db->mutex); ++ iRet = db->lastRowid; ++ sqlite3_mutex_leave(db->mutex); ++ return iRet; + } + + /* +@@ -186044,13 +188514,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid) + ** Return the number of changes in the most recent call to sqlite3_exec(). + */ + SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){ ++ i64 iRet; + #ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } + #endif +- return db->nChange; ++ sqlite3_mutex_enter(db->mutex); ++ iRet = db->nChange; ++ sqlite3_mutex_leave(db->mutex); ++ return iRet; + } + SQLITE_API int sqlite3_changes(sqlite3 *db){ + return (int)sqlite3_changes64(db); +@@ -186060,13 +188534,17 @@ SQLITE_API int sqlite3_changes(sqlite3 *db){ + ** Return the number of changes since the database handle was opened. + */ + SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ ++ i64 iRet; + #ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } + #endif +- return db->nTotalChange; ++ sqlite3_mutex_enter(db->mutex); ++ iRet = db->nTotalChange; ++ sqlite3_mutex_leave(db->mutex); ++ return iRet; + } + SQLITE_API int sqlite3_total_changes(sqlite3 *db){ + return (int)sqlite3_total_changes64(db); +@@ -186749,6 +189227,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ + #ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + #endif ++ sqlite3_mutex_enter(db->mutex); + if( ms>0 ){ + sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, + (void*)db); +@@ -186759,6 +189238,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ + }else{ + sqlite3_busy_handler(db, 0, 0); + } ++ sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } + +@@ -187439,6 +189919,9 @@ SQLITE_API void *sqlite3_wal_hook( + sqlite3_mutex_leave(db->mutex); + return pRet; + #else ++ UNUSED_PARAMETER(db); ++ UNUSED_PARAMETER(xCallback); ++ UNUSED_PARAMETER(pArg); + return 0; + #endif + } +@@ -187454,6 +189937,11 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( + int *pnCkpt /* OUT: Total number of frames checkpointed */ + ){ + #ifdef SQLITE_OMIT_WAL ++ UNUSED_PARAMETER(db); ++ UNUSED_PARAMETER(zDb); ++ UNUSED_PARAMETER(eMode); ++ UNUSED_PARAMETER(pnLog); ++ UNUSED_PARAMETER(pnCkpt); + return SQLITE_OK; + #else + int rc; /* Return code */ +@@ -187467,11 +189955,12 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( + if( pnLog ) *pnLog = -1; + if( pnCkpt ) *pnCkpt = -1; + ++ assert( SQLITE_CHECKPOINT_NOOP==-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 ){ ++ if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ + /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint + ** mode: */ + return SQLITE_MISUSE_BKPT; +@@ -187655,9 +190144,11 @@ SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){ + */ + SQLITE_API int sqlite3_error_offset(sqlite3 *db){ + int iOffset = -1; +- if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){ ++ if( db && sqlite3SafetyCheckSickOrOk(db) ){ + sqlite3_mutex_enter(db->mutex); +- iOffset = db->errByteOffset; ++ if( db->errCode ){ ++ iOffset = db->errByteOffset; ++ } + sqlite3_mutex_leave(db->mutex); + } + return iOffset; +@@ -187711,25 +190202,43 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ + ** passed to this function, we assume a malloc() failed during sqlite3_open(). + */ + SQLITE_API int sqlite3_errcode(sqlite3 *db){ +- if( db && !sqlite3SafetyCheckSickOrOk(db) ){ ++ int iRet; ++ if( !db ) return SQLITE_NOMEM_BKPT; ++ if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +- if( !db || db->mallocFailed ){ +- return SQLITE_NOMEM_BKPT; ++ sqlite3_mutex_enter(db->mutex); ++ if( db->mallocFailed ){ ++ iRet = SQLITE_NOMEM_BKPT; ++ }else{ ++ iRet = db->errCode & db->errMask; + } +- return db->errCode & db->errMask; ++ sqlite3_mutex_leave(db->mutex); ++ return iRet; + } + SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ +- if( db && !sqlite3SafetyCheckSickOrOk(db) ){ ++ int iRet; ++ if( !db ) return SQLITE_NOMEM_BKPT; ++ if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +- if( !db || db->mallocFailed ){ +- return SQLITE_NOMEM_BKPT; ++ sqlite3_mutex_enter(db->mutex); ++ if( db->mallocFailed ){ ++ iRet = SQLITE_NOMEM_BKPT; ++ }else{ ++ iRet = db->errCode; + } +- return db->errCode; ++ sqlite3_mutex_leave(db->mutex); ++ return iRet; + } + SQLITE_API int sqlite3_system_errno(sqlite3 *db){ +- return db ? db->iSysErrno : 0; ++ int iRet = 0; ++ if( db ){ ++ sqlite3_mutex_enter(db->mutex); ++ iRet = db->iSysErrno; ++ sqlite3_mutex_leave(db->mutex); ++ } ++ return iRet; + } + + /* +@@ -187835,6 +190344,7 @@ static const int aHardLimit[] = { + SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ + SQLITE_MAX_TRIGGER_DEPTH, + SQLITE_MAX_WORKER_THREADS, ++ SQLITE_MAX_PARSER_DEPTH, + }; + + /* +@@ -187849,6 +190359,9 @@ static const int aHardLimit[] = { + #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_SQL_LENGTH>2147482624 /* 1024 less than 2^31 */ ++# error SQLITE_MAX_SQL_LENGTH must not be greater than 2147482624 ++#endif + #if SQLITE_MAX_COMPOUND_SELECT<2 + # error SQLITE_MAX_COMPOUND_SELECT must be at least 2 + #endif +@@ -187904,6 +190417,7 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + 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_PARSER_DEPTH]==SQLITE_MAX_PARSER_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 ); +@@ -187913,12 +190427,13 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + 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) ); ++ assert( SQLITE_LIMIT_PARSER_DEPTH==(SQLITE_N_LIMIT-1) ); + + + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ + return -1; + } ++ sqlite3_mutex_enter(db->mutex); + oldLimit = db->aLimit[limitId]; + if( newLimit>=0 ){ /* IMP: R-52476-28732 */ + if( newLimit>aHardLimit[limitId] ){ +@@ -187928,6 +190443,7 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + } + db->aLimit[limitId] = newLimit; + } ++ sqlite3_mutex_leave(db->mutex); + return oldLimit; /* IMP: R-53341-35419 */ + } + +@@ -187970,7 +190486,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( + const char *zVfs = zDefaultVfs; + char *zFile; + char c; +- int nUri = sqlite3Strlen30(zUri); ++ i64 nUri = strlen(zUri); + + assert( *pzErrMsg==0 ); + +@@ -187980,8 +190496,8 @@ SQLITE_PRIVATE int sqlite3ParseUri( + ){ + char *zOpt; + int eState; /* Parser state when parsing URI */ +- int iIn; /* Input character index */ +- int iOut = 0; /* Output character index */ ++ i64 iIn; /* Input character index */ ++ i64 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 +@@ -188015,7 +190531,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( + while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; + if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ + *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", +- iIn-7, &zUri[7]); ++ (int)(iIn-7), &zUri[7]); + rc = SQLITE_ERROR; + goto parse_uri_out; + } +@@ -188090,11 +190606,11 @@ SQLITE_PRIVATE int sqlite3ParseUri( + ** 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]; ++ zOpt = &zFile[strlen(zFile)+1]; + while( zOpt[0] ){ +- int nOpt = sqlite3Strlen30(zOpt); ++ i64 nOpt = strlen(zOpt); + char *zVal = &zOpt[nOpt+1]; +- int nVal = sqlite3Strlen30(zVal); ++ i64 nVal = strlen(zVal); + + if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ + zVfs = zVal; +@@ -188140,7 +190656,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( + 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) ){ ++ if( nVal==(i64)strlen(z) && 0==memcmp(zVal, z, nVal) ){ + mode = aMode[i].mode; + break; + } +@@ -188277,7 +190793,7 @@ static int openDatabase( + db = sqlite3MallocZero( sizeof(sqlite3) ); + if( db==0 ) goto opendb_out; + if( isThreadsafe +-#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS ++#if defined(SQLITE_THREAD_MISUSE_WARNINGS) + || sqlite3GlobalConfig.bCoreMutex + #endif + ){ +@@ -188298,6 +190814,7 @@ static int openDatabase( + db->aDb = db->aDbStatic; + db->lookaside.bDisable = 1; + db->lookaside.sz = 0; ++ db->nFpDigit = 17; + + assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); + memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); +@@ -188743,6 +191260,12 @@ SQLITE_API int sqlite3_collation_needed16( + */ + SQLITE_API void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ + DbClientData *p; ++#ifdef SQLITE_ENABLE_API_ARMOR ++ if( !zName || !sqlite3SafetyCheckOk(db) ){ ++ (void)SQLITE_MISUSE_BKPT; ++ return 0; ++ } ++#endif + sqlite3_mutex_enter(db->mutex); + for(p=db->pDbData; p; p=p->pNext){ + if( strcmp(p->zName, zName)==0 ){ +@@ -188818,13 +191341,17 @@ SQLITE_API int sqlite3_global_recover(void){ + ** by the next COMMIT or ROLLBACK. + */ + SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ ++ int iRet; + #ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } + #endif +- return db->autoCommit; ++ sqlite3_mutex_enter(db->mutex); ++ iRet = db->autoCommit; ++ sqlite3_mutex_leave(db->mutex); ++ return iRet; + } + + /* +@@ -189600,6 +192127,17 @@ SQLITE_API int sqlite3_test_control(int op, ...){ + break; + } + ++ /* sqlite3_test_control(SQLITE_TESTCTRL_ATOF, const char *z, double *p); ++ ** ++ ** Test access to the sqlite3AtoF() routine. ++ */ ++ case SQLITE_TESTCTRL_ATOF: { ++ const char *z = va_arg(ap,const char*); ++ double *pR = va_arg(ap,double*); ++ rc = sqlite3AtoF(z,pR); ++ break; ++ } ++ + #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) + ** +@@ -189816,6 +192354,7 @@ SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ + } + SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){ + #ifdef SQLITE_OMIT_WAL ++ UNUSED_PARAMETER(zFilename); + return 0; + #else + zFilename = sqlite3_filename_journal(zFilename); +@@ -189837,17 +192376,19 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ + ** of range. + */ + SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){ ++ const char *zRet = 0; + #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; ++ sqlite3_mutex_enter(db->mutex); ++ if( N>=0 && NnDb ){ ++ zRet = db->aDb[N].zDbSName; + } ++ sqlite3_mutex_leave(db->mutex); ++ return zRet; + } + + /* +@@ -191189,7 +193730,16 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */ + #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) + #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +-#define deliberate_fall_through ++#if !defined(deliberate_fall_through) ++# if defined(__has_attribute) ++# if __has_attribute(fallthrough) ++# define deliberate_fall_through __attribute__((fallthrough)); ++# endif ++# endif ++#endif ++#if !defined(deliberate_fall_through) ++# define deliberate_fall_through ++#endif + + /* + ** Macros needed to provide flexible arrays in a portable way +@@ -191587,6 +194137,15 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ + ) + ++SQLITE_PRIVATE int sqlite3Fts3PrepareStmt( ++ Fts3Table *p, /* Prepare for this connection */ ++ const char *zSql, /* SQL to prepare */ ++ int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */ ++ int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */ ++ sqlite3_stmt **pp /* OUT: Prepared statement */ ++); ++ ++ + /* fts3.c */ + SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); + SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); +@@ -191680,6 +194239,12 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); + SQLITE_EXTENSION_INIT1 + #endif + ++ ++/* ++** Assume any b-tree layer with more levels than this is corrupt. ++*/ ++#define FTS3_MAX_BTREE_HEIGHT 48 ++ + typedef struct Fts3HashWrapper Fts3HashWrapper; + struct Fts3HashWrapper { + Fts3Hash hash; /* Hash table */ +@@ -193194,9 +195759,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ + 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 +- ); ++ rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt); + p->bLock--; + sqlite3_free(zSql); + } +@@ -193398,7 +195961,11 @@ static int fts3SelectLeaf( + assert( piLeaf || piLeaf2 ); + + fts3GetVarint32(zNode, &iHeight); +- rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); ++ if( iHeight>FTS3_MAX_BTREE_HEIGHT ){ ++ rc = FTS_CORRUPT_VTAB; ++ }else{ ++ rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); ++ } + assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); + + if( rc==SQLITE_OK && iHeight>1 ){ +@@ -193443,8 +196010,13 @@ static void fts3PutDeltaVarint( + 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; ++ if( iVal-(*piPrev)>=0 ){ ++ /* Refuse to write a negative delta integer. This only happens with a ++ ** corrupt db (see the assert above) and can cause buffer overwrites ++ ** in some cases. */ ++ *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); ++ *piPrev = iVal; ++ } + } + + /* +@@ -194771,9 +197343,7 @@ static int fts3FilterMethod( + } + if( zSql ){ + p->bLock++; +- rc = sqlite3_prepare_v3( +- p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 +- ); ++ rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt); + p->bLock--; + sqlite3_free(zSql); + }else{ +@@ -195396,6 +197966,7 @@ static int fts3IntegrityMethod( + + UNUSED_PARAMETER(isQuick); + rc = sqlite3Fts3IntegrityCheck(p, &bOk); ++ assert( pVtab->zErrMsg==0 || rc!=SQLITE_OK ); + assert( rc!=SQLITE_CORRUPT_VTAB ); + if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" +@@ -195799,6 +198370,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ + char *p1; + char *p2; + char *aOut; ++ i64 nAlloc = (i64)nPoslist*2 + FTS3_BUFFER_PADDING; + + if( nMaxUndeferred>iPrev ){ + p1 = aPoslist; +@@ -195810,7 +198382,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ + nDistance = iPrev - nMaxUndeferred; + } + +- aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING); ++ aOut = (char *)sqlite3Fts3MallocZero(nAlloc); + if( !aOut ){ + sqlite3_free(aPoslist); + return SQLITE_NOMEM; +@@ -197912,7 +200484,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ + pCsr->aStat[1].nDoc++; + } + eState = 2; +- /* fall through */ ++ /* no break */ deliberate_fall_through + + case 2: + if( v==0 ){ /* 0x00. Next integer will be a docid. */ +@@ -197928,7 +200500,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ + /* State 3. The integer just read is a column number. */ + default: assert( eState==3 ); + iCol = (int)v; +- if( iCol<1 ){ ++ if( iCol<1 || iCol>(pFts3->nColumn+1) ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } +@@ -198618,6 +201190,7 @@ static int getNextNode( + assert( nKey==4 ); + if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ + nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear); ++ if( nNear>=1000000000 ) nNear = 1000000000; + } + } + +@@ -201833,9 +204406,9 @@ typedef struct SegmentWriter SegmentWriter; + ** incrementally. See function fts3PendingListAppend() for details. + */ + struct PendingList { +- int nData; ++ sqlite3_int64 nData; + char *aData; +- int nSpace; ++ sqlite3_int64 nSpace; + sqlite3_int64 iLastDocid; + sqlite3_int64 iLastCol; + sqlite3_int64 iLastPos; +@@ -202008,6 +204581,24 @@ struct SegmentNode { + #define SQL_UPDATE_LEVEL_IDX 38 + #define SQL_UPDATE_LEVEL 39 + ++/* ++** Wrapper around sqlite3_prepare_v3() to ensure that SQLITE_PREPARE_FROM_DDL ++** is always set. ++*/ ++SQLITE_PRIVATE int sqlite3Fts3PrepareStmt( ++ Fts3Table *p, /* Prepare for this connection */ ++ const char *zSql, /* SQL to prepare */ ++ int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */ ++ int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */ ++ sqlite3_stmt **pp /* OUT: Prepared statement */ ++){ ++ int f = SQLITE_PREPARE_FROM_DDL ++ |((bAllowVtab==0) ? SQLITE_PREPARE_NO_VTAB : 0) ++ |(bPersist ? SQLITE_PREPARE_PERSISTENT : 0); ++ ++ return sqlite3_prepare_v3(p->db, zSql, -1, f, pp, NULL); ++} ++ + /* + ** This function is used to obtain an SQLite prepared statement handle + ** for the statement identified by the second argument. If successful, +@@ -202133,12 +204724,12 @@ static int fts3SqlStmt( + + pStmt = p->aStmt[eStmt]; + if( !pStmt ){ +- int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB; ++ int bAllowVtab = 0; + 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; ++ bAllowVtab = 1; + zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); + }else{ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); +@@ -202146,7 +204737,7 @@ static int fts3SqlStmt( + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ +- rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL); ++ rc = sqlite3Fts3PrepareStmt(p, zSql, 1, bAllowVtab, &pStmt); + sqlite3_free(zSql); + assert( rc==SQLITE_OK || pStmt==0 ); + p->aStmt[eStmt] = pStmt; +@@ -202495,7 +205086,9 @@ static int fts3PendingTermsAddOne( + + pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); + if( pList ){ +- p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); ++ assert( (i64)pList->nData+(i64)nToken+(i64)sizeof(Fts3HashElem) ++ <= (i64)p->nPendingData ); ++ p->nPendingData -= (int)(pList->nData + nToken + sizeof(Fts3HashElem)); + } + if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ + if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ +@@ -202508,7 +205101,9 @@ static int fts3PendingTermsAddOne( + } + } + if( rc==SQLITE_OK ){ +- p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); ++ assert( (i64)p->nPendingData + pList->nData + nToken ++ + sizeof(Fts3HashElem) <= 0x3fffffff ); ++ p->nPendingData += (int)(pList->nData + nToken + sizeof(Fts3HashElem)); + } + return rc; + } +@@ -204842,6 +207437,10 @@ static void fts3ReadEndBlockField( + for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } ++ ++ /* This if() clause is just to avoid an integer overflow. The record is ++ ** corrupt in this case. */ ++ if( (i64)iVal==SMALLEST_INT64 ) iMul = 1; + *pnByte = ((i64)iVal * (i64)iMul); + } + } +@@ -205309,7 +207908,7 @@ static int fts3DoRebuild(Fts3Table *p){ + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ +- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); ++ rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt); + sqlite3_free(zSql); + } + +@@ -206068,7 +208667,7 @@ static int fts3IncrmergeLoad( + return FTS_CORRUPT_VTAB; + } + +- pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; ++ pWriter->nLeafEst = (int)(((iEnd - iStart)+1)/FTS_MAX_APPENDABLE_HEIGHT); + pWriter->iStart = iStart; + pWriter->iEnd = iEnd; + pWriter->iAbsLevel = iAbsLevel; +@@ -207062,7 +209661,7 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ +- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); ++ rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt); + sqlite3_free(zSql); + } + +@@ -207192,7 +209791,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ + 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) ){ ++ }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 11) ){ + v = atoi(&zVal[11]); + if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; + rc = SQLITE_OK; +@@ -208186,8 +210785,8 @@ static int fts3StringAppend( + ** to grow the buffer until so that it is big enough to accommodate the + ** appended data. + */ +- if( pStr->n+nAppend+1>=pStr->nAlloc ){ +- sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; ++ if( (i64)pStr->n+(i64)nAppend+1>=(i64)pStr->nAlloc ){ ++ i64 nAlloc = pStr->nAlloc+(i64)nAppend+100; + char *zNew = sqlite3_realloc64(pStr->z, nAlloc); + if( !zNew ){ + return SQLITE_NOMEM; +@@ -208459,7 +211058,7 @@ static int fts3ExprLHits( + if( p->flag==FTS3_MATCHINFO_LHITS ){ + p->aMatchinfo[iStart + iCol] = (u32)nHit; + }else if( nHit ){ +- p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F)); ++ p->aMatchinfo[iStart + iCol/32] |= (1U << (iCol&0x1F)); + } + } + assert( *pIter==0x00 || *pIter==0x01 ); +@@ -210452,7 +213051,8 @@ struct JsonString { + /* 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 */ ++#define JSTRING_TOODEEP 0x04 /* JSON nested too deep */ ++#define JSTRING_ERR 0x08 /* Error already sent to sqlite3_result */ + + /* The "subtype" set for text JSON values passed through using + ** sqlite3_result_subtype() and sqlite3_value_subtype(). +@@ -210467,7 +213067,10 @@ struct JsonString { + #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 */ ++#define JSON_AINS 0x08 /* json_array_insert(), not json_insert() */ ++#define JSON_BLOB 0x10 /* Use the BLOB output format */ ++ ++#define JSON_INSERT_TYPE(X) (((X)&0xC)>>2) + + + /* A parsed JSON value. Lifecycle: +@@ -210513,6 +213116,7 @@ struct JsonParse { + #define JEDIT_REPL 2 /* Overwrite if exists */ + #define JEDIT_INS 3 /* Insert if not exists */ + #define JEDIT_SET 4 /* Insert or overwrite */ ++#define JEDIT_AINS 5 /* array_insert() */ + + /* + ** Maximum nesting depth of JSON for this implementation. +@@ -210538,7 +213142,7 @@ struct JsonParse { + **************************************************************************/ + static void jsonReturnStringAsBlob(JsonString*); + static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); +-static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); ++static u32 jsonTranslateBlobToText(JsonParse*,u32,JsonString*); + static void jsonReturnParse(sqlite3_context*,JsonParse*); + static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); + static void jsonParseFree(JsonParse*); +@@ -210696,6 +213300,15 @@ static void jsonStringOom(JsonString *p){ + jsonStringReset(p); + } + ++/* Report JSON nested too deep ++*/ ++static void jsonStringTooDeep(JsonString *p){ ++ p->eErr |= JSTRING_TOODEEP; ++ assert( p->pCtx!=0 ); ++ sqlite3_result_error(p->pCtx, "JSON nested too deep", -1); ++ 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 + */ +@@ -210935,7 +213548,7 @@ static void jsonAppendSqlValue( + break; + } + case SQLITE_FLOAT: { +- jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue)); ++ jsonPrintf(100, p, "%!0.17g", sqlite3_value_double(pValue)); + break; + } + case SQLITE_INTEGER: { +@@ -210985,6 +213598,7 @@ static void jsonReturnString( + ){ + assert( (pParse!=0)==(ctx!=0) ); + assert( ctx==0 || ctx==p->pCtx ); ++ jsonStringTerminate(p); + if( p->eErr==0 ){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); + if( flags & JSON_BLOB ){ +@@ -210992,7 +213606,7 @@ static void jsonReturnString( + }else if( p->bStatic ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); +- }else if( jsonStringTerminate(p) ){ ++ }else{ + if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ + int rc; + pParse->zJson = sqlite3RCStrRef(p->zBuf); +@@ -211008,11 +213622,11 @@ static void jsonReturnString( + 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_TOODEEP ){ ++ /* error already in p->pCtx */ + }else if( p->eErr & JSTRING_MALFORMED ){ + sqlite3_result_error(p->pCtx, "malformed JSON", -1); + } +@@ -211343,11 +213957,11 @@ static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ + /* Slow version of jsonBlobAppendNode() that first resizes the + ** pParse->aBlob structure. + */ +-static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); ++static void jsonBlobAppendNode(JsonParse*,u8,u64,const void*); + static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + JsonParse *pParse, + u8 eType, +- u32 szPayload, ++ u64 szPayload, + const void *aPayload + ){ + if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; +@@ -211367,7 +213981,7 @@ static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + static void jsonBlobAppendNode( + JsonParse *pParse, /* The JsonParse object under construction */ + u8 eType, /* Node type. One of JSONB_* */ +- u32 szPayload, /* Number of bytes of payload */ ++ u64 szPayload, /* Number of bytes of payload */ + const void *aPayload /* The payload. Might be NULL */ + ){ + u8 *a; +@@ -212223,12 +214837,8 @@ static int jsonConvertTextToBlob( + */ + static void jsonReturnStringAsBlob(JsonString *pStr){ + JsonParse px; ++ assert( pStr->eErr==0 ); + 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); +@@ -212252,9 +214862,10 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + u8 x; + u32 sz; + u32 n; +- assert( i<=pParse->nBlob ); +- x = pParse->aBlob[i]>>4; +- if( x<=11 ){ ++ if( i>=pParse->nBlob ){ ++ *pSz = 0; ++ return 0; ++ }else if( (x = pParse->aBlob[i]>>4)<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ +@@ -212318,7 +214929,7 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + ** The pOut->eErr JSTRING_OOM flag is set on a OOM. + */ + static u32 jsonTranslateBlobToText( +- const JsonParse *pParse, /* the complete parse of the JSON */ ++ JsonParse *pParse, /* the complete parse of the JSON */ + u32 i, /* Start rendering at this index */ + JsonString *pOut /* Write JSON here */ + ){ +@@ -212379,7 +214990,8 @@ static u32 jsonTranslateBlobToText( + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); +- k++; ++ if( sz<=1 ) goto malformed_jsonb; ++ k = 1; + } + if( zIn[k]=='.' ){ + jsonAppendChar(pOut, '0'); +@@ -212500,10 +215112,14 @@ static u32 jsonTranslateBlobToText( + jsonAppendChar(pOut, '['); + j = i+n; + iEnd = j+sz; ++ if( ++pParse->iDepth > JSON_MAX_DEPTH ){ ++ jsonStringTooDeep(pOut); ++ } + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, ','); + } ++ pParse->iDepth--; + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, ']'); +@@ -212514,10 +215130,14 @@ static u32 jsonTranslateBlobToText( + jsonAppendChar(pOut, '{'); + j = i+n; + iEnd = j+sz; ++ if( ++pParse->iDepth > JSON_MAX_DEPTH ){ ++ jsonStringTooDeep(pOut); ++ } + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); + } ++ pParse->iDepth--; + if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, '}'); +@@ -212574,7 +215194,7 @@ static u32 jsonTranslateBlobToPrettyText( + u32 i /* Start rendering at this index */ + ){ + u32 sz, n, j, iEnd; +- const JsonParse *pParse = pPretty->pParse; ++ JsonParse *pParse = pPretty->pParse; + JsonString *pOut = pPretty->pOut; + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ +@@ -212589,6 +215209,9 @@ static u32 jsonTranslateBlobToPrettyText( + if( jnIndent++; ++ if( pPretty->nIndent >= JSON_MAX_DEPTH ){ ++ jsonStringTooDeep(pOut); ++ } + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToPrettyText(pPretty, j); +@@ -212610,6 +215233,10 @@ static u32 jsonTranslateBlobToPrettyText( + if( jnIndent++; ++ if( pPretty->nIndent >= JSON_MAX_DEPTH ){ ++ jsonStringTooDeep(pOut); ++ } ++ pParse->iDepth = pPretty->nIndent; + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToText(pParse, j, pOut); +@@ -212767,6 +215394,7 @@ static void jsonBlobEdit( + u32 nIns /* Bytes of content to insert */ + ){ + i64 d = (i64)nIns - (i64)nDel; ++ assert( pParse->nBlob >= (u64)iDel + (u64)nDel ); + if( d<0 && d>=(-8) && aIns!=0 + && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d) + ){ +@@ -213009,7 +215637,9 @@ static int jsonLabelCompare( + */ + #define JSON_LOOKUP_ERROR 0xffffffff + #define JSON_LOOKUP_NOTFOUND 0xfffffffe +-#define JSON_LOOKUP_PATHERROR 0xfffffffd ++#define JSON_LOOKUP_NOTARRAY 0xfffffffd ++#define JSON_LOOKUP_TOODEEP 0xfffffffc ++#define JSON_LOOKUP_PATHERROR 0xfffffffb + #define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) + + /* Forward declaration */ +@@ -213038,7 +215668,7 @@ static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); + 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 */ ++ const char *zTail /* Tail of the path that determines substructure */ + ){ + static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; + int rc; +@@ -213056,7 +215686,12 @@ static u32 jsonCreateEditSubstructure( + pIns->eEdit = pParse->eEdit; + pIns->nIns = pParse->nIns; + pIns->aIns = pParse->aIns; ++ pIns->iDepth = pParse->iDepth+1; ++ if( pIns->iDepth >= JSON_MAX_DEPTH ){ ++ return JSON_LOOKUP_TOODEEP; ++ } + rc = jsonLookupStep(pIns, 0, zTail, 0); ++ pParse->iDepth--; + pParse->oom |= pIns->oom; + } + return rc; /* Error code only */ +@@ -213073,9 +215708,9 @@ static u32 jsonCreateEditSubstructure( + ** 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 ++** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, JEDIT_SET, or JEDIT_AINS, 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. + */ +@@ -213101,6 +215736,13 @@ static u32 jsonLookupStep( + jsonBlobEdit(pParse, iRoot, sz, 0, 0); + }else if( pParse->eEdit==JEDIT_INS ){ + /* Already exists, so json_insert() is a no-op */ ++ }else if( pParse->eEdit==JEDIT_AINS ){ ++ /* json_array_insert() */ ++ if( zPath[-1]!=']' ){ ++ return JSON_LOOKUP_NOTARRAY; ++ }else{ ++ jsonBlobEdit(pParse, iRoot, 0, pParse->aIns, pParse->nIns); ++ } + }else{ + /* json_set() or json_replace() */ + jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); +@@ -213155,7 +215797,11 @@ static u32 jsonLookupStep( + n = jsonbPayloadSize(pParse, v, &sz); + if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; + assert( j>0 ); ++ if( ++pParse->iDepth >= JSON_MAX_DEPTH ){ ++ return JSON_LOOKUP_TOODEEP; ++ } + rc = jsonLookupStep(pParse, v, &zPath[i], j); ++ pParse->iDepth--; + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } +@@ -213172,6 +215818,10 @@ static u32 jsonLookupStep( + JsonParse ix; /* Header of the label to be inserted */ + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); ++ testcase( pParse->eEdit==JEDIT_AINS ); ++ if( pParse->eEdit==JEDIT_AINS && sqlite3_strglob("*]",&zPath[i])!=0 ){ ++ return JSON_LOOKUP_NOTARRAY; ++ } + memset(&ix, 0, sizeof(ix)); + ix.db = pParse->db; + jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); +@@ -213199,28 +215849,32 @@ static u32 jsonLookupStep( + return rc; + } + }else if( zPath[0]=='[' ){ ++ u64 kk = 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'; ++ if( kk<0xffffffff ) kk = kk*10 + zPath[i] - '0'; ++ /* ^^^^^^^^^^--- Allow kk to be bigger than any JSON array so that ++ ** we get NOTFOUND instead of PATHERROR, without overflowing kk. */ + i++; + } + if( i<2 || zPath[i]!=']' ){ + if( zPath[1]=='#' ){ +- k = jsonbArrayCount(pParse, iRoot); ++ kk = jsonbArrayCount(pParse, iRoot); + i = 2; + if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ +- unsigned int nn = 0; ++ u64 nn = 0; + i = 3; + do{ +- nn = nn*10 + zPath[i] - '0'; ++ if( nn<0xffffffff ) nn = nn*10 + zPath[i] - '0'; ++ /* ^^^^^^^^^^--- Allow nn to be bigger than any JSON array to ++ ** get NOTFOUND instead of PATHERROR, without overflowing nn. */ + i++; + }while( sqlite3Isdigit(zPath[i]) ); +- if( nn>k ) return JSON_LOOKUP_NOTFOUND; +- k -= nn; ++ if( nn>kk ) return JSON_LOOKUP_NOTFOUND; ++ kk -= nn; + } + if( zPath[i]!=']' ){ + return JSON_LOOKUP_PATHERROR; +@@ -213232,21 +215886,26 @@ static u32 jsonLookupStep( + j = iRoot+n; + iEnd = j+sz; + while( jiDepth >= JSON_MAX_DEPTH ){ ++ return JSON_LOOKUP_TOODEEP; ++ } + rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); ++ pParse->iDepth--; + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } +- k--; ++ kk--; + 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( kk>0 ) return JSON_LOOKUP_NOTFOUND; + if( pParse->eEdit>=JEDIT_INS ){ + JsonParse v; + testcase( pParse->eEdit==JEDIT_INS ); ++ testcase( pParse->eEdit==JEDIT_AINS ); + testcase( pParse->eEdit==JEDIT_SET ); + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); + if( !JSON_LOOKUP_ISERROR(rc) +@@ -213384,7 +216043,7 @@ static void jsonReturnFromBlob( + 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); ++ rc = sqlite3AtoF(z, &r); + sqlite3DbFree(db, z); + if( rc<=0 ) goto returnfromblob_malformed; + sqlite3_result_double(pCtx, r); +@@ -213564,16 +216223,35 @@ static int jsonFunctionArgToBlob( + } + + /* +-** Generate a bad path error. ++** Generate a path error. ++** ++** The specifics of the error are determined by the rc argument. ++** ++** rc error ++** ----------------- ---------------------- ++** JSON_LOOKUP_ARRAY "not an array" ++** JSON_LOOKUP_TOODEEP "JSON nested too deep" ++** JSON_LOOKUP_ERROR "malformed JSON" ++** otherwise... "bad JSON path" + ** + ** 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 */ ++ const char *zPath, /* The path with the problem */ ++ int rc /* Maybe JSON_LOOKUP_NOTARRAY */ + ){ +- char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); ++ char *zMsg; ++ if( rc==(int)JSON_LOOKUP_NOTARRAY ){ ++ zMsg = sqlite3_mprintf("not an array element: %Q", zPath); ++ }else if( rc==(int)JSON_LOOKUP_ERROR ){ ++ zMsg = sqlite3_mprintf("malformed JSON"); ++ }else if( rc==(int)JSON_LOOKUP_TOODEEP ){ ++ zMsg = sqlite3_mprintf("JSON path too deep"); ++ }else{ ++ zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); ++ } + if( ctx==0 ) return zMsg; + if( zMsg ){ + sqlite3_result_error(ctx, zMsg, -1); +@@ -213590,13 +216268,13 @@ static char *jsonBadPathError( + ** and return the result. + ** + ** The specific operation is determined by eEdit, which can be one +-** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. ++** of JEDIT_INS, JEDIT_REPL, JEDIT_SET, or JEDIT_AINS. + */ + static void jsonInsertIntoBlob( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv, +- int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ ++ int eEdit /* JEDIT_INS, JEDIT_REPL, JEDIT_SET, JEDIT_AINS */ + ){ + int i; + u32 rc = 0; +@@ -213633,6 +216311,7 @@ static void jsonInsertIntoBlob( + p->nIns = ax.nBlob; + p->aIns = ax.aBlob; + p->delta = 0; ++ p->iDepth = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + } + jsonParseReset(&ax); +@@ -213645,11 +216324,7 @@ static void jsonInsertIntoBlob( + + jsonInsertIntoBlob_patherror: + jsonParseFree(p); +- if( rc==JSON_LOOKUP_ERROR ){ +- sqlite3_result_error(ctx, "malformed JSON", -1); +- }else{ +- jsonBadPathError(ctx, zPath); +- } ++ jsonBadPathError(ctx, zPath, rc); + return; + } + +@@ -214089,10 +216764,8 @@ static void jsonArrayLengthFunc( + 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); ++ jsonBadPathError(ctx, zPath, i); + } + eErr = 1; + i = 0; +@@ -214195,7 +216868,7 @@ static void jsonExtractFunc( + j = jsonLookupStep(p, 0, jx.zBuf, 0); + jsonStringReset(&jx); + }else{ +- jsonBadPathError(ctx, zPath); ++ jsonBadPathError(ctx, zPath, 0); + goto json_extract_error; + } + if( jnBlob ){ +@@ -214226,11 +216899,8 @@ static void jsonExtractFunc( + 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); ++ jsonBadPathError(ctx, zPath, j); + goto json_extract_error; + } + } +@@ -214254,6 +216924,7 @@ json_extract_error: + #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 */ ++#define JSON_MERGE_TOODEEP 4 /* Nested too deep */ + + /* + ** RFC-7396 MergePatch for two JSONB blobs. +@@ -214305,7 +216976,8 @@ 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[] */ ++ u32 iPatch, /* Index of PATCH in pPatch->aBlob[] */ ++ u32 iDepth /* Nesting depth */ + ){ + u8 x; /* Type of a single node */ + u32 n, sz=0; /* Return values from jsonbPayloadSize() */ +@@ -214414,7 +217086,8 @@ static int jsonMergePatch( + /* Algorithm line 12 */ + int rc, savedDelta = pTarget->delta; + pTarget->delta = 0; +- rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); ++ if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP; ++ rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue, iDepth+1); + if( rc ) return rc; + pTarget->delta += savedDelta; + } +@@ -214435,7 +217108,8 @@ static int jsonMergePatch( + pTarget->aBlob[iTEnd+szNew] = 0x00; + savedDelta = pTarget->delta; + pTarget->delta = 0; +- rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); ++ if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP; ++ rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue,iDepth+1); + if( rc ) return rc; + pTarget->delta += savedDelta; + } +@@ -214466,11 +217140,13 @@ static void jsonPatchFunc( + if( pTarget==0 ) return; + pPatch = jsonParseFuncArg(ctx, argv[1], 0); + if( pPatch ){ +- rc = jsonMergePatch(pTarget, 0, pPatch, 0); ++ rc = jsonMergePatch(pTarget, 0, pPatch, 0, 0); + if( rc==JSON_MERGE_OK ){ + jsonReturnParse(ctx, pTarget); + }else if( rc==JSON_MERGE_OOM ){ + sqlite3_result_error_nomem(ctx); ++ }else if( rc==JSON_MERGE_TOODEEP ){ ++ sqlite3_result_error(ctx, "JSON nested too deep", -1); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } +@@ -214558,10 +217234,8 @@ static void jsonRemoveFunc( + 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); ++ jsonBadPathError(ctx, zPath, rc); + } + goto json_remove_done; + } +@@ -214571,7 +217245,7 @@ static void jsonRemoveFunc( + return; + + json_remove_patherror: +- jsonBadPathError(ctx, zPath); ++ jsonBadPathError(ctx, zPath, 0); + + json_remove_done: + jsonParseFree(p); +@@ -214615,16 +217289,18 @@ static void jsonSetFunc( + int argc, + sqlite3_value **argv + ){ +- + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); +- int bIsSet = (flags&JSON_ISSET)!=0; ++ int eInsType = JSON_INSERT_TYPE(flags); ++ static const char *azInsType[] = { "insert", "set", "array_insert" }; ++ static const u8 aEditType[] = { JEDIT_INS, JEDIT_SET, JEDIT_AINS }; + + if( argc<1 ) return; ++ assert( eInsType>=0 && eInsType<=2 ); + if( (argc&1)==0 ) { +- jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); ++ jsonWrongNumArgs(ctx, azInsType[eInsType]); + return; + } +- jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); ++ jsonInsertIntoBlob(ctx, argc, argv, aEditType[eInsType]); + } + + /* +@@ -214649,17 +217325,15 @@ static void jsonTypeFunc( + zPath = (const char*)sqlite3_value_text(argv[1]); + if( zPath==0 ) goto json_type_done; + if( zPath[0]!='$' ){ +- jsonBadPathError(ctx, zPath); ++ jsonBadPathError(ctx, zPath, 0); + 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); ++ jsonBadPathError(ctx, zPath, i); + } + goto json_type_done; + } +@@ -214913,12 +217587,12 @@ static void jsonArrayStep( + } + static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; ++ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + 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)); ++ jsonAppendRawNZ(pStr, "]", 2); ++ jsonStringTrimOneChar(pStr); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; +@@ -214939,6 +217613,9 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + jsonStringTrimOneChar(pStr); + } ++ }else if( flags & JSON_BLOB ){ ++ static const u8 emptyArray = 0x0b; ++ sqlite3_result_blob(ctx, &emptyArray, 1, SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } +@@ -214972,11 +217649,9 @@ static void jsonGroupInverse( + 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=='"' ){ +@@ -215005,6 +217680,13 @@ static void jsonGroupInverse( + ** json_group_obj(NAME,VALUE) + ** + ** Return a JSON object composed of all names and values in the aggregate. ++** ++** Rows for which NAME is NULL do not result in a new entry. However, we ++** do initially insert a "@" entry into the growing string for each null entry ++** and change the first character of the string to "@" to signal that the ++** string contains null entries. The "@" markers are needed in order to ++** correctly process xInverse() requests. The initial "@" is converted ++** back into "{" and the "@" null values are removed by jsonObjectCompute(). + */ + static void jsonObjectStep( + sqlite3_context *ctx, +@@ -215022,7 +217704,7 @@ static void jsonObjectStep( + if( pStr->zBuf==0 ){ + jsonStringInit(pStr, ctx); + jsonAppendChar(pStr, '{'); +- }else if( pStr->nUsed>1 && z!=0 ){ ++ }else if( pStr->nUsed>1 ){ + jsonAppendChar(pStr, ','); + } + pStr->pCtx = ctx; +@@ -215030,28 +217712,75 @@ static void jsonObjectStep( + jsonAppendString(pStr, z, n); + jsonAppendChar(pStr, ':'); + jsonAppendSqlValue(pStr, argv[1]); ++ }else{ ++ pStr->zBuf[0] = '@'; ++ jsonAppendRawNZ(pStr, "@", 1); + } + } + } + static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; ++ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ +- int flags; +- jsonAppendChar(pStr, '}'); ++ JsonString *pOgStr = pStr; ++ JsonString tmpStr; ++ jsonAppendRawNZ(pOgStr, "}", 2); /* Ensure it is zero-terminated */ ++ jsonStringTrimOneChar(pOgStr); /* Remove the zero terminator */ + 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 ){ ++ } ++ if( pStr->zBuf[0]!='{' ){ ++ /* The string contains null entries that need to be removed */ ++ u64 i, j; ++ int inStr = 0; ++ if( !isFinal ){ ++ /* Work with a temporary copy of the string if this is not the ++ ** final result */ ++ jsonStringInit(&tmpStr, ctx); ++ jsonAppendRawNZ(&tmpStr, pStr->zBuf, pStr->nUsed+1); ++ pStr = &tmpStr; ++ if( pStr->eErr ){ ++ jsonReturnString(pStr, 0, 0); ++ return; ++ } ++ jsonStringTrimOneChar(pStr); /* Remove zero terminator */ ++ } ++ /* Fix up the string by changing the initial "@" flag back to ++ ** to "{" and removing all subsequence "@" entries, with their ++ ** associated comma delimeters. */ ++ pStr->zBuf[0] = '{'; ++ for(i=j=1; inUsed; i++){ ++ char c = pStr->zBuf[i]; ++ if( c=='"' ){ ++ inStr = !inStr; ++ pStr->zBuf[j++] = '"'; ++ }else if( c=='\\' ){ ++ pStr->zBuf[j++] = '\\'; ++ pStr->zBuf[j++] = pStr->zBuf[++i]; ++ }else if( c=='@' && !inStr ){ ++ assert( i+1nUsed ); ++ if( pStr->zBuf[i+1]==',' ){ ++ i++; ++ }else if( pStr->zBuf[j-1]==',' ){ ++ j--; ++ } ++ }else{ ++ pStr->zBuf[j++] = c; ++ } ++ } ++ pStr->zBuf[j] = 0; /* Restore zero terminator */ ++ pStr->nUsed = j; /* Truncate the string */ ++ } ++ if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ +- jsonStringTrimOneChar(pStr); ++ jsonStringTrimOneChar(pOgStr); + } +- return; + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : +@@ -215059,8 +217788,12 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); +- jsonStringTrimOneChar(pStr); ++ jsonStringTrimOneChar(pOgStr); + } ++ if( pStr!=pOgStr ) jsonStringReset(pStr); ++ }else if( flags & JSON_BLOB ){ ++ static const unsigned char emptyObject = 0x0c; ++ sqlite3_result_blob(ctx, &emptyObject, 1, SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } +@@ -215222,7 +217955,9 @@ 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; ++ sz += p->i + n; ++ if( sz >= p->sParse.nBlob ) sz = p->i; ++ return sz; + }else{ + return p->i; + } +@@ -215561,7 +218296,7 @@ static int jsonEachFilter( + if( zRoot==0 ) return SQLITE_OK; + if( zRoot[0]!='$' ){ + sqlite3_free(cur->pVtab->zErrMsg); +- cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); ++ cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot, 0); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } +@@ -215579,7 +218314,7 @@ static int jsonEachFilter( + return SQLITE_OK; + } + sqlite3_free(cur->pVtab->zErrMsg); +- cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); ++ cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot, 0); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } +@@ -215669,6 +218404,8 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ + 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_insert, -1,1,1, 1,0,JSON_AINS, jsonSetFunc), ++ JFUNCTION(jsonb_array_insert,-1,1,0, 1,1,JSON_AINS, jsonSetFunc), + 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), +@@ -215907,7 +218644,7 @@ struct Rtree { + 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 */ ++ u16 nAux; /* # of auxiliary columns in %_rowid */ + #ifdef SQLITE_ENABLE_GEOPOLY + u8 nAuxNotNull; /* Number of initial not-null aux columns */ + #endif +@@ -216047,7 +218784,7 @@ struct RtreeCursor { + 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 */ ++ u32 anQueue[RTREE_MAX_DEPTH+2]; /* Number of queued entries by iLevel */ + }; + + /* Return the Rtree of a RtreeCursor */ +@@ -216502,6 +219239,9 @@ static int nodeAcquire( + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } ++ }else if( iNode<=0 ){ ++ RTREE_IS_CORRUPT(pRtree); ++ rc = SQLITE_CORRUPT_VTAB; + }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); + if( !pNode ){ +@@ -216527,7 +219267,7 @@ static int nodeAcquire( + */ + if( rc==SQLITE_OK && pNode && iNode==1 ){ + pRtree->iDepth = readInt16(pNode->zData); +- if( pRtree->iDepth>RTREE_MAX_DEPTH ){ ++ if( pRtree->iDepth>=RTREE_MAX_DEPTH ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } +@@ -216778,7 +219518,17 @@ static void rtreeRelease(Rtree *pRtree){ + pRtree->inWrTrans = 0; + assert( pRtree->nCursor==0 ); + nodeBlobReset(pRtree); +- assert( pRtree->nNodeRef==0 || pRtree->bCorrupt ); ++ if( pRtree->nNodeRef ){ ++ int i; ++ assert( pRtree->bCorrupt ); ++ for(i=0; iaHash[i] ){ ++ RtreeNode *pNext = pRtree->aHash[i]->pNext; ++ sqlite3_free(pRtree->aHash[i]); ++ pRtree->aHash[i] = pNext; ++ } ++ } ++ } + sqlite3_finalize(pRtree->pWriteNode); + sqlite3_finalize(pRtree->pDeleteNode); + sqlite3_finalize(pRtree->pReadRowid); +@@ -217133,7 +219883,7 @@ static int nodeRowidIndex( + ){ + int ii; + int nCell = NCELL(pNode); +- assert( nCell<200 ); ++ assert( nCell<65536 && nCell>=0 ); + for(ii=0; iiRTREE_MAXCELLS ){ ++ RTREE_IS_CORRUPT(pRtree); ++ return SQLITE_CORRUPT_VTAB; ++ } + pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); + while( p->iCell100) ){ ++ if( cnt>100 ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } +@@ -218428,15 +221181,6 @@ static int SplitNode( + rc = updateMapping(pRtree, pCell->iRowid, 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); +@@ -218621,7 +221365,7 @@ static int rtreeInsertCell( + rc = SplitNode(pRtree, pNode, pCell, iHeight); + }else{ + rc = AdjustTree(pRtree, pNode, pCell); +- if( ALWAYS(rc==SQLITE_OK) ){ ++ if( rc==SQLITE_OK ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); + }else{ +@@ -219381,7 +222125,7 @@ static int rtreeInit( + "Auxiliary rtree columns must be last" /* 4 */ + }; + +- assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */ ++ assert( RTREE_MAX_AUX_COLUMN<256 ); + if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); + return SQLITE_ERROR; +@@ -220249,7 +222993,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ + /* 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); ++ (void)sqlite3AtoF((const char*)p->z, &r); + *pVal = r; + #else + *pVal = (GeoCoord)atof((const char*)p->z); +@@ -221300,6 +224044,11 @@ static int geopolyInit( + int ii; + (void)pAux; + ++ if( argc>=RTREE_MAX_AUX_COLUMN+4 ){ ++ *pzErr = sqlite3_mprintf("Too many columns for a geopoly table"); ++ return SQLITE_ERROR; ++ } ++ + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + +@@ -222434,7 +225183,7 @@ 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 */ ++ sqlite3_int64 nOut; /* Size of output buffer in bytes */ + int cnt; + int bToUpper; /* True for toupper(), false for tolower() */ + UErrorCode status; +@@ -222457,7 +225206,7 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + } + + for(cnt=0; cnt<2; cnt++){ +- UChar *zNew = sqlite3_realloc(zOutput, nOut); ++ UChar *zNew = sqlite3_realloc64(zOutput, nOut); + if( zNew==0 ){ + sqlite3_free(zOutput); + sqlite3_result_error_nomem(p); +@@ -222466,9 +225215,9 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + zOutput = zNew; + status = U_ZERO_ERROR; + if( bToUpper ){ +- nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); ++ nOut = 2LL*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + }else{ +- nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); ++ nOut = 2LL*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + } + + if( U_SUCCESS(status) ){ +@@ -224081,16 +226830,26 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ + 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, ++ ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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; ++ unsigned char *zEnd = z + (*pLen); ++ while( z=0 ){ ++ v = (v<<6) + c; ++ z++; + } +- z--; +- *pLen -= (int)(z - zStart); ++ ++ *pLen -= (int)(z - (unsigned char*)*pz); + *pz = (char*)z; + return v; + } +@@ -224159,21 +226918,22 @@ static int rbuDeltaApply( + int lenDelta, /* Length of the delta */ + char *zOut /* Write the output into this preallocated buffer */ + ){ +- unsigned int limit; +- unsigned int total = 0; ++ sqlite3_uint64 limit; ++ sqlite3_uint64 total = 0; + #if RBU_ENABLE_DELTA_CKSUM + char *zOrigOut = zOut; + #endif + + limit = rbuDeltaGetInt(&zDelta, &lenDelta); +- if( *zDelta!='\n' ){ ++ if( lenDelta<=0 || *zDelta!='\n' ){ + /* ERROR: size integer not terminated by "\n" */ + return -1; + } +- zDelta++; lenDelta--; +- while( *zDelta && lenDelta>0 ){ ++ zDelta++; lenDelta--; /* Skip the \n */ ++ while( lenDelta>0 && zDelta[0] ){ + unsigned int cnt, ofst; + cnt = rbuDeltaGetInt(&zDelta, &lenDelta); ++ if( lenDelta<=0 ) return -1; + switch( zDelta[0] ){ + case '@': { + zDelta++; lenDelta--; +@@ -224203,7 +226963,7 @@ static int rbuDeltaApply( + /* ERROR: insert command gives an output larger than predicted */ + return -1; + } +- if( (int)cnt>lenDelta ){ ++ if( cnt>lenDelta ){ + /* ERROR: insert count exceeds size of delta */ + return -1; + } +@@ -224241,7 +227001,7 @@ static int rbuDeltaApply( + static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ + int size; + size = rbuDeltaGetInt(&zDelta, &lenDelta); +- if( *zDelta!='\n' ){ ++ if( lenDelta<=0 || *zDelta!='\n' ){ + /* ERROR: size integer not terminated by "\n" */ + return -1; + } +@@ -224289,7 +227049,7 @@ static void rbuFossilDeltaFunc( + return; + } + +- aOut = sqlite3_malloc(nOut+1); ++ aOut = sqlite3_malloc64((i64)nOut+1); + if( aOut==0 ){ + sqlite3_result_error_nomem(context); + }else{ +@@ -225834,8 +228594,8 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ + + /* If necessary, grow the pIter->aIdxCol[] array */ + if( iIdxCol==nIdxAlloc ){ +- RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc( +- pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan) ++ RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc64( ++ pIter->aIdxCol, nIdxAlloc*sizeof(RbuSpan) + 16*sizeof(RbuSpan) + ); + if( aIdxCol==0 ){ + rc = SQLITE_NOMEM; +@@ -226216,13 +228976,13 @@ static int rbuGetUpdateStmt( + 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 = ""; +- ++ assert( p->rc==SQLITE_OK ); ++ memcpy(pUp->zMask, zMask, pIter->nTblCol); + if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; + zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", + zPrefix, pIter->zTbl, zSet, zWhere +@@ -226312,6 +229072,9 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ + + case RBU_STATE_ROW: + pRet->nRow = sqlite3_column_int(pStmt, 1); ++ if( pRet->nRow<0 ){ ++ rc = SQLITE_CORRUPT; ++ } + break; + + case RBU_STATE_PROGRESS: +@@ -230183,12 +232946,13 @@ static int dbpageFilter( + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->mxPgno = sqlite3BtreeLastPage(pBt); + if( idxNum & 1 ){ ++ i64 iPg = sqlite3_value_int64(argv[idxNum>>1]); + assert( argc>(idxNum>>1) ); +- pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); +- if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ ++ if( iPg<1 || iPg>pCsr->mxPgno ){ + pCsr->pgno = 1; + pCsr->mxPgno = 0; + }else{ ++ pCsr->pgno = (Pgno)iPg; + pCsr->mxPgno = pCsr->pgno; + } + }else{ +@@ -230508,6 +233272,7 @@ struct carray_bind { + int nData; /* Number of elements */ + int mFlags; /* Control flags */ + void (*xDel)(void*); /* Destructor for aData */ ++ void *pDel; /* Alternative argument to xDel() */ + }; + + +@@ -230840,7 +233605,7 @@ static sqlite3_module carrayModule = { + static void carrayBindDel(void *pPtr){ + carray_bind *p = (carray_bind*)pPtr; + if( p->xDel!=SQLITE_STATIC ){ +- p->xDel(p->aData); ++ p->xDel(p->pDel); + } + sqlite3_free(p); + } +@@ -230848,14 +233613,26 @@ static void carrayBindDel(void *pPtr){ + /* + ** Invoke this interface in order to bind to the single-argument + ** version of CARRAY(). ++** ++** pStmt The prepared statement to which to bind ++** idx The index of the parameter of pStmt to which to bind ++** aData The data to be bound ++** nData The number of elements in aData ++** mFlags One of SQLITE_CARRAY_xxxx indicating datatype of aData ++** xDestroy Destructor for pDestroy or aData if pDestroy==NULL. ++** pDestroy Invoke xDestroy on this pointer if not NULL ++** ++** The destructor is called pDestroy if pDestroy!=NULL, or against ++** aData if pDestroy==NULL. + */ +-SQLITE_API int sqlite3_carray_bind( ++SQLITE_API int sqlite3_carray_bind_v2( + sqlite3_stmt *pStmt, + int idx, + void *aData, + int nData, + int mFlags, +- void (*xDestroy)(void*) ++ void (*xDestroy)(void*), ++ void *pDestroy + ){ + carray_bind *pNew = 0; + int i; +@@ -230932,20 +233709,38 @@ SQLITE_API int sqlite3_carray_bind( + memcpy(pNew->aData, aData, sz); + } + pNew->xDel = sqlite3_free; ++ pNew->pDel = pNew->aData; + }else{ + pNew->aData = aData; + pNew->xDel = xDestroy; ++ pNew->pDel = pDestroy; + } + return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel); + + carray_bind_error: + if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){ +- xDestroy(aData); ++ xDestroy(pDestroy); + } + sqlite3_free(pNew); + return rc; + } + ++/* ++** Invoke this interface in order to bind to the single-argument ++** version of CARRAY(). Same as sqlite3_carray_bind_v2() with the ++** pDestroy parameter set to NULL. ++*/ ++SQLITE_API int sqlite3_carray_bind( ++ sqlite3_stmt *pStmt, ++ int idx, ++ void *aData, ++ int nData, ++ int mFlags, ++ void (*xDestroy)(void*) ++){ ++ return sqlite3_carray_bind_v2(pStmt,idx,aData,nData,mFlags,xDestroy,aData); ++} ++ + /* + ** Invoke this routine to register the carray() function. + */ +@@ -231308,6 +234103,21 @@ static int sessionVarintGet(const u8 *aBuf, int *piVal){ + return getVarint32(aBuf, *piVal); + } + ++/* ++** Read a varint value from buffer aBuf[], size nBuf bytes, into *piVal. ++** Return the number of bytes read. ++*/ ++static int sessionVarintGetSafe(const u8 *aBuf, int nBuf, int *piVal){ ++ u8 aCopy[9]; ++ const u8 *aRead = aBuf; ++ memset(aCopy, 0, sizeof(aCopy)); ++ if( nBuf> 0) & 0xFF; + } + ++/* ++** Write a double value to the buffer aBuf[]. ++*/ ++static void sessionPutDouble(u8 *aBuf, double r){ ++ /* TODO: SQLite does something special to deal with mixed-endian ++ ** floating point values (e.g. ARM7). This code probably should ++ ** too. */ ++ u64 i; ++ assert( sizeof(double)==8 && sizeof(u64)==8 ); ++ memcpy(&i, &r, 8); ++ sessionPutI64(aBuf, i); ++} ++ + /* + ** This function is used to serialize the contents of value pValue (see + ** comment titled "RECORD FORMAT" above). +@@ -231373,16 +234196,13 @@ static int sessionSerializeValue( + /* TODO: SQLite does something special to deal with mixed-endian + ** floating point values (e.g. ARM7). This code probably should + ** too. */ +- u64 i; + if( eType==SQLITE_INTEGER ){ +- i = (u64)sqlite3_value_int64(pValue); ++ u64 i = (u64)sqlite3_value_int64(pValue); ++ sessionPutI64(&aBuf[1], i); + }else{ +- double r; +- assert( sizeof(double)==8 && sizeof(u64)==8 ); +- r = sqlite3_value_double(pValue); +- memcpy(&i, &r, 8); ++ double r = sqlite3_value_double(pValue); ++ sessionPutDouble(&aBuf[1], r); + } +- sessionPutI64(&aBuf[1], i); + } + nByte = 9; + break; +@@ -231572,10 +234392,11 @@ static int sessionSerialLen(const u8 *a){ + int n; + assert( a!=0 ); + e = *a; +- if( e==0 || e==0xFF ) return 1; +- if( e==SQLITE_NULL ) return 1; + if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; +- return sessionVarintGet(&a[1], &n) + 1 + n; ++ if( e==SQLITE_TEXT || e==SQLITE_BLOB ){ ++ return sessionVarintGet(&a[1], &n) + 1 + n; ++ } ++ return 1; + } + + /* +@@ -231598,31 +234419,31 @@ static unsigned int sessionChangeHash( + u8 *a = aRecord; /* Used to iterate through change record */ + + for(i=0; inCol; i++){ +- int eType = *a; + int isPK = pTab->abPK[i]; + if( bPkOnly && isPK==0 ) continue; + +- /* It is not possible for eType to be SQLITE_NULL here. The session +- ** module does not record changes for rows with NULL values stored in +- ** primary key columns. */ +- assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT +- || eType==SQLITE_TEXT || eType==SQLITE_BLOB +- || eType==SQLITE_NULL || eType==0 +- ); +- assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) ); +- + if( isPK ){ +- a++; ++ int eType = *a++; ++ ++ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ++ || eType==SQLITE_TEXT || eType==SQLITE_BLOB ++ || eType==SQLITE_NULL || eType==0 ++ ); ++ + h = sessionHashAppendType(h, eType); + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + h = sessionHashAppendI64(h, sessionGetI64(a)); + a += 8; +- }else{ ++ }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + int n; + a += sessionVarintGet(a, &n); + h = sessionHashAppendBlob(h, n, a); + a += n; + } ++ /* It should not be possible for eType to be SQLITE_NULL or 0x00 here, ++ ** as the session module does not record changes for rows with NULL ++ ** values stored in primary key columns. But a corrupt changesets ++ ** may contain such a value. */ + }else{ + a += sessionSerialLen(a); + } +@@ -232314,9 +235135,7 @@ static void sessionUpdateOneChange( + + case SQLITE_FLOAT: { + double rVal = sqlite3_column_double(pDflt, iField); +- i64 iVal = 0; +- memcpy(&iVal, &rVal, sizeof(rVal)); +- sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); ++ sessionPutDouble(&pNew->aRecord[pNew->nRecord], rVal); + pNew->nRecord += 8; + break; + } +@@ -232412,7 +235231,7 @@ static void sessionAppendStr( + int *pRc + ){ + int nStr = sqlite3Strlen30(zStr); +- if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ ++ if( 0==sessionBufferGrow(p, (i64)nStr+1, pRc) ){ + memcpy(&p->aBuf[p->nBuf], zStr, nStr); + p->nBuf += nStr; + p->aBuf[p->nBuf] = 0x00; +@@ -232480,6 +235299,16 @@ static int sessionPrepareDfltStmt( + return rc; + } + ++/* ++** Finalize statement pStmt. If (*pRc) is SQLITE_OK when this function is ++** called, set it to the results of the sqlite3_finalize() call. Or, if ++** it is already set to an error code, leave it as is. ++*/ ++static void sessionFinalizeStmt(sqlite3_stmt *pStmt, int *pRc){ ++ int rc = sqlite3_finalize(pStmt); ++ if( *pRc==SQLITE_OK ) *pRc = rc; ++} ++ + /* + ** Table pTab has one or more existing change-records with old.* records + ** with fewer than pTab->nCol columns. This function updates all such +@@ -232502,9 +235331,8 @@ static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){ + } + } + ++ sessionFinalizeStmt(pStmt, &rc); + pSession->rc = rc; +- rc = sqlite3_finalize(pStmt); +- if( pSession->rc==SQLITE_OK ) pSession->rc = rc; + return pSession->rc; + } + +@@ -233072,7 +235900,7 @@ static int sessionDiffFindNew( + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pStmt; +- rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); ++ rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; + pDiffCtx->pStmt = pStmt; +@@ -233135,7 +235963,7 @@ static int sessionDiffFindModified( + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pStmt; +- rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); ++ rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0); + + if( rc==SQLITE_OK ){ + SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; +@@ -233573,15 +236401,14 @@ static void sessionAppendCol( + int eType = sqlite3_column_type(pStmt, iCol); + sessionAppendByte(p, (u8)eType, pRc); + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ +- sqlite3_int64 i; + u8 aBuf[8]; + if( eType==SQLITE_INTEGER ){ +- i = sqlite3_column_int64(pStmt, iCol); ++ sqlite3_int64 i = sqlite3_column_int64(pStmt, iCol); ++ sessionPutI64(aBuf, i); + }else{ + double r = sqlite3_column_double(pStmt, iCol); +- memcpy(&i, &r, 8); ++ sessionPutDouble(aBuf, r); + } +- sessionPutI64(aBuf, i); + sessionAppendBlob(p, aBuf, 8, pRc); + } + if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ +@@ -233831,11 +236658,11 @@ static int sessionSelectStmt( + ); + sessionAppendStr(&cols, "tbl, ?2, stat", &rc); + }else{ +- #if 0 ++#if 0 + if( bRowid ){ + sessionAppendStr(&cols, SESSIONS_ROWID, &rc); + } +- #endif ++#endif + for(i=0; irc ) return pSession->rc; +- rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); +- if( rc!=SQLITE_OK ) return rc; + + sqlite3_mutex_enter(sqlite3_db_mutex(db)); ++ rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); ++ if( rc!=SQLITE_OK ){ ++ sqlite3_mutex_leave(sqlite3_db_mutex(db)); ++ return rc; ++ } + + for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ + if( pTab->nEntry ){ +@@ -234517,7 +237347,8 @@ static int sessionReadRecord( + u8 *aVal = &pIn->aData[pIn->iNext]; + if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + int nByte; +- pIn->iNext += sessionVarintGet(aVal, &nByte); ++ int nRem = pIn->nData - pIn->iNext; ++ pIn->iNext += sessionVarintGetSafe(aVal, nRem, &nByte); + rc = sessionInputBuffer(pIn, nByte); + if( rc==SQLITE_OK ){ + if( nByte<0 || nByte>pIn->nData-pIn->iNext ){ +@@ -234570,7 +237401,8 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ + + rc = sessionInputBuffer(pIn, 9); + if( rc==SQLITE_OK ){ +- nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol); ++ int nBuf = pIn->nData - pIn->iNext; ++ nRead += sessionVarintGetSafe(&pIn->aData[pIn->iNext], nBuf, &nCol); + /* The hard upper limit for the number of columns in an SQLite + ** database table is, according to sqliteLimit.h, 32676. So + ** consider any table-header that purports to have more than 65536 +@@ -234590,8 +237422,15 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ + while( (pIn->iNext + nRead)nData && pIn->aData[pIn->iNext + nRead] ){ + nRead++; + } ++ ++ /* Break out of the loop if if the nul-terminator byte has been found. ++ ** Otherwise, read some more input data and keep seeking. If there is ++ ** no more input data, consider the changeset corrupt. */ + if( (pIn->iNext + nRead)nData ) break; + rc = sessionInputBuffer(pIn, nRead + 100); ++ if( rc==SQLITE_OK && (pIn->iNext + nRead)>=pIn->nData ){ ++ rc = SQLITE_CORRUPT_BKPT; ++ } + } + *pnByte = nRead+1; + return rc; +@@ -234612,7 +237451,7 @@ static int sessionChangesetBufferRecord( + int *pnByte /* OUT: Size of record in bytes */ + ){ + int rc = SQLITE_OK; +- int nByte = 0; ++ i64 nByte = 0; + int i; + for(i=0; rc==SQLITE_OK && iaData[pIn->iNext + nByte++]; + if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + int n; +- nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n); ++ int nRem = pIn->nData - (pIn->iNext + nByte); ++ nByte += sessionVarintGetSafe(&pIn->aData[pIn->iNext+nByte], nRem, &n); + nByte += n; + rc = sessionInputBuffer(pIn, nByte); + }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + nByte += 8; ++ }else if( eType!=0 && eType!=SQLITE_NULL ){ ++ rc = SQLITE_CORRUPT_BKPT; + } + } ++ if( rc==SQLITE_OK && (pIn->iNext+nByte)>pIn->nData ){ ++ rc = SQLITE_CORRUPT_BKPT; ++ } + } + *pnByte = nByte; + return rc; +@@ -234723,10 +237568,10 @@ static int sessionChangesetNextOne( + memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); + } + +- /* Make sure the buffer contains at least 10 bytes of input data, or all +- ** remaining data if there are less than 10 bytes available. This is +- ** sufficient either for the 'T' or 'P' byte and the varint that follows +- ** it, or for the two single byte values otherwise. */ ++ /* Make sure the buffer contains at least 2 bytes of input data, or all ++ ** remaining data if there are less than 2 bytes available. This is ++ ** sufficient either for the 'T' or 'P' byte that begins a new table, ++ ** or for the "op" and "bIndirect" single bytes otherwise. */ + p->rc = sessionInputBuffer(&p->in, 2); + if( p->rc!=SQLITE_OK ) return p->rc; + +@@ -234756,11 +237601,13 @@ static int sessionChangesetNextOne( + return (p->rc = SQLITE_CORRUPT_BKPT); + } + +- p->op = op; +- p->bIndirect = p->in.aData[p->in.iNext++]; +- if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ ++ if( (op!=SQLITE_UPDATE && op!=SQLITE_DELETE && op!=SQLITE_INSERT) ++ || (p->in.iNext>=p->in.nData) ++ ){ + return (p->rc = SQLITE_CORRUPT_BKPT); + } ++ p->op = op; ++ p->bIndirect = p->in.aData[p->in.iNext++]; + + if( paRec ){ + int nVal; /* Number of values to buffer */ +@@ -235069,7 +237916,13 @@ static int sessionChangesetInvert( + + /* Test for EOF. */ + if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert; +- if( pInput->iNext>=pInput->nData ) break; ++ if( pInput->iNext+1>=pInput->nData ){ ++ if( pInput->iNext!=pInput->nData ){ ++ rc = SQLITE_CORRUPT_BKPT; ++ goto finished_invert; ++ } ++ break; ++ } + eType = pInput->aData[pInput->iNext]; + + switch( eType ){ +@@ -235265,6 +238118,7 @@ struct SessionApplyCtx { + u8 bRebaseStarted; /* If table header is already in rebase */ + u8 bRebase; /* True to collect rebase information */ + u8 bIgnoreNoop; /* True to ignore no-op conflicts */ ++ u8 bNoUpdateLoop; /* No update-loop processing */ + int bRowid; + char *zErr; /* Error message, if any */ + }; +@@ -235838,7 +238692,7 @@ static int sessionConflictHandler( + u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent]; + int nBlob = pIter->in.iNext - pIter->in.iCurrent; + sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc); +- return SQLITE_OK; ++ return rc; + }else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE + || eType==SQLITE_CHANGESET_CONFLICT + ){ +@@ -235960,7 +238814,7 @@ static int sessionApplyOneOp( + for(i=0; rc==SQLITE_OK && iabPK[i] || (bPatchset==0 && pOld) ){ ++ if( pOld && (p->abPK[i] || bPatchset==0) ){ + rc = sessionBindValue(pUp, i*2+2, pOld); + } + if( rc==SQLITE_OK && pNew ){ +@@ -236086,7 +238940,264 @@ static int sessionApplyOneWithRetry( + } + + /* +-** Retry the changes accumulated in the pApply->constraints buffer. ++** Create an iterator to iterate through the retry buffer pRetry. ++*/ ++static int sessionRetryIterInit( ++ SessionBuffer *pRetry, /* Buffer to iterate through */ ++ int bPatchset, /* True for patchset, false for changeset */ ++ const char *zTab, /* Table name */ ++ SessionApplyCtx *pApply, /* Session apply context */ ++ sqlite3_changeset_iter **ppIter /* OUT: New iterator */ ++){ ++ sqlite3_changeset_iter *pRet = 0; ++ int rc = SQLITE_OK; ++ ++ rc = sessionChangesetStart( ++ &pRet, 0, 0, pRetry->nBuf, pRetry->aBuf, pApply->bInvertConstraints, 1 ++ ); ++ if( rc==SQLITE_OK ){ ++ size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); ++ pRet->bPatchset = bPatchset; ++ pRet->zTab = (char*)zTab; ++ pRet->nCol = pApply->nCol; ++ pRet->abPK = pApply->abPK; ++ sessionBufferGrow(&pRet->tblhdr, nByte, &rc); ++ pRet->apValue = (sqlite3_value**)pRet->tblhdr.aBuf; ++ if( rc==SQLITE_OK ){ ++ memset(pRet->apValue, 0, nByte); ++ }else{ ++ sqlite3changeset_finalize(pRet); ++ pRet = 0; ++ } ++ } ++ ++ *ppIter = pRet; ++ return rc; ++} ++ ++/* ++** Attempt to apply all the changes in retry buffer pRetry to the database. ++** Except, if parameter iSkip is greater than or equal to 0, skip change ++** iSkip. ++*/ ++static int sessionApplyRetryBuffer( ++ SessionBuffer *pRetry, /* Buffer to apply changes from */ ++ int iSkip, /* If >=0, index of change to omit */ ++ sqlite3 *db, /* Database handle */ ++ int bPatchset, /* True for patchset, false for changeset */ ++ const char *zTab, /* Name of table to write to */ ++ SessionApplyCtx *pApply, /* Apply context */ ++ int(*xConflict)(void*, int, sqlite3_changeset_iter*), ++ void *pCtx /* First argument passed to xConflict */ ++){ ++ int rc = SQLITE_OK; ++ int rc2 = SQLITE_OK; ++ int ii = 0; ++ sqlite3_changeset_iter *pIter = 0; ++ ++ assert( pApply->constraints.nBuf==0 ); ++ ++ rc = sessionRetryIterInit(pRetry, bPatchset, zTab, pApply, &pIter); ++ ++ for(ii=0; rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter); ii++){ ++ if( ii!=iSkip ){ ++ rc = sessionApplyOneWithRetry(db, pIter, pApply, xConflict, pCtx); ++ } ++ } ++ ++ rc2 = sqlite3changeset_finalize(pIter); ++ if( rc==SQLITE_OK ) rc = rc2; ++ assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); ++ ++ return rc; ++} ++ ++/* ++** Check if table zTab in the "main" database of db is a WITHOUT ROWID ++** table. ++** ++** If no error occurs, return SQLITE_OK and set output variable (*pbWR) to ++** true if zTab is a WITHOUT ROWID table, or false otherwise. Or, if an ++** error does occur, return an SQLite error code. The final value of (*pbWR) ++** is undefined in this case. ++*/ ++static int sessionTableIsWithoutRowid(sqlite3 *db, const char *zTab, int *pbWR){ ++ sqlite3_stmt *pList = 0; ++ char *zSql = 0; ++ int rc = SQLITE_OK; ++ ++ zSql = sqlite3_mprintf("PRAGMA table_list = %Q", zTab); ++ if( zSql==0 ){ ++ rc = SQLITE_NOMEM; ++ }else{ ++ rc = sqlite3_prepare_v2(db, zSql, -1, &pList, 0); ++ sqlite3_free(zSql); ++ } ++ ++ if( rc==SQLITE_OK ){ ++ sqlite3_step(pList); ++ *pbWR = sqlite3_column_int(pList, 4); ++ rc = sqlite3_finalize(pList); ++ } ++ ++ return rc; ++} ++ ++/* ++** Iterator pUp points to an UPDATE change. This function deletes the ++** affected row from the database and creates an INSERT statement that ++** may be used to reinsert the row as it is after the UPDATE change ++** has been applied. ++** ++** If successful, SQLITE_OK is returned and output variable (*ppInsert) ++** is left pointing to a prepared INSERT statement. It is the responsibility ++** of the caller to eventually free this statement using sqlite3_finalize(). ++** Or, if an error occurs, an SQLite error code is returned and (*ppInsert) ++** set to NULL. pApply->zErr may be set to an error message in this case. ++*/ ++static int sessionUpdateToDeleteInsert( ++ sqlite3 *db, /* Database to write to */ ++ const char *zTab, /* Table name */ ++ SessionApplyCtx *pApply, /* Apply context */ ++ sqlite3_changeset_iter *pUp, /* Iterator pointing to UPDATE change */ ++ sqlite3_stmt **ppInsert /* OUT: INSERT statement */ ++){ ++ sqlite3_stmt *pRet = 0; /* The INSERT statement */ ++ sqlite3_stmt *pSelect = 0; /* SELECT to read current values of row */ ++ int rc = SQLITE_OK; ++ int bWR = 0; ++ ++ rc = sessionTableIsWithoutRowid(db, zTab, &bWR); ++ if( rc==SQLITE_OK ){ ++ char *zSelect = 0; ++ char *zInsert = 0; ++ SessionBuffer cols = {0, 0, 0}; ++ SessionBuffer insbind = {0, 0, 0}; ++ SessionBuffer pkcols = {0, 0, 0}; ++ SessionBuffer selbind = {0, 0, 0}; ++ ++ const char *zComma = ""; ++ const char *zComma2 = ""; ++ int ii; ++ for(ii=0; iinCol; ii++){ ++ sessionAppendStr(&cols, zComma, &rc); ++ sessionAppendIdent(&cols, pApply->azCol[ii], &rc); ++ sessionAppendStr(&insbind, zComma, &rc); ++ sessionAppendStr(&insbind, "?", &rc); ++ zComma = ", "; ++ ++ if( pApply->abPK[ii] ){ ++ sessionAppendStr(&pkcols, zComma2, &rc); ++ sessionAppendIdent(&pkcols, pApply->azCol[ii], &rc); ++ sessionAppendStr(&selbind, zComma2, &rc); ++ sessionAppendPrintf(&selbind, &rc, "?%d", ii+1); ++ zComma2 = ", "; ++ } ++ } ++ if( bWR==0 ){ ++ sessionAppendStr(&cols, zComma, &rc); ++ sessionAppendStr(&cols, SESSIONS_ROWID, &rc); ++ sessionAppendStr(&insbind, zComma, &rc); ++ sessionAppendStr(&insbind, "?", &rc); ++ } ++ ++ if( rc==SQLITE_OK ){ ++ zSelect = sqlite3_mprintf("SELECT %s FROM %Q WHERE (%s) IS (%s)", ++ cols.aBuf, zTab, pkcols.aBuf, selbind.aBuf ++ ); ++ if( zSelect==0 ) rc = SQLITE_NOMEM; ++ } ++ if( rc==SQLITE_OK ){ ++ zInsert = sqlite3_mprintf("INSERT INTO %Q(%s) VALUES(%s)", ++ zTab, cols.aBuf, insbind.aBuf ++ ); ++ if( zInsert==0 ) rc = SQLITE_NOMEM; ++ } ++ ++ if( rc==SQLITE_OK ){ ++ rc = sessionPrepare(db, &pSelect, &pApply->zErr, zSelect); ++ } ++ if( rc==SQLITE_OK ){ ++ rc = sessionPrepare(db, &pRet, &pApply->zErr, zInsert); ++ } ++ ++ sqlite3_free(zSelect); ++ sqlite3_free(zInsert); ++ sqlite3_free(cols.aBuf); ++ sqlite3_free(insbind.aBuf); ++ sqlite3_free(pkcols.aBuf); ++ sqlite3_free(selbind.aBuf); ++ } ++ ++ if( rc==SQLITE_OK ){ ++ rc = sessionBindRow( ++ pUp, sqlite3changeset_old, pApply->nCol, pApply->abPK, pSelect ++ ); ++ } ++ ++ if( rc==SQLITE_OK && sqlite3_step(pSelect)==SQLITE_ROW ){ ++ int iCol; ++ for(iCol=0; iColnCol; iCol++){ ++ sqlite3_value *pVal = pUp->apValue[iCol+pApply->nCol]; ++ if( pVal==0 ){ ++ pVal = sqlite3_column_value(pSelect, iCol); ++ } ++ rc = sqlite3_bind_value(pRet, iCol+1, pVal); ++ } ++ if( bWR==0 ){ ++ sqlite3_bind_int64(pRet, iCol+1, sqlite3_column_int64(pSelect, iCol)); ++ } ++ } ++ sessionFinalizeStmt(pSelect, &rc); ++ ++ /* Delete the row from the database. */ ++ if( rc==SQLITE_OK ){ ++ rc = sessionBindRow( ++ pUp, sqlite3changeset_old, pApply->nCol, pApply->abPK, pApply->pDelete ++ ); ++ sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); ++ } ++ if( rc==SQLITE_OK ){ ++ sqlite3_step(pApply->pDelete); ++ rc = sqlite3_reset(pApply->pDelete); ++ } ++ ++ if( rc!=SQLITE_OK ){ ++ sqlite3_finalize(pRet); ++ pRet = 0; ++ } ++ ++ *ppInsert = pRet; ++ return rc; ++} ++ ++/* ++** Retry the changes accumulated in the pApply->constraints buffer. The ++** pApply->constraints buffer contains all changes to table zTab that ++** could not be applied due to SQLITE_CONSTRAINT errors. This function ++** attempts to apply them as follows: ++** ++** 1) It runs through the buffer and attempts to retry each change, ++** removing any that are successfully applied from the buffer. This ++** is repeated until no further progress can be made. ++** ++** 2) For each UPDATE change in the buffer, try the following in a ++** savepoint transaction: ++** ++** a) DELETE the affected row, ++** b) Attempt step (1) with remaining changes, ++** c) Attempt to INSERT a row equivalent to the one that would be ++** created by applying this UPDATE change. ++** ++** If the INSERT in (c) succeeds, the savepoint is committed and all ++** successfully applied changes are removed from the buffer. Step (2) ++** is then repeated. ++** ++** 3) Once step (2) has been attempted for each UPDATE in the change, ++** a final attempt is made to apply each remaining change. This time, ++** if an SQLITE_CONSTRAINT error is encountered, the conflict handler ++** is invoked and the user has to decide whether to omit the change ++** or rollback the entire _apply() operation. + */ + static int sessionRetryConstraints( + sqlite3 *db, +@@ -236097,41 +239208,101 @@ static int sessionRetryConstraints( + void *pCtx /* First argument passed to xConflict */ + ){ + int rc = SQLITE_OK; ++ int iUpdate = 0; + ++ /* Step (1) */ + while( pApply->constraints.nBuf ){ +- sqlite3_changeset_iter *pIter2 = 0; + SessionBuffer cons = pApply->constraints; + memset(&pApply->constraints, 0, sizeof(SessionBuffer)); + +- rc = sessionChangesetStart( +- &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1 ++ rc = sessionApplyRetryBuffer( ++ &cons, -1, db, bPatchset, zTab, pApply, xConflict, pCtx ++ ); ++ ++ sqlite3_free(cons.aBuf); ++ if( rc!=SQLITE_OK ) break; ++ ++ /* If no progress has been made this round, break out of the loop. */ ++ if( pApply->constraints.nBuf>=cons.nBuf ) break; ++ } ++ ++ /* Step (2) */ ++ while( rc==SQLITE_OK && pApply->constraints.nBuf && !pApply->bNoUpdateLoop ){ ++ SessionBuffer cons = {0, 0, 0}; ++ sqlite3_changeset_iter *pUp = 0; ++ sqlite3_stmt *pInsert = 0; ++ int iSkip = 0; ++ ++ rc = sessionRetryIterInit( ++ &pApply->constraints, bPatchset, zTab, pApply, &pUp + ); + if( rc==SQLITE_OK ){ +- size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); +- int rc2; +- pIter2->bPatchset = bPatchset; +- pIter2->zTab = (char*)zTab; +- pIter2->nCol = pApply->nCol; +- pIter2->abPK = pApply->abPK; +- sessionBufferGrow(&pIter2->tblhdr, nByte, &rc); +- pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf; +- if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte); ++ int iThis = -1; ++ while( SQLITE_ROW==sqlite3changeset_next(pUp) ){ ++ if( pUp->op==SQLITE_UPDATE ) iThis++; ++ if( iThis==iUpdate ) break; ++ iSkip++; ++ } ++ if( iThis==iUpdate ){ ++ rc = sqlite3_exec(db, "SAVEPOINT update_op", 0, 0, 0); ++ if( rc==SQLITE_OK ){ ++ rc = sessionUpdateToDeleteInsert(db, zTab, pApply, pUp, &pInsert); ++ } ++ } ++ sqlite3changeset_finalize(pUp); ++ if( iThis!=iUpdate ) break; ++ } + +- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){ +- rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx); ++ if( rc==SQLITE_OK ){ ++ cons = pApply->constraints; ++ ++ while( rc==SQLITE_OK && pApply->constraints.nBuf>0 ){ ++ SessionBuffer app = pApply->constraints; ++ memset(&pApply->constraints, 0, sizeof(SessionBuffer)); ++ rc = sessionApplyRetryBuffer( ++ &app, iSkip, db, bPatchset, zTab, pApply, xConflict, pCtx ++ ); ++ if( app.aBuf!=cons.aBuf ){ ++ sqlite3_free(app.aBuf); ++ } ++ if( pApply->constraints.nBuf>=app.nBuf ){ ++ break; ++ } ++ iSkip = -1; + } ++ } + +- rc2 = sqlite3changeset_finalize(pIter2); +- if( rc==SQLITE_OK ) rc = rc2; ++ iUpdate++; ++ if( rc==SQLITE_OK ){ ++ sqlite3_step(pInsert); ++ rc = sqlite3_finalize(pInsert); ++ if( rc==SQLITE_CONSTRAINT ){ ++ rc = sqlite3_exec(db, "ROLLBACK TO update_op", 0, 0, 0); ++ sqlite3_free(pApply->constraints.aBuf); ++ pApply->constraints = cons; ++ memset(&cons, 0, sizeof(cons)); ++ }else if( rc==SQLITE_OK ){ ++ iUpdate = 0; ++ } ++ if( rc==SQLITE_OK ){ ++ rc = sqlite3_exec(db, "RELEASE update_op", 0, 0, 0); ++ } ++ }else{ ++ sqlite3_finalize(pInsert); + } +- assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); + + sqlite3_free(cons.aBuf); +- if( rc!=SQLITE_OK ) break; +- if( pApply->constraints.nBuf>=cons.nBuf ){ +- /* No progress was made on the last round. */ +- pApply->bDeferConstraints = 0; +- } ++ } ++ ++ /* Step (3) */ ++ if( rc==SQLITE_OK && pApply->constraints.nBuf ){ ++ SessionBuffer cons = pApply->constraints; ++ memset(&pApply->constraints, 0, sizeof(SessionBuffer)); ++ pApply->bDeferConstraints = 0; ++ rc = sessionApplyRetryBuffer( ++ &cons, -1, db, bPatchset, zTab, pApply, xConflict, pCtx ++ ); ++ sqlite3_free(cons.aBuf); + } + + return rc; +@@ -236185,6 +239356,7 @@ static int sessionChangesetApply( + sApply.bRebase = (ppRebase && pnRebase); + sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); ++ sApply.bNoUpdateLoop = !!(flags & SQLITE_CHANGESETAPPLY_NOUPDATELOOP); + if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ + rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + } +@@ -236608,6 +239780,21 @@ SQLITE_API int sqlite3changeset_apply_strm( + ); + } + ++/* ++** The parts of the sqlite3_changegroup structure used by the ++** sqlite3changegroup_change_xxx() APIs. ++*/ ++typedef struct ChangeData ChangeData; ++struct ChangeData { ++ SessionTable *pTab; ++ int bIndirect; ++ int eOp; ++ ++ int nBufAlloc; ++ SessionBuffer *aBuf; ++ SessionBuffer record; ++}; ++ + /* + ** sqlite3_changegroup handle. + */ +@@ -236619,12 +239806,17 @@ struct sqlite3_changegroup { + + sqlite3 *db; /* Configured by changegroup_schema() */ + char *zDb; /* Configured by changegroup_schema() */ ++ ChangeData cd; /* Used by changegroup_change_xxx() APIs. */ + }; + + /* + ** This function is called to merge two changes to the same row together as + ** part of an sqlite3changeset_concat() operation. A new change object is + ** allocated and a pointer to it stored in *ppNew. ++** ++** Because they have been vetted by sqlite3changegroup_add() or similar, ++** both the aRec[] change and the pExist change are safe to use without ++** checking for buffer overflows. + */ + static int sessionChangeMerge( + SessionTable *pTab, /* Table structure */ +@@ -236765,7 +239957,7 @@ static int sessionChangeMerge( + memcpy(aCsr, aRec, nRec); + aCsr += nRec; + }else{ +- if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){ ++ if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist,0,aRec,0) ){ + sqlite3_free(pNew); + pNew = 0; + } +@@ -236858,15 +240050,14 @@ static int sessionChangesetExtendRecord( + switch( eType ){ + case SQLITE_FLOAT: + case SQLITE_INTEGER: { +- i64 iVal; +- if( eType==SQLITE_INTEGER ){ +- iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); +- }else{ +- double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); +- memcpy(&iVal, &rVal, sizeof(i64)); +- } + if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ +- sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); ++ if( eType==SQLITE_INTEGER ){ ++ sqlite3_int64 iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); ++ sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); ++ }else{ ++ double rVal = sqlite3_column_double(pTab->pDfltStmt, ii); ++ sessionPutDouble(&pOut->aBuf[pOut->nBuf], rVal); ++ } + pOut->nBuf += 8; + } + break; +@@ -236937,13 +240128,19 @@ static int sessionChangesetFindTable( + int nCol = 0; + + *ppTab = 0; +- sqlite3changeset_pk(pIter, &abPK, &nCol); + + /* Search the list for an existing table */ + for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zTab, nTab+1) ) break; + } + ++ ++ if( pIter ){ ++ sqlite3changeset_pk(pIter, &abPK, &nCol); ++ }else if( !pTab && !pGrp->db ){ ++ return SQLITE_OK; ++ } ++ + /* If one was not found above, create a new table now */ + if( !pTab ){ + SessionTable **ppNew; +@@ -236955,15 +240152,17 @@ static int sessionChangesetFindTable( + memset(pTab, 0, sizeof(SessionTable)); + pTab->nCol = nCol; + pTab->abPK = (u8*)&pTab[1]; +- memcpy(pTab->abPK, abPK, nCol); ++ if( nCol>0 ){ ++ memcpy(pTab->abPK, abPK, nCol); ++ } + pTab->zName = (char*)&pTab->abPK[nCol]; + memcpy(pTab->zName, zTab, nTab+1); + + if( pGrp->db ){ + pTab->nCol = 0; + rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); +- if( rc ){ +- assert( pTab->azCol==0 ); ++ if( rc || pTab->nCol==0 ){ ++ sqlite3_free(pTab->azCol); + sqlite3_free(pTab); + return rc; + } +@@ -236978,7 +240177,7 @@ static int sessionChangesetFindTable( + } + + /* Check that the table is compatible. */ +- if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ ++ if( pIter && !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ + rc = SQLITE_SCHEMA; + } + +@@ -236987,44 +240186,27 @@ static int sessionChangesetFindTable( + } + + /* +-** Add the change currently indicated by iterator pIter to the hash table +-** belonging to changegroup pGrp. ++** Add a single change to the changegroup pGrp. + */ + static int sessionOneChangeToHash( +- sqlite3_changegroup *pGrp, +- sqlite3_changeset_iter *pIter, +- int bRebase ++ sqlite3_changegroup *pGrp, /* Changegroup to update */ ++ SessionTable *pTab, /* Table change pertains to */ ++ int op, /* One of SQLITE_INSERT, UPDATE, DELETE */ ++ int bIndirect, /* True to flag change as "indirect" */ ++ int nCol, /* Number of columns in record(s) */ ++ u8 *aRec, /* Serialized change record(s) */ ++ int nRec, /* Size of aRec[] in bytes */ ++ int bRebase /* True if this is a rebase blob */ + ){ + int rc = SQLITE_OK; +- int nCol = 0; +- int op = 0; + int iHash = 0; +- int bIndirect = 0; + SessionChange *pChange = 0; + SessionChange *pExist = 0; + SessionChange **pp = 0; +- SessionTable *pTab = 0; +- u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; +- int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; + + assert( nRec>0 ); + +- /* Ensure that only changesets, or only patchsets, but not a mixture +- ** of both, are being combined. It is an error to try to combine a +- ** changeset and a patchset. */ +- if( pGrp->pList==0 ){ +- pGrp->bPatch = pIter->bPatchset; +- }else if( pIter->bPatchset!=pGrp->bPatch ){ +- rc = SQLITE_ERROR; +- } +- +- if( rc==SQLITE_OK ){ +- const char *zTab = 0; +- sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); +- rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); +- } +- +- if( rc==SQLITE_OK && nColnCol ){ ++ if( nColnCol ){ + SessionBuffer *pBuf = &pGrp->rec; + rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, pBuf); + aRec = pBuf->aBuf; +@@ -237032,7 +240214,7 @@ static int sessionOneChangeToHash( + assert( pGrp->db ); + } + +- if( rc==SQLITE_OK && sessionGrowHash(0, pIter->bPatchset, pTab) ){ ++ if( rc==SQLITE_OK && sessionGrowHash(0, pGrp->bPatch, pTab) ){ + rc = SQLITE_NOMEM; + } + +@@ -237040,12 +240222,12 @@ static int sessionOneChangeToHash( + /* Search for existing entry. If found, remove it from the hash table. + ** Code below may link it back in. */ + iHash = sessionChangeHash( +- pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange ++ pTab, (pGrp->bPatch && op==SQLITE_DELETE), aRec, pTab->nChange + ); + for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ + int bPkOnly1 = 0; + int bPkOnly2 = 0; +- if( pIter->bPatchset ){ ++ if( pGrp->bPatch ){ + bPkOnly1 = (*pp)->op==SQLITE_DELETE; + bPkOnly2 = op==SQLITE_DELETE; + } +@@ -237060,7 +240242,7 @@ static int sessionOneChangeToHash( + + if( rc==SQLITE_OK ){ + rc = sessionChangeMerge(pTab, bRebase, +- pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange ++ pGrp->bPatch, pExist, op, bIndirect, aRec, nRec, &pChange + ); + } + if( rc==SQLITE_OK && pChange ){ +@@ -237069,6 +240251,47 @@ static int sessionOneChangeToHash( + pTab->nEntry++; + } + ++ return rc; ++} ++ ++/* ++** Add the change currently indicated by iterator pIter to the hash table ++** belonging to changegroup pGrp. ++*/ ++static int sessionOneChangeIterToHash( ++ sqlite3_changegroup *pGrp, ++ sqlite3_changeset_iter *pIter, ++ int bRebase ++){ ++ u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; ++ int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; ++ const char *zTab = 0; ++ int nCol = 0; ++ int op = 0; ++ int bIndirect = 0; ++ int rc = SQLITE_OK; ++ SessionTable *pTab = 0; ++ ++ /* Ensure that only changesets, or only patchsets, but not a mixture ++ ** of both, are being combined. It is an error to try to combine a ++ ** changeset and a patchset. */ ++ if( pGrp->pList==0 ){ ++ pGrp->bPatch = pIter->bPatchset; ++ }else if( pIter->bPatchset!=pGrp->bPatch ){ ++ rc = SQLITE_ERROR; ++ } ++ ++ if( rc==SQLITE_OK ){ ++ sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); ++ rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); ++ } ++ ++ if( rc==SQLITE_OK ){ ++ rc = sessionOneChangeToHash( ++ pGrp, pTab, op, bIndirect, nCol, aRec, nRec, bRebase ++ ); ++ } ++ + if( rc==SQLITE_OK ) rc = pIter->rc; + return rc; + } +@@ -237088,7 +240311,12 @@ static int sessionChangesetToHash( + + pIter->in.bNoDiscard = 1; + while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ +- rc = sessionOneChangeToHash(pGrp, pIter, bRebase); ++ if( bRebase && pIter->bPatchset ){ ++ /* A patchset may not be used as a rebase */ ++ rc = SQLITE_ERROR; ++ }else{ ++ rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase); ++ } + if( rc!=SQLITE_OK ) break; + } + +@@ -237178,6 +240406,33 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){ + return rc; + } + ++/* ++** Configure a changegroup object. ++*/ ++SQLITE_API int sqlite3changegroup_config( ++ sqlite3_changegroup *pGrp, ++ int op, ++ void *pArg ++){ ++ int rc = SQLITE_OK; ++ ++ switch( op ){ ++ case SQLITE_CHANGEGROUP_CONFIG_PATCHSET: { ++ int arg = *(int*)pArg; ++ if( pGrp->pList==0 && arg>=0 ){ ++ pGrp->bPatch = (arg>0); ++ } ++ *(int*)pArg = pGrp->bPatch; ++ break; ++ } ++ default: ++ rc = SQLITE_MISUSE; ++ break; ++ } ++ ++ return rc; ++} ++ + /* + ** Provide a database schema to the changegroup object. + */ +@@ -237236,7 +240491,7 @@ SQLITE_API int sqlite3changegroup_add_change( + rc = SQLITE_ERROR; + }else{ + pIter->in.bNoDiscard = 1; +- rc = sessionOneChangeToHash(pGrp, pIter, 0); ++ rc = sessionOneChangeIterToHash(pGrp, pIter, 0); + } + return rc; + } +@@ -237288,6 +240543,12 @@ SQLITE_API int sqlite3changegroup_output_strm( + */ + SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ + if( pGrp ){ ++ int ii; ++ for(ii=0; iicd.nBufAlloc; ii++){ ++ sqlite3_free(pGrp->cd.aBuf[ii].aBuf); ++ } ++ sqlite3_free(pGrp->cd.record.aBuf); ++ sqlite3_free(pGrp->cd.aBuf); + sqlite3_free(pGrp->zDb); + sessionDeleteTable(0, pGrp->pList); + sqlite3_free(pGrp->rec.aBuf); +@@ -237373,14 +240634,17 @@ static void sessionAppendRecordMerge( + u8 *a2, int n2, /* Record 2 */ + int *pRc /* IN/OUT: error code */ + ){ +- sessionBufferGrow(pBuf, n1+n2, pRc); ++ u8 *a1Eof = &a1[n1]; ++ u8 *a2Eof = &a2[n2]; ++ ++ sessionBufferGrow(pBuf, (i64)n1+n2, pRc); + if( *pRc==SQLITE_OK ){ + int i; + u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; + for(i=0; i0 && (*a1==0 || *a1==0xFF)) ){ + memcpy(pOut, a2, nn2); + pOut += nn2; + }else{ +@@ -237422,20 +240686,21 @@ static void sessionAppendPartialUpdate( + u8 *aChange, int nChange, /* Record to rebase against */ + int *pRc /* IN/OUT: Return Code */ + ){ +- sessionBufferGrow(pBuf, 2+nRec+nChange, pRc); ++ sessionBufferGrow(pBuf, (i64)2+nRec+nChange, pRc); + if( *pRc==SQLITE_OK ){ + int bData = 0; + u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; + int i; + u8 *a1 = aRec; + u8 *a2 = aChange; ++ u8 *a2Eof = &a2[nChange]; + + *pOut++ = SQLITE_UPDATE; + *pOut++ = pIter->bIndirect; + for(i=0; inCol; i++){ + int n1 = sessionSerialLen(a1); +- int n2 = sessionSerialLen(a2); +- if( pIter->abPK[i] || a2[0]==0 ){ ++ int n2 = (a2>=a2Eof) ? 0 : sessionSerialLen(a2); ++ if( n2<=0 || pIter->abPK[i] || a2[0]==0 ){ + if( !pIter->abPK[i] && a1[0] ) bData = 1; + memcpy(pOut, a1, n1); + pOut += n1; +@@ -237636,8 +240901,8 @@ SQLITE_API int sqlite3rebaser_configure( + sqlite3_rebaser *p, + int nRebase, const void *pRebase + ){ +- sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ + int rc; /* Return code */ ++ sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ + rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase); + if( rc==SQLITE_OK ){ + rc = sessionChangesetToHash(pIter, &p->grp, 1); +@@ -237718,6 +240983,328 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ + return rc; + } + ++/* ++** Begin adding a change to a changegroup object. ++*/ ++SQLITE_API int sqlite3changegroup_change_begin( ++ sqlite3_changegroup *pGrp, ++ int eOp, ++ const char *zTab, ++ int bIndirect, ++ char **pzErr ++){ ++ SessionTable *pTab = 0; ++ int rc = SQLITE_OK; ++ ++ if( pGrp->cd.pTab ){ ++ rc = SQLITE_MISUSE; ++ }else if( eOp!=SQLITE_INSERT && eOp!=SQLITE_UPDATE && eOp!=SQLITE_DELETE ){ ++ rc = SQLITE_ERROR; ++ }else{ ++ rc = sessionChangesetFindTable(pGrp, zTab, 0, &pTab); ++ } ++ if( rc==SQLITE_OK ){ ++ if( pTab==0 ){ ++ if( pzErr ){ ++ *pzErr = sqlite3_mprintf("no such table: %s", zTab); ++ } ++ rc = SQLITE_ERROR; ++ }else{ ++ int nReq = pTab->nCol * (eOp==SQLITE_UPDATE ? 2 : 1); ++ pGrp->cd.pTab = pTab; ++ pGrp->cd.eOp = eOp; ++ pGrp->cd.bIndirect = bIndirect; ++ ++ if( pGrp->cd.nBufAlloccd.aBuf, nReq * sizeof(SessionBuffer) ++ ); ++ if( aBuf==0 ){ ++ rc = SQLITE_NOMEM; ++ }else{ ++ memset(&aBuf[pGrp->cd.nBufAlloc], 0, ++ sizeof(SessionBuffer) * (nReq - pGrp->cd.nBufAlloc) ++ ); ++ pGrp->cd.aBuf = aBuf; ++ pGrp->cd.nBufAlloc = nReq; ++ } ++ } ++ ++#ifdef SQLITE_DEBUG ++ { ++ /* Assert that all column values are currently undefined */ ++ int ii; ++ for(ii=0; iicd.nBufAlloc; ii++){ ++ assert( pGrp->cd.aBuf[ii].nBuf==0 ); ++ } ++ } ++#endif ++ } ++ } ++ ++ return rc; ++} ++ ++/* ++** This function does processing common to the _change_int64(), _change_text() ++** and other similar APIs. ++*/ ++static int checkChangeParams( ++ sqlite3_changegroup *pGrp, ++ int bNew, ++ int iCol, ++ sqlite3_int64 nReq, ++ SessionBuffer **ppBuf ++){ ++ int rc = SQLITE_OK; ++ if( pGrp->cd.pTab==0 ){ ++ rc = SQLITE_MISUSE; ++ }else if( iCol<0 || iCol>=pGrp->cd.pTab->nCol ){ ++ rc = SQLITE_RANGE; ++ }else if( ++ (bNew && pGrp->cd.eOp==SQLITE_DELETE) ++ || (!bNew && pGrp->cd.eOp==SQLITE_INSERT) ++ ){ ++ rc = SQLITE_ERROR; ++ }else{ ++ SessionBuffer *pBuf = &pGrp->cd.aBuf[iCol]; ++ if( pGrp->cd.eOp==SQLITE_UPDATE && bNew ){ ++ pBuf += pGrp->cd.pTab->nCol; ++ } ++ pBuf->nBuf = 0; ++ sessionBufferGrow(pBuf, nReq, &rc); ++ pBuf->nBuf = nReq; ++ *ppBuf = pBuf; ++ } ++ return rc; ++} ++ ++/* ++** Configure the change currently under construction with an integer value. ++*/ ++SQLITE_API int sqlite3changegroup_change_int64( ++ sqlite3_changegroup *pGrp, ++ int bNew, ++ int iCol, ++ sqlite3_int64 iVal ++){ ++ int rc = SQLITE_OK; ++ SessionBuffer *pBuf = 0; ++ ++ if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, 9, &pBuf)) ){ ++ return rc; ++ } ++ ++ pBuf->aBuf[0] = SQLITE_INTEGER; ++ sessionPutI64(&pBuf->aBuf[1], iVal); ++ return SQLITE_OK; ++} ++ ++/* ++** Configure the change currently under construction with a null value. ++*/ ++SQLITE_API int sqlite3changegroup_change_null( ++ sqlite3_changegroup *pGrp, ++ int bNew, ++ int iCol ++){ ++ int rc = SQLITE_OK; ++ SessionBuffer *pBuf = 0; ++ ++ if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, 1, &pBuf)) ){ ++ return rc; ++ } ++ ++ pBuf->aBuf[0] = SQLITE_NULL; ++ return SQLITE_OK; ++} ++ ++/* ++** Configure the change currently under construction with a real value. ++*/ ++SQLITE_API int sqlite3changegroup_change_double( ++ sqlite3_changegroup *pGrp, ++ int bNew, ++ int iCol, ++ double fVal ++){ ++ int rc = SQLITE_OK; ++ SessionBuffer *pBuf = 0; ++ ++ if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, 9, &pBuf)) ){ ++ return rc; ++ } ++ ++ pBuf->aBuf[0] = SQLITE_FLOAT; ++ sessionPutDouble(&pBuf->aBuf[1], fVal); ++ return SQLITE_OK; ++} ++ ++/* ++** Configure the change currently under construction with a text value. ++*/ ++SQLITE_API int sqlite3changegroup_change_text( ++ sqlite3_changegroup *pGrp, ++ int bNew, ++ int iCol, ++ const char *pVal, ++ int nVal ++){ ++ int nText = nVal>=0 ? nVal : strlen(pVal); ++ sqlite3_int64 nByte = 1 + sessionVarintLen(nText) + nText; ++ int rc = SQLITE_OK; ++ SessionBuffer *pBuf = 0; ++ ++ if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, nByte, &pBuf)) ){ ++ return rc; ++ } ++ ++ pBuf->aBuf[0] = SQLITE_TEXT; ++ pBuf->nBuf = (1 + sessionVarintPut(&pBuf->aBuf[1], nText)); ++ memcpy(&pBuf->aBuf[pBuf->nBuf], pVal, nText); ++ pBuf->nBuf += nText; ++ ++ return SQLITE_OK; ++} ++ ++/* ++** Configure the change currently under construction with a blob value. ++*/ ++SQLITE_API int sqlite3changegroup_change_blob( ++ sqlite3_changegroup *pGrp, ++ int bNew, ++ int iCol, ++ const void *pVal, ++ int nVal ++){ ++ sqlite3_int64 nByte = 1 + sessionVarintLen(nVal) + (i64)nVal; ++ int rc = SQLITE_OK; ++ SessionBuffer *pBuf = 0; ++ ++ if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, nByte, &pBuf)) ){ ++ return rc; ++ } ++ ++ pBuf->aBuf[0] = SQLITE_BLOB; ++ pBuf->nBuf = (1 + sessionVarintPut(&pBuf->aBuf[1], nVal)); ++ memcpy(&pBuf->aBuf[pBuf->nBuf], pVal, nVal); ++ pBuf->nBuf += nVal; ++ ++ return SQLITE_OK; ++} ++ ++/* ++** Finish any change currently being constructed by the changegroup object. ++*/ ++SQLITE_API int sqlite3changegroup_change_finish( ++ sqlite3_changegroup *pGrp, ++ int bDiscard, ++ char **pzErr ++){ ++ int rc = SQLITE_OK; ++ if( pGrp->cd.pTab ){ ++ SessionBuffer *aBuf = pGrp->cd.aBuf; ++ int ii; ++ ++ if( bDiscard==0 ){ ++ int nBuf = pGrp->cd.pTab->nCol; ++ u8 eUndef = SQLITE_NULL; ++ if( pGrp->cd.eOp==SQLITE_UPDATE ){ ++ for(ii=0; iicd.pTab->abPK[ii] ){ ++ if( aBuf[ii].nBuf<=1 ){ ++ *pzErr = sqlite3_mprintf( ++ "invalid change: %s value in PK of old.* record", ++ aBuf[ii].nBuf==1 ? "null" : "undefined" ++ ); ++ rc = SQLITE_ERROR; ++ break; ++ }else if( aBuf[ii + nBuf].nBuf>0 ){ ++ *pzErr = sqlite3_mprintf( ++ "invalid change: defined value in PK of new.* record" ++ ); ++ rc = SQLITE_ERROR; ++ break; ++ } ++ }else ++ if( pGrp->bPatch==0 && (aBuf[ii].nBuf>0)!=(aBuf[ii+nBuf].nBuf>0) ){ ++ *pzErr = sqlite3_mprintf( ++ "invalid change: column %d " ++ "- old.* value is %sdefined but new.* is %sdefined", ++ ii, aBuf[ii].nBuf ? "" : "un", aBuf[ii+nBuf].nBuf ? "" : "un" ++ ); ++ rc = SQLITE_ERROR; ++ break; ++ } ++ } ++ eUndef = 0x00; ++ if( pGrp->bPatch==0 ) nBuf = nBuf * 2; ++ }else{ ++ for(ii=0; iicd.pTab->abPK[ii]; ++ if( (pGrp->cd.eOp==SQLITE_INSERT || pGrp->bPatch==0 || isPK) ++ && aBuf[ii].nBuf==0 ++ ){ ++ *pzErr = sqlite3_mprintf( ++ "invalid change: column %d is undefined", ii ++ ); ++ rc = SQLITE_ERROR; ++ break; ++ } ++ if( aBuf[ii].nBuf==1 && isPK ){ ++ *pzErr = sqlite3_mprintf( ++ "invalid change: null value in PK" ++ ); ++ rc = SQLITE_ERROR; ++ break; ++ } ++ } ++ } ++ ++ pGrp->cd.record.nBuf = 0; ++ for(ii=0; iicd.aBuf[ii]; ++ if( pGrp->bPatch ){ ++ if( pGrp->cd.pTab->abPK[ii]==0 ){ ++ if( pGrp->cd.eOp==SQLITE_UPDATE ){ ++ p += pGrp->cd.pTab->nCol; ++ }else if( pGrp->cd.eOp==SQLITE_DELETE ){ ++ continue; ++ } ++ } ++ } ++ if( 0==sessionBufferGrow(&pGrp->cd.record, p->nBuf?p->nBuf:1, &rc) ){ ++ if( p->nBuf ){ ++ memcpy(&pGrp->cd.record.aBuf[pGrp->cd.record.nBuf],p->aBuf,p->nBuf); ++ pGrp->cd.record.nBuf += p->nBuf; ++ }else{ ++ pGrp->cd.record.aBuf[pGrp->cd.record.nBuf++] = eUndef; ++ } ++ } ++ } ++ if( rc==SQLITE_OK ){ ++ rc = sessionOneChangeToHash( ++ pGrp, pGrp->cd.pTab, ++ pGrp->cd.eOp, pGrp->cd.bIndirect, pGrp->cd.pTab->nCol, ++ pGrp->cd.record.aBuf, pGrp->cd.record.nBuf, 0 ++ ); ++ } ++ } ++ ++ /* Reset all aBuf[] entries to "undefined". */ ++ { ++ int nZero = pGrp->cd.pTab->nCol; ++ if( pGrp->cd.eOp==SQLITE_UPDATE ) nZero += nZero; ++ for(ii=0; iicd.aBuf[ii].nBuf = 0; ++ } ++ } ++ pGrp->cd.pTab = 0; ++ } ++ ++ return rc; ++} ++ + #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ + + /************** End of sqlite3session.c **************************************/ +@@ -239648,14 +243235,22 @@ typedef union { + #define sqlite3Fts5ParserARG_PARAM ,pParse + #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; + #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; ++#undef fts5YYREALLOC + #define fts5YYREALLOC realloc ++#undef fts5YYFREE + #define fts5YYFREE free ++#undef fts5YYDYNSTACK + #define fts5YYDYNSTACK 0 ++#undef fts5YYSIZELIMIT ++#define sqlite3Fts5ParserCTX(P) 0 + #define sqlite3Fts5ParserCTX_SDECL + #define sqlite3Fts5ParserCTX_PDECL + #define sqlite3Fts5ParserCTX_PARAM + #define sqlite3Fts5ParserCTX_FETCH + #define sqlite3Fts5ParserCTX_STORE ++#undef fts5YYERRORSYMBOL ++#undef fts5YYERRSYMDT ++#undef fts5YYFALLBACK + #define fts5YYNSTATE 35 + #define fts5YYNRULE 28 + #define fts5YYNRULE_WITH_ACTION 28 +@@ -239980,15 +243575,24 @@ static int fts5yyGrowStack(fts5yyParser *p){ + int newSize; + int idx; + fts5yyStackEntry *pNew; ++#ifdef fts5YYSIZELIMIT ++ int nLimit = fts5YYSIZELIMIT(sqlite3Fts5ParserCTX(p)); ++#endif + + newSize = oldSize*2 + 100; ++#ifdef fts5YYSIZELIMIT ++ if( newSize>nLimit ){ ++ newSize = nLimit; ++ if( newSize<=oldSize ) return 1; ++ } ++#endif + idx = (int)(p->fts5yytos - p->fts5yystack); + if( p->fts5yystack==p->fts5yystk0 ){ +- pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0])); ++ pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p)); + if( pNew==0 ) return 1; + memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0])); + }else{ +- pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0])); ++ pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p)); + if( pNew==0 ) return 1; + } + p->fts5yystack = pNew; +@@ -240168,7 +243772,9 @@ static void sqlite3Fts5ParserFinalize(void *p){ + } + + #if fts5YYGROWABLESTACK +- if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack); ++ if( pParser->fts5yystack!=pParser->fts5yystk0 ){ ++ fts5YYFREE(pParser->fts5yystack, sqlite3Fts5ParserCTX(pParser)); ++ } + #endif + } + +@@ -241421,7 +245027,7 @@ static void fts5SnippetFunction( + int rc = SQLITE_OK; /* Return code */ + int iCol; /* 1st argument to snippet() */ + const char *zEllips; /* 4th argument to snippet() */ +- int nToken; /* 5th argument to snippet() */ ++ i64 nToken; /* 5th argument to snippet() */ + int nInst = 0; /* Number of instance matches this row */ + int i; /* Used to iterate through instances */ + int nPhrase; /* Number of phrases in query */ +@@ -241446,11 +245052,11 @@ static void fts5SnippetFunction( + ctx.zClose = fts5ValueToText(apVal[2]); + ctx.iRangeEnd = -1; + zEllips = fts5ValueToText(apVal[3]); +- nToken = sqlite3_value_int(apVal[4]); ++ nToken = (int)(MIN( MAX(sqlite3_value_int64(apVal[4]), 0), 64)); + + iBestCol = (iCol>=0 ? iCol : 0); + nPhrase = pApi->xPhraseCount(pFts); +- aSeen = sqlite3_malloc(nPhrase); ++ aSeen = sqlite3_malloc64(nPhrase); + if( aSeen==0 ){ + rc = SQLITE_NOMEM; + } +@@ -242105,7 +245711,7 @@ static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ + if( nIn<0 ){ + nIn = (int)strlen(pIn); + } +- zRet = (char*)sqlite3_malloc(nIn+1); ++ zRet = (char*)sqlite3_malloc64((i64)nIn+1); + if( zRet ){ + memcpy(zRet, pIn, nIn); + zRet[nIn] = '\0'; +@@ -242805,7 +246411,7 @@ static int sqlite3Fts5ConfigParse( + sqlite3_int64 nByte; + int bUnindexed = 0; /* True if there are one or more UNINDEXED */ + +- *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); ++ *ppOut = pRet = (Fts5Config*)sqlite3_malloc64(sizeof(Fts5Config)); + if( pRet==0 ) return SQLITE_NOMEM; + memset(pRet, 0, sizeof(Fts5Config)); + pRet->pGlobal = pGlobal; +@@ -243353,8 +246959,6 @@ static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ + va_end(ap); + } + +- +- + /* + ** 2014 May 31 + ** +@@ -243671,7 +247275,7 @@ static int sqlite3Fts5ExprNew( + + assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); + if( sParse.rc==SQLITE_OK ){ +- *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); ++ *ppNew = pNew = sqlite3_malloc64(sizeof(Fts5Expr)); + if( pNew==0 ){ + sParse.rc = SQLITE_NOMEM; + sqlite3Fts5ParseNodeFree(sParse.pExpr); +@@ -243823,7 +247427,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ + p2->pRoot = 0; + + if( sParse.rc==SQLITE_OK ){ +- Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc( ++ Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc64( + p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*) + ); + if( ap==0 ){ +@@ -244164,7 +247768,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ + i64 iPos = a[i].reader.iPos; + Fts5PoslistWriter *pWriter = &a[i].writer; + if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){ +- sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos); ++ sqlite3Fts5PoslistSafeAppend(a[i].pOut, &pWriter->iPrev, iPos); + } + } + +@@ -245115,10 +248719,10 @@ static int fts5ParseTokenize( + memset(pSyn, 0, (size_t)nByte); + pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); + pSyn->nFullTerm = pSyn->nQueryTerm = nToken; ++ memcpy(pSyn->pTerm, pToken, nToken); + if( pCtx->pConfig->bTokendata ){ + pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); + } +- memcpy(pSyn->pTerm, pToken, nToken); + pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; + pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; + } +@@ -246735,7 +250339,7 @@ static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte + int rc = SQLITE_OK; + Fts5Hash *pNew; + +- *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash)); ++ *ppNew = pNew = (Fts5Hash*)sqlite3_malloc64(sizeof(Fts5Hash)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ +@@ -248118,6 +251722,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ + pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); + if( pRet ){ + pRet->nn = nByte; ++ pRet->szLeaf = 0; + aOut = pRet->p = (u8*)pRet + szData; + }else{ + rc = SQLITE_NOMEM; +@@ -248130,10 +251735,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ + sqlite3_free(pRet); + pRet = 0; + }else{ +- /* TODO1: Fix this */ + pRet->p[nByte] = 0x00; + pRet->p[nByte+1] = 0x00; +- pRet->szLeaf = fts5GetU16(&pRet->p[2]); + } + } + p->rc = rc; +@@ -248154,10 +251757,18 @@ static void fts5DataRelease(Fts5Data *pData){ + sqlite3_free(pData); + } + ++/* ++** Read a leaf-page record. This is similar to fts5DataRead(), except that ++** it fills in the Fts5Data.szLeaf value before returning. ++*/ + static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ + Fts5Data *pRet = fts5DataRead(p, iRowid); + if( pRet ){ +- if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){ ++ assert( pRet->szLeaf==0 ); ++ if( pRet->nn>=4 ){ ++ pRet->szLeaf = fts5GetU16(&pRet->p[2]); ++ } ++ if( pRet->szLeaf<4 || pRet->szLeaf>pRet->nn ){ + FTS5_CORRUPT_ROWID(p, iRowid); + fts5DataRelease(pRet); + pRet = 0; +@@ -248401,7 +252012,7 @@ static int fts5StructureDecode( + i += fts5GetVarint32(&pData[i], nTotal); + if( nTotalnMerge ) rc = FTS5_CORRUPT; + pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, +- nTotal * sizeof(Fts5StructureSegment) ++ (i64)nTotal * sizeof(Fts5StructureSegment) + ); + nSegment -= nTotal; + } +@@ -249328,7 +252939,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ + + /* If necessary, grow the pIter->aRowidOffset[] array. */ + if( iRowidOffset>=pIter->nRowidOffset ){ +- int nNew = pIter->nRowidOffset + 8; ++ i64 nNew = pIter->nRowidOffset + 8; + int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int)); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; +@@ -249357,7 +252968,7 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){ + while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){ + Fts5Data *pNew; + pIter->iLeafPgno--; +- pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID( ++ pNew = fts5LeafRead(p, FTS5_SEGMENT_ROWID( + pIter->pSeg->iSegid, pIter->iLeafPgno + )); + if( pNew ){ +@@ -249811,6 +253422,10 @@ static void fts5LeafSeek( + if( nKeepn ){ ++ FTS5_CORRUPT_ITER(p, pIter); ++ return; ++ } + + assert( nKeep>=nMatch ); + if( nKeep==nMatch ){ +@@ -250062,6 +253677,10 @@ static void fts5SegIterNextInit( + + pIter->iPgidxOff = pIter->pLeaf->szLeaf; + pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff); ++ if( iTermOff > pIter->pLeaf->szLeaf ){ ++ p->rc = FTS5_CORRUPT; ++ return; ++ } + pIter->iLeafOffset = iTermOff; + fts5SegIterLoadTerm(p, pIter, 0); + fts5SegIterLoadNPos(p, pIter); +@@ -250787,8 +254406,7 @@ static void fts5PoslistFilterCallback( + + do { + while( ieState ){ + fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); +@@ -250937,7 +254555,7 @@ static void fts5IndexExtractColset( + /* Advance pointer p until it points to pEnd or an 0x01 byte that is + ** not part of a varint */ + while( paiCol[i]==iCurrent ){ +@@ -251034,8 +254652,11 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ + + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + assert( pIter->pColset ); ++ assert( pIter->poslist.nSpace>=pIter->pIndex->pConfig->nCol ); + +- if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){ ++ if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ++ || pSeg->nPos>pIter->pIndex->pConfig->nCol ++ ){ + fts5IterSetOutputs_Col(pIter, pSeg); + }else{ + u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; +@@ -252386,7 +256007,7 @@ static void fts5SecureDeleteOverflow( + int iNext = 0; + u8 *aPg = 0; + +- pLeaf = fts5DataRead(p, iRowid); ++ pLeaf = fts5LeafRead(p, iRowid); + if( pLeaf==0 ) break; + aPg = pLeaf->p; + +@@ -252394,7 +256015,7 @@ static void fts5SecureDeleteOverflow( + if( iNext!=0 ){ + *pbLastInDoclist = 0; + } +- if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){ ++ if( iNext==0 && pLeaf->szLeafnn ){ + fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext); + } + +@@ -252529,6 +256150,11 @@ static void fts5DoSecureDelete( + }else{ + iStart = fts5GetU16(&aPg[0]); + } ++ if( iStart>nPg ){ ++ FTS5_CORRUPT_IDX(p); ++ sqlite3_free(aIdx); ++ return; ++ } + + iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); + assert_nc( iSOP<=pSeg->iLeafOffset ); +@@ -252634,31 +256260,31 @@ static void fts5DoSecureDelete( + ** is another term following it on this page. So the subsequent term + ** needs to be moved to replace the term associated with the entry + ** being removed. */ +- int nPrefix = 0; +- int nSuffix = 0; +- int nPrefix2 = 0; +- int nSuffix2 = 0; ++ u64 nPrefix = 0; ++ u64 nSuffix = 0; ++ u64 nPrefix2 = 0; ++ u64 nSuffix2 = 0; + + iDelKeyOff = iNextOff; +- iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2); +- iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2); ++ iNextOff += fts5GetVarint(&aPg[iNextOff], &nPrefix2); ++ iNextOff += fts5GetVarint(&aPg[iNextOff], &nSuffix2); + + if( iKey!=1 ){ +- iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix); ++ iKeyOff += fts5GetVarint(&aPg[iKeyOff], &nPrefix); + } +- iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix); ++ iKeyOff += fts5GetVarint(&aPg[iKeyOff], &nSuffix); + + nPrefix = MIN(nPrefix, nPrefix2); + nSuffix = (nPrefix2 + nSuffix2) - nPrefix; + +- if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){ ++ if( (iKeyOff+nSuffix)>(u64)iPgIdx || (iNextOff+nSuffix2)>(u64)iPgIdx ){ + FTS5_CORRUPT_IDX(p); + }else{ + if( iKey!=1 ){ + iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); + } + iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); +- if( nPrefix2>pSeg->term.n ){ ++ if( nPrefix2>(u64)pSeg->term.n ){ + FTS5_CORRUPT_IDX(p); + }else if( nPrefix2>nPrefix ){ + memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); +@@ -252676,7 +256302,7 @@ static void fts5DoSecureDelete( + /* The entry being removed may be the only position list in + ** its doclist. */ + for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){ +- Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); ++ Fts5Data *pPg = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); + int bEmpty = (pPg && pPg->nn==4); + fts5DataRelease(pPg); + if( bEmpty==0 ) break; +@@ -252684,12 +256310,12 @@ static void fts5DoSecureDelete( + + if( iPgno==pSeg->iTermLeafPgno ){ + i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); +- Fts5Data *pTerm = fts5DataRead(p, iId); ++ Fts5Data *pTerm = fts5LeafRead(p, iId); + if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){ + u8 *aTermIdx = &pTerm->p[pTerm->szLeaf]; + int nTermIdx = pTerm->nn - pTerm->szLeaf; + int iTermIdx = 0; +- int iTermOff = 0; ++ i64 iTermOff = 0; + + while( 1 ){ + u32 iVal = 0; +@@ -252700,12 +256326,15 @@ static void fts5DoSecureDelete( + } + nTermIdx = iTermIdx; + +- memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); +- fts5PutU16(&pTerm->p[2], iTermOff); +- +- fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); +- if( nTermIdx==0 ){ +- fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); ++ if( iTermOff>pTerm->szLeaf ){ ++ FTS5_CORRUPT_IDX(p); ++ }else{ ++ memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); ++ fts5PutU16(&pTerm->p[2], iTermOff); ++ fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); ++ if( nTermIdx==0 ){ ++ fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); ++ } + } + } + fts5DataRelease(pTerm); +@@ -252728,7 +256357,9 @@ static void fts5DoSecureDelete( + int iPrevKeyOut = 0; + int iKeyIn = 0; + +- memmove(&aPg[iOff], &aPg[iNextOff], nMove); ++ if( nMove>0 ){ ++ memmove(&aPg[iOff], &aPg[iNextOff], nMove); ++ } + iPgIdx -= nShift; + nPg = iPgIdx; + fts5PutU16(&aPg[2], iPgIdx); +@@ -253648,16 +257279,16 @@ struct Fts5TokenDataMap { + ** aMap[] variables. + */ + struct Fts5TokenDataIter { +- int nMapAlloc; /* Allocated size of aMap[] in entries */ +- int nMap; /* Number of valid entries in aMap[] */ ++ i64 nMapAlloc; /* Allocated size of aMap[] in entries */ ++ i64 nMap; /* Number of valid entries in aMap[] */ + Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ + + /* The following are used for prefix-queries only. */ + Fts5Buffer terms; + + /* The following are used for other full-token tokendata queries only. */ +- int nIter; +- int nIterAlloc; ++ i64 nIter; ++ i64 nIterAlloc; + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[FLEXARRAY]; +@@ -253713,11 +257344,11 @@ static void fts5TokendataIterAppendMap( + ){ + if( p->rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ +- int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; +- int nAlloc = nNew * sizeof(Fts5TokenDataMap); ++ i64 nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; ++ i64 nAlloc = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + +- aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc); ++ aNew = (Fts5TokenDataMap*)sqlite3_realloc64(pT->aMap, nAlloc); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; +@@ -253743,7 +257374,7 @@ static void fts5TokendataIterAppendMap( + */ + static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ + Fts5TokenDataMap *aTmp = 0; +- int nByte = pT->nMap * sizeof(Fts5TokenDataMap); ++ i64 nByte = pT->nMap * sizeof(Fts5TokenDataMap); + + aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( aTmp ){ +@@ -254277,9 +257908,10 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( + + if( p->rc==SQLITE_OK ){ + if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ +- int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; +- int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); +- Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); ++ i64 nAlloc = pIn ? pIn->nIterAlloc*2 : 16; ++ i64 nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); ++ Fts5TokenDataIter *pNew; ++ pNew = (Fts5TokenDataIter*)sqlite3_realloc64(pIn, nByte); + + if( pNew==0 ){ + p->rc = SQLITE_NOMEM; +@@ -254376,8 +258008,8 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ + + /* Ensure the token-mapping is large enough */ + if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){ +- int nNew = (pT->nMapAlloc + nByte) * 2; +- Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc( ++ i64 nNew = (pT->nMapAlloc + nByte) * 2; ++ Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc64( + pT->aMap, nNew*sizeof(Fts5TokenDataMap) + ); + if( aNew==0 ){ +@@ -255208,8 +258840,8 @@ static void fts5IndexTombstoneRebuild( + ){ + const int MINSLOT = 32; + int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey); +- int nSlot = 0; /* Number of slots in each output page */ +- int nOut = 0; ++ i64 nSlot = 0; /* Number of slots in each output page */ ++ i64 nOut = 0; + + /* Figure out how many output pages (nOut) and how many slots per + ** page (nSlot). There are three possibilities: +@@ -255234,23 +258866,26 @@ static void fts5IndexTombstoneRebuild( + nSlot = MINSLOT; + }else if( pSeg->nPgTombstone==1 ){ + /* Case 2. */ +- int nElem = (int)fts5GetU32(&pData1->p[4]); ++ u32 nElem = fts5GetU32(&pData1->p[4]); + assert( pData1 && iPg1==0 ); +- nOut = 1; +- nSlot = MAX(nElem*4, MINSLOT); +- if( nSlot>nSlotPerPage ) nOut = 0; ++ if( nElem>((u32)nSlotPerPage/4) ){ ++ nOut = 0; ++ }else{ ++ nOut = 1; ++ nSlot = MAX((i64)nElem*4, MINSLOT); ++ } + } + if( nOut==0 ){ + /* Case 3. */ +- nOut = (pSeg->nPgTombstone * 2 + 1); ++ nOut = ((i64)pSeg->nPgTombstone * 2 + 1); + nSlot = nSlotPerPage; + } + + /* Allocate the required array and output pages */ + while( 1 ){ + int res = 0; +- int ii = 0; +- int szPage = 0; ++ i64 ii = 0; ++ i64 szPage = 0; + Fts5Data **apOut = 0; + + /* Allocate space for the new hash table */ +@@ -255627,7 +259262,7 @@ static void fts5IndexIntegrityCheckEmpty( + /* Now check that the iter.nEmpty leaves following the current leaf + ** (a) exist and (b) contain no terms. */ + for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){ +- Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i)); ++ Fts5Data *pLeaf = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i)); + if( pLeaf ){ + if( !fts5LeafIsTermless(pLeaf) + || (i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf)) +@@ -255755,9 +259390,13 @@ static void fts5IndexIntegrityCheckSegment( + FTS5_CORRUPT_ROWID(p, iRow); + }else{ + iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm); +- res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); +- if( res==0 ) res = nTerm - nIdxTerm; +- if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow); ++ if( (i64)iOff+(i64)nTerm>(i64)pLeaf->szLeaf ){ ++ FTS5_CORRUPT_ROWID(p, iRow); ++ }else{ ++ res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); ++ if( res==0 ) res = nTerm - nIdxTerm; ++ if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow); ++ } + } + + fts5IntegrityCheckPgidx(p, iRow, pLeaf); +@@ -255788,7 +259427,7 @@ static void fts5IndexIntegrityCheckSegment( + /* Check any rowid-less pages that occur before the current leaf. */ + for(iPg=iPrevLeaf+1; iPg=3008002 ) + #endif + { +- pIdxInfo->estimatedRows = nRow; ++ pIdxInfo->estimatedRows = MAX(1, nRow); + } + #endif + } +@@ -257361,19 +261000,30 @@ static int fts5UsePatternMatch( + ** a) If a MATCH operator is present, the cost depends on the other + ** constraints also present. As follows: + ** +-** * No other constraints: cost=1000.0 +-** * One rowid range constraint: cost=750.0 +-** * Both rowid range constraints: cost=500.0 +-** * An == rowid constraint: cost=100.0 ++** * No other constraints: cost=50000.0 ++** * One rowid range constraint: cost=37500.0 ++** * Both rowid range constraints: cost=30000.0 ++** * An == rowid constraint: cost=25000.0 + ** + ** b) Otherwise, if there is no MATCH: + ** +-** * No other constraints: cost=1000000.0 +-** * One rowid range constraint: cost=750000.0 +-** * Both rowid range constraints: cost=250000.0 +-** * An == rowid constraint: cost=10.0 ++** * No other constraints: cost=3000000.0 ++** * One rowid range constraints: cost=2250000.0 ++** * Both rowid range constraint: cost=750000.0 ++** * An == rowid constraint: cost=25.0 + ** + ** Costs are not modified by the ORDER BY clause. ++** ++** The ratios used in case (a) are based on informal results obtained from ++** the tool/fts5cost.tcl script. The "MATCH and ==" combination has the ++** cost set quite high because the query may be a prefix query. Unless ++** there is a prefix index, prefix queries with rowid constraints are much ++** more expensive than non-prefix queries with rowid constraints. ++** ++** The estimated rows returned is set to the cost/40. For simple queries, ++** experimental results show that cost/4 might be about right. But for ++** more complex queries that use multiple terms the number of rows might ++** be far fewer than this. So we compromise and use cost/40. + */ + static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + Fts5Table *pTab = (Fts5Table*)pVTab; +@@ -257406,7 +261056,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + return SQLITE_ERROR; + } + +- idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1); ++ idxStr = (char*)sqlite3_malloc64((i64)pInfo->nConstraint * 8 + 1); + if( idxStr==0 ) return SQLITE_NOMEM; + pInfo->idxStr = idxStr; + pInfo->needToFreeIdxStr = 1; +@@ -257499,21 +261149,35 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + + /* Calculate the estimated cost based on the flags set in idxFlags. */ + if( bSeenEq ){ +- pInfo->estimatedCost = nSeenMatch ? 1000.0 : 25.0; +- fts5SetUniqueFlag(pInfo); ++ pInfo->estimatedCost = nSeenMatch ? 25000.0 : 25.0; + fts5SetEstimatedRows(pInfo, 1); ++ fts5SetUniqueFlag(pInfo); + }else{ +- if( bSeenLt && bSeenGt ){ +- pInfo->estimatedCost = nSeenMatch ? 5000.0 : 750000.0; +- }else if( bSeenLt || bSeenGt ){ +- pInfo->estimatedCost = nSeenMatch ? 7500.0 : 2250000.0; ++ i64 nEstRows; ++ if( nSeenMatch ){ ++ if( bSeenLt && bSeenGt ){ ++ pInfo->estimatedCost = 50000.0; ++ }else if( bSeenLt || bSeenGt ){ ++ pInfo->estimatedCost = 37500.0; ++ }else{ ++ pInfo->estimatedCost = 50000.0; ++ } ++ nEstRows = (i64)(pInfo->estimatedCost / 40.0); ++ for(i=1; iestimatedCost *= 2.5; ++ nEstRows = nEstRows / 2; ++ } + }else{ +- pInfo->estimatedCost = nSeenMatch ? 10000.0 : 3000000.0; +- } +- for(i=1; iestimatedCost *= 0.4; ++ if( bSeenLt && bSeenGt ){ ++ pInfo->estimatedCost = 750000.0; ++ }else if( bSeenLt || bSeenGt ){ ++ pInfo->estimatedCost = 2250000.0; ++ }else{ ++ pInfo->estimatedCost = 3000000.0; ++ } ++ nEstRows = (i64)(pInfo->estimatedCost / 4.0); + } +- fts5SetEstimatedRows(pInfo, (i64)(pInfo->estimatedCost / 4.0)); ++ fts5SetEstimatedRows(pInfo, nEstRows); + } + + pInfo->idxNum = idxFlags; +@@ -258856,6 +262520,7 @@ static int fts5UpdateMethod( + } + + update_out: ++ sqlite3Fts5IndexCloseReader(pTab->p.pIndex); + pTab->p.pConfig->pzErrmsg = 0; + return rc; + } +@@ -259453,19 +263118,23 @@ static int fts5ApiPhraseFirstColumn( + + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + Fts5Sorter *pSorter = pCsr->pSorter; +- int n; +- if( pSorter ){ +- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); +- n = pSorter->aIdx[iPhrase] - i1; +- pIter->a = &pSorter->aPoslist[i1]; ++ if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ ++ rc = SQLITE_RANGE; + }else{ +- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); +- } +- if( rc==SQLITE_OK ){ +- assert( pIter->a || n==0 ); +- pIter->b = (pIter->a ? &pIter->a[n] : 0); +- *piCol = 0; +- fts5ApiPhraseNextColumn(pCtx, pIter, piCol); ++ int n; ++ if( pSorter ){ ++ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); ++ n = pSorter->aIdx[iPhrase] - i1; ++ pIter->a = &pSorter->aPoslist[i1]; ++ }else{ ++ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); ++ } ++ if( rc==SQLITE_OK ){ ++ assert( pIter->a || n==0 ); ++ pIter->b = (pIter->a ? &pIter->a[n] : 0); ++ *piCol = 0; ++ fts5ApiPhraseNextColumn(pCtx, pIter, piCol); ++ } + } + }else{ + int n; +@@ -260373,7 +264042,7 @@ static void fts5SourceIdFunc( + ){ + assert( nArg==0 ); + UNUSED_PARAM2(nArg, apUnused); +- sqlite3_result_text(pCtx, "fts5: 2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618", -1, SQLITE_TRANSIENT); ++ sqlite3_result_text(pCtx, "fts5: 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc", -1, SQLITE_TRANSIENT); + } + + /* +@@ -260537,7 +264206,7 @@ static int fts5Init(sqlite3 *db){ + int rc; + Fts5Global *pGlobal = 0; + +- pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global)); ++ pGlobal = (Fts5Global*)sqlite3_malloc64(sizeof(Fts5Global)); + if( pGlobal==0 ){ + rc = SQLITE_NOMEM; + }else{ +@@ -261015,34 +264684,31 @@ static int sqlite3Fts5StorageOpen( + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ +- int nDefn = 32 + pConfig->nCol*10; +- char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); +- if( zDefn==0 ){ +- rc = SQLITE_NOMEM; +- }else{ +- int i; +- int iOff; +- sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); +- iOff = (int)strlen(zDefn); +- for(i=0; inCol; i++){ +- if( pConfig->eContent==FTS5_CONTENT_NORMAL +- || pConfig->abUnindexed[i] +- ){ +- sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); +- iOff += (int)strlen(&zDefn[iOff]); +- } ++ int i = 0; ++ char *zDefn = 0; ++ sqlite3_str *pDefn = sqlite3_str_new(pConfig->db); ++ ++ sqlite3_str_appendf(pDefn, "id INTEGER PRIMARY KEY"); ++ for(i=0; inCol; i++){ ++ if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->abUnindexed[i] ){ ++ sqlite3_str_appendf(pDefn, ", c%d", i); + } +- if( pConfig->bLocale ){ +- for(i=0; inCol; i++){ +- if( pConfig->abUnindexed[i]==0 ){ +- sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); +- iOff += (int)strlen(&zDefn[iOff]); +- } ++ } ++ if( pConfig->bLocale ){ ++ for(i=0; inCol; i++){ ++ if( pConfig->abUnindexed[i]==0 ){ ++ sqlite3_str_appendf(pDefn, ", l%d", i); + } + } ++ } ++ zDefn = sqlite3_str_finish(pDefn); ++ ++ if( zDefn ){ + rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); ++ sqlite3_free(zDefn); ++ }else{ ++ rc = SQLITE_NOMEM; + } +- sqlite3_free(zDefn); + } + + if( rc==SQLITE_OK && pConfig->bColumnsize ){ +@@ -262253,7 +265919,7 @@ static int fts5AsciiCreate( + if( nArg%2 ){ + rc = SQLITE_ERROR; + }else{ +- p = sqlite3_malloc(sizeof(AsciiTokenizer)); ++ p = sqlite3_malloc64(sizeof(AsciiTokenizer)); + if( p==0 ){ + rc = SQLITE_NOMEM; + }else{ +@@ -262548,7 +266214,7 @@ static int fts5UnicodeCreate( + if( nArg%2 ){ + rc = SQLITE_ERROR; + }else{ +- p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer)); ++ p = (Unicode61Tokenizer*)sqlite3_malloc64(sizeof(Unicode61Tokenizer)); + if( p ){ + const char *zCat = "L* N* Co"; + int i; +@@ -262767,11 +266433,17 @@ static int fts5PorterCreate( + const char *zBase = "unicode61"; + fts5_tokenizer_v2 *pV2 = 0; + +- if( nArg>0 ){ +- zBase = azArg[0]; ++ while( nArg>0 ){ ++ if( sqlite3_stricmp(azArg[0],"porter")==0 ){ ++ nArg--; ++ azArg++; ++ }else{ ++ zBase = azArg[0]; ++ break; ++ } + } + +- pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); ++ pRet = (PorterTokenizer*)sqlite3_malloc64(sizeof(PorterTokenizer)); + if( pRet ){ + memset(pRet, 0, sizeof(PorterTokenizer)); + rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); +@@ -263478,7 +267150,7 @@ static int fts5TriCreate( + rc = SQLITE_ERROR; + }else{ + int i; +- pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); ++ pNew = (TrigramTokenizer*)sqlite3_malloc64(sizeof(*pNew)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ +@@ -265464,7 +269136,7 @@ static int fts5VocabFilterMethod( + const char *zCopy = (const char *)sqlite3_value_text(pLe); + if( zCopy==0 ) zCopy = ""; + pCsr->nLeTerm = sqlite3_value_bytes(pLe); +- pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); ++ pCsr->zLeTerm = sqlite3_malloc64((i64)pCsr->nLeTerm+1); + if( pCsr->zLeTerm==0 ){ + rc = SQLITE_NOMEM; + }else{ +diff --git a/deps/sqlite/sqlite3.h b/deps/sqlite/sqlite3.h +index 302f0f5b..c91b81c0 100644 +--- a/deps/sqlite/sqlite3.h ++++ b/deps/sqlite/sqlite3.h +@@ -146,12 +146,12 @@ extern "C" { + ** [sqlite3_libversion_number()], [sqlite3_sourceid()], + ** [sqlite_version()] and [sqlite_source_id()]. + */ +-#define SQLITE_VERSION "3.51.3" +-#define SQLITE_VERSION_NUMBER 3051003 +-#define SQLITE_SOURCE_ID "2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618" +-#define SQLITE_SCM_BRANCH "branch-3.51" +-#define SQLITE_SCM_TAGS "release version-3.51.3" +-#define SQLITE_SCM_DATETIME "2026-03-13T10:38:09.694Z" ++#define SQLITE_VERSION "3.53.4" ++#define SQLITE_VERSION_NUMBER 3053004 ++#define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc" ++#define SQLITE_SCM_BRANCH "branch-3.53" ++#define SQLITE_SCM_TAGS "release version-3.53.4" ++#define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z" + + /* + ** CAPI3REF: Run-Time Library Version Numbers +@@ -578,7 +578,7 @@ SQLITE_API int sqlite3_exec( + #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) + #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) + #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) +-#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ ++#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */ + + /* + ** CAPI3REF: Flags For File Open Operations +@@ -1290,6 +1290,12 @@ struct sqlite3_io_methods { + #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE + #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + ++/* reserved file-control numbers: ++** 101 ++** 102 ++** 103 ++*/ ++ + + /* + ** CAPI3REF: Mutex Handle +@@ -1490,7 +1496,7 @@ typedef const char *sqlite3_filename; + ** greater and the function pointer is not NULL) and will fall back + ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. + ** +-** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces ++** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces + ** are not used by the SQLite core. These optional interfaces are provided + ** by some VFSes to facilitate testing of the VFS code. By overriding + ** system calls with functions under its control, a test program can +@@ -1711,7 +1717,8 @@ SQLITE_API int sqlite3_os_end(void); + ** are called "anytime configuration options". + ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before + ** [sqlite3_shutdown()] with a first argument that is not an anytime +-** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. ++** configuration option, then the sqlite3_config() call will ++** return SQLITE_MISUSE. + ** Note, however, that ^sqlite3_config() can be called as part of the + ** implementation of an application-defined [sqlite3_os_init()]. + ** +@@ -2277,9 +2284,10 @@ struct sqlite3_mem_methods { + ** is less than 8. The "sz" argument should be a multiple of 8 less than + ** 65536. If "sz" does not meet this constraint, it is reduced in size until + ** it does. +-**
  • The third argument ("cnt") is the number of slots. Lookaside is disabled +-** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so +-** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" ++**

  • The third argument ("cnt") is the number of slots. ++** Lookaside is disabled if "cnt"is less than 1. ++* The "cnt" value will be reduced, if necessary, so ++** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" + ** parameter is usually chosen so that the product of "sz" and "cnt" is less + ** than 1,000,000. + ** +@@ -2567,12 +2575,15 @@ struct sqlite3_mem_methods { + ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] + **

    SQLITE_DBCONFIG_STMT_SCANSTATUS
    + **
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in +-** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears +-** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() +-** statistics. For statistics to be collected, the flag must be set on +-** the database handle both when the SQL statement is prepared and when it +-** is stepped. The flag is set (collection of statistics is enabled) +-** by default.

    This option takes two arguments: an integer and a pointer to ++** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears ++** a flag that enables collection of run-time performance statistics ++** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] ++** columns of the [bytecode virtual table]. ++** For statistics to be collected, the flag must be set on ++** the database handle both when the SQL statement is ++** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. ++** The flag is set (collection of statistics is enabled) by default. ++**

    This option takes two arguments: an integer and a pointer to + ** an integer. The first argument is 1, 0, or -1 to enable, disable, or + ** leave unchanged the statement scanstatus option. If the second argument + ** is not NULL, then the value of the statement scanstatus setting after +@@ -2645,16 +2656,34 @@ struct sqlite3_mem_methods { + ** comments are allowed in SQL text after processing the first argument. + **

    + ** ++** [[SQLITE_DBCONFIG_FP_DIGITS]] ++**
    SQLITE_DBCONFIG_FP_DIGITS
    ++**
    The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines ++** the number of significant digits that SQLite will attempt to preserve when ++** converting floating point numbers (IEEE 754 "doubles") into text. The ++** default value 17, as of SQLite version 3.52.0. The value was 15 in all ++** prior versions.

    ++** This option takes two arguments which are an integer and a pointer ++** to an integer. The first argument is a small integer, between 3 and 23, or ++** zero. The FP_DIGITS setting is changed to that small integer, or left ++** unaltered if the first argument is zero or out of range. The second argument ++** is a pointer to an integer. If the pointer is not NULL, then the value of ++** the FP_DIGITS setting, after possibly being modified by the first ++** arguments, is written into the integer to which the second argument points. ++**

    ++** + ** + ** + ** [[DBCONFIG arguments]]

    Arguments To SQLITE_DBCONFIG Options

    + ** + **

    Most of the SQLITE_DBCONFIG options take two arguments, so that the + ** overall call to [sqlite3_db_config()] has a total of four parameters. +-** The first argument (the third parameter to sqlite3_db_config()) is an integer. +-** The second argument is a pointer to an integer. If the first argument is 1, +-** then the option becomes enabled. If the first integer argument is 0, then the +-** option is disabled. If the first argument is -1, then the option setting ++** The first argument (the third parameter to sqlite3_db_config()) is ++** an integer. ++** The second argument is a pointer to an integer. If the first argument is 1, ++** then the option becomes enabled. If the first integer argument is 0, ++** then the option is disabled. ++** If the first argument is -1, then the option setting + ** is unchanged. The second argument, the pointer to an integer, may be NULL. + ** If the second argument is not NULL, then a value of 0 or 1 is written into + ** the integer to which the second argument points, depending on whether the +@@ -2662,9 +2691,10 @@ struct sqlite3_mem_methods { + ** the first argument. + ** + **

    While most SQLITE_DBCONFIG options use the argument format +-** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME] +-** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the +-** documentation of those exceptional options for details. ++** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME], ++** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options ++** are different. See the documentation of those exceptional options for ++** details. + */ + #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ + #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +@@ -2689,7 +2719,8 @@ struct sqlite3_mem_methods { + #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ + #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ + #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ +-#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */ ++#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */ ++#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */ + + /* + ** CAPI3REF: Enable Or Disable Extended Result Codes +@@ -4171,6 +4202,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); + **

  • sqlite3_errmsg() + **
  • sqlite3_errmsg16() + **
  • sqlite3_error_offset() ++**
  • sqlite3_db_handle() + ** + ** + ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +@@ -4217,7 +4249,7 @@ SQLITE_API const char *sqlite3_errstr(int); + SQLITE_API int sqlite3_error_offset(sqlite3 *db); + + /* +-** CAPI3REF: Set Error Codes And Message ++** CAPI3REF: Set Error Code And Message + ** METHOD: sqlite3 + ** + ** Set the error code of the database handle passed as the first argument +@@ -4334,7 +4366,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + ** or in an ORDER BY or GROUP BY clause.
  • )^ + ** + ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    +-**
    The maximum depth of the parse tree on any expression.
    )^ ++**
    The maximum depth of the parse tree on any expression and ++** the maximum nesting depth for subqueries and VIEWs
    )^ ++** ++** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(
    SQLITE_LIMIT_PARSER_DEPTH
    ++**
    The maximum depth of the LALR(1) parser stack used to analyze ++** input SQL statements.
    )^ + ** + ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    + **
    The maximum number of terms in a compound SELECT statement.
    )^ +@@ -4361,7 +4398,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + **
    The maximum index number of any [parameter] in an SQL statement.)^ + ** + ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    +-**
    The maximum depth of recursion for triggers.
    )^ ++**
    The maximum depth of recursion for triggers, and the maximum ++** nesting depth for separate triggers.
    )^ + ** + ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    + **
    The maximum number of auxiliary worker threads that a single +@@ -4380,6 +4418,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + #define SQLITE_LIMIT_VARIABLE_NUMBER 9 + #define SQLITE_LIMIT_TRIGGER_DEPTH 10 + #define SQLITE_LIMIT_WORKER_THREADS 11 ++#define SQLITE_LIMIT_PARSER_DEPTH 12 + + /* + ** CAPI3REF: Prepare Flags +@@ -4424,12 +4463,29 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + ** fails, the sqlite3_prepare_v3() call returns the same error indications + ** with or without this flag; it just omits the call to [sqlite3_log()] that + ** logs the error. ++** ++** [[SQLITE_PREPARE_FROM_DDL]]
    SQLITE_PREPARE_FROM_DDL
    ++**
    The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce ++** security constraints that would otherwise only be enforced when parsing ++** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag ++** causes the SQL compiler to treat the SQL statement being prepared as if ++** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and ++** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called ++** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only ++** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice ++** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that ++** is derived from parts of the database schema. In particular, virtual ++** table implementations that run SQL statements that are derived from ++** arguments to their CREATE VIRTUAL TABLE statement should always use ++** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to ++** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks. + ** + */ + #define SQLITE_PREPARE_PERSISTENT 0x01 + #define SQLITE_PREPARE_NORMALIZE 0x02 + #define SQLITE_PREPARE_NO_VTAB 0x04 + #define SQLITE_PREPARE_DONT_LOG 0x10 ++#define SQLITE_PREPARE_FROM_DDL 0x20 + + /* + ** CAPI3REF: Compiling An SQL Statement +@@ -4443,8 +4499,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + ** + ** The preferred routine to use is [sqlite3_prepare_v2()]. The + ** [sqlite3_prepare()] interface is legacy and should be avoided. +-** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used +-** for special purposes. ++** [sqlite3_prepare_v3()] has an extra ++** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes ++** needed for special purpose or to pass along security restrictions. + ** + ** The use of the UTF-8 interfaces is preferred, as SQLite currently + ** does all parsing using UTF-8. The UTF-16 interfaces are provided +@@ -4849,8 +4906,8 @@ typedef struct sqlite3_context sqlite3_context; + ** it should be a pointer to well-formed UTF16 text. + ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then + ** it should be a pointer to a well-formed unicode string that is +-** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 +-** otherwise. ++** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT, ++** or UTF16 otherwise. + ** + ** [[byte-order determination rules]] ^The byte-order of + ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) +@@ -4896,10 +4953,15 @@ typedef struct sqlite3_context sqlite3_context; + ** object and pointer to it must remain valid until then. ^SQLite will then + ** manage the lifetime of its private copy. + ** +-** ^The sixth argument to sqlite3_bind_text64() must be one of +-** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] +-** to specify the encoding of the text in the third parameter. If +-** the sixth argument to sqlite3_bind_text64() is not one of the ++** ^The sixth argument (the E argument) ++** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of ++** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], ++** or [SQLITE_UTF16LE] to specify the encoding of the text in the ++** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the ++** string argument is both UTF-8 encoded and is zero-terminated. In other ++** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at ++** least N+1 bytes and that the Z[N] byte is zero. If ++** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the + ** allowed values shown above, or if the text encoding is different + ** from the encoding specified by the sixth parameter, then the behavior + ** is undefined. +@@ -5766,6 +5828,52 @@ SQLITE_API int sqlite3_create_window_function( + ** + ** These constants define integer codes that represent the various + ** text encodings supported by SQLite. ++** ++**
    ++** [[SQLITE_UTF8]]
    SQLITE_UTF8
    Text is encoding as UTF-8
    ++** ++** [[SQLITE_UTF16LE]]
    SQLITE_UTF16LE
    Text is encoding as UTF-16 ++** with each code point being expressed "little endian" - the least significant ++** byte first. This is the usual encoding, for example on Windows.
    ++** ++** [[SQLITE_UTF16BE]]
    SQLITE_UTF16BE
    Text is encoding as UTF-16 ++** with each code point being expressed "big endian" - the most significant ++** byte first. This encoding is less common, but is still sometimes seen, ++** specially on older systems. ++** ++** [[SQLITE_UTF16]]
    SQLITE_UTF16
    Text is encoding as UTF-16 ++** with each code point being expressed either little endian or as big ++** endian, according to the native endianness of the host computer. ++** ++** [[SQLITE_ANY]]
    SQLITE_ANY
    This encoding value may only be used ++** to declare the preferred text for [application-defined SQL functions] ++** created using [sqlite3_create_function()] and similar. If the preferred ++** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep ++** parameter) is SQLITE_ANY, that indicates that the function does not have ++** a preference regarding the text encoding of its parameters and can take ++** any text encoding that the SQLite core find convenient to supply. This ++** option is deprecated. Please do not use it in new applications. ++** ++** [[SQLITE_UTF16_ALIGNED]]
    SQLITE_UTF16_ALIGNED
    This encoding ++** value may be used as the 3rd parameter (the eTextRep parameter) to ++** [sqlite3_create_collation()] and similar. This encoding value means ++** that the application-defined collating sequence created expects its ++** input strings to be in UTF16 in native byte order, and that the start ++** of the strings must be aligned to a 2-byte boundary. ++** ++** [[SQLITE_UTF8_ZT]]
    SQLITE_UTF8_ZT
    This option can only be ++** used to specify the text encoding to strings input to ++** [sqlite3_result_text64()] and [sqlite3_bind_text64()]. ++** The SQLITE_UTF8_ZT encoding means that the input string (call it "z") ++** is UTF-8 encoded and that it is zero-terminated. If the length parameter ++** (call it "n") is non-negative, this encoding option means that the caller ++** guarantees that z array contains at least n+1 bytes and that the z[n] ++** byte has a value of zero. ++** This option gives the same output as SQLITE_UTF8, but can be more efficient ++** by avoiding the need to make a copy of the input string, in some cases. ++** However, if z is allocated to hold fewer than n+1 bytes or if the ++** z[n] byte is not zero, undefined behavior may result. ++**
    + */ + #define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ + #define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +@@ -5773,6 +5881,7 @@ SQLITE_API int sqlite3_create_window_function( + #define SQLITE_UTF16 4 /* Use native byte order */ + #define SQLITE_ANY 5 /* Deprecated */ + #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ ++#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */ + + /* + ** CAPI3REF: Function Flags +@@ -6007,26 +6116,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 + ** the SQL function that supplied the [sqlite3_value*] parameters. + ** + ** As long as the input parameter is correct, these routines can only +-** fail if an out-of-memory error occurs during a format conversion. +-** Only the following subset of interfaces are subject to out-of-memory +-** errors: +-** +-**
      +-**
    • sqlite3_value_blob() +-**
    • sqlite3_value_text() +-**
    • sqlite3_value_text16() +-**
    • sqlite3_value_text16le() +-**
    • sqlite3_value_text16be() +-**
    • sqlite3_value_bytes() +-**
    • sqlite3_value_bytes16() +-**
    +-** ++** fail if an out-of-memory error occurs while trying to do a ++** UTF8→UTF16 or UTF16→UTF8 conversion. + ** If an out-of-memory error occurs, then the return value from these + ** routines is the same as if the column had contained an SQL NULL value. +-** Valid SQL NULL returns can be distinguished from out-of-memory errors +-** by invoking the [sqlite3_errcode()] immediately after the suspect ++** If the input sqlite3_value was not obtained from [sqlite3_value_dup()], ++** then valid SQL NULL returns can also be distinguished from ++** out-of-memory errors after extracting the value ++** by invoking the [sqlite3_errcode()] immediately after the suspicious + ** return value is obtained and before any + ** other SQLite interface is called on the same [database connection]. ++** If the input sqlite3_value was obtained from sqlite3_value_dup() then ++** it is disconnected from the database connection and so sqlite3_errcode() ++** will not work. ++** In that case, the only way to distinguish an out-of-memory ++** condition from a true SQL NULL is to invoke sqlite3_value_type() on the ++** input to see if it is NULL prior to trying to extract the value. + */ + SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); + SQLITE_API double sqlite3_value_double(sqlite3_value*); +@@ -6053,7 +6158,8 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value*); + ** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) + ** returns something other than SQLITE_TEXT, then the return value from + ** sqlite3_value_encoding(X) is meaningless. ^Calls to +-** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], ++** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], ++** [sqlite3_value_text16be(X)], + ** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or + ** [sqlite3_value_bytes16(X)] might change the encoding of the value X and + ** thus change the return from subsequent calls to sqlite3_value_encoding(X). +@@ -6184,17 +6290,17 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + ** query execution, under some circumstances the associated auxiliary data + ** might be preserved. An example of where this might be useful is in a + ** regular-expression matching function. The compiled version of the regular +-** expression can be stored as auxiliary data associated with the pattern string. +-** Then as long as the pattern string remains the same, ++** expression can be stored as auxiliary data associated with the pattern ++** string. Then as long as the pattern string remains the same, + ** the compiled regular expression can be reused on multiple + ** invocations of the same function. + ** +-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data +-** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument +-** value to the application-defined function. ^N is zero for the left-most +-** function argument. ^If there is no auxiliary data +-** associated with the function argument, the sqlite3_get_auxdata(C,N) interface +-** returns a NULL pointer. ++** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary ++** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the ++** Nth argument value to the application-defined function. ^N is zero ++** for the left-most function argument. ^If there is no auxiliary data ++** associated with the function argument, the sqlite3_get_auxdata(C,N) ++** interface returns a NULL pointer. + ** + ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the + ** N-th argument of the application-defined function. ^Subsequent +@@ -6278,10 +6384,14 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi + ** + ** There is no limit (other than available memory) on the number of different + ** client data pointers (with different names) that can be attached to a +-** single database connection. However, the implementation is optimized +-** for the case of having only one or two different client data names. +-** Applications and wrapper libraries are discouraged from using more than +-** one client data name each. ++** single database connection. However, the current implementation stores ++** the content on a linked list. Insert and retrieval performance will ++** be proportional to the number of entries. The design use case, and ++** the use case for which the implementation is optimized, is ++** that an application will store only small number of client data names, ++** typically just one or two. This interface is not intended to be a ++** generalized key/value store for thousands or millions of keys. It ++** will work for that, but performance might be disappointing. + ** + ** There is no way to enumerate the client data pointers + ** associated with a database connection. The N parameter can be thought +@@ -6389,10 +6499,14 @@ typedef void (*sqlite3_destructor_type)(void*); + ** set the return value of the application-defined function to be + ** a text string which is represented as UTF-8, UTF-16 native byte order, + ** UTF-16 little endian, or UTF-16 big endian, respectively. +-** ^The sqlite3_result_text64() interface sets the return value of an ++** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an + ** application-defined function to be a text string in an encoding +-** specified by the fifth (and last) parameter, which must be one +-** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ++** specified the E parameter, which must be one ++** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], ++** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that ++** the result text is both UTF-8 and zero-terminated. In other words, ++** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that ++** the Z[N] is zero. + ** ^SQLite takes the text result from the application from + ** the 2nd parameter of the sqlite3_result_text* interfaces. + ** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces +@@ -6479,7 +6593,7 @@ SQLITE_API void sqlite3_result_int(sqlite3_context*, int); + SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); + SQLITE_API void sqlite3_result_null(sqlite3_context*); + SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +-SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, ++SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n, + void(*)(void*), unsigned char encoding); + SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); + SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +@@ -7418,7 +7532,7 @@ SQLITE_API int sqlite3_table_column_metadata( + ** ^The sqlite3_load_extension() interface attempts to load an + ** [SQLite extension] library contained in the file zFile. If + ** the file cannot be loaded directly, attempts are made to load +-** with various operating-system specific extensions added. ++** with various operating-system specific filename extensions added. + ** So for example, if "samplelib" cannot be loaded, then names like + ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might + ** be tried also. +@@ -7426,10 +7540,10 @@ SQLITE_API int sqlite3_table_column_metadata( + ** ^The entry point is zProc. + ** ^(zProc may be 0, in which case SQLite will try to come up with an + ** entry point name on its own. It first tries "sqlite3_extension_init". +-** If that does not work, it constructs a name "sqlite3_X_init" where +-** X consists of the lower-case equivalent of all ASCII alphabetic +-** characters in the filename from the last "/" to the first following +-** "." and omitting any initial "lib".)^ ++** If that does not work, it tries names of the form "sqlite3_X_init" ++** where X consists of the lower-case equivalent of all ASCII alphabetic ++** characters or all ASCII alphanumeric characters in the filename from ++** the last "/" to the first following "." and omitting any initial "lib".)^ + ** ^The sqlite3_load_extension() interface returns + ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. + ** ^If an error occurs and pzErrMsg is not 0, then the +@@ -7503,7 +7617,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + **
    + **    int xEntryPoint(
    + **      sqlite3 *db,
    +-**      const char **pzErrMsg,
    ++**      char **pzErrMsg,
    + **      const struct sqlite3_api_routines *pThunk
    + **    );
    + ** 
    )^ +@@ -8253,13 +8367,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix + ** and Windows. + ** +-** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +-** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +-** implementation is included with the library. In this case the +-** application must supply a custom mutex implementation using the +-** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +-** before calling sqlite3_initialize() or any other public sqlite3_ +-** function that calls sqlite3_initialize(). + ** + ** ^The sqlite3_mutex_alloc() routine allocates a new + ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +@@ -8614,6 +8721,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); + #define SQLITE_TESTCTRL_TUNE 32 + #define SQLITE_TESTCTRL_LOGEST 33 + #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ ++#define SQLITE_TESTCTRL_ATOF 34 + #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ + + /* +@@ -8722,17 +8830,22 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); + ** pass the returned value to [sqlite3_free()] to avoid a memory leak. + ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any + ** errors were encountered during construction of the string. ^The +-** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the ++** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the + ** string in [sqlite3_str] object X is zero bytes long. ++** ++** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object ++** X and the string content it contains. Calling sqlite3_str_free(X) is ++** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). + */ + SQLITE_API char *sqlite3_str_finish(sqlite3_str*); ++SQLITE_API void sqlite3_str_free(sqlite3_str*); + + /* + ** CAPI3REF: Add Content To A Dynamic String + ** METHOD: sqlite3_str + ** +-** These interfaces add content to an sqlite3_str object previously obtained +-** from [sqlite3_str_new()]. ++** These interfaces add or remove content to an sqlite3_str object ++** previously obtained from [sqlite3_str_new()]. + ** + ** ^The [sqlite3_str_appendf(X,F,...)] and + ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] +@@ -8755,6 +8868,10 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); + ** ^The [sqlite3_str_reset(X)] method resets the string under construction + ** inside [sqlite3_str] object X back to zero bytes in length. + ** ++** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string ++** under construction to be N bytes or less. This routine is a no-op if ++** N is negative or if the string is already N bytes or smaller in size. ++** + ** These methods do not return a result code. ^If an error occurs, that fact + ** is recorded in the [sqlite3_str] object and can be recovered by a + ** subsequent call to [sqlite3_str_errcode(X)]. +@@ -8765,6 +8882,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); + SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); + SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); + SQLITE_API void sqlite3_str_reset(sqlite3_str*); ++SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); + + /* + ** CAPI3REF: Status Of A Dynamic String +@@ -10295,7 +10413,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + ** + ** sqlite3_vtab_distinct() return value + ** Rows are returned in aOrderBy order +-** Rows with the same value in all aOrderBy columns are adjacent ++** Rows with the same value in all aOrderBy columns are ++** adjacent + ** Duplicates over all colUsed columns may be omitted + ** 0yesyesno + ** 1noyesno +@@ -10304,8 +10423,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + ** + ** + ** ^For the purposes of comparing virtual table output values to see if the +-** values are the same value for sorting purposes, two NULL values are considered +-** to be the same. In other words, the comparison operator is "IS" ++** values are the same value for sorting purposes, two NULL values are ++** considered to be the same. In other words, the comparison operator is "IS" + ** (or "IS NOT DISTINCT FROM") and not "==". + ** + ** If a virtual table implementation is unable to meet the requirements +@@ -10598,9 +10717,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** + ** a variable pointed to by the "pOut" parameter. + ** + ** The "flags" parameter must be passed a mask of flags. At present only +-** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX ++** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX + ** is specified, then status information is available for all elements +-** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If ++** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If + ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements + ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of + ** the EXPLAIN QUERY PLAN output) are available. Invoking API +@@ -10614,7 +10733,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** + ** elements used to implement the statement - a non-zero value is returned and + ** the variable that pOut points to is unchanged. + ** +-** See also: [sqlite3_stmt_scanstatus_reset()] ++** See also: [sqlite3_stmt_scanstatus_reset()] and the ++** [nexec and ncycle] columns of the [bytecode virtual table]. + */ + SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ +@@ -11156,19 +11276,42 @@ SQLITE_API int sqlite3_deserialize( + /* + ** CAPI3REF: Bind array values to the CARRAY table-valued function + ** +-** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to +-** one of the first argument of the [carray() table-valued function]. The +-** S parameter is a pointer to the [prepared statement] that uses the carray() +-** functions. I is the parameter index to be bound. P is a pointer to the +-** array to be bound, and N is the number of eements in the array. The +-** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], +-** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to +-** indicate the datatype of the array being bound. The X argument is not a +-** NULL pointer, then SQLite will invoke the function X on the P parameter +-** after it has finished using P, even if the call to +-** sqlite3_carray_bind() fails. The special-case finalizer +-** SQLITE_TRANSIENT has no effect here. +-*/ ++** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to ++** parameter that is the first argument of the [carray() table-valued function]. ++** The S parameter is a pointer to the [prepared statement] that uses the ++** carray() functions. I is the parameter index to be bound. I must be the ++** index of the parameter that is the first argument to the carray() ++** table-valued function. P is a pointer to the array to be bound, and N ++** is the number of elements in the array. The F argument is one of ++** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], ++** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], ++** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P. ++** ++** If the X argument is not a NULL pointer or one of the special ++** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke ++** the function X with argument D when it is finished using the data in P. ++** The call to X(D) is a destructor for the array P. The destructor X(D) ++** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X ++** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes ++** that the data static and the destructor is never invoked. If the X ++** parameter is the special-case value [SQLITE_TRANSIENT], then ++** sqlite3_carray_bind_v2() makes its own private copy of the data prior ++** to returning and never invokes the destructor X. ++** ++** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2() ++** with a D parameter set to P. In other words, ++** sqlite3_carray_bind(S,I,P,N,F,X) is same as ++** sqlite3_carray_bind_v2(S,I,P,N,F,X,P). ++*/ ++SQLITE_API int sqlite3_carray_bind_v2( ++ sqlite3_stmt *pStmt, /* Statement to be bound */ ++ int i, /* Parameter index */ ++ void *aData, /* Pointer to array data */ ++ int nData, /* Number of data elements */ ++ int mFlags, /* CARRAY flags */ ++ void (*xDel)(void*), /* Destructor for aData */ ++ void *pDel /* Optional argument to xDel() */ ++); + SQLITE_API int sqlite3_carray_bind( + sqlite3_stmt *pStmt, /* Statement to be bound */ + int i, /* Parameter index */ +@@ -12712,11 +12855,23 @@ SQLITE_API int sqlite3changeset_apply_v3( + ** database behave as if they were declared with "ON UPDATE NO ACTION ON + ** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL + ** or SET DEFAULT. ++** ++**
    SQLITE_CHANGESETAPPLY_NOUPDATELOOP
    ++** Sometimes, a changeset contains two or more update statements such that ++** although after applying all updates the database will contain no ++** constraint violations, no single update can be applied before the others. ++** The simplest example of this is a pair of UPDATEs that have "swapped" ++** two column values with a UNIQUE constraint. ++**

    ++** Usually, sqlite3changeset_apply() and similar functions work hard to try ++** to find a way to apply such a changeset. However, if this flag is set, ++** then all such updates are considered CONSTRAINT conflicts. + */ + #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 + #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 + #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 + #define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 ++#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010 + + /* + ** CAPI3REF: Constants Passed To The Conflict Handler +@@ -13199,6 +13354,232 @@ SQLITE_API int sqlite3session_config(int op, void *pArg); + */ + #define SQLITE_SESSION_CONFIG_STRMSIZE 1 + ++/* ++** CAPI3REF: Configure a changegroup object ++** ++** Configure the changegroup object passed as the first argument. ++** At present the only valid value for the second parameter is ++** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET]. ++*/ ++SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg); ++ ++/* ++** CAPI3REF: Options for sqlite3changegroup_config(). ++** ++** The following values may be passed as the 2nd parameter to ++** sqlite3changegroup_config(). ++** ++**

    SQLITE_CHANGEGROUP_CONFIG_PATCHSET
    ++** A changegroup object generates either a changeset or patchset. Usually, ++** this is determined by whether the first call to sqlite3changegroup_add() ++** is passed a changeset or a patchset. Or, if the first changes are added ++** to the changegroup object using the sqlite3changegroup_change_xxx() ++** APIs, then this option may be used to configure whether the changegroup ++** object generates a changeset or patchset. ++** ++** When this option is invoked, parameter pArg must point to a value of ++** type int. If the changegroup currently contains zero changes, and the ++** value of the int variable is zero or greater than zero, then the ++** changegroup is configured to generate a changeset or patchset, ++** respectively. It is a no-op, not an error, if the changegroup is not ++** configured because it has already started accumulating changes. ++** ++** Before returning, the int variable is set to 0 if the changegroup is ++** configured to generate a changeset, or 1 if it is configured to generate ++** a patchset. ++*/ ++#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1 ++ ++ ++/* ++** CAPI3REF: Begin adding a change to a changegroup ++** ++** This API is used, in concert with other sqlite3changegroup_change_xxx() ++** APIs, to add changes to a changegroup object one at a time. To add a ++** single change, the caller must: ++** ++** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of ++** change (INSERT, UPDATE or DELETE), the affected table and whether ++** or not the change should be marked as indirect. ++** ++** 2. Invoke sqlite3changegroup_change_int64() or one of the other four ++** value functions - _null(), _double(), _text() or _blob() - one or ++** more times to specify old.* and new.* values for the change being ++** constructed. ++** ++** 3. Invoke sqlite3changegroup_change_finish() to either finish adding ++** the change to the group, or to discard the change altogether. ++** ++** The first argument to this function must be a pointer to the existing ++** changegroup object that the change will be added to. The second argument ++** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the ++** name of the table that the change affects, and the fourth is a boolean ++** flag specifying whether the change should be marked as "indirect" (if ++** bIndirect is non-zero) or not indirect (if bIndirect is zero). ++** ++** Following a successful call to this function, this function may not be ++** called again on the same changegroup object until after ++** sqlite3changegroup_change_finish() has been called. Doing so is an ++** SQLITE_MISUSE error. ++** ++** The changegroup object passed as the first argument must be already ++** configured with schema data for the specified table. It may be configured ++** either by calling sqlite3changegroup_schema() with a database that contains ++** the table, or sqlite3changegroup_add() with a changeset that contains the ++** table. If the changegroup object has not been configured with a schema for ++** the specified table when this function is called, SQLITE_ERROR is returned. ++** ++** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an ++** SQLite error code is returned. In this case, if argument pzErr is non-NULL, ++** then (*pzErr) may be set to point to a buffer containing a utf-8 formated, ++** nul-terminated, English language error message. It is the responsibility ++** of the caller to eventually free this buffer using sqlite3_free(). ++*/ ++SQLITE_API int sqlite3changegroup_change_begin( ++ sqlite3_changegroup*, ++ int eOp, ++ const char *zTab, ++ int bIndirect, ++ char **pzErr ++); ++ ++/* ++** CAPI3REF: Add a 64-bit integer to a changegroup ++** ++** This function may only be called between a successful call to ++** sqlite3changegroup_change_begin() and its matching ++** sqlite3changegroup_change_finish() call. If it is called at any ++** other time, it is an SQLITE_MISUSE error. Calling this function ++** specifies a 64-bit integer value to be used in the change currently being ++** added to the changegroup object passed as the first argument. ++** ++** The second parameter, bNew, specifies whether the value is to be part of ++** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of ++** the change under construction. If this does not match the type of change ++** specified by the preceding call to sqlite3changegroup_change_begin() (i.e. ++** an old.* value for an SQLITE_INSERT change, or a new.* value for an ++** SQLITE_DELETE), then SQLITE_ERROR is returned. ++** ++** The third parameter specifies the column of the old.* or new.* record that ++** the value will be a part of. If the specified table has an explicit primary ++** key, then this is the index of the table column, numbered from 0 in the order ++** specified within the CREATE TABLE statement. Or, if the table uses an ++** implicit rowid key, then the column 0 is the rowid and the explicit columns ++** are numbered starting from 1. If the iCol parameter is less than 0 or greater ++** than the index of the last column in the table, SQLITE_RANGE is returned. ++** ++** The fourth parameter is the integer value to use as part of the old.* or ++** new.* record. ++** ++** If this call is successful, SQLITE_OK is returned. Otherwise, if an ++** error occurs, an SQLite error code is returned. ++*/ ++SQLITE_API int sqlite3changegroup_change_int64( ++ sqlite3_changegroup*, ++ int bNew, ++ int iCol, ++ sqlite3_int64 iVal ++); ++ ++/* ++** CAPI3REF: Add a NULL to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). Except that ++** it configures the change currently under construction with a NULL value ++** instead of a 64-bit integer. ++*/ ++SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int); ++ ++/* ++** CAPI3REF: Add an double to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). Except that ++** it configures the change currently being constructed with a real value ++** instead of a 64-bit integer. ++*/ ++SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double); ++ ++/* ++** CAPI3REF: Add a text value to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). It configures ++** the currently accumulated change with a text value instead of a 64-bit ++** integer. Parameter pVal points to a buffer containing the text encoded using ++** utf-8. Parameter nVal may either be the size of the text value in bytes, or ++** else a negative value, in which case the buffer pVal points to is assumed to ++** be nul-terminated. ++*/ ++SQLITE_API int sqlite3changegroup_change_text( ++ sqlite3_changegroup*, int, int, const char *pVal, int nVal ++); ++ ++/* ++** CAPI3REF: Add a blob to a changegroup ++** ++** This function is similar to sqlite3changegroup_change_int64(). It configures ++** the currently accumulated change with a blob value instead of a 64-bit ++** integer. Parameter pVal points to a buffer containing the blob. Parameter ++** nVal is the size of the blob in bytes. ++*/ ++SQLITE_API int sqlite3changegroup_change_blob( ++ sqlite3_changegroup*, int, int, const void *pVal, int nVal ++); ++ ++/* ++** CAPI3REF: Finish adding one-at-at-time changes to a changegroup ++** ++** This function may only be called following a successful call to ++** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error. ++** ++** If parameter bDiscard is non-zero, then the current change is simply ++** discarded. In this case this function is always successful and SQLITE_OK ++** returned. ++** ++** If parameter bDiscard is zero, then an attempt is made to add the current ++** change to the changegroup. Assuming the changegroup is configured to ++** produce a changeset (not a patchset), this requires that: ++** ++** * If the change is an INSERT or DELETE, then a value must be specified ++** for all columns of the new.* or old.* record, respectively. ++** ++** * If the change is an UPDATE record, then values must be provided for ++** the PRIMARY KEY columns of the old.* record, but must not be provided ++** for PRIMARY KEY columns of the new.* record. ++** ++** * If the change is an UPDATE record, then for each non-PRIMARY KEY ++** column in the old.* record for which a value has been provided, a ++** value must also be provided for the same column in the new.* record. ++** Similarly, for each non-PK column in the old.* record for which ++** a value is not provided, a value must not be provided for the same ++** column in the new.* record. ++** ++** * All values specified for PRIMARY KEY columns must be non-NULL. ++** ++** Otherwise, it is an error. ++** ++** If the changegroup already contains a change for the same row (identified ++** by PRIMARY KEY columns), then the current change is combined with the ++** existing change in the same way as for sqlite3changegroup_add(). ++** ++** For a patchset, all of the above rules apply except that it doesn't matter ++** whether or not values are provided for the non-PK old.* record columns ++** for an UPDATE or DELETE change. This means that code used to produce ++** a changeset using the sqlite3changegroup_change_xxx() APIs may also ++** be used to produce patchsets. ++** ++** If the call is successful, SQLITE_OK is returned. Otherwise, if an error ++** occurs, an SQLite error code is returned. If an error is returned and ++** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer ++** containing a nul-terminated, utf-8 encoded, English language error message. ++** It is the responsibility of the caller to eventually free any such error ++** message buffer using sqlite3_free(). ++*/ ++SQLITE_API int sqlite3changegroup_change_finish( ++ sqlite3_changegroup*, ++ int bDiscard, ++ char **pzErr ++); ++ + /* + ** Make sure we can call this stuff from C++. + */ +diff --git a/deps/sqlite/sqlite3ext.h b/deps/sqlite/sqlite3ext.h +index 5258faae..cad1a2a0 100644 +--- a/deps/sqlite/sqlite3ext.h ++++ b/deps/sqlite/sqlite3ext.h +@@ -371,7 +371,11 @@ struct sqlite3_api_routines { + /* Version 3.51.0 and later */ + int (*set_errmsg)(sqlite3*,int,const char*); + int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); +- ++ /* Version 3.52.0 and later */ ++ void (*str_truncate)(sqlite3_str*,int); ++ void (*str_free)(sqlite3_str*); ++ int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*)); ++ int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*); + }; + + /* +@@ -710,6 +714,11 @@ typedef int (*sqlite3_loadext_entry)( + /* Version 3.51.0 and later */ + #define sqlite3_set_errmsg sqlite3_api->set_errmsg + #define sqlite3_db_status64 sqlite3_api->db_status64 ++/* Version 3.52.0 and later */ ++#define sqlite3_str_truncate sqlite3_api->str_truncate ++#define sqlite3_str_free sqlite3_api->str_free ++#define sqlite3_carray_bind sqlite3_api->carray_bind ++#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2 + #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + + #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) +-- +2.55.0 + diff --git a/SOURCES/0002-CVE-2026-42338-npm-ip-address-security-fix.patch b/SOURCES/0002-CVE-2026-42338-npm-ip-address-security-fix.patch deleted file mode 100644 index 9210882..0000000 --- a/SOURCES/0002-CVE-2026-42338-npm-ip-address-security-fix.patch +++ /dev/null @@ -1,166 +0,0 @@ -From d98f88cfa68abef0e57ec2b48df0049032e50c85 Mon Sep 17 00:00:00 2001 -From: Beau Gunderson -Date: Sun, 27 Apr 2026 10:28:29 -0700 -Subject: [PATCH] CVE-2026-42338 ip-address HTML escaping fix - -Fix HTML escaping in ip-address library to prevent XSS vulnerabilities. -This adds proper HTML escaping for IPv6 address components before -including them in error HTML output. - -Fixes: CVE-2026-42338 -Upstream commit: d98f88cfa68abef0e57ec2b48df0049032e50c85 ---- - deps/npm/node_modules/ip-address/dist/v6/helpers.js | 9 +++++++++ - deps/npm/node_modules/ip-address/dist/ipv6.js | 32 ++++++++++++++---------- - deps/npm/node_modules/ip-address/package.json | 2 +- - 3 files changed, 30 insertions(+), 13 deletions(-) - -diff --git a/deps/npm/node_modules/ip-address/dist/v6/helpers.js b/deps/npm/node_modules/ip-address/dist/v6/helpers.js -index 1234567..abcdefg 100644 ---- a/deps/npm/node_modules/ip-address/dist/v6/helpers.js -+++ b/deps/npm/node_modules/ip-address/dist/v6/helpers.js -@@ -1,14 +1,23 @@ - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+exports.escapeHtml = escapeHtml; - exports.spanAllZeroes = spanAllZeroes; - exports.spanAll = spanAll; - exports.spanLeadingZeroes = spanLeadingZeroes; - exports.simpleGroup = simpleGroup; -+function escapeHtml(s) { -+ return s -+ .replace(/&/g, '&') -+ .replace(//g, '>') -+ .replace(/"/g, '"') -+ .replace(/'/g, '''); -+} - /** - * @returns {String} the string with all zeroes contained in a - */ - function spanAllZeroes(s) { -- return s.replace(/(0+)/g, '$1'); -+ return escapeHtml(s).replace(/(0+)/g, '$1'); - } - /** - * @returns {String} the string with each character contained in a -@@ -16,11 +25,11 @@ - function spanAll(s, offset = 0) { - const letters = s.split(''); - return letters -- .map((n, i) => `${spanAllZeroes(n)}`) -+ .map((n, i) => `${spanAllZeroes(n)}`) - .join(''); - } - function spanLeadingZeroesSimple(group) { -- return group.replace(/^(0+)/, '$1'); -+ return escapeHtml(group).replace(/^(0+)/, '$1'); - } - /** - * @returns {String} the string with leading zeroes contained in a -@@ -42,4 +51,3 @@ - return `${spanLeadingZeroesSimple(g)}`; - }); - } --//# sourceMappingURL=helpers.js.map -\ No newline at end of file -diff --git a/deps/npm/node_modules/ip-address/dist/ipv6.js b/deps/npm/node_modules/ip-address/dist/ipv6.js -index 1234567..abcdefg 100644 ---- a/deps/npm/node_modules/ip-address/dist/ipv6.js -+++ b/deps/npm/node_modules/ip-address/dist/ipv6.js -@@ -17,13 +17,23 @@ - }) : function(o, v) { - o["default"] = v; - }); --var __importStar = (this && this.__importStar) || function (mod) { -- if (mod && mod.__esModule) return mod; -- var result = {}; -- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); -- __setModuleDefault(result, mod); -- return result; --}; -+var __importStar = (this && this.__importStar) || (function () { -+ var ownKeys = function(o) { -+ ownKeys = Object.getOwnPropertyNames || function (o) { -+ var ar = []; -+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; -+ return ar; -+ }; -+ return ownKeys(o); -+ }; -+ return function (mod) { -+ if (mod && mod.__esModule) return mod; -+ var result = {}; -+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); -+ __setModuleDefault(result, mod); -+ return result; -+ }; -+})(); - Object.defineProperty(exports, "__esModule", { value: true }); - exports.Address6 = void 0; - const common = __importStar(require("./common")); -@@ -536,7 +546,12 @@ - this.address4 = new ipv4_1.Address4(this.parsedAddress4); - for (let i = 0; i < this.address4.groups; i++) { - if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) { -- throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", address.replace(constants4.RE_ADDRESS, this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'))); -+ // The prefix groups haven't been through the bad-character check -+ // yet, so escape them before including in the error HTML. -+ const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'); -+ const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':'); -+ const separator = groups.length > 1 ? ':' : ''; -+ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`); - } - } - this.v4 = true; -@@ -896,10 +911,13 @@ - formFunction = this.to4in6; - } - const form = formFunction.call(this); -+ const safeHref = helpers.escapeHtml(`${options.prefix}${form}`); -+ const safeForm = helpers.escapeHtml(form); - if (options.className) { -- return `${form}`; -+ const safeClass = helpers.escapeHtml(options.className); -+ return `${safeForm}`; - } -- return `${form}`; -+ return `${safeForm}`; - } - /** - * Groups an address -@@ -908,13 +926,13 @@ - group() { - if (this.elidedGroups === 0) { - // The simple case -- return helpers.simpleGroup(this.address).join(':'); -+ return helpers.simpleGroup(this.addressMinusSuffix).join(':'); - } - assert(typeof this.elidedGroups === 'number'); - assert(typeof this.elisionBegin === 'number'); - // The elided case - const output = []; -- const [left, right] = this.address.split('::'); -+ const [left, right] = this.addressMinusSuffix.split('::'); - if (left.length) { - output.push(...helpers.simpleGroup(left)); - } -@@ -1000,4 +1018,3 @@ - } - } - exports.Address6 = Address6; --//# sourceMappingURL=ipv6.js.map -\ No newline at end of file -diff --git a/deps/npm/node_modules/ip-address/package.json b/deps/npm/node_modules/ip-address/package.json -index 1234567..abcdefg 100644 ---- a/deps/npm/node_modules/ip-address/package.json -+++ b/deps/npm/node_modules/ip-address/package.json -@@ -7,7 +7,7 @@ - "browser", - "validation" - ], -- "version": "10.1.0", -+ "version": "10.1.1", - "author": "Beau Gunderson (https://beaugunderson.com/)", - "license": "MIT", - "main": "dist/ip-address.js", diff --git a/SOURCES/0004-CVE-2026-13149-brace-expansion-unbound-recursion.patch b/SOURCES/0004-CVE-2026-13149-brace-expansion-unbound-recursion.patch deleted file mode 100644 index 80626ce..0000000 --- a/SOURCES/0004-CVE-2026-13149-brace-expansion-unbound-recursion.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 213dc171de329a09f34c7a3222cad723ee65d693 Mon Sep 17 00:00:00 2001 -From: RHEL Packaging Agent -Date: Tue, 14 Jul 2026 08:27:05 +0000 -Subject: [PATCH] CVE-2026-13149: Fix unbound recursion in brace-expansion - -A run of non-expanding {} groups expanded post once per group before the -early returns that never use it, doubling the work on every group. expand() -ran in O(2^n) and blocked for minutes on a ~90 byte input. - -Defer expanding post until a brace set is known to expand, and turn the -{a},b} restart into a loop so a long run of {} groups can't exhaust the -call stack. - -Adapted from upstream TypeScript fix to the JavaScript version (2.0.2) -vendored in Node.js. - -Upstream: https://github.com/juliangruber/brace-expansion/commit/c7e33ec ---- - .../npm/node_modules/brace-expansion/index.js | 49 ++++++++++++------- - 1 file changed, 32 insertions(+), 17 deletions(-) - -diff --git a/deps/npm/node_modules/brace-expansion/index.js b/deps/npm/node_modules/brace-expansion/index.js -index d084bac4..5d5f61ff 100644 ---- a/deps/npm/node_modules/brace-expansion/index.js -+++ b/deps/npm/node_modules/brace-expansion/index.js -@@ -99,21 +99,27 @@ function gte(i, y) { - function expand(str, max, isTop) { - var expansions = []; - -- var m = balanced('{', '}', str); -- if (!m) return [str]; -- -- // no need to expand pre, since it is guaranteed to be free of brace-sets -- var pre = m.pre; -- var post = m.post.length -- ? expand(m.post, max, false) -- : ['']; -- -- if (/\$$/.test(m.pre)) { -- for (var k = 0; k < post.length && k < max; k++) { -- var expansion = pre+ '{' + m.body + '}' + post[k]; -- expansions.push(expansion); -+ // The {a},b} rewrite below restarts expansion on a rewritten string with -+ // the same max and isTop = true. Loop instead of recursing so a long run -+ // of non-expanding {} groups can't exhaust the call stack. -+ for (;;) { -+ var m = balanced('{', '}', str); -+ if (!m) return [str]; -+ -+ // no need to expand pre, since it is guaranteed to be free of brace-sets -+ var pre = m.pre; -+ -+ if (/\$$/.test(m.pre)) { -+ var post = m.post.length -+ ? expand(m.post, max, false) -+ : ['']; -+ for (var k = 0; k < post.length && k < max; k++) { -+ var expansion = pre+ '{' + m.body + '}' + post[k]; -+ expansions.push(expansion); -+ } -+ return expansions; - } -- } else { -+ - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; -@@ -122,11 +128,20 @@ function expand(str, max, isTop) { - // {a},b} - if (m.post.match(/,(?!,).*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; -- return expand(str, max, true); -+ isTop = true; -+ continue; - } - return [str]; - } - -+ // Only expand post once we know this brace set actually expands. Computing -+ // it before the early returns above expanded post a second time on every -+ // non-expanding {}, which is what made inputs like a{},{},{}... blow up -+ // exponentially. -+ var post = m.post.length -+ ? expand(m.post, max, false) -+ : ['']; -+ - var n; - if (isSequence) { - n = m.body.split(/\.\./); -@@ -200,8 +215,8 @@ function expand(str, max, isTop) { - expansions.push(expansion); - } - } -- } - -- return expansions; -+ return expansions; -+ } - } - diff --git a/SPECS/nodejs.spec b/SPECS/nodejs.spec index d9f0b78..a905d56 100644 --- a/SPECS/nodejs.spec +++ b/SPECS/nodejs.spec @@ -67,7 +67,7 @@ # This is used by both the nodejs package and the npm subpackage that # has a separate version - the name is special so that rpmdev-bumpspec # will bump this rather than adding .1 to the end. -%global baserelease 2 +%global baserelease 3 %{?!_pkgdocdir:%global _pkgdocdir %{_docdir}/%{name}-%{version}} @@ -163,7 +163,7 @@ %global histogram_version 0.11.9 # sqlite – from deps/sqlite/sqlite3.h -%global sqlite_version 3.51.3 +%global sqlite_version 3.53.4 # Version: jq '.version' deps/undici/src/package.json %global undici_version 6.27.0 @@ -223,12 +223,14 @@ Source301: test-should-pass.txt Patch1: 0001-Remove-unused-OpenSSL-config.patch Patch2: 0002-fips-disable-options.patch -Patch3: 0001-CVE-2026-25547-braces-expansion.patch # npm deps patches -Patch4: 0002-CVE-2026-42338-npm-ip-address-security-fix.patch -Patch5: 0003-CVE-2026-59873-CVE-2026-59874-upgrade-bundled-tar-to-7.5.19.patch -Patch6: 0004-CVE-2026-13149-brace-expansion-unbound-recursion.patch - +Patch3: 0003-CVE-2026-59873-CVE-2026-59874-upgrade-bundled-tar-to-7.5.19.patch +# CVE-2026-11824 and CVE-2026-11822 +Patch4: 0001-update-sqlite-to-3.53.4.patch +# CVE-2026-69192-CVE-2026-54272 within deps/npm/../ip-address +Patch5: 0001-CVE-2026-69192-CVE-2026-54272-ip-address-10.4.0.patch +# Brace-expansion rebase to 2.1.4 +Patch6: 0001-CVE-2026-69152-brace-expansion-2.1.4.patch %global pkgname nodejs BuildRequires: make @@ -959,6 +961,16 @@ end %changelog +* Wed Aug 5 2026 Tomas Juhasz - 1:22.23.1-3 +- deps: update npm/ip-address to 10.4.0 +- deps: update npm/brace-expansion to 2.1.4 + Fix: CVE-2026-69192 & CVE-2026-54272 CVE-2026-69152 + +* Fri Jul 31 2026 Andrei Radchenko - 1:22.23.1-3 +- Backport patch: update sqlite to 3.53.4 + Fix: CVE-2026-11824, CVE-2026-11822 + Resolves: RHEL-224135 RHEL-224144 + * Thu Jul 23 2026 Jan Staněk - 1:22.23.1-2 - Backport patches for various CVEs Fixes: CVE-2026-59873 CVE-2026-59874 CVE-2026-13149