{"record":{"id":"d4cc7742cc6431b1","repo":"risingwavelabs/risingwave","slug":"streaming-vector-index-lookup-join-must-be-proctim","errorCode":null,"errorMessage":"streaming vector index lookup join must be proctime temporal join","messagePattern":"streaming vector index lookup join must be proctime temporal join","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_vector_search_lookup_join.rs","lineNumber":306,"sourceCode":"            .is_identity()\n        {\n            // TODO: support it\n            bail!(\n                \"LogicalVectorSearchLookupJoin does not support input that can possibly be rewritten\"\n            )\n        }\n        Ok((\n            self.clone().into(),\n            ColIndexMapping::identity(self.base.schema().len()),\n        ))\n    }\n\n    fn to_stream(&self, ctx: &mut ToStreamContext) -> Result<StreamPlanRef> {\n        if let Some(core) = self.to_vector_index_lookup_join(|plan| plan.to_stream(ctx))? {\n            // `ProcessTimeBroadcast` is intentionally excluded: the vector-index lookup executor\n            // does not consume a broadcast change stream or maintain replicated lookup state.\n            if !matches!(&core.as_of, Some(AsOf::ProcessTime)) {\n                bail!(\"streaming vector index lookup join must be proctime temporal join\");\n            }\n            return Ok(StreamVectorIndexLookupJoin::new(core)?.into());\n        }\n        bail!(\"LogicalVectorSearchLookupJoin should use proper vector index in streaming job\")\n    }\n}\n\nimpl LogicalVectorSearchLookupJoin {\n    pub(crate) fn as_index_lookup(&self) -> Option<(&Arc<VectorIndex>, Vec<usize>, Option<AsOf>)> {\n        if let Some(scan) = self.core.lookup.as_logical_scan()\n            && let Some((\n                index,\n                _covered_table_cols_idx,\n                non_covered_table_cols_idx,\n                primary_table_col_in_output,\n            )) = LogicalVectorSearch::resolve_vector_index_lookup(\n                scan,\n                &self.core.lookup_vector,","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_vector_search_lookup_join.rs#L288-L324","documentation":"Raised in LogicalVectorSearchLookupJoin::to_stream when the temporal join is not an AS OF PROCTIME join. Streaming vector-index lookup joins are only defined against the current processing time; other temporal join variants (event-time AS OF) cannot use the lookup executor, so the plan is rejected.","triggerScenarios":"Thrown at src/frontend/src/optimizer/plan_node/logical_vector_search_lookup_join.rs:306 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Define the temporal join in the streaming vector index lookup as a process-time (NOW() AS OF) temporal join.","Use the standard temporal join syntax with process time on the lookup side."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}