Skip to content

Commit d920859

Browse files
authored
Merge pull request #7857 from googleapis/mila/ifnull-coalesce
2 parents f17a791 + 6168679 commit d920859

5 files changed

Lines changed: 547 additions & 1 deletion

File tree

handwritten/firestore/api-report/firestore.api.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,12 @@ function charLength(fieldName: string): FunctionExpression;
498498
// @beta
499499
function charLength(stringExpression: Expression): FunctionExpression;
500500

501+
// @beta
502+
function coalesce(expression: Expression, replacement: Expression | unknown, ...others: Array<Expression | unknown>): FunctionExpression;
503+
504+
// @beta
505+
function coalesce(fieldName: string, replacement: Expression | unknown, ...others: Array<Expression | unknown>): FunctionExpression;
506+
501507
// Warning: (tsdoc-undefined-tag) The TSDoc tag "@class" is not defined in this configuration
502508
//
503509
// @public
@@ -1099,6 +1105,7 @@ abstract class Expression implements firestore.Pipelines.Expression, HasUserData
10991105
byteLength(): FunctionExpression;
11001106
ceil(): FunctionExpression;
11011107
charLength(): FunctionExpression;
1108+
coalesce(replacement: Expression | unknown, ...others: Array<Expression | unknown>): FunctionExpression;
11021109
collectionId(): FunctionExpression;
11031110
concat(second: Expression | unknown, ...others: Array<Expression | unknown>): FunctionExpression;
11041111
cosineDistance(vectorExpression: Expression): FunctionExpression;
@@ -1135,6 +1142,8 @@ abstract class Expression implements firestore.Pipelines.Expression, HasUserData
11351142
ifAbsent(elseExpression: unknown): Expression;
11361143
ifError(catchExpr: Expression): FunctionExpression;
11371144
ifError(catchValue: unknown): FunctionExpression;
1145+
ifNull(elseExpression: Expression): FunctionExpression;
1146+
ifNull(elseValue: unknown): FunctionExpression;
11381147
isAbsent(): BooleanExpression;
11391148
isError(): BooleanExpression;
11401149
isType(type: string): BooleanExpression;
@@ -1643,6 +1652,18 @@ function ifError(tryExpr: Expression, catchExpr: Expression): FunctionExpression
16431652
// @beta
16441653
function ifError(tryExpr: Expression, catchValue: unknown): FunctionExpression;
16451654

1655+
// @beta
1656+
function ifNull(ifExpr: Expression, elseExpr: Expression): FunctionExpression;
1657+
1658+
// @beta
1659+
function ifNull(ifExpr: Expression, elseValue: unknown): FunctionExpression;
1660+
1661+
// @beta
1662+
function ifNull(ifFieldName: string, elseExpr: Expression): FunctionExpression;
1663+
1664+
// @beta
1665+
function ifNull(ifFieldName: string, elseValue: unknown): FunctionExpression;
1666+
16461667
// @beta
16471668
function isAbsent(value: Expression): BooleanExpression;
16481669

@@ -2139,7 +2160,9 @@ declare namespace Pipelines {
21392160
stringReplaceAll,
21402161
stringReplaceOne,
21412162
nor,
2142-
switchOn
2163+
switchOn,
2164+
ifNull,
2165+
coalesce
21432166
}
21442167
}
21452168
export { Pipelines }

handwritten/firestore/dev/src/pipelines/expression.ts

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,6 +2976,79 @@ export abstract class Expression
29762976
]);
29772977
}
29782978

2979+
/**
2980+
* @beta
2981+
* Creates an expression that returns the `elseValue` argument if this expression evaluates to null, else
2982+
* return the result of this expression evaluation.
2983+
*
2984+
* @remarks
2985+
* This function provides a fallback for both absent and explicit null values. In contrast, {@link Expression#ifAbsent}
2986+
* only triggers for missing fields.
2987+
*
2988+
* @example
2989+
* ```typescript
2990+
* // Returns the user's preferred name, or if that is null, returns their full name.
2991+
* field("preferredName").ifNull(field("fullName"))
2992+
* ```
2993+
*
2994+
* @param elseExpression The Expression that will be evaluated if this Expression evaluates to null.
2995+
* @returns A new [Expression] representing the ifNull operation.
2996+
*/
2997+
ifNull(elseExpression: Expression): FunctionExpression;
2998+
2999+
/**
3000+
* @beta
3001+
* Creates an expression that returns the `elseValue` argument if this expression evaluates to null, else
3002+
* return the result of this expression evaluation.
3003+
*
3004+
* @remarks
3005+
* This function provides a fallback for both absent and explicit null values. In contrast, {@link Expression#ifAbsent}
3006+
* only triggers for missing fields.
3007+
*
3008+
* @example
3009+
* ```typescript
3010+
* // Returns the user's display name, or returns "Anonymous" if the field is null.
3011+
* field("displayName").ifNull("Anonymous")
3012+
* ```
3013+
*
3014+
* @param elseValue The value that will be returned if this Expression evaluates to null.
3015+
* @returns A new [Expression] representing the ifNull operation.
3016+
*/
3017+
ifNull(elseValue: unknown): FunctionExpression;
3018+
ifNull(elseValueOrExpression: Expression | unknown): FunctionExpression {
3019+
return new FunctionExpression('if_null', [
3020+
this,
3021+
valueToDefaultExpr(elseValueOrExpression),
3022+
]);
3023+
}
3024+
3025+
/**
3026+
* @beta
3027+
* Creates an expression that returns the first non-null, non-absent argument, without evaluating
3028+
* the rest of the arguments. When all arguments are null or absent, returns the last argument.
3029+
*
3030+
* @example
3031+
* ```typescript
3032+
* // Returns the value of the first non-null, non-absent field among 'preferredName', 'fullName',
3033+
* // or the last argument if all previous fields are null.
3034+
* field("preferredName").coalesce(field("fullName"), "Anonymous");
3035+
* ```
3036+
*
3037+
* @param replacement - The value to use if this expression evaluates to null.
3038+
* @param others - Optional additional values to check if previous values are null.
3039+
* @returns A new [Expression] representing the coalesce operation.
3040+
*/
3041+
coalesce(
3042+
replacement: Expression | unknown,
3043+
...others: Array<Expression | unknown>
3044+
): FunctionExpression {
3045+
const values = [replacement, ...others];
3046+
return new FunctionExpression('coalesce', [
3047+
this,
3048+
...values.map(valueToDefaultExpr),
3049+
]);
3050+
}
3051+
29793052
/**
29803053
* @beta
29813054
* Creates an expression that joins the elements of an array into a string.
@@ -9310,6 +9383,167 @@ export function ifAbsent(
93109383
);
93119384
}
93129385

9386+
/**
9387+
* @beta
9388+
* Creates an expression that returns the `elseExpr` argument if `ifExpr` is null, else
9389+
* return the result of the `ifExpr` argument evaluation.
9390+
*
9391+
* @remarks
9392+
* This function provides a fallback for both absent and explicit null values. In contrast,
9393+
* {@link Expression#ifAbsent} only triggers for missing fields.
9394+
*
9395+
* @example
9396+
* ```typescript
9397+
* // Returns the user's preferred name, or if that is null, returns their full name.
9398+
* ifNull(field("preferredName"), field("fullName"))
9399+
* ```
9400+
*
9401+
* @param ifExpr The expression to check for null.
9402+
* @param elseExpr The expression that will be evaluated and returned if `ifExpr` is null.
9403+
* @returns A new `Expression` representing the ifNull operation.
9404+
*/
9405+
export function ifNull(
9406+
ifExpr: Expression,
9407+
elseExpr: Expression,
9408+
): FunctionExpression;
9409+
9410+
/**
9411+
* @beta
9412+
* Creates an expression that returns the `elseValue` argument if `ifExpr` is null, else
9413+
* return the result of the `ifExpr` argument evaluation.
9414+
*
9415+
* @remarks
9416+
* This function provides a fallback for both absent and explicit null values. In contrast,
9417+
* {@link Expression#ifAbsent} only triggers for missing fields.
9418+
*
9419+
* @example
9420+
* ```typescript
9421+
* // Returns the user's display name, or returns "Anonymous" if the field is null.
9422+
* ifNull(field("displayName"), "Anonymous")
9423+
* ```
9424+
*
9425+
* @param ifExpr The expression to check for null.
9426+
* @param elseValue The value that will be returned if `ifExpr` evaluates to null.
9427+
* @returns A new `Expression` representing the ifNull operation.
9428+
*/
9429+
export function ifNull(
9430+
ifExpr: Expression,
9431+
elseValue: unknown,
9432+
): FunctionExpression;
9433+
9434+
/**
9435+
* @beta
9436+
* Creates an expression that returns the `elseExpr` argument if `ifFieldName` is null, else
9437+
* return the value of the field.
9438+
*
9439+
* @remarks
9440+
* This function provides a fallback for both absent and explicit null values. In contrast,
9441+
* {@link Expression#ifAbsent} only triggers for missing fields.
9442+
*
9443+
* @example
9444+
* ```typescript
9445+
* // Returns the user's preferred name, or if that is null, returns their full name.
9446+
* ifNull("preferredName", field("fullName"))
9447+
* ```
9448+
*
9449+
* @param ifFieldName The field to check for null.
9450+
* @param elseExpr The expression that will be evaluated and returned if `ifFieldName` is
9451+
* null.
9452+
* @returns A new `Expression` representing the ifNull operation.
9453+
*/
9454+
export function ifNull(
9455+
ifFieldName: string,
9456+
elseExpr: Expression,
9457+
): FunctionExpression;
9458+
9459+
/**
9460+
* @beta
9461+
* Creates an expression that returns the `elseValue` argument if `ifFieldName` is null, else
9462+
* return the value of the field.
9463+
*
9464+
* @remarks
9465+
* This function provides a fallback for both absent and explicit null values. In contrast,
9466+
* {@link Expression#ifAbsent} only triggers for missing fields.
9467+
*
9468+
* @example
9469+
* ```typescript
9470+
* // Returns the user's display name, or returns "Anonymous" if the field is null.
9471+
* ifNull("displayName", "Anonymous")
9472+
* ```
9473+
*
9474+
* @param ifFieldName The field to check for null.
9475+
* @param elseValue The value that will be returned if `ifFieldName` is null.
9476+
* @returns A new `Expression` representing the ifNull operation.
9477+
*/
9478+
export function ifNull(
9479+
ifFieldName: string,
9480+
elseValue: unknown,
9481+
): FunctionExpression;
9482+
export function ifNull(
9483+
fieldNameOrExpression: string | Expression,
9484+
elseValue: Expression | unknown,
9485+
): FunctionExpression {
9486+
return fieldOrExpression(fieldNameOrExpression).ifNull(
9487+
valueToDefaultExpr(elseValue),
9488+
);
9489+
}
9490+
9491+
/**
9492+
* @beta
9493+
* Creates an expression that returns the first non-null, non-absent argument, without evaluating
9494+
* the rest of the arguments. When all arguments are null or absent, returns the last argument.
9495+
*
9496+
* @example
9497+
* ```typescript
9498+
* // Returns the value of the first non-null, non-absent field among 'preferredName', 'fullName',
9499+
* // or the last argument if all previous fields are null.
9500+
* coalesce(field("preferredName"), field("fullName"), constant("Anonymous"))
9501+
* ```
9502+
*
9503+
* @param expression The first expression to check for null.
9504+
* @param replacement The fallback expression or value if the first one is null.
9505+
* @param others Optional additional expressions to check if previous ones are null.
9506+
* @returns A new `Expression` representing the coalesce operation.
9507+
*/
9508+
export function coalesce(
9509+
expression: Expression,
9510+
replacement: Expression | unknown,
9511+
...others: Array<Expression | unknown>
9512+
): FunctionExpression;
9513+
9514+
/**
9515+
* @beta
9516+
* Creates an expression that returns the first non-null, non-absent argument, without evaluating
9517+
* the rest of the arguments. When all arguments are null or absent, returns the last argument.
9518+
*
9519+
* @example
9520+
* ```typescript
9521+
* // Returns the value of the first non-null, non-absent field among 'preferredName', 'fullName',
9522+
* // or the last argument if all previous fields are null.
9523+
* coalesce("preferredName", field("fullName"), constant("Anonymous"))
9524+
* ```
9525+
*
9526+
* @param fieldName The name of the first field to check for null.
9527+
* @param replacement The fallback expression or value if the first one is null.
9528+
* @param others Optional additional expressions to check if previous ones are null.
9529+
* @returns A new `Expression` representing the coalesce operation.
9530+
*/
9531+
export function coalesce(
9532+
fieldName: string,
9533+
replacement: Expression | unknown,
9534+
...others: Array<Expression | unknown>
9535+
): FunctionExpression;
9536+
export function coalesce(
9537+
fieldNameOrExpression: Expression | string,
9538+
replacement: Expression | unknown,
9539+
...others: Array<Expression | unknown>
9540+
): FunctionExpression {
9541+
return fieldOrExpression(fieldNameOrExpression).coalesce(
9542+
replacement,
9543+
...others,
9544+
);
9545+
}
9546+
93139547
/**
93149548
* @beta
93159549
* Creates an expression that joins the elements of an array into a string.

handwritten/firestore/dev/src/pipelines/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,5 +159,7 @@ export {
159159
stringReplaceOne,
160160
nor,
161161
switchOn,
162+
ifNull,
163+
coalesce,
162164
// TODO(new-expression): Add new expression exports above this line
163165
} from './expression';

0 commit comments

Comments
 (0)