On 2018/07/19 2:32 PM, Christian Duta wrote:

WITH RECURSIVE
  count_down(v) AS (
    SELECT 5
      UNION ALL
    SELECT cd.v - 1
    FROM (
      SELECT cd.v
      FROM count_down AS cd
    ) AS cd
    WHERE cd.v > 0
  )
SELECT * FROM count_down;

Error: near line 1: recursive reference in a subquery: count_down

What is the reasoning behind this restriction?
And more importantly: Are there plans to allow recursive references inside of a subquery in a future release of SQLite?

The problem is that there can be only one "builder" of the recursive set.

In your example above, the full recursive set is not known at the time of first encountering the sub-query. i.e. do you expect it to have results on the first iteration? Because it can't, since by the time it is reached (which must be before the first row from the main select is produced, as is the nature of FROM/JOIN clauses), there is no set built to choose any values from, and since it has no values, it will produce no rows, and if it doesn't produce rows, the entire recursive part of the query doesn't produce rows (since it selects from the very sub-query in question, which has no rows yet on the first iteration), and therefore there simply is no row added at all on the first (or any next) iteration since there never occurs a first row.

And THAT would probably thorroughly confuse even more people than my explanation of it does.

Or, let's say you envision the sub-query building its own recursive set before we get to the main query - this seems like a solution, but it would fill up to infinity because you did not specify a limit or WHERE clause inside the sub-query.

But, let's assume for a moment you did add a WHERE or LIMIT to avoid filling the sub-query-recursed-set of rows to infinity, where does the main recursive set build from? It clearly has to accommodate all rows added by the sub-query recursive set, and in your case there is no main recursive set (because you did not FROM or JOIN the count_down table, which by definition stops this query from being "recursive").

But again, let's assume for a moment you did add the count_down table to the FROM/JOIN in the second select (the recursive part) also, then you have 2 recursive sets being built, one for the sub query, and the correct main query one. What will happen now is either one of the sets will not be what you wanted, OR, they will feed each other into an exponential growing set (depending on the nature of the JOIN you apply).

None of this is what we want from the recursive queries.

I guess it's much like recursion in programming, you have to be very careful not to run into infinite loops or nonsense results, and for that you have to have some strict rules. SQL solves this by not allowing a dream in a dream.

Please note that I've only discussed some of the theory here, but there might be other unrelated physical design limits in the sqlite code which may or may not prevent it, and which the devs may or may not  overcome eventually.

That said, if this is something you seriously hope to employ as a mechanic for finding a more complex result from a recursive query - note that you can daisy-chain recursive queries together to form nicely complex results. This simple example shows the basic idea, but you can also use any join on them, filter from one another in the recursive parts, etc. There really is no conceptual limit, so long as any recursive part doesn't self-reference in a sub-part of it.

  -- SQLite version 3.24.0  [ Release: 2018-06-04 ]

WITH a(x) AS (
  SELECT 1 UNION ALL SELECT x+2 FROM a WHERE x < 3
), b(fx) AS (
  SELECT 1 UNION ALL SELECT fx*x FROM b,a LIMIT 30
)
SELECT * FROM b;


  --  fx
  -- ---
  --  1
  --  1
  --  3
  --  1
  --  3
  --  3
  --  9
  --  1
  --  3
  --  3
  --  9
  --  3
  --  9
  --  9
  --  27
  --  1
  --  3
  --  3
  --  9
  --  3
  --  9
  --  9
  --  27
  --  3
  --  9
  --  9
  --  27
  --  9
  --  27
  --  27

PS: Apologies, I know the descriptions above lack some simplistic clarity, but I couldn't find the vocabulary for reducing it to more succinct, yet well-defined, ideas.

_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to