mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-15 01:28:30 +00:00
Resolve "isNan/whenNan formulas"
This commit is contained in:
parent
935ba12f25
commit
c1cfdb235b
7 changed files with 102 additions and 1 deletions
backend
src/baserow/contrib/database/formula/ast
tests/baserow/contrib/database/formula
web-frontend
locales
modules/database
test/unit/database/formula
|
@ -1,6 +1,6 @@
|
|||
from abc import ABC
|
||||
from decimal import Decimal
|
||||
from typing import List, Optional, Type
|
||||
from typing import List, Optional, Type, Union
|
||||
|
||||
from django.contrib.postgres.aggregates import JSONBAgg
|
||||
from django.db.models import (
|
||||
|
@ -147,6 +147,8 @@ def register_formula_functions(registry):
|
|||
registry.register(BaserowCeil())
|
||||
registry.register(BaserowFloor())
|
||||
registry.register(BaserowSign())
|
||||
registry.register(BaserowIsNaN())
|
||||
registry.register(BaserowWhenNan())
|
||||
# Boolean functions
|
||||
registry.register(BaserowIf())
|
||||
registry.register(BaserowEqual())
|
||||
|
@ -769,6 +771,44 @@ def int_like_numeric_output_field() -> fields.DecimalField:
|
|||
)
|
||||
|
||||
|
||||
class BaserowIsNaN(OneArgumentBaserowFunction):
|
||||
type = "is_nan"
|
||||
arg_type = [BaserowFormulaNumberType]
|
||||
|
||||
def type_function(
|
||||
self,
|
||||
func_call: BaserowFunctionCall[UnTyped],
|
||||
arg: Union[BaserowExpression[BaserowFormulaNumberType]],
|
||||
) -> BaserowExpression[BaserowFormulaType]:
|
||||
return func_call.with_valid_type(BaserowFormulaBooleanType())
|
||||
|
||||
def to_django_expression(self, arg: Expression) -> Expression:
|
||||
return EqualsExpr(
|
||||
arg,
|
||||
Value(Decimal("NaN")),
|
||||
output_field=fields.BooleanField(),
|
||||
)
|
||||
|
||||
|
||||
class BaserowWhenNan(TwoArgumentBaserowFunction):
|
||||
type = "when_nan"
|
||||
arg1_type = [BaserowFormulaNumberType]
|
||||
arg2_type = [BaserowFormulaNumberType]
|
||||
|
||||
def type_function(
|
||||
self,
|
||||
func_call: BaserowFunctionCall[UnTyped],
|
||||
arg1: Union[BaserowExpression[BaserowFormulaNumberType]],
|
||||
arg2: Union[BaserowExpression[BaserowFormulaNumberType]],
|
||||
) -> BaserowExpression[BaserowFormulaType]:
|
||||
return func_call.with_valid_type(
|
||||
calculate_number_type([arg1.expression_type, arg2.expression_type])
|
||||
)
|
||||
|
||||
def to_django_expression(self, arg1: Expression, arg2: Expression) -> Expression:
|
||||
return handle_arg_being_nan(arg1, arg2, arg1)
|
||||
|
||||
|
||||
class BaserowInt(BaserowTrunc):
|
||||
"""
|
||||
Kept for backwards compatability as was introduced in v3 of formula language but
|
||||
|
|
|
@ -263,6 +263,12 @@ VALID_FORMULA_TESTS = [
|
|||
("exp(-1.00)", "0.37"),
|
||||
("exp(1/0)", "NaN"),
|
||||
("exp(tonumber('invalid'))", "NaN"),
|
||||
("is_nan(1/0)", True),
|
||||
("is_nan(1)", False),
|
||||
("when_nan(1/0, 4)", "4.0000000000"),
|
||||
("when_nan(1.0, 4)", "1.0"),
|
||||
("when_nan(1, 4.0)", "1.0"),
|
||||
("when_nan(1/0, 1/0)", "NaN"),
|
||||
("int(1.1234)", "1"),
|
||||
("int(1.56)", "1"),
|
||||
("int(-1.56)", "-1"),
|
||||
|
|
|
@ -16,6 +16,7 @@ For example:
|
|||
* Can add a row with textual values for single select, multiple select and link row field. [#1312](https://gitlab.com/bramw/baserow/-/issues/1312)
|
||||
* Add e2e tests. [#820](https://gitlab.com/bramw/baserow/-/issues/820)
|
||||
* Added missing actions for audit log. [#1500](https://gitlab.com/bramw/baserow/-/issues/1500)
|
||||
* Add `is_nan` and `when_nan` formula functions [#1527](https://gitlab.com/bramw/baserow/-/issues/1527)
|
||||
|
||||
### Bug Fixes
|
||||
* Add missing `procps` system package to all-in-one docker image fixing `/baserow/supervisor/docker-postgres-setup.sh run` (#1512)[https://gitlab.com/bramw/baserow/-/issues/1512]
|
||||
|
|
|
@ -381,6 +381,8 @@
|
|||
"sqrtDescription": "Returns the square root of the argument provided.",
|
||||
"roundDescription": "Returns first argument rounded to the number of digits specified by the second argument.",
|
||||
"truncDescription": "Returns only the first argument converted into an integer by truncating any decimal places.",
|
||||
"isNanDescription": "Returns true if the argument is 'NaN', returns false otherwise.",
|
||||
"wheNanDescription": "Returns the first argument if it's not 'NaN'. Returns the second argument if the first argument is 'NaN'",
|
||||
"absDescription": "Returns the absolute value for the argument number provided.",
|
||||
"ceilDescription": "Returns the smallest integer that is greater than or equal the argument number provided.",
|
||||
"floorDescription": "Returns the largest integer that is less than or equal the argument number provided."
|
||||
|
|
|
@ -1594,6 +1594,52 @@ export class BaserowTrunc extends BaserowFunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
export class BaserowIsNaN extends BaserowFunctionDefinition {
|
||||
static getType() {
|
||||
return 'is_nan'
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('formulaFunctions.isNanDescription')
|
||||
}
|
||||
|
||||
getSyntaxUsage() {
|
||||
return ['is_nan(number)']
|
||||
}
|
||||
|
||||
getExamples() {
|
||||
return ['is_nan(1 / 0) = true', 'is_nan(1) = false']
|
||||
}
|
||||
|
||||
getFormulaType() {
|
||||
return 'number'
|
||||
}
|
||||
}
|
||||
|
||||
export class BaserowWhenNaN extends BaserowFunctionDefinition {
|
||||
static getType() {
|
||||
return 'when_nan'
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('formulaFunctions.whenNanDescription')
|
||||
}
|
||||
|
||||
getSyntaxUsage() {
|
||||
return ['when_nan(number, fallback)']
|
||||
}
|
||||
|
||||
getExamples() {
|
||||
return ['when_nan(1 / 0, 4) = 4', 'when_nan(1, 4) = 1']
|
||||
}
|
||||
|
||||
getFormulaType() {
|
||||
return 'number'
|
||||
}
|
||||
}
|
||||
|
||||
export class BaserowLeast extends BaserowFunctionDefinition {
|
||||
static getType() {
|
||||
return 'least'
|
||||
|
|
|
@ -155,6 +155,8 @@ import {
|
|||
BaserowContains,
|
||||
BaserowFilter,
|
||||
BaserowTrunc,
|
||||
BaserowIsNaN,
|
||||
BaserowWhenNaN,
|
||||
BaserowEven,
|
||||
BaserowOdd,
|
||||
BaserowCeil,
|
||||
|
@ -458,6 +460,8 @@ export default (context) => {
|
|||
app.$registry.register('formula_function', new BaserowSum(context))
|
||||
app.$registry.register('formula_function', new BaserowFilter(context))
|
||||
app.$registry.register('formula_function', new BaserowTrunc(context))
|
||||
app.$registry.register('formula_function', new BaserowIsNaN(context))
|
||||
app.$registry.register('formula_function', new BaserowWhenNaN(context))
|
||||
app.$registry.register('formula_function', new BaserowEven(context))
|
||||
app.$registry.register('formula_function', new BaserowOdd(context))
|
||||
app.$registry.register('formula_function', new BaserowAbs(context))
|
||||
|
|
|
@ -47,6 +47,7 @@ describe('Formula Functions Test', () => {
|
|||
'if',
|
||||
'equal',
|
||||
'isblank',
|
||||
'is_nan',
|
||||
'not',
|
||||
'not_equal',
|
||||
'greater_than',
|
||||
|
@ -67,6 +68,7 @@ describe('Formula Functions Test', () => {
|
|||
'minus',
|
||||
'row_id',
|
||||
'when_empty',
|
||||
'when_nan',
|
||||
'any',
|
||||
'every',
|
||||
'max',
|
||||
|
|
Loading…
Add table
Reference in a new issue