edgedb-js
edgedb-js copied to clipboard
Allow the queries generator to statically analyze the query to ensure expressions are typed correctly and fail at generation time if not
- EdgeDB Version: 4.5
- EdgeDB CLI Version: 4.1.0
- OS Version: macos 13
Unsure if this is considered a bug or an FR but it caused a bug for us to slip into production basically breaking this expectation
Steps to Reproduce:
- Create an object type with a required property
Example {
required name: str;
}
- Run query file generation for a query assigning an optional
insert Example {
name := <optional str>$name
}
- This generates a seemingly valid query file that fails at runtime with an optional arg
// GENERATED by @edgedb/generate v0.4.1
import type {Executor} from "edgedb";
export type TestArgs = {
"name"?: string | null;
};
export type TestReturns = {
"id": string;
};
export async function Test(client: Executor, args: TestArgs): Promise<TestReturns> {
return client.queryRequiredSingle(`\
insert Example {
name := <optional str>$name
}`, args);
}
It occurs to me that this might be query-file specific: in normal edgeql, the runtime failure is all you need, and in QB, this can be enforced. This makes me think it might be more disruptive than I thought to add this mechanism & more of an FR
Yeah, and having flexibility in the arguments means you can do things like `?? "default value" or use optional arguments for updates.
Maybe the kind of static analysis you're looking for is whether we can know statically if we're not providing the right type of value to an expression like name := arg
? Or maybe as part of the query generation you'd want to perhaps attempt the query with some kind of arbitrary data of the parameter type and see if it throws a runtime error and fail to codegen the query?
Certainly agree on the argument being optional for purposes like like `?? "default value" or updates.
Maybe the kind of static analysis you're looking for is whether we can know statically if we're not providing the right type of value to an expression like name := arg?
Bingo.
Or maybe as part of the query generation you'd want to perhaps attempt the query with some kind of arbitrary data of the parameter type and see if it throws a runtime error and fail to codegen the query?
This is an interesting implementation idea and has the added benefit of statically surfacing any edgedb bugs that come along. However, it seems difficult for data dependent situations like conditionals or unless conflict
. However, you'd know about the feasibility of that much better than I would.
Yeah, statically analyzing the query to ensure the query types are correct at introspection time seems like a doable thing! I'll move this to the edgedb-js repo and talk it over with the compiler team to see how feasible it is.
We do do static checking of types and cardinalities. The issue here is that for inserts and updates, we intentionally don't enforce whether it is required statically, because required links can very rarely be determined statically to exist. (Since they usually come from a select+filter, which we can't know will find anything.)
I see (similar to the fundamental inability to know cardinality statically in 6694?) This situation makes sense for links, though one can enforce that say, a required UUID argument for a filter is populated? As you say that doesn't offer guaranteed protection at runtime but at least ensures the query is written correctly?