aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-05-18 20:00:08 +0000
committerdrh <>2024-05-18 20:00:08 +0000
commit04624990514ae7c593ad224dd87cd9037cec752f (patch)
tree88e3ed5bd9703df77b9193cf3594eb557d049a70 /src
parent79dac84b315ced19266d55f769341782f429e6b4 (diff)
downloadsqlite-04624990514ae7c593ad224dd87cd9037cec752f.tar.gz
sqlite-04624990514ae7c593ad224dd87cd9037cec752f.zip
Fix the definition of sqlite3_vtab_distinct() such that return codes 2 and
3 mean that all rows must be distinct over "colUsed" which is a superset of "aOrderBy". Also, disallow return codes 2 and 3 if the rowid of the virtual table is accessed. FossilOrigin-Name: 922731ce98c0ce7837784ff7966049e59fa73da2aa04abf3506503b6fc4aa048
Diffstat (limited to 'src')
-rw-r--r--src/resolve.c8
-rw-r--r--src/sqlite.h.in16
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/treeview.c6
-rw-r--r--src/where.c2
5 files changed, 21 insertions, 12 deletions
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/sqlite.h.in b/src/sqlite.h.in
index d553abb7b..459af929b 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -9942,20 +9942,22 @@ 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
+** order, as long as rows with the same values in all "colUsed" columns
** are adjacent.)^ ^(Furthermore, only a single row for each particular
-** combination of values in the columns identified by the "aOrderBy" field
+** combination of values in the columns identified by the "colUsed" 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
+** values in all "colUsed" 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".
+** that have the same value for all columns identified by "colUsed".
** ^However omitting the extra rows is optional.
** 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
+** that the query planner needs only rows that are distinct over the
+** set of columns defined by "colUsed" but it does need the
+** rows to be sorted according to the order defined by "aOrderBy".)^
+** ^The virtual table implementation is free to omit
+** rows that are identical in all "colUsed" columns, if it wants to, but
** it is not required to omit any rows. This mode is used for queries
** that have both DISTINCT and ORDER BY clauses.
** </ol>
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 d3346b468..fa9eac614 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/where.c b/src/where.c
index 13a362dcc..fac0f6c5e 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;