| Previous | Next |
| SQLITE_E_WARNING | SQLITE_E_DONE |
SQLITE_E_ROW
SQLITE_E_ROW (0x87AF0064) represents sqlite3_step has produced one result row. This HRESULT wraps SQLite result code 100. It is a control-flow result, not an error: column values for the current row are available until the statement is stepped again, reset, or finalized. For SQLITE_E_ROW, apply the native SQLite state-machine rules even though Windows stores the result in an HRESULT facility.
Correct loop contract
- Call sqlite3_step on a prepared statement
- Read every required column while the result is SQLITE_ROW
- Step again until SQLITE_DONE or an actual error is returned
Lifetime rules
| Object | Boundary |
|---|---|
| Column pointers | Text and blob pointers are tied to the current statement row. |
| Bindings | Bindings normally remain until cleared or rebound, but result data does not. |
| Reset/finalize | Reset permits reuse; finalize releases the prepared statement. |
Common bug pattern
Code that treats every nonzero SQLite result as failure will reject valid rows. The opposite bug is to process one row and assume the statement is complete without stepping to SQLITE_DONE.
Proof
A regression query with multiple rows must deliver each row once, end in DONE, and release or reset the statement on every exit path.
Read columns before advancing
Call sqlite3_column_type before conversions when NULL and dynamic typing matter, and copy text or blob data that must outlive the current row. A subsequent step, reset, or finalize can invalidate pointers returned by the column accessors even though the database connection remains open. Also verify that every expected column index is within the prepared statement’s result shape; a changed SELECT list is a contract change, not a ROW-state failure. Include an empty-result query and a row containing SQL NULL in the same regression suite.
Two independent axes for SQLITE_E_ROW
| Comparison | What it reveals |
|---|---|
| Same artifact, different implementation | Whether the representation is independently rejected |
| Known-good artifact, same environment | Whether the local stack fails without production-specific input |
| Original operation, one isolated change | Whether the proposed correction controls the observed result |
| Deliberate boundary violation | Whether validation remains active after the change |
Safe logging for SQLITE_E_ROW
Capture SQLITE_E_ROW with the operation, byte count, parser or statement position, and contract version, replacing sensitive bodies with hashes and bounded excerpts without losing the state needed to reproduce the event.
SQLite object lifetimes for SQLITE_E_ROW
| Object | Record |
|---|---|
| Database connection | Open flags, threading mode, transaction state, and latest connection error |
| Prepared statement | SQL identity, bindings, prepare API, and step call |
| Current row | Column values governed by the documented SQLITE_ROW lifetime |
| Log callback | Extended code and message retained even when the active API succeeds |
Native SQLite identity behind SQLITE_E_ROW
Keep the primary and extended SQLite result before mapping it to SQLITE_E_ROW, because masking the low byte or treating every HRESULT alike can erase the distinction among ROW, DONE, NOTICE, WARNING, and an extended warning.
Cleanup paths for SQLITE_E_ROW
- Finalize every statement that will not be reused
- Reset reusable statements only at a documented terminal state
- Avoid recursive SQLite use from the configured log callback
- Verify rollback, commit, and close independently from this result
Decision boundary for SQLITE_E_ROW
| Evidence | Use |
|---|---|
| Direct API return | Determines control flow for prepare, step, reset, finalize, or transaction work |
| Extended result code | Preserves the specific SQLite condition before HRESULT translation |
| Log callback event | Adds diagnostics but does not automatically replace the direct API result |
| Transaction outcome | Separately determines whether completed statement work becomes durable |
Technical references for SQLITE_E_ROW
- SQLite result and extended result codes
- SQLite sqlite3_step contract
- SQLite error logging interface
- SQLite query planner and automatic indexes
Looking for a different code? Search another status or error code.