LuaSQLite3

Ticket Change Details
Login

Ticket Change Details

Overview

Artifact ID: 576e0bc9289bad870d34a7ac030d09e5931def31
Ticket: b5ceb24111d7ecfdcf5bafefe82b61c60a7354d0
Can't use the iterator from db:*rows as a variable
User & Date: anonymous 2019-09-15 15:30:11
Changes

  1. foundin changed to: "0.9.5-1"
  2. icomment:
    In Lua, an iterator is a function that returns new values on successive calls, and the function can be passed around as a variable. However, for some reason this doesn't work with the db:*rows functions of lsqlite3:
    
    <pre>
    local sqlite3 = require("lsqlite3complete")
    local db = sqlite3.open_memory()
    
    local rows = db:nrows("select 11 as qwe")
    for row in rows do
        print(row.qwe)
    end
    </pre>
    
    This produces the following error message:
    
    <pre>
    lua: s.lua:5: bad argument #1 to 'for iterator' (:sqlite3:vm expected, got nil)
    stack traceback:
    	[C]: in for iterator 'for iterator'
    	s.lua:6: in main chunk
    	[C]: in ?
    </pre>
    
    The iteration only works if a *rows function is called directly in a `for` statement.
    
    The same happens with db:rows, db:nrows, and db:urows functions and corresponding stmt:*rows functions for prepared statements. It affects both lsqlite3complete and lsqlite3 with a dynamically loaded sqlite3 lib.
    
    My use-case is that I use Fennel, a Lisp language on top of Lua, and I need to pick just the first row from the results. As a functional language, Fennel doesn't have early returns or `break` statements, but could easily call the iterator just once. More generally, iterators could be used with higher-order functions.
    
    Versions are as follows:
    
    LSQLite3 0.9.5-1, installed with Luarocks.<br />
    Lua 5.3.5 and 5.1.5 installed with Homebrew (haven't tested with other versions).<br />
    MacOSX 10.13.6.
    
    For comparison, here's Lua code creating an iterator as a var:
    
    <pre>
    function create_iterator(limit)
        local i = 0
        return function()
            i = i + 1
            if i <= limit then return i end
        end
    end
    
    iterator = create_iterator(10)
    for x in iterator do
        print(x)
    end
    </pre>
    
  3. login: "anonymous"
  4. mimetype: "text/x-fossil-wiki"
  5. private_contact changed to: "ed1c74f3036cfa043d8e02a8b2806e9b50371cf2"
  6. severity changed to: "Minor"
  7. status changed to: "Open"
  8. title changed to: "Can't use the iterator from db:*rows as a variable"
  9. type changed to: "Code_Defect"