muttakin2301/ccr_train_1000 huggingface dataset:
Code review comment: It was a deliberate decision not to do it using CleanupTimer. Setting the timer is an implementation detail and should be transparent to the CleanupTimer class.

Code before review:
public void setTimer(TimerData timer) {
if (timer.getTimestamp().isAfter(GlobalWindow.INSTANCE.maxTimestamp())) {
if (timer.getTimerId().equals(StatefulDoFnRunner.TimeInternalsCleanupTimer.GC_TIMER_ID)
|| timer.getTimerId().equals(ExecutableStageDoFnOperator.CleanupTimer.GC_TIMER_ID)) {
return;
} else {
throw new IllegalStateException(
"Timer cannot be set past the maximum timestamp: " + timer);
}
}
try {
LOG.debug(
"Setting timer: {} at {} with output time {}",
timer.getTimerId(),
timer.getTimestamp().getMillis(),
timer.getOutputTimestamp().getMillis());
String contextTimerId = getContextTimerId(timer.getTimerId(), timer.getNamespace());
cancelPendingTimerById(contextTimerId);
registerTimer(timer, contextTimerId);
} catch (Exception e) {
throw new RuntimeException("Failed to set timer", e);
}
}

Line under review: if (timer.getTimestamp().isAfter(GlobalWindow.INSTANCE.maxTimestamp())) {

Code after addressing the review:
public void setTimer(TimerData timer) {
try {
LOG.debug(
"Setting timer: {} at {} with output time {}",
timer.getTimerId(),
timer.getTimestamp().getMillis(),
timer.getOutputTimestamp().getMillis());
String contextTimerId = getContextTimerId(timer.getTimerId(), timer.getNamespace());
cancelPendingTimerById(contextTimerId);
registerTimer(timer, contextTimerId);
} catch (Exception e) {
throw new RuntimeException("Failed to set timer", e);
}
}
Code review comment: Ok, it seems to be an IDE-specific thing. I can reproduce the failure when calling the test from the command line: ```bash $ /mvnw -pl flink-runtime test -Dtest=ExecutingTest -Dfast ```

Code before review:
private Executing build(MockExecutingContext ctx) {
executionGraph.transitionToRunning();
try {
return new Executing(
executionGraph,
getExecutionGraphHandler(executionGraph, ctx.getMainThreadExecutor()),
operatorCoordinatorHandler,
log,
ctx,
ClassLoader.getSystemClassLoader(),
new ArrayList<>(),
scalingIntervalMin,
scalingIntervalMax,
lastRescale);
} finally {
Preconditions.checkState(
!ctx.hadStateTransition,
"State construction is an on-going state transition, during which no further transitions are allowed.");
}
}

Line under review: try {

Code after addressing the review:
private Executing build(MockExecutingContext ctx) {
executionGraph.transitionToRunning();
try {
return new Executing(
executionGraph,
getExecutionGraphHandler(executionGraph, ctx.getMainThreadExecutor()),
operatorCoordinatorHandler,
log,
ctx,
ClassLoader.getSystemClassLoader(),
new ArrayList<>(),
scalingIntervalMin,
scalingIntervalMax,
lastRescale);
} finally {
Preconditions.checkState(
!ctx.hadStateTransition,
"State construction is an on-going state transition, during which no further transitions are allowed.");
}
}
Code review comment: I thought about it, but the methods are really small so it's worth decreasing readability here

Code before review:
private JobGraph getStatefulParDoAfterGroupByKeyChainingJobGraph(boolean stablePartitioning) {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
final FlinkStreamingPipelineTranslator translator =
new FlinkStreamingPipelineTranslator(env, PipelineOptionsFactory.create());
final PipelineOptions pipelineOptions = PipelineOptionsFactory.create();
pipelineOptions.setRunner(FlinkRunner.class);
final Pipeline pipeline = Pipeline.create(pipelineOptions);
PCollection<KV<String, Iterable<Long>>> aggregate =
pipeline
.apply(
Create.of(KV.of("foo", 1L), KV.of("bar", 1L))
.withCoder(KvCoder.of(StringUtf8Coder.of(), VarLongCoder.of())))
.apply(GroupByKey.create());
if (!stablePartitioning) {
aggregate = aggregate.apply(ParDo.of(new StatelessIdentityDoFn<>()));
}
aggregate.apply(ParDo.of(new StatefulNoopDoFn<>()));
translator.translate(pipeline);
return env.getStreamGraph().getJobGraph();
}

Line under review: .apply(GroupByKey.create());

Code after addressing the review:
private JobGraph getStatefulParDoAfterGroupByKeyChainingJobGraph(boolean stablePartitioning) {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
final FlinkStreamingPipelineTranslator translator =
new FlinkStreamingPipelineTranslator(env, PipelineOptionsFactory.create());
final PipelineOptions pipelineOptions = PipelineOptionsFactory.create();
pipelineOptions.setRunner(FlinkRunner.class);
final Pipeline pipeline = Pipeline.create(pipelineOptions);
PCollection<KV<String, Iterable<Long>>> aggregate =
pipeline
.apply(
Create.of(KV.of("foo", 1L), KV.of("bar", 1L))
.withCoder(KvCoder.of(StringUtf8Coder.of(), VarLongCoder.of())))
.apply(GroupByKey.create());
if (!stablePartitioning) {
aggregate = aggregate.apply(ParDo.of(new StatelessIdentityDoFn<>()));
}
aggregate.apply(ParDo.of(new StatefulNoopDoFn<>()));
translator.translate(pipeline);
return env.getStreamGraph().getJobGraph();
}
Code review comment: I can't repeat the same thing again.  Read this comment. https://github.com/ballerina-platform/ballerina-lang/pull/10157#discussion_r212197848

Code before review:
public void execute(Context context) {
BMap<String, BValue> socketStruct;
try {
socketStruct = (BMap<String, BValue>) context.getRefArgument(0);
int port = (int) context.getIntArgument(0);
BValue networkInterface = context.getNullableRefArgument(1);
SocketChannel socket = (SocketChannel) socketStruct.getNativeData(SocketConstants.SOCKET_KEY);
if (networkInterface == null) {
socket.bind(new InetSocketAddress(port));
} else {
socket.bind(new InetSocketAddress(networkInterface.stringValue(), port));
}
} catch (IOException e) {
String message = "Error occurred while bind the socket address: " + e.getMessage();
log.error(message, e);
context.setReturnValues(IOUtils.createError(context, message));
}
}

Line under review: String message = "Error occurred while bind the socket address: " + e.getMessage();

Code after addressing the review:
public void execute(Context context) {
BMap<String, BValue> socketStruct;
int port = (int) context.getIntArgument(0);
try {
socketStruct = (BMap<String, BValue>) context.getRefArgument(0);
BValue networkInterface = context.getNullableRefArgument(1);
SocketChannel socket = (SocketChannel) socketStruct.getNativeData(SocketConstants.SOCKET_KEY);
if (networkInterface == null) {
socket.bind(new InetSocketAddress(port));
} else {
socket.bind(new InetSocketAddress(networkInterface.stringValue(), port));
}
} catch (ConnectionPendingException e) {
String message = "Socket initialization already in process. Unable to bind to the port.";
context.setReturnValues(IOUtils.createError(context, message));
} catch (AlreadyBoundException e) {
String message = "Unable to bind to the port: " + port + ". Socket is already bound.";
context.setReturnValues(IOUtils.createError(context, message));
} catch (UnsupportedAddressTypeException e) {
String message = "Socket address doesn't support for a TCP connection.";
context.setReturnValues(IOUtils.createError(context, message));
} catch (ClosedChannelException e) {
String message = "Socket connection is already closed.";
context.setReturnValues(IOUtils.createError(context, message));
} catch (IOException e) {
String message = "Error occurred while bind to the socket address: " + e.getMessage();
log.error(message, e);
context.setReturnValues(IOUtils.createError(context, message));
} catch (SecurityException e) {
String message = "Unknown error occurred.";
log.error(message, e);
context.setReturnValues(IOUtils.createError(context, message));
} catch (Throwable e) {
String message = "An error occurred.";
log.error(message, e);
context.setReturnValues(IOUtils.createError(context, message));
}
}
Code review comment: You will need to update this error message.

Code before review:
public void testMultipleSelectStatementsThrowsException() {
String sql = "SELECT 1; SELECT 2;";
ZetaSQLQueryPlanner zetaSQLQueryPlanner = new ZetaSQLQueryPlanner(config);
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(
"Statement list must end in a SELECT statement, and cannot contain more than one SELECT statement.");
zetaSQLQueryPlanner.convertToBeamRel(sql);
}

Line under review: "Statement list must end in a SELECT statement, and cannot contain more than one SELECT statement.");

Code after addressing the review:
public void testMultipleSelectStatementsThrowsException() {
String sql = "SELECT 1; SELECT 2;";
ZetaSQLQueryPlanner zetaSQLQueryPlanner = new ZetaSQLQueryPlanner(config);
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage("No additional statements are allowed after a SELECT statement.");
zetaSQLQueryPlanner.convertToBeamRel(sql);
}
Code review comment: Yes, it's used in the next commit to persist in-flight data (replaces `notifyBufferReceived`).

Code before review:
public Optional<BufferOrEvent> pollNext() throws IOException, InterruptedException {
Optional<BufferOrEvent> next = inputGate.pollNext();
if (!next.isPresent()) {
return handleEmptyBuffer();
}
BufferOrEvent bufferOrEvent = next.get();
checkState(!barrierHandler.isBlocked(bufferOrEvent.getChannelInfo()));
if (bufferOrEvent.isEvent()) {
handleEvent(bufferOrEvent);
} else {
barrierHandler.processBuffer(bufferOrEvent.getBuffer(), bufferOrEvent.getChannelInfo());
}
return next;
}

Line under review: barrierHandler.processBuffer(bufferOrEvent.getBuffer(), bufferOrEvent.getChannelInfo());

Code after addressing the review:
public Optional<BufferOrEvent> pollNext() throws IOException, InterruptedException {
Optional<BufferOrEvent> next = inputGate.pollNext();
if (!next.isPresent()) {
return handleEmptyBuffer();
}
BufferOrEvent bufferOrEvent = next.get();
checkState(!barrierHandler.isBlocked(bufferOrEvent.getChannelInfo()));
if (bufferOrEvent.isEvent()) {
handleEvent(bufferOrEvent);
}
return next;
}
Code review comment: ```suggestion                                "Unsupported schema version type: %s", ```

Code before review:
public Table getTable(String tableName) {
final ObjectIdentifier identifier =
ObjectIdentifier.of(catalogName, databaseName, tableName);
Optional<ContextResolvedTable> table;
if (getSchemaVersion().isPresent()) {
SchemaVersion schemaVersion = getSchemaVersion().get();
if (schemaVersion instanceof FlinkSchemaVersion.TimestampSchemaVersion) {
FlinkSchemaVersion.TimestampSchemaVersion timestampSchemaVersion =
(FlinkSchemaVersion.TimestampSchemaVersion) getSchemaVersion().get();
table = catalogManager.getTable(identifier, timestampSchemaVersion.getTimestamp());
} else {
throw new UnsupportedOperationException(
String.format(
"Unsupported schema version type, the class is %s",
schemaVersion.getClass()));
}
} else {
table = catalogManager.getTable(identifier);
}
return table.map(
lookupResult ->
new CatalogSchemaTable(
lookupResult,
getStatistic(lookupResult, identifier),
isStreamingMode))
.orElse(null);
}

Line under review: "Unsupported schema version type, the class is %s",

Code after addressing the review:
public Table getTable(String tableName) {
final ObjectIdentifier identifier =
ObjectIdentifier.of(catalogName, databaseName, tableName);
Optional<ContextResolvedTable> table;
if (getSchemaVersion().isPresent()) {
SchemaVersion schemaVersion = getSchemaVersion().get();
if (schemaVersion instanceof TimestampSchemaVersion) {
TimestampSchemaVersion timestampSchemaVersion =
(TimestampSchemaVersion) getSchemaVersion().get();
table = catalogManager.getTable(identifier, timestampSchemaVersion.getTimestamp());
} else {
throw new UnsupportedOperationException(
String.format(
"Unsupported schema version type: %s", schemaVersion.getClass()));
}
} else {
table = catalogManager.getTable(identifier);
}
return table.map(
lookupResult ->
new CatalogSchemaTable(
lookupResult,
getStatistic(lookupResult, identifier),
isStreamingMode))
.orElse(null);
}
Code review comment: ```suggestion         // Reads the next frame when `readyOnConnect` is true or `isReady` is true. ```

Code before review:
public void onSuccess(WebSocketConnection webSocketConnection, HttpCarbonResponse carbonResponse) {
RetryContext retryConfig = null;
if (WebSocketUtil.hasRetryConfig(webSocketClient)) {
retryConfig = (RetryContext) webSocketClient.getNativeData(WebSocketConstants.RETRY_CONFIG);
}
ObjectValue webSocketConnector;
if (retryConfig != null && !retryConfig.isFirstConnectionMadeSuccessfully()) {
webSocketConnector = BallerinaValues.createObjectValue(HttpConstants.PROTOCOL_HTTP_PKG_ID,
WebSocketConstants.WEBSOCKET_CONNECTOR);
} else {
webSocketConnector = (ObjectValue) webSocketClient.get(WebSocketConstants.CLIENT_CONNECTOR_FIELD);
}
setWebSocketClient(webSocketClient, carbonResponse, webSocketConnection, retryConfig);
WebSocketConnectionInfo connectionInfo = getWebSocketOpenConnectionInfo(webSocketConnection,
webSocketConnector,
webSocketClient, wsService);
clientConnectorListener.setConnectionInfo(connectionInfo);
readNextFrame(readyOnConnect, webSocketClient, webSocketConnection, retryConfig);
if (countDownLatch == null) {
countDownForHandshake(webSocketClient);
} else {
countDownLatch.countDown();
}
WebSocketObservabilityUtil.observeConnection(connectionInfo);
logger.debug(WebSocketConstants.LOG_MESSAGE, CONNECTED_TO, webSocketClient.getStringValue(
WebSocketConstants.CLIENT_URL_CONFIG));
if (retryConfig != null) {
setReconnectContexValue(retryConfig);
}
}


Code after addressing the review:
public void onSuccess(WebSocketConnection webSocketConnection, HttpCarbonResponse carbonResponse) {
webSocketClient.set(WebSocketConstants.CLIENT_RESPONSE_FIELD,
HttpUtil.createResponseStruct(carbonResponse));
ObjectValue webSocketConnector = BallerinaValues.createObjectValue(WebSocketConstants.PROTOCOL_HTTP_PKG_ID,
WebSocketConstants.WEBSOCKET_CONNECTOR);
WebSocketConnectionInfo connectionInfo = WebSocketUtil.getWebSocketOpenConnectionInfo(webSocketConnection,
webSocketConnector, webSocketClient, wsService);
WebSocketUtil.populateWebSocketEndpoint(webSocketConnection, webSocketClient);
clientConnectorListener.setConnectionInfo(connectionInfo);
if (readyOnConnect) {
WebSocketUtil.readFirstFrame(webSocketConnection, webSocketClient);
}
countDownLatch.countDown();
WebSocketObservabilityUtil.observeConnection(connectionInfo);
}
Code review comment: :clap: remove repeated and useless :clap: 

Code before review:
public void validate(PipelineOptions pipelineOptions) {
checkState(
hosts() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires a list of hosts to be set via withHosts(hosts)");
checkState(
port() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires a "
+ "valid port number to be set via withPort(port)");
checkState(
keyspace() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires a keyspace to be set via "
+ "withKeyspace(keyspace)");
checkState(
entity() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires an entity to be set via "
+ "withEntity(entity)");
}

Line under review: "CassandraIO."

Code after addressing the review:
public void validate(PipelineOptions pipelineOptions) {
checkState(
hosts() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires a list of hosts to be set via withHosts(hosts)");
checkState(
port() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires a "
+ "valid port number to be set via withPort(port)");
checkState(
keyspace() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires a keyspace to be set via "
+ "withKeyspace(keyspace)");
checkState(
entity() != null,
"CassandraIO."
+ getMutationTypeName()
+ "() requires an entity to be set via "
+ "withEntity(entity)");
}
Code review comment: This feature will do in Support alter materialized view properties or later PR

Code before review:
public static int analyzePartitionRefreshNumber(Map<String, String> properties) throws AnalysisException {
int partitionRefreshNumber = -1;
if (properties != null && properties.containsKey(PROPERTIES_PARTITION_REFRESH_NUMBER)) {
try {
partitionRefreshNumber = Integer.parseInt(properties.get(PROPERTIES_PARTITION_REFRESH_NUMBER));
} catch (NumberFormatException e) {
throw new AnalysisException("Partition Refresh Number: " + e.getMessage());
}
if (partitionRefreshNumber <= 0) {
throw new AnalysisException("Partition Refresh Number should larger than 0.");
}
properties.remove(PROPERTIES_PARTITION_REFRESH_NUMBER);
}
return partitionRefreshNumber;
}

Line under review: throw new AnalysisException("Partition Refresh Number should larger than 0.");

Code after addressing the review:
public static int analyzePartitionRefreshNumber(Map<String, String> properties) throws AnalysisException {
int partitionRefreshNumber = -1;
if (properties != null && properties.containsKey(PROPERTIES_PARTITION_REFRESH_NUMBER)) {
try {
partitionRefreshNumber = Integer.parseInt(properties.get(PROPERTIES_PARTITION_REFRESH_NUMBER));
} catch (NumberFormatException e) {
throw new AnalysisException("Partition Refresh Number: " + e.getMessage());
}
if (partitionRefreshNumber <= 0) {
throw new AnalysisException("Partition Refresh Number should larger than 0.");
}
properties.remove(PROPERTIES_PARTITION_REFRESH_NUMBER);
}
return partitionRefreshNumber;
}
Code review comment: this logic is wired.  why if  the object doesn't `hasProperties` then use `QueryDelimiter` or `PathQueryDelimiter`

Code before review:
public String enhanceConnectionString(Map<String, String> enhancedProperties) {
if (enhancedProperties == null || enhancedProperties.isEmpty()) {
return this.jdbcURL;
}
LOGGER.debug("Trying to enhance url for {}", databaseType);
StringBuilder builder = new StringBuilder(this.jdbcURL);
if (!this.hasProperties()) {
builder.append(databaseType.getPathQueryDelimiter());
} else {
builder.append(databaseType.getQueryDelimiter());
}
for (Map.Entry<String, String> entry : enhancedProperties.entrySet()) {
String key = entry.getKey(), value = entry.getValue();
String valueProvidedInConnectionString = this.getProperty(key);
if (valueProvidedInConnectionString == null) {
builder.append(key)
.append("=")
.append(value)
.append(databaseType.getQueryDelimiter());
} else if (!value.equals(valueProvidedInConnectionString)) {
LOGGER.debug("The property {} is set to another value than default {}", key, value);
throw new IllegalArgumentException("Inconsistent property detected");
} else {
LOGGER.debug("The property {} is already set", key);
}
}
String enhancedUrl = builder.toString();
return enhancedUrl.substring(0, enhancedUrl.length() - 1);
}

Line under review: if (!this.hasProperties()) {

Code after addressing the review:
public String enhanceConnectionString(Map<String, String> enhancedProperties) {
if (enhancedProperties == null || enhancedProperties.isEmpty()) {
return this.jdbcURL;
}
LOGGER.debug("Trying to enhance jdbc url for {}", databaseType);
StringBuilder builder = new StringBuilder(this.jdbcURL);
if (!this.hasProperties()) {
builder.append(databaseType.getPathQueryDelimiter());
} else {
builder.append(databaseType.getQueryDelimiter());
}
for (Map.Entry<String, String> entry : enhancedProperties.entrySet()) {
String key = entry.getKey(), value = entry.getValue();
String valueProvidedInConnectionString = this.getProperty(key);
if (valueProvidedInConnectionString == null) {
builder.append(key)
.append("=")
.append(value)
.append(databaseType.getQueryDelimiter());
} else if (!value.equals(valueProvidedInConnectionString)) {
LOGGER.debug("The property {} is set to another value than default {}", key, value);
throw new IllegalArgumentException("Inconsistent property detected");
} else {
LOGGER.debug("The property {} is already set", key);
}
}
String enhancedUrl = builder.toString();
return enhancedUrl.substring(0, enhancedUrl.length() - 1);
}
Code review comment: Speaking of exceptions (not specific to this line, but in general): for hybrid, are you swallowing (or even logging) cryptographic exceptions from the local crypto client and calling remote?

Code before review:
private void unpackAndValidateId(String keyId) {
if (CoreUtils.isNullOrEmpty(keyId)) {
throw logger.logExceptionAsError(new IllegalArgumentException("Key Id is invalid"));
}
try {
URL url = new URL(keyId);
String[] tokens = url.getPath().split("/");
String endpoint = url.getProtocol() + ":
String keyName = (tokens.length >= 3 ? tokens[2] : null);
String version = (tokens.length >= 4 ? tokens[3] : null);
this.keyCollection = (tokens.length >= 2 ? tokens[1] : null);
if (Strings.isNullOrEmpty(endpoint)) {
throw logger.logExceptionAsError(
new IllegalArgumentException("Key endpoint in key identifier is invalid."));
} else if (Strings.isNullOrEmpty(keyName)) {
throw logger.logExceptionAsError(
new IllegalArgumentException("Key name in key identifier is invalid."));
} else if (Strings.isNullOrEmpty(version)) {
throw logger.logExceptionAsError(
new IllegalArgumentException("Key version in key identifier is invalid."));
}
} catch (MalformedURLException e) {
throw logger.logExceptionAsError(new IllegalArgumentException("The key identifier is malformed.", e));
}
}

Line under review: throw logger.logExceptionAsError(new IllegalArgumentException("The key identifier is malformed.", e));

Code after addressing the review:
private void unpackAndValidateId(String keyId) {
if (CoreUtils.isNullOrEmpty(keyId)) {
throw logger.logExceptionAsError(new IllegalArgumentException("Key Id is invalid"));
}
try {
URL url = new URL(keyId);
String[] tokens = url.getPath().split("/");
String endpoint = url.getProtocol() + ":
String keyName = (tokens.length >= 3 ? tokens[2] : null);
String version = (tokens.length >= 4 ? tokens[3] : null);
this.keyCollection = (tokens.length >= 2 ? tokens[1] : null);
if (Strings.isNullOrEmpty(endpoint)) {
throw logger.logExceptionAsError(
new IllegalArgumentException("Key endpoint in key identifier is invalid."));
} else if (Strings.isNullOrEmpty(keyName)) {
throw logger.logExceptionAsError(
new IllegalArgumentException("Key name in key identifier is invalid."));
} else if (Strings.isNullOrEmpty(version)) {
throw logger.logExceptionAsError(
new IllegalArgumentException("Key version in key identifier is invalid."));
}
} catch (MalformedURLException e) {
throw logger.logExceptionAsError(new IllegalArgumentException("The key identifier is malformed.", e));
}
}
Code review comment: How about assertThat(taskError).withFailMessage("xxx").isNull()?  This class has 3 similar code, LeftOuterJoinTaskTest has 2, and RightOuterJoinTaskTest has 2, please update them if make sense to you.

Code before review:
void testCancelOuterJoinTaskWhileSort1() throws Exception {
setOutput(new DiscardingOutputCollector<Tuple2<Integer, Integer>>());
addDriverComparator(this.comparator1);
addDriverComparator(this.comparator2);
getTaskConfig().setDriverPairComparator(new RuntimePairComparatorFactory());
getTaskConfig().setDriverStrategy(this.getSortDriverStrategy());
getTaskConfig().setRelativeMemoryDriver(this.bnljn_frac);
setNumFileHandlesForSort(4);
final AbstractOuterJoinDriver<
Tuple2<Integer, Integer>,
Tuple2<Integer, Integer>,
Tuple2<Integer, Integer>>
testTask = getOuterJoinDriver();
addInputSorted(
new DelayingIterator<>(new InfiniteIntTupleIterator(), 100),
this.serializer,
this.comparator1.duplicate());
addInput(new DelayingIterator<>(new InfiniteIntTupleIterator(), 100), this.serializer);
final AtomicReference<Throwable> error = new AtomicReference<>();
final Thread taskRunner =
new Thread("Task runner for testCancelOuterJoinTaskWhileSort1()") {
@Override
public void run() {
try {
testDriver(testTask, MockJoinStub.class);
} catch (Throwable t) {
error.set(t);
}
}
};
taskRunner.start();
Thread.sleep(1000);
cancel();
taskRunner.interrupt();
taskRunner.join(60000);
assertThat(taskRunner.isAlive())
.withFailMessage("Task thread did not finish within 60 seconds")
.isFalse();
final Throwable taskError = error.get();
if (taskError != null) {
fail("Error in task while canceling:\n" + Throwables.getStackTraceAsString(taskError));
}
}

Line under review: fail("Error in task while canceling:\n" + Throwables.getStackTraceAsString(taskError));

Code after addressing the review:
void testCancelOuterJoinTaskWhileSort1() throws Exception {
setOutput(new DiscardingOutputCollector<Tuple2<Integer, Integer>>());
addDriverComparator(this.comparator1);
addDriverComparator(this.comparator2);
getTaskConfig().setDriverPairComparator(new RuntimePairComparatorFactory());
getTaskConfig().setDriverStrategy(this.getSortDriverStrategy());
getTaskConfig().setRelativeMemoryDriver(this.bnljn_frac);
setNumFileHandlesForSort(4);
final AbstractOuterJoinDriver<
Tuple2<Integer, Integer>,
Tuple2<Integer, Integer>,
Tuple2<Integer, Integer>>
testTask = getOuterJoinDriver();
addInputSorted(
new DelayingIterator<>(new InfiniteIntTupleIterator(), 100),
this.serializer,
this.comparator1.duplicate());
addInput(new DelayingIterator<>(new InfiniteIntTupleIterator(), 100), this.serializer);
final AtomicReference<Throwable> error = new AtomicReference<>();
final Thread taskRunner =
new Thread("Task runner for testCancelOuterJoinTaskWhileSort1()") {
@Override
public void run() {
try {
testDriver(testTask, MockJoinStub.class);
} catch (Throwable t) {
error.set(t);
}
}
};
taskRunner.start();
Thread.sleep(1000);
cancel();
taskRunner.interrupt();
taskRunner.join(60000);
assertThat(taskRunner.isAlive())
.withFailMessage("Task thread did not finish within 60 seconds")
.isFalse();
assertThat(error.get()).isNull();
}
Code review comment: Unless `entry.getValue()` is pre-sanitized we might want to add some escaping here to ensure our label values are always edible: > `label_value` can be any sequence of UTF-8 characters, but the backslash (`\`), double-quote (`"`), and line feed (`\n`) characters have to be escaped as `\\`, `\"`, and `\n`, respectively

Code before review:
private String toPrometheusDimensions(MetricDimensions dimensions) {
if (dimensions == null) return "";
StringBuilder builder = new StringBuilder();
dimensions.forEach(entry -> {
var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + entry.getValue() + "\",";
builder.append(sanitized);
});
return builder.toString();
}

Line under review: var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + entry.getValue() + "\",";

Code after addressing the review:
private String toPrometheusDimensions(MetricDimensions dimensions) {
if (dimensions == null) return "";
StringBuilder builder = new StringBuilder();
dimensions.forEach(entry -> {
var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + entry.getValue() + "\",";
builder.append(sanitized);
});
return builder.toString();
}
Code review comment: nit: add comments just like getProperties. ditto: isStatisticsEnabled.

Code before review:
public Collection<TickerType> getMonitorTickerTypes() {
return Collections.unmodifiableCollection(monitorTickerTypes);
}

Line under review: return Collections.unmodifiableCollection(monitorTickerTypes);

Code after addressing the review:
public Collection<TickerType> getMonitorTickerTypes() {
return Collections.unmodifiableCollection(monitorTickerTypes);
}
Code review comment: Yes. It's inevitable IMO. Need to go through all elements in a JsonArray object. First `break` is to break iteration of inner loop, when we found the correct element. Second `break` is to break if atleast one of element is non-existent no point of continuing, just breaks outer loop.

Code before review:
private boolean isSubArray(JsonArray subArray, JsonArray array) {
boolean isSubList = true;
for (JsonElement exp : subArray) {
isSubList = false;
for (JsonElement res : array) {
if (exp.equals(res)) {
isSubList = true;
break;
}
}
if (!isSubList) {
break;
}
}
return isSubList;
}

Line under review: if (!isSubList) {

Code after addressing the review:
private boolean isSubArray(JsonArray subArray, JsonArray array) {
boolean isSubList = true;
for (JsonElement exp : subArray) {
isSubList = false;
for (JsonElement res : array) {
if (exp.equals(res)) {
isSubList = true;
break;
}
}
if (!isSubList) {
break;
}
}
return isSubList;
}
Code review comment: would it be worth wrapping the collection in ImmutableList?

Code before review:
private CompositeProvider(List<TranslatorProvider> orderedTranslatorsChain) {
requireNonNull(orderedTranslatorsChain);
this.orderedTranslatorsChain = orderedTranslatorsChain;
}

Line under review: this.orderedTranslatorsChain = orderedTranslatorsChain;

Code after addressing the review:
private CompositeProvider(List<TranslatorProvider> orderedTranslatorsChain) {
requireNonNull(orderedTranslatorsChain);
this.orderedTranslatorsChain = Collections.unmodifiableList(orderedTranslatorsChain);
}
Code review comment: I see, thanks for your clarifications. I misunderstood you here initially. :+1: 

Code before review:
public void testCheckpointRescalingNonPartitionedStateCausesException() throws Exception {
final int parallelism = totalSlots / 2;
final int parallelism2 = totalSlots;
final int maxParallelism = 13;
ClusterClient<?> client = cluster.getClusterClient();
try {
JobGraph jobGraph =
createJobGraphWithOperatorState(
parallelism, maxParallelism, OperatorCheckpointMethod.NON_PARTITIONED);
StateSourceBase.canFinishLatch = new CountDownLatch(1);
final JobID jobID = jobGraph.getJobID();
client.submitJob(jobGraph).get();
waitForAllTaskRunning(cluster.getMiniCluster(), jobGraph.getJobID(), false);
StateSourceBase.workStartedLatch.await();
waitForNewCheckpoint(jobID, cluster.getMiniCluster());
JobResourceRequirements.Builder builder = JobResourceRequirements.newBuilder();
for (JobVertex vertex : jobGraph.getVertices()) {
builder.setParallelismForJobVertex(vertex.getID(), parallelism2, parallelism2);
}
restClusterClient.updateJobResourceRequirements(jobID, builder.build()).join();
waitForRunningTasks(restClusterClient, jobID, 2 * parallelism2);
waitForAvailableSlots(restClusterClient, totalSlots - parallelism2);
StateSourceBase.canFinishLatch.countDown();
client.requestJobResult(jobID).get();
} catch (JobExecutionException exception) {
if (!(exception.getCause() instanceof IllegalStateException)) {
throw exception;
}
}
}

Line under review: waitForRunningTasks(restClusterClient, jobID, 2 * parallelism2);

Code after addressing the review:
public void testCheckpointRescalingNonPartitionedStateCausesException() throws Exception {
final int parallelism = totalSlots / 2;
final int parallelism2 = totalSlots;
final int maxParallelism = 13;
ClusterClient<?> client = cluster.getClusterClient();
try {
JobGraph jobGraph =
createJobGraphWithOperatorState(
parallelism, maxParallelism, OperatorCheckpointMethod.NON_PARTITIONED);
StateSourceBase.canFinishLatch = new CountDownLatch(1);
final JobID jobID = jobGraph.getJobID();
client.submitJob(jobGraph).get();
waitForAllTaskRunning(cluster.getMiniCluster(), jobGraph.getJobID(), false);
StateSourceBase.workStartedLatch.await();
waitForNewCheckpoint(jobID, cluster.getMiniCluster());
JobResourceRequirements.Builder builder = JobResourceRequirements.newBuilder();
for (JobVertex vertex : jobGraph.getVertices()) {
builder.setParallelismForJobVertex(vertex.getID(), parallelism2, parallelism2);
}
restClusterClient.updateJobResourceRequirements(jobID, builder.build()).join();
waitForRunningTasks(restClusterClient, jobID, 2 * parallelism2);
waitForAvailableSlots(restClusterClient, totalSlots - parallelism2);
StateSourceBase.canFinishLatch.countDown();
client.requestJobResult(jobID).get();
} catch (JobExecutionException exception) {
if (!(exception.getCause() instanceof IllegalStateException)) {
throw exception;
}
}
}
Code review comment: Does it work to simply write Collections.sort(fields, Comparator.comparing(FieldDescriptor::getFieldId))?  We needed the verbose version before because it was captured inside the Set class, so had to be serializable. I suspect we can drop back to the simple version now.

Code before review:
private List<FieldDescriptor> resolveDirectFieldsAccessed(Schema schema) {
List<FieldDescriptor> fields = new ArrayList<>();
for (FieldDescriptor field : getFieldsAccessed()) {
validateFieldDescriptor(schema, field);
if (field.getFieldId() == null) {
field = field.toBuilder().setFieldId(schema.indexOf(field.getFieldName())).build();
}
if (field.getFieldName() == null) {
field = field.toBuilder().setFieldName(schema.nameOf(field.getFieldId())).build();
}
field = fillInMissingQualifiers(field, schema);
fields.add(field);
}
if (!getFieldInsertionOrder()) {
Function<FieldDescriptor, Integer> extract =
(Function<FieldDescriptor, Integer> & Serializable) FieldDescriptor::getFieldId;
Collections.sort(fields, Comparator.comparing(extract));
}
return fields;
}

Line under review: Collections.sort(fields, Comparator.comparing(extract));

Code after addressing the review:
private List<FieldDescriptor> resolveDirectFieldsAccessed(Schema schema) {
List<FieldDescriptor> fields = new ArrayList<>();
for (FieldDescriptor field : getFieldsAccessed()) {
validateFieldDescriptor(schema, field);
if (field.getFieldId() == null) {
field = field.toBuilder().setFieldId(schema.indexOf(field.getFieldName())).build();
}
if (field.getFieldName() == null) {
field = field.toBuilder().setFieldName(schema.nameOf(field.getFieldId())).build();
}
field = fillInMissingQualifiers(field, schema);
fields.add(field);
}
if (!getFieldInsertionOrder()) {
Collections.sort(fields, Comparator.comparing(FieldDescriptor::getFieldId));
}
return fields;
}
Code review comment: Put the error message into ErrorCode.java

Code before review:
private static void preCheckColumnRef(CreateTableStmt statement) {
List<ColumnDef> columnDefs = statement.getColumnDefs();
if (columnDefs == null || columnDefs.isEmpty()) {
ErrorReport.reportSemanticException(ErrorCode.ERR_TABLE_MUST_HAVE_COLUMNS);
}
if (columnDefs.size() > Config.max_column_number_per_table) {
throw new SemanticException("The number of columns in a table must be less than or equal to %d,"
+ " Please decrease the number of columns or increase frontend config 'max_column_number_per_table'.",
Config.max_column_number_per_table);
}
Set<String> columnSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
for (ColumnDef columnDef : columnDefs) {
if (!columnSet.add(columnDef.getName())) {
ErrorReport.reportSemanticException(ErrorCode.ERR_DUP_FIELDNAME, columnDef.getName());
}
if (columnDef.getAggregateType() != null && columnDef.getAggregateType().isReplaceFamily()) {
statement.setHasReplace(true);
}
if (columnDef.isGeneratedColumn()) {
statement.setHasGeneratedColumn(true);
}
}
}

Line under review: throw new SemanticException("The number of columns in a table must be less than or equal to %d,"

Code after addressing the review:
private static void preCheckColumnRef(CreateTableStmt statement) {
List<ColumnDef> columnDefs = statement.getColumnDefs();
if (columnDefs == null || columnDefs.isEmpty()) {
ErrorReport.reportSemanticException(ErrorCode.ERR_TABLE_MUST_HAVE_COLUMNS);
}
if (columnDefs.size() > Config.max_column_number_per_table) {
ErrorReport.reportSemanticException(ErrorCode.ERR_TOO_MANY_COLUMNS, Config.max_column_number_per_table);
}
Set<String> columnSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
for (ColumnDef columnDef : columnDefs) {
if (!columnSet.add(columnDef.getName())) {
ErrorReport.reportSemanticException(ErrorCode.ERR_DUP_FIELDNAME, columnDef.getName());
}
if (columnDef.getAggregateType() != null && columnDef.getAggregateType().isReplaceFamily()) {
statement.setHasReplace(true);
}
if (columnDef.isGeneratedColumn()) {
statement.setHasGeneratedColumn(true);
}
}
}
Code review comment: Can you explain why the deadlock is triggered? I'm missing some context.

Code before review:
public void reserveSegments(int numberOfSegmentsToReserve) throws IOException {
checkArgument(
numberOfSegmentsToReserve <= minNumberOfMemorySegments,
"Can not reserve more segments than number of minimum segments.");
CompletableFuture<?> toNotify = null;
int numSegmentsNeeded;
synchronized (availableMemorySegments) {
checkDestroyed();
numSegmentsNeeded = numberOfSegmentsToReserve - numberOfRequestedMemorySegments;
}
if (numSegmentsNeeded > 0) {
List<MemorySegment> segments =
networkBufferPool.requestPooledMemorySegmentsBlocking(numSegmentsNeeded);
synchronized (availableMemorySegments) {
availableMemorySegments.addAll(segments);
toNotify = availabilityHelper.getUnavailableToResetAvailable();
}
}
mayNotifyAvailable(toNotify);
}

Line under review: if (numSegmentsNeeded > 0) {

Code after addressing the review:
public void reserveSegments(int numberOfSegmentsToReserve) throws IOException {
checkArgument(
numberOfSegmentsToReserve <= minNumberOfMemorySegments,
"Can not reserve more segments than number of minimum segments.");
CompletableFuture<?> toNotify = null;
int numSegmentsNeeded;
synchronized (availableMemorySegments) {
checkDestroyed();
numSegmentsNeeded = numberOfSegmentsToReserve - numberOfRequestedMemorySegments;
}
if (numSegmentsNeeded > 0) {
List<MemorySegment> segments =
networkBufferPool.requestPooledMemorySegmentsBlocking(numSegmentsNeeded);
synchronized (availableMemorySegments) {
availableMemorySegments.addAll(segments);
toNotify = availabilityHelper.getUnavailableToResetAvailable();
}
}
mayNotifyAvailable(toNotify);
}
Code review comment: @steveniemitz Please follow up with a separate PR if this is not addressed.

Code before review:
public List<String> detect(ClassLoader classLoader) {
List<File> classpathContents =
classGraph
.disableNestedJarScanning()
.addClassLoader(classLoader)
.scan(1)
.getClasspathFiles();
return classpathContents.stream().map(File::getAbsolutePath).collect(Collectors.toList());
}

Line under review: .scan(1)

Code after addressing the review:
public List<String> detect(ClassLoader classLoader) {
List<File> classpathContents =
classGraph
.disableNestedJarScanning()
.addClassLoader(classLoader)
.scan(1)
.getClasspathFiles();
return classpathContents.stream().map(File::getAbsolutePath).collect(Collectors.toList());
}
Code review comment: en, don't effect, because analyze will use real name

Code before review:
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!super.equals(o)) {
return false;
}
SubfieldExpr that = (SubfieldExpr) o;
return Objects.equals(fieldNames, that.fieldNames);
}

Line under review: return Objects.equals(fieldNames, that.fieldNames);

Code after addressing the review:
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!super.equals(o)) {
return false;
}
SubfieldExpr that = (SubfieldExpr) o;
return Objects.equals(fieldNames, that.fieldNames);
}
Code review comment: We can add a negative test like  ```ballerina     record {         byte i;         int j?;     } rec = let int v = 160 in {i: v}; ```  Without this fix, the error was something like ``` incompatible types: expected 'record {| byte i; int j?; anydata...; |}', found 'record {| int i; |}' ```  With this fix I believe it'll be something like ``` incompatible types: expected 'byte', found 'int' ```

Code before review:
public void testLetExpressionNegative() {
int i = 0;
BAssertUtil.validateError(negativeResult, i++, "redeclared symbol 'x'", 19, 21);
BAssertUtil.validateError(negativeResult, i++, "undefined symbol 'y'", 23, 27);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'string'", 27, 25);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'string'", 28, 39);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'string', found 'int'", 29, 28);
BAssertUtil.validateError(negativeResult, i, "incompatible types: expected 'string', found 'int'", 30, 42);
}

Line under review: BAssertUtil.validateError(negativeResult, i, "incompatible types: expected 'string', found 'int'", 30, 42);

Code after addressing the review:
public void testLetExpressionNegative() {
int i = 0;
BAssertUtil.validateError(negativeResult, i++, "redeclared symbol 'x'", 19, 21);
BAssertUtil.validateError(negativeResult, i++, "undefined symbol 'y'", 23, 27);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'string'", 27, 25);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'string'", 28, 39);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'string', found 'int'", 29, 28);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'string', found 'int'", 30, 42);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'byte', found 'int'", 41, 37);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'string'", 46, 48);
BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'float'", 48, 14);
BAssertUtil.validateError(negativeResult, i, "too many arguments in call to 'new()'", 57, 37);
}
Code review comment: No biggie but maybe the null check could be the first statement to check in this `if-else` chain

Code before review:
public CompletionStage<ResultNode> resolve(SectionResolutionContext context) {
return context.resolutionContext().evaluate(iterable).thenCompose(it -> {
List<CompletionStage<ResultNode>> results = new ArrayList<>();
Iterator<?> iterator;
if (it instanceof Iterable) {
iterator = ((Iterable<?>) it).iterator();
} else if (it instanceof Iterator) {
iterator = (Iterator<?>) it;
} else if (it instanceof Map) {
iterator = ((Map<?, ?>) it).entrySet().iterator();
} else if (it instanceof Stream) {
iterator = ((Stream<?>) it).sequential().iterator();
} else if (it instanceof Integer) {
iterator = IntStream.rangeClosed(1, (Integer) it).iterator();
} else if (it != null && it.getClass().isArray()) {
iterator = Arrays.stream((Object[]) it).iterator();
} else {
throw new IllegalStateException(
String.format("Cannot iterate over [%s] resolved for [%s] in template %s on line %s", it,
iterable.toOriginalString(), iterable.origin.getTemplateId(), iterable.origin.getLine()));
}
int idx = 0;
while (iterator.hasNext()) {
results.add(nextElement(iterator.next(), idx++, iterator.hasNext(), context));
}
if (results.isEmpty()) {
return CompletableFuture.completedFuture(ResultNode.NOOP);
}
CompletableFuture<ResultNode> result = new CompletableFuture<>();
CompletableFuture<ResultNode>[] all = new CompletableFuture[results.size()];
idx = 0;
for (CompletionStage<ResultNode> r : results) {
all[idx++] = r.toCompletableFuture();
}
CompletableFuture
.allOf(all)
.whenComplete((v, t) -> {
if (t != null) {
result.completeExceptionally(t);
} else {
result.complete(new MultiResultNode(all));
}
});
return result;
});
}

Line under review: } else if (it != null && it.getClass().isArray()) {

Code after addressing the review:
public CompletionStage<ResultNode> resolve(SectionResolutionContext context) {
return context.resolutionContext().evaluate(iterable).thenCompose(it -> {
if (it == null) {
throw new TemplateException(String.format(
"Loop section error in template %s on line %s: [%s] resolved to [null] which is not iterable",
iterable.origin.getTemplateId(), iterable.origin.getLine(), iterable.toOriginalString()));
}
List<CompletionStage<ResultNode>> results = new ArrayList<>();
Iterator<?> iterator = extractIterator(it);
int idx = 0;
while (iterator.hasNext()) {
results.add(nextElement(iterator.next(), idx++, iterator.hasNext(), context));
}
if (results.isEmpty()) {
return CompletableFuture.completedFuture(ResultNode.NOOP);
}
CompletableFuture<ResultNode> result = new CompletableFuture<>();
CompletableFuture<ResultNode>[] all = new CompletableFuture[results.size()];
idx = 0;
for (CompletionStage<ResultNode> r : results) {
all[idx++] = r.toCompletableFuture();
}
CompletableFuture
.allOf(all)
.whenComplete((v, t) -> {
if (t != null) {
result.completeExceptionally(t);
} else {
result.complete(new MultiResultNode(all));
}
});
return result;
});
}
Code review comment: is there a lib in java like URL in C# that does this for us? 

Code before review:
private String getHostNameFromEndpoint() {
return endpoint.replace("https:
}

Line under review: return endpoint.replace("https:

Code after addressing the review:
private String getHostNameFromEndpoint() throws MalformedURLException {
return new URL(endpoint).getHost();
}
Code review comment: Could probably use auto-(un)boxing  of bools for these if desired, i.e. `if (alreadySending && ...)`, `isSending.set(true)`. etc

Code before review:
private void sendNextInSequence(long seqId) {
Message msg = null;
synchronized (this) {
Queue<Message> queue = seqMap.get(seqId);
if (queue == null || queue.isEmpty()) {
seqMap.remove(seqId);
} else {
msg = queue.remove();
}
}
if (msg != null) {
Boolean alreadySending = isSending.get();
if ((alreadySending == Boolean.TRUE) && (msn != null)) {
msn.enqueue(new SequencedSendTask(msg));
} else {
isSending.set(Boolean.TRUE);
sequencedSend(msg);
}
isSending.set(Boolean.FALSE);
}
}

Line under review: if ((alreadySending == Boolean.TRUE) && (msn != null)) {

Code after addressing the review:
private void sendNextInSequence(long seqId) {
Message msg = null;
synchronized (this) {
Queue<Message> queue = seqMap.get(seqId);
if (queue == null || queue.isEmpty()) {
seqMap.remove(seqId);
} else {
msg = queue.remove();
}
}
if (msg != null) {
Boolean alreadySending = isSending.get();
if (alreadySending && (msn != null)) {
msn.enqueue(new SequencedSendTask(msg));
} else {
isSending.set(Boolean.TRUE);
sequencedSend(msg);
}
isSending.set(Boolean.FALSE);
}
}
Code review comment: File reading will have problems when packaged into jar

Code before review:
public byte[] toConfigurationBytes() {
try (InputStream stream = inClasspath ? ShardingSphereDriverURL.class.getResourceAsStream("/" + file) : Files.newInputStream(new File(file).toPath())) {
LineProcessor<byte[]> lineProcessor = new LineProcessor<byte[]>() {
private final StringBuilder builder = new StringBuilder();
@Override
public boolean processLine(final String line) {
if (line.startsWith("
return true;
}
builder.append(line);
return true;
}
@Override
public byte[] getResult() {
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
};
final byte[] result = CharStreams.readLines(new InputStreamReader(stream, Charsets.UTF_8), lineProcessor);
Objects.requireNonNull(stream, String.format("Can not find configuration file `%s`.", file)).read(result);
return result;
}
}


Code after addressing the review:
public byte[] toConfigurationBytes() {
try (InputStream stream = inClasspath ? ShardingSphereDriverURL.class.getResourceAsStream("/" + file) : Files.newInputStream(new File(file).toPath())) {
Objects.requireNonNull(stream, String.format("Can not find configuration file `%s`.", file));
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("
builder.append(line);
}
}
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
}
Code review comment: Is this really necessary? I vaguely remember removing this because it was deprecated.

Code before review:
public EntityManagerFactory build() {
try {
final SessionFactoryOptionsBuilder optionsBuilder = metadata.buildSessionFactoryOptionsBuilder();
populate(persistenceUnitName, optionsBuilder, standardServiceRegistry);
return new SessionFactoryImpl(metadata, optionsBuilder.buildOptions(),
metadata.getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext());
} catch (Exception e) {
throw persistenceException("Unable to build Hibernate SessionFactory", e);
}
}

Line under review: metadata.getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext());

Code after addressing the review:
public EntityManagerFactory build() {
try {
final SessionFactoryOptionsBuilder optionsBuilder = metadata.buildSessionFactoryOptionsBuilder();
populate(persistenceUnitName, optionsBuilder, standardServiceRegistry);
return new SessionFactoryImpl(metadata, optionsBuilder.buildOptions(),
metadata.getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext());
} catch (Exception e) {
throw persistenceException("Unable to build Hibernate SessionFactory", e);
}
}
Code review comment: Any news on this one? It looks like you didn't update the PR, is it because `@JdbcTypeCode` didn't work?

Code before review:
public Duration getLatestLunchBreakDuration() {
return latestLunchBreakDuration;
}

Line under review: return latestLunchBreakDuration;

Code after addressing the review:
public Duration getLatestLunchBreakDuration() {
return latestLunchBreakDuration;
}