justinmclean opened a new issue, #10273:
URL: https://github.com/apache/gravitino/issues/10273
### What would you like to be improved?
LancePartitionStatisticStorage.dropStatisticsImpl builds the
dataset.delete(...) predicate by directly concatenating partitionName and
statisticNames into SQL-like quoted strings. If a name contains a single quote
(for example part'ition0), the generated predicate becomes invalid. This path
is reachable from production REST flow for drop-partition-statistics requests
when Lance partition stats storage is enabled.
### How should we improve?
Stop building predicates with raw string concatenation. Escape single quotes
in all string literals before composing the filter (for SQL-style literals,
replace ' with ''), or switch to a safe API that supports
parameterized/structured predicates if available in the Lance Java API.
Here's a test to help:
```
@Test
public void testDropPartitionStatisticsWithSingleQuotePartitionName() throws
Exception {
PartitionStatisticStorageFactory factory = new
LancePartitionStatisticStorageFactory();
String metalakeName = "metalake";
MetadataObject metadataObject =
MetadataObjects.of(Lists.newArrayList("catalog", "schema", "table"),
MetadataObject.Type.TABLE);
EntityStore entityStore = mock(EntityStore.class);
TableEntity tableEntity = mock(TableEntity.class);
when(entityStore.get(any(), any(), any())).thenReturn(tableEntity);
when(tableEntity.id()).thenReturn(202L);
FieldUtils.writeField(GravitinoEnv.getInstance(), "entityStore",
entityStore, true);
String location =
Files.createTempDirectory("lance_stats_quote_drop_test").toString();
Map<String, String> properties = Maps.newHashMap();
properties.put("location", location);
LancePartitionStatisticStorage storage =
(LancePartitionStatisticStorage) factory.create(properties);
try {
Map<String, StatisticValue<?>> statistics = Maps.newHashMap();
statistics.put("statistic0", StatisticValues.longValue(1L));
List<MetadataObjectStatisticsUpdate> updates =
Lists.newArrayList(
MetadataObjectStatisticsUpdate.of(
metadataObject,
Lists.newArrayList(
PartitionStatisticsModification.update("part'ition0",
statistics))));
storage.updateStatistics(metalakeName, updates);
List<MetadataObjectStatisticsDrop> drops =
Lists.newArrayList(
MetadataObjectStatisticsDrop.of(
metadataObject,
Lists.newArrayList(
PartitionStatisticsModification.drop(
"part'ition0", Lists.newArrayList("statistic0")))));
Assertions.assertDoesNotThrow(() -> storage.dropStatistics(metalakeName,
drops));
} finally {
FileUtils.deleteDirectory(new File(location + "/" + tableEntity.id() +
".lance"));
storage.close();
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]