This is an automated email from the ASF dual-hosted git repository.
xiangfu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 6d0eb45c9c8 Add INITCAP scalar function to Apache Pinot (#17642)
6d0eb45c9c8 is described below
commit 6d0eb45c9c85cea131ce49f75e80d1509bb781d8
Author: Akanksha kedia <[email protected]>
AuthorDate: Fri Feb 20 10:44:32 2026 +0530
Add INITCAP scalar function to Apache Pinot (#17642)
- Implements INITCAP function that converts the first letter of each word
to uppercase and the rest to lowercase
- Words are delimited by whitespace characters (space, tab, newline, etc.)
- Handles edge cases: empty strings, single characters, multiple spaces,
special characters
- Includes comprehensive unit tests with 40+ test cases covering various
scenarios
- Follows existing code patterns and includes proper Javadoc documentation
---
.../common/function/scalar/StringFunctions.java | 34 +++++++++++++
.../function/scalar/StringFunctionsTest.java | 58 ++++++++++++++++++++++
2 files changed, 92 insertions(+)
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/StringFunctions.java
b/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/StringFunctions.java
index d09debc6faf..03d8d1aa2d0 100644
---
a/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/StringFunctions.java
+++
b/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/StringFunctions.java
@@ -73,6 +73,40 @@ public class StringFunctions {
return input.toUpperCase();
}
+ /**
+ * Converts the first letter of each word to uppercase and the rest to
lowercase.
+ * Words are delimited by whitespace characters.
+ * This is a standard SQL function for title case conversion.
+ *
+ * @param input the input string to convert
+ * @return string with the first letter of each word capitalized and the
rest in lowercase
+ */
+ @ScalarFunction
+ public static String initcap(String input) {
+ if (input == null || input.isEmpty()) {
+ return input;
+ }
+
+ StringBuilder result = new StringBuilder(input.length());
+ boolean capitalizeNext = true;
+
+ for (int i = 0; i < input.length(); i++) {
+ char currentChar = input.charAt(i);
+
+ if (Character.isWhitespace(currentChar)) {
+ result.append(currentChar);
+ capitalizeNext = true;
+ } else if (capitalizeNext) {
+ result.append(Character.toUpperCase(currentChar));
+ capitalizeNext = false;
+ } else {
+ result.append(Character.toLowerCase(currentChar));
+ }
+ }
+
+ return result.toString();
+ }
+
/**
* @see String#substring(int)
* @param input Parent string
diff --git
a/pinot-common/src/test/java/org/apache/pinot/common/function/scalar/StringFunctionsTest.java
b/pinot-common/src/test/java/org/apache/pinot/common/function/scalar/StringFunctionsTest.java
index 9a4aadbd587..523c4971485 100644
---
a/pinot-common/src/test/java/org/apache/pinot/common/function/scalar/StringFunctionsTest.java
+++
b/pinot-common/src/test/java/org/apache/pinot/common/function/scalar/StringFunctionsTest.java
@@ -94,6 +94,59 @@ public class StringFunctionsTest {
};
}
+ @DataProvider(name = "initcapTestCases")
+ public static Object[][] initcapTestCases() {
+ return new Object[][]{
+ // Basic test cases
+ {"hello world", "Hello World"},
+ {"HELLO WORLD", "Hello World"},
+ {"hello WORLD", "Hello World"},
+ {"HeLLo WoRLd", "Hello World"},
+
+ // Single word
+ {"hello", "Hello"},
+ {"HELLO", "Hello"},
+ {"hELLO", "Hello"},
+
+ // Multiple spaces
+ {"hello world", "Hello World"},
+ {"hello world test", "Hello World Test"},
+
+ // Leading and trailing spaces
+ {" hello world", " Hello World"},
+ {"hello world ", "Hello World "},
+ {" hello world ", " Hello World "},
+
+ // Special characters and numbers
+ {"hello-world", "Hello-world"},
+ {"hello_world", "Hello_world"},
+ {"hello123world", "Hello123world"},
+ {"123hello world", "123hello World"},
+
+ // Mixed whitespace characters
+ {"hello\tworld", "Hello\tWorld"},
+ {"hello\nworld", "Hello\nWorld"},
+ {"hello\rworld", "Hello\rWorld"},
+
+ // Edge cases
+ {"", ""},
+ {" ", " "},
+ {"a", "A"},
+ {"A", "A"},
+
+ // Real-world examples
+ {"apache pinot", "Apache Pinot"},
+ {"the quick brown fox", "The Quick Brown Fox"},
+ {"SQL is AWESOME", "Sql Is Awesome"},
+ {"new york city", "New York City"},
+
+ // Unicode and special characters
+ {"café résumé", "Café Résumé"},
+ {"[email protected]", "[email protected]"},
+ {"one,two,three", "One,two,three"}
+ };
+ }
+
@DataProvider(name = "levenshteinDistanceTestCases")
public static Object[][] levenshteinDistanceTestCases() {
return new Object[][]{
@@ -160,6 +213,11 @@ public class StringFunctionsTest {
assertEquals(StringFunctions.suffixesWithSuffix(input, length, "$"),
expectedSuffixWithRegexChar);
}
+ @Test(dataProvider = "initcapTestCases")
+ public void testInitcap(String input, String expected) {
+ assertEquals(StringFunctions.initcap(input), expected);
+ }
+
@Test(dataProvider = "levenshteinDistanceTestCases")
public void testLevenshteinDistance(String input1, String input2, int
expectedDistance) {
assertEquals(StringFunctions.levenshteinDistance(input1, input2),
expectedDistance);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]