Data Types#
Concourse is a dynamically typed database. Value types are intelligently inferred when data is written, and comparisons can be made across compatible types. You never need to declare a schema or specify column types.
Primitive Types#
Boolean#
A true or false value. Booleans are stored as a single byte
and support equality and inequality comparisons.
1 2 | |
1 2 | |
Double#
A 64-bit IEEE 754 double-precision floating-point number. Use
Double for high-precision decimal values or very large/small
numbers.
1 2 | |
Concourse distinguishes between Double and Float values. If
precision matters, be explicit about which type you use.
Float#
A 32-bit IEEE 754 single-precision floating-point number. Values
written as floating-point literals without a type suffix are stored
as Float by default.
1 2 | |
Integer#
A 32-bit signed integer, supporting values from -2,147,483,648 to
2,147,483,647. Whole numbers within this range are stored as
Integer by default.
1 2 | |
1 2 | |
Long#
A 64-bit signed integer, supporting values from
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Whole
numbers that exceed the Integer range are automatically stored
as Long.
1 2 | |
String#
A UTF-8 encoded character sequence. Strings are automatically indexed for full-text search, enabling substring and keyword matching.
1 2 | |
1 2 | |
String vs Tag
If you do not want a string value to be indexed for full-text search, store it as a Tag instead.
Tag#
A Tag is a string that is not indexed for full-text search.
Use Tags for structured or categorical data (e.g., identifiers,
codes, enum-like values) where full-text search is unnecessary.
Once stored, a Tag is treated as a String for all other purposes. Tag values are returned as Strings when read back, and queries treat Tags and Strings identically for comparison.
1 2 | |
Timestamp#
A Timestamp represents a point in time with microsecond
precision. Internally, it is a 64-bit signed integer counting
microseconds since the Unix epoch (January 1, 1970 00:00:00 UTC).
The signed representation supports dates approximately 290,000
years into the past and future.
1 2 | |
Creating Timestamps#
1 2 3 4 5 6 7 8 9 10 11 12 | |
Natural Language Timestamps#
The Timestamp.fromString method accepts natural language
descriptions of time, which are especially useful in CaSH and
for time travel queries.
1 2 3 4 5 | |
Link#
A Link is a pointer to another record, identified by that
record’s unique ID. Links are the foundation of Concourse’s
graph features, enabling you to model relationships
between records and traverse them with navigation queries.
Links are directional — a link from record 1 to record 2 does not imply a link from record 2 back to record 1.
1 2 3 | |
Links are displayed with an @ prefix (e.g., @100) when read
back from Concourse.
Link Queries#
You can query for records that link to a specific record using the
LINKS_TO operator:
1 | |
1 2 3 4 | |
Link Navigation#
Use dot-separated navigation keys to traverse links and read data from linked records. See Graph for details.
NULL#
The NULL type represents the absence of a value. Concourse
handles nulls internally in certain operations (e.g., when a key
has no value in a record). You typically do not write null values
directly.
Advanced Types#
Dynamic Link#
A dynamic link is a conceptual relationship where the set of linked records is determined by evaluating a criteria at read time. Unlike a resolvable link, which is evaluated once at write time and produces static links, a dynamic link would re-evaluate its criteria on every read.
Note
Concourse does not currently have a native dynamic link type.
To achieve dynamic link behavior, use a
navigation key query
that evaluates criteria at read time. For example,
employer.name = "Cinchapi" dynamically finds all records
whose linked employer has a matching name.
Resolvable Link#
A resolvable link is a write-time instruction to create links
to all records that match a given criteria. Unlike a regular Link,
a resolvable link is evaluated once at the time of write. The
resulting links are static and do not change as the matching
criteria’s results change over time.
Use Link.toWhere(criteria) to create a resolvable link
instruction within an insert operation:
1 2 3 4 5 6 | |
Only use within insert operations
Resolvable links should only be used within insert
operations (JSON, Map, or Multimap). Do not use add to
write resolvable links because the evaluation and linking
would not be atomic.
Type Inference and Coercion#
Concourse automatically infers the type of a value when it is written. In most cases, the inferred type matches what you expect:
| Input | Inferred Type |
|---|---|
true / false |
Boolean |
42 |
Integer |
8000000000 |
Long |
3.14 |
Float |
3.14d |
Double |
"hello" |
String |
Tag.create("x") |
Tag |
Link.to(5) |
Link |
Cross-Type Comparisons#
Concourse supports comparisons across compatible numeric types.
An Integer value of 42 is considered equal to a Long value
of 42, and numeric ordering works across Integer, Long,
Float, and Double types.
String and Tag values are compared as strings, regardless of which type was used during the write.