From 34d78fd8ed3eddc4ae53e90946839cae801789d4 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Thu, 3 Sep 2026 11:52:00 -0500 Subject: [PATCH 1/2] docs: state varchar/char defaults to '' as a rule, not a preference NULL and '' both read as "nothing," and allowing both on a string attribute forces every query and make() body to handle two representations of the same absence. Surfaced by a live example in datajoint-python#1548, whose own new test fixtures defaulted varchar attributes to NULL. --- src/reference/definition-syntax.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/reference/definition-syntax.md b/src/reference/definition-syntax.md index dcdb1f22..dc6181be 100644 --- a/src/reference/definition-syntax.md +++ b/src/reference/definition-syntax.md @@ -92,8 +92,13 @@ ratio = NULL : float64 # Nullable (only NULL can be default) **Nullable attributes:** An attribute is nullable if and only if its default is `NULL`. DataJoint does not allow other defaults for nullable attributes—this prevents ambiguity -about whether an attribute is optional. For strings, prefer empty string `''` as the -default rather than `NULL`. +about whether an attribute is optional. + +**`varchar` and `char` attributes should default to `''`, not `NULL`.** `NULL` and `''` +both read as "nothing," and once an attribute allows both, every query and every `make()` +body has to handle two representations of the same absence. Reserve `NULL` for an +attribute that is genuinely optional and where "not yet known" must be distinguishable +from "known to be empty"—a case that arises rarely for text. ## Comments From 6da0f626a6e3958893a56e5140a43806c6b258c8 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Thu, 3 Sep 2026 12:05:53 -0500 Subject: [PATCH 2/2] docs: extend the empty-string-default rule to enum attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An enum's closed value set is exactly the place to add '' as an explicit member rather than reaching for NULL — no reason to layer a second absence-mechanism on a type that already enumerates its allowed values. --- src/reference/definition-syntax.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/reference/definition-syntax.md b/src/reference/definition-syntax.md index dc6181be..f4b67a24 100644 --- a/src/reference/definition-syntax.md +++ b/src/reference/definition-syntax.md @@ -86,6 +86,7 @@ raw_path : # Portable file reference status = "pending" : varchar(20) # String default count = 0 : int32 # Numeric default notes = '' : varchar(1000) # Empty string default (preferred for strings) +stage = '' : enum('', 'draft', 'reviewed', 'released') # Empty-string member (preferred for enums) created = CURRENT_TIMESTAMP : datetime # Auto-timestamp ratio = NULL : float64 # Nullable (only NULL can be default) ``` @@ -94,11 +95,15 @@ ratio = NULL : float64 # Nullable (only NULL can be default) DataJoint does not allow other defaults for nullable attributes—this prevents ambiguity about whether an attribute is optional. -**`varchar` and `char` attributes should default to `''`, not `NULL`.** `NULL` and `''` -both read as "nothing," and once an attribute allows both, every query and every `make()` -body has to handle two representations of the same absence. Reserve `NULL` for an -attribute that is genuinely optional and where "not yet known" must be distinguishable -from "known to be empty"—a case that arises rarely for text. +**`varchar`, `char`, and `enum` attributes should default to `''`, not `NULL`.** `NULL` +and `''` both read as "nothing," and once an attribute allows both, every query and every +`make()` body has to handle two representations of the same absence. For `enum`, this +means adding `''` as an explicit member rather than making the attribute nullable—the +empty string is then just another value the type already enumerates, not a second +absence-mechanism layered on top of it. Reserve `NULL` for an attribute that is +genuinely optional and where "not yet known" must be distinguishable from "known to be +empty"—a case that arises rarely for text, and rarer still for a closed set of values a +schema author chose in the first place. ## Comments