aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/json.c9
-rw-r--r--src/resolve.c8
-rw-r--r--src/shell.c.in2
-rw-r--r--src/sqlite.h.in47
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/treeview.c6
-rw-r--r--src/vdbemem.c2
-rw-r--r--src/where.c2
-rw-r--r--src/wherecode.c2
9 files changed, 50 insertions, 29 deletions
diff --git a/src/json.c b/src/json.c
index 44ae84646..4db468c92 100644
--- a/src/json.c
+++ b/src/json.c
@@ -3795,13 +3795,6 @@ static void jsonArrayLengthFunc(
jsonParseFree(p);
}
-/* True if the string is all digits */
-static int jsonAllDigits(const char *z, int n){
- int i;
- for(i=0; i<n && sqlite3Isdigit(z[i]); i++){}
- return i==n;
-}
-
/* True if the string is all alphanumerics and underscores */
static int jsonAllAlphanum(const char *z, int n){
int i;
@@ -3866,7 +3859,7 @@ static void jsonExtractFunc(
** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
*/
jsonStringInit(&jx, ctx);
- if( jsonAllDigits(zPath, nPath) ){
+ if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){
jsonAppendRawNZ(&jx, "[", 1);
jsonAppendRaw(&jx, zPath, nPath);
jsonAppendRawNZ(&jx, "]", 2);
diff --git a/src/resolve.c b/src/resolve.c
index 546731afe..bf8326aa6 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -828,8 +828,12 @@ static int lookupName(
** If a generated column is referenced, set bits for every column
** of the table.
*/
- if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){
- pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
+ if( pMatch ){
+ if( pExpr->iColumn>=0 ){
+ pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
+ }else{
+ pMatch->fg.rowidUsed = 1;
+ }
}
pExpr->op = eNewExprOp;
diff --git a/src/shell.c.in b/src/shell.c.in
index 298485344..0029682f3 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -7943,7 +7943,7 @@ static struct {
int nHit; /* Number of hits seen so far */
int nRepeat; /* Turn off after this many hits. 0 for never */
int nSkip; /* Skip this many before first fault */
-} faultsim_state = {-1, 0, 0, 0, 0, 0, 0};
+} faultsim_state = {-1, 0, 0, 0, 0, 0, 0, 0};
/*
** This is the fault-sim callback
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index d553abb7b..549b52a15 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -9942,24 +9942,45 @@ const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
** <li value="2"><p>
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
** that the query planner does not need the rows returned in any particular
-** order, as long as rows with the same values in all "aOrderBy" columns
-** are adjacent.)^ ^(Furthermore, only a single row for each particular
-** combination of values in the columns identified by the "aOrderBy" field
-** needs to be returned.)^ ^It is always ok for two or more rows with the same
-** values in all "aOrderBy" columns to be returned, as long as all such rows
-** are adjacent. ^The virtual table may, if it chooses, omit extra rows
-** that have the same value for all columns identified by "aOrderBy".
-** ^However omitting the extra rows is optional.
+** order, as long as rows with the same values in all columns identified
+** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows
+** contain the same values for all columns identified by "colUsed", all but
+** one such row may optionally be omitted from the result.)^
+** The virtual table is not required to omit rows that are duplicates
+** over the "colUsed" columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
** This mode is used for a DISTINCT query.
** <li value="3"><p>
-** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
-** that the query planner needs only distinct rows but it does need the
-** rows to be sorted.)^ ^The virtual table implementation is free to omit
-** rows that are identical in all aOrderBy columns, if it wants to, but
-** it is not required to omit any rows. This mode is used for queries
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the
+** virtual table must return rows in the order defined by "aOrderBy" as
+** if the sqlite3_vtab_distinct() interface had returned 0. However if
+** two or more rows in the result have the same values for all columns
+** identified by "colUsed", then all but one such row may optionally be
+** omitted.)^ Like when the return value is 2, the virtual table
+** is not required to omit rows that are duplicates over the "colUsed"
+** columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
+** This mode is used for queries
** that have both DISTINCT and ORDER BY clauses.
** </ol>
**
+** <p>The following table summarizes the conditions under which the
+** virtual table is allowed to set the "orderByConsumed" flag based on
+** the value returned by sqlite3_vtab_distinct(). This table is a
+** restatement of the previous four paragraphs:
+**
+** <table border=1 cellspacing=0 cellpadding=10 width="90%">
+** <tr>
+** <td valign="top">sqlite3_vtab_distinct() return value
+** <td valign="top">Rows are returned in aOrderBy order
+** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent
+** <td valign="top">Duplicates over all colUsed columns may be omitted
+** <tr><td>0<td>yes<td>yes<td>no
+** <tr><td>1<td>no<td>yes<td>no
+** <tr><td>2<td>no<td>yes<td>yes
+** <tr><td>3<td>yes<td>yes<td>yes
+** </table>
+**
** ^For the purposes of comparing virtual table output values to see if the
** values are same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index aa8bfc4b7..d98a4f7f0 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3312,6 +3312,7 @@ struct SrcItem {
unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
+ unsigned rowidUsed :1; /* The ROWID of this table is referenced */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
union {
diff --git a/src/treeview.c b/src/treeview.c
index 586106cad..4dcc130cd 100644
--- a/src/treeview.c
+++ b/src/treeview.c
@@ -194,8 +194,10 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
x.printfFlags |= SQLITE_PRINTF_INTERNAL;
sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s",
+ pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab,
+ pItem->colUsed,
+ pItem->fg.rowidUsed ? "+rowid" : "");
}
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 8a4011e10..8e2aa4a6c 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -1959,7 +1959,7 @@ int sqlite3Stat4Column(
assert( iCol>0 );
iHdr = getVarint32(a, nHdr);
- if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
+ if( nHdr>(u32)nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
iField = nHdr;
for(i=0; i<=iCol; i++){
iHdr += getVarint32(&a[iHdr], t);
diff --git a/src/where.c b/src/where.c
index 07c5b9cf9..a266b51d0 100644
--- a/src/where.c
+++ b/src/where.c
@@ -1416,7 +1416,7 @@ static sqlite3_index_info *allocateIndexInfo(
}
if( i==n ){
nOrderBy = n;
- if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
+ if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){
eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
}else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
eDistinct = 1;
diff --git a/src/wherecode.c b/src/wherecode.c
index 4aca6eb62..a620a5ac0 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1436,7 +1436,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
- VdbeComment((v, "init LEFT JOIN no-match flag"));
+ VdbeComment((v, "init LEFT JOIN match flag"));
}
/* Compute a safe address to jump to if we discover that the table for