@Override public void finishDelete(ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments) { RaptorTableHandle table = (RaptorTableHandle) tableHandle; long transactionId = table.getTransactionId().getAsLong(); long tableId = table.getTableId(); List<ColumnInfo> columns = getColumnHandles(session, tableHandle).values().stream() .map(RaptorColumnHandle.class::cast) .map(ColumnInfo::fromHandle).collect(toList()); ImmutableSet.Builder<UUID> oldShardUuidsBuilder = ImmutableSet.builder(); ImmutableList.Builder<ShardInfo> newShardsBuilder = ImmutableList.builder(); fragments.stream() .map(fragment -> SHARD_DELTA_CODEC.fromJson(fragment.getBytes())) .forEach(delta -> { oldShardUuidsBuilder.addAll(delta.getOldShardUuids()); newShardsBuilder.addAll(delta.getNewShards()); }); Set<UUID> oldShardUuids = oldShardUuidsBuilder.build(); List<ShardInfo> newShards = newShardsBuilder.build(); OptionalLong updateTime = OptionalLong.of(session.getStartTime()); log.info("Finishing delete for tableId %s (removed: %s, rewritten: %s)", tableId, oldShardUuids.size() - newShards.size(), newShards.size()); shardManager.replaceShardUuids(transactionId, tableId, columns, oldShardUuids, newShards, updateTime); clearRollback(); }
private static long timeAtTimeZone(ConnectorSession session, long timeWithTimeZone, TimeZoneKey timeZoneKey) { DateTimeZone sourceTimeZone = getDateTimeZone(unpackZoneKey(timeWithTimeZone)); DateTimeZone targetTimeZone = getDateTimeZone(timeZoneKey); long millis = unpackMillisUtc(timeWithTimeZone); // STEP 1. Calculate source UTC millis in session start millis += valueToSessionTimeZoneOffsetDiff(session.getStartTime(), sourceTimeZone); // STEP 2. Calculate target UTC millis in 1970 millis -= valueToSessionTimeZoneOffsetDiff(session.getStartTime(), targetTimeZone); // STEP 3. Make sure that value + offset is in 0 - 23:59:59.999 long localMillis = millis + targetTimeZone.getOffset(0); // Loops up to 2 times in total while (localMillis > TimeUnit.DAYS.toMillis(1)) { millis -= TimeUnit.DAYS.toMillis(1); localMillis -= TimeUnit.DAYS.toMillis(1); } while (localMillis < 0) { millis += TimeUnit.DAYS.toMillis(1); localMillis += TimeUnit.DAYS.toMillis(1); } return packDateTimeWithZone(millis, timeZoneKey); }
@Override public Optional<ConnectorOutputMetadata> finishInsert(ConnectorSession session, ConnectorInsertTableHandle insertHandle, Collection<Slice> fragments, Collection<ComputedStatistics> computedStatistics) { RaptorInsertTableHandle handle = (RaptorInsertTableHandle) insertHandle; long transactionId = handle.getTransactionId(); long tableId = handle.getTableId(); Optional<String> externalBatchId = handle.getExternalBatchId(); List<ColumnInfo> columns = handle.getColumnHandles().stream().map(ColumnInfo::fromHandle).collect(toList()); long updateTime = session.getStartTime(); Collection<ShardInfo> shards = parseFragments(fragments); log.info("Committing insert into tableId %s (queryId: %s, shards: %s, columns: %s)", handle.getTableId(), session.getQueryId(), shards.size(), columns.size()); shardManager.commitShards(transactionId, tableId, columns, shards, externalBatchId, updateTime); clearRollback(); return Optional.empty(); }
private static long timeAtTimeZone(ConnectorSession session, long timeWithTimeZone, TimeZoneKey timeZoneKey) { DateTimeZone sourceTimeZone = getDateTimeZone(unpackZoneKey(timeWithTimeZone)); DateTimeZone targetTimeZone = getDateTimeZone(timeZoneKey); long millis = unpackMillisUtc(timeWithTimeZone); // STEP 1. Calculate source UTC millis in session start millis += valueToSessionTimeZoneOffsetDiff(session.getStartTime(), sourceTimeZone); // STEP 2. Calculate target UTC millis in 1970 millis -= valueToSessionTimeZoneOffsetDiff(session.getStartTime(), targetTimeZone); // STEP 3. Make sure that value + offset is in 0 - 23:59:59.999 long localMillis = millis + targetTimeZone.getOffset(0); // Loops up to 2 times in total while (localMillis > TimeUnit.DAYS.toMillis(1)) { millis -= TimeUnit.DAYS.toMillis(1); localMillis -= TimeUnit.DAYS.toMillis(1); } while (localMillis < 0) { millis += TimeUnit.DAYS.toMillis(1); localMillis += TimeUnit.DAYS.toMillis(1); } return packDateTimeWithZone(millis, timeZoneKey); }
@Description("current timestamp without time zone") @ScalarFunction("localtimestamp") @SqlType(StandardTypes.TIMESTAMP) public static long localTimestamp(ConnectorSession session) { if (session.isLegacyTimestamp()) { return session.getStartTime(); } ISOChronology localChronology = getChronology(session.getTimeZoneKey()); return localChronology.getZone().convertUTCToLocal(session.getStartTime()); }
@Description("current timestamp without time zone") @ScalarFunction("localtimestamp") @SqlType(StandardTypes.TIMESTAMP) public static long localTimestamp(ConnectorSession session) { if (session.isLegacyTimestamp()) { return session.getStartTime(); } ISOChronology localChronology = getChronology(session.getTimeZoneKey()); return localChronology.getZone().convertUTCToLocal(session.getStartTime()); }
@Description("current date") @ScalarFunction @SqlType(StandardTypes.DATE) public static long currentDate(ConnectorSession session) { ISOChronology chronology = getChronology(session.getTimeZoneKey()); // It is ok for this method to use the Object interfaces because it is constant folded during // plan optimization LocalDate currentDate = new DateTime(session.getStartTime(), chronology).toLocalDate(); return Days.daysBetween(new LocalDate(1970, 1, 1), currentDate).getDays(); }
@Description("current date") @ScalarFunction @SqlType(StandardTypes.DATE) public static long currentDate(ConnectorSession session) { ISOChronology chronology = getChronology(session.getTimeZoneKey()); // It is ok for this method to use the Object interfaces because it is constant folded during // plan optimization LocalDate currentDate = new DateTime(session.getStartTime(), chronology).toLocalDate(); return Days.daysBetween(new LocalDate(1970, 1, 1), currentDate).getDays(); }
@Description("current time without time zone") @ScalarFunction("localtime") @SqlType(StandardTypes.TIME) public static long localTime(ConnectorSession session) { if (session.isLegacyTimestamp()) { return UTC_CHRONOLOGY.millisOfDay().get(session.getStartTime()); } ISOChronology localChronology = getChronology(session.getTimeZoneKey()); return localChronology.millisOfDay().get(session.getStartTime()); }
@Description("current timestamp with time zone") @ScalarFunction(value = "current_timestamp", alias = "now") @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) public static long currentTimestamp(ConnectorSession session) { return packDateTimeWithZone(session.getStartTime(), session.getTimeZoneKey()); }
@Description("current timestamp with time zone") @ScalarFunction(value = "current_timestamp", alias = "now") @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) public static long currentTimestamp(ConnectorSession session) { return packDateTimeWithZone(session.getStartTime(), session.getTimeZoneKey()); }
@Description("current time without time zone") @ScalarFunction("localtime") @SqlType(StandardTypes.TIME) public static long localTime(ConnectorSession session) { if (session.isLegacyTimestamp()) { return UTC_CHRONOLOGY.millisOfDay().get(session.getStartTime()); } ISOChronology localChronology = getChronology(session.getTimeZoneKey()); return localChronology.millisOfDay().get(session.getStartTime()); }
long updateTime = session.getStartTime();
@Override public void renameColumn(ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle source, String target) { RaptorTableHandle table = (RaptorTableHandle) tableHandle; RaptorColumnHandle sourceColumn = (RaptorColumnHandle) source; daoTransaction(dbi, MetadataDao.class, dao -> { dao.renameColumn(table.getTableId(), sourceColumn.getColumnId(), target); dao.updateTableVersion(table.getTableId(), session.getStartTime()); }); }
@Description("current time with time zone") @ScalarFunction @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) public static long currentTime(ConnectorSession session) { // We do all calculation in UTC, as session.getStartTime() is in UTC // and we need to have UTC millis for packDateTimeWithZone long millis = UTC_CHRONOLOGY.millisOfDay().get(session.getStartTime()); if (!session.isLegacyTimestamp()) { // However, those UTC millis are pointing to the correct UTC timestamp // Our TIME WITH TIME ZONE representation does use UTC 1970-01-01 representation // So we have to hack here in order to get valid representation // of TIME WITH TIME ZONE millis -= valueToSessionTimeZoneOffsetDiff(session.getStartTime(), getDateTimeZone(session.getTimeZoneKey())); } return packDateTimeWithZone(millis, session.getTimeZoneKey()); }
@Description("current time with time zone") @ScalarFunction @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) public static long currentTime(ConnectorSession session) { // We do all calculation in UTC, as session.getStartTime() is in UTC // and we need to have UTC millis for packDateTimeWithZone long millis = UTC_CHRONOLOGY.millisOfDay().get(session.getStartTime()); if (!session.isLegacyTimestamp()) { // However, those UTC millis are pointing to the correct UTC timestamp // Our TIME WITH TIME ZONE representation does use UTC 1970-01-01 representation // So we have to hack here in order to get valid representation // of TIME WITH TIME ZONE millis -= valueToSessionTimeZoneOffsetDiff(session.getStartTime(), getDateTimeZone(session.getTimeZoneKey())); } return packDateTimeWithZone(millis, session.getTimeZoneKey()); }
@Override public void dropColumn(ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle column) { RaptorTableHandle table = (RaptorTableHandle) tableHandle; RaptorColumnHandle raptorColumn = (RaptorColumnHandle) column; List<TableColumn> existingColumns = dao.listTableColumns(table.getSchemaName(), table.getTableName()); if (existingColumns.size() <= 1) { throw new PrestoException(NOT_SUPPORTED, "Cannot drop the only column in a table"); } long maxColumnId = existingColumns.stream().mapToLong(TableColumn::getColumnId).max().getAsLong(); if (raptorColumn.getColumnId() == maxColumnId) { throw new PrestoException(NOT_SUPPORTED, "Cannot drop the column which has the largest column ID in the table"); } if (getBucketColumnHandles(table.getTableId()).contains(column)) { throw new PrestoException(NOT_SUPPORTED, "Cannot drop bucket columns"); } Optional.ofNullable(dao.getTemporalColumnId(table.getTableId())).ifPresent(tempColumnId -> { if (raptorColumn.getColumnId() == tempColumnId) { throw new PrestoException(NOT_SUPPORTED, "Cannot drop the temporal column"); } }); if (getSortColumnHandles(table.getTableId()).contains(raptorColumn)) { throw new PrestoException(NOT_SUPPORTED, "Cannot drop sort columns"); } daoTransaction(dbi, MetadataDao.class, dao -> { dao.dropColumn(table.getTableId(), raptorColumn.getColumnId()); dao.updateTableVersion(table.getTableId(), session.getStartTime()); }); // TODO: drop column from index table }
@Override public void addColumn(ConnectorSession session, ConnectorTableHandle tableHandle, ColumnMetadata column) { RaptorTableHandle table = (RaptorTableHandle) tableHandle; // Always add new columns to the end. List<TableColumn> existingColumns = dao.listTableColumns(table.getSchemaName(), table.getTableName()); TableColumn lastColumn = existingColumns.get(existingColumns.size() - 1); long columnId = lastColumn.getColumnId() + 1; int ordinalPosition = lastColumn.getOrdinalPosition() + 1; String type = column.getType().getTypeSignature().toString(); daoTransaction(dbi, MetadataDao.class, dao -> { dao.insertColumn(table.getTableId(), columnId, column.getName(), ordinalPosition, type, null, null); dao.updateTableVersion(table.getTableId(), session.getStartTime()); }); shardManager.addColumn(table.getTableId(), new ColumnInfo(columnId, column.getType())); }
public static Session toSession(ConnectorTransactionHandle transactionHandle, ConnectorSession session) { TransactionId transactionId = ((GlobalSystemTransactionHandle) transactionHandle).getTransactionId(); ConnectorIdentity connectorIdentity = session.getIdentity(); Identity identity = new Identity(connectorIdentity.getUser(), connectorIdentity.getPrincipal()); return Session.builder(new SessionPropertyManager(SYSTEM_SESSION_PROPERTIES)) .setQueryId(new QueryId(session.getQueryId())) .setTransactionId(transactionId) .setCatalog("catalog") .setSchema("schema") .setPath(new SqlPath(Optional.of("path"))) .setIdentity(identity) .setTimeZoneKey(session.getTimeZoneKey()) .setLocale(session.getLocale()) .setStartTime(session.getStartTime()) .build(); } }
public static Session toSession(ConnectorTransactionHandle transactionHandle, ConnectorSession session) { TransactionId transactionId = ((GlobalSystemTransactionHandle) transactionHandle).getTransactionId(); ConnectorIdentity connectorIdentity = session.getIdentity(); Identity identity = new Identity(connectorIdentity.getUser(), connectorIdentity.getPrincipal()); return Session.builder(new SessionPropertyManager(SYSTEM_SESSION_PROPERTIES)) .setQueryId(new QueryId(session.getQueryId())) .setTransactionId(transactionId) .setCatalog("catalog") .setSchema("schema") .setPath(new SqlPath(Optional.of("path"))) .setIdentity(identity) .setTimeZoneKey(session.getTimeZoneKey()) .setLocale(session.getLocale()) .setStartTime(session.getStartTime()) .build(); } }