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 ScreenshotAdd voteVotersWatch issueWatchersCreate sub-taskConvert to sub-taskMoveLinkCloneLabelsUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Normal
    • Resolution: Unresolved
    • Fix Version/s: 3.0.x, 3.11.x, 4.0.x
    • Component/s: Legacy/CQL
    • Labels:
      None
    • Bug Category:
      Code - Bug - Unclear Impact
    • Severity:
      Normal
    • Complexity:
      Normal
    • Discovered By:
      Code Inspection
    • Platform:
      All
    • Impacts:
      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

          Activity

            People

            • Assignee:
              cimon cimon Assign to me
              Reporter:
              cimon cimon
              Authors:
              cimon
              Reviewers:
              Ekaterina Dimitrova, Michael Semb Wever

              Dates

              • Created:
                Updated:

                Issue deployment