risingwavelabs/risingwave · error
postgres_query function is not supported in streaming mode
Error message
postgres_query function is not supported in streaming mode
What it means
LogicalPostgresQuery represents a query executed via the postgres_query table function, evaluated only in batch mode by delegating to the external Postgres source. Streaming execution cannot continuously maintain such results, so to_stream intentionally returns an error.
Solutions
- Keep postgres_query in batch SELECT queries only; never reference it in MVs or streaming definitions
- Use RisingWave's Postgres CDC connector to stream the external table into RisingWave
- Persist batch results into a table via scheduled ingestion, then build MVs on that table
- Restructure so external reads occur at batch query time, not in streaming pipelines
Example fix
-- before (fails)
CREATE MATERIALIZED VIEW mv AS SELECT * FROM postgres_query('conn_name', 'SELECT * FROM t');
-- after: batch query only, or CDC source
SELECT * FROM postgres_query('conn_name', 'SELECT * FROM t');
-- streaming alternative: Postgres CDC source + MV over the source Defensive patterns
Strategy: validation
Validate before calling
-- Pre-check that streaming definitions do not use postgres_query -- if /\bpostgres_query\s*\(/i.test(sql) && isStreamingDdl(sql) reject();
Try / catch
try {
await conn.query('CREATE MATERIALIZED VIEW mv AS SELECT * FROM postgres_query(...)');
} catch (e) {
if (String(e.message).includes('postgres_query function is not supported in streaming mode')) {
// fall back to CDC source setup or batch persistence
}
throw e;
} Prevention
- Never reference postgres_query in MVs, indexes, or sources
- Use Postgres CDC for streaming replication
- Keep postgres_query limited to ad-hoc batch queries
When it happens
Trigger: Building a streaming plan (materialized view, source, MV refresh) containing a postgres_query(...) table function, causing to_stream to be called on the node.
Common situations: Users attempt CREATE MATERIALIZED VIEW AS SELECT ... FROM postgres_query(...) expecting live external-table streaming; assumptions that the function behaves like a native table in streaming contexts.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- mysql_query function is not supported in streaming mode
- Actor exited unexpectedly
- Array error
- {batch write failure, with context()}
- below watermark check condition eval must return bool array
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/6108a240e0f7cb5e.
Report an issue: GitHub.
Appendix: source
Thrown at src/frontend/src/optimizer/plan_node/logical_postgres_query.rs:113
_ctx: &mut PredicatePushdownContext,
) -> PlanRef {
// No pushdown.
LogicalFilter::create(self.clone().into(), predicate)
}
}
impl ToBatch for LogicalPostgresQuery {
fn to_batch(&self) -> Result<crate::optimizer::plan_node::BatchPlanRef> {
Ok(BatchPostgresQuery::new(self.core.clone()).into())
}
}
impl ToStream for LogicalPostgresQuery {
fn to_stream(
&self,
_ctx: &mut ToStreamContext,
) -> Result<crate::optimizer::plan_node::StreamPlanRef> {
bail!("postgres_query function is not supported in streaming mode")
}
fn logical_rewrite_for_stream(
&self,
_ctx: &mut RewriteStreamContext,
) -> Result<(PlanRef, ColIndexMapping)> {
bail!("postgres_query function is not supported in streaming mode")
}
}
View on GitHub (pinned to 6469eb736d)