@@ -60,7 +60,23 @@ auto database::iterator::next() -> iterator&
6060
6161 if (code == SQLITE_DONE) {
6262 done_ = true ;
63- } else if (code != SQLITE_ROW) {
63+ } else if ( code == SQLITE_ROW){
64+ // Update column dtypes for the next row
65+ // There are a couple ways to do this, each with some nuance:
66+ // 1) use sqlite3_column_type upon construction of the iterator and inspect the first row
67+ // then use those column types for all rows
68+ // 2) use the sqlite3 table definition schema (i.e. PRAGMA table_info(...);) to get column types
69+ // 3) check each row during iteration using sqlite3_column_type
70+ // 1 & 2 may not produce consistent results because if the value in a column is NaN,
71+ // then sqlite3_column_type will report that as a 5 or NULL type, even if the schema has a datatype
72+ // Using 1, when the first row contains NaN but other rows have valid data, then all types are reported as NULL.
73+ // Using 2, any NaN/NULL data will get interperted as the schema type
74+ // Using 3 ensures we get a non-null type if there is valid data in the column in that row, and NULL when
75+ // no data is present, with a small bit of additional iterator overhead.
76+ for (int i = 0 ; i < ncol_ && i < types_.size (); i++) {
77+ types_[i] = (sqlite3_column_type (ptr_ (), i));
78+ }
79+ } else {
6480 throw sqlite_error{" sqlite3_step" , code};
6581 }
6682
0 commit comments