The way I see it, the from part of the query should be specifying the source (e.g. "all methods").
The ability to extract data from the results and store it in a variable within the where part seems to be something completely different.
As an example, I have the following query:
from Method uncalled, RefType uncalledType, Package uncalledPackage
where not exists(Callable caller | caller.getACall() == uncalled)
and uncalledType = uncalled.getDeclaringType()
and uncalledPackage = uncalledType.getPackage()
select uncalledPackage, uncalledType, uncalled
order by uncalledPackage, uncalledType, uncalled
All I'm doing here is attempting to get all uncalled methods and display them in a tree view grouped by package and type. It doesn't seem right that I have to declare the temporary helper variables (uncalledType, uncalledPackage) in the from clause next to the source.
I might be wrong but from what I've seen so far assignments in the where statement are just used to allow an expression to be re-used in later parts of the query (without having to retype the whole expression multiple times).
I hope that's made my point of view a bit clearer.
First, "declare before use" makes queries easier to read
I'd have to disagree with that. Having "RefType uncalledType, Package uncalledPackage" in the from clause above doesn't seem very helpful. If the intent is to make the type of a variable explicit then surely the declaration should be next to the use? I think it would be much more helpful to show a tooltip displaying the (infered) type of a variable when the mouse is hovered over it.
Second, what should we do about auto-completion if we went this route? When one first types "p." without declaring p, there are no sensible suggestions to give
That should be exactly the same as it is now. If the type of p cannot be inferred (which I assume can only be the case if it hasn't been assigned to) then the error "p cannot be resolved" should be given, just as it is now if p has not been declared. In fact, that would give you better error checking than you currently have, as you don't currently tell the user if they have not assigned to a variable (since you have to assume the user wanted to select all variables).
Similarly, while messing about with a query, it is common that at an intermediate state, the type inferencer decides there is *no* type for a variable. If you declared that variable, at least we know your intention and we can try to use that for auto-completion on the ill-typed query. But without such hints, autocompletion will fail miserably.
Well I'll have to give you that. I can't really say whether this would be a problem in practice without trying it. I would have thought it would just be the same as it is now. If the declaration cannot be read as the query is in an intermediate state then you can't show the autocompletion list.
Kirill's suggestion could be used, although I would have a declaration changing along with the inferred type (unless doing so would take the query into an error state). Either that or it could work similarly to Eclipse's "Organize imports" command which would insert the correct declarations when the user asks for it (from a toolbar icon, a menu item or a shortcut key)
Martin