Index: function.c ================================================================== --- function.c +++ function.c @@ -840,11 +840,11 @@ cur->unique=0; cur->eof=0; cur->arg[0]=idxNum; cur->arg[1]=0; cur->arg[2]=cur->arg[3]=1; - if(!nobjects) { + if(idxNum==-1 || !nobjects) { cur->eof=1; return SQLITE_OK; } if(idxStr) for(i=0;idxStr[i];i++) switch(idxStr[i]) { case 'a': @@ -899,10 +899,15 @@ cur->rowid=objects[t]->up; if(cur->rowid==VOIDLINK) cur->eof=1; cur->unique=1; } break; + case 'h': + if(sqlite3_value_type(argv[i])==SQLITE_INTEGER) { + if(sqlite3_value_int64(argv[i])!=(pcur->pVtab==bizarro_vtab?1:0)) cur->eof=1; + } + break; } if(cur->unique) { if(cur->rowid<0 || cur->rowid>=nobjects || !objects[cur->rowid]) cur->eof=1; return SQLITE_OK; } @@ -913,10 +918,11 @@ return vt1_objects_next(pcur); } static int vt1_objects_index(sqlite3_vtab*vt,sqlite3_index_info*info) { sqlite3_str*str=sqlite3_str_new(0); + sqlite3_value*v; int arg=0; int i,j; info->estimatedCost=100000.0; for(i=0;inConstraint;i++) if(info->aConstraint[i].usable) { j=info->aConstraint[i].op; @@ -974,10 +980,29 @@ info->idxNum|=0x0010; info->aConstraintUsage[i].omit=1; info->aConstraintUsage[i].argvIndex=++arg; sqlite3_str_appendchar(str,1,'g'); info->estimatedCost/=80.0; + } + break; + case 12: // BIZARRO + if(j==SQLITE_INDEX_CONSTRAINT_EQ || j==SQLITE_INDEX_CONSTRAINT_IS) { + if(!sqlite3_vtab_rhs_value(info,i,&v) && sqlite3_value_type(v)==SQLITE_INTEGER && sqlite3_value_int64(v)!=(vt==bizarro_vtab?1:0)) { + empty: + info->idxNum=-1; + info->aConstraintUsage[i].omit=1; + info->idxFlags=SQLITE_INDEX_SCAN_UNIQUE; + info->estimatedCost=1.0; + info->estimatedRows=0; + info->orderByConsumed=1; + sqlite3_free(sqlite3_str_finish(str)); + return SQLITE_OK; + } else { + info->aConstraintUsage[i].argvIndex=++arg; + sqlite3_str_appendchar(str,1,'h'); + info->estimatedCost/=20.0; + } } break; } } if(info->nOrderBy==1) {