doltgresql

repository·main·Indexed 24 days ago

https://github.com/dolthub/doltgresql

A project focused on implementing PostgreSQL compatibility. It includes the doltgres server binary, Docker images for deployment, and tools for analyzing extension dependencies and implementing contextual help within the SQL parser.

Tokens
2.8K
Snippets
7
Records
22
Agent score
84%

What's inside doltgresql

  1. Use LALR error recovery for contextual help

    main

    The parser leverages the LALR error token to provide help during error recovery. When an unexpected token is encountered, the parser pops the stack until it matches a rule containing the error token.

    To implement this in the grammar, you can use the helpWith(sqllex, "KEYWORD") function within an error rule. This function:

    • Halts parsing.
    • Returns a non-zero error code.
    • Extends the error message with help text that clients can use to display friendly messages.

    Shorthand Syntax: You can use a special comment to automate the generation of these rules:

    | BACKUP error // SHOW HELP: BACKUP

    This is automatically expanded by replace_help_rules.awk into the full helpWith return statement.

    backup_stmt:
      BACKUP targets TO string_or_placeholder opt_as_of_clause opt_incremental opt_with_options
      { 
        $$.val = &Backup{...} 
      }
    | BACKUP error { return helpWith(sqllex, `BACKUP`) }
  2. Handle HELPTOKEN at the end of valid statements

    main

    If a user requests help using HELPTOKEN (e.g., DELETE FROM foo ??) after a complete, valid statement, the parser has already reduced the statement, losing the context.

    To solve this without duplicating every grammar rule, you can factor the statement into a 'real' rule and then extend that rule with the HELPTOKEN using precedence directives to resolve shift/reduce conflicts.

    Shorthand Syntax: Use the following comment to automate the complex precedence logic:

    rule:
      somerule // EXTEND WITH HELP: XXX

    This expands via replace_help_rules.awk into a pattern that uses %prec to ensure the HELPTOKEN is prioritized over the standard reduction.

    alter_rename_table_stmt:
      real_alter_rename_table_stmt           %prec LOWTOKEN { $$ = $1 }
    | real_alter_rename_table_stmt HELPTOKEN %prec HIGHTOKEN { help ... }
  3. How contextual help is implemented in the parser

    main

    The parser package provides interactive, contextual help in two scenarios:

    1. Grammatical Mistakes: When a user provides invalid SQL (e.g., INSERT sometable INTO(x, y) ...), the parser uses LALR error recovery to trigger help.
    2. Explicit Help Request: When a user inserts the HELPTOKEN (currently the standalone ??) into a statement.

    The parser uses two primary mechanisms to achieve this: LALR error recovery for mistakes/mid-statement help, and explicit help token handling for help requested after a valid partial statement.

  4. Generate SQL function and operator documentation

    main

    Documentation for SQL functions and operators is generated using the docgen utility. The output is stored as markdown files in docs/generated/sql.

    To regenerate the documentation, run:

    make generate PKG=./docs/...\n```
    
    **Note**: Documentation should be re-generated whenever functions or operators change. If regenerating produces a diff, it is expected to cause a CI failure, ensuring documentation stays in sync with the code.
    
    make generate PKG=./docs/...
  5. Find extension function imports on Windows

    main

    To identify which functions an extension imports (required for implementation to ensure the extension loads correctly), use the dumpbin utility. dumpbin is part of the full Visual Studio installation (not Visual Studio Code).

    Focus on the functions imported by postgres.exe or the specific extension DLL to determine the necessary implementations.

    dumpbin /imports "C:/Program Files/PostgreSQL/15/lib/LIBRARY_NAME.dll"
  6. Connect to the Doltgres server from the host

    main

    To connect to the server running inside a container from your host machine, map the container's port (default 5432) to a port on your host.

    Note: If you already have a local Postgres instance running, port 5432 will be occupied. You must either shut down your local Postgres or map to a different host port (e.g., -p 5433:5432).

    Once running, connect using psql or any Postgres-compatible client.

  7. Find extension function imports on Linux

    main

    To identify which functions an extension imports on Linux, use the nm command.

    When reviewing the output, look for functions marked with U (undefined). Specifically, target functions that do not have an @ symbol near the end, as those with an @ are typically implemented in external libraries rather than the core PostgreSQL environment you need to implement.

    nm -D -u /usr/lib/postgresql/15/lib/LIBRARY_NAME.so
  8. Run the Doltgres Docker image

    main

    The dolthub/doltgresql image runs the Doltgres server. Running the image without arguments is equivalent to running the doltgres command inside the container. You can view all supported doltgres options by passing the --help flag.

    $ docker run dolthub/doltgresql:latest --help
  9. Build the Doltgres Docker image

    main

    You can build the image using the Dockerfile in the root of the Doltgres repository. Use the DOLTGRES_VERSION build argument to specify which version to fetch or whether to use local source code.

    Available build patterns:

    • Latest version (automatic): docker build -t doltgres:latest .
    • Latest version (explicit): docker build --build-arg DOLTGRES_VERSION=latest -t doltgres:latest .
    • Specific version: docker build --build-arg DOLTGRES_VERSION=0.55.1 -t doltgres:0.55.1 .
    • Local source code: docker build --build-arg DOLTGRES_VERSION=source -t doltgres:source .
    # Build the latest Doltgres version (automatically fetches the latest release)
    $ docker build -t doltgres:latest .
  10. Initialize the database with SQL scripts

    main

    To run arbitrary SQL setup or add initial data during container startup, include .sql files in a directory mounted to /docker-entrypoint-initdb.d/.

    Supported file formats:

    • .sql (statements must be separated by semicolons)
    • Compressed files: .sql.bz2, .sql.gz, .sql.xz, or .sql.zst.
    $ docker run -v ./init_scripts:/docker-entrypoint-initdb.d/ -p 5432:5432 dolthub/doltgresql:latest
  11. Configure the default database name

    main

    Doltgres determines the name of the default database to create on the first run using the following priority:

    1. The value of the DOLTGRES_DB environment variable.
    2. If the environment variable is not set, it defaults to the superuser's username.

    The superuser username is configured via the DOLTGRES_USER environment variable, which defaults to postgres.

  12. Configure the Doltgres server

    main

    Server Configuration (config.yaml)

    Provide a custom config.yaml by mounting a local directory to /etc/doltgres/servercfg.d inside the container.

    $ docker run -v ./doltgres_cfg:/etc/doltgres/servercfg.d -p 5432:5432 dolthub/doltgresql:latest

    Data Directory

    The default data directory in the container is /var/lib/doltgresql/. You can change this by setting the PGDATA or DOLTGRES_DATA environment variables. You can also mount a local directory to this path to persist data.

    $ docker run -e PGDATA=/path/to/doltgres/data -p 5432:5432 dolthub/doltgresql:latest