SQLite

Check-in [507890a913]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 507890a9139875b1b594225c432c714f67312c0e
User & Date: dan 2009-12-04 19:07:25.000
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: 04fc9c7661 user: drh tags: trunk)
19:07
Fix a problem involving a 3-way NEAR query. (check-in: 507890a913 user: dan tags: trunk)
14:25
In the OSTRACE debugging macros in os_unix.c, identify the VFS currently in use. (check-in: 082b8da005 user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to ext/fts3/fts3.c.
1047
1048
1049
1050
1051
1052
1053


1054
1055
1056
1057
1058
1059
1060
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062







+
+







  }
  *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;
1102
1103
1104
1105
1106
1107
1108






1109
1110






1111
1112
1113
1114
1115
1116
1117
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







+
+
+
+
+
+


+
+
+
+
+
+







          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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  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.
  #
167
168
169
170
171
172
173
174
175
176
177
178












179
180
181
182
183
184
185
186
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







-



-
+
+
+
+
+
+
+
+
+
+
+
+








      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 {
      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