use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class Function method calculatePrecisionAndDisplaySize.
private void calculatePrecisionAndDisplaySize() {
switch(info.type) {
case ENCRYPT:
case DECRYPT:
precision = args[2].getPrecision();
displaySize = args[2].getDisplaySize();
break;
case COMPRESS:
precision = args[0].getPrecision();
displaySize = args[0].getDisplaySize();
break;
case CHAR:
precision = 1;
displaySize = 1;
break;
case CONCAT:
precision = 0;
displaySize = 0;
for (Expression e : args) {
precision += e.getPrecision();
displaySize = MathUtils.convertLongToInt((long) displaySize + e.getDisplaySize());
if (precision < 0) {
precision = Long.MAX_VALUE;
}
}
break;
case HEXTORAW:
precision = (args[0].getPrecision() + 3) / 4;
displaySize = MathUtils.convertLongToInt(precision);
break;
case LCASE:
case LTRIM:
case RIGHT:
case RTRIM:
case UCASE:
case LOWER:
case UPPER:
case TRIM:
case STRINGDECODE:
case UTF8TOSTRING:
case TRUNCATE:
precision = args[0].getPrecision();
displaySize = args[0].getDisplaySize();
break;
case RAWTOHEX:
precision = args[0].getPrecision() * 4;
displaySize = MathUtils.convertLongToInt(precision);
break;
case SOUNDEX:
precision = 4;
displaySize = (int) precision;
break;
case DAY_NAME:
case MONTH_NAME:
// day and month names may be long in some languages
precision = 20;
displaySize = (int) precision;
break;
default:
DataType type = DataType.getDataType(dataType);
precision = type.defaultPrecision;
displaySize = type.defaultDisplaySize;
}
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class Function method getSQL.
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder(info.name);
if (info.type == CASE) {
if (args[0] != null) {
buff.append(" ").append(args[0].getSQL());
}
for (int i = 1, len = args.length - 1; i < len; i += 2) {
buff.append(" WHEN ").append(args[i].getSQL());
buff.append(" THEN ").append(args[i + 1].getSQL());
}
if (args.length % 2 == 0) {
buff.append(" ELSE ").append(args[args.length - 1].getSQL());
}
return buff.append(" END").toString();
}
buff.append('(');
switch(info.type) {
case CAST:
{
buff.append(args[0].getSQL()).append(" AS ").append(new Column(null, dataType, precision, scale, displaySize).getCreateSQL());
break;
}
case CONVERT:
{
if (database.getMode().swapConvertFunctionParameters) {
buff.append(new Column(null, dataType, precision, scale, displaySize).getCreateSQL()).append(',').append(args[0].getSQL());
} else {
buff.append(args[0].getSQL()).append(',').append(new Column(null, dataType, precision, scale, displaySize).getCreateSQL());
}
break;
}
case EXTRACT:
{
ValueString v = (ValueString) ((ValueExpression) args[0]).getValue(null);
buff.append(v.getString()).append(" FROM ").append(args[1].getSQL());
break;
}
default:
{
for (Expression e : args) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
}
}
return buff.append(')').toString();
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class Function method getSimpleValue.
private Value getSimpleValue(Session session, Value v0, Expression[] args, Value[] values) {
Value result;
switch(info.type) {
case ABS:
result = v0.getSignum() >= 0 ? v0 : v0.negate();
break;
case ACOS:
result = ValueDouble.get(Math.acos(v0.getDouble()));
break;
case ASIN:
result = ValueDouble.get(Math.asin(v0.getDouble()));
break;
case ATAN:
result = ValueDouble.get(Math.atan(v0.getDouble()));
break;
case CEILING:
result = ValueDouble.get(Math.ceil(v0.getDouble()));
break;
case COS:
result = ValueDouble.get(Math.cos(v0.getDouble()));
break;
case COSH:
result = ValueDouble.get(Math.cosh(v0.getDouble()));
break;
case COT:
{
double d = Math.tan(v0.getDouble());
if (d == 0.0) {
throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL());
}
result = ValueDouble.get(1. / d);
break;
}
case DEGREES:
result = ValueDouble.get(Math.toDegrees(v0.getDouble()));
break;
case EXP:
result = ValueDouble.get(Math.exp(v0.getDouble()));
break;
case FLOOR:
result = ValueDouble.get(Math.floor(v0.getDouble()));
break;
case LN:
result = ValueDouble.get(Math.log(v0.getDouble()));
break;
case LOG:
if (database.getMode().logIsLogBase10) {
result = ValueDouble.get(Math.log10(v0.getDouble()));
} else {
result = ValueDouble.get(Math.log(v0.getDouble()));
}
break;
case LOG10:
result = ValueDouble.get(Math.log10(v0.getDouble()));
break;
case PI:
result = ValueDouble.get(Math.PI);
break;
case RADIANS:
result = ValueDouble.get(Math.toRadians(v0.getDouble()));
break;
case RAND:
{
if (v0 != null) {
session.getRandom().setSeed(v0.getInt());
}
result = ValueDouble.get(session.getRandom().nextDouble());
break;
}
case ROUNDMAGIC:
result = ValueDouble.get(roundMagic(v0.getDouble()));
break;
case SIGN:
result = ValueInt.get(v0.getSignum());
break;
case SIN:
result = ValueDouble.get(Math.sin(v0.getDouble()));
break;
case SINH:
result = ValueDouble.get(Math.sinh(v0.getDouble()));
break;
case SQRT:
result = ValueDouble.get(Math.sqrt(v0.getDouble()));
break;
case TAN:
result = ValueDouble.get(Math.tan(v0.getDouble()));
break;
case TANH:
result = ValueDouble.get(Math.tanh(v0.getDouble()));
break;
case SECURE_RAND:
result = ValueBytes.getNoCopy(MathUtils.secureRandomBytes(v0.getInt()));
break;
case EXPAND:
result = ValueBytes.getNoCopy(CompressTool.getInstance().expand(v0.getBytesNoCopy()));
break;
case ZERO:
result = ValueInt.get(0);
break;
case RANDOM_UUID:
result = ValueUuid.getNewRandom();
break;
// string
case ASCII:
{
String s = v0.getString();
if (s.length() == 0) {
result = ValueNull.INSTANCE;
} else {
result = ValueInt.get(s.charAt(0));
}
break;
}
case BIT_LENGTH:
result = ValueLong.get(16 * length(v0));
break;
case CHAR:
result = ValueString.get(String.valueOf((char) v0.getInt()), database.getMode().treatEmptyStringsAsNull);
break;
case CHAR_LENGTH:
case LENGTH:
result = ValueLong.get(length(v0));
break;
case OCTET_LENGTH:
result = ValueLong.get(2 * length(v0));
break;
case CONCAT_WS:
case CONCAT:
{
result = ValueNull.INSTANCE;
int start = 0;
String separator = "";
if (info.type == CONCAT_WS) {
start = 1;
separator = getNullOrValue(session, args, values, 0).getString();
}
for (int i = start; i < args.length; i++) {
Value v = getNullOrValue(session, args, values, i);
if (v == ValueNull.INSTANCE) {
continue;
}
if (result == ValueNull.INSTANCE) {
result = v;
} else {
String tmp = v.getString();
if (!StringUtils.isNullOrEmpty(separator) && !StringUtils.isNullOrEmpty(tmp)) {
tmp = separator + tmp;
}
result = ValueString.get(result.getString() + tmp, database.getMode().treatEmptyStringsAsNull);
}
}
if (info.type == CONCAT_WS) {
if (separator != null && result == ValueNull.INSTANCE) {
result = ValueString.get("", database.getMode().treatEmptyStringsAsNull);
}
}
break;
}
case HEXTORAW:
result = ValueString.get(hexToRaw(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case LOWER:
case LCASE:
// TODO this is locale specific, need to document or provide a way
// to set the locale
result = ValueString.get(v0.getString().toLowerCase(), database.getMode().treatEmptyStringsAsNull);
break;
case RAWTOHEX:
result = ValueString.get(rawToHex(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case SOUNDEX:
result = ValueString.get(getSoundex(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case SPACE:
{
int len = Math.max(0, v0.getInt());
char[] chars = new char[len];
for (int i = len - 1; i >= 0; i--) {
chars[i] = ' ';
}
result = ValueString.get(new String(chars), database.getMode().treatEmptyStringsAsNull);
break;
}
case UPPER:
case UCASE:
// TODO this is locale specific, need to document or provide a way
// to set the locale
result = ValueString.get(v0.getString().toUpperCase(), database.getMode().treatEmptyStringsAsNull);
break;
case STRINGENCODE:
result = ValueString.get(StringUtils.javaEncode(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case STRINGDECODE:
result = ValueString.get(StringUtils.javaDecode(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case STRINGTOUTF8:
result = ValueBytes.getNoCopy(v0.getString().getBytes(StandardCharsets.UTF_8));
break;
case UTF8TOSTRING:
result = ValueString.get(new String(v0.getBytesNoCopy(), StandardCharsets.UTF_8), database.getMode().treatEmptyStringsAsNull);
break;
case XMLCOMMENT:
result = ValueString.get(StringUtils.xmlComment(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case XMLCDATA:
result = ValueString.get(StringUtils.xmlCData(v0.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case XMLSTARTDOC:
result = ValueString.get(StringUtils.xmlStartDoc(), database.getMode().treatEmptyStringsAsNull);
break;
case DAY_NAME:
{
int dayOfWeek = DateTimeUtils.getSundayDayOfWeek(DateTimeUtils.dateAndTimeFromValue(v0)[0]);
result = ValueString.get(DateTimeFunctions.getMonthsAndWeeks(1)[dayOfWeek], database.getMode().treatEmptyStringsAsNull);
break;
}
case DAY_OF_MONTH:
case DAY_OF_WEEK:
case DAY_OF_YEAR:
case HOUR:
case MINUTE:
case MONTH:
case QUARTER:
case ISO_YEAR:
case ISO_WEEK:
case ISO_DAY_OF_WEEK:
case SECOND:
case WEEK:
case YEAR:
result = ValueInt.get(DateTimeFunctions.getIntDatePart(v0, info.type));
break;
case MONTH_NAME:
{
int month = DateTimeUtils.monthFromDateValue(DateTimeUtils.dateAndTimeFromValue(v0)[0]);
result = ValueString.get(DateTimeFunctions.getMonthsAndWeeks(0)[month - 1], database.getMode().treatEmptyStringsAsNull);
break;
}
case CURDATE:
case CURRENT_DATE:
{
long now = session.getTransactionStart();
// need to normalize
result = ValueDate.fromMillis(now);
break;
}
case CURTIME:
case CURRENT_TIME:
{
long now = session.getTransactionStart();
// need to normalize
result = ValueTime.fromMillis(now);
break;
}
case NOW:
case CURRENT_TIMESTAMP:
{
long now = session.getTransactionStart();
ValueTimestamp vt = ValueTimestamp.fromMillis(now);
if (v0 != null) {
Mode mode = database.getMode();
vt = (ValueTimestamp) vt.convertScale(mode.convertOnlyToSmallerScale, v0.getInt());
}
result = vt;
break;
}
case DATABASE:
result = ValueString.get(database.getShortName(), database.getMode().treatEmptyStringsAsNull);
break;
case USER:
case CURRENT_USER:
result = ValueString.get(session.getUser().getName(), database.getMode().treatEmptyStringsAsNull);
break;
case IDENTITY:
result = session.getLastIdentity();
break;
case SCOPE_IDENTITY:
result = session.getLastScopeIdentity();
break;
case AUTOCOMMIT:
result = ValueBoolean.get(session.getAutoCommit());
break;
case READONLY:
result = ValueBoolean.get(database.isReadOnly());
break;
case DATABASE_PATH:
{
String path = database.getDatabasePath();
result = path == null ? (Value) ValueNull.INSTANCE : ValueString.get(path, database.getMode().treatEmptyStringsAsNull);
break;
}
case LOCK_TIMEOUT:
result = ValueInt.get(session.getLockTimeout());
break;
case DISK_SPACE_USED:
result = ValueLong.get(getDiskSpaceUsed(session, v0));
break;
case CAST:
case CONVERT:
{
v0 = v0.convertTo(dataType);
Mode mode = database.getMode();
v0 = v0.convertScale(mode.convertOnlyToSmallerScale, scale);
v0 = v0.convertPrecision(getPrecision(), false);
result = v0;
break;
}
case MEMORY_FREE:
session.getUser().checkAdmin();
result = ValueInt.get(Utils.getMemoryFree());
break;
case MEMORY_USED:
session.getUser().checkAdmin();
result = ValueInt.get(Utils.getMemoryUsed());
break;
case LOCK_MODE:
result = ValueInt.get(database.getLockMode());
break;
case SCHEMA:
result = ValueString.get(session.getCurrentSchemaName(), database.getMode().treatEmptyStringsAsNull);
break;
case SESSION_ID:
result = ValueInt.get(session.getId());
break;
case IFNULL:
{
result = v0;
if (v0 == ValueNull.INSTANCE) {
result = getNullOrValue(session, args, values, 1);
}
result = convertResult(result);
break;
}
case CASEWHEN:
{
Value v;
if (!v0.getBoolean()) {
v = getNullOrValue(session, args, values, 2);
} else {
v = getNullOrValue(session, args, values, 1);
}
result = v.convertTo(dataType);
break;
}
case DECODE:
{
int index = -1;
for (int i = 1, len = args.length - 1; i < len; i += 2) {
if (database.areEqual(v0, getNullOrValue(session, args, values, i))) {
index = i + 1;
break;
}
}
if (index < 0 && args.length % 2 == 0) {
index = args.length - 1;
}
Value v = index < 0 ? ValueNull.INSTANCE : getNullOrValue(session, args, values, index);
result = v.convertTo(dataType);
break;
}
case NVL2:
{
Value v;
if (v0 == ValueNull.INSTANCE) {
v = getNullOrValue(session, args, values, 2);
} else {
v = getNullOrValue(session, args, values, 1);
}
result = v.convertTo(dataType);
break;
}
case COALESCE:
{
result = v0;
for (int i = 0; i < args.length; i++) {
Value v = getNullOrValue(session, args, values, i);
if (v != ValueNull.INSTANCE) {
result = v.convertTo(dataType);
break;
}
}
break;
}
case GREATEST:
case LEAST:
{
result = ValueNull.INSTANCE;
for (int i = 0; i < args.length; i++) {
Value v = getNullOrValue(session, args, values, i);
if (v != ValueNull.INSTANCE) {
v = v.convertTo(dataType);
if (result == ValueNull.INSTANCE) {
result = v;
} else {
int comp = database.compareTypeSafe(result, v);
if (info.type == GREATEST && comp < 0) {
result = v;
} else if (info.type == LEAST && comp > 0) {
result = v;
}
}
}
}
break;
}
case CASE:
{
Expression then = null;
if (v0 == null) {
// (null, when, then, when, then, else)
for (int i = 1, len = args.length - 1; i < len; i += 2) {
Value when = args[i].getValue(session);
if (when.getBoolean()) {
then = args[i + 1];
break;
}
}
} else {
// (expr, when, then, when, then, else)
if (v0 != ValueNull.INSTANCE) {
for (int i = 1, len = args.length - 1; i < len; i += 2) {
Value when = args[i].getValue(session);
if (database.areEqual(v0, when)) {
then = args[i + 1];
break;
}
}
}
}
if (then == null && args.length % 2 == 0) {
// then = elsePart
then = args[args.length - 1];
}
Value v = then == null ? ValueNull.INSTANCE : then.getValue(session);
result = v.convertTo(dataType);
break;
}
case ARRAY_GET:
{
if (v0.getType() == Value.ARRAY) {
Value v1 = getNullOrValue(session, args, values, 1);
int element = v1.getInt();
Value[] list = ((ValueArray) v0).getList();
if (element < 1 || element > list.length) {
result = ValueNull.INSTANCE;
} else {
result = list[element - 1];
}
} else {
result = ValueNull.INSTANCE;
}
break;
}
case ARRAY_LENGTH:
{
if (v0.getType() == Value.ARRAY) {
Value[] list = ((ValueArray) v0).getList();
result = ValueInt.get(list.length);
} else {
result = ValueNull.INSTANCE;
}
break;
}
case ARRAY_CONTAINS:
{
result = ValueBoolean.FALSE;
if (v0.getType() == Value.ARRAY) {
Value v1 = getNullOrValue(session, args, values, 1);
Value[] list = ((ValueArray) v0).getList();
for (Value v : list) {
if (v.equals(v1)) {
result = ValueBoolean.TRUE;
break;
}
}
}
break;
}
case CANCEL_SESSION:
{
result = ValueBoolean.get(cancelStatement(session, v0.getInt()));
break;
}
case TRANSACTION_ID:
{
result = session.getTransactionId();
break;
}
default:
result = null;
}
return result;
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class AggregateDataMedian method getValue.
@Override
Value getValue(Database database, int dataType, boolean distinct) {
Value[] a = getArray();
if (a == null) {
return ValueNull.INSTANCE;
}
final CompareMode mode = database.getCompareMode();
Arrays.sort(a, new Comparator<Value>() {
@Override
public int compare(Value o1, Value o2) {
return o1.compareTo(o2, mode);
}
});
int len = a.length;
int idx = len / 2;
Value v1 = a[idx];
if ((len & 1) == 1) {
return v1.convertTo(dataType);
}
return getMedian(a[idx - 1], v1, dataType, mode);
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class AggregateDataMedian method getResultFromIndex.
/**
* Get the result from the index.
*
* @param session the session
* @param on the expression
* @param dataType the data type
* @return the result
*/
static Value getResultFromIndex(Session session, Expression on, int dataType) {
Index index = getMedianColumnIndex(on);
long count = index.getRowCount(session);
if (count == 0) {
return ValueNull.INSTANCE;
}
Cursor cursor = index.find(session, null, null);
cursor.next();
int columnId = index.getColumns()[0].getColumnId();
ExpressionColumn expr = (ExpressionColumn) on;
if (expr.getColumn().isNullable()) {
boolean hasNulls = false;
SearchRow row;
// will be used to read values.
while (count > 0) {
row = cursor.getSearchRow();
if (row == null) {
return ValueNull.INSTANCE;
}
if (row.getValue(columnId) == ValueNull.INSTANCE) {
count--;
cursor.next();
hasNulls = true;
} else {
break;
}
}
if (count == 0) {
return ValueNull.INSTANCE;
}
// cursor to count nulls at the end.
if (!hasNulls && isNullsLast(index)) {
TableFilter tableFilter = expr.getTableFilter();
SearchRow check = tableFilter.getTable().getTemplateSimpleRow(true);
check.setValue(columnId, ValueNull.INSTANCE);
Cursor nullsCursor = index.find(session, check, check);
while (nullsCursor.next()) {
count--;
}
if (count <= 0) {
return ValueNull.INSTANCE;
}
}
}
long skip = (count - 1) / 2;
for (int i = 0; i < skip; i++) {
cursor.next();
}
SearchRow row = cursor.getSearchRow();
if (row == null) {
return ValueNull.INSTANCE;
}
Value v = row.getValue(columnId);
if (v == ValueNull.INSTANCE) {
return v;
}
if ((count & 1) == 0) {
cursor.next();
row = cursor.getSearchRow();
if (row == null) {
return v;
}
Value v2 = row.getValue(columnId);
if (v2 == ValueNull.INSTANCE) {
return v;
}
return getMedian(v, v2, dataType, session.getDatabase().getCompareMode());
}
return v;
}
Aggregations