-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#412] feat(core): Generic property system support #441
Conversation
Code Coverage Report
Files
|
catalogs/catalog-hive/src/main/java/com/datastrato/graviton/catalog/hive/HiveCatalog.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/BaseCatalog.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/CatalogOperationDispatcher.java
Outdated
Show resolved
Hide resolved
boolean required, | ||
boolean immutable, | ||
Class<T> javaType, | ||
T defaultValue, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems missing defaultValue
process logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defaultValue
is handled by each catalog separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why defaultValue
is handled by each catalog? seems it's common
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because catalog maybe want to know has the user set this property, If we set defaultValue
for all absent non-required properties in advance, the catalog can't tell if it was set by the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any property meets the scene you described? why should catalog differences it's set by user or graviton?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For instance, the location
is a non-required property for a Hive table. If the user does not specify a location
, Hive will automatically assign different values to different tables. However, if null
is set as the default value for the location
, it will result in a NPE in HMS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
location
is special and shouldn't have a default value. HiveCatalog should assign a table location. For most cases, such as table format
, which have a fixed default value, I think it's more suitable to be processed in common code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HiveCatalog should assign a table location.
It's not necessary. For external table, location
can also be assigned by user.
As you said, here does have some special properties that cannot be processed in common code, so I still think the defaultValue should be processed in catalog themselves
() -> | ||
mergeTablePropertySpecs( | ||
basicCapability.tablePropertySpecs(), | ||
acquireCatalogCapability().tablePropertySpecs()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here, we mixed CatalogCapabity
and TableCapabity
, should we separate them? Take Iceberg for example,
catalogType
is required when creating IcebergCatalog, while when creating IcebergTable, I don't want to specify catalogType
again, it becomes reserved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HiveCatalog. metastore.uri
maybe have same logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here, we mixed CatalogCapabity and TableCapabity
Here only process tablePropertySpecs
, does not include CatalogPropertySpecs
@@ -87,6 +87,10 @@ public <R> R doWithTableOps(ThrowableFunction<TableCatalog, R> fn) throws Except | |||
}); | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when Create&Alter&Load
catalog, should we check properties?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
catalog property validation work in another pr #452
I have refactored the |
@mchades you need to update the PR description. |
* @param hidden Whether this property is hidden from user, such as password | ||
* @param reserved This property is reserved and cannot be set by user | ||
*/ | ||
private PropertyEntry( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to change to builder pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
public static boolean isReservedProperty( | ||
String propertyName, Map<String, PropertyEntry<?>> propertySpecs) { | ||
return propertySpecs.containsKey(propertyName) && propertySpecs.get(propertyName).isReserved(); | ||
} | ||
|
||
public static boolean isRequiredProperty( | ||
String propertyName, Map<String, PropertyEntry<?>> propertySpecs) { | ||
return propertySpecs.containsKey(propertyName) && propertySpecs.get(propertyName).isRequired(); | ||
} | ||
|
||
public static boolean isImmutableProperty( | ||
String propertyName, Map<String, PropertyEntry<?>> propertySpecs) { | ||
return propertySpecs.containsKey(propertyName) && propertySpecs.get(propertyName).isImmutable(); | ||
} | ||
|
||
public static boolean isHiddenProperty( | ||
String propertyName, Map<String, PropertyEntry<?>> propertySpecs) { | ||
return propertySpecs.containsKey(propertyName) && propertySpecs.get(propertyName).isHidden(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these better to move to PropertyMetadata
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved
} | ||
|
||
// need remove? | ||
public static Map<String, String> encodeProperties( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not used, then we can remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
@@ -31,7 +32,7 @@ public String shortName() { | |||
*/ | |||
@Override | |||
protected CatalogOperations newOps(Map<String, String> config) { | |||
HiveCatalogOperations ops = new HiveCatalogOperations(entity()); | |||
HiveCatalogOperations ops = new HiveCatalogOperations(entity(), tableProperty()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you don't have to create xxxProperty()
here and pass in to the specific HiveCatalogOperations
. Instead, you can let HiveCatalogOperations
implements HasPropertyMetadata
interface, and in catalog, we can change to:
@Override
public PropertyMetadata tableProperty() throws UnsupportedOperationException {
return ops.tableProperty();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I have let CatalogOperations
implements HasPropertyMetadata
interface to make sure catalog developers implement the interface.
BTW, the PR description already updated.
fix Iceberg rename ability to capability fix typo add illegal combination validation in PropertySpec remove alterTable and loadTable wrapper remove generics V refact split HasPropertyMetadata interface PropertyEntry use builder pattern move static method to PropertyMetadata
core/src/main/java/com/datastrato/graviton/PropertyMetadata.java
Outdated
Show resolved
Hide resolved
...s/catalog-hive/src/main/java/com/datastrato/graviton/catalog/hive/HiveCatalogOperations.java
Outdated
Show resolved
Hide resolved
return decoder.apply(value); | ||
} | ||
|
||
public static PropertyEntry<String> stringProperty( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better changing to stringPropertyEntry
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I think you can add several help methods like stringRequiredProperty, stringReservedProperty to simplify the use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added stringRequiredProperty
, stringReservedProperty
and stringImmutablePropertyEntry
method for current usage and test, and will add more help methods in catalog development later on, since there are many flag combinations.
return table; | ||
} | ||
|
||
private Table loadTableWithAllProperties(NameIdentifier ident) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to split to a new method, I think changing the loadTable should be enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the original loadTable
method will verify the ID_KEY
property, but the property framework will remove hidden property after loadTable
, so I renamed the original loadTable
to loadTableWithAllProperties
for reuse the logic.
core/src/main/java/com/datastrato/graviton/catalog/CatalogOperationDispatcher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/HasPropertyMetadata.java
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/PropertyMetadata.java
Outdated
Show resolved
Hide resolved
for (TableChange change : changes) { | ||
if (change instanceof TableChange.SetProperty) { | ||
String propertyName = ((TableChange.SetProperty) change).getProperty(); | ||
if (isReservedProperty(propertyName, tablePropertySpecs)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not very clear here: Why here is not the same as line 514, as both SetProperty
and RemoveProperty
will change the property value. If the value of property is unchanging, it should fail here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ImmutableProperty
means the property cannot be changed by user, but if the property has not been set before, user can set it.
core/src/main/java/com/datastrato/graviton/catalog/CatalogOperationDispatcher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/CatalogOperationDispatcher.java
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/PropertyEntry.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/CatalogOperationDispatcher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/rel/EntityCombinedTable.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastrato/graviton/catalog/CatalogOperationDispatcher.java
Outdated
Show resolved
Hide resolved
### What changes were proposed in this pull request? 1. Add the `HasPropertyMetadata` interface to `BaseCatalog` and `CatalogOperations` for acquiring `PropertyMetadata` 2. Add `PropertyMetadata` interface for `tableProperty`, `schemaProperty` and `catalogProperty` can also implement it later on 3. validate table properties when `CatalogOperationDispatcher` operates tables ### Why are the changes needed? Under the property framework, every catalog only needs to care about the table property metadata definition in itself, the work of property validation will be done by the framework. Fix: #412 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? UT added in `TestCatalogOperationDispatcher` --------- Co-authored-by: yuqi <yuqi@datastrato.com>
What changes were proposed in this pull request?
HasPropertyMetadata
interface toBaseCatalog
andCatalogOperations
for acquiringPropertyMetadata
PropertyMetadata
interface fortableProperty
,schemaProperty
andcatalogProperty
can also implement it later onCatalogOperationDispatcher
operates tablesWhy are the changes needed?
Under the property framework, every catalog only needs to care about the table property metadata definition in itself, the work of property validation will be done by the framework.
Fix: #412
Does this PR introduce any user-facing change?
No
How was this patch tested?
UT added in
TestCatalogOperationDispatcher