branch: elpa/pg commit 66963646838b9f78cbba04d5bccff4580959950d Author: Eric Marsden <eric.mars...@risk-engineering.org> Commit: Eric Marsden <eric.mars...@risk-engineering.org>
Add support for variants ArcadeDB, PolarDB, AgensGraph --- README.md | 20 ++++++++++++++------ pg.el | 20 ++++++++++++++++++++ test/test-pg.el | 6 +++--- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c96d64091b..f1e491cf50 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ main points where this compatibility may be problematic: particular the official client library libpq) use OpenSSL for TLS support, whereas Emacs uses GnuTLS, and you may encounter incompatibilities. -The following PostgreSQL-compatible databases have been tested: +The following PostgreSQL-compatible databases or extensions have been tested: - [Neon](https://neon.tech/) “serverless PostgreSQL” works perfectly. This is a commercially hosted service using a new storage engine for PostgreSQL, that they make available under the Apache @@ -83,7 +83,7 @@ The following PostgreSQL-compatible databases have been tested: - The [OrioleDB](https://github.com/orioledb/orioledb) extension, which adds a new storage engine designed for better multithreading and solid state storage, works perfectly. Last tested 2025-07 - with version beta11. + with version beta12. - The [Microsoft DocumentDB](https://github.com/microsoft/documentdb) extension for MongoDB-like queries (MIT licensed). Works perfectly. Note that this is not the same product as Amazon @@ -92,6 +92,9 @@ The following PostgreSQL-compatible databases have been tested: - The [Hydra Columnar](https://github.com/hydradatabase/columnar) extension for column-oriented storage and parallel queries (Apache license). Works perfectly (last tested 2025-05 with v1.1.2). +- The [AgensGraph](https://github.com/skaiworldwide-oss/agensgraph) extension for transactional + graph processing (Apache 2 license) works perfectly. Last tested 2025-07 with version 2.15. + - The [PgBouncer](https://www.pgbouncer.org/) connection pooler for PostgreSQL (open source, ISC licensed). Works fine (last tested 2025-06 with version 1.24 in the default session pooling mode). @@ -105,9 +108,14 @@ The following PostgreSQL-compatible databases have been tested: - [Google AlloyDB Omni](https://cloud.google.com/alloydb/omni/docs/quickstart) is a proprietary fork of PostgreSQL with Google-developed extensions, including a columnar storage extension, adaptive - autovacuum, and an index advisor. It works perfectly with pg-el as of 2025-06 (version that + autovacuum, and an index advisor. It works perfectly with pg-el as of 2025-07 (version that reports itself as "15.7"). +- [PolarDB for PostgreSQL](https://github.com/ApsaraDB/PolarDB-for-PostgreSQL) is free software + (Apache 2 licence) developed by Alibaba Cloud, also available as a commercial hosted service with + a proprietary distributed storage architecture. It works perfectly with pg-el (last tested 2025-07 + with version 15.13). + - [Xata](https://xata.io/) “serverless PostgreSQL” has many limitations including lack of support for `CREATE DATABASE`, `CREATE COLLATION`, for XML processing, for temporary tables, for cursors, for `EXPLAIN`, for `CREATE EXTENSION`, for `DROP FUNCTION`, for functions such as `pg_notify`. @@ -169,14 +177,14 @@ The following PostgreSQL-compatible databases have been tested: are many limitations in the PostgreSQL compatibility: no user metainformation, no cursors, no server-side prepared statements, no support for various types including arrays, JSON, UUID, vectors, tsvector, numeric ranges, geometric types. It works with these limitations with pg-el - (last tested 2025-05 with YottaDB 2.0.2). + (last tested 2025-07 with YottaDB 2.0.2). - The [GreptimeDB](https://github.com/GrepTimeTeam/greptimedb) time series database (Apache license) implements quite a lot of the PostgreSQL wire protocol, but the names it uses for types in the `pg_catalog.pg_types` table are not the same as those used by PostgreSQL (e.g. `Int64` instead of `int8`), so our parsing machinery does not work. This database also has more restrictions on the use of identifiers than PostgreSQL (for example, `id` is not accepted as a column name, nor are - identifiers containing Unicode characters). Last tested v0.14.3 in 2025-06. + identifiers containing Unicode characters). Last tested v0.15.2 in 2025-07. - Hosted PostgreSQL services that have been tested: as of 2025-06 render.com is running a Debian build of PostgreSQL 16.8 and works fine (requires TLS connection), as of 2024-12 @@ -197,7 +205,7 @@ PostgreSQL variants that **don't work** with pg-el: - The [ReadySet cache](https://github.com/readysettech/readyset) does not work in a satisfactory manner: it generate spurious errors such as `invalid binary data value` when using the extended - query protocol (last tested 2025-06). + query protocol (last tested 2025-07). Tested **Emacs versions**: mostly tested with versions 31 pre-release, 30.1 and 29.4. Emacs versions diff --git a/pg.el b/pg.el index 6da4375d44..e7691191dc 100644 --- a/pg.el +++ b/pg.el @@ -503,6 +503,11 @@ Uses connection CON. The variant can be accessed by `pgcon-server-variant'." (setf (pgcon-server-variant con) 'materialize)) ((cl-search "Vertica Analytic" version) (setf (pgcon-server-variant con) 'vertica)) + ((cl-search "PolarDB " version) + (setf (pgcon-server-variant con) 'polardb)) + ;; TODO: find a better detection method for ArcadeDB + ((string-suffix-p "/main)" version) + (setf (pgcon-server-variant con) 'arcadedb)) ;; A more expensive test is needed for Google AlloyDB. If this parameter is defined, ;; the query will return "on" or "off" as a string, and if the parameter is not defined ;; the query (second argument meaning no-error) will return '((nil)). @@ -639,6 +644,8 @@ Uses database DBNAME, user USER and password PASSWORD." (1+ (length dbname)) (1+ (length "application_name")) (1+ (length pg-application-name)) + (1+ (length "client_encoding")) + (1+ (length "UTF8")) 1))) (pg-send-uint con packet-octets 4) (pg-send-uint con 3 2) ; Protocol major version = 3 @@ -649,6 +656,8 @@ Uses database DBNAME, user USER and password PASSWORD." (pg-send-string con dbname) (pg-send-string con "application_name") (pg-send-string con pg-application-name) + (pg-send-string con "client_encoding") + (pg-send-string con "UTF8") ;; A zero byte is required as a terminator after the last name/value pair. (pg-send-uint con 0 1) (pg-flush con)) @@ -3451,6 +3460,9 @@ Uses database connection CON." (let* ((sql "SELECT database_name FROM v_catalog.databases") (res (pg-exec con sql))) (apply #'append (pg-result res :tuples)))) + ('arcadedb + (let ((res (pg-exec con "SELECT FROM schema:database"))) + (apply #'append (pg-result res :tuples)))) (_ (let ((res (pg-exec con "SELECT datname FROM pg_catalog.pg_database"))) (apply #'append (pg-result res :tuples)))))) @@ -3462,6 +3474,7 @@ Uses database connection CON." (let* ((res (pg-exec con "SELECT currentDatabase()")) (row (pg-result res :tuple 0))) (cl-first row))) + ('arcadedb nil) (_ (let* ((res (pg-exec con "SELECT current_schema()")) (row (pg-result res :tuple 0))) @@ -3474,6 +3487,7 @@ Uses database connection CON." (pcase (pgcon-server-variant con) ;; QuestDB doesn't really support schemas. ('questdb (list "sys" "public")) + ('arcadedb nil) ((or 'risingwave 'octodb) (let ((res (pg-exec con "SELECT DISTINCT table_schema FROM information_schema.tables"))) (apply #'append (pg-result res :tuples)))) @@ -3573,6 +3587,10 @@ Queries legacy internal PostgreSQL tables." for row in rows collect (make-pg-qualified-name :schema (cl-first row) :name (cl-second row))))) +(defun pg--tables-arcadedb (con) + (let ((res (pg-exec con "SELECT FROM schema:types"))) + (apply #'append (pg-result res :tuples)))) + (defun pg-tables (con) "List of the tables present in the database we are connected to via CON. Only tables to which the current user has access are listed." @@ -3588,6 +3606,8 @@ Only tables to which the current user has access are listed." (pg--tables-clickhouse con)) ((eq (pgcon-server-variant con) 'vertica) (pg--tables-vertica con)) + ((eq (pgcon-server-variant con) 'arcadedb) + (pg--tables-arcadedb con)) ((eq (pgcon-server-variant con) 'octodb) (pg--tables-legacy con)) ((> (pgcon-server-version-major con) 11) diff --git a/test/test-pg.el b/test/test-pg.el index b531ebc12e..92af9ca54d 100755 --- a/test/test-pg.el +++ b/test/test-pg.el @@ -14,7 +14,7 @@ (require 'ert) -(defvar pgtest--enable-query-log t) +(defvar pgtest--enable-query-log nil) (setq debug-on-error t) @@ -232,13 +232,13 @@ (message "Backend major-version is %s" (pgcon-server-version-major con)) (message "Detected backend variant: %s" (pgcon-server-variant con)) (unless (member (pgcon-server-variant con) - '(cockroachdb cratedb yugabyte ydb xata greptimedb risingwave clickhouse octodb vertica)) + '(cockroachdb cratedb yugabyte ydb xata greptimedb risingwave clickhouse octodb vertica arcadedb)) (when (> (pgcon-server-version-major con) 11) (let* ((res (pg-exec con "SELECT current_setting('ssl_library')")) (row (pg-result res :tuple 0))) (message "Backend compiled with SSL library %s" (cl-first row))))) (unless (member (pgcon-server-variant con) - '(questdb cratedb ydb xata greptimedb risingwave clickhouse materialize vertica)) + '(questdb cratedb ydb xata greptimedb risingwave clickhouse materialize vertica arcadedb)) (let* ((res (pg-exec con "SHOW ssl")) (row (pg-result res :tuple 0))) (message "PostgreSQL connection TLS: %s" (cl-first row))))