/ Check-in [507890a9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a problem involving a 3-way NEAR query.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:507890a9139875b1b594225c432c714f67312c0e
User & Date: dan 2009-12-04 19:07:25
Context
2009-12-04
22:51
Remove an assert() in btree.c:releasePage() that is not necessarily true when the btree is recovering from an OOM that occurs in the middle of a balance(). check-in: 04fc9c76 user: drh tags: trunk
19:07
Fix a problem involving a 3-way NEAR query. check-in: 507890a9 user: dan tags: trunk
14:25
In the OSTRACE debugging macros in os_unix.c, identify the VFS currently in use. check-in: 082b8da0 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

1047
1048
1049
1050
1051
1052
1053


1054
1055
1056
1057
1058
1059
1060
....
1102
1103
1104
1105
1106
1107
1108






1109
1110






1111
1112
1113
1114
1115
1116
1117
  }
  *ppPoslist = pEnd;
}

static void fts3ColumnlistCopy(char **pp, char **ppPoslist){
  char *pEnd = *ppPoslist;
  char c = 0;


  while( 0xFE & (*pEnd | c) ) c = *pEnd++ & 0x80;
  if( pp ){
    int n = (int)(pEnd - *ppPoslist);
    char *p = *pp;
    memcpy(p, *ppPoslist, n);
    p += n;
    *pp = p;
................................................................................
          fts3GetDeltaVarint(&p2, &i2); i2 -= 2;
        }
        fts3PutDeltaVarint(&p, &iPrev, (i1<i2 ? i1 : i2) + 2); iPrev -= 2;
        if( 0==(*p1&0xFE) ) i1 = 0x7FFFFFFF;
        if( 0==(*p2&0xFE) ) i2 = 0x7FFFFFFF;
      }
    }else if( iCol1<iCol2 ){






      fts3ColumnlistCopy(&p, &p1);
    }else{






      fts3ColumnlistCopy(&p, &p2);
    }
  }

  *p++ = '\0';
  *pp = p;
  *pp1 = p1 + 1;







>
>







 







>
>
>
>
>
>


>
>
>
>
>
>







1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
....
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
  }
  *ppPoslist = pEnd;
}

static void fts3ColumnlistCopy(char **pp, char **ppPoslist){
  char *pEnd = *ppPoslist;
  char c = 0;

  /* A column-list is terminated by either a 0x01 or 0x00. */
  while( 0xFE & (*pEnd | c) ) c = *pEnd++ & 0x80;
  if( pp ){
    int n = (int)(pEnd - *ppPoslist);
    char *p = *pp;
    memcpy(p, *ppPoslist, n);
    p += n;
    *pp = p;
................................................................................
          fts3GetDeltaVarint(&p2, &i2); i2 -= 2;
        }
        fts3PutDeltaVarint(&p, &iPrev, (i1<i2 ? i1 : i2) + 2); iPrev -= 2;
        if( 0==(*p1&0xFE) ) i1 = 0x7FFFFFFF;
        if( 0==(*p2&0xFE) ) i2 = 0x7FFFFFFF;
      }
    }else if( iCol1<iCol2 ){
      if( iCol1 ){
        int n = sqlite3Fts3PutVarint(&p[1], iCol1);
        *p = 0x01;
        p += n+1;
        p1 += n+1;
      }
      fts3ColumnlistCopy(&p, &p1);
    }else{
      if( iCol2 ){
        int n = sqlite3Fts3PutVarint(&p[1], iCol2);
        *p = 0x01;
        p += n+1;
        p2 += n+1;
      }
      fts3ColumnlistCopy(&p, &p2);
    }
  }

  *p++ = '\0';
  *pp = p;
  *pp1 = p1 + 1;

Changes to test/fts3rnd.test.

87
88
89
90
91
92
93































94
95
96
97
98
99
100
...
167
168
169
170
171
172
173
174
175
176
177
178











179
180
181
182
183
184
185
186
  foreach {key value} [array get ::t1] {
    if {[string match $pattern $value]} { lappend ret $key }
  }
  lsort -integer $ret
}

proc simple_near {termlist nNear} {































}

foreach nodesize {50 500 1000 2000} {
  catch { array unset ::t1 }

  # Create the FTS3 table. Populate it (and the Tcl array) with 100 rows.
  #
................................................................................
      do_test fts3rnd-1.$nodesize.$iTest.4.$i {
        execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
      } [simple_term $term]
    }

    # A NEAR query with terms as the arguments.
    #
if 0 {
    for {set i 0} {$i < 10} {incr i} {
      set terms [list [random_term] [random_term]]
      set match [join $terms " NEAR "]
      do_test fts3rnd-1.$nodesize.$iTest.5.$i {











        execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
      } [simple_near $terms 10]
    }
}
  }
}

finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<



|
>
>
>
>
>
>
>
>
>
>
>








87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  foreach {key value} [array get ::t1] {
    if {[string match $pattern $value]} { lappend ret $key }
  }
  lsort -integer $ret
}

proc simple_near {termlist nNear} {
  set ret [list]

  # List of nNear+1 elements that contains no terms.
  #
  set dummyfields "[string repeat "X " $nNear]X"

  foreach {key value} [array get ::t1] {
    foreach v $value {
      set v [concat $dummyfields $v $dummyfields]

      set l [lsearch -exact -all $v [lindex $termlist 0]]
      foreach T [lrange $termlist 1 end] {
        set l2 [list]
        foreach i $l {
          set iStart [expr $i - $nNear - 1]
          set iEnd [expr $i + $nNear + 1]
          foreach i2 [lsearch -exact -all [lrange $v $iStart $iEnd] $T] {
            incr i2 $iStart
            if {$i2 != $i} { lappend l2 $i2 } 
          }
        }
        set l $l2
      }

      if {[llength $l]} {
        lappend ret $key
      } 
    }
  }

  lsort -unique -integer $ret
}

foreach nodesize {50 500 1000 2000} {
  catch { array unset ::t1 }

  # Create the FTS3 table. Populate it (and the Tcl array) with 100 rows.
  #
................................................................................
      do_test fts3rnd-1.$nodesize.$iTest.4.$i {
        execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
      } [simple_term $term]
    }

    # A NEAR query with terms as the arguments.
    #

    for {set i 0} {$i < 10} {incr i} {
      set terms [list [random_term] [random_term]]
      set match [join $terms " NEAR "]
      do_test fts3rnd-1.$nodesize.$iTest.5.$i.$match {
        execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
      } [simple_near $terms 10]
    }
 
if 0 {
    # A 3-way NEAR query with terms as the arguments.
    #
    for {set i 0} {$i < 10} {incr i} {
      set terms [list [random_term] [random_term] [random_term]]
      set match [join $terms " NEAR "]
      do_test fts3rnd-1.$nodesize.$iTest.5.$i.$match {
        execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
      } [simple_near $terms 10]
    }
}
  }
}

finish_test