Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Why is the result of "count" different from what I expected? #15759

Discussion options

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.

You must be logged in to vote

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

Comment options

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

You must be logged in to vote
2 replies
Comment options

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 |
Comment options

Thank you for your responses and examples, I have understood now.

Answer selected by ryokoCL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /