use of org.h2.value.ValueArray in project h2database by h2database.
the class ConditionInParameter method getValue.
@Override
public Value getValue(Session session) {
Value l = left.getValue(session);
if (l == ValueNull.INSTANCE) {
return l;
}
boolean result = false;
boolean hasNull = false;
Value value = parameter.getValue(session);
if (value instanceof ValueArray) {
for (Value r : ((ValueArray) value).getList()) {
if (r == ValueNull.INSTANCE) {
hasNull = true;
} else {
r = r.convertTo(l.getType());
result = Comparison.compareNotNull(database, l, r, Comparison.EQUAL);
if (result) {
break;
}
}
}
} else {
if (value == ValueNull.INSTANCE) {
hasNull = true;
} else {
value = value.convertTo(l.getType());
result = Comparison.compareNotNull(database, l, value, Comparison.EQUAL);
}
}
if (!result && hasNull) {
return ValueNull.INSTANCE;
}
return ValueBoolean.get(result);
}
use of org.h2.value.ValueArray in project h2database by h2database.
the class Expression method getExpressionColumns.
/**
* Extracts expression columns from ValueArray
*
* @param session the current session
* @param value the value to extract columns from
* @return array of expression columns
*/
static Expression[] getExpressionColumns(Session session, ValueArray value) {
Value[] list = value.getList();
ExpressionColumn[] expr = new ExpressionColumn[list.length];
for (int i = 0, len = list.length; i < len; i++) {
Value v = list[i];
Column col = new Column("C" + (i + 1), v.getType(), v.getPrecision(), v.getScale(), v.getDisplaySize());
expr[i] = new ExpressionColumn(session.getDatabase(), col);
}
return expr;
}
use of org.h2.value.ValueArray 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.value.ValueArray in project h2database by h2database.
the class TableFunction method getTable.
private ValueResultSet getTable(Session session, Expression[] argList, boolean onlyColumnList, boolean distinctRows) {
int len = columnList.length;
Expression[] header = new Expression[len];
Database db = session.getDatabase();
for (int i = 0; i < len; i++) {
Column c = columnList[i];
ExpressionColumn col = new ExpressionColumn(db, c);
header[i] = col;
}
LocalResult result = new LocalResult(session, header, len);
if (distinctRows) {
result.setDistinct();
}
if (!onlyColumnList) {
Value[][] list = new Value[len][];
int rows = 0;
for (int i = 0; i < len; i++) {
Value v = argList[i].getValue(session);
if (v == ValueNull.INSTANCE) {
list[i] = new Value[0];
} else {
ValueArray array = (ValueArray) v.convertTo(Value.ARRAY);
Value[] l = array.getList();
list[i] = l;
rows = Math.max(rows, l.length);
}
}
for (int row = 0; row < rows; row++) {
Value[] r = new Value[len];
for (int j = 0; j < len; j++) {
Value[] l = list[j];
Value v;
if (l.length <= row) {
v = ValueNull.INSTANCE;
} else {
Column c = columnList[j];
v = l[row];
v = c.convert(v);
v = v.convertPrecision(c.getPrecision(), false);
v = v.convertScale(true, c.getScale());
}
r[j] = v;
}
result.addRow(r);
}
}
result.done();
return ValueResultSet.get(getSimpleResultSet(result, Integer.MAX_VALUE));
}
use of org.h2.value.ValueArray in project h2database by h2database.
the class Session method rollbackTo.
/**
* Partially roll back the current transaction.
*
* @param savepoint the savepoint to which should be rolled back
* @param trimToSize if the list should be trimmed
*/
public void rollbackTo(Savepoint savepoint, boolean trimToSize) {
int index = savepoint == null ? 0 : savepoint.logIndex;
while (undoLog.size() > index) {
UndoLogRecord entry = undoLog.getLast();
entry.undo(this);
undoLog.removeLast(trimToSize);
}
if (transaction != null) {
long savepointId = savepoint == null ? 0 : savepoint.transactionSavepoint;
HashMap<String, MVTable> tableMap = database.getMvStore().getTables();
Iterator<Change> it = transaction.getChanges(savepointId);
while (it.hasNext()) {
Change c = it.next();
MVTable t = tableMap.get(c.mapName);
if (t != null) {
long key = ((ValueLong) c.key).getLong();
ValueArray value = (ValueArray) c.value;
short op;
Row row;
if (value == null) {
op = UndoLogRecord.INSERT;
row = t.getRow(this, key);
} else {
op = UndoLogRecord.DELETE;
row = createRow(value.getList(), Row.MEMORY_CALCULATE);
}
row.setKey(key);
UndoLogRecord log = new UndoLogRecord(t, op, row);
log.undo(this);
}
}
}
if (savepoints != null) {
String[] names = savepoints.keySet().toArray(new String[savepoints.size()]);
for (String name : names) {
Savepoint sp = savepoints.get(name);
int savepointIndex = sp.logIndex;
if (savepointIndex > index) {
savepoints.remove(name);
}
}
}
}
Aggregations