case TransactionManager.LOCKS :
default :
return Tokens.T_LOCKS;
}
case FUNC_TIMEZONE :
return new IntervalSecondData(session.getZoneSeconds(), 0);
case FUNC_SESSION_TIMEZONE :
return new IntervalSecondData(session.sessionTimeZoneSeconds,
0);
case FUNC_DATABASE_TIMEZONE :
int sec =
HsqlDateTime.getZoneSeconds(HsqlDateTime.tempCalDefault);
return new IntervalSecondData(sec, 0);
case FUNC_DATABASE_VERSION :
return HsqlDatabaseProperties.THIS_FULL_VERSION;
case FUNC_SESSION_ID : {
return Long.valueOf(session.getId());
}
case FUNC_ACTION_ID : {
return Long.valueOf(session.actionTimestamp);
}
case FUNC_TRANSACTION_ID : {
return Long.valueOf(session.transactionTimestamp);
}
case FUNC_TRANSACTION_SIZE : {
return Long.valueOf(session.actionIndex);
}
case FUNC_LOB_ID : {
LobData lob = (LobData) data[0];
if (lob == null) {
return null;
}
return Long.valueOf(lob.getId());
}
case FUNC_IDENTITY : {
Number id = session.getLastIdentity();
if (id instanceof Long) {
return id;
} else {
return ValuePool.getLong(id.longValue());
}
}
case FUNC_DIAGNOSTICS : {
return session.sessionContext
.diagnosticsVariables[exprSubType];
}
case FUNC_SEQUENCE_ARRAY : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
HsqlArrayList list = new HsqlArrayList();
Object current = data[0];
Type type = nodes[0].getDataType();
boolean ascending = type.compare(session, data[1], data[0])
>= 0;
while (true) {
int compare = type.compare(session, current, data[1]);
if (ascending) {
if (compare > 0) {
break;
}
} else if (compare < 0) {
break;
}
list.add(current);
Object newValue = type.add(session, current, data[2],
nodes[2].getDataType());
compare = type.compare(session, current, newValue);
if (ascending) {
if (compare >= 0) {
break;
}
} else if (compare <= 0) {
break;
}
current = newValue;
}
Object[] array = list.toArray();
return array;
}
case FUNC_TIMESTAMPADD : {
if (data[1] == null || data[2] == null) {
return null;
}
data[1] = Type.SQL_BIGINT.convertToType(session, data[1],
nodes[1].getDataType());
int part = ((Number) nodes[0].valueData).intValue();
long units = ((Number) data[1]).longValue();
TimestampData source = (TimestampData) data[2];
IntervalType t;
Object o;
switch (part) {
case Tokens.SQL_TSI_FRAC_SECOND : {
long seconds = units / DTIType.limitNanoseconds;
int nanos = (int) (units % DTIType.limitNanoseconds);
t = Type.SQL_INTERVAL_SECOND_MAX_FRACTION;
o = new IntervalSecondData(seconds, nanos, t);
return dataType.add(session, source, o, t);
}
case Tokens.SQL_TSI_MILLI_SECOND : {
long seconds = units / 1000;
int nanos = (int) (units % 1000) * 1000000;
t = Type.SQL_INTERVAL_SECOND_MAX_FRACTION;
o = new IntervalSecondData(seconds, nanos, t);
return dataType.add(session, source, o, t);
}
case Tokens.SQL_TSI_SECOND :
t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
o = IntervalSecondData.newIntervalSeconds(units, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_MINUTE :
t = Type.SQL_INTERVAL_MINUTE_MAX_PRECISION;
o = IntervalSecondData.newIntervalMinute(units, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_HOUR :
t = Type.SQL_INTERVAL_HOUR_MAX_PRECISION;
o = IntervalSecondData.newIntervalHour(units, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_DAY :
t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
o = IntervalSecondData.newIntervalDay(units, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_WEEK :
t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
o = IntervalSecondData.newIntervalDay(units * 7, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_MONTH :
t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
o = IntervalMonthData.newIntervalMonth(units, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_QUARTER :
t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
o = IntervalMonthData.newIntervalMonth(units * 3, t);
return dataType.add(session, source, o, t);
case Tokens.SQL_TSI_YEAR :
t = Type.SQL_INTERVAL_YEAR_MAX_PRECISION;
o = IntervalMonthData.newIntervalMonth(units * 12, t);
return dataType.add(session, source, o, t);
default :
throw Error.runtimeError(ErrorCode.U_S0500,
"FunctionCustom");
}
}
case FUNC_TIMESTAMPDIFF : {
if (data[1] == null || data[2] == null) {
return null;
}
int part = ((Number) nodes[0].valueData).intValue();
TimestampData a = (TimestampData) data[2];
TimestampData b = (TimestampData) data[1];
if (nodes[2].dataType.isDateTimeTypeWithZone()) {
a = (TimestampData) Type.SQL_TIMESTAMP.convertToType(
session, a, Type.SQL_TIMESTAMP_WITH_TIME_ZONE);
}
if (nodes[1].dataType.isDateTimeTypeWithZone()) {
b = (TimestampData) Type.SQL_TIMESTAMP.convertToType(
session, b, Type.SQL_TIMESTAMP_WITH_TIME_ZONE);
}
IntervalType t;
switch (part) {
case Tokens.SQL_TSI_FRAC_SECOND : {
t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
IntervalSecondData interval =
(IntervalSecondData) t.subtract(session, a, b,
null);
return new Long(
DTIType.limitNanoseconds * interval.getSeconds()
+ interval.getNanos());
}
case Tokens.SQL_TSI_MILLI_SECOND : {
t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
IntervalSecondData interval =
(IntervalSecondData) t.subtract(session, a, b,
null);
return new Long(1000 * interval.getSeconds()
+ interval.getNanos() / 1000000);
}
case Tokens.SQL_TSI_SECOND :
t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)));
case Tokens.SQL_TSI_MINUTE :
t = Type.SQL_INTERVAL_MINUTE_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)));
case Tokens.SQL_TSI_HOUR :
t = Type.SQL_INTERVAL_HOUR_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)));
case Tokens.SQL_TSI_DAY :
t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)));
case Tokens.SQL_TSI_WEEK :
t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)) / 7);
case Tokens.SQL_TSI_MONTH :
t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)));
case Tokens.SQL_TSI_QUARTER :
t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)) / 3);
case Tokens.SQL_TSI_YEAR :
t = Type.SQL_INTERVAL_YEAR_MAX_PRECISION;
return new Long(
t.convertToLongEndUnits(
t.subtract(session, a, b, null)));
default :
throw Error.runtimeError(ErrorCode.U_S0500,
"FunctionCustom");
}
}
case FUNC_DATE_ADD : {
if (data[0] == null || data[1] == null) {
return null;
}
return dataType.add(session, data[0], data[1],
nodes[RIGHT].dataType);
}
case FUNC_DATE_SUB : {
if (data[0] == null || data[1] == null) {
return null;
}
return dataType.subtract(session, data[0], data[1],
nodes[RIGHT].dataType);
}
case FUNC_DAYS : {
if (data[0] == null) {
return null;
}
IntervalSecondData diff =
(IntervalSecondData) Type.SQL_INTERVAL_DAY_MAX_PRECISION
.subtract(session, data[0],
DateTimeType.epochTimestamp, Type.SQL_DATE);
return ValuePool.getInt((int) (diff.getSeconds()
/ (24 * 60 * 60) + 1));
}
case FUNC_ROUND :
case FUNC_TRUNC : {
int interval = Types.SQL_INTERVAL_DAY;
if (data[0] == null) {
return null;
}
if (dataType.isDateTimeType()) {
DateTimeType type = (DateTimeType) dataType;
if (nodes.length > 1 && nodes[1] != null) {
if (data[1] == null) {
return null;
}
interval = HsqlDateTime.toStandardIntervalPart(
(String) data[1]);
}
if (interval < 0) {
throw Error.error(ErrorCode.X_42566, (String) data[1]);
}
return funcType == FUNC_ROUND
? type.round(data[0], interval)
: type.truncate(data[0], interval);
}
}
// fall through
case FUNC_TRUNCATE : {
int offset = 0;
if (data[0] == null) {
return null;
}
if (nodes.length > 1) {
if (data[1] == null) {
return null;
}
data[1] = Type.SQL_INTEGER.convertToType(session, data[1],
nodes[1].getDataType());
offset = ((Number) data[1]).intValue();
}
return funcType == FUNC_ROUND
? ((NumberType) dataType).round(data[0], offset)
: ((NumberType) dataType).truncate(data[0], offset);
}
case FUNC_TO_CHAR : {
if (data[0] == null || data[1] == null) {
return null;
}
SimpleDateFormat format = session.getSimpleDateFormatGMT();
Date date =
(Date) ((DateTimeType) nodes[0].dataType)
.convertSQLToJavaGMT(session, data[0]);
return HsqlDateTime.toFormattedDate(date, (String) data[1],
format);
}
case FUNC_TO_NUMBER : {
if (data[0] == null) {
return null;
}
return dataType.convertToType(session, data[0],
nodes[0].dataType);
}
case FUNC_TO_DATE :
case FUNC_TO_TIMESTAMP : {
if (data[0] == null || data[1] == null) {
return null;
}
SimpleDateFormat format = session.getSimpleDateFormatGMT();
TimestampData value = HsqlDateTime.toDate((String) data[0],
(String) data[1], format);
if (funcType == FUNC_TO_DATE) {
value.clearNanos();
}
return value;
}
case FUNC_TIMESTAMP : {
boolean unary = nodes[1] == null;
if (data[0] == null) {
return null;
}
if (unary) {
if (nodes[0].dataType.isNumberType()) {
return new TimestampData(
((Number) data[0]).longValue());
}
try {
return Type.SQL_TIMESTAMP.convertToType(session,
data[0], nodes[0].dataType);
} catch (HsqlException e) {
return Type.SQL_DATE.convertToType(session, data[0],
nodes[0].dataType);
}
}
if (data[1] == null) {
return null;
}
TimestampData date =
(TimestampData) Type.SQL_DATE.convertToType(session,
data[0], nodes[0].dataType);
TimeData time = (TimeData) Type.SQL_TIME.convertToType(session,
data[1], nodes[1].dataType);
return new TimestampData(date.getSeconds()
+ time.getSeconds(), time.getNanos());
}
case FUNC_TIMESTAMP_WITH_ZONE : {
Calendar calendar = session.getCalendar();
long seconds;
int nanos = 0;
int zone;
if (data[0] == null) {
return null;
}
if (nodes[0].dataType.isNumberType()) {
seconds = ((Number) data[0]).longValue();
} else if (nodes[0].dataType.typeCode == Types.SQL_TIMESTAMP) {
seconds = ((TimestampData) data[0]).getSeconds();
seconds =
HsqlDateTime.convertMillisToCalendar(
calendar, seconds * 1000) / 1000;
} else if (nodes[0].dataType.typeCode
== Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {
seconds = ((TimestampData) data[0]).getSeconds();
} else {
throw Error.error(ErrorCode.X_42566, (String) data[1]);
}
synchronized (calendar) {
calendar.setTimeInMillis(seconds * 1000);
zone = HsqlDateTime.getZoneSeconds(calendar);
}
return new TimestampData(seconds, nanos, zone);
}
case FUNC_PI :
return new Double(Math.PI);
case FUNC_RAND : {
if (nodes[0] == null) {
return new Double(session.random());
} else {
data[0] = Type.SQL_BIGINT.convertToType(session, data[0],
nodes[0].getDataType());
long seed = ((Number) data[0]).longValue();
return new Double(session.random(seed));
}
}
case FUNC_UUID : {
if (nodes[0] == null) {
UUID uuid = java.util.UUID.randomUUID();
long hi = uuid.getMostSignificantBits();
long lo = uuid.getLeastSignificantBits();
return new BinaryData(ArrayUtil.toByteArray(hi, lo),
false);
} else {
if (data[0] == null) {
return null;
}
if (dataType.isBinaryType()) {
return new BinaryData(
StringConverter.toBinaryUUID((String) data[0]),
false);
} else {
return StringConverter.toStringUUID(
((BinaryData) data[0]).getBytes());
}
}
}
case FUNC_UNIX_MILLIS : {
TimestampData ts;
if (nodes[0] == null) {
ts = session.getCurrentTimestamp(true);
} else {
if (data[0] == null) {
return null;
}
ts = (TimestampData) data[0];
}
long millis = ts.getSeconds() * 1000 + ts.getNanos() / 1000000;
return Long.valueOf(millis);
}
case FUNC_UNIX_TIMESTAMP : {
TimestampData ts;
if (nodes[0] == null) {
ts = session.getCurrentTimestamp(true);
} else {
if (data[0] == null) {
return null;
}
ts = (TimestampData) data[0];
}
return Long.valueOf(ts.getSeconds());
}
case FUNC_ACOS : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.acos(d));
}
case FUNC_ASIN : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.asin(d));
}
case FUNC_ATAN : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.atan(d));
}
case FUNC_COS : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.cos(d));
}
case FUNC_COT : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
double c = 1.0 / java.lang.Math.tan(d);
return new Double(c);
}
case FUNC_DEGREES : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.toDegrees(d));
}
case FUNC_SIN : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.sin(d));
}
case FUNC_TAN : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.tan(d));
}
case FUNC_LOG10 : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.log10(d));
}
case FUNC_RADIANS : {
if (data[0] == null) {
return null;
}
double d = NumberType.toDouble(data[0]);
return new Double(java.lang.Math.toRadians(d));
}
//
case FUNC_SIGN : {
if (data[0] == null) {
return null;
}
int val =
((NumberType) nodes[0].dataType).compareToZero(data[0]);
return ValuePool.getInt(val);
}
case FUNC_ATAN2 : {
if (data[0] == null) {
return null;
}
double a = NumberType.toDouble(data[0]);
double b = NumberType.toDouble(data[1]);
return new Double(java.lang.Math.atan2(a, b));
}
case FUNC_ASCII : {
String arg;
if (data[0] == null) {
return null;
}
if (nodes[0].dataType.isLobType()) {
arg = ((ClobData) data[0]).getSubString(session, 0, 1);
} else {
arg = (String) data[0];
}
if (arg.length() == 0) {
return null;
}
return ValuePool.getInt(arg.charAt(0));
}
case FUNC_CHAR :
if (data[0] == null) {
return null;
}
data[0] = Type.SQL_INTEGER.convertToType(session, data[0],
nodes[0].getDataType());
int arg = ((Number) data[0]).intValue();
if (Character.isValidCodePoint(arg)
&& Character.isValidCodePoint((char) arg)) {
return String.valueOf((char) arg);
}
throw Error.error(ErrorCode.X_22511);
case FUNC_ROUNDMAGIC : {
int offset = 0;
if (data[0] == null) {
return null;
}
if (nodes.length > 1) {
if (data[1] == null) {
return null;
}
offset = ((Number) data[1]).intValue();
}
return ((NumberType) dataType).round(data[0], offset);
}
case FUNC_SOUNDEX : {
if (data[0] == null) {
return null;
}
String s = (String) data[0];
return new String(soundex(s), 0, 4);
}
case FUNC_BITAND :
case FUNC_BITANDNOT :
case FUNC_BITNOT :
case FUNC_BITOR :
case FUNC_BITXOR : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
if (dataType.isNumberType()) {
long v = 0;
long a;
long b = 0;
data[0] = Type.SQL_BIGINT.convertToType(session, data[0],
nodes[0].getDataType());
a = ((Number) data[0]).longValue();
if (funcType != FUNC_BITNOT) {
data[1] = Type.SQL_BIGINT.convertToType(session,
data[1], nodes[1].getDataType());
b = ((Number) data[1]).longValue();
}
switch (funcType) {
case FUNC_BITAND :
v = a & b;
break;
case FUNC_BITANDNOT :
v = a & ~b;
break;
case FUNC_BITNOT :
v = ~a;
break;
case FUNC_BITOR :
v = a | b;
break;
case FUNC_BITXOR :
v = a ^ b;
break;
}
switch (dataType.typeCode) {
case Types.SQL_NUMERIC :
case Types.SQL_DECIMAL :
return BigDecimal.valueOf(v);
case Types.SQL_BIGINT :
return ValuePool.getLong(v);
case Types.SQL_INTEGER :
case Types.SQL_SMALLINT :
case Types.TINYINT :
return ValuePool.getInt((int) v);
default :
throw Error.error(ErrorCode.X_42561);
}
} else {
byte[] a = ((BinaryData) data[0]).getBytes();
byte[] b = null;
byte[] v;
if (funcType != FUNC_BITNOT) {
b = ((BinaryData) data[1]).getBytes();
}
switch (funcType) {
case FUNC_BITAND :
v = BitMap.and(a, b);
break;
case FUNC_BITANDNOT :
b = BitMap.not(b);
v = BitMap.and(a, b);
break;
case FUNC_BITNOT :
v = BitMap.not(a);
break;
case FUNC_BITOR :
v = BitMap.or(a, b);
break;
case FUNC_BITXOR :
v = BitMap.xor(a, b);
break;
default :
throw Error.error(ErrorCode.X_42561);
}
return new BinaryData(v, dataType.precision);
}
}
case FUNC_DIFFERENCE : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
char[] s1 = soundex((String) data[0]);
char[] s2 = soundex((String) data[1]);
int e = 0;
if (s1[0] == s2[0]) {
e++;
}
int js = 1;
for (int i = 1; i < 4; i++) {
for (int j = js; j < 4; j++) {
if (s1[j] == s2[i]) {
e++;
js = j + 1;
break;
}
}
}
return ValuePool.getInt(e);
}
case FUNC_HEXTORAW : {
if (data[0] == null) {
return null;
}
return dataType.convertToType(session, data[0],
nodes[0].dataType);
}
case FUNC_RAWTOHEX : {
if (data[0] == null) {
return null;
}
BlobData binary = (BlobData) data[0];
byte[] bytes = binary.getBytes(session, 0,
(int) binary.length(session));
return StringConverter.byteArrayToHexString(bytes);
}
case FUNC_REPEAT : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
data[1] = Type.SQL_INTEGER.convertToType(session, data[1],
nodes[1].getDataType());
String string = (String) data[0];
int i = ((Number) data[1]).intValue();
StringBuffer sb = new StringBuffer(string.length() * i);
while (i-- > 0) {
sb.append(string);
}
return sb.toString();
}
case FUNC_REPLACE : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
String string = (String) data[0];
String find = (String) data[1];
String replace = (String) data[2];
StringBuffer sb = new StringBuffer();
int start = 0;
if (find.length() == 0) {
return string;
}
while (true) {
int i = string.indexOf(find, start);
if (i == -1) {
sb.append(string.substring(start));
break;
}
sb.append(string.substring(start, i));
sb.append(replace);
start = i + find.length();
}
return sb.toString();
}
case FUNC_LEFT :
case FUNC_RIGHT : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
int count = ((Number) data[1]).intValue();
return ((CharacterType) dataType).substring(session, data[0],
0, count, true, funcType == FUNC_RIGHT);
}
case FUNC_SPACE : {
if (data[0] == null) {
return null;
}
data[0] = Type.SQL_INTEGER.convertToType(session, data[0],
nodes[0].getDataType());
int count = ((Number) data[0]).intValue();
char[] array = new char[count];
ArrayUtil.fillArray(array, 0, ' ');
return String.valueOf(array);
}
case FUNC_REVERSE : {
if (data[0] == null) {
return null;
}
StringBuffer sb = new StringBuffer((String) data[0]);
sb = sb.reverse();
return sb.toString();
}
case FUNC_REGEXP_MATCHES :
case FUNC_REGEXP_SUBSTRING :
case FUNC_REGEXP_SUBSTRING_ARRAY : {
for (int i = 0; i < data.length; i++) {
if (data[i] == null) {
return null;
}
}
Pattern currentPattern = pattern;
if (currentPattern == null) {
String matchPattern = (String) data[1];
currentPattern = Pattern.compile(matchPattern);
}
Matcher matcher = currentPattern.matcher((String) data[0]);
switch (funcType) {
case FUNC_REGEXP_MATCHES : {
boolean match = matcher.matches();
return Boolean.valueOf(match);
}
case FUNC_REGEXP_SUBSTRING : {
boolean match = matcher.find();
if (match) {
return matcher.group();
} else {
return null;
}
}
case FUNC_REGEXP_SUBSTRING_ARRAY : {
HsqlArrayList list = new HsqlArrayList();
while (matcher.find()) {
list.add(matcher.group());
}
return list.toArray();
}
}
}
case FUNC_CRYPT_KEY : {
byte[] bytes = Crypto.getNewKey((String) data[0],
(String) data[1]);
return StringConverter.byteArrayToHexString(bytes);
}
case FUNC_LOAD_FILE : {
String fileName = (String) data[0];
if (fileName == null) {
return null;
}
switch (dataType.typeCode) {
case Types.SQL_CLOB :
return session.sessionData.createClobFromFile(fileName,
(String) data[1]);
case Types.SQL_BLOB :
default :
return session.sessionData.createBlobFromFile(
fileName);
}
}
case FUNC_LPAD :
case FUNC_RPAD : {
if (data[0] == null || data[1] == null) {
return null;
}
String value;
if (nodes[0].dataType.typeCode == Types.SQL_CLOB) {
value = (String) Type.SQL_VARCHAR.convertToType(session,
data[0], nodes[0].dataType);
} else if (nodes[0].dataType.isCharacterType()) {
value = (String) data[0];
} else {
value = nodes[0].dataType.convertToString(data[0]);
}
int length = ((Integer) Type.SQL_INTEGER.convertToType(session,
data[1], nodes[1].dataType)).intValue();
String pad = " ";
if (nodes[2] != null) {
pad = nodes[2].dataType.convertToString(data[2]);
if (pad.length() == 0) {
pad = " ";
}
}
value = (String) Type.SQL_VARCHAR.trim(session, value, ' ',
true, true);
value = StringUtil.toPaddedString(value, length, pad,
funcType == FUNC_RPAD);
if (dataType.isLobType()) {
return dataType.convertToType(session, value,
Type.SQL_VARCHAR);
} else {
return value;
}
}
case FUNC_POSITION_ARRAY : {
if (data[1] == null) {
return null;
}
if (data[2] == null) {
return null;
}
Object[] array = (Object[]) data[1];
ArrayType dt = (ArrayType) nodes[1].dataType;
Type elementType = dt.collectionBaseType();
int start = ((Number) Type.SQL_INTEGER.convertToType(session,
data[2], nodes[2].dataType)).intValue();
if (start <= 0) {
throw Error.error(ErrorCode.X_22003);
}
start--;
for (int i = start; i < array.length; i++) {
if (elementType.compare(session, data[0], array[i]) == 0) {
return ValuePool.getInt(i + 1);
}
}
return ValuePool.INTEGER_0;
}
case FUNC_SORT_ARRAY : {
if (data[0] == null) {
return null;
}
ArrayType dt = (ArrayType) dataType;
SortAndSlice exprSort = new SortAndSlice();
exprSort.prepareSingleColumn(1);
exprSort.sortDescending[0] = ((Number) data[1]).intValue()
== Tokens.DESC;
exprSort.sortNullsLast[0] = ((Number) data[2]).intValue()
== Tokens.LAST;
Object array = ArrayUtil.duplicateArray(data[0]);
dt.sort(session, array, exprSort);
return array;
}
case FUNC_ADD_MONTHS : {
if (data[0] == null) {
return null;
}
if (data[1] == null) {
return null;
}
TimestampData ts = (TimestampData) data[0];
int months = ((Number) data[1]).intValue();
return Type.SQL_TIMESTAMP_NO_FRACTION.addMonthsSpecial(session,
ts, months);
}
case FUNC_DBTIMEZONE : {
TimestampData timestamp = session.getSystemTimestamp(true);
IntervalSecondData zone =
new IntervalSecondData(timestamp.getZone(), 0);
return Type.SQL_INTERVAL_HOUR_TO_MINUTE.convertToString(zone);
}
case FUNC_FROM_TZ : {
if (data[0] == null || data[1] == null) {
return null;
}
TimestampData timestamp = (TimestampData) data[0];
IntervalSecondData zone =
(IntervalSecondData) Type.SQL_INTERVAL_HOUR_TO_MINUTE
.convertToDefaultType(session, data[1]);
return new TimestampData(
timestamp.getSeconds() - zone.getSeconds(),
timestamp.getNanos(), (int) zone.getSeconds());
}
case FUNC_LAST_DAY : {
if (data[0] == null) {
return null;
}
return Type.SQL_TIMESTAMP_NO_FRACTION.getLastDayOfMonth(
session, data[0]);
}
case FUNC_MONTHS_BETWEEN : {
if (data[0] == null || data[1] == null) {
return null;
}
return DateTimeType.subtractMonthsSpecial(session,
(TimestampData) data[0], (TimestampData) data[1]);
}
case FUNC_NEW_TIME : {
if (data[0] == null || data[1] == null || data[2] == null) {
return null;
}
IntervalSecondData zone1 =
(IntervalSecondData) Type.SQL_INTERVAL_HOUR_TO_MINUTE
.convertToDefaultType(session, data[1]);
IntervalSecondData zone2 =
(IntervalSecondData) Type.SQL_INTERVAL_HOUR_TO_MINUTE
.convertToDefaultType(session, data[1]);
Object val =
Type.SQL_TIMESTAMP_WITH_TIME_ZONE.changeZone(data[0],
Type.SQL_TIMESTAMP, (int) zone2.getSeconds(),
(int) zone1.getSeconds());
return Type.SQL_TIMESTAMP.convertToType(session, val,
Type.SQL_TIMESTAMP_WITH_TIME_ZONE);
}
case FUNC_NEXT_DAY : {
if (data[0] == null || data[1] == null) {
return null;
}
}
case FUNC_NUMTODSINTERVAL : {
if (data[0] == null || data[1] == null) {
return null;
}
Object st = Type.SQL_VARCHAR.trim(session, data[1], ' ', true,
true);
st = Type.SQL_VARCHAR.upper(session, st);
st = Type.SQL_VARCHAR.convertToDefaultType(session, st);
int token = Tokens.get((String) st);
int typeCode = IntervalType.getFieldNameTypeForToken(token);
switch (typeCode) {
case Types.SQL_INTERVAL_DAY :
case Types.SQL_INTERVAL_HOUR :
case Types.SQL_INTERVAL_MINUTE :
case Types.SQL_INTERVAL_SECOND :
break;
default :
throw Error.error(ErrorCode.X_42566);
}
double value = ((Number) data[0]).doubleValue();
return IntervalSecondData.newInterval(value, typeCode);
}
case FUNC_NUMTOYMINTERVAL : {
if (data[0] == null || data[1] == null) {
return null;
}
Object st = Type.SQL_VARCHAR.trim(session, data[1], ' ', true,
true);
st = Type.SQL_VARCHAR.upper(session, st);
st = Type.SQL_VARCHAR.convertToDefaultType(session, st);
int token = Tokens.get((String) st);
int typeCode = IntervalType.getFieldNameTypeForToken(token);
switch (typeCode) {
case Types.SQL_INTERVAL_YEAR :
case Types.SQL_INTERVAL_MONTH :
break;
default :
throw Error.error(ErrorCode.X_42566);
}
double value = ((Number) data[0]).doubleValue();
return IntervalMonthData.newInterval(value, typeCode);
}
case FUNC_SESSIONTIMEZONE : {
IntervalSecondData zone =
new IntervalSecondData(session.sessionTimeZoneSeconds, 0);
return Type.SQL_INTERVAL_HOUR_TO_MINUTE.convertToString(zone);
}
case FUNC_SYS_EXTRACT_UTC : {
if (data[0] == null) {