Skip to content

Commit 95afd27

Browse files
committed
fix usage of count in expressions
1 parent eeea59f commit 95afd27

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

src/tests/count.spec.ts

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ describe('[Queries] Count', () => {
3434
.to.deep.equal({ cnt: 3 });
3535
});
3636

37+
it('selects simple count in expression', () => {
38+
expect(one(`create table test(val text);
39+
insert into test values ('a'), ('b'), (null);
40+
select count(*)+1 as cnt from test`))
41+
.to.deep.equal({ cnt: 4 });
42+
});
43+
3744

3845

3946
it('counts nulls the right way', () => {

src/transforms/aggregation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ export class Aggregation<T> extends TransformBase<T> implements _ISelection<T> {
282282
, []
283283
, raw => raw[id]
284284
, {
285-
unpure: true
285+
forceNotConstant: true,
286286
});
287287

288288
this.aggregations.set(hashed, {

src/valuetypes.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ export class Evaluator<T = any> implements IValue<T> {
1414

1515
readonly isConstantLiteral: boolean;
1616
readonly usedColumns = new Set<IValue>();
17+
readonly forceNotConstant: boolean;
1718

1819
get index() {
1920
return this.origin?.getIndex(this);
2021
}
2122

2223
get isConstant(): boolean {
23-
return !this.usedColumns.size;
24+
return !this.usedColumns.size && !this.forceNotConstant;
2425
}
2526

2627
get isConstantReal(): boolean {
@@ -42,16 +43,22 @@ export class Evaluator<T = any> implements IValue<T> {
4243
, private opts?: {
4344
isAny?: boolean;
4445
isColumnOf?: _ISelection;
46+
forceNotConstant?: boolean;
4547
unpure?: boolean;
4648
}) {
4749
this.isConstantLiteral = typeof val !== 'function';
50+
if (opts?.forceNotConstant) {
51+
this.forceNotConstant = true;
52+
}
4853

4954
// fetch columns to depend on
5055
let depArray: IValue[];
56+
let hasNotConstant = false;
5157
if (dependencies) {
5258
if (!Array.isArray(dependencies)) {
5359
depArray = [dependencies];
5460
this.usedColumns = dependencies.usedColumns as Set<IValue>;
61+
hasNotConstant = !dependencies.isConstant;
5562
this.origin = dependencies.origin;
5663
} else {
5764
this.usedColumns = new Set();
@@ -62,6 +69,9 @@ export class Evaluator<T = any> implements IValue<T> {
6269
}
6370
this.origin = d.origin;
6471
}
72+
if (!d.isConstant) {
73+
hasNotConstant = true;
74+
}
6575
for (const u of d.usedColumns) {
6676
this.usedColumns.add(u);
6777
}
@@ -74,10 +84,14 @@ export class Evaluator<T = any> implements IValue<T> {
7484
this.origin = opts.isColumnOf;
7585
delete opts.isColumnOf;
7686
}
87+
if (hasNotConstant && !this.usedColumns.size) {
88+
this.forceNotConstant = true;
89+
}
7790

7891
if (!this.usedColumns.size // no used columns
7992
&& !this.origin
8093
&& !this.opts?.unpure
94+
&& !this.forceNotConstant
8195
&& !depArray?.some(x => !x.isConstantReal) // all real constant dependencies
8296
) {
8397
// no dependency => this is a real constant => evaluate it.

0 commit comments

Comments
 (0)