If you’re interested in helping further the development of sql-lint then read on. Casual users can ignore this section.

How it works

A raw query (either from stdin, a file, or a string) hits main.ts. This query then gets categorised into the type of statement it is (SELECT, INSERT, UPDATE, DELETE etc…), as the SQL grammar is pretty damn huge, there is a lexer per statement. This adds redundancy but increases flexibility.

Once a query has been categorised, it is then lexxed by the relevant lexer. See the src/lexer directory for the inner workings.

i.e. if we have the statement

SELECT name FROM user

This will hit the lexer which will categorise this as a SELECT statement which the SELECT lexer will then tokenise. The tokenised string is then passed through to every checker to look for any linting errors.

Adding a check

If you want to add your own check, read on. It’s quite simple but also verbose.

This can probably be automated to make it WAY easier.

Anyway, here are the steps.

  • Create a check under src/checker/checks
    • The name of the class is also the name of the checker so name it well
  • Add your check to src/barrel/checks.ts
    • All checks live here so we can import them all conveniently
  • Import your check in src/checker/checkFactory.ts
  • Add your check to the checkMap in src/checker/checkFactory.ts
  • Add it to the so people know it’s a thing
  • Add it to This is an exhaustive list of the checks
  • Add tests. The name of the test should match the name of the check
  • Add it to, the main documentation for checks
  • npm run build to compile the changes


TypeError: checkMap[check] is not a constructor

Your check is not being picked up by the checkerRunner. log out what the value of checks is in checkerRunner after the spliceing.

Testing the code

Testing requires sql-lint to be installed.

npm install -g sql-lint
./build/ //This will run more than just the tests (recommended)

Using the Docker container

First, make sure port 3306 is available locally. (You can do this by inspecting the output of sudo lsof -i :3306 and docker ps and killing anything using that port) Now do:

docker-compose up --build -d --force-recreate

At this point the container(s) will be up and ready to use. You can login with the following credentials: mysql -u root -ppassword.

Here’s an example of a query:

docker exec sqllint_mysql_1 mysql -u root -ppassword -e "SHOW DATABASES"

Connecting sql-lint to the Docker container

Change your config file in ~/.config/sql-lint/config.json to have the following values:

    "driver": "mysql",
    "host": "localhost",
    "user": "root",
    "password": "password",
    "port": 3306

This documentation

This documentation is built on sphinx and readthedocs. To run it locally, you will need the following:

  • The sql-lint repository (documentation lies in docs/)
  • sphinx to be installed (pip install sphinx)
  • sphinx-rtd-theme to be installed (pip install sphinx-rtd-theme)
  • recommonmark to be installed (pip install recommonmark)

Once those prerequisites are met, you can edit the files and see them exactly how they would appear on readthedocs.