yihua commented on code in PR #19304:
URL: https://github.com/apache/hudi/pull/19304#discussion_r4041638751


##########
hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableConfig.java:
##########
@@ -413,6 +414,17 @@ public static final String getDefaultPayloadClassName() {
       .sinceVersion("1.1.0")
       .withDocumentation("This property when set, will define how two versions 
of the record will be merged together when records are partially formed");
 
+  public static final ConfigProperty<String> COMPLEX_KEYGEN_ENCODING = 
ConfigProperty
+      .key("hoodie.table.complex.keygen.encoding")
+      .noDefaultValue()
+      .sinceVersion("1.1.0")

Review Comment:
   Should this be changed to `1.3.0`, or should `1.1.2` and `1.2.2` be added 
for minor releases?



##########
hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableConfig.java:
##########
@@ -1387,6 +1399,19 @@ public Option<PartialUpdateMode> getPartialUpdateMode() {
     }
   }
 
+  /**
+   * @return the persisted record key encoding of a single-field complex key 
generator table, if the
+   * table was upgraded from version 8 or below and the encoding was stamped. 
Empty for tables created at
+   * version 9 and above (which always use {@link 
ComplexKeyGenEncoding#FIELD_PREFIXED}) and for tables
+   * below version 9, where the property is never persisted.
+   */
+  public Option<ComplexKeyGenEncoding> getComplexKeyGenEncoding() {
+    if (getTableVersion().greaterThanOrEquals(HoodieTableVersion.NINE) && 
contains(COMPLEX_KEYGEN_ENCODING)) {
+      return 
Option.of(ComplexKeyGenEncoding.fromString(getString(COMPLEX_KEYGEN_ENCODING)));
+    }

Review Comment:
   Should we remove the condition 
`getTableVersion().greaterThanOrEquals(HoodieTableVersion.NINE)` so that table 
version 6 and 8 that are affected by the complex keygen issue can be 
automatically mitigated by the new table config as well?



##########
hudi-client/hudi-client-common/src/main/java/org/apache/hudi/keygen/KeyGenUtils.java:
##########
@@ -436,15 +456,154 @@ public static String getComplexKeygenErrorMessage(String 
operation) {
         + "`hoodie.write.complex.keygen.validation.enable=false` to skip this 
validation.";
   }
 
+  /**
+   * Whether a complex key generator with a single record key field prepends 
the field name to the key.
+   *
+   * <p>The encoding persisted on the table ({@link 
HoodieTableConfig#COMPLEX_KEYGEN_ENCODING}, stamped by the
+   * table version 8 to 9 upgrade from the table's existing data) is 
authoritative whenever it is present in
+   * the properties, because it describes what the data actually carries. 
Otherwise the write table version
+   * decides: 9 and above always prefix, 8 and below follow {@code 
hoodie.write.complex.keygen.new.encoding}.
+   */
   public static boolean 
encodeSingleKeyFieldNameForComplexKeyGen(TypedProperties props) {
+    String tableEncoding = 
props.getProperty(HoodieTableConfig.COMPLEX_KEYGEN_ENCODING.key());
+    if (!StringUtils.isNullOrEmpty(tableEncoding)) {
+      return 
ComplexKeyGenEncoding.fromString(tableEncoding).encodesFieldName();
+    }
     int tableVersionCode = ConfigUtils.getIntWithAltKeys(props, 
WRITE_TABLE_VERSION);
     HoodieTableVersion tableVersion = 
HoodieTableVersion.fromVersionCode(tableVersionCode);
     return tableVersion.greaterThanOrEquals(HoodieTableVersion.NINE)
         || !ConfigUtils.getBooleanWithAltKeys(props, 
COMPLEX_KEYGEN_NEW_ENCODING);
   }
 
+  /**
+   * Whether the record key encoding of a single-field complex key generator 
table is unknown to readers,
+   * i.e. the table is below version 9, where the encoding is a per-write 
decision that is never recorded.
+   */
   public static boolean mayUseNewEncodingForComplexKeyGen(HoodieTableConfig 
tableConfig) {
     return tableConfig.getTableVersion().lesserThan(HoodieTableVersion.NINE)
         && isComplexKeyGeneratorWithSingleRecordKeyField(tableConfig);
   }
+
+  /**
+   * The record key encoding a single-field complex key generator table is 
known to carry.
+   *
+   * @return the persisted encoding, or {@link 
ComplexKeyGenEncoding#FIELD_PREFIXED} for a table at version 9
+   * and above without the property (created there, never migrated); empty 
when the table does not use a
+   * single-field complex key generator or is below version 9 (encoding not 
recorded, see
+   * {@link #mayUseNewEncodingForComplexKeyGen}).
+   */
+  public static Option<ComplexKeyGenEncoding> 
resolveComplexKeyGenEncoding(HoodieTableConfig tableConfig) {
+    if (!isComplexKeyGeneratorWithSingleRecordKeyField(tableConfig)
+        || tableConfig.getTableVersion().lesserThan(HoodieTableVersion.NINE)) {
+      return Option.empty();
+    }
+    Option<ComplexKeyGenEncoding> persisted = 
tableConfig.getComplexKeyGenEncoding();
+    return Option.of(persisted.isPresent() ? persisted.get() : 
ComplexKeyGenEncoding.FIELD_PREFIXED);

Review Comment:
   It would be simpler to always follow the `ComplexKeyGenEncoding` in table 
config for complex keygen with single record key for table version 6 and above; 
if the table config does not exist in this case, it should always be inferred, 
backfilled in the table config and continue.  If it cannot be inferred due to 
conflicting evidence, fail the write to let user chime in. So we can get rid of 
default behavior.



-- 
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]

Reply via email to