diff --git a/src/completion.rs b/src/completion.rs index 5bb1580..28447f7 100644 --- a/src/completion.rs +++ b/src/completion.rs @@ -18,7 +18,7 @@ use crate::dsl::grammar::IdentSource; use crate::dsl::types::Type; use crate::dsl::walker::outcome::Expectation; use crate::dsl::{ParseError, parse_command}; -use crate::dsl::parser::parse_command_in_mode; +use crate::dsl::parser::parse_command_with_schema_in_mode; use crate::mode::Mode; /// Composite literal candidates whose lexed shape is more than @@ -333,7 +333,18 @@ pub fn candidates_at_cursor_with_in_mode( // `pk` at the end of `create table T with pk`. The // optional-suffix case (`save ` → `as`) is preserved // because there `partial_prefix` is empty. - let input_parses_complete = parse_command_in_mode(input, mode).is_ok(); + // + // Parse *with the schema* (not the schemaless `parse_command_in_mode`) + // so "complete" means the schema-aware grammar accepts it — the same + // consistency fix as issue #2's ambient-hint fallback. A schemaless + // parse can report a type-/arity-wrong tuple as complete and wrongly + // gate the drop on. Today the two agree at every position this drop + // can fire (the drop only removes a re-offered keyword == partial, + // and schema divergence is confined to value type/arity, which never + // coincides — see issue #18); schema-aware is the principled, latent- + // bug-proof choice and can only ever *retain* a candidate the + // schemaless gate would have dropped, never the reverse. + let input_parses_complete = parse_command_with_schema_in_mode(input, cache, mode).is_ok(); // Schema-aware probe: one walk yields both the expected set // and the table-context snapshot (ADR-0024 §Phase D