38 · HANA-Specific Types

Use HANA-specific types: LargeString (NCLOB), LargeBinary (BLOB), hana.ST_POINT, and hana.tableType.

Episode 38 — HANA-Specific CDS Types & Features

What you'll learn

Why this matters

HANA Cloud offers column types and indexing strategies unavailable in SQLite. Knowing which annotations unlock them saves you from hand-crafting native SQL for features CAP can generate automatically.

Standard CDS types (all databases)

CDS type HANA type SQLite type
String(n) NVARCHAR(n) TEXT
Integer INTEGER INTEGER
Decimal(p, s) DECIMAL(p, s) REAL
Boolean BOOLEAN INTEGER
Date DATE TEXT
DateTime SECONDDATE TEXT
Timestamp TIMESTAMP TEXT
UUID NVARCHAR(36) TEXT
Binary(n) VARBINARY(n) BLOB

Large types

entity Documents {
  key ID      : UUID;
  title       : String;
  body        : LargeString;    // → NCLOB in HANA (up to 2GB text)
  attachment  : LargeBinary;   // → BLOB in HANA (up to 2GB binary)
  thumbnail   : Binary(32768); // small fixed-size binary
}

Use LargeString for rich text, JSON, or Markdown content. Use LargeBinary for file attachments. Never select LargeString/LargeBinary columns in list queries — fetch them only for individual records.

HANA-specific native types

// Opt in to HANA-native types with cds.hana namespace
using { cds.hana } from '@sap/cds/common';

entity Locations {
  key ID       : UUID;
  name         : String;
  coordinates  : hana.ST_POINT;    // spatial point (lat/lon)
  boundary     : hana.ST_GEOMETRY; // polygon / multipolygon
}
-- OData exposes these as opaque strings; use native SQL for spatial queries
SELECT ID, name,
  coordinates.ST_AsGeoJSON() AS geoJson,
  coordinates.ST_Distance(ST_GeomFromText('POINT(13.4 52.5)','WGS84')) AS distanceM
FROM Locations
ORDER BY distanceM;

Full-text index annotation

entity Books {
  key ID      : UUID;
  title       : String @hana.fullTextIndex;        // basic full-text
  description : String @hana.fullTextIndex: {
    fuzzySearchIndex: true,                         // fuzzy matching
    text_analysis:    true                          // language detection
  };
}

Enables HANA's CONTAINS() predicate in OData $filter:

GET /Books?$filter=contains(description,'machine learning')&fuzzy=0.8

Column table vs row table

entity FactSales @hana.tableType: 'COLUMN' {  // default for HANA
  // good for analytical queries
}
entity SessionLog @hana.tableType: 'ROW' {    // transactional
  // good for high-frequency inserts/updates
}

Collation (case-sensitive search)

entity Products {
  code : String @hana.collation: 'BINARY';  // exact case match
  name : String;                             // UNICODE by default (case-insensitive)
}

HANA-specific annotations summary

Annotation Effect
@hana.fullTextIndex Creates full-text index on the column
@hana.tableType: 'COLUMN' Column store (default); analytical workloads
@hana.tableType: 'ROW' Row store; transactional workloads
@hana.collation: 'BINARY' Case-sensitive string comparison
@hana.storeType: 'PAGE' Page-based blob storage

Type compatibility table (important for migration)

Your intent Use on SQLite Use on HANA
Long text (markdown, JSON) LargeString LargeString → NCLOB
File content LargeBinary LargeBinary → BLOB
UUID primary key UUID UUID → NVARCHAR(36)
Geographic point Not available hana.ST_POINT

Hands-on exercise

  1. Add description: LargeString to your Books entity
  2. Annotate title with @hana.fullTextIndex: { fuzzySearchIndex: true }
  3. Add a location: hana.ST_POINT field to a Stores entity
  4. Build with cds build --for hana and inspect the generated artifact to confirm NCLOB vs NVARCHAR

Checkpoint ✓

Sign in for progress tracking & Q&A →