Skip to Main Content
  • Questions
  • Bug in recursive subquery factoring ?

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Marcin.

Asked: December 01, 2016 - 2:01 pm UTC

Last updated: December 02, 2016 - 1:44 pm UTC

Version: 11.2.0.4.0 - 64bit

Viewed 1000+ times

You Asked

Hi AskTom team.

I was playing with recursive subqueries and tried to do some string manipulations, but I noticed something strange:

SQL> WITH r(str, outtxt, outtxt2) AS (
  2    SELECT 'aabbba', '', '' FROM   dual
  3    UNION ALL
  4    SELECT substr(str, 2)
  5          ,CASE WHEN substr(str, 1, 1) = substr(outtxt, -1)
  6                THEN (1 + substr(outtxt, -2, 1)) || substr(str, 1, 1)
  7                ELSE '1' || substr(str, 1, 1)
  8           END
  9          ,CASE WHEN substr(str, 1, 1) = substr(outtxt, -1)
 10                THEN (1 + substr(outtxt, -2, 1)) || substr(str, 1, 1)
 11                ELSE '1' || substr(str, 1, 1)
 12           END
 13    FROM   r
 14    WHERE  str IS NOT NULL
 15  )
 16  SELECT * FROM r;

STR      OUTTXT   OUTTXT2
-------- -------- --------
aabbba
abbba    1a       1a
bbba     1a       2a
bba      1b       1b
ba       1b       2b
a        1b       2b
         1a       1a

7 rows selected.


You see, the expressions for outtxt and outtxt2 are identical, yet they return different results (e.g. 1a, 2a).
Should I consider it a bug? Or is there something I don't understand about recursive subqueries?

Thanks

with LiveSQL Test Case:

and Chris said...

This looks like a bug to me. If you change outtxt from null to a value in the base condition you get the exepcted result:

WITH r(str, outtxt, outtxt2) AS (
  SELECT 'aabbba', 'a1', '' FROM   dual
  UNION ALL
  SELECT substr(str, 2)
        ,CASE WHEN substr(str, 1, 1) = substr(outtxt, -1)
              THEN (1 + substr(outtxt, -2, 1)) || substr(str, 1, 1)
              ELSE '1' || substr(str, 1, 1)
         END
        ,CASE WHEN substr(str, 1, 1) = substr(outtxt, -1)
              THEN (1 + substr(outtxt, -2, 1)) || substr(str, 1, 1)
              ELSE '1' || substr(str, 1, 1)
         END
  FROM   r
  WHERE  str IS NOT NULL
)
SELECT * FROM r ; 


I'm following up internally.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks!

Marcin, December 02, 2016 - 6:49 pm UTC

So it was because of null...
Well, at least there's a workaround. Thanks