******************************
How to contribute
******************************

Error Reports
==============================

Please report any issue to the `GitHub Issue Tracker <https://github.com/JSQLParser/JSqlParser/issues>`_:

   1) Provide the **Sample SQL** (shortened and simplified, properly formatted)
   2) State the exact **Version of JSQLParser**
   3) State the **RDBMS** in use and point on the applicable Grammar specification
   4) Please write in **English** and post **Plain Text only** (avoiding screen shots or bitmap pictures).

Before reporting any issues, please verify your statement using `JSQLFormatter Online <http://jsqlformatter.manticore-projects.com>`_.

Feature Requests
==============================

JSQLParser is a demand-driven software library, where many contributors have shared solutions for their own needs. Requests for new features have a good chance to get implemented when

   1) the request is about a commonly used feature for one of the major RDBMS
   2) or the request is backed by a sponsor or a bounty, which may attract developers to spend their time on it.

Implementing new Features
==============================

The team around JSQLParser warmly welcomes Code Contributions and Pull Requests. Please follow the guidance below and do not hesitate to ask us for assistance.

Create a new Git Branch
------------------------------

When starting afresh, clone `JSQLParser` from the `GitHub` repository:

.. code-block:: Bash

   git clone https://github.com/JSQLParser/JSqlParser.git
   cd JSqlParser
   git branch <new-branch>

When having a local repository already, then pull/merge from the `GitHub` repository:

.. code-block:: Bash

   cd JSqlParser
   git pull origin master
   git branch <new-branch>

Amend the Code
------------------------------

The JSQLParser is generated by ``JavaCC`` based on the provided Grammar. The Grammar defines how a SQL Text is read and translated into Java Objects. Thus any contribution will depend on the following steps:

   1) Edit the ``JavaCC`` Grammar at ``src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt``
   2) Add or edit the Java Classes at ``src/main/java/net/sf/jsqlparser`` to facilitate this Grammar.
   3) When have added new Java Classes, amend the Visitors, the Visitor Adaptors, the De-Parsers and the Validators.
   4) Provide Java Unit Tests at ``src/test/java/net/sf/jsqlparser`` to test the new feature

      * The test should call at least one time the method ``assertSqlCanBeParsedAndDeparsed()``
      * The test should ensure complete coverage of the new Java Classes.
      * The complete test suite must succeed.

   5) Add the description of the new feature to the ``README.md`` file, section `Extensions`.
   6) Build the package with ``Gradle`` and ensure, all checks do pass (PMD and CheckStyle and Code Formatting).

      .. tab:: Gradle

          .. code-block:: shell
              :caption: Gradle `check` Task

                  gradle check

      .. tab:: Maven

          .. code-block:: shell
              :caption: Maven `verify` Task

                  mvn verify

   7) Verify the performance and avoid any deterioration

      .. code-block:: shell
          :caption: Gradle `check` Task

              gradle jmh

      .. code-block:: text
                :caption: JMH performance results

                    Benchmark                               (version)  Mode  Cnt    Score   Error  Units
                    JSQLParserBenchmark.parseSQLStatements     latest  avgt   30   83.504 ± 1.557  ms/op
                    JSQLParserBenchmark.parseSQLStatements        5.2  avgt   30  400.876 ± 8.291  ms/op
                    JSQLParserBenchmark.parseSQLStatements        5.1  avgt   30   85.731 ± 1.288  ms/op

   8) Create your `GitHub Pull Request <https://www.youtube.com/watch?v=nCKdihvneS0>`_

Manage Reserved Keywords
------------------------------

Since JSQLParser is built by JavaCC from a Token based Grammar, ``Reserved Keywords`` need a special treatment. All Tokens of the Grammar would become ``Reserved Keywords`` -- unless explicitly allowed and white-listened.

.. code-block:: sql
    :caption: White-list Keyword example

    -- <K_OVERLAPS:"OVERLAPS"> is a Token, recently defined in the Grammar
    -- Although it is not restricted by the SQL Standard and could be used for Column, Table and Alias names
    -- Explicitly white-listing OVERLAPS by adding it to the  RelObjectNameWithoutValue() Production will allow for parsing the following statement

    SELECT Overlaps( overlaps ) AS overlaps
    FROM overlaps.overlaps overlaps
    WHERE overlaps = 'overlaps'
        AND (CURRENT_TIME, INTERVAL '1' HOUR) OVERLAPS (CURRENT_TIME, INTERVAL -'1' HOUR)
    ;

So we will need to define and white-list any Keywords which may be allowed for Object Names (such as `Schema`, `Table`, `Column`, `Function`, `Alias`). This White-List must be updated whenever the Tokens of the Grammar change (e. |_| g. when adding a new Token or Production).

There is a task ``updateKeywords`` for Gradle and Maven, which will:

    1) Parse the Grammar in order to find all Token definitions
    2) Read the list of explicitly ``Reserved Keywords`` from ``net/sf/jsqlparser/parser/ParserKeywordsUtils.java``
    3) Derive the list of ``White-Listed Keywords`` as difference between ``All Tokens`` and ``Reserved Keywords``
    4) Modifies the Grammar Productions ``RelObjectNameWithoutValue...`` adding all Tokens according to ``White-Listed Keywords``
    5) Run two special Unit Tests to verify parsing of all ``White-Listed Keywords`` (as `Schema`, `Table`, `Column`, `Function` or `Alias`)
    6) Update the web page about the Reserved Keywords


.. tab:: Gradle

    .. code-block:: shell
        :caption: Gradle `updateKeywords` Task

            gradle updateKeywords

.. tab:: Maven

    .. code-block:: shell
        :caption: Maven `updateKeywords` Task

            mvn exec:java


Without this Gradle Task, any new Token or Production will become a ``Reserved Keyword`` automatically and can't be used for Object Names without quoting.


Commit a Pull Request
---------------------------------

.. code-block:: Bash

   cd JSqlParser
   git add -A
   git commit -m <title> -m <description>
   git push –set-upstream origin <new-branch>

Follow the advice on `Meaningful Commit Messages <https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/>`_ and consider using `Commitizen <https://commitizen-tools.github.io/commitizen/>`_ when describing your commits.

Please consider using `Conventional Commits` and structure your commit message as follows:

.. code-block:: text
    :caption: Conventional Commit Message Structure

    <type>[optional scope]: <description>

    [optional body]

    [BREAKING CHANGE: <change_description>]

    [optional footer(s)]

.. list-table:: Commit Message Types
   :widths: 15 85
   :header-rows: 1

   * - Type
     - Description
   * - **feat**
     - introduce a new feature
   * - **fix**
     - patches a bug in your codebase (bugfix or hotfix)
   * - **build**
     - changes that affect the build system or external dependencies
   * - **chore**
     - updates dependencies and does not relate to fix or feat and does not modify src or test files.
   * - **ci**
     - changes that affect the continuous integration process
   * - **docs**
     - updates the documentation or introduce documentation
   * - **style**
     - updates the formatting of code; remove white spaces, add missing spaces, remove unnecessary newlines
   * - **refactor**
     - reactors code segments to optimize readability without changing behavior
   * - **perf**
     - improve performance
   * - **test**
     - add/remove/update tests
   * - **revert**
     - reverts one or many previous commits

Please visit `Better Programming <https://betterprogramming.pub/write-better-git-commit-messages-to-increase-your-productivity-89fa773e8375>`_ for more information and guidance.
