CqlNaming

object CqlNaming

Shared CQL identifier naming/validation logic.

This is consumed by two independent call sites that must never drift apart:

  • SchemaRegistry.buildSchema (this module, runtime schema validation — see GH-30)

  • kandra-codegen's KandraProcessor.resolveCqlName (compile-time *Table generation)

kandra-codegen already has an implementation(project(":kandra-core")) compile dependency (needed to reference the annotation classes), so it calls these functions directly rather than re-implementing them — see KandraProcessor.kt, which delegates here instead of keeping its own copy. If you ever change the blank-name fallback or the identifier-shape rule, this is the only place to change it; both SchemaRegistry and KandraProcessor pick it up automatically.

Properties

Link copied to clipboard

Words that Cassandra 4.1 or ScyllaDB 2026.1 reject as a bare identifier. Every word in the keyword appendix of either grammar was tried as a bare column name in CREATE TABLE against both databases (GH #188); this is the union of the ones that failed (e.g. token, order, default), plus the documented reserved keywords that happened to parse in those versions (mbean, mbeans). Unreserved keywords such as timestamp, type, key, ttl, date or count are deliberately absent: they work bare, so their DDL stays byte-for-byte unchanged.

Functions

Link copied to clipboard

Naive camelCase -> snake_case conversion: every individual uppercase letter is replaced with _ + its lowercase form, then a leading underscore (from a name starting with a capital) is trimmed. No special-casing for acronyms or existing underscores/digits — "userId" ->"user_id", but "userURL" ->"user_u_r_l".

Link copied to clipboard

true when name (case-insensitively) is in RESERVED_WORDS.

Link copied to clipboard

Basic CQL identifier shape check: non-blank, first character is a letter or underscore, remaining characters are letters/digits/underscores. This is intentionally not a full CQL grammar validator (reserved words are handled by quoteIfNeeded) — it exists only to catch obvious mistakes (blank names, names starting with a digit, names containing spaces or punctuation) before they get spliced into DDL/DML strings.

Link copied to clipboard

Renders a column name for splicing into generated CQL. A reserved word is double-quoted in its lowercase form (token ->"token"), which names exactly the column an unquoted token would if the grammar allowed it, so existing tables, system_schema lookups and Row.get("token") reads keep working. Every other name is returned unchanged. GH #188.

Link copied to clipboard
fun resolveColumnName(columnAnnotationName: String?, propertyName: String): String

Resolves the CQL column name for a property given the raw @Column.name argument value, or null if the property carries no @Column annotation at all.