mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-07 15:45:59 +00:00
Correctly compare numeric field values
This commit is contained in:
parent
d4006461f6
commit
1c834cbb77
@ -0,0 +1,12 @@
|
|||||||
|
DROP ALIAS IF EXISTS CAST_TO_NUMERIC;
|
||||||
|
CREATE ALIAS CAST_TO_NUMERIC AS '
|
||||||
|
import java.text.*;
|
||||||
|
import java.math.*;
|
||||||
|
@CODE
|
||||||
|
BigDecimal castToNumeric(String s) throws Exception {
|
||||||
|
try { return new BigDecimal(s); }
|
||||||
|
catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'
|
@ -0,0 +1,5 @@
|
|||||||
|
-- Create a function to cast to a numeric, if an error occurs return null
|
||||||
|
-- Could not get it working with decimal type, so using double
|
||||||
|
create or replace function CAST_TO_NUMERIC (s char(255))
|
||||||
|
returns double deterministic
|
||||||
|
return cast(s as double);
|
@ -0,0 +1,9 @@
|
|||||||
|
-- Create a function to cast to a numeric, if an error occurs return null
|
||||||
|
create or replace function CAST_TO_NUMERIC(text) returns numeric as $$
|
||||||
|
begin
|
||||||
|
return cast($1 as numeric);
|
||||||
|
exception
|
||||||
|
when invalid_text_representation then
|
||||||
|
return null;
|
||||||
|
end;
|
||||||
|
$$ language plpgsql immutable;
|
@ -29,6 +29,8 @@ object DBFunction {
|
|||||||
|
|
||||||
case class Cast(expr: SelectExpr, newType: String) extends DBFunction
|
case class Cast(expr: SelectExpr, newType: String) extends DBFunction
|
||||||
|
|
||||||
|
case class CastNumeric(expr: SelectExpr) extends DBFunction
|
||||||
|
|
||||||
case class Avg(expr: SelectExpr) extends DBFunction
|
case class Avg(expr: SelectExpr) extends DBFunction
|
||||||
|
|
||||||
case class Sum(expr: SelectExpr) extends DBFunction
|
case class Sum(expr: SelectExpr) extends DBFunction
|
||||||
|
@ -89,6 +89,9 @@ trait DSL extends DoobieMeta {
|
|||||||
def cast(expr: SelectExpr, targetType: String): DBFunction =
|
def cast(expr: SelectExpr, targetType: String): DBFunction =
|
||||||
DBFunction.Cast(expr, targetType)
|
DBFunction.Cast(expr, targetType)
|
||||||
|
|
||||||
|
def castNumeric(expr: SelectExpr): DBFunction =
|
||||||
|
DBFunction.CastNumeric(expr)
|
||||||
|
|
||||||
def coalesce(expr: SelectExpr, more: SelectExpr*): DBFunction.Coalesce =
|
def coalesce(expr: SelectExpr, more: SelectExpr*): DBFunction.Coalesce =
|
||||||
DBFunction.Coalesce(expr, more.toVector)
|
DBFunction.Coalesce(expr, more.toVector)
|
||||||
|
|
||||||
|
@ -242,16 +242,33 @@ object ItemQueryGenerator {
|
|||||||
)(coll: Ident, op: QOp, value: String): Select = {
|
)(coll: Ident, op: QOp, value: String): Select = {
|
||||||
val cf = RCustomField.as("cf")
|
val cf = RCustomField.as("cf")
|
||||||
val cfv = RCustomFieldValue.as("cfv")
|
val cfv = RCustomFieldValue.as("cfv")
|
||||||
val v = if (op == QOp.LowerLike) QueryWildcard.lower(value) else value
|
|
||||||
|
val baseSelect =
|
||||||
Select(
|
Select(
|
||||||
select(cfv.itemId),
|
select(cfv.itemId),
|
||||||
from(cfv).innerJoin(cf, cf.id === cfv.field),
|
from(cfv).innerJoin(cf, sel(cf) && cf.cid === coll && cf.id === cfv.field)
|
||||||
cf.cid === coll && sel(cf) && Condition.CompareVal(
|
|
||||||
cfv.value,
|
|
||||||
op,
|
|
||||||
v
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (op == QOp.LowerLike) {
|
||||||
|
val v = QueryWildcard.lower(value)
|
||||||
|
baseSelect.where(Condition.CompareVal(cfv.value, op, v))
|
||||||
|
} else {
|
||||||
|
val stringCmp =
|
||||||
|
Condition.CompareVal(cfv.value, op, value)
|
||||||
|
|
||||||
|
value.toDoubleOption
|
||||||
|
.map { n =>
|
||||||
|
val numericCmp = Condition.CompareFVal(castNumeric(cfv.value.s), op, n)
|
||||||
|
val fieldIsNumeric =
|
||||||
|
cf.ftype === CustomFieldType.Numeric || cf.ftype === CustomFieldType.Money
|
||||||
|
val fieldNotNumeric =
|
||||||
|
cf.ftype <> CustomFieldType.Numeric && cf.ftype <> CustomFieldType.Money
|
||||||
|
baseSelect.where(
|
||||||
|
(fieldIsNumeric && numericCmp) || (fieldNotNumeric && stringCmp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.getOrElse(baseSelect.where(stringCmp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,9 @@ object DBFunctionBuilder extends CommonBuilder {
|
|||||||
fr" AS" ++ Fragment.const(newType) ++
|
fr" AS" ++ Fragment.const(newType) ++
|
||||||
sql")"
|
sql")"
|
||||||
|
|
||||||
|
case DBFunction.CastNumeric(f) =>
|
||||||
|
sql"CAST_TO_NUMERIC(" ++ SelectExprBuilder.build(f) ++ sql")"
|
||||||
|
|
||||||
case DBFunction.Avg(expr) =>
|
case DBFunction.Avg(expr) =>
|
||||||
sql"AVG(" ++ SelectExprBuilder.build(expr) ++ fr")"
|
sql"AVG(" ++ SelectExprBuilder.build(expr) ++ fr")"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user