Inflector DuckDB Extension
The Inflector extension, developed by Query.Farm, brings powerful string case transformation and inflection capabilities directly to your SQL queries in DuckDB. Transform column names, validate naming conventions, handle pluralization, and moreโall without leaving your database environment.
Whether youโre normalizing API responses, migrating schemas between naming conventions, or ensuring consistent data formatting, Inflector makes string manipulation in SQL simple and efficient.
Use Cases
The Inflector extension is perfect for:
- Data normalization: Standardize column names and values to a consistent case style
- ETL pipelines: Transform and clean data during ingestion or export
- API and report generation: Match naming conventions for downstream systems
- Schema migration: Convert between naming conventions (snake_case, camelCase, etc.)
- Data validation: Check if strings conform to required case or format
- Pluralization/Singularization: Automatically convert between singular and plural forms
- Foreign key and module name handling: Generate or validate foreign key names and Ruby-style module paths
Installation
inflector is a DuckDB Community Extension.
You can install and load it with:
INSTALL inflector FROM community;
LOAD inflector;Quick Start
-- Install and load the extension
INSTALL inflector FROM community;
LOAD inflector;
-- Transform a single string
SELECT inflector_to_camel_case('hello_world'); -- helloWorld
-- Transform all column names in a struct
SELECT inflect('snake', {'firstName': 'John', 'lastName': 'Doe'});
-- {'first_name': John, 'last_name': Doe}
-- Transform all column names from a table or query
SELECT * FROM inflect('kebab', read_csv('data.csv'));Functions
Case Transformation Functions
Transform a string to a specific case style:
inflector_to_class_case(str)โClassCaseinflector_to_camel_case(str)โcamelCaseinflector_to_pascal_case(str)โPascalCaseinflector_to_screamingsnake_case(str)โSCREAMING_SNAKE_CASEinflector_to_snake_case(str)โsnake_caseinflector_to_kebab_case(str)โkebab-caseinflector_to_train_case(str)โTrain-Caseinflector_to_sentence_case(str)โSentence caseinflector_to_title_case(str)โTitle Caseinflector_to_table_case(str)โtable_namesinflector_to_upper_case(str)โUPPERCASEinflector_to_lower_case(str)โlowercase
Examples:
SELECT inflector_to_camel_case('hello_world') as v;
โโโโโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโโโโค
โ helloWorld โ
โโโโโโโโโโโโโโ
SELECT inflector_to_snake_case('HelloWorld') as v;
โโโโโโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโโโโโค
โ hello_world โ
โโโโโโโโโโโโโโโ
SELECT inflector_to_title_case('hello_world') as v;
โโโโโโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโโโโโค
โ Hello World โ
โโโโโโโโโโโโโโโPluralization and Singularization
inflector_to_plural(str)โ plural forminflector_to_singular(str)โ singular form
SELECT inflector_to_plural('person') as v;
โโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโค
โ people โ
โโโโโโโโโโโ
SELECT inflector_to_singular('ducks') as v;
โโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโค
โ duck โ
โโโโโโโโโโโOrdinalization
inflector_ordinalize(str)โ ordinal string (e.g.,1st,2nd)inflector_deordinalize(str)โ number string (e.g.,1stโ1)
SELECT inflector_ordinalize('5') as v;
โโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโค
โ 5th โ
โโโโโโโโโโโ
SELECT inflector_deordinalize('21st') as v;
โโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโค
โ 21 โ
โโโโโโโโโโโForeign Key and Module Functions
inflector_to_foreign_key(str)โ foreign key name (e.g.,Userโuser_id)inflector_demodulize(str)โ last module/class name (e.g.,A::B::CโC)inflector_deconstantize(str)โ parent module path (e.g.,A::B::CโA::B)
SELECT inflector_to_foreign_key('User') as v;
โโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโค
โ user_id โ
โโโโโโโโโโโ
SELECT inflector_demodulize('ActiveRecord::CoreExtensions::String::Inflections') as v;
โโโโโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโโโโค
โ Inflection โ
โโโโโโโโโโโโโโ
SELECT inflector_deconstantize('ActiveRecord::CoreExtensions::String::Inflections') as v;
โโโโโโโโโโโ
โ v โ
โ varchar โ
โโโโโโโโโโโค
โ String โ
โโโโโโโโโโโPredicate Functions
Check if a string matches a specific case or format:
inflector_is_class_case(str)inflector_is_camel_case(str)inflector_is_pascal_case(str)inflector_is_screamingsnake_case(str)inflector_is_snake_case(str)inflector_is_kebab_case(str)inflector_is_train_case(str)inflector_is_sentence_case(str)inflector_is_title_case(str)inflector_is_table_case(str)inflector_is_foreign_key(str)
Returns true or false.
Examples:
SELECT inflector_is_snake_case('hello_world') as v;
โโโโโโโโโโโ
โ v โ
โ boolean โ
โโโโโโโโโโโค
โ true โ
โโโโโโโโโโโ
SELECT inflector_is_camel_case('HelloWorld') as v;
โโโโโโโโโโโ
โ v โ
โ boolean โ
โโโโโโโโโโโค
โ false โ
โโโโโโโโโโโ
SELECT inflector_is_foreign_key('user_id') as v;
โโโโโโโโโโโ
โ v โ
โ boolean โ
โโโโโโโโโโโค
โ true โ
โโโโโโโโโโโStruct and Table Column Inflection
The inflect() function is the most powerful feature, allowing you to transform all column names in a struct or table result at once.
Inflect the keys of a STRUCT or tableโs column names to a target case style:
Syntax:
inflect('case_style', struct_or_table)Supported case styles:
'camel'/'camel_case'โ camelCase'class'/'class_case'โ ClassCase'snake'/'snake_case'โ snake_case'kebab'/'kebab_case'โ kebab-case'train'/'train_case'โ Train-Case'title'/'title_case'โ Title Case'table'/'table_case'โ table_names (pluralized snake_case)'sentence'/'sentence_case'โ Sentence case'upper'/'upper_case'โ UPPERCASE'lower'/'lower_case'โ lowercase
Examples:
SELECT inflect('snake', {'firstName': 1, 'lastName': 2}) as v;
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ v โ
โ struct(first_name integer, last_name integer) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ {'first_name': 1, 'last_name': 2} โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
SELECT inflect('class', {'first_name': 1, 'last_name': 2}) as v;
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ v โ
โ struct(firstname integer, lastname integer) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ {'FirstName': 1, 'LastName': 2} โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-- Table returning function.
SELECT n FROM inflect('camel', (SELECT 1 AS counterValue, 't' AS first_name)) AS n;
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ n โ
โ struct(countervalue integer, firstname varchar) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ {'counterValue': 1, 'firstName': t} โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโReal-World Examples
Normalize CSV Column Names
-- Convert PascalCase CSV headers to snake_case
SELECT * FROM inflect('snake', read_csv('UserData.csv'));
-- FirstName, LastName, EmailAddress โ first_name, last_name, email_addressTransform API Response Data
-- Convert camelCase JSON keys to snake_case for database storage
CREATE TABLE users AS
SELECT * FROM inflect('snake',
read_json('api_response.json')
);Validate Naming Conventions
-- Check if all column names follow snake_case convention
SELECT
column_name,
inflector_is_snake_case(column_name) as is_valid
FROM information_schema.columns
WHERE table_name = 'my_table';Schema Migration Between Conventions
-- Convert a Ruby on Rails style table to JavaScript convention
CREATE TABLE users_camel AS
SELECT * FROM inflect('camel', users);Generate Foreign Key Names
-- Create foreign key column names from table names
SELECT
table_name,
inflector_to_foreign_key(table_name) as fk_column
FROM information_schema.tables;Pluralize Table Names
-- Ensure all table names are plural
SELECT
table_name,
inflector_to_plural(table_name) as plural_name
FROM information_schema.tables;Clean and Standardize Text Data
-- Standardize mixed-case product categories
UPDATE products
SET category = inflector_to_title_case(category);Generate Display Labels
-- Convert snake_case column names to human-readable titles
SELECT
'first_name' as column,
inflector_to_title_case('first_name') as label; -- First NameAdvanced Usage
Nested Struct Transformation
-- Inflect nested struct keys recursively
SELECT inflect('camel', {
'user_info': {
'first_name': 'John',
'last_name': 'Doe'
}
}) as result;Bulk Column Validation
-- Find all columns that don't follow snake_case
WITH column_check AS (
SELECT
table_name,
column_name,
inflector_is_snake_case(column_name) as is_snake_case
FROM information_schema.columns
)
SELECT * FROM column_check WHERE NOT is_snake_case;Data Pipeline Transformation
SELECT * FROM inflect('snake', read_csv('example.csv'));Performance Considerations
- Transformation functions are highly optimized and work efficiently on large datasets
- The
inflect()function operates on column metadata, not data, making it very fast - Predicate functions can be used in WHERE clauses and are optimized for filtering
Tips and Best Practices
- Use the right case for your project: Consistent naming improves maintainability and reduces errors
- Validate data early: Use predicate functions in data quality checks during ETL
- Automate schema migrations: Use
inflect()to convert column names in bulk rather than manual renaming - Combine with DuckDBโs JSON/struct features: Inflect nested data structures from APIs and config files
- Standardize imports: Apply inflection when reading external data (CSV, JSON, Parquet)
- Use table_case for database tables: Automatically pluralizes and converts to snake_case
- Document your conventions: Choose a case style and stick with it across your project
Error Handling
The extension provides clear error messages for common issues:
-- Unknown case style
SELECT inflect('unknown', {'foo': 1});
-- Error: Unknown inflection 'unknown'. Supported: camel, class, snake, kebab, train, title, table, sentence, upper, lower
-- Invalid arguments
SELECT inflect('snake');
-- Error: inflect() requires exactly two arguments: function name and value to inflectFrequently Asked Questions
Q: Whatโs the difference between class_case and pascal_case?
A: Theyโre the same! Both produce PascalCase output.
Q: Can I use inflect() on a table with millions of rows?
A: Yes! The inflect() function only transforms column names, not the data itself, so itโs extremely fast regardless of table size.
Q: Does table_case always pluralize?
A: Yes, table_case converts to snake_case and pluralizes the name (e.g., User โ users).
Q: Can I chain transformations?
A: Yes! You can nest inflect() calls or pipe results through multiple transformations.
Contributing
The Inflector extension is open source and developed by Query.Farm.
License
Love โค๏ธ this DuckDB extension? Youโll Love This.
Get the best from Query.Farm โ smart tips, powerful tools, and project updates sent directly to your inbox, but only when weโve got something great to share.