Uploaded image for project: 'Ignite'
  1. Ignite
  2. IGNITE-18488

SQL: SUBSTRING function does not support NULL values

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 3.0.0-beta1
    • 3.0
    • sql

    Description

      ANSI99 SQL specification ("6.18 <string value function>") says the following:

      3) If <character substring function> is specified, then:
        a) Let C be the value of the <character value expression>, ..., and let S be the value of the <start position>.
        b) If <string length> is specified, then let L be the value of <string length> ...
        c) If either C, S, or L is the null value, then the result of the <character substring function> is the null value.
      

      So, we should expect the following behavior:

      SUBSTRING('text' FROM 1 FOR NULL) -> NULL
      SUBSTRING('text' FROM NULL FOR 2) -> NULL
      SUBSTRING(NULL FROM 1 FOR 2) -> NULL
      

      Instead, we got errors for these queries:

      sql-cli> SELECT SUBSTRING('text' FROM 1 FOR NULL);
      SQL query execution error
      Exception while executing query [query=SELECT SUBSTRING('text' FROM 1 FOR NULL);]. Error message:From line 1, column 8 to line 1, column 40: Cannot apply 'SUBSTRING' to arguments of type 'SUBSTRING(<CHAR(4)> FROM <INTEGER> FOR <NULL>)'. Supported form(s): 'SUBSTRING(<CHAR> FROM <INTEGER>)'
      'SUBSTRING(<CHAR> FROM <INTEGER> FOR <INTEGER>)'
      'SUBSTRING(<VARCHAR> FROM <INTEGER>)'
      'SUBSTRING(<VARCHAR> FROM <INTEGER> FOR <INTEGER>)'
      'SUBSTRING(<BINARY> FROM <INTEGER>)'
      'SUBSTRING(<BINARY> FROM <INTEGER> FOR <INTEGER>)'
      'SUBSTRING(<VARBINARY> FROM <INTEGER>)'
      'SUBSTRING(<VARBINARY> FROM <INTEGER> FOR <INTEGER>)'
      
      sql-cli> SELECT SUBSTRING('text' FROM NULL FOR 2);
      SQL query execution error
      Exception while executing query [query=SELECT SUBSTRING('text' FROM NULL FOR 2);]. Error message:From line 1, column 8 to line 1, column 40: Cannot apply 'SUBSTRING' to arguments of type 'SUBSTRING(<CHAR(4)> FROM <NULL> FOR <INTEGER>)'. Supported form(s): 'SUBSTRING(<CHAR> FROM <INTEGER>)'
      'SUBSTRING(<CHAR> FROM <INTEGER> FOR <INTEGER>)'
      'SUBSTRING(<VARCHAR> FROM <INTEGER>)'
      'SUBSTRING(<VARCHAR> FROM <INTEGER> FOR <INTEGER>)'
      'SUBSTRING(<BINARY> FROM <INTEGER>)'
      'SUBSTRING(<BINARY> FROM <INTEGER> FOR <INTEGER>)'
      'SUBSTRING(<VARBINARY> FROM <INTEGER>)'
      'SUBSTRING(<VARBINARY> FROM <INTEGER> FOR <INTEGER>)'
      
      sql-cli> SELECT SUBSTRING(NULL FROM 1 FOR 2);
        (client freezes, no answer at all)
      

      Important: the last query causes NullPointerException within DB:

      2022-12-30 07:32:46:210 +0000 [WARNING][node1-srv-worker-1][ClientInboundMessageHandler] Error processing client request
      java.lang.NullPointerException
              at org.apache.ignite.internal.sql.SqlColumnTypeConverter.columnTypeToClass(SqlColumnTypeConverter.java:42)
              at org.apache.ignite.client.handler.JdbcQueryCursorHandlerImpl.createColumnMetadata(JdbcQueryCursorHandlerImpl.java:162)
              at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
              at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
              at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
              at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
              at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
              at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
              at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
              at org.apache.ignite.client.handler.JdbcQueryCursorHandlerImpl.queryMetadataAsync(JdbcQueryCursorHandlerImpl.java:133)
              at org.apache.ignite.client.handler.requests.jdbc.ClientJdbcQueryMetadataRequest.process(ClientJdbcQueryMetadataRequest.java:47)
              at org.apache.ignite.client.handler.ClientInboundMessageHandler.processOperation(ClientInboundMessageHandler.java:454)
              at org.apache.ignite.client.handler.ClientInboundMessageHandler.processOperation(ClientInboundMessageHandler.java:336)
              at org.apache.ignite.client.handler.ClientInboundMessageHandler.channelRead(ClientInboundMessageHandler.java:187)
              at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
              at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
              at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
              at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327)
              at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299)
              at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
              at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
              at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
              at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
              at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
              at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
              at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
              at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
              at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
              at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
              at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
              at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
              at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
              at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
              at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
              at java.base/java.lang.Thread.run(Thread.java:829)
      

      Attachments

        Issue Links

          Activity

            People

              amashenkov Andrey Mashenkov
              akhitrin Andrey Khitrin
              Votes:
              0 Vote for this issue
              Watchers:
              2 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 - 10m
                  10m