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

Capital P gets confused in the parser for a Duration in places where IDENT are needed

    XMLWordPrintableJSON

Details

    • Correctness - API / Semantic Definition
    • Normal
    • Low Hanging Fruit
    • Fuzz Test
    • All
    • None
    • Hide

      Pull requests

      Source code changes
      There was a change in the Lexer.g.
      Capital letter "P" is no longer a valid representation for 0 duration. It has to comply with https://en.wikipedia.org/wiki/ISO_8601#Durations (see Benjamin Lerer's comment).
      A couple of examples for valid 0 duration representation are:

      PT0S
      P0D
      PT0H
      P0W
      P0Y0M0DT0H0M0S
      

      Unit tests changes
      The following tests have been expanded with new logic to cover the ticket's changes:

      • org.apache.cassandra.cql3.validation.operations.CreateTest
      • org.apache.cassandra.cql3.validation.operations.DropTest
      • org.apache.cassandra.cql3.validation.operations.InsertTest

      Manual test case flow
      Let's go through the case where we create a "P" keyspace, use it, create a "P" table and insert 0 duration twice with the correct format (the updated), select all rows, try to insert 0 duration with incorrect format, get the error and lastly drop the "P" keyspace.

      cqlsh> CREATE KEYSPACE IF NOT EXISTS P WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};
      
      cqlsh> USE P;
      
      cqlsh:p> CREATE TABLE P (a INT PRIMARY KEY, b DURATION);
      
      cqlsh:p> INSERT INTO P (a, b) VALUES (1, PT0S);
      cqlsh:p> INSERT INTO P (a, b) VALUES (2, P0D);
      
      cqlsh:p> SELECT * FROM P;
      
       a | b
      ---+---
       1 |  
       2 |  
      
      (2 rows)
      
      cqlsh:p> INSERT INTO P (a, b) VALUES (3, P);
      SyntaxException: line 1:33 no viable alternative at input ')' (... b) VALUES (3, [P])...)
      
      cqlsh:p> DROP KEYSPACE P;
      
      cqlsh:p> describe keyspaces;
      
      system       system_distributed  system_traces  system_virtual_schema
      system_auth  system_schema       system_views 
      Show
      Pull requests cassandra-3.11 - https://github.com/apache/cassandra/pull/1977 cassandra-4.0 - https://github.com/apache/cassandra/pull/1975 cassandra-4.1 - https://github.com/apache/cassandra/pull/1976 trunk - https://github.com/apache/cassandra/pull/2283 Source code changes There was a change in the Lexer.g. Capital letter "P" is no longer a valid representation for 0 duration. It has to comply with https://en.wikipedia.org/wiki/ISO_8601#Durations (see Benjamin Lerer's comment). A couple of examples for valid 0 duration representation are: PT0S P0D PT0H P0W P0Y0M0DT0H0M0S Unit tests changes The following tests have been expanded with new logic to cover the ticket's changes: org.apache.cassandra.cql3.validation.operations.CreateTest org.apache.cassandra.cql3.validation.operations.DropTest org.apache.cassandra.cql3.validation.operations.InsertTest Manual test case flow Let's go through the case where we create a "P" keyspace, use it, create a "P" table and insert 0 duration twice with the correct format (the updated), select all rows, try to insert 0 duration with incorrect format, get the error and lastly drop the "P" keyspace. cqlsh> CREATE KEYSPACE IF NOT EXISTS P WITH replication = { 'class' : 'SimpleStrategy' , 'replication_factor' : '1' }; cqlsh> USE P; cqlsh:p> CREATE TABLE P (a INT PRIMARY KEY, b DURATION); cqlsh:p> INSERT INTO P (a, b) VALUES (1, PT0S); cqlsh:p> INSERT INTO P (a, b) VALUES (2, P0D); cqlsh:p> SELECT * FROM P; a | b ---+--- 1 | 2 | (2 rows) cqlsh:p> INSERT INTO P (a, b) VALUES (3, P); SyntaxException: line 1:33 no viable alternative at input ')' (... b) VALUES (3, [P])...) cqlsh:p> DROP KEYSPACE P; cqlsh:p> describe keyspaces; system       system_distributed  system_traces  system_virtual_schema system_auth  system_schema       system_views

    Description

      This was found while adding Accord Transaction syntax into CQL and fuzz testing to validate all possible cases… in doing this the following was found

      String query = "BEGIN TRANSACTION\n" +
                                 "  LET P = (SELECT v FROM " + keyspace + ".tbl WHERE k=? AND c=?);\n" +
                                 "  LET row2 = (SELECT v FROM " + keyspace + ".tbl WHERE k=? AND c=?);\n" +
                                 "  SELECT v FROM " + keyspace + ".tbl WHERE k=? AND c=?;\n" +
                                 "  IF P IS NULL AND row2.v = ? THEN\n" +
                                 "    INSERT INTO " + keyspace + ".tbl (k, c, v) VALUES (?, ?, ?);\n" +
                                 "  END IF\n" +
                                 "COMMIT TRANSACTION";
      

      Fails with

      SyntaxException: line 2:6 mismatched input 'P' expecting IDENT (BEGIN TRANSACTION  LET [P]...)
      

      The new LET syntax found this, but was able to reproduce in other cases

      cqlsh:ks> CREATE TABLE P (k INT PRIMARY KEY);
      SyntaxException: line 1:13 no viable alternative at input 'P' (CREATE TABLE [P]...)
      cqlsh:ks>
      cqlsh:ks> CREATE TABLE p (k INT PRIMARY KEY);
      cqlsh:ks>
      

      Attachments

        Activity

          People

            maximc Maxim Chanturiay
            dcapwell David Capwell
            Maxim Chanturiay
            Benjamin Lerer, Stefan Miklosovic
            Stefan Miklosovic Stefan Miklosovic
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 1h 40m
                1h 40m