Class ValueComparisons

java.lang.Object
dev.frostlake.executor.ValueComparisons

public final class ValueComparisons extends Object
Stateless value/ordering comparison helpers extracted from QueryExecutor. These are pure functions used by sort, DISTINCT, and column-resolution logic across query stages; none of them read engine instance state.
  • Method Details

    • findColumnIndex

      public static int findColumnIndex(Table table, String columnName)
      Like getColumnIndex(dev.frostlake.metastore.model.Table, java.lang.String) but answers -1 instead of throwing — for callers probing whether a text is a bare column at all (the throw built a stack trace per probe).
    • getColumnIndex

      public static int getColumnIndex(Table table, String columnName)
    • normalizeValueForDistinct

      public static Object normalizeValueForDistinct(Object value)
      Normalize a value for DISTINCT comparison. Converts numbers to Double for consistent comparison (e.g., 1 == 1.0).
    • canonicalGroupKeyValue

      public static Object canonicalGroupKeyValue(Object value)
      Canonicalize one grouping-key value so equal numbers with different runtime types land in the same bucket: Integer 1, Long 1, Double 1.0 and BigDecimal 1.00 must form one group (mixed representations arise from VARIANT casts, set-operation branches and literal folding). Unlike the join-key normalizer this must not over-group — the bucket IS the grouping decision, with no downstream re-confirmation — so only exact-value numeric canonicalization is applied; strings, temporals and booleans pass through unchanged. Integral values become Long, everything else a trailing-zero-stripped BigDecimal, both of which honor equals/hashCode.
    • compareValues

      public static int compareValues(Object v1, Object v2)
    • compareForExtreme

      public static int compareForExtreme(Object v1, Object v2)
      The comparison an EXTREME uses — MIN, MAX, GREATEST and LEAST — which differs from compareValues(java.lang.Object, java.lang.Object) in one cell: -0.0 and 0.0 are a TIE, so whichever was seen first is kept. Live answers -0 for GREATEST(-0.0::FLOAT, 0.0::FLOAT) and for MAX over the same pair in that order, and 0 for either written the other way round; a sort-style comparator that puts -0 first would pick the wrong one half the time.
      Parameters:
      v1 - one value
      v2 - the other
      Returns:
      negative, zero (a tie) or positive
    • nullsFirstFlag

      public static Boolean nullsFirstFlag(FrostlakeParser.OrderItemContext item)
      NULLS FIRST → TRUE, NULLS LAST → FALSE, unspecified → null, for an ORDER BY item.
    • compareOrderKey

      public static int compareOrderKey(Object v1, Object v2, boolean ascending, Boolean nullsFirst)
      Compare two ORDER BY key values, returning the final (already ASC/DESC-adjusted) ordering. NULL placement follows an explicit NULLS FIRST/LAST when nullsFirst is non-null, otherwise the Snowflake default: NULLS LAST for ASC, NULLS FIRST for DESC.
    • isNumericDotted

      public static boolean isNumericDotted(String s)
      True when s matches \d+\.\d+ (a numeric literal like 1.5), to tell it from a qualified name.