risingwavelabs/risingwave · error

not implemented: DECLARE SUBSCRIPTION CURSOR

Error message

not implemented: DECLARE SUBSCRIPTION CURSOR

What it means

`unimplemented!()` fires in `Planner::plan_statement` (src/frontend/src/planner/statement.rs:28) when a `DECLARE SUBSCRIPTION CURSOR` statement reaches the planner. The frontend binds the statement but the planner has no implementation for planning subscription cursors, so it panics deliberately to mark the feature as not yet supported.

Solutions

  1. Avoid `DECLARE SUBSCRIPTION CURSOR`; use a regular `DECLARE ... CURSOR` on a query, or consume subscriptions via `SUBSCRIBE` output streams.
  2. Upgrade RisingWave if a newer version added subscription cursor support.
  3. If you need the feature, file/implement a planner arm returning a proper plan or a user-facing 'not supported' error instead of `unimplemented!()`.

Example fix

// before
BoundStatement::DeclareSubscriptionCursor(_) => unimplemented!(),
// after
BoundStatement::DeclareSubscriptionCursor(_) => {
    Err(ErrorCode::NotImplemented(
        "DECLARE SUBSCRIPTION CURSOR is not supported".into(),
        1191.into(),
    ).into())
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject subscription cursor statements before sending
if /^DECLARE\s+\w+\s+SUBSCRIPTION\s+CURSOR/i.test(stmt) {
  throw new Error('DECLARE SUBSCRIPTION CURSOR is not supported; use SUBSCRIBE or a regular cursor');
}

Try / catch

// Panics are not catchable in SQL; guard the statement text client-side
if (stmt.toLowerCase().includes('subscription cursor')) {
  return Promise.reject(new Error('unsupported statement: DECLARE SUBSCRIPTION CURSOR'));
}

Prevention

When it happens

Trigger: Executing `DECLARE sub_cursor SUBSCRIPTION CURSOR FOR ...` (subscription cursor variant of DECLARE) against the frontend. Ordinary `DECLARE ... CURSOR FOR <query>` works; only the subscription-cursor form hits this arm.

Common situations: Porting Postgres application code that uses subscription cursors, or testing new streaming subscription features before frontend planning support landed.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/45c8c7854ea57514. Report an issue: GitHub.

Appendix: source

Thrown at src/frontend/src/planner/statement.rs:28

// distributed under the License is distributed on an "AS IS" BASIS,
// 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)