-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Why is the result of "count" different from what I expected? #15759
-
a simple class definition:
class SmallInt extends int {
SmallInt() {
this = 1 or this = 2
}
SmallInt child() {
result = this + 1
}
}
When I run the following query:
from SmallInt i
select count(i)
the resule is 1.
however, when using the "count" like this :
select count(SmallInt i | | i)
the result is 2. I don't quite understand why.
and further I write :
from int res
where exists( SmallInt s | res = count(s.child()) )
select res
the result is 0 and 1.
if I modify the query to:
select count(SmallInt s | | s.child())
I get a result of 1.
Why does a variable behave differently when it's defined in the "from" clause as opposed to directly in the "count"? Could someone explain this for me?
Thank you for your assistance.
Beta Was this translation helpful? Give feedback.
All reactions
count() determines the possible values of a variable.
from SmallInt i
select count(i)
from creates the variable i which is a value set of [1,2] and count is passed those values independently in the select. so 1 is only one value, and 2 is only one value. this is how the select statements are evaluated.
though select count(SmallInt i | | i) will result in 2 because you are using temporary variables and counting the possible values in the expression part of the aggregate, and then selecting that.
hope this helps. you could also just read: https://codeql.github.com/docs/ql-language-reference/expressions/#aggregations-1
Replies: 1 comment 2 replies
-
count() determines the possible values of a variable.
from SmallInt i
select count(i)
from creates the variable i which is a value set of [1,2] and count is passed those values independently in the select. so 1 is only one value, and 2 is only one value. this is how the select statements are evaluated.
though select count(SmallInt i | | i) will result in 2 because you are using temporary variables and counting the possible values in the expression part of the aggregate, and then selecting that.
hope this helps. you could also just read: https://codeql.github.com/docs/ql-language-reference/expressions/#aggregations-1
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
That's right. The following example illustrates what is going on:
from SmallInt i
select i, count(i)
gives
| i | count |
| 1 | 1 |
| 2 | 1 |
The query
from SmallInt i
select count(i)
is the same as the above except that it drops a column and would result in something like
| count |
| 1 |
| 1 |
However, QL results are real sets and have no duplicates, so the final answer is
| count |
| 1 |
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2 -
🚀 1
-
Thank you for your responses and examples, I have understood now.
Beta Was this translation helpful? Give feedback.