Back to The Four Attributes

Attributes · The Four Attributes · Practice Question

What Does It Mean That Attributes Are "Descriptive, Not Prescriptive"?

Sign in to track your progress

Question

Explain the statement "kdb+ attributes are descriptive, not prescriptive." What happens when you apply s# to an unsorted list? What about p# to a non-contiguous list?

Solution

/ All three structured attributes validate at apply time:

/ s# — throws 's-fail if not sorted
`s# 4 2 5 1 3           / 's-fail

/ u# — throws 'u-fail if not unique
`u# 1 2 1 3 4           / 'u-fail

/ p# — throws 'u-fail if not contiguous
`p# 1 1 2 3 4 1 2       / 'u-fail — 1 appears non-contiguously

/ p# succeeds only when values are genuinely contiguous (grouped)
`p# 1 1 2 2 3 3         / ok — each value forms one contiguous block
`p# `AAPL`AAPL`GOOG`GOOG`MSFT   / ok

/ g# — no structural constraint, always succeeds
`g# 1 2 1 3 2 1         / ok — any order, any values

/ Descriptive: attributes assert existing structure
/ They do NOT sort, deduplicate, or reorganise the data for you
L: `s# asc 5 3 1 4 2    / correct: sort first, then assert s#
L: asc 5 3 1 4 2        / asc automatically applies s# anyway

Explanation

Descriptive means an attribute is a declaration: "this data has this structure." kdb+ validates the declaration at apply time and uses it to choose a faster algorithm. It does not impose or maintain the structure going forward.

Prescriptive would mean "enforce this structure going forward." Attributes are not prescriptive — applying g# to a sym column does not prevent you from inserting a row that breaks some invariant; it just maintains the inverted index as data arrives. Applying s# does not re-sort the list when you append a smaller element — it drops the attribute.

Validation at apply time:

All three structured attributes check the data when you apply them:

  • s# — verifies ascending order → 's-fail if not
  • u# — verifies uniqueness → 'u-fail if not
  • p# — verifies contiguity → 'u-fail if not (same error code as u#)
  • g# — no constraint to check → always succeeds

After apply, kdb+ does not maintain the guarantee. This is the "descriptive" part. If you apply s# to a sorted list and then insert a smaller value (n,: smallValue), the attribute is silently dropped — kdb+ detects the violation and removes the attribute rather than leaving it in an inconsistent state. Similarly, p# is dropped on any append (even one that would maintain contiguity). Always re-check with attr after mutations if the attribute matters for query correctness.

The correct EOD sequence for HDB:

/ Sort first — this is what makes the data parted
`sym xasc `:/hdb/2025.01.01/trade/

/ Then assert p# — will throw if xasc failed or data has issues
@[`:/hdb/2025.01.01/trade/; `sym; `p#]

/ WRONG order — xasc strips p# immediately after it was applied
@[`:/hdb/2025.01.01/trade/; `sym; `p#]   / p# set
`sym xasc `:/hdb/2025.01.01/trade/        / xasc then drops p#