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:
parent
db694f8003
commit
f78014ab2a
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user