Uploaded image for project: 'Cassandra'
  1. Cassandra
  2. CASSANDRA-16592

The token function in where clause return incorrect data when using token equal condition and Specified a non-exist token value

Agile BoardAttach filesAttach ScreenshotBulk Copy AttachmentsBulk Move AttachmentsVotersWatch issueWatchersCreate sub-taskConvert to sub-taskMoveLinkCloneLabelsUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Code - Bug - Unclear Impact
    • Normal
    • Normal
    • Code Inspection
    • All
    • None

    Description

      I get incorrect value when use query like 'select Token(pk1,pk2),pk1,pk2 from ks.table1 where token(pk1,pk2) = tokenValue'. The returned token value mismatch the where condition.

      This problem is reproduced in 3.11.3 and 4.0.

      Here is my schema and select statement

      // schema
      cqlsh> desc testprefix.cprefix_03 ;CREATE TABLE testprefix.cprefix_03 (
          pk1 int,
          pk2 int,
          ck1 text,
          ck2 text,
          t1 int,
          PRIMARY KEY ((pk1, pk2), ck1, ck2)
      ) WITH CLUSTERING ORDER BY (ck1 ASC, ck2 ASC)
          AND additional_write_policy = '99p'
          AND bloom_filter_fp_chance = 0.01
          AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
          AND cdc = false
          AND comment = ''
          AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
          AND compression = {'chunk_length_in_kb': '16', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
          AND crc_check_chance = 1.0
          AND default_time_to_live = 0
          AND extensions = {}
          AND gc_grace_seconds = 864000
          AND max_index_interval = 2048
          AND memtable_flush_period_in_ms = 0
          AND min_index_interval = 128
          AND read_repair = 'BLOCKING'
          AND speculative_retry = '99p';
      
      
      

      execute cql query

      // code placeholder
      cqlsh> SELECT Token(pk1,pk2), pk1,pk2  from testprefix.cprefix_03 WHERE  token(pk1, pk2) =-9223372036854775808 LIMIT 2; 
      system.token(pk1, pk2) | pk1    | pk2
      ------------------------+--------+---------
         -9222849988925915479 | 394560 | 3394560
         -9222849988925915479 | 394560 | 3394560
      (2 rows)
      
      cqlsh> SELECT Token(pk1,pk2) from testprefix.cprefix_03 where pk1 = 394560 and pk2 = 3394560 LIMIT 2; 
      system.token(pk1, pk2)
      ------------------------
         -9222849988925915479
         -9222849988925915479
      (2 rows)
      
      cqlsh> SELECT Token(pk1,pk2), pk1,pk2  from testprefix.cprefix_03 WHERE  token(pk1, pk2) =-9222849988925915479 LIMIT 2; 
      system.token(pk1, pk2) | pk1    | pk2
      ------------------------+--------+---------
         -9222849988925915479 | 394560 | 3394560
         -9222849988925915479 | 394560 | 3394560
      (2 rows)

      we can find  that token value in the condition  are inconsistent with the values in the result.

      --------------------------------------------------------------------------------------------

      Then review the source code, to seek the anwser. 

      // code placeholder
      private static void addRange(SSTableReader sstable, AbstractBounds<PartitionPosition> requested, List<AbstractBounds<PartitionPosition>> boundsList)
      {
          if (requested instanceof Range && ((Range)requested).isWrapAround())    //  first condition
          {
              if (requested.right.compareTo(sstable.first) >= 0)
              {
                  // since we wrap, we must contain the whole sstable prior to stopKey()
                  Boundary<PartitionPosition> left = new Boundary<PartitionPosition>(sstable.first, true);
                  Boundary<PartitionPosition> right;
                  right = requested.rightBoundary();
                  right = minRight(right, sstable.last, true);
                  if (!isEmpty(left, right))
                      boundsList.add(AbstractBounds.bounds(left, right));
              }
              if (requested.left.compareTo(sstable.last) <= 0)
              {
                  // since we wrap, we must contain the whole sstable after dataRange.startKey()
                  Boundary<PartitionPosition> right = new Boundary<PartitionPosition>(sstable.last, true);
                  Boundary<PartitionPosition> left;
                  left = requested.leftBoundary();
                  left = maxLeft(left, sstable.first, true); // second condition
                  if (!isEmpty(left, right))
                      boundsList.add(AbstractBounds.bounds(left, right));
              }
          }
          else
          {
              assert requested.left.compareTo(requested.right) <= 0 || requested.right.isMinimum();
              Boundary<PartitionPosition> left, right;
              left = requested.leftBoundary();
              right = requested.rightBoundary();
              left = maxLeft(left, sstable.first, true);
              // apparently isWrapAround() doesn't count Bounds that extend to the limit (min) as wrapping
              right = requested.right.isMinimum() ? new Boundary<PartitionPosition>(sstable.last, true)
                                                      : minRight(right, sstable.last, true);
              if (!isEmpty(left, right))
                  boundsList.add(AbstractBounds.bounds(left, right));
          }
      }
      
      • we use token equal ,so isWrapAround is true.
      • requestd.left = requestd.right = -9223372036854775808,
      • the real sst dataBoundary.left = -9222849988925915479
      • so the maxLeft return the real dataBoudary.left. We get the incorrect  data

       

      Attachments

        Issue Links

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned Assign to me
            cimon cimon
            Ekaterina Dimitrova, Michael Semb Wever
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment