use of org.voltdb.types.TimestampType in project voltdb by VoltDB.
the class TestExpressionUtil method testSetOutputTypeForInsertExpressionWithLiteralStringDates.
public void testSetOutputTypeForInsertExpressionWithLiteralStringDates() throws Exception {
ConstantValueExpression cve = new ConstantValueExpression();
TimestampType ts = new TimestampType(999999999);
cve.setValue(ts.toString());
cve.setValueType(VoltType.STRING);
cve.setValueSize(ts.toString().length());
cve.refineValueType(VoltType.TIMESTAMP, 8);
assertEquals(VoltType.TIMESTAMP, cve.getValueType());
assertEquals("999999999", cve.m_value);
}
use of org.voltdb.types.TimestampType in project voltdb by VoltDB.
the class ConstantValueExpression method refineValueType.
/**
* This method will alter the type of this constant expression based on the context
* in which it appears. For example, each constant in the value list of an INSERT
* statement will be refined to the type of the column in the table being inserted into.
*
* Here is a summary of the rules used to convert types here:
* - VARCHAR literals may be reinterpreted as (depending on the type needed):
* - VARBINARY (string is required to have an even number of hex digits)
* - TIMESTAMP (string must have timestamp format)
* - Some numeric type (any of the four integer types, DECIMAL or FLOAT)
*
* In addition, if this object is a VARBINARY constant (e.g., X'00abcd') and we need
* an integer constant, (any of TINYINT, SMALLINT, INTEGER or BIGINT),
* we interpret the hex digits as a 64-bit signed integer. If there are fewer than 16 hex digits,
* the most significant bits are assumed to be zeros. So for example, X'FF' appearing where we want a
* TINYINT would be out-of-range, since it's 255 and not -1.
*
* There is corresponding code for handling integer hex literals in ParameterConverter for parameters,
* and in HSQL's ExpressionValue class.
*/
@Override
public void refineValueType(VoltType neededType, int neededSize) {
int size_unit = 1;
if (neededType == m_valueType) {
if (neededSize == m_valueSize) {
return;
}
// Variably sized types need to fit within the target width.
if (neededType == VoltType.VARBINARY) {
if (!Encoder.isHexEncodedString(getValue())) {
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + neededType.toSQLString() + " value");
}
size_unit = 2;
} else {
assert neededType == VoltType.STRING;
}
if (getValue().length() > size_unit * neededSize) {
throw new PlanningErrorException("Value (" + getValue() + ") is too wide for a constant " + neededType.toSQLString() + " value of size " + neededSize);
}
setValueSize(neededSize);
return;
}
if (m_isNull) {
setValueType(neededType);
setValueSize(neededSize);
return;
}
// Constant's apparent type may not exactly match the target type needed.
if (neededType == VoltType.VARBINARY && (m_valueType == VoltType.STRING || m_valueType == null)) {
if (!Encoder.isHexEncodedString(getValue())) {
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + neededType.toSQLString() + " value");
}
size_unit = 2;
if (getValue().length() > size_unit * neededSize) {
throw new PlanningErrorException("Value (" + getValue() + ") is too wide for a constant " + neededType.toSQLString() + " value of size " + neededSize);
}
setValueType(neededType);
setValueSize(neededSize);
return;
}
if (neededType == VoltType.STRING && m_valueType == null) {
if (getValue().length() > size_unit * neededSize) {
throw new PlanningErrorException("Value (" + getValue() + ") is too wide for a constant " + neededType.toSQLString() + " value of size " + neededSize);
}
setValueType(neededType);
setValueSize(neededSize);
return;
}
if (neededType == VoltType.TIMESTAMP) {
if (m_valueType == VoltType.STRING) {
try {
// Convert date value in whatever format is supported by
// TimeStampType into VoltDB native microsecond count.
// TODO: Should datetime string be supported as the new
// canonical internal format for timestamp constants?
// Historically, the long micros value made sense because
// it was initially the only way and later the most
// direct way to initialize timestamp values in the EE.
// But now that long value can not be used to "explain"
// an expression as a valid SQL timestamp value for DDL
// round trips, forcing a reverse conversion back through
// TimeStampType to a datetime string.
TimestampType ts = new TimestampType(m_value);
m_value = String.valueOf(ts.getTime());
}// It couldn't be converted to timestamp.
catch (IllegalArgumentException e) {
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + neededType.toSQLString() + " value");
}
setValueType(neededType);
setValueSize(neededSize);
return;
}
}
if ((neededType == VoltType.FLOAT || neededType == VoltType.DECIMAL) && getValueType() != VoltType.VARBINARY) {
if (m_valueType == null || (m_valueType != VoltType.NUMERIC && !m_valueType.isExactNumeric())) {
try {
Double.parseDouble(getValue());
} catch (NumberFormatException nfe) {
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + neededType.toSQLString() + " value");
}
}
setValueType(neededType);
setValueSize(neededSize);
return;
}
if (neededType.isBackendIntegerType()) {
long value = 0;
try {
if (getValueType() == VoltType.VARBINARY) {
value = SQLParser.hexDigitsToLong(getValue());
setValue(Long.toString(value));
} else {
value = Long.parseLong(getValue());
}
} catch (SQLParser.Exception | NumberFormatException exc) {
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + neededType.toSQLString() + " value");
}
checkIntegerValueRange(value, neededType);
m_valueType = neededType;
m_valueSize = neededType.getLengthInBytesForFixedTypes();
return;
}
// That's it for known type conversions.
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + neededType.toSQLString() + " value");
}
use of org.voltdb.types.TimestampType in project voltdb by VoltDB.
the class ConstantValueExpression method explain.
@Override
public String explain(String unused) {
if (m_isNull) {
return "NULL";
}
if (m_valueType == VoltType.STRING) {
return "'" + m_value + "'";
}
if (m_valueType == VoltType.TIMESTAMP) {
try {
// Convert the datetime value in its canonical internal form,
// currently a count of epoch microseconds,
// through TimeStampType into a timestamp string.
long micros = Long.valueOf(m_value);
TimestampType ts = new TimestampType(micros);
return "'" + ts.toString() + "'";
}// It couldn't be converted to timestamp.
catch (IllegalArgumentException e) {
throw new PlanningErrorException("Value (" + getValue() + ") has an invalid format for a constant " + VoltType.TIMESTAMP.toSQLString() + " value");
}
}
return m_value;
}
use of org.voltdb.types.TimestampType in project voltdb by VoltDB.
the class DeleteOldestToTarget method run.
/**
* Procedure main logic.
*
* @param partitionValue Partitioning key for this procedure.
* @param maxTotalRows The desired number of rows per partition.
* @param targetMaxRowsToDelete The upper limit on the number of rows to delete per transaction.
* @return The number of rows deleted.
* @throws VoltAbortException on bad input.
*/
public long run(String partitionValue, long maxTotalRows, long targetMaxRowsToDelete) {
if (targetMaxRowsToDelete <= 0) {
throw new VoltAbortException("maxRowsToDeletePerProc must be > 0.");
}
if (maxTotalRows < 0) {
throw new VoltAbortException("maxTotalRows must be >= 0.");
}
// Count the rows in the current partition.
voltQueueSQL(countRows, EXPECT_SCALAR_LONG);
long count = voltExecuteSQL()[0].asScalarLong();
// If partition is smaller than desired, return without deleting rows.
if (count < maxTotalRows) {
// Return 0 deleted rows.
return 0;
}
// If asked to remove all rows, go ahead
if ((maxTotalRows == 0) && (count < targetMaxRowsToDelete)) {
voltQueueSQL(deleteAll, EXPECT_SCALAR_MATCH(count));
voltExecuteSQL(true);
// Total deleted rows = table size.
return count;
}
// Figure out how many rows to try to delete.
long agedOutCount = count - maxTotalRows;
long rowsToConsider = Math.min(agedOutCount, targetMaxRowsToDelete);
// Find the timestamp of the row at position N in the sorted order, where N is the chunk size
voltQueueSQL(getNthOldestTimestamp, EXPECT_SCALAR, rowsToConsider);
TimestampType newestToDiscard = voltExecuteSQL()[0].fetchRow(0).getTimestampAsTimestamp(0);
// Delete all rows >= the timestamp found in the previous statement.
// This will delete AT LEAST N rows, but since timestamps may be non-unique,
// it might delete more than N. In the worst case, it could delete all rows
// if every row has an identical timestamp value. It is guaranteed to make
// progress. If we used strictly less than, it might not make progress.
// This is why the max rows to delete number is a target, not always a perfect max.
voltQueueSQL(deleteOlderThanDate, EXPECT_SCALAR_LONG, newestToDiscard);
long deletedCount = voltExecuteSQL(true)[0].asScalarLong();
return deletedCount;
}
use of org.voltdb.types.TimestampType in project voltdb by VoltDB.
the class EndCall method run.
/**
* Procedure main logic.
*
* @param uuid Column value for tuple insertion and partitioning key for this procedure.
* @param val Column value for tuple insertion.
* @param update_ts Column value for tuple insertion.
* @param maxTotalRows The desired number of rows per partition.
* @param targetMaxRowsToDelete The upper limit on the number of rows to delete per transaction.
* @return The number of deleted rows.
* @throws VoltAbortException on bad input.
*/
public long run(int agent_id, String phone_no, long call_id, TimestampType end_ts) {
voltQueueSQL(findOpenCall, EXPECT_ZERO_OR_ONE_ROW, call_id, agent_id, phone_no);
voltQueueSQL(findCompletedCall, EXPECT_ZERO_OR_ONE_ROW, call_id, agent_id, phone_no);
VoltTable[] results = voltExecuteSQL();
boolean completedCall = results[1].getRowCount() > 0;
if (completedCall) {
return -1;
}
VoltTable openRowTable = results[0];
if (openRowTable.getRowCount() > 0) {
VoltTableRow existingCall = openRowTable.fetchRow(0);
// check if this is the second begin we've seen for this open call
existingCall.getTimestampAsTimestamp("end_ts");
if (existingCall.wasNull() == false) {
return -1;
}
// check if this completes the call
TimestampType start_ts = existingCall.getTimestampAsTimestamp("start_ts");
if (existingCall.wasNull() == false) {
int durationms = (int) ((end_ts.getTime() - start_ts.getTime()) / 1000);
// update per-day running stddev calculation
computeRunningStdDev(agent_id, end_ts, durationms);
// completes the call
voltQueueSQL(deleteOpenCall, EXPECT_SCALAR_MATCH(1), call_id, agent_id, phone_no);
voltQueueSQL(insertCompletedCall, EXPECT_SCALAR_MATCH(1), call_id, agent_id, phone_no, start_ts, end_ts, durationms);
voltExecuteSQL(true);
return 0;
}
}
voltQueueSQL(upsertOpenCall, EXPECT_SCALAR_MATCH(1), call_id, agent_id, phone_no, end_ts);
voltExecuteSQL(true);
return 0;
}
Aggregations