Class VariantJsonNulls

java.lang.Object
dev.frostlake.values.VariantJsonNulls

public final class VariantJsonNulls extends Object
The VARIANT JSON null (NULL_VALUE) versus SQL NULL boundary.

A JSON null is a real VARIANT value, not SQL NULL. Live-verified on a real account , with jn standing for PARSE_JSON('{"b":null}'):b:

   TYPEOF(jn)          -> 'NULL_VALUE'      jn IS NULL      -> FALSE
   IS_NULL_VALUE(jn)   -> TRUE              jn IS NOT NULL  -> TRUE
   TO_JSON(jn)         -> 'null'            EQUAL_NULL(jn, NULL) -> FALSE
 

A MISSING key stays SQL NULL and is a different thing entirely: live, PARSE_JSON('{"a":1}'):zz IS NULL is TRUE and TYPEOF(...) of it is SQL NULL.

The JSON null only becomes SQL NULL where it has to leave the semi-structured world and be read as an ordinary scalar. Live-verified in the same run:

   jn + 1  jn * 2  jn - 1     -> SQL NULL      jn || 'x'   CONCAT(jn,'x')  -> SQL NULL
   jn::INT  jn::VARCHAR  jn::BOOLEAN -> SQL NULL
   UPPER(jn)  LENGTH(jn)  ABS(jn)  TO_VARCHAR(jn) -> SQL NULL
   DATEADD(day, jn, d) -> SQL NULL
   COUNT(jn) -> 0    SUM/AVG/LISTAGG over {jn, 3} -> 3 / 3 / '3'   (the JSON null is skipped)
 

while the semi-structured and null-handling families keep seeing the value itself — live, COALESCE(jn, 9) returns the JSON null (so COALESCE(jn,9)::VARCHAR is SQL NULL, not 9), ARRAY_CONSTRUCT(jn) is [null], OBJECT_CONSTRUCT('k',jn) is {"k":null} and MIN/MAX order it as a value (MAX over {jn,5} is the JSON null, MIN is 5).

  • Method Details

    • isJsonNull

      public static boolean isJsonNull(Object value)
      Whether value is the VARIANT JSON null — a typed semi-structured null.
    • asScalar

      public static Object asScalar(Object value)
      The value as an ordinary scalar operand: a JSON null reads as SQL NULL, everything else is itself. Apply this wherever a VARIANT leaves the semi-structured world — arithmetic, string concatenation, a cast to a non-semi-structured type, a scalar function argument.
    • isValueAggregate

      public static boolean isValueAggregate(String aggregateName)
      Whether an aggregate of this name reads a JSON null as a value rather than as missing input.
    • asAggregateInput

      public static Object asAggregateInput(String aggregateName, Object value)
      The aggregate's input value: SQL NULL for a JSON null unless the aggregate orders or collects values rather than reading them as scalars.
    • asScalarArgs

      public static List<Object> asScalarArgs(List<Object> args)
      A copy of args with every JSON null read as SQL NULL, or args itself when nothing changes. Callers must skip this for variant-aware functions.