Fixes #769, Pages "is less than" in Advanced Search appears to never return results

Addresses #775, Convert integers stored in DB as strings to integers

The Pages bug was actually a big broader and more complex. We were accidentally storing all values--including integer values--as strings, so the less-than operator didn't work on them (and the greater-than operator was matching most values, since "1"<"A").

Fixed by storing integers (up to 64-bits) not beginning with 0 as integers, casting numeric strings to integers for < and > comparisons, and using 'LIKE' instead of '=' for comparison of numeric search values for the "is"/"isNot" conditions. In 1.5, we'll handle #775.
This commit is contained in:
Dan Stillman 2007-09-24 06:52:52 +00:00
parent db694f8003
commit f78014ab2a
2 changed files with 60 additions and 7 deletions

View File

@ -792,9 +792,29 @@ Zotero.Item.prototype.save = function(){
Zotero.DB.query(sql, {int: valueID});
}
else {
if (Zotero.ItemFields.isInteger(fieldID)) {
insertStatement.
bindInt32Parameter(1, value);
// DISABLED
//if (Zotero.ItemFields.isInteger(fieldID)) {
// If integer not beginning with 0, bind as integer
//
// If this is changed, search.js also needs to
// change
if (value.match(/^[1-9]+[0-9]*$/)) {
// Store as 32-bit signed integer
if (value <= 2147483647) {
insertStatement.
bindInt32Parameter(1, value);
}
// Store as 64-bit signed integer
else if (value < 9223372036800000000) {
insertStatement.
bindInt64Parameter(1, value);
}
// Store as string if larger then 64-bit
else {
insertStatement.
bindUTF8StringParameter(1, value);
}
}
else {
insertStatement.

View File

@ -819,6 +819,7 @@ Zotero.Search.prototype._buildQuery = function(){
condSQL += "valueID IN (SELECT valueID FROM "
+ "itemDataValues WHERE ";
openParens++;
break;
@ -928,13 +929,17 @@ Zotero.Search.prototype._buildQuery = function(){
// Special handling for date fields
//
// Note: We assume full datetimes are already UTC and don't
// need to be handle specially
// need to be handled specially
if ((condition['name']=='dateAdded' ||
condition['name']=='dateModified' ||
condition['name']=='datefield') &&
!Zotero.Date.isSQLDateTime(condition['value'])){
// TODO: document parseDate, alt, and useFreeform
// TODO: document these flags
var parseDate = null;
var alt = null;
var useFreeform = null;
switch (condition['operator']){
case 'is':
case 'isNot':
@ -1051,7 +1056,26 @@ Zotero.Search.prototype._buildQuery = function(){
// Non-date fields
else {
condSQL += condition['field'];
switch (condition.operator) {
// Cast strings as integers for < and > comparisons,
// at least until
case 'isLessThan':
case 'isGreaterThan':
condSQL += "CAST(" + condition['field'] + " AS INT)";
// Make sure either field is an integer or
// converting to an integer and back to a string
// yields the same result (i.e. it's numeric)
var opAppend = " AND (TYPEOF("
+ condition['field'] + ") = 'integer' OR "
+ "CAST("
+ "CAST(" + condition['field'] + " AS INT)"
+ " AS STRING) = " + condition['field'] + ")"
break;
default:
condSQL += condition['field'];
}
switch (condition['operator']){
case 'contains':
case 'doesNotContain': // excluded with NOT IN above
@ -1070,7 +1094,14 @@ Zotero.Search.prototype._buildQuery = function(){
case 'is':
case 'isNot': // excluded with NOT IN above
condSQL += '=?';
// Automatically cast values which might
// have been stored as integers
if (condition.value.match(/^[1-9]+[0-9]*$/)) {
condSQL += ' LIKE ?';
}
else {
condSQL += '=?';
}
condSQLParams.push(condition['value']);
break;
@ -1082,11 +1113,13 @@ Zotero.Search.prototype._buildQuery = function(){
case 'isLessThan':
condSQL += '<?';
condSQLParams.push({int:condition['value']});
condSQL += opAppend;
break;
case 'isGreaterThan':
condSQL += '>?';
condSQLParams.push({int:condition['value']});
condSQL += opAppend;
break;
// Next two only used with full datetimes