HIVE-28654: MSCK repair fails for default partition when partition column is of numeric type - #5568
Conversation
d502d48 to
0eff58b
Compare
|
|
||
| public static String getNormalisedPartitionValue(String partitionValue, String type) { | ||
|
|
||
| if (partitionValue.equals("__HIVE_DEFAULT_PARTITION__")) |
There was a problem hiding this comment.
I have a quick question here. Does the patch solve the issue regardless of the value of hive.exec.default.partition.name? If not, I think it would be better to retreive the default partition name from HiveConf rather than using __HIVE_DEFAULT_PARTITION__.
There was a problem hiding this comment.
@ngsg, thanks for reviewing the PR. Yes, the issue is regarding hive.exec.default.partition.name. As hive-common is not a dependency in standalone-metastore/metastore-server/pom.xml , i think it better to use MetaConf as done in getPartitionListByFilterExp
0eff58b to
6476ff1
Compare
| } | ||
|
|
||
| public static String getNormalisedPartitionValue(String partitionValue, String type) { | ||
| public static String getNormalisedPartitionValue(String partitionValue, String type, String defaultPartName) { |
There was a problem hiding this comment.
why dont we get and check MetastoreConf.ConfVars.DEFAULTPARTITIONNAME here itself, rather than passing from the caller ?
There was a problem hiding this comment.
We would need a conf object to fetch the value of DEFAULTPARTITIONNAME and conf is not attribute of MetaStoreServerUtils class. Therefore, String is passed in the function argument.
| partColNames.add(fSchema.getName()); | ||
| } | ||
|
|
||
| String defaultPartName = MetastoreConf.getVar(conf, MetastoreConf.ConfVars.DEFAULTPARTITIONNAME); |
There was a problem hiding this comment.
I think, this solution may not work in all scenarios. Since hive.exec.default.partition.name is session configurable, that means, we can use different default partition names with multiple inserts. And when user does MSCK repair, if we take current configuration value of hive.exec.default.partition.name, it can fail.
There was a problem hiding this comment.
Yes, that case the solution won't work.
But IMO, its user's responsibility to create the default partition of same type as that of the partition column type and ensure no other datatype partition column is present.
Consider 2 scenarios where partition column is of INT type:
Scenario1:
User1 sets default partition conf value to "ANOTHER_PARTITION" and user 2 in another beeline session tries to insert data in default partition, then hdfs dir structure will look something like this:
path to table/part=ANOTHER_PARITION
path to table/part=__HIVE_DEFAULT_PARTITION__
and running msck repair will never succeed for any user. One user will get this
Caused by: java.lang.NumberFormatException: For input string: "ANOTHER_PARITION"
and other will get this
Caused by: java.lang.NumberFormatException: For input string: "__HIVE_DEFAULT_PARTITION__"
Scenario2:
User set default partition conf value to INT. Lets say 13, so hdfs dir structure looks like this
path to table/part=13
path to table/part=__HIVE_DEFAULT_PARTITION__
and in same session user creates a new table pointing of location of old table and run msck repair then it will fail for __HIVE_DEFAULT_PARTITION__.
Unless the user change the config back to __HIVE_DEFAULT_PARTITION__
Questions that I also have, is going forward what should be the expected behaviour? That the user has to ensure that there shouldn't be 2 partitions of different datatype than that of partition column as shown in scenario 1?
CC @ayushtkn @deniskuzZ -- please provide your insights on this?
Also, there are multiple places where __HIVE_DEFAULT_PARTITION__ is explicitly used instead of the config value. For instance here:
There was a problem hiding this comment.
I just had a quick look seems like the problem is coming post HIVE-23347, which added this method getNormalisedPartitionValue which does this parsing for numeric values. Before that patch things should have worked & Scenario-1 would have passed as well, with both values being shown in show partitions
This method getNormalisedPartitionValue looks like is valid only for numeric values to sort out some 0s or so. Maybe we can just have a numeric check & return rather than this default partition value matching
if(!NumberUtils.isParsable(partitionValue)) {
return partitionValue;
}
If we check the regular case without MSCK for scenario-1, the show partitions would show both the values, I tried locally
+------------------------------------------+
| partition |
+------------------------------------------+
| month=12/day=2 |
| month=12/day=3 |
| month=12/day=__HIVE_DEFAULT_PARTITION__ |
| month=__ANOTHER_PARTITION__/day=9 |
| month=__HIVE_DEFAULT_PARTITION__/day=3 |
+------------------------------------------+
5 rows selected (0.052 seconds)
0: jdbc:hive2://localhost:10000/>
So, post MSCK also we should show both those values. So, I believe we should just check whether the value is numeric or not, if not, just return the value as is..
There was a problem hiding this comment.
@ayushtkn Thanks for looking into this. Yes, I have update the PR based on your suggestion
6476ff1 to
7ceb72b
Compare
…lumn is of numeric type
7ceb72b to
ff4994b
Compare
| SHOW PARTITIONS tbl_y; | ||
|
|
||
| DROP TABLE tbl_x; | ||
| DROP TABLE tbl_y; |
There was a problem hiding this comment.
Thanks for adding great test cases
|
|
||
| if (!NumberUtils.isParsable(partitionValue)) { | ||
| return partitionValue; | ||
| } |
There was a problem hiding this comment.
I slightly suspect this can skip the case of decimal.
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#isParsable(java.lang.String)
There was a problem hiding this comment.
@okumin , thanks for the input. I think there is already a UT for this and passing post the patch. Please check
Let me know if I am missing something, but NumberUtils.isParsable(partitionValue) will return true for a decimal and later in same function it will be handled.
There was a problem hiding this comment.
I originally thought it could not work when Double.parseDouble can not decode it but new BigDecimal can decode it. An example in my mind was a huge number. Looking at the implementation, now I feel the current implementation would work
https://github.com/apache/commons-lang/blob/daa63aa595ea39a69e1b44ac23bc50fdcf2afd62/src/main/java/org/apache/commons/lang3/math/NumberUtils.java#L1794-L1810
|



What changes were proposed in this pull request?
HIVE-28654
Why are the changes needed?
To ensure msck repair command works when default partition "HIVE_DEFAULT_PARTITION" is present
Does this PR introduce any user-facing change?
NO
Is the change a dependency upgrade?
NO
How was this patch tested?
Using q files (present in PR)