risingwavelabs/risingwave · error
not implemented: FETCH
Error message
not implemented: FETCH
What it means
`unimplemented!()` fires in `Planner::plan_statement` (src/frontend/src/planner/statement.rs:29) for `BoundStatement::FetchCursor(_)`. A `FETCH` statement is bound by the binder, but the planner cannot produce a plan for fetching rows from a declared cursor, so it panics with a not-implemented marker.
Solutions
- Replace cursor/FETCH pagination with `SELECT ... LIMIT ... OFFSET ...` or keyset pagination (`WHERE id > $last ORDER BY id LIMIT n`).
- Upgrade RisingWave if FETCH support has since been implemented.
- If implementing, replace the arm with a proper fetch plan or a `ErrorCode::NotImplemented` user error instead of a panic.
Example fix
// before
BoundStatement::FetchCursor(_) => unimplemented!(),
// after
BoundStatement::FetchCursor(_) => {
Err(ErrorCode::NotImplemented("FETCH is not supported".into(), 1191.into()).into())
} Defensive patterns
Strategy: validation
Validate before calling
// Reject FETCH statements before sending
if /^FETCH\b/i.test(stmt) {
throw new Error('FETCH is not supported; use LIMIT/OFFSET or keyset pagination');
} Try / catch
if (/^fetch\b/i.test(stmt)) {
return Promise.reject(new Error('unsupported statement: FETCH'));
} Prevention
- Replace server-side cursor pagination with LIMIT/OFFSET or keyset pagination.
- Audit ORM/JDBC cursor usage when migrating from Postgres.
- Track RisingWave release notes for cursor/FETCH support.
When it happens
Trigger: Executing `FETCH [NEXT|...] FROM cursor_name` (or `FETCH cursor_name`) after declaring a cursor in RisingWave.
Common situations: Applications using cursor pagination (`DECLARE`/`FETCH`/`CLOSE` flows, e.g. psql-driven cursors or ORMs like some JDBC/psycopg patterns) ported from Postgres.
Related errors
- not implemented: DECLARE SUBSCRIPTION CURSOR
- unimplemented
- call predicate_pushdown of the PlanRef instead of calling…
- call prune_col of the PlanRef instead of calling directly…
- children expression must not be empty for constant lookup…
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/d5cf82097ad35607.
Report an issue: GitHub.
Appendix: source
Thrown at src/frontend/src/planner/statement.rs:29
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::binder::BoundStatement;
use crate::error::Result;
use crate::optimizer::LogicalPlanRoot;
use crate::planner::Planner;
impl Planner {
pub(super) fn plan_statement(&mut self, stmt: BoundStatement) -> Result<LogicalPlanRoot> {
match stmt {
BoundStatement::Insert(i) => self.plan_insert(*i),
BoundStatement::Delete(d) => self.plan_delete(*d),
BoundStatement::Update(u) => self.plan_update(*u),
BoundStatement::Query(q) => self.plan_query(*q),
BoundStatement::DeclareCursor(d) => self.plan_query(*d.query),
BoundStatement::DeclareSubscriptionCursor(_) => unimplemented!(),
BoundStatement::FetchCursor(_) => unimplemented!(),
BoundStatement::CreateView(c) => self.plan_query(*c.query),
}
}
}
View on GitHub (pinned to 6469eb736d)