anchor.diff:      : SHOW | TABLES | COLUMNS | PARTITIONS | FUNCTIONS
       | OVER | PARTITION | RANGE | ROWS | PRECEDING | FOLLOWING | CURRENT | ROW
       | REFRESH | MATERIALIZED | VIEW | ALIAS
  +    | YEAR | MONTH | DAY | HOUR | MINUTE | SECOND
       ;
   
   SELECT: 'SELECT';
  
positive.code:     | CURRENT_TIME ('(' integer ')')?              -> ^(CURRENT_TIME integer?)
      | CURRENT_TIMESTAMP ('(' integer ')')?         -> ^(CURRENT_TIMESTAMP integer?)
      | SUBSTRING '(' expr FROM expr (FOR expr)? ')' -> ^(FUNCTION_CALL ^(QNAME IDENT[$SUBSTRING]) expr expr expr?)
      | EXTRACT '(' extractFieldOrIdent FROM expr ')'-> ^(EXTRACT IDENT[$extractFieldOrIdent.text] expr)
      // handle function call-like syntax for extract
      | extractField '(' expr ')'                    -> ^(FUNCTION_CALL ^(QNAME IDENT[$extractField.text]) expr)
      | CAST '(' expr AS type ')'                    -> ^(CAST expr IDENT[$type.text])
      ;
  
  
negative.code:     | DOUBLE
      | BOOLEAN
      ;
  
  caseExpression
      : NULLIF '(' expr ',' expr ')'          -> ^(NULLIF expr expr)
  