docs: private Expression readColumnOrFunctionExpression() {
  
          String  name           = token.tokenString;
          boolean isSimpleQuoted = isDelimitedSimpleName();
          String  prefix         = token.namePrefix;
          String  prePrefix      = token.namePrePrefix;
  
          if (isUndelimitedSimpleName()) {
              // A VoltDB extension to augment the standard sql function set.
              FunctionSQL function;
              function = FunctionForVoltDB.newVoltDBFunction(name);
              if (function == null) {
                  // These seem to be JDBC ("Open Group"?) aliases and extensions to the standard sql functions.
                  function = FunctionCustom.newCustomFunction(token.tokenString, token.tokenType);
              }
              /* disable 3 lines ...
              FunctionSQL function =
                  FunctionCustom.newCustomFunction(token.tokenString,
                                                   token.tokenType);
              ... disabled 3 lines */
              // End of VoltDB extension
  
              if (function != null) {
                  int pos = getPosition();
  
                  // A VoltDB extension to avoid abusing the exception handling mechanism
                  // for normal flow control.
                  HsqlException ex = null;
                  try {
                      ExpressionOrException result = readSQLFunction(function, false);
                      ex = result.exception();
                      if (ex == null) {
                          return result.knownGood();
                      }
                  } catch (HsqlException caught) {
                      ex = caught;
                  }
                  if (ex != null) {
                  /* disable 3 lines ...
                  try {
                      return readSQLFunction(function);
                  } catch (HsqlException ex) {
                  ... disabled 3 lines */
                  // End of VoltDB extension
                      ex.setLevel(compileContext.subQueryDepth);
  
                      if (lastError == null
                              || lastError.getLevel() < ex.getLevel()) {
                          lastError = ex;
                      }
  
                      rewind(pos);
                  }
              } else if (isReservedKey()) {
                  function = FunctionSQL.newSQLFunction(name, compileContext);
  
                  if (function != null) {
                      // It's not really clear why readSQLFunction exceptions just get thrown through here
                      // but get post-processed in the similar call above for FunctionForVoltDB and FunctionCustom
                      return readSQLFunction(function);
                  }
              }
          }
  
          read();
  
          if (token.tokenType != Tokens.OPENBRACKET) {
              Expression column = new ExpressionColumn(prePrefix, prefix, name);
  
              return column;
          }
  
          checkValidCatalogName(prePrefix);
  
          prefix = session.getSchemaName(prefix);
  
          RoutineSchema routineSchema =
              (RoutineSchema) database.schemaManager.findSchemaObject(name,
                  prefix, SchemaObject.FUNCTION);
  
          if (routineSchema == null && isSimpleQuoted) {
              HsqlName schema =
                  database.schemaManager.getDefaultSchemaHsqlName();
  
              routineSchema =
                  (RoutineSchema) database.schemaManager.findSchemaObject(name,
                      schema.name, SchemaObject.FUNCTION);
  
              if (routineSchema == null) {
                  Method[]  methods  = Routine.getMethods(name);
                  Routine[] routines = Routine.newRoutines(methods);
                  HsqlName routineName = database.nameManager.newHsqlName(schema,
                      name, true, SchemaObject.FUNCTION);
  
                  for (int i = 0; i < routines.length; i++) {
                      routines[i].setName(routineName);
                      session.database.schemaManager.addSchemaObject(
                          routines[i]);
                  }
  
                  routineSchema =
                      (RoutineSchema) database.schemaManager.findSchemaObject(
                          name, schema.name, SchemaObject.FUNCTION);
              }
          }
  
          if (routineSchema == null) {
              throw Error.error(ErrorCode.X_42501, name);
          }
  
          HsqlArrayList list = new HsqlArrayList();
  
          readThis(Tokens.OPENBRACKET);
  
          if (token.tokenType == Tokens.CLOSEBRACKET) {
              read();
          } else {
              while (true) {
                  Expression e = XreadValueExpression();
  
                  list.add(e);
  
                  if (token.tokenType == Tokens.COMMA) {
                      read();
                  } else {
                      readThis(Tokens.CLOSEBRACKET);
  
                      break;
                  }
              }
          }
  
          FunctionSQLInvoked function  = new FunctionSQLInvoked(routineSchema);
          Expression[]       arguments = new Expression[list.size()];
  
          list.toArray(arguments);
          function.setArguments(arguments);
          compileContext.addRoutine(function);
  
          return function;
      }