Implementing Tables.jl interface results in Stack Overflow

For my package, I’m trying to implement the Tables.jl package. I however don’t really have a clue on how to implement the interface, and what the specific functions need to return.

Currently, I have this code. It however results in a stack overflow:

mutable struct TextCursor <: DBInterface.Cursor
  conn::DB
  sql::String
  nfields::Int
  nrows::Int
  rows_affected::Int64
  result::Vector{Vector{internal_column}}
  names::Vector{Symbol}
  types::Vector{Type}
  lookup::Dict{Symbol,Int}
  current_rownumber::Int
  current_resultsetnumber::Int

  function TextCursor(db, sql, data)
    nfields = length(data) > 0 ? length(data[1]) : 0
    nrows = length(data)
    rows_affected = 0
    current_rownumber = 0
    current_resultsetnumber = 0
    types = length(data) > 0 ? get_types(data) : Vector()
    names = length(data) > 0 ? get_names(data) : Vector()
    lookup = length(data) > 0 ? Dict(x => i for (i, x) in enumerate(names)) : Dict()

    cursor = new(db, sql, nfields, nrows, rows_affected, data, names, types, lookup, current_rownumber, current_resultsetnumber)

    return cursor
  end

  function get_types(data)
    types = Vector()

    for col in data[1]
      _type = col.type
      push!(types, _type)
    end

    return types
  end

  function get_names(data)
    names = Vector()

    for col in data[1]
      symbol_name = Symbol(col.name)
      push!(names, symbol_name)
    end

    return names
  end
end

struct TextRow <: Tables.AbstractRow
  row::Int
  cursor::TextCursor
end

Base.eltype(c::TextCursor) = internal_column
Tables.istable(::Type{TextCursor}) = true
Tables.rowaccess(::Type{TextCursor}) = true
Tables.rows(c::TextCursor) = c
Tables.columnnames(r::TextRow) = r.cursor.names

function Tables.getcolumn(r::TextRow, i::Int)
  println(r)
end

 function Tables.getcolumn(r::TextRow, nm::Symbol)
  println(r)
 end

Base.iterate(c::TextCursor, st=1) = st > c.nrows ? nothing : (TextRow(st, c), st + 1)

Within the getcolumn functions, the stack overflow happens. For some odd reason, it keeps printing the row a million times and crashes. I was wondering, what does the specific function need to return?

Please use the following as a general guideline: Implementing the Interface (i.e. becoming a Tables.jl source)

Please take a close look at the required methods and their stated return value compatibility: for example, Tables.rows needs to return an Tables.AbstractRow-compatible iterator.

Another, maybe more practical, approach is to dive into some of the existing integrations. Besides seeing how others successfully implemented the interface, you might even find some that are pretty close to your data structure.

I hope this gets you started - if there are still things that cause issues after applying the methodology from above, please follow up on this topic so we can get into those.