import com.healthmarketscience.jackcess.expr.Identifier;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
-import com.healthmarketscience.jackcess.impl.expr.BuiltinOperators;
import com.healthmarketscience.jackcess.impl.expr.Expressionator;
+import com.healthmarketscience.jackcess.impl.expr.ValueSupport;
/**
*
try {
val = ColumnImpl.toInternalValue(dType, val, getDatabase());
if(val == null) {
- return BuiltinOperators.NULL_VAL;
+ return ValueSupport.NULL_VAL;
}
Value.Type vType = toValueType(dType);
switch(vType) {
case STRING:
- return BuiltinOperators.toValue(val.toString());
+ return ValueSupport.toValue(val.toString());
case DATE:
case TIME:
case DATE_TIME:
- return BuiltinOperators.toValue(this, vType, (Date)val);
+ return ValueSupport.toValue(this, vType, (Date)val);
case LONG:
Integer i = ((val instanceof Integer) ? (Integer)val :
((Number)val).intValue());
- return BuiltinOperators.toValue(i);
+ return ValueSupport.toValue(i);
case DOUBLE:
Double d = ((val instanceof Double) ? (Double)val :
((Number)val).doubleValue());
- return BuiltinOperators.toValue(d);
+ return ValueSupport.toValue(d);
case BIG_DEC:
BigDecimal bd = ColumnImpl.toBigDecimal(val, getDatabase());
- return BuiltinOperators.toValue(bd);
+ return ValueSupport.toValue(bd);
default:
throw new RuntimeException("Unexpected type " + vType);
}
package com.healthmarketscience.jackcess.impl.expr;
import java.math.BigDecimal;
-import java.text.DateFormat;
-import java.util.Date;
import java.util.regex.Pattern;
import com.healthmarketscience.jackcess.expr.EvalContext;
import com.healthmarketscience.jackcess.expr.EvalException;
import com.healthmarketscience.jackcess.expr.Value;
-import com.healthmarketscience.jackcess.impl.ColumnImpl;
import com.healthmarketscience.jackcess.impl.NumberFormatter;
+import static com.healthmarketscience.jackcess.impl.expr.ValueSupport.*;
/**
private static final double MIN_INT = Integer.MIN_VALUE;
private static final double MAX_INT = Integer.MAX_VALUE;
- public static final Value NULL_VAL = new BaseValue() {
- @Override public boolean isNull() {
- return true;
- }
- public Type getType() {
- return Type.NULL;
- }
- public Object get() {
- return null;
- }
- };
- // access seems to like -1 for true and 0 for false (boolean values are
- // basically an illusion)
- public static final Value TRUE_VAL = new LongValue(-1);
- public static final Value FALSE_VAL = new LongValue(0);
- public static final Value EMPTY_STR_VAL = new StringValue("");
- public static final Value ZERO_VAL = FALSE_VAL;
- public static final Value NEG_ONE_VAL = TRUE_VAL;
- public static final Value ONE_VAL = new LongValue(1);
-
-
private enum CoercionType {
SIMPLE(true, true), GENERAL(false, true), COMPARE(false, false);
}
}
- public static Value toValue(boolean b) {
- return (b ? TRUE_VAL : FALSE_VAL);
- }
-
- public static Value toValue(String s) {
- return new StringValue(s);
- }
-
- public static Value toValue(int i) {
- return new LongValue(i);
- }
-
- public static Value toValue(Integer i) {
- return new LongValue(i);
- }
-
- public static Value toValue(float f) {
- return new DoubleValue((double)f);
- }
-
- public static Value toValue(double s) {
- return new DoubleValue(s);
- }
-
- public static Value toValue(Double s) {
- return new DoubleValue(s);
- }
-
- public static Value toValue(BigDecimal s) {
- return new BigDecimalValue(normalize(s));
- }
-
- public static Value toValue(Value.Type type, double dd, DateFormat fmt) {
- return toValue(type, new Date(ColumnImpl.fromDateDouble(
- dd, fmt.getCalendar())), fmt);
- }
-
- public static Value toValue(EvalContext ctx, Value.Type type, Date d) {
- return toValue(type, d, getDateFormatForType(ctx, type));
- }
-
- public static Value toValue(Value.Type type, Date d, DateFormat fmt) {
- switch(type) {
- case DATE:
- return new DateValue(d, fmt);
- case TIME:
- return new TimeValue(d, fmt);
- case DATE_TIME:
- return new DateTimeValue(d, fmt);
- default:
- throw new EvalException("Unexpected date/time type " + type);
- }
- }
-
- static Value toDateValue(EvalContext ctx, Value.Type type, double v,
- Value param1, Value param2)
- {
- DateFormat fmt = null;
- if((param1 instanceof BaseDateValue) && (param1.getType() == type)) {
- fmt = ((BaseDateValue)param1).getFormat();
- } else if((param2 instanceof BaseDateValue) && (param2.getType() == type)) {
- fmt = ((BaseDateValue)param2).getFormat();
- } else {
- fmt = getDateFormatForType(ctx, type);
- }
-
- Date d = new Date(ColumnImpl.fromDateDouble(v, fmt.getCalendar()));
-
- return toValue(type, d, fmt);
- }
-
- static DateFormat getDateFormatForType(EvalContext ctx, Value.Type type) {
- String fmtStr = null;
- switch(type) {
- case DATE:
- fmtStr = ctx.getTemporalConfig().getDefaultDateFormat();
- break;
- case TIME:
- fmtStr = ctx.getTemporalConfig().getDefaultTimeFormat();
- break;
- case DATE_TIME:
- fmtStr = ctx.getTemporalConfig().getDefaultDateTimeFormat();
- break;
- default:
- throw new EvalException("Unexpected date/time type " + type);
- }
- return ctx.createDateFormat(fmtStr);
- }
-
private static Value.Type getMathTypePrecedence(
Value param1, Value param2, CoercionType cType)
{
return ((d == id) && (d >= MIN_INT) && (d <= MAX_INT) &&
!Double.isInfinite(d) && !Double.isNaN(d));
}
-
- /**
- * Converts the given BigDecimal to the minimal scale >= 0;
- */
- static BigDecimal normalize(BigDecimal bd) {
- if(bd.scale() == 0) {
- return bd;
- }
- // handle a bug in the jdk which doesn't strip zero values
- if(bd.compareTo(BigDecimal.ZERO) == 0) {
- return BigDecimal.ZERO;
- }
- bd = bd.stripTrailingZeros();
- if(bd.scale() < 0) {
- bd = bd.setScale(0);
- }
- return bd;
- }
}
public static final Function DATE = registerFunc(new Func0("Date") {
@Override
protected Value eval0(EvalContext ctx) {
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.DATE);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.DATE);
double dd = dateOnly(currentTimeDouble(fmt));
- return BuiltinOperators.toValue(Value.Type.DATE, dd, fmt);
+ return ValueSupport.toValue(Value.Type.DATE, dd, fmt);
}
});
return dv;
}
double dd = dateOnly(dv.getAsDouble());
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.DATE);
- return BuiltinOperators.toValue(Value.Type.DATE, dd, fmt);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.DATE);
+ return ValueSupport.toValue(Value.Type.DATE, dd, fmt);
}
});
year += ((year <= 29) ? 2000 : 1900);
}
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.DATE);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.DATE);
Calendar cal = fmt.getCalendar();
cal.clear();
cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.DAY_OF_MONTH, day);
- return BuiltinOperators.toValue(Value.Type.DATE, cal.getTime(), fmt);
+ return ValueSupport.toValue(Value.Type.DATE, cal.getTime(), fmt);
}
});
public static final Function NOW = registerFunc(new Func0("Now") {
@Override
protected Value eval0(EvalContext ctx) {
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.DATE_TIME);
- return BuiltinOperators.toValue(Value.Type.DATE_TIME, new Date(), fmt);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.DATE_TIME);
+ return ValueSupport.toValue(Value.Type.DATE_TIME, new Date(), fmt);
}
});
public static final Function TIME = registerFunc(new Func0("Time") {
@Override
protected Value eval0(EvalContext ctx) {
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.TIME);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.TIME);
double dd = timeOnly(currentTimeDouble(fmt));
- return BuiltinOperators.toValue(Value.Type.TIME, dd, fmt);
+ return ValueSupport.toValue(Value.Type.TIME, dd, fmt);
}
});
return dv;
}
double dd = timeOnly(dv.getAsDouble());
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.TIME);
- return BuiltinOperators.toValue(Value.Type.TIME, dd, fmt);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.TIME);
+ return ValueSupport.toValue(Value.Type.TIME, dd, fmt);
}
});
public static final Function TIMER = registerFunc(new Func0("Timer") {
@Override
protected Value eval0(EvalContext ctx) {
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.TIME);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.TIME);
double dd = timeOnly(currentTimeDouble(fmt)) * DSECONDS_PER_DAY;
- return BuiltinOperators.toValue(dd);
+ return ValueSupport.toValue(dd);
}
});
totalSeconds %= SECONDS_PER_DAY;
}
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, Value.Type.TIME);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, Value.Type.TIME);
double dd = totalSeconds / DSECONDS_PER_DAY;
- return BuiltinOperators.toValue(Value.Type.TIME, dd, fmt);
+ return ValueSupport.toValue(Value.Type.TIME, dd, fmt);
}
});
public static final Function HOUR = registerFunc(new Func1NullIsNull("Hour") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
nonNullToCalendarField(ctx, param1, Calendar.HOUR_OF_DAY));
}
});
public static final Function MINUTE = registerFunc(new Func1NullIsNull("Minute") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
nonNullToCalendarField(ctx, param1, Calendar.MINUTE));
}
});
public static final Function SECOND = registerFunc(new Func1NullIsNull("Second") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
nonNullToCalendarField(ctx, param1, Calendar.SECOND));
}
});
public static final Function YEAR = registerFunc(new Func1NullIsNull("Year") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
nonNullToCalendarField(ctx, param1, Calendar.YEAR));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
// convert from 0 based to 1 based value
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
nonNullToCalendarField(ctx, param1, Calendar.MONTH) + 1);
}
});
public static final Function DAY = registerFunc(new Func1NullIsNull("Day") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
nonNullToCalendarField(ctx, param1, Calendar.DAY_OF_MONTH));
}
});
// back to 1 based to return the result
day = (((day - 1) - (firstDay - 1) + 7) % 7) + 1;
- return BuiltinOperators.toValue(day);
+ return ValueSupport.toValue(day);
}
});
Value.Type type = (hasDate ? (hasTime ? Value.Type.DATE_TIME : Value.Type.DATE) :
Value.Type.TIME);
- DateFormat fmt = BuiltinOperators.getDateFormatForType(ctx, type);
- return BuiltinOperators.toValue(type, dd, fmt);
+ DateFormat fmt = ValueSupport.getDateFormatForType(ctx, type);
+ return ValueSupport.toValue(type, dd, fmt);
}
private static DateFormat getDateValueFormat(EvalContext ctx, Value param) {
return ((param instanceof BaseDateValue) ?
((BaseDateValue)param).getFormat() :
- BuiltinOperators.getDateFormatForType(ctx, param.getType()));
+ ValueSupport.getDateFormatForType(ctx, param.getType()));
}
private static double dateOnly(double dd) {
result += calculateAnnuityPaymentPeriods(rate, pmt, fv, pmtType);
}
- return BuiltinOperators.toValue(result);
+ return ValueSupport.toValue(result);
}
});
double result = calculateFutureValue(rate, nper, pmt, pmtType);
- return BuiltinOperators.toValue(result);
+ return ValueSupport.toValue(result);
}
});
double result = calculatePresentValue(rate, nper, pmt, pmtType);
- return BuiltinOperators.toValue(result);
+ return ValueSupport.toValue(result);
}
});
result += calculateAnnuityPayment(rate, nper, fv, pmtType);
}
- return BuiltinOperators.toValue(result);
+ return ValueSupport.toValue(result);
}
});
// double result = calculateInterestPayment(pmt, rate, per, pv, pmtType);
- // return BuiltinOperators.toValue(result);
+ // return ValueSupport.toValue(result);
// }
// });
// double result = pmt - calculateInterestPayment(pmt, rate, per, pv,
// pmtType);
- // return BuiltinOperators.toValue(result);
+ // return ValueSupport.toValue(result);
// }
// });
// cost -= result;
// }
- // return BuiltinOperators.toValue(result);
+ // return ValueSupport.toValue(result);
// }
// });
// double result = calculateStraightLineDepreciation(cost, salvage, life);
- // return BuiltinOperators.toValue(result);
+ // return ValueSupport.toValue(result);
// }
// });
// double result = calculateSumOfYearsDepreciation(
// cost, salvage, life, period);
- // return BuiltinOperators.toValue(result);
+ // return ValueSupport.toValue(result);
// }
// });
protected Value eval1(EvalContext ctx, Value param1) {
if((param1.getType() == Value.Type.STRING) &&
(param1.getAsString().length() == 0)) {
- return BuiltinOperators.ZERO_VAL;
+ return ValueSupport.ZERO_VAL;
}
int lv = param1.getAsLongInt();
- return BuiltinOperators.toValue(Integer.toHexString(lv).toUpperCase());
+ return ValueSupport.toValue(Integer.toHexString(lv).toUpperCase());
}
});
Value.Type resultType = ctx.getResultType();
return (((resultType == null) ||
(resultType == Value.Type.STRING)) ?
- BuiltinOperators.EMPTY_STR_VAL : BuiltinOperators.ZERO_VAL);
+ ValueSupport.EMPTY_STR_VAL : ValueSupport.ZERO_VAL);
}
});
Value param1 = params[0];
int idx = param1.getAsLongInt();
if((idx < 1) || (idx >= params.length)) {
- return BuiltinOperators.NULL_VAL;
+ return ValueSupport.NULL_VAL;
}
return params[idx];
}
return params[i + 1];
}
}
- return BuiltinOperators.NULL_VAL;
+ return ValueSupport.NULL_VAL;
}
});
protected Value eval1(EvalContext ctx, Value param1) {
if((param1.getType() == Value.Type.STRING) &&
(param1.getAsString().length() == 0)) {
- return BuiltinOperators.ZERO_VAL;
+ return ValueSupport.ZERO_VAL;
}
int lv = param1.getAsLongInt();
- return BuiltinOperators.toValue(Integer.toOctalString(lv));
+ return ValueSupport.toValue(Integer.toOctalString(lv));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
boolean b = param1.getAsBoolean();
- return BuiltinOperators.toValue(b);
+ return ValueSupport.toValue(b);
}
});
if((lv < 0) || (lv > 255)) {
throw new EvalException("Byte code '" + lv + "' out of range ");
}
- return BuiltinOperators.toValue(lv);
+ return ValueSupport.toValue(lv);
}
});
protected Value eval1(EvalContext ctx, Value param1) {
BigDecimal bd = param1.getAsBigDecimal();
bd = bd.setScale(4, NumberFormatter.ROUND_MODE);
- return BuiltinOperators.toValue(bd);
+ return ValueSupport.toValue(bd);
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
Double dv = param1.getAsDouble();
- return BuiltinOperators.toValue(dv);
+ return ValueSupport.toValue(dv);
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
BigDecimal bd = param1.getAsBigDecimal();
- return BuiltinOperators.toValue(bd);
+ return ValueSupport.toValue(bd);
}
});
if((lv < Short.MIN_VALUE) || (lv > Short.MAX_VALUE)) {
throw new EvalException("Int value '" + lv + "' out of range ");
}
- return BuiltinOperators.toValue(lv);
+ return ValueSupport.toValue(lv);
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
int lv = param1.getAsLongInt();
- return BuiltinOperators.toValue(lv);
+ return ValueSupport.toValue(lv);
}
});
if((dv < Float.MIN_VALUE) || (dv > Float.MAX_VALUE)) {
throw new EvalException("Single value '" + dv + "' out of range ");
}
- return BuiltinOperators.toValue(dv.floatValue());
+ return ValueSupport.toValue(dv.floatValue());
}
});
public static final Function CSTR = registerFunc(new Func1("CStr") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(param1.getAsString());
+ return ValueSupport.toValue(param1.getAsString());
}
});
public static final Function ISNULL = registerFunc(new Func1("IsNull") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(param1.isNull());
+ return ValueSupport.toValue(param1.isNull());
}
});
public static final Function ISDATE = registerFunc(new Func1("IsDate") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
!param1.isNull() &&
(DefaultDateFunctions.nonNullToDateValue(ctx, param1) != null));
}
default:
throw new EvalException("Unknown type " + type);
}
- return BuiltinOperators.toValue(vType);
+ return ValueSupport.toValue(vType);
}
});
default:
throw new EvalException("Unknown type " + type);
}
- return BuiltinOperators.toValue(tName);
+ return ValueSupport.toValue(tName);
}
});
case DATE_TIME:
// dates/times get converted to date doubles for arithmetic
double result = Math.abs(param1.getAsDouble());
- return BuiltinOperators.toDateValue(ctx, mathType, result, param1, null);
+ return ValueSupport.toDateValue(ctx, mathType, result, param1, null);
case LONG:
- return BuiltinOperators.toValue(Math.abs(param1.getAsLongInt()));
+ return ValueSupport.toValue(Math.abs(param1.getAsLongInt()));
case DOUBLE:
- return BuiltinOperators.toValue(Math.abs(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.abs(param1.getAsDouble()));
case STRING:
case BIG_DEC:
- return BuiltinOperators.toValue(param1.getAsBigDecimal().abs(
+ return ValueSupport.toValue(param1.getAsBigDecimal().abs(
NumberFormatter.DEC_MATH_CONTEXT));
default:
throw new EvalException("Unexpected type " + mathType);
public static final Function ATAN = registerFunc(new Func1("Atan") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(Math.atan(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.atan(param1.getAsDouble()));
}
});
public static final Function COS = registerFunc(new Func1("Cos") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(Math.cos(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.cos(param1.getAsDouble()));
}
});
public static final Function EXP = registerFunc(new Func1("Exp") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(Math.exp(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.exp(param1.getAsDouble()));
}
});
if(param1.getType().isIntegral()) {
return param1;
}
- return BuiltinOperators.toValue(param1.getAsDouble().intValue());
+ return ValueSupport.toValue(param1.getAsDouble().intValue());
}
});
if(param1.getType().isIntegral()) {
return param1;
}
- return BuiltinOperators.toValue((int)Math.floor(param1.getAsDouble()));
+ return ValueSupport.toValue((int)Math.floor(param1.getAsDouble()));
}
});
public static final Function LOG = registerFunc(new Func1("Log") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(Math.log(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.log(param1.getAsDouble()));
}
});
@Override
protected Value evalVar(EvalContext ctx, Value[] params) {
Integer seed = ((params.length > 0) ? params[0].getAsLongInt() : null);
- return BuiltinOperators.toValue(ctx.getRandom(seed));
+ return ValueSupport.toValue(ctx.getRandom(seed));
}
});
}
BigDecimal bd = param1.getAsBigDecimal()
.setScale(scale, NumberFormatter.ROUND_MODE);
- return BuiltinOperators.toValue(bd);
+ return ValueSupport.toValue(bd);
}
});
} else {
val = param1.getAsBigDecimal().signum();
}
- return ((val > 0) ? BuiltinOperators.ONE_VAL :
- ((val < 0) ? BuiltinOperators.NEG_ONE_VAL :
- BuiltinOperators.ZERO_VAL));
+ return ((val > 0) ? ValueSupport.ONE_VAL :
+ ((val < 0) ? ValueSupport.NEG_ONE_VAL :
+ ValueSupport.ZERO_VAL));
}
});
if(dv < 0.0d) {
throw new EvalException("Invalid value '" + dv + "'");
}
- return BuiltinOperators.toValue(Math.sqrt(dv));
+ return ValueSupport.toValue(Math.sqrt(dv));
}
});
public static final Function SIN = registerFunc(new Func1("Sin") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(Math.sin(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.sin(param1.getAsDouble()));
}
});
public static final Function TAN = registerFunc(new Func1("Tan") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
- return BuiltinOperators.toValue(Math.tan(param1.getAsDouble()));
+ return ValueSupport.toValue(Math.tan(param1.getAsDouble()));
}
});
throw new EvalException("Character code '" + lv +
"' out of range ");
}
- return BuiltinOperators.toValue(lv);
+ return ValueSupport.toValue(lv);
}
});
throw new EvalException("No characters in string");
}
int lv = str.charAt(0);
- return BuiltinOperators.toValue(lv);
+ return ValueSupport.toValue(lv);
}
});
"' out of range ");
}
char[] cs = Character.toChars(lv);
- return BuiltinOperators.toValue(new String(cs));
+ return ValueSupport.toValue(new String(cs));
}
});
protected Value eval1(EvalContext ctx, Value param1) {
int lv = param1.getAsLongInt();
char[] cs = Character.toChars(lv);
- return BuiltinOperators.toValue(new String(cs));
+ return ValueSupport.toValue(new String(cs));
}
});
if(bd.compareTo(BigDecimal.ZERO) >= 0) {
str = " " + str;
}
- return BuiltinOperators.toValue(str);
+ return ValueSupport.toValue(str);
}
});
String s1 = param1.getAsString();
int s1Len = s1.length();
if(s1Len == 0) {
- return BuiltinOperators.ZERO_VAL;
+ return ValueSupport.ZERO_VAL;
}
Value param2 = params[idx++];
if(param2.isNull()) {
int s2Len = s2.length();
if(s2Len == 0) {
// 1 based offsets
- return BuiltinOperators.toValue(start + 1);
+ return ValueSupport.toValue(start + 1);
}
boolean ignoreCase = true;
if(params.length > 3) {
while(start < end) {
if(s1.regionMatches(ignoreCase, start, s2, 0, s2Len)) {
// 1 based offsets
- return BuiltinOperators.toValue(start + 1);
+ return ValueSupport.toValue(start + 1);
}
++start;
}
- return BuiltinOperators.ZERO_VAL;
+ return ValueSupport.ZERO_VAL;
}
});
String s1 = param1.getAsString();
int s1Len = s1.length();
if(s1Len == 0) {
- return BuiltinOperators.ZERO_VAL;
+ return ValueSupport.ZERO_VAL;
}
Value param2 = params[1];
if(param2.isNull()) {
int start = s1Len - 1;
if(s2Len == 0) {
// 1 based offsets
- return BuiltinOperators.toValue(start + 1);
+ return ValueSupport.toValue(start + 1);
}
if(params.length > 2) {
start = params[2].getAsLongInt();
while(start >= 0) {
if(s1.regionMatches(ignoreCase, start, s2, 0, s2Len)) {
// 1 based offsets
- return BuiltinOperators.toValue(start + 1);
+ return ValueSupport.toValue(start + 1);
}
--start;
}
- return BuiltinOperators.ZERO_VAL;
+ return ValueSupport.ZERO_VAL;
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(str.toLowerCase());
+ return ValueSupport.toValue(str.toLowerCase());
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(str.toUpperCase());
+ return ValueSupport.toValue(str.toUpperCase());
}
});
}
String str = param1.getAsString();
int len = Math.min(str.length(), param2.getAsLongInt());
- return BuiltinOperators.toValue(str.substring(0, len));
+ return ValueSupport.toValue(str.substring(0, len));
}
});
String str = param1.getAsString();
int strLen = str.length();
int len = Math.min(strLen, param2.getAsLongInt());
- return BuiltinOperators.toValue(str.substring(strLen - len, strLen));
+ return ValueSupport.toValue(str.substring(strLen - len, strLen));
}
});
int len = Math.min(
((params.length > 2) ? params[2].getAsLongInt() : strLen),
(strLen - start));
- return BuiltinOperators.toValue(str.substring(start, start + len));
+ return ValueSupport.toValue(str.substring(start, start + len));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(str.length());
+ return ValueSupport.toValue(str.length());
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(trim(str, true, false));
+ return ValueSupport.toValue(trim(str, true, false));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(trim(str, false, true));
+ return ValueSupport.toValue(trim(str, false, true));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(trim(str, true, true));
+ return ValueSupport.toValue(trim(str, true, true));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
int lv = param1.getAsLongInt();
- return BuiltinOperators.toValue(nchars(lv, ' '));
+ return ValueSupport.toValue(nchars(lv, ' '));
}
});
Value param1 = params[0];
Value param2 = params[1];
if(param1.isNull() || param2.isNull()) {
- return BuiltinOperators.NULL_VAL;
+ return ValueSupport.NULL_VAL;
}
String s1 = param1.getAsString();
String s2 = param2.getAsString();
int cmp = (ignoreCase ?
s1.compareToIgnoreCase(s2) : s1.compareTo(s2));
// stupid java doesn't return 1, -1, 0...
- return ((cmp < 0) ? BuiltinOperators.NEG_ONE_VAL :
- ((cmp > 0) ? BuiltinOperators.ONE_VAL :
- BuiltinOperators.ZERO_VAL));
+ return ((cmp < 0) ? ValueSupport.NEG_ONE_VAL :
+ ((cmp > 0) ? ValueSupport.ONE_VAL :
+ ValueSupport.ZERO_VAL));
}
});
@Override
protected Value eval2(EvalContext ctx, Value param1, Value param2) {
if(param1.isNull() || param2.isNull()) {
- return BuiltinOperators.NULL_VAL;
+ return ValueSupport.NULL_VAL;
}
int lv = param1.getAsLongInt();
char c = (char)(param2.getAsString().charAt(0) % 256);
- return BuiltinOperators.toValue(nchars(lv, c));
+ return ValueSupport.toValue(nchars(lv, c));
}
});
@Override
protected Value eval1(EvalContext ctx, Value param1) {
String str = param1.getAsString();
- return BuiltinOperators.toValue(
+ return ValueSupport.toValue(
new StringBuilder(str).reverse().toString());
}
});
private static final Expr THIS_COL_VALUE = new EThisValue();
private static final Expr NULL_VALUE = new EConstValue(
- BuiltinOperators.NULL_VAL, "Null");
+ ValueSupport.NULL_VAL, "Null");
private static final Expr TRUE_VALUE = new EConstValue(
- BuiltinOperators.TRUE_VAL, "True");
+ ValueSupport.TRUE_VAL, "True");
private static final Expr FALSE_VALUE = new EConstValue(
- BuiltinOperators.FALSE_VAL, "False");
+ ValueSupport.FALSE_VAL, "False");
private Expressionator() {}
{
switch(valType) {
case STRING:
- return BuiltinOperators.toValue((String)value);
+ return ValueSupport.toValue((String)value);
case DATE:
return new DateValue((Date)value, sdf);
case TIME:
case DATE_TIME:
return new DateTimeValue((Date)value, sdf);
case LONG:
- return BuiltinOperators.toValue((Integer)value);
+ return ValueSupport.toValue((Integer)value);
case DOUBLE:
- return BuiltinOperators.toValue((Double)value);
+ return ValueSupport.toValue((Double)value);
case BIG_DEC:
- return BuiltinOperators.toValue((BigDecimal)value);
+ return ValueSupport.toValue((BigDecimal)value);
default:
throw new ParseException("unexpected literal type " + valType);
}
if(_num == null) {
// see if it is parseable as a number
try {
- _num = BuiltinOperators.normalize(new BigDecimal(_val));
+ _num = ValueSupport.normalize(new BigDecimal(_val));
return (BigDecimal)_num;
} catch(NumberFormatException nfe) {
_num = NOT_A_NUMBER;
--- /dev/null
+/*
+Copyright (c) 2018 James Ahlborn
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package com.healthmarketscience.jackcess.impl.expr;
+
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.util.Date;
+
+import com.healthmarketscience.jackcess.expr.EvalContext;
+import com.healthmarketscience.jackcess.expr.EvalException;
+import com.healthmarketscience.jackcess.expr.Value;
+import com.healthmarketscience.jackcess.impl.ColumnImpl;
+
+/**
+ *
+ * @author James Ahlborn
+ */
+public class ValueSupport
+{
+ public static final Value NULL_VAL = new BaseValue() {
+ @Override public boolean isNull() {
+ return true;
+ }
+ public Type getType() {
+ return Type.NULL;
+ }
+ public Object get() {
+ return null;
+ }
+ };
+ // access seems to like -1 for true and 0 for false (boolean values are
+ // basically an illusion)
+ public static final Value TRUE_VAL = new LongValue(-1);
+ public static final Value FALSE_VAL = new LongValue(0);
+ public static final Value EMPTY_STR_VAL = new StringValue("");
+ public static final Value ZERO_VAL = FALSE_VAL;
+ public static final Value NEG_ONE_VAL = TRUE_VAL;
+ public static final Value ONE_VAL = new LongValue(1);
+
+ private ValueSupport() {}
+
+ public static Value toValue(boolean b) {
+ return (b ? TRUE_VAL : FALSE_VAL);
+ }
+
+ public static Value toValue(String s) {
+ return new StringValue(s);
+ }
+
+ public static Value toValue(int i) {
+ return new LongValue(i);
+ }
+
+ public static Value toValue(Integer i) {
+ return new LongValue(i);
+ }
+
+ public static Value toValue(float f) {
+ return new DoubleValue((double)f);
+ }
+
+ public static Value toValue(double s) {
+ return new DoubleValue(s);
+ }
+
+ public static Value toValue(Double s) {
+ return new DoubleValue(s);
+ }
+
+ public static Value toValue(BigDecimal s) {
+ return new BigDecimalValue(normalize(s));
+ }
+
+ public static Value toValue(Value.Type type, double dd, DateFormat fmt) {
+ return toValue(type, new Date(ColumnImpl.fromDateDouble(
+ dd, fmt.getCalendar())), fmt);
+ }
+
+ public static Value toValue(EvalContext ctx, Value.Type type, Date d) {
+ return toValue(type, d, getDateFormatForType(ctx, type));
+ }
+
+ public static Value toValue(Value.Type type, Date d, DateFormat fmt) {
+ switch(type) {
+ case DATE:
+ return new DateValue(d, fmt);
+ case TIME:
+ return new TimeValue(d, fmt);
+ case DATE_TIME:
+ return new DateTimeValue(d, fmt);
+ default:
+ throw new EvalException("Unexpected date/time type " + type);
+ }
+ }
+
+ static Value toDateValue(EvalContext ctx, Value.Type type, double v,
+ Value param1, Value param2)
+ {
+ DateFormat fmt = null;
+ if((param1 instanceof BaseDateValue) && (param1.getType() == type)) {
+ fmt = ((BaseDateValue)param1).getFormat();
+ } else if((param2 instanceof BaseDateValue) && (param2.getType() == type)) {
+ fmt = ((BaseDateValue)param2).getFormat();
+ } else {
+ fmt = getDateFormatForType(ctx, type);
+ }
+
+ Date d = new Date(ColumnImpl.fromDateDouble(v, fmt.getCalendar()));
+
+ return toValue(type, d, fmt);
+ }
+
+ static DateFormat getDateFormatForType(EvalContext ctx, Value.Type type) {
+ String fmtStr = null;
+ switch(type) {
+ case DATE:
+ fmtStr = ctx.getTemporalConfig().getDefaultDateFormat();
+ break;
+ case TIME:
+ fmtStr = ctx.getTemporalConfig().getDefaultTimeFormat();
+ break;
+ case DATE_TIME:
+ fmtStr = ctx.getTemporalConfig().getDefaultDateTimeFormat();
+ break;
+ default:
+ throw new EvalException("Unexpected date/time type " + type);
+ }
+ return ctx.createDateFormat(fmtStr);
+ }
+
+ /**
+ * Converts the given BigDecimal to the minimal scale >= 0;
+ */
+ static BigDecimal normalize(BigDecimal bd) {
+ if(bd.scale() == 0) {
+ return bd;
+ }
+ // handle a bug in the jdk which doesn't strip zero values
+ if(bd.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO;
+ }
+ bd = bd.stripTrailingZeros();
+ if(bd.scale() < 0) {
+ bd = bd.setScale(0);
+ }
+ return bd;
+ }
+}
import com.healthmarketscience.jackcess.expr.FunctionLookup;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
-import com.healthmarketscience.jackcess.impl.expr.BuiltinOperators;
import com.healthmarketscience.jackcess.impl.expr.DefaultFunctions;
import com.healthmarketscience.jackcess.impl.expr.FunctionSupport;
+import com.healthmarketscience.jackcess.impl.expr.ValueSupport;
import junit.framework.TestCase;
import static com.healthmarketscience.jackcess.Database.*;
@Override
protected Value eval0(EvalContext ctx) {
Object val = ctx.get("someKey");
- return BuiltinOperators.toValue("FOO_" + val);
+ return ValueSupport.toValue("FOO_" + val);
}
};
}
TestContext tc = new TestContext() {
@Override
public Value getThisColumnValue() {
- return BuiltinOperators.toValue(23.0);
+ return ValueSupport.toValue(23.0);
}
@Override
public Value getIdentifierValue(Identifier identifier) {
- return BuiltinOperators.toValue(23.0);
+ return ValueSupport.toValue(23.0);
}
};
}
private static Boolean evalCondition(String exprStr, String thisVal) {
- TestContext tc = new TestContext(BuiltinOperators.toValue(thisVal));
+ TestContext tc = new TestContext(ValueSupport.toValue(thisVal));
Expression expr = Expressionator.parse(
Expressionator.Type.FIELD_VALIDATOR, exprStr, null, tc);
return (Boolean)expr.eval(tc);
}
static BigDecimal toBD(BigDecimal bd) {
- return BuiltinOperators.normalize(bd);
+ return ValueSupport.normalize(bd);
}
private static class TestContext