use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class Column method validateConvertUpdateSequence.
/**
* Validate the value, convert it if required, and update the sequence value
* if required. If the value is null, the default value (NULL if no default
* is set) is returned. Check constraints are validated as well.
*
* @param session the session
* @param value the value or null
* @return the new or converted value
*/
public Value validateConvertUpdateSequence(Session session, Value value) {
// take a local copy of defaultExpression to avoid holding the lock
// while calling getValue
final Expression localDefaultExpression;
synchronized (this) {
localDefaultExpression = defaultExpression;
}
Mode mode = session.getDatabase().getMode();
if (value == null) {
if (localDefaultExpression == null) {
value = ValueNull.INSTANCE;
} else {
value = convert(localDefaultExpression.getValue(session), mode);
if (!localDefaultExpression.isConstant()) {
session.getGeneratedKeys().add(this);
}
if (primaryKey) {
session.setLastIdentity(value);
}
}
}
if (value == ValueNull.INSTANCE) {
if (convertNullToDefault) {
value = convert(localDefaultExpression.getValue(session), mode);
if (!localDefaultExpression.isConstant()) {
session.getGeneratedKeys().add(this);
}
}
if (value == ValueNull.INSTANCE && !nullable) {
if (mode.convertInsertNullToZero) {
DataType dt = DataType.getDataType(type);
if (dt.decimal) {
value = ValueInt.get(0).convertTo(type);
} else if (dt.type == Value.TIMESTAMP) {
value = ValueTimestamp.fromMillis(session.getTransactionStart());
} else if (dt.type == Value.TIMESTAMP_TZ) {
long ms = session.getTransactionStart();
value = ValueTimestampTimeZone.fromDateValueAndNanos(DateTimeUtils.dateValueFromDate(ms), DateTimeUtils.nanosFromDate(ms), (short) 0);
} else if (dt.type == Value.TIME) {
value = ValueTime.fromNanos(0);
} else if (dt.type == Value.DATE) {
value = ValueDate.fromMillis(session.getTransactionStart());
} else {
value = ValueString.get("").convertTo(type);
}
} else {
throw DbException.get(ErrorCode.NULL_NOT_ALLOWED, name);
}
}
}
if (checkConstraint != null) {
resolver.setValue(value);
Value v;
synchronized (this) {
v = checkConstraint.getValue(session);
}
// Both TRUE and NULL are ok
if (v != ValueNull.INSTANCE && !v.getBoolean()) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, checkConstraint.getSQL());
}
}
value = value.convertScale(mode.convertOnlyToSmallerScale, scale);
if (precision > 0) {
if (!value.checkPrecision(precision)) {
String s = value.getTraceSQL();
if (s.length() > 127) {
s = s.substring(0, 128) + "...";
}
throw DbException.get(ErrorCode.VALUE_TOO_LONG_2, getCreateSQL(), s + " (" + value.getPrecision() + ")");
}
}
if (isEnumerated() && value != ValueNull.INSTANCE) {
if (!ValueEnum.isValid(enumerators, value)) {
String s = value.getTraceSQL();
if (s.length() > 127) {
s = s.substring(0, 128) + "...";
}
throw DbException.get(ErrorCode.ENUM_VALUE_NOT_PERMITTED, getCreateSQL(), s);
}
value = ValueEnum.get(enumerators, value.getInt());
}
updateSequenceIfRequired(session, value);
return value;
}
use of org.h2.mvstore.type.DataType in project ignite by apache.
the class DmlAstUtils method elementOrDefault.
/**
* Do what we can to compute default value for this column (mimics H2 behavior).
* @see Table#getDefaultValue
* @see Column#validateConvertUpdateSequence
* @param el SQL element.
* @param col Column.
* @return {@link GridSqlConst#NULL}, if {@code el} is null, or {@code el} if
* it's not {@link GridSqlKeyword#DEFAULT}, or computed default value.
*/
private static GridSqlElement elementOrDefault(GridSqlElement el, GridSqlColumn col) {
if (el == null)
return GridSqlConst.NULL;
if (el != GridSqlKeyword.DEFAULT)
return el;
Column h2Col = col.column();
Expression dfltExpr = h2Col.getDefaultExpression();
Value dfltVal;
try {
dfltVal = dfltExpr != null ? dfltExpr.getValue(null) : null;
} catch (Exception ignored) {
throw new IgniteSQLException("Failed to evaluate default value for a column " + col.columnName());
}
if (dfltVal != null)
return new GridSqlConst(dfltVal);
int type = h2Col.getType();
DataType dt = DataType.getDataType(type);
if (dt.decimal)
dfltVal = ValueInt.get(0).convertTo(type);
else if (dt.type == Value.TIMESTAMP)
dfltVal = ValueTimestamp.fromMillis(U.currentTimeMillis());
else if (dt.type == Value.TIME)
dfltVal = ValueTime.fromNanos(0);
else if (dt.type == Value.DATE)
dfltVal = ValueDate.fromMillis(U.currentTimeMillis());
else
dfltVal = ValueString.get("").convertTo(type);
return new GridSqlConst(dfltVal);
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class AggregateDataSelectivity method getValue.
@Override
Value getValue(Database database, int dataType, boolean distinct) {
if (distinct) {
count = 0;
}
Value v = null;
int s = 0;
if (count == 0) {
s = 0;
} else {
m2 += distinctHashes.size();
m2 = 100 * m2 / count;
s = (int) m2;
s = s <= 0 ? 1 : s > 100 ? 100 : s;
}
v = ValueInt.get(s);
return v.convertTo(dataType);
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class CompareLike method createIndexConditions.
@Override
public void createIndexConditions(Session session, TableFilter filter) {
if (regexp) {
return;
}
if (!(left instanceof ExpressionColumn)) {
return;
}
ExpressionColumn l = (ExpressionColumn) left;
if (filter != l.getTableFilter()) {
return;
}
// which may be slower (possibly not in this case)
if (!right.isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
return;
}
if (escape != null && !escape.isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
return;
}
String p = right.getValue(session).getString();
if (!isInit) {
Value e = escape == null ? null : escape.getValue(session);
if (e == ValueNull.INSTANCE) {
// should already be optimized
DbException.throwInternalError();
}
initPattern(p, getEscapeChar(e));
}
if (invalidPattern) {
return;
}
if (patternLength <= 0 || patternTypes[0] != MATCH) {
// can't use an index
return;
}
int dataType = l.getColumn().getType();
if (dataType != Value.STRING && dataType != Value.STRING_IGNORECASE && dataType != Value.STRING_FIXED) {
// column is not a varchar - can't use the index
return;
}
// Get the MATCH prefix and see if we can create an index condition from
// that.
int maxMatch = 0;
StringBuilder buff = new StringBuilder();
while (maxMatch < patternLength && patternTypes[maxMatch] == MATCH) {
buff.append(patternChars[maxMatch++]);
}
String begin = buff.toString();
if (maxMatch == patternLength) {
filter.addIndexCondition(IndexCondition.get(Comparison.EQUAL, l, ValueExpression.get(ValueString.get(begin))));
} else {
// TODO check if this is correct according to Unicode rules
// (code points)
String end;
if (begin.length() > 0) {
filter.addIndexCondition(IndexCondition.get(Comparison.BIGGER_EQUAL, l, ValueExpression.get(ValueString.get(begin))));
char next = begin.charAt(begin.length() - 1);
// that is higher)
for (int i = 1; i < 2000; i++) {
end = begin.substring(0, begin.length() - 1) + (char) (next + i);
if (compareMode.compareString(begin, end, ignoreCase) == -1) {
filter.addIndexCondition(IndexCondition.get(Comparison.SMALLER, l, ValueExpression.get(ValueString.get(end))));
break;
}
}
}
}
}
use of org.h2.mvstore.type.DataType in project h2database by h2database.
the class Aggregate method optimize.
@Override
public Expression optimize(Session session) {
if (on != null) {
on = on.optimize(session);
dataType = on.getType();
scale = on.getScale();
precision = on.getPrecision();
displaySize = on.getDisplaySize();
}
if (orderByList != null) {
for (SelectOrderBy o : orderByList) {
o.expression = o.expression.optimize(session);
}
orderBySort = initOrder(session);
}
if (groupConcatSeparator != null) {
groupConcatSeparator = groupConcatSeparator.optimize(session);
}
if (filterCondition != null) {
filterCondition = filterCondition.optimize(session);
}
switch(type) {
case GROUP_CONCAT:
dataType = Value.STRING;
scale = 0;
precision = displaySize = Integer.MAX_VALUE;
break;
case COUNT_ALL:
case COUNT:
dataType = Value.LONG;
scale = 0;
precision = ValueLong.PRECISION;
displaySize = ValueLong.DISPLAY_SIZE;
break;
case SELECTIVITY:
dataType = Value.INT;
scale = 0;
precision = ValueInt.PRECISION;
displaySize = ValueInt.DISPLAY_SIZE;
break;
case HISTOGRAM:
dataType = Value.ARRAY;
scale = 0;
precision = displaySize = Integer.MAX_VALUE;
break;
case SUM:
if (dataType == Value.BOOLEAN) {
// example: sum(id > 3) (count the rows)
dataType = Value.LONG;
} else if (!DataType.supportsAdd(dataType)) {
throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL());
} else {
dataType = DataType.getAddProofType(dataType);
}
break;
case AVG:
if (!DataType.supportsAdd(dataType)) {
throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL());
}
break;
case MIN:
case MAX:
case MEDIAN:
break;
case STDDEV_POP:
case STDDEV_SAMP:
case VAR_POP:
case VAR_SAMP:
dataType = Value.DOUBLE;
precision = ValueDouble.PRECISION;
displaySize = ValueDouble.DISPLAY_SIZE;
scale = 0;
break;
case BOOL_AND:
case BOOL_OR:
dataType = Value.BOOLEAN;
precision = ValueBoolean.PRECISION;
displaySize = ValueBoolean.DISPLAY_SIZE;
scale = 0;
break;
case BIT_AND:
case BIT_OR:
if (!DataType.supportsAdd(dataType)) {
throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL());
}
break;
case ARRAY_AGG:
dataType = Value.ARRAY;
scale = 0;
precision = displaySize = Integer.MAX_VALUE;
break;
default:
DbException.throwInternalError("type=" + type);
}
return this;
}
Aggregations