{"id":14483065,"url":"https://github.com/bigsmoke/pg_readme","last_synced_at":"2025-08-30T03:32:52.533Z","repository":{"id":65487966,"uuid":"573427536","full_name":"bigsmoke/pg_readme","owner":"bigsmoke","description":"Functions to generate a `README.md` document for a database extension or schema, based on `COMMENT` objects found in the `pg_description` system catalog","archived":false,"fork":false,"pushed_at":"2024-09-02T22:00:30.000Z","size":386,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-27T04:32:11.865Z","etag":null,"topics":["postgres","postgresql","postgresql-extension"],"latest_commit_sha":null,"homepage":"https://blog.bigsmoke.us/tag/pg_readme","language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bigsmoke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-02T12:47:00.000Z","updated_at":"2024-11-18T03:03:32.000Z","dependencies_parsed_at":"2024-09-03T00:04:45.825Z","dependency_job_id":"b97e1569-10c4-4eda-ace0-14dc851cdec5","html_url":"https://github.com/bigsmoke/pg_readme","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/bigsmoke/pg_readme","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigsmoke%2Fpg_readme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigsmoke%2Fpg_readme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigsmoke%2Fpg_readme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigsmoke%2Fpg_readme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigsmoke","download_url":"https://codeload.github.com/bigsmoke/pg_readme/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigsmoke%2Fpg_readme/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272800742,"owners_count":24995138,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["postgres","postgresql","postgresql-extension"],"created_at":"2024-09-03T00:01:28.229Z","updated_at":"2025-08-30T03:32:52.139Z","avatar_url":"https://github.com/bigsmoke.png","language":"PLpgSQL","funding_links":[],"categories":["PLpgSQL"],"sub_categories":[],"readme":"---\npg_extension_name: pg_readme\npg_extension_version: 0.7.0\npg_readme_generated_at: 2024-09-02 22:38:30.962606+01\npg_readme_version: 0.7.0\n---\n\n# The `pg_readme` PostgreSQL extension\n\nThe `pg_readme` PostgreSQL extension provides functions to generate\na `README.md` document for a database extension or schema, based on\n[`COMMENT`](https://www.postgresql.org/docs/current/sql-comment.html) objects\nfound in the\n[`pg_description`](https://www.postgresql.org/docs/current/catalog-pg-description.html)\nsystem catalog.\n\n## Usage\n\nTo use `pg_readme` in your extension, the most self-documenting way to do it is\nto create a function that calls the `readme.pg_extension_readme(name)`\nfunction.  Here is an example take from the\n[`pg_rowalesce`](https://github.com/bigsmoke/pg_rowalesce) extension:\n\n```sql\ncreate function pg_rowalesce_readme()\n    returns text\n    volatile\n    set search_path from current\n    set pg_readme.include_view_definitions to 'true'\n    set pg_readme.include_routine_definition_like to '{test__%}'\n    language plpgsql\n    as $plpgsql$\ndeclare\n    _readme text;\nbegin\n    create extension if not exists pg_readme\n        with version '0.1.0';\n    _readme := pg_extension_readme('pg_rowalesce'::name);\n    raise transaction_rollback;  -- to drop extension if we happened to `CREATE EXTENSION` for just this.\nexception\n    when transaction_rollback then\n        return _readme;\nend;\n$plpgsql$;\n```\n\nIn the above example, the `pg_readme.*` settings are (quite redundantly) set to\ntheir default values.  There is no need to add `pg_readme` to the list of\nrequirements in your extension's control file; after all, the extension is only\nintermittently required, _by you_, when you need to update your extension's\n`README.md`.\n\nTo make it easy (and self-documenting) to update the readme, add something like\nthe following recipe to the bottom of your extension's `Makefile`:\n\n```sql\nREADME.md: README.sql install\n        psql --quiet postgres \u003c $\u003c \u003e $@\n```\n\nAnd turn the `README.sql` into something like this (again an example from `pg_rowalesce`):\n\n```sql\n\\pset tuples_only\n\\pset format unaligned\n\nbegin;\n\ncreate schema rowalesce;\n\ncreate extension pg_rowalesce\n    with schema rowalesce\n    cascade;\n\nselect rowalesce.pg_rowalesce_readme();\n\nrollback;\n```\n\nNow you can update your `README.md` by running:\n\n```\nmake README.md\n```\n\n`COMMENT` (also on your extension), play with it, and never go back.  And don't\nforget to send me the pull requests for you enhancements.\n\n## Markdown\n\nThe `pg_readme` author has made the choice for Markdown, not out of love for\nMarkdown, but out of practicality: Markdown, in all its neo-formal\ninterprations, has become ubiquitous.  Also, it has a straight-forward\nfall-through to (X)HTML.  And we're not creating tech. books here (where TEI or\nDocBook would have been the superior choice); we're merely generating\nonline/digital documentation on the basis of inline `COMMENT`s.\n\nTo make the pain of Markdown's many competing extensions and implementations\n_somewhat_ bearable, `pg_readme` attempts to stick to those Markdown constructs\nthat are valid both according to:\n\n  * [GitHub Flavored Markdown](https://github.github.com/gfm/) (GFM), and\n  * [CommonMark](https://commonmark.org/).\n\n“Attempts to”, because `pg_readme` relies heavily on MarkDown tables, which\n_are_ supported by GFM, but _not_ by CommonMark.\n\n## Processing instructions\n\n`pg_readme` has support for a bunch of special XML processing instructions that\nyou can include in the Markdown `COMMENT ON EXTENSION` or `COMMENT ON SCHEMA`\nobjects:\n\n  * \u003ccode\u003e\u0026lt;?pg-readme-reference?\u0026gt;\u003c/code\u003e will be replaced with a full\n    reference with all the objects found by `pg_readme` that belong to the\n    schema or extension (when\n    [`pg_schema_readme()`](#function-pg_schema_readme-regnamespace) or\n    [`pg_extension_readme()`](#function-pg_extension_readme-name) are run\n    respectively.\n  * \u003ccode\u003e\u0026lt;?pg-readme-colophon?\u0026gt;\u003c/code\u003e adds a colophon with information\n    about `pg_readme` to the text.\n\n\u003c!--\n\u003ccode\u003e\u003c/code\u003e instead of `` is used to encode the above processing\ninstructions to jump into raw HTML mode, so that the \u0026lt; and \u0026gt; entity\nreferences are not escaped.  And we need those entity references to keep\npg_readme from putting the full object reference and the colophon in the middle\nof these list items.\n--\u003e\n\nThe following pseudo-attributes are supported for these processing instructions:\n\n| Pseudo-attribute           | Coerced to | Default value                        |\n| -------------------------- | ---------- | ------------------------------------ |\n| `context-division-depth`   | `smallint` | `1`                                  |\n| `context-division-is-self` | `boolean`  | `false`                              |\n| `division-title`           | `text`     | `'Object reference'` / `'Colophon'`  |\n\n(These attributes are called _pseudo-attributes_, because the XML spec does not\nprescribe any particular structure for a processing instruction's content.\n\n## Extension-specific settings\n\n| Setting                                      | Default                                                         |\n| -------------------------------------------- | --------------------------------------------------------------- |\n| `pg_readme.include_view_definitions`         | `true`                                                          |\n| `pg_readme.readme_url`                       | `'https://github.com/bigsmoke/pg_readme/blob/master/README.md'` |\n| `pg_readme.include_routine_definitions_like` | `'{test__%}'`                                                   |\n| `pg_readme.include_this_routine_definition`  | `null`                                                          |\n\n`pg_readme.include_this_routine_definition` is meant to be only used on a\nroutine-local level to make sure that the definition for that particular\nroutine is either _always_ or _never_ included in the reference, regardless of\nthe `pg_readme.include_routine_definitions_like` setting.\n\nFor `pg_readme` version 0.3.0, `pg_readme.include_routine_definitions` has been\ndeprecated in favor of `pg_readme.include_routine_definitions_like`, and\n`pg_readme.include_routine_definitions` is now interpreted as:\n\n| Legacy setting                                  | Deduced setting                                                 |\n| ----------------------------------------------- | --------------------------------------------------------------- |\n| `pg_readme.include_routine_definitions is null` | `pg_readme.include_routine_definitions_like = array['test__%']` |\n| `pg_readme.include_routine_definitions = true`  | `pg_readme.include_routine_definitions_like = array['%']`       |\n| `pg_readme.include_routine_definitions = false` | `pg_readme.include_routine_definitions_like = array[]::text[]`  |\n\n## To-dos and to-maybes\n\n### Missing features\n\n* Table synopsis is not generated yet.\n\n### Ideas for improvement\n\n* Support for `\u003c?pg-readme-install?\u003e` PI could be nice.\n* Support for a `\u003c?pg-readme-table-rows?\u003e` PI in the `COMMENT` of specific\n  tables could be a nice addition for extensions/schemas that have type-type\n  tables.\n* Automatically turning references to objects from other/builtin extensions or\n  schemas into links could be a plus.  But this might also render the raw markup\n  unreadable.  That, at least, would be a good argument against doing the same\n  for extension-local object references.\n\n## The origins of the `pg_readme` extension\n\n`pg_readme`, together with a sizeable number of other PostgreSQL extensions, was\ndeveloped as part of the backend for the super-scalable [FlashMQ MQTT SaaS\nservice](https://www.flashmq.com).  Bundling and releasing this code publically\nhas:\n\n- made the PostgreSQL schema architecture cleaner, with fewer\n  interdependencies;\n- made the documentation more complete and up-to-date;\n- increased the amount of polish; and\n- reduced the number of rough edges.\n\nThe public gaze does improve quality!\n\n## Object reference\n\n### Routines\n\n#### Function: `pg_extension_readme (name)`\n\n`pg_extension_readme()` automatically generates a `README.md` for the given extension, taking the `COMMENT ON EXTENSION` as the prelude, and optionally adding a full reference (with neatly layed out object characteristics from the `pg_catalog`) in the place where a \u003ccode\u003e\u0026lt;?pg-readme-reference?\u0026gt;\u003c/code\u003e processing instruction is encountered in the `COMMENT ON EXTENSION`.\n\nSee the [_Processing instructions_](#processing-instructions) section for\ndetails about the processing instructions that are recognized and which\npseudo-attributes they support.\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` |                                                                   | `name`                                                               |  |\n\nFunction return type: `text`\n\nFunction attributes: `STABLE`\n\nFunction-local settings:\n\n  *  `SET search_path TO readme, ext, pg_temp`\n\n#### Function: `pg_readme_colophon (pg_readme_collection_type, name, smallint, boolean, text)`\n\n`pg_readme_colophon()` is a function internal to `pg_readme` that is used by `pg_readme_pis_process()` to replace \u003ccode\u003e\u0026lt;?pg-readme-colophon?\u0026gt;\u003c/code\u003e processing instructions with a standard colophon indicating that `pg_readme` was used to generate a schema or extension README.\n\nSee the [_Processing instructions_](#processing-instructions) section for an\noverview of the processing instructions and their pseudo-attributes.\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` | `collection_type$`                                                | `pg_readme_collection_type`                                          |  |\n|   `$2` |       `IN` | `collection_name$`                                                | `name`                                                               |  |\n|   `$3` |       `IN` | `context_division_depth$`                                         | `smallint`                                                           | `1` |\n|   `$4` |       `IN` | `context_division_is_self$`                                       | `boolean`                                                            | `false` |\n|   `$5` |       `IN` | `division_title$`                                                 | `text`                                                               | `'Colophon'::text` |\n\nFunction return type: `text`\n\nFunction attributes: `IMMUTABLE`, `LEAKPROOF`, `PARALLEL SAFE`\n\n#### Function: `pg_readme_meta_pgxn()`\n\nReturns the JSON meta data that has to go into the `META.json` file needed for [PGXN—PostgreSQL Extension Network](https://pgxn.org/) packages.\n\nThe `Makefile` includes a recipe to allow the developer to: `make META.json` to\nrefresh the meta file with the function's current output, including the\n`default_version`.\n\nFunction return type: `jsonb`\n\nFunction attributes: `STABLE`\n\n#### Function: `pg_readme_object_reference (pg_readme_objects_for_reference, pg_readme_collection_type, name, smallint, boolean, text)`\n\n`pg_readme_object_reference()` is a function internal to `pg_readme` that is delegated to by `pg_readme_pis_process()` to replace \u003ccode\u003e\u0026lt;?pg-readme-reference?\u0026gt;\u003c/code\u003e processing instructions with a standard colophon indicating that `pg_readme` was used to generate a schema or extension README.\n\nSee the [_Processing instructions_](#processing-instructions) section for an\noverview of the processing instructions and their pseudo-attributes.\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` | `objects$`                                                        | `pg_readme_objects_for_reference`                                    |  |\n|   `$2` |       `IN` | `collection_type$`                                                | `pg_readme_collection_type`                                          |  |\n|   `$3` |       `IN` | `collection_name$`                                                | `name`                                                               |  |\n|   `$4` |       `IN` | `context_division_depth$`                                         | `smallint`                                                           | `1` |\n|   `$5` |       `IN` | `context_division_is_self$`                                       | `boolean`                                                            | `false` |\n|   `$6` |       `IN` | `division_title$`                                                 | `text`                                                               | `'Object reference'::text` |\n\nFunction return type: `text`\n\nFunction attributes: `STABLE`\n\nFunction-local settings:\n\n  *  `SET search_path TO readme, ext, pg_temp`\n\n#### Function: `pg_readme_object_reference__rel_attr_list (pg_class)`\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` |                                                                   | `pg_class`                                                           |  |\n\nFunction return type: `text`\n\nFunction attributes: `STABLE`\n\n#### Function: `pg_readme_pi_pseudo_attrs (text, text)`\n\n`pg_readme_pi_pseudo_attrs()` extracts the pseudo-attributes from the XML processing instruction with the given `pi_target$` found in the given`haystack$` argument.\n\nSee the `test__pg_readme_pi_pseudo_attrs()` procedure source for examples.\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` | `haystack$`                                                       | `text`                                                               |  |\n|   `$2` |       `IN` | `pi_target$`                                                      | `text`                                                               |  |\n\nFunction return type: `hstore`\n\nFunction attributes: `IMMUTABLE`, `LEAKPROOF`, `RETURNS NULL ON NULL INPUT`, `PARALLEL SAFE`\n\n#### Function: `pg_readme_pis_process (text, pg_readme_collection_type, name, pg_readme_objects_for_reference)`\n\n`pg_readme_object_reference()` is a function internal to `pg_readme` that is responsible for replacing processing instructions in the source text with generated content.\n\nSee the [_Processing instructions_](#processing-instructions) section for an overview of the processing instructions and their pseudo-attributes.\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` | `unprocessed$`                                                    | `text`                                                               |  |\n|   `$2` |       `IN` | `collection_type$`                                                | `pg_readme_collection_type`                                          |  |\n|   `$3` |       `IN` | `collection_name$`                                                | `name`                                                               |  |\n|   `$4` |       `IN` | `objects$`                                                        | `pg_readme_objects_for_reference`                                    |  |\n\nFunction return type: `text`\n\nFunction attributes: `STABLE`, `LEAKPROOF`, `RETURNS NULL ON NULL INPUT`, `PARALLEL SAFE`\n\nFunction-local settings:\n\n  *  `SET search_path TO readme, ext, pg_temp`\n\n#### Function: `pg_schema_readme (regnamespace)`\n\n`pg_schema_readme()` automatically generates a `README.md` for the given schema, taking the `COMMENT ON SCHEMA` as the prelude, and optionally adding a full reference (with neatly layed out object characteristics from the `pg_catalog`) in the place where a \u003ccode\u003e\u0026lt;?pg-readme-reference?\u0026gt;\u003c/code\u003e processing instruction is encountered in the `COMMENT ON SCHEMA`.\n\nSee the [_Processing instructions_](#processing-instructions) section for\ndetails about the processing instructions that are recognized and which\npseudo-attributes they support.\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` |                                                                   | `regnamespace`                                                       |  |\n\nFunction return type: `text`\n\nFunction attributes: `STABLE`\n\nFunction-local settings:\n\n  *  `SET search_path TO readme, ext, pg_temp`\n\n#### Function: `string_diff (text, text)`\n\nFunction arguments:\n\n| Arg. # | Arg. mode  | Argument name                                                     | Argument type                                                        | Default expression  |\n| ------ | ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------- |\n|   `$1` |       `IN` |                                                                   | `text`                                                               |  |\n|   `$2` |       `IN` |                                                                   | `text`                                                               |  |\n\nFunction return type: `text`\n\nFunction attributes: `IMMUTABLE`, `LEAKPROOF`, `RETURNS NULL ON NULL INPUT`\n\n#### Procedure: `test__pg_readme()`\n\nThis routine tests the `pg_readme` extension.\n\nThe routine name is compliant with the `pg_tst` extension. An intentional choice has been made to not _depend_ on the `pg_tst` extension its test runner or developer-friendly assertions to keep the number of inter-extension dependencies to a minimum.\n\nProcedure-local settings:\n\n  *  `SET search_path TO readme, ext, pg_temp`\n  *  `SET pg_readme.include_this_routine_definition TO false`\n  *  `SET plpgsql.check_asserts TO true`\n\n#### Procedure: `test__pg_readme_pi_pseudo_attrs()`\n\nThis routine tests the `pg_readme_pi_pseudo_attrs()` function.\n\nThe routine name is compliant with the `pg_tst` extension. An intentional\nchoice has been made to not _depend_ on the `pg_tst` extension its test runner\nor developer-friendly assertions to keep the number of inter-extension\ndependencies to a minimum.\n\nProcedure-local settings:\n\n  *  `SET search_path TO readme, ext, pg_temp`\n\n```sql\nCREATE OR REPLACE PROCEDURE readme.test__pg_readme_pi_pseudo_attrs()\n LANGUAGE plpgsql\n SET search_path TO 'readme', 'ext', 'pg_temp'\nAS $procedure$\nbegin\n    assert pg_readme_pi_pseudo_attrs(\n        '\u003c?muizen-stapje soort=\"woelmuis\" hem-of-haar=\"piep\" a1=\"4\"?\u003e',\n        'muizen-stapje'\n    ) = hstore('soort=\u003ewoelmuis, hem-of-haar=\u003epiep, a1=\u003e4');\n\n    assert pg_readme_pi_pseudo_attrs(\n        'Blabla bla \u003c?muizen-stapje soort=\"woelmuis\" hem-of-haar=\"piep\"?\u003e Frotsepots',\n        'muizen-stapje'\n    ) = hstore('soort=\u003ewoelmuis, hem-of-haar=\u003epiep');\n\n    assert pg_readme_pi_pseudo_attrs(\n        'Blabla bla \u003c?muizen-stapje ?\u003e Frotsepots',\n        'muizen-stapje'\n    ) is null;\nend;\n$procedure$\n```\n\n### Types\n\nThe following extra types have been defined _besides_ the implicit composite types of the [tables](#tables) and [views](#views) in this extension.\n\n#### Composite type: `pg_readme_objects_for_reference`\n\n```sql\nCREATE TYPE pg_readme_objects_for_reference AS (\n  table_objects regclass[],\n  view_objects regclass[],\n  procedure_objects regprocedure[],\n  operator_objects regoperator[],\n  type_objects regtype[]\n);\n```\n\n#### Domain: `pg_readme_collection_type`\n\n```sql\nCREATE DOMAIN pg_readme_collection_type AS text\n  CHECK ((VALUE = ANY (ARRAY['extension'::text, 'schema'::text])));\n```\n\n## Authors and contributors\n\n* [Rowan](https://www.bigsmoke.us/) originated this extension in 2022 while\n  developing the PostgreSQL backend for the [FlashMQ SaaS MQTT cloud\n  broker](https://www.flashmq.com/).  Rowan does not like to see himself as a\n  tech person or a tech writer, but, much to his chagrin, [he\n  _is_](https://blog.bigsmoke.us/category/technology). Some of his chagrin\n  about his disdain for the IT industry he poured into a book: [_Why\n  Programming Still Sucks_](https://www.whyprogrammingstillsucks.com/).  Much\n  more than a “tech bro”, he identifies as a garden gnome, fairy and ork rolled\n  into one, and his passion is really to [regreen and reenchant his\n  environment](https://sapienshabitat.com/).  One of his proudest achievements\n  is to be the third generation ecological gardener to grow the wild garden\n  around his beautiful [family holiday home in the forest of Norg, Drenthe,\n  the Netherlands](https://www.schuilplaats-norg.nl/) (available for rent!).\n\n## Colophon\n\nThis `README.md` for the `pg_readme` extension was automatically generated using the [`pg_readme`](https://github.com/bigsmoke/pg_readme) PostgreSQL extension.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigsmoke%2Fpg_readme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigsmoke%2Fpg_readme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigsmoke%2Fpg_readme/lists"}