Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] Merge PR #8735

Open
wants to merge 37 commits into
base: feat/pipelines
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
acbf24f
add pipeline to Listen RPC
wu-hui Oct 15, 2024
93fdb23
Prepre for serializaion/deserialization
wu-hui Oct 17, 2024
8ac835e
fix rebase error
wu-hui Oct 17, 2024
422723a
quick hack to integrate with watch.
wu-hui Oct 21, 2024
ee64690
add api/pipelinesource and setup basic listen test
wu-hui Oct 31, 2024
1738c15
watch integration works.
wu-hui Nov 6, 2024
946a266
add pipeline canonify and eq
wu-hui Oct 22, 2024
6fc2050
runPipeline initial
wu-hui Oct 25, 2024
377e82f
initial offline function evaluation
wu-hui Oct 29, 2024
2b244a2
add basic tests for pipeline eval
wu-hui Oct 29, 2024
23b5135
runPipeline initial
wu-hui Oct 25, 2024
82b8303
Setting up QueryOrPipeline to replace Query
wu-hui Oct 30, 2024
7a3e789
type1 compiles
wu-hui Nov 12, 2024
4d7d917
introduce new variant for query_engine.test.ts
wu-hui Nov 13, 2024
c274177
Fix core/expression rebase error
wu-hui Nov 13, 2024
6e4a7e3
Add basic tests
wu-hui Nov 14, 2024
e6f860e
remove api/pipeline and use the lite one
wu-hui Nov 14, 2024
667c398
query_engine.test.ts pass with pipelines
wu-hui Nov 19, 2024
48a6324
local store tests PASS
wu-hui Nov 25, 2024
6ab2ba5
memory spec tests pass sans limitToLast
wu-hui Nov 28, 2024
58124c4
most spec tests PASS!
wu-hui Dec 2, 2024
0f63a54
limit to last, cursors and multitab for documents and database stages
wu-hui Dec 4, 2024
5945776
Merge remote-tracking branch 'origin/feat/pipelines' into wuandy/offp…
wu-hui Dec 6, 2024
5ad944e
fix merge errors
wu-hui Dec 10, 2024
da4dee3
Add expressions tests
wu-hui Dec 16, 2024
656e848
Ported all tests, plus some bug fixes
wu-hui Dec 19, 2024
90ce598
Merge remote-tracking branch 'origin/feat/pipelines' into wuandy/offp…
wu-hui Dec 19, 2024
34b3e71
fix merge errors
wu-hui Dec 19, 2024
c5678fe
fixed expressions tests
wu-hui Dec 20, 2024
f2a0585
Fixed all incompatibilities
wu-hui Dec 23, 2024
bc9ac99
Add gitignore entries
wu-hui Dec 28, 2024
0212394
Merge with feat/pipelines
wu-hui Dec 28, 2024
5e6cd52
Proto update sync and add query spec tests back
wu-hui Dec 28, 2024
2b4a5ad
merge with feat/pipeline
wu-hui Jan 28, 2025
ffc17e4
merge with feat/pipeline
wu-hui Jan 28, 2025
d2b18f9
Fix circular dependency caused by import from api_pipelines. Also sim…
MarkDuckworth Jan 29, 2025
d49ff96
Merge branch 'push-vwqlstsxuovu' of github.com:firebase/firebase-js-s…
MarkDuckworth Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fixed all incompatibilities
  • Loading branch information
wu-hui committed Dec 23, 2024
commit f2a05859c668bcedc373835d8fee93cbad97904e
34 changes: 24 additions & 10 deletions packages/firestore/src/core/expressions.ts
Original file line number Diff line number Diff line change
@@ -83,7 +83,8 @@ import {
TimestampSub,
Field,
Constant,
FilterExpr
FilterExpr,
IsNull
} from '../lite-api/expressions';
import {
CREATE_TIME_NAME,
@@ -176,6 +177,8 @@ export function toEvaluable<T>(expr: T): EvaluableExpr {
return new CoreNotEqAny(expr);
} else if (expr instanceof IsNan) {
return new CoreIsNan(expr);
} else if (expr instanceof IsNull) {
return new CoreIsNull(expr);
} else if (expr instanceof Exists) {
return new CoreExists(expr);
} else if (expr instanceof Not) {
@@ -283,10 +286,7 @@ export class CoreField implements EvaluableExpr {
timestampValue: toVersion(context.serializer, input.createTime)
};
}
return (
input.data.field(FieldPath.fromServerFormat(this.expr.fieldName())) ??
undefined
);
return input.data.field(this.expr.fieldPath) ?? undefined;
}
}

@@ -831,6 +831,24 @@ export class CoreIsNan implements EvaluableExpr {
}
}

export class CoreIsNull implements EvaluableExpr {
constructor(private expr: IsNull) {}

evaluate(
context: EvaluationContext,
input: PipelineInputOutput
): Value | undefined {
const evaluated = toEvaluable(this.expr.expr).evaluate(context, input);
return {
booleanValue: evaluated === undefined ? false : isNullValue(evaluated)
};
}

static fromProtoToApiObj(value: ProtoFunction): IsNan {
return new IsNan(exprFromProto(value.args![0]));
}
}

export class CoreExists implements EvaluableExpr {
constructor(private expr: Exists) {}

@@ -839,11 +857,7 @@ export class CoreExists implements EvaluableExpr {
input: PipelineInputOutput
): Value | undefined {
const evaluated = toEvaluable(this.expr.expr).evaluate(context, input);
if (evaluated === undefined) {
return undefined;
}

return TRUE_VALUE;
return evaluated === undefined ? FALSE_VALUE : TRUE_VALUE;
}

static fromProtoToApiObj(value: ProtoFunction): Exists {
64 changes: 62 additions & 2 deletions packages/firestore/src/lite-api/expressions.ts
Original file line number Diff line number Diff line change
@@ -885,6 +885,21 @@ export abstract class Expr implements ProtoSerializable<ProtoValue>, UserData {
return new IsNan(this);
}

/**
* Creates an expression that checks if this expression evaluates to `null`.
*
* ```typescript
* // Check if a field is set to value `null`. Returns false if it is set to
* // other values or is not set at all.
* Field.of("value").isNull();
* ```
*
* @return A new `Expr` representing the 'isNull' check.
*/
isNull(): IsNan {
return new IsNull(this);
}

/**
* Creates an expression that checks if a field exists in the document.
*
@@ -1923,7 +1938,7 @@ export class Field extends Expr implements Selectable {
* @private
*/
constructor(
private fieldPath: InternalFieldPath,
readonly fieldPath: InternalFieldPath,
private pipeline: Pipeline | null = null
) {
super();
@@ -1957,7 +1972,7 @@ export class Field extends Expr implements Selectable {
if (DOCUMENT_KEY_NAME === pipelineOrName) {
return new Field(documentId()._internalPath);
}
return new Field(fieldPathFromArgument('of', pipelineOrName));
return new Field(InternalFieldPath.fromServerFormat(pipelineOrName));
} else if (pipelineOrName instanceof FieldPath) {
if (documentId().isEqual(pipelineOrName)) {
return new Field(documentId()._internalPath);
@@ -2576,6 +2591,16 @@ export class IsNan extends FirestoreFunction implements FilterCondition {
filterable = true as const;
}

/**
* @beta
*/
export class IsNull extends FirestoreFunction implements FilterCondition {
constructor(readonly expr: Expr) {
super('is_null', [expr]);
}
filterable = true as const;
}

/**
* @beta
*/
@@ -4897,6 +4922,41 @@ export function isNan(value: Expr | string): IsNan {
return new IsNan(valueExpr);
}

/**
* @beta
*
* Creates an expression that checks if an expression evaluates to 'null'.
*
* ```typescript
* // Check if the field is set to 'null'. Returns false if it is not set, or
* // set to any other value.
* isNull(Field.of("value"));
* ```
*
* @param value The expression to check.
* @return A new {@code Expr} representing the 'isNull' check.
*/
export function isNull(value: Expr): IsNull;

/**
* @beta
*
* Creates an expression that checks if a field's value evaluates to 'null'.
*
* ```typescript
* // Check if the result of a calculation is null.
* isNull("value");
* ```
*
* @param value The name of the field to check.
* @return A new {@code Expr} representing the 'isNull' check.
*/
export function isNull(value: string): IsNull;
export function isNull(value: Expr | string): IsNull {
const valueExpr = value instanceof Expr ? value : Field.of(value);
return new IsNull(valueExpr);
}

/**
* @beta
*
4 changes: 2 additions & 2 deletions packages/firestore/test/unit/core/expressions.test.ts
Original file line number Diff line number Diff line change
@@ -351,7 +351,7 @@ function errorFilterExpr(): FilterExpr {
return Field.of('not-an-array').gt(0);
}

describe.only('Comparison Expressions', () => {
describe('Comparison Expressions', () => {
describe('eq', () => {
it('returns false for lessThan values', () => {
ComparisonValueTestData.lessThanValues().forEach(({ left, right }) => {
@@ -955,7 +955,7 @@ function expectEqual(
).to.be.true;
}

describe.only('Expressions', () => {
describe('Expressions', () => {
describe('Arithmetic Expressions', () => {
describe('add', () => {
it('basic_add_numerics', () => {
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.