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]

Reply via email to