cursorBackwardFlow covers the forward-only restriction: backward fetch fails with a clean error. NO SCROLL pins real PostgreSQL to the same forward-only behavior Duckgres always has (without it, PostgreSQL can satisfy backward fetches from materialized plans like sorts).
(t *testing.T, db *sql.DB)
| 148 | // forward-only behavior Duckgres always has (without it, PostgreSQL can |
| 149 | // satisfy backward fetches from materialized plans like sorts). |
| 150 | func cursorBackwardFlow(t *testing.T, db *sql.DB) { |
| 151 | tx := beginCursorTx(t, db) |
| 152 | |
| 153 | mustExecTx(t, tx, "DECLARE cur_backward NO SCROLL CURSOR FOR SELECT id, name FROM users ORDER BY id") |
| 154 | assertCursorRows(t, "FETCH 2", fetchCursorRows(t, tx, "FETCH 2 FROM cur_backward"), cursorUsers(1, 2)) |
| 155 | |
| 156 | rows, err := tx.Query("FETCH BACKWARD 1 FROM cur_backward") |
| 157 | if err == nil { |
| 158 | _ = rows.Close() |
| 159 | t.Fatal("FETCH BACKWARD succeeded, want forward-only error") |
| 160 | } |
| 161 | if !strings.Contains(err.Error(), "cursor can only scan forward") { |
| 162 | t.Errorf("FETCH BACKWARD: error = %q, want forward-only error", err) |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | // cursorMissingFlow covers FETCH/CLOSE on a cursor that was never declared. |
| 167 | // Each statement gets its own transaction because the error aborts the |
no test coverage detected