docs: StatementSchema compileCreateProcedureOrFunction() {
  
          int routineType = token.tokenType == Tokens.PROCEDURE
                            ? SchemaObject.PROCEDURE
                            : SchemaObject.FUNCTION;
          HsqlName name;
  
          read();
  
          name = readNewSchemaObjectNameNoCheck(routineType);
  
          Routine routine = new Routine(routineType);
  
          routine.setName(name);
          readThis(Tokens.OPENBRACKET);
  
          if (token.tokenType == Tokens.CLOSEBRACKET) {
              read();
          } else {
              while (true) {
                  ColumnSchema newcolumn = readRoutineParameter(routine);
  
                  routine.addParameter(newcolumn);
  
                  if (token.tokenType == Tokens.COMMA) {
                      read();
                  } else {
                      readThis(Tokens.CLOSEBRACKET);
  
                      break;
                  }
              }
          }
  
          if (routineType != SchemaObject.PROCEDURE) {
              readThis(Tokens.RETURNS);
  
              if (token.tokenType == Tokens.TABLE) {
                  read();
  
                  TableDerived table =
                      new TableDerived(database, name, TableBase.FUNCTION_TABLE);
  
                  readThis(Tokens.OPENBRACKET);
  
                  if (token.tokenType == Tokens.CLOSEBRACKET) {
                      read();
                  } else {
                      while (true) {
                          ColumnSchema newcolumn = readRoutineParameter(routine);
  
                          table.addColumn(newcolumn);
  
                          if (token.tokenType == Tokens.COMMA) {
                              read();
                          } else {
                              readThis(Tokens.CLOSEBRACKET);
  
                              break;
                          }
                      }
                  }
  
                  routine.setReturnTable(table);
              } else {
                  Type type = readTypeDefinition(true);
  
                  routine.setReturnType(type);
              }
          }
  
          readRoutineCharacteristics(routine);
  
          if (token.tokenType == Tokens.EXTERNAL) {
              if (routine.getLanguage() != Routine.LANGUAGE_JAVA) {
                  throw unexpectedToken();
              }
  
              read();
              readThis(Tokens.NAME);
              checkIsValue(Types.SQL_CHAR);
              routine.setMethodURL((String) token.tokenValue);
              read();
  
              if (token.tokenType == Tokens.PARAMETER) {
                  read();
                  readThis(Tokens.STYLE);
                  readThis(Tokens.JAVA);
              }
          } else {
              startRecording();
  
              Statement statement = readSQLProcedureStatementOrNull(routine,
                  null);
              Token[] tokenList = getRecordedStatement();
              String  sql       = Token.getSQL(tokenList);
  
              statement.setSQL(sql);
              routine.setProcedure(statement);
          }
  
          Object[] args = new Object[]{ routine };
          String   sql  = getLastPart();
          StatementSchema cs = new StatementSchema(sql,
              StatementTypes.CREATE_ROUTINE, args, null, null);
  
          return cs;
      }