@@ -277,6 +277,100 @@ public static Expression ifAbsent(String ifFieldName, Object elseValue) {
277277 return ifAbsent (field (ifFieldName ), toExprOrConstant (elseValue ));
278278 }
279279
280+ /**
281+ * Creates an expression that returns a default value if an expression evaluates to null.
282+ *
283+ * <p>Note: This function provides a fallback for both absent and explicit null values. In
284+ * contrast, {@link ifAbsent} only triggers for missing fields.
285+ *
286+ * @param ifExpr The expression to check.
287+ * @param elseExpression The default expression that will be evaluated and returned.
288+ * @return A new {@link Expression} representing the ifNull operation.
289+ */
290+ @ BetaApi
291+ public static Expression ifNull (Expression ifExpr , Expression elseExpression ) {
292+ return new FunctionExpression ("if_null" , ImmutableList .of (ifExpr , elseExpression ));
293+ }
294+
295+ /**
296+ * Creates an expression that returns a default value if an expression evaluates to null.
297+ *
298+ * <p>Note: This function provides a fallback for both absent and explicit null values. In
299+ * contrast, {@link ifAbsent} only triggers for missing fields.
300+ *
301+ * @param ifExpr The expression to check.
302+ * @param elseValue The default value that will be returned.
303+ * @return A new {@link Expression} representing the ifNull operation.
304+ */
305+ @ BetaApi
306+ public static Expression ifNull (Expression ifExpr , Object elseValue ) {
307+ return ifNull (ifExpr , toExprOrConstant (elseValue ));
308+ }
309+
310+ /**
311+ * Creates an expression that returns a default value if a field is null.
312+ *
313+ * <p>Note: This function provides a fallback for both absent and explicit null values. In
314+ * contrast, {@link ifAbsent} only triggers for missing fields.
315+ *
316+ * @param ifFieldName The field to check.
317+ * @param elseExpression The default expression that will be evaluated and returned.
318+ * @return A new {@link Expression} representing the ifNull operation.
319+ */
320+ @ BetaApi
321+ public static Expression ifNull (String ifFieldName , Expression elseExpression ) {
322+ return ifNull (field (ifFieldName ), elseExpression );
323+ }
324+
325+ /**
326+ * Creates an expression that returns a default value if a field is null.
327+ *
328+ * <p>Note: This function provides a fallback for both absent and explicit null values. In
329+ * contrast, {@link ifAbsent} only triggers for missing fields.
330+ *
331+ * @param ifFieldName The field to check.
332+ * @param elseValue The default value that will be returned.
333+ * @return A new {@link Expression} representing the ifNull operation.
334+ */
335+ @ BetaApi
336+ public static Expression ifNull (String ifFieldName , Object elseValue ) {
337+ return ifNull (field (ifFieldName ), toExprOrConstant (elseValue ));
338+ }
339+
340+ /**
341+ * Returns the first non-null, non-absent argument, without evaluating the rest of the arguments.
342+ * When all arguments are null or absent, returns the last argument.
343+ *
344+ * @param expression The first expression to check for null.
345+ * @param replacement The fallback expression or value if the first one is null.
346+ * @param others Optional additional expressions to check if previous ones are null.
347+ * @return A new {@link Expression} representing the coalesce operation.
348+ */
349+ @ BetaApi
350+ public static Expression coalesce (Expression expression , Object replacement , Object ... others ) {
351+ ImmutableList .Builder <Expression > args = ImmutableList .builder ();
352+ args .add (expression );
353+ args .add (toExprOrConstant (replacement ));
354+ for (Object other : others ) {
355+ args .add (toExprOrConstant (other ));
356+ }
357+ return new FunctionExpression ("coalesce" , args .build ());
358+ }
359+
360+ /**
361+ * Returns the first non-null, non-absent argument, without evaluating the rest of the arguments.
362+ * When all arguments are null or absent, returns the last argument.
363+ *
364+ * @param firstFieldName The name of the first field to check for null.
365+ * @param replacement The fallback expression or value if the first one is null.
366+ * @param others Optional additional expressions to check if previous ones are null.
367+ * @return A new {@link Expression} representing the coalesce operation.
368+ */
369+ @ BetaApi
370+ public static Expression coalesce (String firstFieldName , Object replacement , Object ... others ) {
371+ return coalesce (field (firstFieldName ), replacement , others );
372+ }
373+
280374 /**
281375 * Creates an expression that joins the elements of an array into a string.
282376 *
@@ -5118,6 +5212,33 @@ public Expression ifAbsent(Object elseValue) {
51185212 return Expression .ifAbsent (this , elseValue );
51195213 }
51205214
5215+ /**
5216+ * Creates an expression that returns a default value if this expression evaluates null.
5217+ *
5218+ * <p>Note: This function provides a fallback for both absent and explicit null values. In
5219+ * contrast, {@link ifAbsent} only triggers for missing fields.
5220+ *
5221+ * @param elseValue The default value that will be returned.
5222+ * @return A new {@link Expression} representing the ifNull operation.
5223+ */
5224+ @ BetaApi
5225+ public Expression ifNull (Object elseValue ) {
5226+ return Expression .ifNull (this , elseValue );
5227+ }
5228+
5229+ /**
5230+ * Returns the first non-null, non-absent argument, without evaluating the rest of the arguments.
5231+ * When all arguments are null or absent, returns the last argument.
5232+ *
5233+ * @param second The next expression or literal to evaluate.
5234+ * @param others Additional expressions or literals to evaluate.
5235+ * @return A new {@link Expression} representing the coalesce operation.
5236+ */
5237+ @ BetaApi
5238+ public Expression coalesce (Object second , Object ... others ) {
5239+ return Expression .coalesce (this , second , others );
5240+ }
5241+
51215242 /**
51225243 * Creates an expression that joins the elements of this array expression into a string.
51235244 *
0 commit comments