auphong2707/dl4se-code-review-dataset huggingface dataset:
Source:
public ConnectorBucketNodeMap getBucketNodeMap(ConnectorTransactionHandle transactionHandle, ConnectorSession session, ConnectorPartitioningHandle partitioningHandle) { Set<Node> nodes = nodeManager.getRequiredWorkerNodes(); checkState(!nodes.isEmpty(), "No TPCH nodes available"); // Split the data using split and skew by the number of nodes available. return createBucketNodeMap(toIntExact((long)nodes.size() * splitsPerNode)); }

Target:
`nodeManager.getRequiredWorkerNodes();` never returns an empty set
Source:
public void onLifespanFinished(Iterable<Lifespan> newlyCompletedDriverGroups) { checkState(initialScheduled); SettableFuture<?> newDriverGroupReady = this.newDriverGroupReady; synchronized (this) { for (Lifespan newlyCompletedDriverGroup : newlyCompletedDriverGroups) { checkArgument(!newlyCompletedDriverGroup.isTaskWide()); recentlyCompletedDriverGroups.add(newlyCompletedDriverGroup); } } newDriverGroupReady.set(null); }

Target:
I'm pretty sure that the setting of this local variable must happen within the synchronized block, and maybe at the old location the set was happening (not sure about the state machine), otherwise, you may observe an old stale value. Also, I'd merge this change into the commit that creates these classes.
Source:
public ConnectorBucketNodeMap getBucketNodeMap(ConnectorTransactionHandle transactionHandle, ConnectorSession session, ConnectorPartitioningHandle partitioningHandle) { // create one bucket per node return createBucketNodeMap( nodeManager.getRequiredWorkerNodes().size(), value -> { throw new PrestoException(NOT_SUPPORTED, "Black hole connector does not supported distributed reads"); }); }

Target:
consider making this change in the commit that introduced `ConnectorBucketNodeMap`
Source:
public QuantileDigestAggregationFunction(TypeSignature... typeSignatures) { super(NAME, ImmutableList.of(comparableTypeParameter("V")), ImmutableList.of(), parseTypeSignature("qdigest(V)"), ImmutableList.copyOf(typeSignatures)); }

Target:
make this private
Source:
protected Optional<PlanNodeStatsEstimate> visitNotExpression(NotExpression node, Void context) { if (node.getValue() instanceof IsNullPredicate) { return process(new IsNotNullPredicate(((IsNullPredicate) node.getValue()).getValue())); } return process(node.getValue()).map(estimate -> differenceInStats(input, estimate)); }

Target:
Why not get rid of `Optional` here either (as in `ComparisonCalculator`)?
Source:
public ThriftIndexHandle( @JsonProperty("schemaTableName") SchemaTableName schemaTableName, @JsonProperty("tupleDomain") TupleDomain<ColumnHandle> tupleDomain) { this.schemaTableName = requireNonNull(schemaTableName, "schemaTableName is null"); this.tupleDomain = requireNonNull(tupleDomain, "tupleDomain is null"); this.session = Optional.empty(); }

Target:
Is this only used on workers?
Source:
public MemoryEstimate visitIndexJoin(IndexJoinNode node, EstimationContext context) { PlanCostEstimate sourcesCost = context.sourcesCosts.stream() .reduce(PlanCostEstimate.zero(), CachingCostProvider::addSiblingsCost); return new MemoryEstimate( sourcesCost.getMaxMemory(), context.localMaxMemory + sourcesCost.getMaxMemoryWhenOutputting()); }

Target:
can you explain this?
Source:
List<Page> generateTestData() { List<Type> typesArray = new ArrayList<>(); int currentPartitionIdentifier = 1; typesArray.add(BIGINT); typesArray.add(BIGINT); typesArray.add(BIGINT); typesArray.add(BIGINT); RowPagesBuilder pagesBuilder = buildPages(currentPartitionIdentifier, typesArray); return pagesBuilder.build(); }

Target:
Private?
Source:
public boolean equals(Object o) { new RuntimeException("partitioningHandle equals").printStackTrace(); if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } HivePartitionHandle that = (HivePartitionHandle) o; return bucket == that.bucket; }

Target:
I imagine this was leftover from debugging?
Source:
public void abort() { // rollback and close try (Connection connection = this.connection; PreparedStatement statement = this.statement) { connection.rollback(); } catch (SQLException e) { throw new PrestoException(JDBC_ERROR, e); } finally { try { jdbcClient.rollbackCreateTable(handle); } catch (Exception e) { log.warn(e, format("Failed to cleanup temporary table: %s", handle.getTemporaryTableName())); } } }

Target:
why is this needed if whole transaction is rollbacked, then table should be dropped as well, am I right? Also `JdbcPageSink` has not created this table, it looks fishy that it drops this.
Source:
private static Connector createTestSessionConnector() { return new Connector() { @Override public ConnectorTransactionHandle beginTransaction(IsolationLevel isolationLevel, boolean readOnly) { return new ConnectorTransactionHandle() {}; } @Override public ConnectorMetadata getMetadata(ConnectorTransactionHandle transaction) { return new TestingConnectorMetadata(new SystemTablesMetadata(new ConnectorId("test_session_connector"), new StaticSystemTablesProvider(ImmutableSet.of()))); } @Override public ConnectorSplitManager getSplitManager() { throw new UnsupportedOperationException(); } }; }

Target:
Why do we need to wrap it in a TestingConnectorMetadata (which seems do nothing but call the delegated connectorMetadata).
Source:
private static Statement parseFormatted(SqlParser sqlParser, ParsingOptions parsingOptions, String sql, Node tree) { try { return sqlParser.createStatement(sql, parsingOptions); } catch (ParsingException e) { String error = format("failed to parse formatted SQL: %s\nerror: %s\ntree: %s", sql, e.getMessage(), tree); throw new AssertionError(error, e); } }

Target:
I would inline error. Up to you.
Source:
public void createTable(ConnectorSession session, ConnectorTableMetadata tableMetadata, boolean ignoreExisting) { JdbcOutputTableHandle handle = jdbcClient.beginCreateTable(tableMetadata, ignoreExisting); finishCreateTable(session, handle, emptyList(), emptyList()); }

Target:
If we fail to finish (rename) the table, we leave a temp table behind. Am i right?
Source:
public void createTable(ConnectorSession session, ConnectorTableMetadata tableMetadata, boolean ignoreExisting) { JdbcOutputTableHandle handle = jdbcClient.beginCreateTable(tableMetadata); finishCreateTable(session, handle, emptyList(), emptyList()); }

Target:
We probably had the JDBC connector before INSERT support, so creating an empty table would not have been useful. But I don't remember for sure. The shorter answer is that no one needed it.
Source:
public void createTable(ConnectorTableMetadata tableMetadata) { try { createTable(tableMetadata, tableMetadata.getTable().getTableName()); } catch (SQLException e) { if (DUPLICATE_TABLE_SQLSTATE.equals(e.getSQLState())) { throw new PrestoException(ALREADY_EXISTS, e); } else { throw new PrestoException(JDBC_ERROR, e); } } }

Target:
Nit: else is redundant
Source:
SymbolStatistics(String symbolName, SymbolStatsEstimate estimate) { this.symbol = new Symbol(symbolName); this.estimate = estimate; }

Target:
`this(new Symbol(symbolName), estimate)`
Source:
public final void readFully(long position, byte[] buffer, int bufferOffset, int bufferLength) { readBytes += bufferLength; long readStart = System.nanoTime(); readInternal(position, buffer, bufferOffset, bufferLength); long currentReadTimeNanos = System.nanoTime() - readStart; readTimeNanos += currentReadTimeNanos; stats.readDataBytesPerSecond(bufferLength, currentReadTimeNanos); }

Target:
That’s simpler, for sure. But there’s no benefit to using StopWatch and having a dependency on external code in this case when the alternative is trivial.
Source:
private <T> T runWithHandle(ThrowingSupplier<T> supplier) throws TException { try { T t = supplier.get(); responseHandle.success(); return t; } catch (TException e) { responseHandle.failed(e); throw e; } }

Target:
nit: move this after `catch`, so that `.success()` failure doesn't trigger `failed()` ``` T t; try { t = supplier.get(); } catch (TException e) { responseHandle.failed(e); throw e; } responseHandle.success(); return t; ```
Source:
public PlanNodeStatsEstimate( @JsonProperty("outputRowCount") double outputRowCount, @JsonProperty("symbolStatistics") Map<Symbol, SymbolStatsEstimate> symbolStatistics) { checkArgument(isNaN(outputRowCount) || outputRowCount >= 0, "outputRowCount cannot be negative"); this.outputRowCount = outputRowCount; this.symbolStatistics = HashTreePMap.from(requireNonNull(symbolStatistics, "symbolStatistics is null")); }

Target:
nit: Just do `this(outputRowCount, HashTreePMap.from(requireNonNull(symbolStatistics, "symbolStatistics is null")))` to avoud copy pasting the argument checks
Source:
private PlanNodeCostEstimate calculateCumulativeCost(PlanNode node) { PlanNodeCostEstimate localCosts = costCalculator.calculateCost(node, statsProvider, noLookup(), session, types); PlanNodeCostEstimate sourcesCost = node.getSources().stream() .map(this::getCumulativeCost) .reduce(ZERO_COST, PlanNodeCostEstimate::add); PlanNodeCostEstimate cumulativeCost = localCosts.add(sourcesCost); return cumulativeCost; }

Target:
Inline
Source:
public void doesNotFire() { RuleApplication ruleApplication = applyRule(); if (ruleApplication.wasRuleApplied()) { fail(String.format( "Expected %s to not fire for:\n%s", rule.getClass().getName(), inTransaction(session -> textLogicalPlan(plan, ruleApplication.types, metadata.getFunctionRegistry(), new StatsAndCosts(ImmutableMap.of(), ImmutableMap.of()), session, 2)))); } }

Target:
`StatsAndCosts.empty()`
Source:
private PlanNodeCostEstimate calculateCumulativeCost(PlanNode node) { PlanNodeCostEstimate localCosts = costCalculator.calculateCost(node, statsProvider, session, types); PlanNodeCostEstimate sourcesCost = node.getSources().stream() .map(this::getCumulativeCost) .reduce(ZERO_COST, PlanNodeCostEstimate::add); PlanNodeCostEstimate cumulativeCost = costCalculator.calculateCost(node, statsProvider, session, types).add(sourcesCost); return cumulativeCost; }

Target:
Remove this
Source:
private PlanNodeCostEstimate calculateCumulativeCost(PlanNode node) { PlanNodeCostEstimate sourcesCost = node.getSources().stream() .map(this::getCumulativeCost) .reduce(ZERO_COST, PlanNodeCostEstimate::add); PlanNodeCostEstimate cumulativeCost = costCalculator.calculateCost(node, statsProvider, noLookup(), session, types).add(sourcesCost); return cumulativeCost; }

Target:
inline this
Source:
public static Slice stConvexHull(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { OGCGeometry geometry = deserialize(input); if (geometry.isEmpty()) { return input; } if (GeometryType.getForEsriGeometryType(geometry.geometryType()) == POINT) { return input; } OGCGeometry convexHull = geometry.convexHull(); return serialize(convexHull); }

Target:
nit: inline this variable
Source:
public void testDefaultAcl() throws Exception { Configuration config = new Configuration(); try (PrestoS3FileSystem fs = new PrestoS3FileSystem()) { MockAmazonS3 s3 = new MockAmazonS3(); String expectedBucketName = "test-bucket"; fs.initialize(new URI("s3n://" + expectedBucketName + "/"), config); fs.setS3Client(s3); FSDataOutputStream stream = fs.create(new Path("s3n://test-bucket/test")); stream.close(); assertEquals(CannedAccessControlList.Private, s3.getAcl()); } }

Target:
You can also do ``` try (FSDataOutputStream stream = fs.create(new Path("s3n://test-bucket/test"))) { assertEquals(CannedAccessControlList.Private, s3.getAcl()); } ```
Source:
private static Iterable<Slice> getGeometrySlicesFromBlock(Block block) { requireNonNull(block, "block is null"); return () -> new Iterator<Slice>() { private final int blockPositionCount = block.getPositionCount(); private int iteratorPosition; @Override public boolean hasNext() { return iteratorPosition != blockPositionCount; } @Override public Slice next() { if (!hasNext()) { throw new NoSuchElementException("Slices have been consumed"); } return GEOMETRY.getSlice(block, iteratorPosition++); } }; }

Target:
Why not call `block.getPositionCount()` here instead of having a `final` variable? Does it make any diff in perf?
Source:
private String randomTwoChoices() { // Randomly pick 2 different candidates and select the less loaded one int randomPosition = ThreadLocalRandom.current().nextInt(activeNodes.size()); int randomOffset = ThreadLocalRandom.current().nextInt(1, activeNodes.size()); String candidate1 = activeNodes.get(randomPosition); String candidate2 = activeNodes.get((randomPosition + randomOffset) % activeNodes.size()); if (nodeBucketCounts.get(candidate2) < nodeBucketCounts.get(candidate1)) { candidate1 = candidate2; } return candidate1; }

Target:
I think this would be a bit easier to read as ```java return (nodeBucketCounts.get(candidate1) <= nodeBucketCounts.get(candidate2)) ? candidate1 : candidate2; ``` The assignment looks strange
Source:
public int getBufferedBytes() { return toIntExact((rowCount * otherColumnsBytesPerRow) + dictionaryColumns.stream() .mapToLong(TestDictionaryColumn::getBufferedBytes) .sum()); }

Target:
Consider making the method return long instead
Source:
public List<? extends Node> getChildren() { return ImmutableList.<Node>builder() .addAll(properties).build(); }

Target:
- what about the `table`? - move `.build()` to separate line
Source:
YieldingIterator(WorkProcessor<T> processor) { this.processor = requireNonNull(processor, "processorParameter is null"); }

Target:
`@Nullable` `private`
Source:
ProcessWorkProcessor(WorkProcessor.Process<T> process) { this.process = requireNonNull(process, "process is null"); }

Target:
no need for Optional, it wouldn't make the code more readable. What about NEEDS_MORE_DATA as the initial state? (i don't insist)
Source:
public void getSetBits(int batchSize, boolean[] vector) throws IOException { for (int i = 0; i < batchSize; i++) { vector[i] = nextBit(); } }

Target:
Tough call. I'd say if we don't need it now, then let's not add it. We can always throw it in later.
Source:
private static RowGroupStatistics buildActualRowGroupStatistics(int rowGroupIndex, Map<StreamId, List<RowGroupIndex>> actualRowGroupStatistics) { return new RowGroupStatistics( BOTH, actualRowGroupStatistics.entrySet() .stream() .collect(Collectors.toMap((entry) -> entry.getKey().getColumn(), (entry) -> entry.getValue().get(rowGroupIndex).getColumnStatistics()))); }

Target:
nit: Just write `entry -> ...`
Source:
private boolean isSchemaAccessible(CatalogSchemaName schema) { Set<String> schemas = ImmutableSet.of(schema.getSchemaName()); schemas = accessControl.filterSchemas(session.getRequiredTransactionId(), session.getIdentity(), schema.getCatalogName(), schemas); return schemas.contains(schema.getSchemaName()) && metadata.schemaExists(session, schema); }

Target:
inline
Source:
public void forEach(MultimapAggregationStateConsumer consumer) { BlockBuilder keyBlockBuilder = keyBlockBuilders.get(getGroupId()); BlockBuilder valueBlockBuilder = valueBlockBuilders.get(getGroupId()); for (int i = 0; !isEmpty() && keyBlockBuilder != null && i < keyBlockBuilder.getPositionCount(); i++) { consumer.accept(keyBlockBuilder, valueBlockBuilder, i); } }

Target:
I would just write: ```java BlockBuilder keyBlockBuilder = keyBlockBuilders.get(getGroupId()); BlockBuilder valueBlockBuilder = valueBlockBuilders.get(getGroupId()); if (keyBlockBuilder == null) { return; } for (int i = 0; i < keyBlockBuilder.getPositionCount(); i++) { consumer.accept(keyBlockBuilder, valueBlockBuilder, i); } ``` In general, for global checks such as `keyBlockBuilder != null`, do it outsize the loop instead of check it per loop. It makes logic clear.
Source:
public void serialize(MultimapAggregationState state, BlockBuilder out) { if (state.isEmpty()) { out.appendNull(); } else { BlockBuilder entryBuilder = out.beginBlockEntry(); state.forEach((keyBlock, valueBlock, position) -> { BlockBuilder rowBlockBuilder = entryBuilder.beginBlockEntry(); valueType.appendTo(valueBlock, position, rowBlockBuilder); keyType.appendTo(keyBlock, position, rowBlockBuilder); entryBuilder.closeEntry(); }); out.closeEntry(); } }

Target:
nit: you can `return` in the `if` block and get rid of this else.
Source:
public SingleMultimapAggregationState(Type keyType, Type valueType) { this.keyType = requireNonNull(keyType); this.valueType = requireNonNull(valueType); keyBlockBuilder = this.keyType.createBlockBuilder(null, EXPECTED_ENTRIES, expectedValueSize(keyType, EXPECTED_ENTRY_SIZE)); valueBlockBuilder = this.valueType.createBlockBuilder(null, EXPECTED_ENTRIES, expectedValueSize(valueType, EXPECTED_ENTRY_SIZE)); }

Target:
nit: do `keyType.createBlockBuilder` instead of `this.keyType.xxxx`
Source:
public PlanNodeStatsEstimate calculateStats(PlanNode node, StatsProvider sourceStats, Lookup lookup, Session session, TypeProvider types) { if (node instanceof RemoteSourceNode) { return calculateRemoteSourceStats((RemoteSourceNode) node, sourceStats, lookup, session, types); } return delegate.calculateStats(node, sourceStats, lookup, session, types); }

Target:
move it to the top, just below the constructor
Source:
private PlanNodeStatsEstimate calculateRemoteSourceStats(RemoteSourceNode node, StatsProvider statsProvider) { PlanNodeStatsEstimate estimate = null; for (PlanFragment sourceFragment : sourceProvider.getSourceFragments(node)) { PlanNodeStatsEstimate sourceStatsWithMappedSymbols = mapToOutputSymbols(statsProvider.getStats(sourceFragment.getRoot()), sourceFragment.getPartitioningScheme().getOutputLayout(), node.getOutputSymbols()); if (estimate != null) { addStatsAndMaxDistinctValues(estimate, sourceStatsWithMappedSymbols); } else { estimate = sourceStatsWithMappedSymbols; } } verify(estimate != null, "estimate is null"); return estimate; }

Target:
Maybe `FragmentedPlanSourceProvider::getSources` for `RemoteSourceNode` should return nodes with output symbols already mapped? That way you wouldn't need to map symbols here.
Source:
public ConnectorTransactionHandle create() { long transactionId = metadata.nextTransactionId(); long commitId = metadata.getCurrentCommitId(); Transaction transaction = new Transaction(metadata, transactionId, commitId); RaptorTransactionHandle handle = new RaptorTransactionHandle(transactionId, commitId); transactions.put(handle, transaction); return handle; }

Target:
Let me describe a potential data race here. Let's verify together whether it's a real issue. The race happens when some logics jump in after line 44 and before line 48, the time series is: thread2 called beginTransaction, get CurrentCommitId == 1 thread1 metadata.getCurrentCommitId(); get CurrentCommitId==1 thread2 execute, finish commit, update CurrentCommitId=2, exit fully CommitCleaner threadxx called oldestActiveCommitId, since transactions is empty, CurrentCommitId==2, it gets oldestActiveCommitId == 2 thread1 called transactions.put(handle, transaction); Then this enters a unsafe state, since oldestActiveCommitId is actually 1, but CommitCleaner get 2.
Source:
private static void deleteChunks(ShardWriterDao dao, long commitId, long tableId, Set<Long> chunkIds) { int rows = dao.deleteChunks(commitId, chunkIds); verifyMetadata(rows == chunkIds.size(), "Wrong row count %s for delete of %s chunks", rows, chunkIds.size()); rows = dao.deleteIndexChunks(chunkIndexTable(tableId), chunkIds); verifyMetadata(rows == chunkIds.size(), "Wrong row count %s for delete of %s index chunks", rows, chunkIds.size()); }

Target:
Here we delete all, instead of setting end_commit_id. The following 2 cases may be issues: 1 ChunkSupplier.java line 105, getBucketChunks. called by RaptorSplitManager.getSplits(), the only place for presto to get chunks. If it can be called twice in a transaction, not good. But if only called once, maybe fine. 2 DatabaseMetadataWriter.recover line 205 dao.rollbackDeletedIndexChunks(chunkIndexTable(tableId), commitId); filters end_commit_id. So the rollback of delete, only rollback chunks, but index are not, then index is less then chunks.
Source:
public BlockBuilder nextColumn() { int currentChannel = channel; channel++; return pageBuilder.getBlockBuilder(currentChannel); }

Target:
make this `private`
Source:
public JoinNode.Type getType() { return type; }

Target:
Is this still correct? Can this be ensured only by `LocalExecutionPlanner`?
Source:
public PlanNode replaceChildren(List<PlanNode> newChildren) { checkArgument(newChildren.size() == 2, "expected newChildren to contain 2 nodes"); PlanNode newLeft = newChildren.get(0); PlanNode newRight = newChildren.get(1); return new SpatialJoinNode(getId(), type, newLeft, newRight, outputSymbols, filter); }

Target:
I would inline them
Source:
public StreamProperties visitSpatialJoin(SpatialJoinNode node, List<StreamProperties> inputProperties) { StreamProperties leftProperties = inputProperties.get(0); switch (node.getType()) { case INNER: case LEFT: return leftProperties.translate(column -> PropertyDerivations.filterIfMissing(node.getOutputSymbols(), column)); default: throw new UnsupportedOperationException("Unsupported spatial join type: " + node.getType()); } }

Target:
`IllegalArgumentException`
Source:
public static Type fromJoinNodeType(JoinNode.Type joinNodeType) { switch (joinNodeType) { case INNER: return Type.INNER; case LEFT: return Type.LEFT; default: throw new UnsupportedOperationException("Unsupported spatial join type: " + joinNodeType); } }

Target:
IllegalArgumentException
Source:
static Long toMillis(Duration duration) { if (duration == null) { return null; } return duration.toMillis(); }

Target:
Instead of exporting this, I would simply replace the future usages with Optional.ofNullable(duration).map(Duration::toMillis).orElse(null)
Source:
public static MetadataManager createTestMetadataManager(CatalogManager catalogManager, FeaturesConfig featuresConfig) { TypeManager typeManager = new TypeRegistry(ImmutableSet.of(), featuresConfig); return new MetadataManager( featuresConfig, typeManager, new BlockEncodingManager(typeManager), new SessionPropertyManager(), new SchemaPropertyManager(), new TablePropertyManager(), new ColumnPropertyManager(), InMemoryTransactionManager.createTestTransactionManager(catalogManager)); }

Target:
Keep this static imported?
Source:
private static long getGeometryMemorySize(OGCGeometry geometry) { if (geometry == null) { return 0; } else if (geometry.isEmpty()) { return OGC_GEOMETRY_BASE_INSTANCE_SIZE; } else { return geometry.estimateMemorySize(); } }

Target:
style: drop redundant `else`s: ``` if (geometry == null) { return 0; } if (geometry.isEmpty()) { return ... } return geometry.estimateMemorySize(); ``` Could you add a reference to ESRI issue to explain special handling for empty geometries?
Source:
public void serialize(GeometryState state, BlockBuilder out) { if (state.getGeometry() == null) { out.appendNull(); } else { GeometryType.GEOMETRY.writeSlice(out, GeometrySerde.serialize(state.getGeometry())); } }

Target:
style: static import `GeometryType.GEOMETRY`, `GeometrySerde.serialize` and `GeometrySerde.deserialize`
Source:
public void removePreAllocation(QueryId queryId) { synchronized (this) { preAllocations.remove(queryId); } MemoryPoolInfo info = pools.get(GENERAL_POOL).getInfo(); for (Consumer<MemoryPoolInfo> listener : changeListeners.get(GENERAL_POOL)) { listenerExecutor.execute(() -> listener.accept(info)); } }

Target:
What's the reason behind this change? `changeListeners` and `pools` are also `GuardedBy` `this`, and this change removes the synchronization on them.
Source:
public Rectangle merge(Rectangle other) { requireNonNull(other, "other is null"); return new Rectangle(min(this.xMin, other.xMin), min(this.yMin, other.yMin), max(this.xMax, other.xMax), max(this.yMax, other.yMax)); }

Target:
This is not really necessary. It will fail with NPE in the line below if it comes to it. In general, it's more important to do these kinds of checks when holding on to the value, which may cause the code to fail much later in an unrelated place.
Source:
public boolean isFinished() { return blocked.isDone() && state == State.FINISHED; }

Target:
nit: reverse (as it was originally): `state == State.FINISHED && ..` -- do the cheaper thing first
Source:
public String getTableName() { return tableName; }

Target:
all these methods can be private
Source:
public String getType() { return type; }

Target:
all these methods can be private
Source:
private boolean isS3SelectEnabled(ConnectorSession session) { if (!hiveClientConfig.isS3SelectPushdownEnabled()) { LOG.debug("S3Select is not enabled."); return false; } if (!HiveSessionProperties.isS3SelectPushdownEnabled(session)) { LOG.debug("Session S3SelectPushdown is disabled."); return false; } LOG.info("S3Select is enabled."); return true; }

Target:
This line may get logged a lot of times in a production system when s3 select is enabled, no? (when I trace it, it gets called from `HiveSplitManager.getSplits()`).
Source:
public void shouldThrowNullPointerExceptionWhenSchemaIsNull() { updateSplitSchema(null, EMPTY_LIST); }

Target:
nit: You can use `ImmutableList.of()` instead of `EMPTY_LIST` with the additional benefit of getting rid of the unchecked assignment warning.
Source:
private static JoinNode.EquiJoinClause toEquiJoinClause(ComparisonExpression equality, Set<Symbol> leftSymbols) { Symbol leftSymbol = Symbol.from(equality.getLeft()); Symbol rightSymbol = Symbol.from(equality.getRight()); JoinNode.EquiJoinClause equiJoinClause = new JoinNode.EquiJoinClause(leftSymbol, rightSymbol); return leftSymbols.contains(leftSymbol) ? equiJoinClause : equiJoinClause.flip(); }

Target:
nit: static import `EquiJoinClause `
Source:
public void testDoesNotAllowOuterJoin() { PlanBuilder p = planBuilder(); Symbol a1 = p.symbol("A1"); Symbol b1 = p.symbol("B1"); JoinNode outerJoin = p.join( JoinNode.Type.FULL, p.values(a1), p.values(b1), ImmutableList.of(equiJoinClause(a1, b1)), ImmutableList.of(a1, b1), Optional.empty()); toMultiJoinNode(outerJoin, noLookup(), DEFAULT_JOIN_LIMIT); }

Target:
Import `FULL`
Source:
private JoinNode.EquiJoinClause equiJoinClause(Symbol symbol1, Symbol symbol2) { return new JoinNode.EquiJoinClause(symbol1, symbol2); }

Target:
Import `EquiJoinClause `
Source:
public RuleAssert overrideStats(String nodeId, PlanNodeStatsEstimate nodeStats) { ((TestingStatsCalculator) statsCalculator).setNodeStats(new PlanNodeId(nodeId), nodeStats); return this; }

Target:
The cast is no longer needed
Source:
public boolean isEnabled(Session session) { // we run this for cost-based reordering also for cases when some of the tables do not have statistics FeaturesConfig.JoinReorderingStrategy joinReorderingStrategy = getJoinReorderingStrategy(session); return joinReorderingStrategy == ELIMINATE_CROSS_JOINS || joinReorderingStrategy == COST_BASED; }

Target:
Import `JoinReorderingStrategy `
Source:
public long getRetainedSizeInBytes() { return INSTANCE_SIZE + SizeOf.sizeOf(nullVector); }

Target:
static import `sizeOf` (also in other stream readers)
Source:
public void close() throws IOException { try (Closer closer = Closer.create()) { closer.register(super::close); closer.register(s3::shutdown); if (credentialsProvider instanceof Closeable) { closer.register((Closeable) credentialsProvider); } } }

Target:
nit: `s3` should be closed before closing credentials providers (because its a dependent resource), so add it last to the closer.
Source:
private static Comparable<?> encodeDecimal(Type type, BigDecimal value) { BigInteger unscaled = Decimals.rescale(value, (DecimalType) type).unscaledValue(); if (Decimals.isShortDecimal(type)) { return unscaled.longValueExact(); } else { return Decimals.encodeUnscaledValue(unscaled); } }

Target:
Nit: else is redundant
Source:
public PartitionMetadata withColumnStatistics(Map<String, HiveColumnStatistics> columnStatistics) { requireNonNull(columnStatistics, "columnStatistics is null"); return new PartitionMetadata(columns, parameters, storageFormat, bucketProperty, serdeParameters, externalLocation, columnStatistics); }

Target:
This is not needed, since the constructor already checks it
Source:
public SpecializedSignature getSpecializedSignature() { SpecializedSignature specializedSignature = new SpecializedSignature( signature, argumentNativeContainerTypes, specializedTypeParameters, returnNativeContainerType); return specializedSignature; }

Target:
nit: You can create the `SpecializedSignature` and return it in one step. ```java return new SpecializedSignature( signature, argumentNativeContainerTypes, specializedTypeParameters, returnNativeContainerType); ```
Source:
static FileBasedSystemAccessControlRules parse(byte[] json) { ObjectMapper mapper = new ObjectMapperProvider().get() .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Class<FileBasedSystemAccessControlRules> javaType = FileBasedSystemAccessControlRules.class; try { return mapper.readValue(json, javaType); } catch (IOException e) { throw new IllegalArgumentException(format("Invalid JSON string for %s", javaType), e); } }

Target:
You can use `JsonCodec`: ```java return new JsonCodecFactory().jsonCodec(FileBasedSystemAccessControlRules.class).fromJson(json);
Source:
private Block getNullBlock(Type type, int positionCount) { Block nullValueBlock = type.createBlockBuilder(null, 1) .appendNull() .build(); return new RunLengthEncodedBlock(nullValueBlock, positionCount); }

Target:
I think this can be static
Source:
private static boolean isDeterminateConstant(RowExpression expression, MethodHandle isIndeterminateFunction) { if (!(expression instanceof ConstantExpression)) { return false; } ConstantExpression constantExpression = (ConstantExpression) expression; Object value = constantExpression.getValue(); boolean isNull = value == null; if (isNull) { return false; } try { return !(boolean) isIndeterminateFunction.invoke(value, isNull); } catch (Throwable t) { throwIfUnchecked(t); throw new RuntimeException(t); } }

Target:
Use `InterpretedFunctionInvoker` instead
Source:
public static long xxHash64(@SqlType(StandardTypes.TINYINT) long value) { return XxHash64.hash((byte) value); }

Target:
We do not unpack it for all the inequality operators. Because of that i assume that the assumption is that the higher bits are always zero (or the same). Therefore i don't think the downcast to `byte` is needed here.
Source:
public Optional<SystemTable> getSystemTable(ConnectorSession session, SchemaTableName tableName) { return getSourceTable(tableName) .map(t -> (RaptorTableHandle) getTableHandle(t)) .map(handle -> new ColumnRangesSystemTable(handle, dbi)); }

Target:
If we change `getTableHandle` to return `RaptorTableHandle`, we can remove the cast and make this `map(this::getTableHandle)`
Source:
public List<BytecodeNode> getChildNodes() { return null; }

Target:
So we decide this class to be a leaf ByteCode Node? (Alternative would be make this returns `ImmutableList.of(block, position)`
Source:
public void testDefaults() { ConfigAssertions.assertRecordedDefaults(ConfigAssertions.recordDefaults(SqlEnvironmentConfig.class) .setPath(" ")); }

Target:
static import the assert methods on this line, so this becomes: ``` assertRecordedDefaults(recordDefaults(SqlEnvironmentConfig.class).setPath(" ")); ```
Source:
private static ExpressionRewriter createRewrite() { return (expression, context) -> ExpressionTreeRewriter.rewriteWith(new com.facebook.presto.sql.tree.ExpressionRewriter<Void>() { @Override public Expression rewriteCurrentPath(CurrentPath node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { return DesugarCurrentPath.getCall(node); } }, expression); }

Target:
No need to use the fully qualified name since you import this class already.
Source:
public SetPath(Optional<NodeLocation> location, PathSpecification pathSpecification) { super(location); this.pathSpecification = requireNonNull(pathSpecification, "path is null"); }

Target:
this is used only internally, so can be private.
Source:
public PathElement(Optional<NodeLocation> location, Optional<Identifier> catalog, Identifier schema) { super(location); this.catalog = requireNonNull(catalog, "catalog is null"); this.schema = requireNonNull(schema, "schema is null"); }

Target:
can be private.
Source:
public PhysicalOperation visitRemoteSource(RemoteSourceNode node, LocalExecutionPlanContext context) { if (node.getOrderingScheme().isPresent()) { return createMergeSource(node, context); } else { return createRemoteSource(node, context); } }

Target:
nit: it seems like we prefer to not put `else` after `return` elsewhere in the codebase
Source:
public static List<SqlScalarFunction> parseFunctionDefinitions(Class<?> clazz) { ImmutableList.Builder<SqlScalarFunction> builder = ImmutableList.builder(); for (ScalarHeaderAndMethods methods : findScalarsInFunctionSetClass(clazz)) { // Non-static function only makes sense in classes annotated @ScalarFunction. builder.add(parseParametricScalar(methods, ImmutableMap.of())); } return builder.build(); }

Target:
nit: Maybe more explicit: ``` Only function definition classes (classes annotated with @ScalarFunction) can define SQL functions via non-static java function. Function set classes can only define SQL functions via static java functions. Thus constructor in function set classes is used to define SQL functions. ```
Source:
private static String getExpectedErrorMessageForInsertExistingBucketedTable(InsertExistingPartitionsBehavior behavior, String partitionName) { if (behavior == InsertExistingPartitionsBehavior.APPEND) { return "Cannot insert into existing partition of bucketed Hive table: " + partitionName; } else if (behavior == InsertExistingPartitionsBehavior.ERROR) { return "Cannot insert into an existing partition of Hive table: " + partitionName; } throw new IllegalArgumentException("Unexpected insertExistingPartitionsBehavior: " + behavior.name()); }

Target:
These `else` is redundant
Source:
private static List<Type> toTypes(List<Type> groupByTypes, List<Aggregator> aggregates) { ImmutableList.Builder<Type> builder = ImmutableList.builder(); builder.addAll(groupByTypes); aggregates.stream().forEach(aggregator -> builder.add(aggregator.getType())); return builder.build(); }

Target:
Do we want to support partial streaming aggregations now?
Source:
public boolean isStreamable() { if (!preGroupedSymbols.isEmpty() && groupingSets.size() == 1) { List<Symbol> groupingSet = Iterables.getOnlyElement(groupingSets); return !groupingSet.isEmpty() && Sets.newHashSet(preGroupedSymbols).equals(Sets.newHashSet(groupingSet)); } return false; }

Target:
don't you need to check that `aggregations.isEmpty()`?
Source:
public void checkCanCreateViewWithSelectFromColumns(TransactionId transactionId, Identity identity, QualifiedObjectName tableName, Set<String> columnNames) { if (shouldDenyPrivilege(identity.getUser(), tableName.getObjectName(), CREATE_VIEW_WITH_SELECT_COLUMNS)) { denyCreateViewWithSelect(tableName.toString()); } if (denyPrivileges.isEmpty()) { super.checkCanCreateViewWithSelectFromColumns(transactionId, identity, tableName, columnNames); } }

Target:
Why change this but not the other `checkCanCreateViewXXX` methods?
Source:
public void addTableColumnReferences(AccessControl accessControl, Identity identity, Multimap<QualifiedObjectName, String> tableColumnMap) { AccessControlInfo accessControlInfo = new AccessControlInfo(accessControl, identity); Map<QualifiedObjectName, Set<String>> references = tableColumnReferences.computeIfAbsent(accessControlInfo, (k) -> new LinkedHashMap<>()); tableColumnMap.asMap() .forEach((key, value) -> references.computeIfAbsent(key, k -> new HashSet<>()).addAll(value)); }

Target:
Nit: no need for parens around lambda parameter. Also, I think it can be replaced with `LinkedHashMap::new`
Source:
private void updateDataSize() { retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values) + NULL_VALUE_BLOCK.getRetainedSizeInBytes(); if (blockBuilderStatus != null) { retainedSizeInBytes += BlockBuilderStatus.INSTANCE_SIZE; } }

Target:
This is a constant shared across all instances, so should not be part of the retained size.
Source:
void unexport(MBeanExporter exporter) { for (Class<?> rule : stats.keySet()) { String name = ObjectNames.builder(PlanOptimizer.class) .withProperty("optimizer", rule.getSimpleName()) .build(); exporter.unexport(name); } }

Target:
Consider extracting object name building to a method to emphasize that export and unexport use the same naming strategy.
Source:
public final boolean execute(String sql) throws SQLException { if (connection().shouldStartTransaction()) { internalExecute(connection().getStartTransactionSql()); } return internalExecute(sql); }

Target:
it needs to be overridden in the subclass
Source:
public static long stNumPoints(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { return GeometryUtils.getPointCount(deserialize(input)); }

Target:
static import
Source:
default TableStatisticsMetadata getInsertIntoTableStatisticsMetadata(ConnectorSession session, ConnectorTableHandle tableHandle) { return EMPTY_STATISTICS_METADATA; }

Target:
Lets name this `getInsertStatisticsMetadata` to be consistent with `getInsertLayout`
Source:
private static int getHashPosition(Block keyBlock, int position, MethodHandle keyBlockHashCode, int hashTableSize) { if (keyBlock.isNull(position)) { throw new IllegalArgumentException("map keys cannot be null"); } long hashCode; try { hashCode = (long) keyBlockHashCode.invokeExact(keyBlock, position); } catch (Throwable throwable) { if (throwable instanceof RuntimeException) { throw (RuntimeException) throwable; } throw new RuntimeException(throwable); } return (int) Math.floorMod(hashCode, hashTableSize); }

Target:
``` long hashCode; try { hashCode = (long) keyBlockHashCode.invokeExact(keyBlock, position); } catch (RuntimeException e) { throw e; } catch (Throwable throwable) { throw new RuntimeException(throwable); }
Source:
private static boolean coordinateInsideBoundary(int coordinate, long maxTileIndex) { return (coordinate >= 0 && coordinate <= maxTileIndex); }

Target:
brackets are extra here
Source:
public FileBasedSystemAccessControlRules( @JsonProperty("catalogs") Optional<List<CatalogAccessControlRule>> catalogRules, @JsonProperty("principals") Optional<List<PrincipalUserMatchRule>> principalUserMatchRules) { this.catalogRules = catalogRules.map(ImmutableList::copyOf).orElse(ImmutableList.of()); this.principalUserMatchRules = principalUserMatchRules.map(ImmutableList::copyOf).orElse(ImmutableList.of()); }

Target:
`principalUserMatchRules` could remain `Optional<List<..>>`
Source:
public String toString() { ToStringHelper helper = toStringHelper(this) .add("name", name) .add("ordinalPosition", ordinalPosition) .add("type", type); return helper.toString(); }

Target:
please inline the `helper`
Source:
public ConnectorTableHandle beginDelete(ConnectorSession session, ConnectorTableHandle tableHandle) { KuduTableHandle kuduTableHandle = fromConnectorTableHandle(session, tableHandle); return kuduTableHandle; }

Target:
just cast here
Source:
public boolean isFinished() { if (finished) { return true; } boolean finished = finishing && probe == null && pageBuilder.isEmpty() && outputPage == null; // if finished drop references so memory is freed early if (finished) { close(); } return finished; }

Target:
> If you do a join with an empty probe the operator waits until the build finishes, which could take hours. i was aware of this limitation and we've been discussing this with @losipiuk last summer. Question is -- how much of a problem is this? Ideally, we should be quite good at knowing which side of the join is bigger, so empty probe side and hours-worth of the build side is not something we can be proud of.
Source:
private static ListenableFuture<?> firstFinishedFuture(List<ListenableFuture<?>> futures) { if (futures.size() == 1) { return futures.get(0); } SettableFuture<?> result = SettableFuture.create(); ExecutorService executor = newDirectExecutorService(); for (ListenableFuture<?> future : futures) { future.addListener(() -> result.set(null), executor); } return result; }

Target:
This function appears like duplicate of `whenAnyComplete` in airlift `MoreFutures`. What about using that instead?
Source:
public void testDefaults() { ConfigAssertions.assertRecordedDefaults(ConfigAssertions.recordDefaults(JsonWebTokenConfig.class) .setKey(null) .setRequiredAudience(null) .setRequiredIssuer(null)); }

Target:
Static import the assertion methods
Source:
private List<String> getSchemaNames(ConnectorSession session, Optional<String> schemaName) { if (!schemaName.isPresent()) { return listSchemaNames(session); } else if (schemaNameToScaleFactor(schemaName.get()) > 0) { return ImmutableList.of(schemaName.get()); } return ImmutableList.of(); }

Target:
`else` is redundant
Source:
private static void assertGeometryEquals(Geometry actual, Geometry expected) { if (expected.isEmpty()) { assertTrue(actual.isEmpty()); } else { assertEquals(actual.norm(), expected.norm()); } }

Target:
Since earlier commits enhanced serialization to avoid losing multi-types this test can be simplified to `assertEquals(actual.norm(), expected.norm());` in all cases.
Source:
private static Envelope getEnvelope(BasicSliceInput input, GeometryType type, int length) { switch (type) { case POINT: return getPointEnvelope(input); case MULTI_POINT: case LINE_STRING: case MULTI_LINE_STRING: case POLYGON: case MULTI_POLYGON: return getSimpleGeometryEnvelope(input, length); case GEOMETRY_COLLECTION: return getGeometryCollectionOverallEnvelope(input); default: throw new UnsupportedOperationException("Unexpected type: " + type); } }

Target:
In other switches `IllegalArgumentException` is thrown, which I think is a better fit to here.
Source:
public List<SchemaTableName> listTables(ConnectorSession session, String schemaNameOrNull) { Stream<SchemaTableName> stream = tables.listSystemTables(session).stream() .map(SystemTable::getTableMetadata) .map(ConnectorTableMetadata::getTable); if (schemaNameOrNull != null) { stream = stream .filter(table -> table.getSchemaName().equals(schemaNameOrNull)); } return stream.collect(toImmutableList()); }

Target:
You could extract this to a method: ``` .stream() ... .filter(tableSchemaMatcher(schemaNameOrNull)) .collect ```
Source:
public DelegatingSystemTablesProvider(List<SystemTablesProvider> delegates) { requireNonNull(delegates, "delegates is null"); Preconditions.checkArgument(delegates.size() >= 1, "empty delegates"); this.delegates = ImmutableList.copyOf(delegates); }

Target:
- static import - why is having no delegates an error?
Source:
public static boolean isPartitionsSystemTable(SchemaTableName tableName) { return tableName.getTableName().endsWith(PARTITIONS_TABLE_SUFFIX) && !tableName.getTableName().equals(PARTITIONS_TABLE_SUFFIX); }

Target:
`... && tableName.getTableName().length() > PARTITIONS_TABLE_SUFFIX.length()` ?
Source:
SymbolMapper getCorrelatedSymbolMapper() { return new SymbolMapper(correlatedSymbolsMapping.asMap().entrySet().stream() .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, symbols -> Iterables.getLast(symbols.getValue())))); }

Target:
static import
Source:
public Optional<DecorrelationResult> visitEnforceSingleRow(EnforceSingleRowNode node, Void context) { Optional<DecorrelationResult> childDecorrelationResultOptional = lookup.resolve(node.getSource()).accept(this, null); if (!childDecorrelationResultOptional.isPresent() || !childDecorrelationResultOptional.get().atMostSingleRow) { return Optional.empty(); } return childDecorrelationResultOptional; }

Target:
use `return childDecorrelationResultOptional.filter(DecorrelationResult::isAtMostSingleRow);`
Source:
public static void main(String[] args) throws IOException, RunnerException { BenchmarkData data = new BenchmarkData(); data.setup(); data.validate(); Options options = new OptionsBuilder() .verbosity(VerboseMode.NORMAL) .include(".*" + BenchmarkSTIntersects.class.getSimpleName() + ".*") .build(); new Runner(options).run(); }

Target:
nit: @martint Martin told me a trick of adding @Test method with validation logic. This ensures that benchmark code stays valid even if benchmark is not run.
Source:
private static Type getInt32Type(RichColumnDescriptor descriptor) { OriginalType originalType = descriptor.getPrimitiveType().getOriginalType(); if (originalType == null) { return IntegerType.INTEGER; } switch (originalType) { case DECIMAL: return createDecimalType(descriptor.getPrimitiveType().getDecimalMetadata()); case DATE: return DateType.DATE; default: return IntegerType.INTEGER; } }

Target:
static import `INTEGER`.
Source:
public static void combine(HistogramState state, HistogramState otherState) { // NOTE: state = current merged state; otherState = scratchState (new data to be added) // since we have a single instance of a histogram, it will never be non-null. Even asking for a histogram that does not exist returns the histogram object. It doesn't // "exist" until we call add() on it,though requireNonNull(state.get() != null, "this.typedHistogram should always be non-null"); requireNonNull(otherState.get() != null, "scratch state should always be non-null"); TypedHistogram typedHistogram = state.get(); long startSize = typedHistogram.getEstimatedSize(); typedHistogram.addAll(otherState.get()); state.addMemoryUsage(typedHistogram.getEstimatedSize() - startSize); }

Target:
nit: `current merged state should always be non-null`
Source:
public void testShowTablesLikeWithEscape() { //Cassandra connector currently does not support create table, so here override MaterializedResult withEscape = computeActual("SHOW TABLES LIKE '%$_%' ESCAPE '$'"); assertThat(withEscape.getOnlyColumnAsSet()).allMatch(tableName -> ((String) tableName).contains("_")); }

Target:
`s/withEscape/result/`
Source:
public void testShowTablesLikeWithEscape() { assertQueryFails("SHOW TABLES IN a LIKE '%$_%' ESCAPE", "line 1:36: no viable alternative at input '<EOF>'"); assertQueryFails("SHOW TABLES LIKE 't$_%' ESCAPE ''", "Escape string must be a single character"); assertQueryFails("SHOW TABLES LIKE 't$_%' ESCAPE '$$'", "Escape string must be a single character"); try { assertUpdate("CREATE TABLE test_escape_1 (a bigint)"); assertUpdate("CREATE TABLE test_escape11 (a bigint)"); } catch (RuntimeException e) { assertTrue(ImmutableSet.of("This connector does not support creating tables", "Unsupported statement type CreateTable") .contains(e.getMessage())); return; } assertQuery("SHOW TABLES LIKE 'test_escape_%'", "VALUES 'test_escape_1', 'test_escape11'"); assertQuery("SHOW TABLES LIKE 'test_escape\\_%' ESCAPE '\\'", "VALUES 'test_escape_1'"); assertUpdate("DROP TABLE test_escape_1"); assertUpdate("DROP TABLE test_escape11"); }

Target:
I am not particularly in favor of this lenient approach, as it may mask other (run-time) problems, not just inability to create table. I would recommend adding overrides to all relevant connectors, just as you did in cassandra case. (Or, you could introduce (in a separate, preparatory commit) a `supportsCreateTable` method (see `com.facebook.presto.tests.AbstractTestDistributedQueries#supportsViews`). )
Source:
synchronized Collection<ClientBuffer> safeGetBuffersSnapshot() { return ImmutableList.copyOf(this.buffers.values()); }

Target:
You don't need this any more.
Source:
private static void testSerialization(String wkt) { OGCGeometry geometry = OGCGeometry.fromText(wkt); geometry.setSpatialReference(null); OGCGeometry deserializedGeometry = deserialize(serialize(geometry)); assertEquals(geometry.asText(), deserializedGeometry.asText()); }

Target:
this code seems unnecessary
Source:
protected String getWarningMessage(PrestoWarning warning) { // If this is a real terminal color the warnings yellow return REAL_TERMINAL ? format("%sWARNING: %s%s", WARNING_BEGIN, warning.getMessage(), WARNING_END) : format("WARNING: %s", warning.getMessage()); }

Target:
why do you need this flag? This is only used by `printWithInitialSeparator` (why don't other methods need it if this is needed?).
Source:
private static void assertStartsWithExpectedWarnings(SQLWarning warning, SQLWarning expected) { // Warnings generated with the testing warning collector may have more warnings than expected // due to getWarnings being called multiple times in the StatementClient implementation if (warning == null) { assertNull(expected); return; } assertNotNull(expected); while (true) { assertWarningsEqual(warning, expected); warning = warning.getNextWarning(); expected = expected.getNextWarning(); if (expected == null) { return; } else { assertNotNull(warning); } } }

Target:
unnecessary else
Source:
public ArrayAggregationState createGroupedState() { if (mode == NEW) { return new GroupArrayAggregationState(type); } if (mode == LEGACY) { return new LegacyArrayAggregationGroupState(type); } throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, format("Unexpected group enum type %s", mode)); }

Target:
Use `switch` instead of `if`s