Null in the OData Standard

Kenneth Baclawski, Northeastern University
June 2, 2016

The concept of "null" is used both in relational databases and programming languages. However, as noted in The Meaning of Null, the relational database notion of "null" is very different from the notion of "null" in most programming languages. The main distinction between the relational database "null" and the programming language "null" is the following: The RDB "null" represents the absence of a value in a field of a record; whereas the PL "null" represents one of the possible values of a variable. Succinctly,

The programming language null is a value but database null is not a value.

The Open Data Protocol (OData) is an open protocol which allows the creation and consumption of queryable and interoperable RESTful APIs in a simple and standard way. OData shares some similarities with JDBC and ODBC. Unlike SQL, OData is not limited to relational databases. One of the data formats supported by OData is JSON.

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is based on a subset of the JavaScript Programming Language. Although JSON is programming language independent, it obviously has a close connection with JavaScript. A JSON value can be an object, array, string, number, Boolean or null. All of these are disjoint possibilities. There is, in fact, one additional possibility; namely, that no value is specified. In JavaScript this last possibility is called "undefined". Consider the following JavaScript statement:

var x = {
  "field1" : 10,
  "field2" : null
}
In this case, x.field1 has value 10, x.field2 is null and x.field3 is undefined. These three cases are distinguishable from one another in JavaScript.

JavaScript has two different equality operators: loose and strict. Nulls are not loosely equal to each other, but they are strictly equal to each other. To test for null and undefined, one must use strict equality. (In fact, as of 2015, JavaScript now has three different equality operators, and the third equality operator could also be used to distinguish null and undefined.)

This report examines the meaning of null in OData. It is meant as a starting point for discussion, and it is not necessarily either complete or correct in all details.

Null in the OData Protocol

We now discuss what null means in the OData Protocol OData Version 4.0 Part 1: Protocol.

Null in the OData URL Conventions

We now discuss what null means in the OData URL conventions OData Version 4.0 Part 2: URL Conventions.

Null in OData CSDL

There are many examples in the CSDL that have "OnDelete":null. While it should be clear that this means that there is no OnDelete element, it might be helpful to mention this. See 7.3 Element edm:OnDelete.

Null in OData JSON Format

We now discuss what null means in the OData JSON Format OData JSON Format Version 4.0.

Null in OData Atom Format

There is nothing to add for this format beyond what was said for JSON.

Summary

In most cases, the OData null means that there is an absence of a value. For example, it often means "no content", and it is also used to mean that a parameter has not been specified. However, OData null is clearly a value which can be compared with other values. This places OData somewhere in between RDBs and PLs with respect to null. This alone does not mean that OData is inconsistent. However, there are some places where there appear to be some problems.

The role of null in logical and arithmetic operators is problematic. While logical operators are supposed to evaluate only to true or false, the and and or operators can evaluate to null. This has the effect of introducing a 3-valued logic, as well as a new meaning for null. The OData 3-valued logic differs from the 3-valued logic of SQL where a null operand in an comparison expression will cause the expression to evaluate to null. The new meaning for null is "unknown" rather than "no value".

A somewhat minor issue is that the gt and lt operators return false if either operand is null, but when sorting null precedes other values.

While the null literal is untyped, one can cast null to any type. This introduces typed nulls. It is unclear whether nulls of different types are still equal.

The difference between "unknown" and "no value" has an effect on the any and all operators. If null is "no value", then nulls should be ignored when computing these operators. However, if null is "unknown", then nulls are part of the collection and since they are not true, they should be treated as being false.

Still another meaning of null is introduced in odata.id. This new meaning is inconsistent with the "no value" meaning, since omitting odata.id has an explicitly different meaning.