trace_processor: fix comparision of sqlvalues and add neq db constraint

Context: go/perfetto-tp-refactor
Bug: 135177627
Change-Id: Id2547c6fb9388bdcb3e5fc1a1834c76963c9ff96
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 8bd946d..4c0f951 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -66,8 +66,8 @@
 
   int Compare(const SqlValue& value) const {
     // TODO(lalitm): this is almost the same as what SQLite does with the
-    // exception of comparisons between long and double - we choose (for
-    // performance reasons) to omit comparisons between them.
+    // exception of comparisions between long and double - we choose (for
+    // performance reasons) to omit comparisions between them.
     if (type != value.type)
       return type - value.type;
 
@@ -75,9 +75,11 @@
       case Type::kNull:
         return 0;
       case Type::kLong:
-        return signbit(long_value - value.long_value);
-      case Type::kDouble:
-        return signbit(double_value - value.double_value);
+        return static_cast<int>(long_value - value.long_value);
+      case Type::kDouble: {
+        double diff = double_value - value.double_value;
+        return diff < 0 ? -1 : (diff > 0 ? 1 : 0);
+      }
       case Type::kString:
         return strcmp(string_value, value.string_value);
       case Type::kBytes: {
@@ -85,7 +87,7 @@
         int ret = memcmp(bytes_value, value.bytes_value, bytes);
         if (ret != 0)
           return ret;
-        return signbit(bytes_count - value.bytes_count);
+        return static_cast<int>(bytes_count - value.bytes_count);
       }
     }
     PERFETTO_FATAL("For GCC");
diff --git a/src/trace_processor/db/column.cc b/src/trace_processor/db/column.cc
index 9e46036..91b22ef 100644
--- a/src/trace_processor/db/column.cc
+++ b/src/trace_processor/db/column.cc
@@ -66,6 +66,9 @@
     case FilterOp::kGt:
       iv->RemoveIf([this, value](uint32_t row) { return Get(row) <= value; });
       break;
+    case FilterOp::kNeq:
+      iv->RemoveIf([this, value](uint32_t row) { return Get(row) == value; });
+      break;
   }
 }
 
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index 8930ba8..3f4b717 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -30,8 +30,9 @@
 namespace trace_processor {
 
 // Represents the possible filter operations on a column.
-enum FilterOp {
+enum class FilterOp {
   kEq,
+  kNeq,
   kGt,
   kLt,
 };
@@ -186,6 +187,9 @@
   Constraint lt(SqlValue value) const {
     return Constraint{col_idx_, FilterOp::kLt, value};
   }
+  Constraint neq(SqlValue value) const {
+    return Constraint{col_idx_, FilterOp::kNeq, value};
+  }
 
   // Returns an Order for each Order type for this Column.
   Order ascending() const { return Order{col_idx_, false}; }
diff --git a/src/trace_processor/sqlite/db_sqlite_table.cc b/src/trace_processor/sqlite/db_sqlite_table.cc
index 8853984..a288918 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.cc
+++ b/src/trace_processor/sqlite/db_sqlite_table.cc
@@ -32,6 +32,8 @@
       return FilterOp::kGt;
     case SQLITE_INDEX_CONSTRAINT_LT:
       return FilterOp::kLt;
+    case SQLITE_INDEX_CONSTRAINT_NE:
+      return FilterOp::kNeq;
     default:
       PERFETTO_FATAL("Currently unsupported constraint");
   }