Class StructuredArgumentFunction

java.lang.Object
dev.frostlake.functions.BuiltInFunction
dev.frostlake.functions.StructuredArgumentFunction
Direct Known Subclasses:
AsArray, AsBinary, AsBoolean, AsDate, AsDouble, AsObject, AsTime, AsVarchar, IsArray, IsBinary, IsBoolean, IsDate, IsDecimal, IsDoubleFn, IsInteger, IsNullValue, IsObject, IsTime, IsTimestampNtz, IsVarchar, ToJson, ToXml, TypeOf

public abstract class StructuredArgumentFunction extends BuiltInFunction
A built-in that reads its argument as a VARIANT and therefore refuses a STRUCTURED one — an OBJECT(x VARCHAR), an ARRAY(INT) or a MAP(VARCHAR, INT) — in EVERY argument position, while taking the plain semi-structured OBJECT and ARRAY happily. The structured twin of TextArgumentFunction, and the same live message shape ("Invalid argument types for function 'TO_JSON': (OBJECT(x VARCHAR(16777216)))", SQLSTATE 42P13) — only the type name is the whole parameterised type rather than the bare family.

This is a DIVERGENCE, not a generalisation: live over one table carrying both, TO_JSON(o) returns {"k":"v1"} and TYPEOF(o) returns OBJECT while TO_JSON(so) and TYPEOF(so) are compile errors. Snowflake will not implicitly convert a structured value to the VARIANT these functions read, and there is no run-time answer to fall back on, so the whole signature refuses it. An explicit conversion is legal and is how a caller opts in: TO_JSON(so::VARIANT), TO_JSON(so::OBJECT) and ARRAY_AGG(TO_VARIANT(so)) all work live.

Membership is by measurement, so close neighbours deliberately stay out. PARSE_JSON, CHECK_JSON and CHECK_XML refuse a plain OBJECT too, so they are not a DIVERGENCE and belong to the semi-structured rule if they are ever declared. AS_INTEGER, AS_DECIMAL, AS_NUMBER and the AS_TIMESTAMP_* trio refuse both kinds AND use a different sentence entirely ("invalid type [ARRAY] for parameter 'AS_INTEGER(variantValue...)'"), which is why the AS_* family is split down the middle here. And the ACCESSORS are untouched: GET, GET_PATH, OBJECT_KEYS, OBJECT_INSERT, ARRAY_SIZE, ARRAY_APPEND, MAP_KEYS and FLATTEN all read a structured value live.

  • Constructor Details

    • StructuredArgumentFunction

      protected StructuredArgumentFunction(String name, DataType returnType)
  • Method Details

    • structuredRejection

      public SemiStructuredRejection structuredRejection(int position)
      Description copied from class: BuiltInFunction
      The EXTRA refusal argument position reserves for a STRUCTURED value — OBJECT(x VARCHAR), ARRAY(INT), MAP(VARCHAR, INT) — where the plain semi-structured OBJECT or ARRAY is ACCEPTED. Consulted only when BuiltInFunction.semiStructuredRejection(int) declares nothing for the position, so a function that refuses every semi-structured value keeps saying so in one place.

      The two are separate because Snowflake genuinely treats OBJECT and OBJECT(x VARCHAR) as different types, and they DIVERGE — measured over populated columns of both: ARRAY_AGG(o) returns the array while ARRAY_AGG(so) is an argument-type error, TO_JSON(o) returns the JSON text while TO_JSON(so) is refused, and TYPEOF, IS_OBJECT, AS_VARCHAR, ARRAY_TO_STRING and the constructors all split the same way. A single rule keyed on "is this semi-structured?" gets both cases wrong in opposite directions, which is why the answer is asked twice.

      What a structured type does NOT get is a rejection anywhere the plain types are accepted as KEYS: live, GROUP BY so, ORDER BY so, SELECT DISTINCT so, PARTITION BY so, the set operators, JOIN … ON so = so and COUNT(DISTINCT so) all work over each of the three structured kinds — that was measured rather than inferred from the plain behaviour.

      The default is NONE for the same reason as above: undeclared means unconstrained.

      Overrides:
      structuredRejection in class BuiltInFunction
      Parameters:
      position - the zero-based argument position being asked about
      Returns:
      the extra refusal this position gives a structured value, or NONE when undeclared