{"id":14063374,"url":"https://github.com/lacanoid/pgddl","last_synced_at":"2026-02-05T05:10:16.031Z","repository":{"id":6000376,"uuid":"54445829","full_name":"lacanoid/pgddl","owner":"lacanoid","description":"DDL eXtractor functions for PostgreSQL (ddlx)","archived":false,"fork":false,"pushed_at":"2025-08-28T09:10:24.000Z","size":794,"stargazers_count":146,"open_issues_count":3,"forks_count":25,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-08-28T16:17:58.037Z","etag":null,"topics":["database","ddl","postgresql","postgresql-extension","sql"],"latest_commit_sha":null,"homepage":"","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/lacanoid.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-03-22T04:46:34.000Z","updated_at":"2025-08-26T10:13:39.000Z","dependencies_parsed_at":"2023-10-20T16:45:57.658Z","dependency_job_id":"d98b3b94-6ed1-4215-9b79-82d1b86d9fb4","html_url":"https://github.com/lacanoid/pgddl","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/lacanoid/pgddl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lacanoid%2Fpgddl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lacanoid%2Fpgddl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lacanoid%2Fpgddl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lacanoid%2Fpgddl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lacanoid","download_url":"https://codeload.github.com/lacanoid/pgddl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lacanoid%2Fpgddl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29113201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T03:44:17.043Z","status":"ssl_error","status_checked_at":"2026-02-05T03:44:12.077Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["database","ddl","postgresql","postgresql-extension","sql"],"created_at":"2024-08-13T07:03:18.482Z","updated_at":"2026-02-05T05:10:16.025Z","avatar_url":"https://github.com/lacanoid.png","language":"PLpgSQL","funding_links":[],"categories":["PLpgSQL"],"sub_categories":[],"readme":"DDL eXtractor functions  for PostgreSQL\n=======================================\n\nThis is an SQL-only extension for PostgreSQL that provides uniform functions for generating \nSQL Data Definition Language (DDL) scripts for objects created in a database. \nIt contains a bunch of SQL functions  to convert PostgreSQL system catalogs \nto nicely formatted snippets of SQL DDL, such as CREATE TABLE.\n\nSome other SQL databases support commands like SHOW CREATE TABLE or provide \nother facilities for the purpose. \n\nPostgreSQL currently doesn't provide overall in-server DDL extracting functions,\nbut rather a separate `pg_dump` program. It is an external tool to the server \nand therefore requires shell access or local installation to be of use.\n\nPostgreSQL however already provides a number of helper functions which greatly help \nwith reconstructing DDL and are of course used by this extension.\nPostgreSQL also has sophisticated query capabilities, such as common table expressions and window functions \nwhich make this project possible by using only SQL.\n\nAdvantages over using other tools like `psql` or `pg_dump` include:\n\n- You can use it to extract DDL with **any client** which support running plain SQL queries\n- **Simple API** with just three functions. Just supply `oid`.\n- **No shell access** or shell commands with hairy options required (for running pg_dump), \n  just use SELECT and hairy SQL instead!\n- With SQL you can select things to dump by using **usual SQL semantics** (WHERE, etc)\n- Special function for creating scripts, which drop and recreate entire **dependancy trees**.\n  This is great when you need to edit a table, then a view, then a function that uses the view, \n  then a function that returns SETOF.\n  It works particularly well with the transactional DDL of Postgres.\n- Created scripts are mostly intended to be run and copy/pasted manually by the DBA\n  into other databases/scripts, such as a database upgrade scripts. It attempts to strike\n  a reasonable balance between detail and clutter.\n  This involves \n   pretty printing,\n   using **idempotent DDL** where possible (preferring ALTER to CREATE), \n   creating indexes which are part of a constraint with ADD CONSTRAINT and so on.\n- It is entrely made out of **plain SQL functions** so you don't have to install any extra\n  languages, not even PL/PgSQL! It runs on plain vanilla Postgres.\n\nSome disadvantages:\n\n- Not all Postgres objects and all options are supported yet. Postgres is huge. \n  This package provides support for basic user-level objects such as types, classes and functions.\n  Currently most objects are at least somewhat supported but not all options are.\n  The intention is for version 1.0 is to support all objects and options. \n  See [ROADMAP](ROADMAP.md) for some of what is still missing.\n- It is not very well tested. While it contains a number of regression tests, these can be\n  hardly considered as proofs of correctness. Be certain there are bugs. Use at your own risk!\n  In fact, generated scripts might not run at all.\n  Do not run them on production databases without inspecting and testing them first!\n- It is kind of slow-ish for complicated dependancy trees\n\nThat said, it has still proven quite useful in a many situations\nand is being used with a number of production databases.\nBug reports are welcome.\n\nIf support for your favorite Postgres feature is broken or missing, please let us know and we will put some focus on it.\n\nCurently developed and tested on PostgreSQL 13. \nIncluded preprocessor adapts the source to target PG version. \nTested to install on version 9.1 and later. \nSome tests might fail on older versions. \n\nInstallation\n------------\n\nTo build this module:\n\n    make\n\nThis builds extension for your particular version of Postgres in a file like `ddlx--0.30.sql`.\n\n    make install\n    make install installcheck\n\nYou can select a specific PostgreSQL installation:\n\n    make PG_CONFIG=/some/where/bin/pg_config\n    make PG_CONFIG=/some/where/bin/pg_config install\n    make PG_CONFIG=/some/where/bin/pg_config installcheck\n    make PGPORT=5432 PG_CONFIG=/usr/lib/postgresql/10/bin/pg_config clean install installcheck\n\nMake sure you set the connection parameters like `PGPORT` right for testing.\n\nAnd finally inside the database:\n\n    CREATE EXTENSION ddlx;\n\nIt you use multiple schemas, you will need to have variable `search_path` \nset appropriately for the extension to work. To make it work with any value of\n`search_path`, you can install the extension in the `pg_catalog` schema:\n\n    CREATE EXTENSION ddlx SCHEMA pg_catalog;\n\nThis of course requires superuser privileges.\n\nIf for some reason you are unable to use this as an extension, you can simply load generated SQL file\ninto your database by any regular means:\n\n    $ psql my_database -1 -f ddlx--0.31.sql\n\nUsing\n-----\n\nThe API provides three main public user functions:\n\n- `ddlx_create(oid, options)` - builds SQL DDL create statements\n- `ddlx_drop(oid, options)`   - builds SQL DDL drop statements\n- `ddlx_script(oid, options)` - builds SQL DDL scripts of entire dependancy trees\n\nFor other functions see below.\n\nThese are useful with various `reg*` [object identifier types](https://www.postgresql.org/docs/current/datatype-oid.html) \nsupported by Postgres, which are then automatically cast to `oid`. Options can be ommited.\n\nYou can use them simply by casting object name (or oid) to some `reg*` type:\n\n    SELECT ddlx_create('my_table'::regclass,'{ine}');\n    \n    SELECT ddlx_create('my_type'::regtype,'{noowner}');\n\n    SELECT ddlx_create('my_function'::regproc);\n\n    SELECT ddlx_create(current_role::regrole);\n\n    SELECT ddlx_create('+(int,int)'::regoperator);\n\nAll object identifier types are supported:\n`regclass`,`regtype`,`regrole`,`regnamespace`,`regproc`,`regprocedure`,\n`regoper`,`regoperator`,`regconfig`,`regdictionary`,`regcollation`\n\nFor objects without object identifier types, you have to find object ID `oid` first.\nYou can use something like:\n\n    SELECT ddlx_create(oid) FROM pg_foreign_data_wrapper WHERE fdwname='postgres_fdw';\n\n    SELECT ddlx_create(oid) FROM pg_database WHERE datname=current_database();\n\nOptions are optional and are passed as text array, for example `{ine,nodcl}`. They specify extra options on how things in created DDL should be. Currently supported options are:\n\n* `drop` - include `drop` statements in a script. These are otherwise commented out.\n* `nodrop` - omit `drop` statements from a script entirely\n* `owner` - always include `alter set owner`. Otherwise this is omitted when object owner is the same as the current user.\n* `noowner` - do not include `alter set owner` statements\n* `nogrants` - do not include `grant` statements\n* `nodcl` - include neither `alter set owner` nor grants\n* `noalter` - include neither `alter` nor DCL (grant) statements\n* `ine` - add `if not exists` in bunch of places\n* `ie` - add `if exists` in a bunch of places\n* `ext` - include extension contents instead of `create extension`.\n* `lite` - move defaults and constraints into `create table` statement, omit some other Postgres specific stuff (SQLite compatibility)\n* `nowrap` - do not wrap scripts with `BEGIN` and `END`\n* `nopartitions` - do not include table partitions in a script\n* `comments` - include all comments, even if null\n* `nocomments` - do not include any comments\n* `nostorage` - do not include storage settings\n* `noconstraints` - do not include constraints\n* `noindexes` - do not include indexes\n* `nosettings` - do not include settings\n* `notriggers` - do not include triggers\n* `grantor` - include grantor in grant statements\n* `data` - attempt to preserve table data, really only makes sense when used together with `drop`\n\nDrop statements are created with `ddlx_drop()` function.\t\n\n- `ddlx_drop(oid) returns text`\n\n    Generates SQL DDL DROP statement for object ID, `oid`.\n\nThere is also a higher level function to build entire DDL scripts. \nScripts include dependant objects and subpartitions and can get quite large.\n\n- `ddlx_script(oid[,options]) returns text`\n\n    Generates SQL DDL script for object ID, `oid` and all it's dependants.\n\n- `ddlx_script(text[,options]) returns text`\n\n    Generates SQL DDL script for object identified by textual sql identifier\n    and all it's dependants.\n    \n    This works only for types, including classes such as tables and views and\n    for functions. For a function, argument types need to be specified.\n\nAt the begining of a script, there are commented-out DROP statements for all dependant objects, \nso you can see them easily.\n\nAt the end of a script, there are CREATE statements to rebuild dropped dependant objects.\n\nDDL statements generated have identifiers schema-prefixed for stuff not in current schema.\nIf you want to dump a whole namespace without schema names, set `search_path` before calling `ddlx_script`().\n\nNote that dropping dependant tables will erase all data stored there, so use with care!\nScripts might be more useful for rebuilding layers of functions and views and such.\n\n### Example\n\n    CREATE TABLE users (\n        id int PRIMARY KEY,\n        name text\n    );\n\n    SELECT ddlx_script('users');\n\n    CREATE TYPE my_enum AS ENUM ('foo','bar');\n\n    SELECT ddlx_script('my_enum');\n\n    SELECT ddlx_script(current_role::regrole);\n\n### Additional functions\n\nA number of other functions are provided to extract more specific objects.\nTheir names all begin with `ddlx_`. They are used internally by the extension \nand are possibly subject to change in future versions of the extension. \nThey are generally not intended to be used by the end user. \nNevertheless, some of them are:\n\n- `ddlx_identify(oid) returns table(oid, classid, name, namespace, owner, sql_kind, sql_identifier, acl)`\n\n    Identify an object by object ID, `oid`. Searches all supported system catalogs.\n\n- `ddlx_describe(regclass) returns table`\n\n    Get columns of a class.\n\n- `ddlx_definitions(oid) returns table(oid, classid, sql_kind, sql_identifier, base_ddl, comment, owner,storage, defaults, settings, constraints, indexes, triggers, rules, rls, grants)`\n\n    Get individual parts of object definition, \n    such as: base_ddl, comment, owner, storage, defaults, settings, constraints, indexes, triggers, rules, rls, grants.\n\n- `ddlx_createonly(oid [,options]) returns text`\n\n    Get SQL DDL statements to create an object, typically before the data is loaded.\n    For classes, this includes base_ddl, comments, owner, storage, defaults and settings.\n\n- `ddlx_alter(oid [,options]) returns text`\n\n    Get additional SQL DDL ALTER statements for an object, typically after the data is loaded.\n    For classes, this includes defaults, storage parametes, constraints, indexes, triggers, rules,\n    owner and grants.\n\n- `ddlx_grants(oid) returns text`\n\n    Return GRANT statements for an object\n\n- `ddlx_apropos(regexp) returns table(classid, objid, sql_identifier, sql_kind, language, owner, comment, retset, namespace, name, source)`\n\n    Search query bodies (functions and view definitions) matching POSIX regular expression.\n```    \nSELECT ddlx_create(objid) FROM ddlx_apropos('users');\n\nSELECT * FROM ddlx_apropos('users') JOIN ddlx_identify(objid) ON true;\n\nSELECT * FROM ddlx_apropos('users') JOIN ddlx_definitions(objid) ON true;\n```\nSee file [ddlx.sql](ddlx.sql) and [full list of functions](test/expected/manifest.out) for additional details.\nFunctions with comments are public API. The rest are intended for internal use, the purpose can\nusually be inferred from the name.\n\nSee file [function_usage.svg](docs/function_usage.svg) for a picture of how this is put together.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flacanoid%2Fpgddl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flacanoid%2Fpgddl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flacanoid%2Fpgddl/lists"}