branch: elpa/pg
commit 3f894bd7b07c1b2c40ac7d22dc61b2337d67cb2f
Author: Eric Marsden <[email protected]>
Commit: Eric Marsden <[email protected]>

    Tests: additional tests for prepared statements, casting, numerical 
functions
---
 test/test-pg.el | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 7 deletions(-)

diff --git a/test/test-pg.el b/test/test-pg.el
index 3b4ed8a7775..14aaf2daaa0 100755
--- a/test/test-pg.el
+++ b/test/test-pg.el
@@ -20,7 +20,7 @@
 
 
 ;; for performance testing
-(setq process-adaptive-read-buffering nil)
+(setq process-adaptive-read-buffering t)
 
 
 ;; 
https://www.reidatcheson.com/floating%20point/comparison/2019/03/20/floating-point-comparison.html
@@ -326,11 +326,15 @@
       (message "Current schema: %s" (pg-current-schema con))
       (message "List of schemas in db: %s" (pg-schemas con))
       (message "List of tables in db: %s" (pg-tables con))
+      ;; Special testing for pg_duckdb
+      (when (cl-find "duckdb" (pg-schemas con) :test #'string=)
+        (message "Activating duckdb.force_execution")
+        (pg-exec con "SET duckdb.force_execution = true"))
       (when (eq 'orioledb (pgcon-server-variant con))
         (pg-exec con "CREATE EXTENSION IF NOT EXISTS orioledb"))
       (unless (member (pgcon-server-variant con) '(clickhouse alloydb 
risingwave stoolap))
         (pg-setup-postgis con))
-      (unless (member (pgcon-server-variant con) '(clickhouse risingwave 
stoolap))
+      (unless (member (pgcon-server-variant con) '(clickhouse risingwave 
stoolap arcadedb))
         (pg-vector-setup con))
       (pgtest-add #'pg-test-basic)
       (pgtest-add #'pg-test-insert)
@@ -349,7 +353,7 @@
       (pgtest-add #'pg-test-numeric
                   :skip-variants '(vertica))
       (pgtest-add #'pg-test-numeric-range
-                  :skip-variants '(xata cratedb cockroachdb ydb risingwave 
questdb clickhouse greptimedb spanner octodb vertica cedardb datafusion immudb))
+                  :skip-variants '(xata cratedb cockroachdb ydb risingwave 
questdb clickhouse greptimedb spanner octodb vertica cedardb datafusion immudb 
stoolap))
       (pgtest-add #'pg-test-prepared
                   :skip-variants '(ydb cratedb)
                   :need-emacs "28")
@@ -574,6 +578,10 @@
     (should (eql 42 (scalar "SELECT $1 + 142" '((-100 . "int4")))))
     (should (eql 42 (scalar "SELECT $1 + 1" '((41 . "int8")))))
     (should (eql 42 (scalar "SELECT $1 + 142" '((-100 . "int8")))))
+    (should (eql 42 (scalar "SELECT $1 + 142" '((-100 . "smallint")))))
+    (should (eql 42 (scalar "SELECT $1 + 142" '((-100 . "integer")))))
+    (should (eql 42 (scalar "SELECT $1 + 142" '((-100 . "bigint")))))
+    (should (eql 100 (scalar "SELECT $1" '((100 . "oid")))))
     (should (pgtest-approx= -55.0 (scalar "SELECT $1" '((-55.0 . "float4")))))
     (should (pgtest-approx= -55.0 (scalar "SELECT $1" '((-55.0 . "float8")))))
     (should (pgtest-approx= 42.0 (scalar "SELECT $1 + 1" '((41.0 . 
"float4")))))
@@ -748,6 +756,8 @@
     (should (eql -6 (scalar "SELECT -(6)")))
     (should (eql ?Z (scalar "SELECT 'Z'::char")))
     (should (eql ?@ (scalar "SELECT '@'::char(1)")))
+    (should (eql 97 (scalar "SELECT ascii('a')")))
+    (should (eql 0 (scalar "SELECT ascii('')")))
     (unless (member (pgcon-server-variant con) '(cratedb cockroachdb cedardb 
spanner))
       (should (eql ?! (scalar "SELECT '!'::bpchar(1)"))))
     (should (string= "Z" (scalar "SELECT 'Z'::varchar")))
@@ -755,6 +765,9 @@
     (should (string= "AB" (scalar "SELECT 'AB'::char(2)")))
     (should (string= "ÁÔ" (scalar "SELECT 'ÁÔ'::char(2)")))
     (should (string= "ÁÔ" (scalar "SELECT 'ÁÔ'::varchar(2)")))
+    (should (string= "3" (scalar "SELECT CAST (1+2 AS text)")))
+    (should (string= "3" (scalar "SELECT CAST (1+2 AS varchar)")))
+    (should (string= "3" (scalar "SELECT CAST (1+2 AS varchar(10))")))
     (unless (member (pgcon-server-variant con) '(cratedb cockroachdb cedardb 
spanner))
       (should (string= "12" (scalar "SELECT '12'::bpchar(2)"))))
     (should (string= "£Öí" (scalar "SELECT '£Öí'::text")))
@@ -795,6 +808,7 @@
       (should (eql nil (row " SELECT 3 WHERE 1=0"))))
     (should (eql 4 (scalar "SELECT ((2 * 2))")))
     (should (string= "abcdef" (scalar "SELECT 'abc' || 'def'")))
+    (should (equal pg-null-marker (scalar "SELECT NULL || NULL")))
     (should (string= "abc" (scalar "SELECT concat('abc', NULL)")))
     (should (string= "foo69" (scalar "SELECT concat('foo', 69)")))
     (should (string= "howdy" (scalar "SELECT 'howdy'::text")))
@@ -864,6 +878,8 @@
     (should (string= "" (scalar "SELECT substring('foobles' from 2 for 0)")))
     (should (eql 0 (scalar "SELECT length(concat('', NULL, ''))")))
     (should (string= "" (scalar "SELECT ''::VARCHAR")))
+    (should (string= "" (scalar "SELECT substr('foobles', 8, 0)")))
+    (should (equal pg-null-marker (scalar "SELECT substring('foo' FROM 
null::text)")))
     ;; Returns NULL because NULL is weird in SQL
     (should (equal pg-null-marker (scalar "SELECT NULL = NULL")))
     ;; IS checks for NULL identity
@@ -893,6 +909,14 @@
     (unless (member (pgcon-server-variant con) '(cratedb))
       (should (eql nil (row "-- comment")))
       (should (eql nil (row "  /* only a comment */ "))))
+    (should (eql 42 (scalar "SELECT 42; -- comment")))
+    (should (eql 42 (scalar "SELECT /* Free Palestine */ 42 -- more ")))
+    (should (eql 42 (scalar "SELECT 40
+-- more
+-- that
+-- is
+-- ignored
++ 2")))
     ;; This statement is strangely very poorly supported in semi-compatible 
PostgreSQL variants...
     (unless (member (pgcon-server-variant con) '(cratedb risingwave))
       (let* ((res (pg-exec con "SELECT 42 as éléphant"))
@@ -1303,6 +1327,7 @@ bar$$"))))
       ;; Here the hh:mm:ss are taken into account.
       (should (equal (scalar "SELECT '2063-03-31T22:13:02'::timestamp")
                      (encode-time (list 2 13 22 31 3 2063 nil -1 nil))))
+      (should (eql 21 (scalar "SELECT EXTRACT (century FROM NOW())")))
       (unless (member (pgcon-server-variant con) '(ydb))
         (message "TZ test: current PostgreSQL timezone is %s" (scalar "SHOW 
timezone")))
       (message "TZ test: current Emacs timezone is %s" (current-time-zone))
@@ -1351,6 +1376,8 @@ bar$$"))))
                      (encode-time (list 21 42 14 5 4 2010 nil -1 nil))))
       (should (equal (scalar "SELECT 'PT42S'::interval") "00:00:42"))
       (should (equal (scalar "SELECT 'PT3H4M42S'::interval") "03:04:42"))
+      (should (equal (scalar "SELECT 0 * interval '10 second'") "00:00:00"))
+      (should (eql 3 (scalar "SELECT extract(year from '3 years'::interval)")))
       (should (equal (scalar "select '05:00'::time") "05:00:00"))
       (should (equal (scalar "SELECT '04:15:31.445+05'::timetz") 
"04:15:31.445+05"))
       (should (equal (scalar "SELECT '2001-02-03 04:05:06'::timestamp")
@@ -1436,7 +1463,15 @@ bar$$"))))
     (should (eql 42 (scalar "SELECT ceil(41.9)")))
     (should (eql -42 (scalar "SELECT ceil(-42.9)")))
     (should (eql 42 (scalar "SELECT ceil(42::bigint)")))
+    (should (pgtest-approx= 1.0 (scalar "SELECT sign(42.0)")))
+    (should (pgtest-approx= 1.0 (scalar "SELECT sign(42::bigint)")))
+    (should (pgtest-approx= 1.0 (scalar "SELECT sign(42.0::float)")))
+    (should (equal pg-null-marker (scalar "SELECT sqrt(NULL)")))
     (should (eql pg-null-marker (scalar "SELECT ceil(NULL)")))
+    (should (pgtest-approx= (scalar "SELECT log(10, 10)") 1.0))
+    (should (pgtest-approx= (scalar "SELECT log(100.0)") 2.0))
+    (should (eql 1 (scalar "SELECT 3 % 2")))
+    (should (pgtest-approx= 81 (scalar "SELECT 3::numeric ^ 4::numeric")))
     ;; The cube root operator
     (unless (member (pgcon-server-variant con) '(cratedb materialize))
       (should (pgtest-approx= 3.0 (scalar "SELECT ||/ float8 '27'"))))
@@ -1718,16 +1753,22 @@ bar$$"))))
       (should (equal pg-null-marker (aref res 1))))
     (let ((res (scalar "SELECT array_remove(ARRAY[1,2,-3], 10)")))
       (should (equal (vector 1 2 -3) res)))
-    (should (equal (vector 1 2) (scalar "SELECT concat(NULL, ARRAY[1, 2])")))
-    (should (equal (vector 1 2 69) (scalar "SELECT concat(ARRAY[1::bigint], 
ARRAY[2, 69::int2])")))
-    (should (equal (vector 69 420) (scalar "SELECT concat(69, ARRAY[420])")))
+    (let ((res (scalar "SELECT array_prepend(42, ARRAY[7,8,9])")))
+      (should (eql (length res) 4))
+      (should (eql (aref res 0) 42)))
+    (should (equal (vector 2 3 4) (scalar "SELECT a[2:] FROM (SELECT 
'{1,2,3,4}'::integer[] AS a)")))
+    (should (equal (vector) (scalar "SELECT a[10:] FROM (SELECT 
'{1,2,3,4}'::integer[] AS a)")))
+    (should (string= "{1,2}" (scalar "SELECT concat(NULL, ARRAY[1, 2])")))
+    (should (string= "{1}{2,69}" (scalar "SELECT concat(ARRAY[1::bigint], 
ARRAY[2, 69::int2])")))
+    (should (string= "69{420}" (scalar "SELECT concat(69, ARRAY[420])")))
     (let* ((res (pg-exec-prepared con "SELECT $1" '(([1 2 3] . "_int4"))))
            (row (pg-result res :tuple 0)))
       (should (equal (vector 1 2 3) (cl-first row))))
     (let ((vec (scalar "SELECT ARRAY[44.3, 8999.5]")))
       (should (equal 2 (length vec)))
       (should (pgtest-approx= 44.3 (aref vec 0)))
-      (should (pgtest-approx= 8999.5 (aref vec 1))))))
+      (should (pgtest-approx= 8999.5 (aref vec 1))))
+    (should (equal 42 (scalar "SELECT unnest(ARRAY[42])")))))
 
 ;; TODO: we do not currently handle multidimension arrays correctly
 ;; (should (equal (vector (vector 4 5) (vector 6 7))
@@ -2446,6 +2487,7 @@ bar$$"))))
       (should (string= (scalar "SELECT 'SRID=4326;POINT(45 80.0)'::geography")
                        ;; "0101000020E610000000000000008046400000000000005440"
                        "POINT (45 80)"))
+      (should (eql 20 (scalar "SELECT st_distance('POINT (10 20)'::geometry, 
'POINT (30 20)'::geometry)")))
       (should (string= (scalar "SELECT 
'SPHEROID[\"GRS_1980\",6378137,298.2572]'::spheroid")
                        "SPHEROID(\"GRS_1980\",6378137,298.2572)"))
       (should (string= (scalar "SELECT Box2D(ST_GeomFromText('LINESTRING(1 2, 
3 4, 5 6)'))")
@@ -2780,6 +2822,9 @@ bar$$"))))
   (should (eql 'ok (condition-case nil
                        (funcall scalar-fn "SELECT log(-2.1)")
                      (pg-floating-point-exception 'ok))))
+  (should (eql 'ok (condition-case nil
+                       (funcall scalar-fn "SELECT asin(2.0)")
+                     (pg-numeric-value-out-of-range 'ok))))
   (should (eql 'ok (condition-case nil
                        (funcall scalar-fn "SELECT abs(true)")
                      (pg-undefined-function 'ok))))
@@ -2818,6 +2863,9 @@ bar$$"))))
                        ;; numerical overflow on smallint
                        (funcall scalar-fn "SELECT (-32768)::int2 / (-1)::int2")
                      (pg-numeric-value-out-of-range 'ok))))
+  (should (eql 'ok (condition-case nil
+                       (funcall scalar-fn "SELECT  -2147483647::integer - 
2::integer")
+                     (pg-numeric-value-out-of-range 'ok))))
   (should (eql 'ok (condition-case nil
                        (funcall scalar-fn "SELECT -12345::numeric(3)")
                      (pg-numeric-value-out-of-range 'ok))))
@@ -2831,6 +2879,10 @@ bar$$"))))
                          ;; numerical overflow on smallint
                          (funcall scalar-fn "SELECT int2 
'-0b1000000000000001'")
                        (pg-numeric-value-out-of-range 'ok)))))
+  (should (eql 'ok (condition-case nil
+                       ;; Can't OR bitstrings of different length
+                       (funcall scalar-fn "SELECT B'10001' | B'001'")
+                     (pg-data-error 'ok))))
   (should (eql 'ok (condition-case nil
                        ;; numerical overflow
                        (funcall scalar-fn "SELECT 
lcm((-9223372036854775808)::int8, 1::int8)")
@@ -2941,6 +2993,9 @@ bar$$"))))
   (should (eql 'ok (condition-case nil
                        (funcall scalar-fn "EXECUTE phantom_prepared_statement")
                      (pg-invalid-sql-statement-name 'ok))))
+  (should (eql 'ok (condition-case nil
+                       (funcall scalar-fn "ALTER DATABASE pgeltest_nonexistent 
REFRESH COLLATION VERSION")
+                     (pg-invalid-catalog-name 'ok))))
   ;; In PostgreSQL 18.1, this does not trigger an error.
   (should (eql nil (pg-close-portal con "nonexistent_portal")))
   ;; CockroachDB reports this as a pg-data-error, and PostgreSQL as 
pg-undefined-function.
@@ -2994,6 +3049,10 @@ bar$$"))))
   (should (eql 'ok (condition-case nil
                        (funcall scalar-fn "SELECT int2 '10__000'")
                      (pg-invalid-text-representation 'ok))))
+  (should (eql 'ok (condition-case nil
+                       (funcall scalar-fn "SELECT '{ }}'::text[]")
+                     (pg-invalid-text-representation 'ok)
+                     (pg-syntax-error 'ok))))
   (should (eql 'ok (condition-case nil
                        (funcall scalar-fn "SELECT 'true false::json")
                      (pg-syntax-error 'ok))))

Reply via email to