-
I was writting an overly messy request trying to find the latest assignment to a VariableAccess in cpp (I know it's impossible, just limiting my request to variable and references for now), I didn't understood something so I tried debugging over a smaller example, but then I felt like I was missing understanding of basic concepts. The pattern that I'm trying to fix is similar to this one (I know this is a pointless request, it's juste for debugging and understanding purposes): bindingset[i]
int rec(int i){
result = i
or
exists(int stop |
stop = 20
and i < stop
and result=rec(i+1)
)
}
from int i
where i in [1..5]
select rec(i) I expected this request to be valid and return all integer from 1 to 19, but it fails because : Or maybe the thing I don't understand is the (To give real context : I'm looking if a "path" from an assigned value to the variable access without encountering another assignment to that variable exists, fot that I use Node from DataFlowUtil and localFlowStep. I managed to write a somewhat working request with getAPredecessor+ / dominates / postDominates predicates but it wasn't working for some conditional branching case. There are probably many other mistakes in what I've wrote because my actual request doesn't fail and it seems like my exists predicate alway holds but I can't move forward if I don't understand basic recursion) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
QL is a form of datalog and uses a bottom-up evaluation strategy. You might want to have a look at https://codeql.github.com/docs/ql-language-reference/evaluation-of-ql-programs/ . QL evaluates a predicate into a set of tuples (a sort of table). QL requires all its results to be of finite size, and to achieve this it has a rule that all variable should be "bound". For example the expression |
Beta Was this translation helpful? Give feedback.
The evaluation of a
predicate
in QL does not yield a single return value, instead it returns a set of all possible combinations of parameters and result values for which the predicate "holds".The evaluation of a recursive predicate in QL is done bottom-up and is quite different from evaluating a recursive function in a more common programming language. The evaluation strategy is roughly as follows: initially the set of answers is empty, evaluate the body of the predicate to find new possible answers, add those to the set and repeat until no new answers are found.
For example