Commits

Kirill Simonov committed fe48c17

Added tests for numeric functions and operators.

Integer literals: assume support for 64-bit signed integers.
SQLite: added support for `round(_,_)`.

  • Participants
  • Parent commits e6ce0ef

Comments (0)

Files changed (6)

File src/htsql/tr/dump.py

         # Dump an integer number.  A backend may override this implementation
         # to support a different range of integer values.
 
-        # We assume that the database supports no more that 4-byte signed
-        # integer values natively and complain if the value is out of this
-        # range.
-        if not (-2**31 <= self.value < 2**31):
+        # We assume that the database supports 8-byte signed integer values
+        # natively and complain if the value is out of this range.
+        if not (-2**63 <= self.value < 2**63):
             raise SerializeError("invalid integer value",
                                  self.phrase.mark)
         # Write the number.

File src/htsql_pgsql/tr/dump.py

                 self.write(", ")
 
 
-class PGSQLDumpInteger(DumpInteger):
-
-    def __call__(self):
-        if not (-2**63 <= self.value < 2**63):
-            raise SerializeError("invalid integer value",
-                                 self.phrase.mark)
-        self.write(str(self.value))
-
-
 class PGSQLDumpFloat(DumpFloat):
 
     def __call__(self):
-        value = repr(self.value)
-        if value == 'inf':
-            value = "'Infinity'"
-        elif value == '-inf':
-            value = "'-Infinity'"
-        elif value == 'nan':
-            value = "'NaN'"
-        self.format("%s::FLOAT8" % value)
+        self.write("%s::FLOAT8" % repr(self.value))
 
 
 class PGSQLDumpDecimal(DumpDecimal):
 
     def __call__(self):
-        if self.value.is_nan():
-            self.write("'NaN'::NUMERIC")
-            return
-        if not self.value.is_finite():
-            raise SerializeError("invalid decimal value",
-                                 self.phrase.mark)
-        self.format("%s::NUMERIC" % self.value)
+        self.write("%s::NUMERIC" % self.value)
 
 
 class PGSQLDumpDate(DumpDate):

File src/htsql_sqlite/tr/bind.py

 """
 
 
-from htsql.domain import FloatDomain
-from htsql.tr.fn.bind import CorrelateDecimalAvg
+from htsql.domain import IntegerDomain, FloatDomain
+from htsql.tr.fn.bind import (correlates, CorrelateDecimalRoundTo,
+                              CorrelateDecimalAvg)
+from htsql.tr.fn.signature import RoundToSig
 
 
 class SQLiteCorrelateDecimalAvg(CorrelateDecimalAvg):
     codomain = FloatDomain()
 
 
+class SQLiteCorrelateFloatRoundTo(CorrelateDecimalRoundTo):
+
+    correlates(RoundToSig, (FloatDomain, IntegerDomain))
+
+

File test/input/library.yaml

   # Integer values
   - uri: /{0, 7, -97, 3571}
   - uri: /{integer('4862'), integer('-9694845')}
-  # 32-bit signed integers
-  - uri: /{integer('-2147483648'), integer('2147483647')}
   # 64-bit signed integers
   - uri: /{integer('-9223372036854775808'),
            integer('9223372036854775807')}
-    ifndef: sqlite
   # Invalid integer literal
   - uri: /{integer('2.5e1')}
     expect: 400
-  # Overflow 32-bit
-  - uri: /{4294967296}
-    expect: 400
-    ifndef: pgsql
-  # Overflow 64-bit
+  # Out of range
   - uri: /{18446744073709551616}
     expect: 400
 
            null()==null(), null()!==null()}
   # Coercion
   - uri: /{7=0.7e1, '13'=13.0, '13'!=='13.0'}
-  # Incompatible Operands
+  # Incompatible operands
   - uri: /{true()=1}
     expect: 400
   - uri: /{'cinq'!=4.9}
   - uri: /{0<null(), ''>null(), null()>=null()}
   # Coercion
   - uri: /{175e-2>'875e-3', '2010-04-15'>=date('1991-08-20')}
-  # Incompatible Operands
+  # Incompatible operands
   - uri: /{false()<true()}
     expect: 400
   - uri: /{'cinq'>4.9}
            null_if(null(), null())}
   # Coercion
   - uri: /{if_null(1, 0.1e1), null_if(1, 0.1e1)}
-  # Incompatible Operands
+  # Incompatible operands
   - uri: /{if_null('cinq', 5)}
     expect: 400
   - uri: /{null_if('cinq', 5)}
   - uri: /{switch(date('2010-04-15'),
                   '1991-08-20', 'WWW',
                   '2010-04-15', 'HTSQL')}
-  # Incompatible Operands
+  # Incompatible operands
   - uri: /{if('', 'then', 'else')}
     expect: 400
   - uri: /{switch(1, date('2010-04-15'), 1, date('1991-08-20'), 2)}
   - uri: /{switch(1, 1, 'George', 2, false())}
     expect: 400
 
+- title: Numeric Functions and Operators
+  tests:
+
+  # Conversion
+  - uri: /{integer(null()), integer('60'), integer(60)}
+  - uri: /{integer(2.125), integer(271828e-5)}
+  - uri: /{integer(string('60'))}
+  # Incompatible operand
+  - uri: /{integer('cinq')}
+    expect: 400
+  - uri: /{integer(true())}
+    expect: 400
+  - uri: /{integer(date('2010-04-15'))}
+    expect: 400
+  # Not a number
+  - uri: /{integer(string('zero'))}
+    ifdef: sqlite
+  - uri: /{integer(string('cinq'))}
+    expect: 409
+    ifdef: pgsql
+  # Integer overflow
+  - uri: /{integer(4294967296.0)}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{integer(1.8446744073709552e+19)}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{integer(4294967296.0),
+           integer(1.8446744073709552e+19)}
+    ifdef: sqlite
+
+  # Arithmetics
+  - uri: /{+7, -7, +2.125, -2.125, +271828e-5, -271828e-5}
+  - uri: /{7920+9504, 7.25+0.875, 120205e-5+57721e-5}
+  - uri: /{7920-9504, 7.25-0.875, 120205e-5-57721e-5}
+  - uri: /{7920*9504, 7.25*0.875, 120205e-5*57721e-5}
+  - uri: /{7920/9504, 7.25/0.875, 120205e-5/57721e-5}
+  # Coercion
+  - uri: /{7+2.125, 7+271828e-5, 2.125+271828e-5}
+  - uri: /{7-2.125, 7-271828e-5, 2.125-271828e-5}
+  - uri: /{7*2.125, 7*271828e-5, 2.125*271828e-5}
+  - uri: /{7/2.125, 7/271828e-5, 2.125/271828e-5}
+  # Incompatible operands
+  - uri: /{'cinq'+7}
+    expect: 400
+  - uri: /{2.125-date('2010-04-15')}
+    expect: 400
+  - uri: /{true()/271828e-5}
+    expect: 400
+  # Integer overflow
+  - uri: /{7*2147483647}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{9223372036854775807+1}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{7*2147483647, 9223372036854775807+1}
+    ifdef: sqlite
+  # Division by zero
+  - uri: /{7/0}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{7/0.0}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{7/0e0}
+    expect: 409
+    ifdef: pgsql
+  - uri: /{7/0, 7/0.0, 7/0e0}
+    ifdef: sqlite
+
+  # Rounding
+  - uri: /{round(3272.78125,2)}
+  - uri: /{round(3272.78125,-2)}
+    ifndef: sqlite
+  - uri: /{round(3272.78125), round(271828e-5)}
+  # Coercion
+  - uri: /{round(9973)}
+  - uri: /{round(9973,-2)}
+    ifndef: sqlite
+  # Incompatible operand
+  - uri: /{round(271828e-5,2)}
+    expect: 400
+    ifndef: sqlite
+
+
 # FIXME: update and refurbish!
 
 

File test/output/pgsql.yaml

              /{integer('4862'),integer('-9694845')}
              SELECT 4862,
                     -9694845
-        - uri: /{integer('-2147483648'), integer('2147483647')}
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                |
-            -+------------------------------------------------+-
-             | integer('-2147483648') | integer('2147483647') |
-            -+------------------------+-----------------------+-
-             |            -2147483648 |            2147483647 |
-                                                        (1 row)
-
-             ----
-             /{integer('-2147483648'),integer('2147483647')}
-             SELECT -2147483648,
-                    2147483647
         - uri: /{integer('-9223372036854775808'), integer('9223372036854775807')}
           status: 200 OK
           headers:
             encode error: invalid Boolean literal: expected 'true' or 'false'; got 'George':
                 /{switch(1, 1, 'George', 2, false())}
                                ^^^^^^^^
+      - id: numeric-functions-and-operators
+        tests:
+        - uri: /{integer(null()), integer('60'), integer(60)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                               |
+            -+-----------------------------------------------+-
+             | integer(null()) | integer('60') | integer(60) |
+            -+-----------------+---------------+-------------+-
+             |                 |            60 |          60 |
+                                                       (1 row)
+
+             ----
+             /{integer(null()),integer('60'),integer(60)}
+             SELECT NULL,
+                    60,
+                    60
+        - uri: /{integer(2.125), integer(271828e-5)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                     |
+            -+-------------------------------------+-
+             | integer(2.125) | integer(271828e-5) |
+            -+----------------+--------------------+-
+             |              2 |                  3 |
+                                             (1 row)
+
+             ----
+             /{integer(2.125),integer(271828e-5)}
+             SELECT CAST(2.125::NUMERIC AS INTEGER),
+                    CAST(2.71828::FLOAT8 AS INTEGER)
+        - uri: /{integer(string('60'))}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                       |
+            -+-----------------------+-
+             | integer(string('60')) |
+            -+-----------------------+-
+             |                    60 |
+                               (1 row)
+
+             ----
+             /{integer(string('60'))}
+             SELECT CAST('60' AS INTEGER)
+        - uri: /{integer('cinq')}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            encode error: invalid integer literal: expected an integer in a decimal format; got 'cinq':
+                /{integer('cinq')}
+                  ^^^^^^^^^^^^^^^
+        - uri: /{integer(true())}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            encode error: inadmissible conversion:
+                /{integer(true())}
+                  ^^^^^^^^^^^^^^^
+        - uri: /{integer(date('2010-04-15'))}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            encode error: inadmissible conversion:
+                /{integer(date('2010-04-15'))}
+                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{integer(string('cinq'))}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing "SELECT CAST('cinq' AS INTEGER)\n": invalid input syntax for integer: "cinq"
+            LINE 1: SELECT CAST('cinq' AS INTEGER)
+                                ^
+            :
+                /{integer(string('cinq'))}
+                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{integer(4294967296.0)}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT CAST(4294967296.0::NUMERIC AS INTEGER)\n': integer out of range
+            :
+                /{integer(4294967296.0)}
+                ^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{integer(1.8446744073709552e+19)}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT CAST(1.8446744073709552e+19::FLOAT8 AS INTEGER)\n': integer out of range
+            :
+                /{integer(1.8446744073709552e+19)}
+                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{+7, -7, +2.125, -2.125, +271828e-5, -271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                     |
+            -+-----------------------------------------------------+-
+             | +7 | -7 | +2.125 | -2.125 | +271828e-5 | -271828e-5 |
+            -+----+----+--------+--------+------------+------------+-
+             |  7 | -7 |  2.125 | -2.125 |    2.71828 |   -2.71828 |
+                                                             (1 row)
+
+             ----
+             /{+7,-7,+2.125,-2.125,+271828e-5,-271828e-5}
+             SELECT 7,
+                    (- 7),
+                    2.125::NUMERIC,
+                    (- 2.125::NUMERIC),
+                    2.71828::FLOAT8,
+                    (- 2.71828::FLOAT8)
+        - uri: /{7920+9504, 7.25+0.875, 120205e-5+57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                             |
+            -+---------------------------------------------+-
+             | 7920+9504 | 7.25+0.875 | 120205e-5+57721e-5 |
+            -+-----------+------------+--------------------+-
+             |     17424 |      8.125 |            1.77926 |
+                                                     (1 row)
+
+             ----
+             /{7920+9504,7.25+0.875,120205e-5+57721e-5}
+             SELECT (7920 + 9504),
+                    (7.25::NUMERIC + 0.875::NUMERIC),
+                    (1.2020500000000001::FLOAT8 + 0.57721::FLOAT8)
+        - uri: /{7920-9504, 7.25-0.875, 120205e-5-57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                             |
+            -+---------------------------------------------+-
+             | 7920-9504 | 7.25-0.875 | 120205e-5-57721e-5 |
+            -+-----------+------------+--------------------+-
+             |     -1584 |      6.375 |            0.62484 |
+                                                     (1 row)
+
+             ----
+             /{7920-9504,7.25-0.875,120205e-5-57721e-5}
+             SELECT (7920 - 9504),
+                    (7.25::NUMERIC - 0.875::NUMERIC),
+                    (1.2020500000000001::FLOAT8 - 0.57721::FLOAT8)
+        - uri: /{7920*9504, 7.25*0.875, 120205e-5*57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                             |
+            -+---------------------------------------------+-
+             | 7920*9504 | 7.25*0.875 | 120205e-5*57721e-5 |
+            -+-----------+------------+--------------------+-
+             |  75271680 |    6.34375 |       0.6938352805 |
+                                                     (1 row)
+
+             ----
+             /{7920*9504,7.25*0.875,120205e-5*57721e-5}
+             SELECT (7920 * 9504),
+                    (7.25::NUMERIC * 0.875::NUMERIC),
+                    (1.2020500000000001::FLOAT8 * 0.57721::FLOAT8)
+        - uri: /{7920/9504, 7.25/0.875, 120205e-5/57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                  |
+            -+------------------------------------------------------------------+-
+             | 7920/9504              | 7.25/0.875         | 120205e-5/57721e-5 |
+            -+------------------------+--------------------+--------------------+-
+             | 0.83333333333333333333 | 8.2857142857142857 |       2.0825176279 |
+                                                                          (1 row)
+
+             ----
+             /{7920/9504,7.25/0.875,120205e-5/57721e-5}
+             SELECT (7920::NUMERIC / 9504::NUMERIC),
+                    (7.25::NUMERIC / 0.875::NUMERIC),
+                    (1.2020500000000001::FLOAT8 / 0.57721::FLOAT8)
+        - uri: /{7+2.125, 7+271828e-5, 2.125+271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                         |
+            -+-----------------------------------------+-
+             | 7+2.125 | 7+271828e-5 | 2.125+271828e-5 |
+            -+---------+-------------+-----------------+-
+             |   9.125 |     9.71828 |         4.84328 |
+                                                 (1 row)
+
+             ----
+             /{7+2.125,7+271828e-5,2.125+271828e-5}
+             SELECT (7::NUMERIC + 2.125::NUMERIC),
+                    (7.0::FLOAT8 + 2.71828::FLOAT8),
+                    (2.125::FLOAT8 + 2.71828::FLOAT8)
+        - uri: /{7-2.125, 7-271828e-5, 2.125-271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                         |
+            -+-----------------------------------------+-
+             | 7-2.125 | 7-271828e-5 | 2.125-271828e-5 |
+            -+---------+-------------+-----------------+-
+             |   4.875 |     4.28172 |        -0.59328 |
+                                                 (1 row)
+
+             ----
+             /{7-2.125,7-271828e-5,2.125-271828e-5}
+             SELECT (7::NUMERIC - 2.125::NUMERIC),
+                    (7.0::FLOAT8 - 2.71828::FLOAT8),
+                    (2.125::FLOAT8 - 2.71828::FLOAT8)
+        - uri: /{7*2.125, 7*271828e-5, 2.125*271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                         |
+            -+-----------------------------------------+-
+             | 7*2.125 | 7*271828e-5 | 2.125*271828e-5 |
+            -+---------+-------------+-----------------+-
+             |  14.875 |    19.02796 |        5.776345 |
+                                                 (1 row)
+
+             ----
+             /{7*2.125,7*271828e-5,2.125*271828e-5}
+             SELECT (7::NUMERIC * 2.125::NUMERIC),
+                    (7.0::FLOAT8 * 2.71828::FLOAT8),
+                    (2.125::FLOAT8 * 2.71828::FLOAT8)
+        - uri: /{7/2.125, 7/271828e-5, 2.125/271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                      |
+            -+------------------------------------------------------+-
+             | 7/2.125            | 7/271828e-5   | 2.125/271828e-5 |
+            -+--------------------+---------------+-----------------+-
+             | 3.2941176470588235 | 2.57515782039 |  0.781744338332 |
+                                                              (1 row)
+
+             ----
+             /{7/2.125,7/271828e-5,2.125/271828e-5}
+             SELECT (7::NUMERIC / 2.125::NUMERIC),
+                    (7.0::FLOAT8 / 2.71828::FLOAT8),
+                    (2.125::FLOAT8 / 2.71828::FLOAT8)
+        - uri: /{'cinq'+7}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{'cinq'+7}
+                  ^^^^^^^^
+        - uri: /{2.125-date('2010-04-15')}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{2.125-date('2010-04-15')}
+                  ^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{true()/271828e-5}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{true()/271828e-5}
+                  ^^^^^^^^^^^^^^^^
+        - uri: /{7*2147483647}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT (7 * 2147483647)\n': integer out of range
+            :
+                /{7*2147483647}
+                ^^^^^^^^^^^^^^^
+        - uri: /{9223372036854775807+1}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT (9223372036854775807 + 1)\n': bigint out of range
+            :
+                /{9223372036854775807+1}
+                ^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{7/0}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT (7::NUMERIC / 0::NUMERIC)\n': division by zero
+            :
+                /{7/0}
+                ^^^^^^
+        - uri: /{7/0.0}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT (7::NUMERIC / 0.0::NUMERIC)\n': division by zero
+            :
+                /{7/0.0}
+                ^^^^^^^^
+        - uri: /{7/0e0}
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            engine failure: error while executing 'SELECT (7.0::FLOAT8 / 0.0::FLOAT8)\n': division by zero
+            :
+                /{7/0e0}
+                ^^^^^^^^
+        - uri: /{round(3272.78125,2)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                     |
+            -+---------------------+-
+             | round(3272.78125,2) |
+            -+---------------------+-
+             |             3272.78 |
+                             (1 row)
+
+             ----
+             /{round(3272.78125,2)}
+             SELECT ROUND(3272.78125::NUMERIC, 2)
+        - uri: /{round(3272.78125,-2)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                      |
+            -+----------------------+-
+             | round(3272.78125,-2) |
+            -+----------------------+-
+             |                 3300 |
+                              (1 row)
+
+             ----
+             /{round(3272.78125,-2)}
+             SELECT ROUND(3272.78125::NUMERIC, (- 2))
+        - uri: /{round(3272.78125), round(271828e-5)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                      |
+            -+--------------------------------------+-
+             | round(3272.78125) | round(271828e-5) |
+            -+-------------------+------------------+-
+             |              3273 |              3.0 |
+                                              (1 row)
+
+             ----
+             /{round(3272.78125),round(271828e-5)}
+             SELECT ROUND(3272.78125::NUMERIC),
+                    ROUND(2.71828::FLOAT8)
+        - uri: /{round(9973)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |             |
+            -+-------------+-
+             | round(9973) |
+            -+-------------+-
+             |        9973 |
+                     (1 row)
+
+             ----
+             /{round(9973)}
+             SELECT ROUND(9973::NUMERIC)
+        - uri: /{round(9973,-2)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                |
+            -+----------------+-
+             | round(9973,-2) |
+            -+----------------+-
+             |          10000 |
+                        (1 row)
+
+             ----
+             /{round(9973,-2)}
+             SELECT ROUND(9973::NUMERIC, (- 2))
+        - uri: /{round(271828e-5,2)}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{round(271828e-5,2)}
+                  ^^^^^^^^^^^^^^^^^^
       - id: scalar-functions
         tests:
         - id: boolean-constants-and-logical-operators

File test/output/sqlite.yaml

              /{integer('4862'),integer('-9694845')}
              SELECT 4862,
                     -9694845
-        - uri: /{integer('-2147483648'), integer('2147483647')}
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                |
-            -+------------------------------------------------+-
-             | integer('-2147483648') | integer('2147483647') |
-            -+------------------------+-----------------------+-
-             |            -2147483648 |            2147483647 |
-                                                        (1 row)
-
-             ----
-             /{integer('-2147483648'),integer('2147483647')}
-             SELECT -2147483648,
-                    2147483647
+        - uri: /{integer('-9223372036854775808'), integer('9223372036854775807')}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                  |
+            -+------------------------------------------------------------------+-
+             | integer('-9223372036854775808') | integer('9223372036854775807') |
+            -+---------------------------------+--------------------------------+-
+             |            -9223372036854775808 |            9223372036854775807 |
+                                                                          (1 row)
+
+             ----
+             /{integer('-9223372036854775808'),integer('9223372036854775807')}
+             SELECT -9223372036854775808,
+                    9223372036854775807
         - uri: /{integer('2.5e1')}
           status: 400 Bad Request
           headers:
             encode error: invalid integer literal: expected an integer in a decimal format; got '2.5e1':
                 /{integer('2.5e1')}
                   ^^^^^^^^^^^^^^^^
-        - uri: /{4294967296}
-          status: 400 Bad Request
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |
-            serialize error: invalid integer value:
-                /{4294967296}
-                  ^^^^^^^^^^
         - uri: /{18446744073709551616}
           status: 400 Bad Request
           headers:
             encode error: invalid Boolean literal: expected 'true' or 'false'; got 'George':
                 /{switch(1, 1, 'George', 2, false())}
                                ^^^^^^^^
+      - id: numeric-functions-and-operators
+        tests:
+        - uri: /{integer(null()), integer('60'), integer(60)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                               |
+            -+-----------------------------------------------+-
+             | integer(null()) | integer('60') | integer(60) |
+            -+-----------------+---------------+-------------+-
+             |                 |            60 |          60 |
+                                                       (1 row)
+
+             ----
+             /{integer(null()),integer('60'),integer(60)}
+             SELECT NULL,
+                    60,
+                    60
+        - uri: /{integer(2.125), integer(271828e-5)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                     |
+            -+-------------------------------------+-
+             | integer(2.125) | integer(271828e-5) |
+            -+----------------+--------------------+-
+             |              2 |                  2 |
+                                             (1 row)
+
+             ----
+             /{integer(2.125),integer(271828e-5)}
+             SELECT CAST(2.125 AS INTEGER),
+                    CAST(2.71828 AS INTEGER)
+        - uri: /{integer(string('60'))}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                       |
+            -+-----------------------+-
+             | integer(string('60')) |
+            -+-----------------------+-
+             |                    60 |
+                               (1 row)
+
+             ----
+             /{integer(string('60'))}
+             SELECT CAST('60' AS INTEGER)
+        - uri: /{integer('cinq')}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            encode error: invalid integer literal: expected an integer in a decimal format; got 'cinq':
+                /{integer('cinq')}
+                  ^^^^^^^^^^^^^^^
+        - uri: /{integer(true())}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            encode error: inadmissible conversion:
+                /{integer(true())}
+                  ^^^^^^^^^^^^^^^
+        - uri: /{integer(date('2010-04-15'))}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            encode error: inadmissible conversion:
+                /{integer(date('2010-04-15'))}
+                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{integer(string('zero'))}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                         |
+            -+-------------------------+-
+             | integer(string('zero')) |
+            -+-------------------------+-
+             |                       0 |
+                                 (1 row)
+
+             ----
+             /{integer(string('zero'))}
+             SELECT CAST('zero' AS INTEGER)
+        - uri: /{integer(4294967296.0), integer(1.8446744073709552e+19)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                         |
+            -+---------------------------------------------------------+-
+             | integer(4294967296.0) | integer(1.8446744073709552e+19) |
+            -+-----------------------+---------------------------------+-
+             |            4294967296 |            -9223372036854775808 |
+                                                                 (1 row)
+
+             ----
+             /{integer(4294967296.0),integer(1.8446744073709552e+19)}
+             SELECT CAST(4294967296.0 AS INTEGER),
+                    CAST(1.8446744073709552e+19 AS INTEGER)
+        - uri: /{+7, -7, +2.125, -2.125, +271828e-5, -271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                     |
+            -+-----------------------------------------------------+-
+             | +7 | -7 | +2.125 | -2.125 | +271828e-5 | -271828e-5 |
+            -+----+----+--------+--------+------------+------------+-
+             |  7 | -7 |  2.125 | -2.125 |    2.71828 |   -2.71828 |
+                                                             (1 row)
+
+             ----
+             /{+7,-7,+2.125,-2.125,+271828e-5,-271828e-5}
+             SELECT 7,
+                    (- 7),
+                    2.125,
+                    (- 2.125),
+                    2.71828,
+                    (- 2.71828)
+        - uri: /{7920+9504, 7.25+0.875, 120205e-5+57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                             |
+            -+---------------------------------------------+-
+             | 7920+9504 | 7.25+0.875 | 120205e-5+57721e-5 |
+            -+-----------+------------+--------------------+-
+             |     17424 |      8.125 |            1.77926 |
+                                                     (1 row)
+
+             ----
+             /{7920+9504,7.25+0.875,120205e-5+57721e-5}
+             SELECT (7920 + 9504),
+                    (7.25 + 0.875),
+                    (1.2020500000000001 + 0.57721)
+        - uri: /{7920-9504, 7.25-0.875, 120205e-5-57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                             |
+            -+---------------------------------------------+-
+             | 7920-9504 | 7.25-0.875 | 120205e-5-57721e-5 |
+            -+-----------+------------+--------------------+-
+             |     -1584 |      6.375 |            0.62484 |
+                                                     (1 row)
+
+             ----
+             /{7920-9504,7.25-0.875,120205e-5-57721e-5}
+             SELECT (7920 - 9504),
+                    (7.25 - 0.875),
+                    (1.2020500000000001 - 0.57721)
+        - uri: /{7920*9504, 7.25*0.875, 120205e-5*57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                             |
+            -+---------------------------------------------+-
+             | 7920*9504 | 7.25*0.875 | 120205e-5*57721e-5 |
+            -+-----------+------------+--------------------+-
+             |  75271680 |    6.34375 |       0.6938352805 |
+                                                     (1 row)
+
+             ----
+             /{7920*9504,7.25*0.875,120205e-5*57721e-5}
+             SELECT (7920 * 9504),
+                    (7.25 * 0.875),
+                    (1.2020500000000001 * 0.57721)
+        - uri: /{7920/9504, 7.25/0.875, 120205e-5/57721e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                     |
+            -+-----------------------------------------------------+-
+             | 7920/9504      | 7.25/0.875    | 120205e-5/57721e-5 |
+            -+----------------+---------------+--------------------+-
+             | 0.833333333333 | 8.28571428571 |       2.0825176279 |
+                                                             (1 row)
+
+             ----
+             /{7920/9504,7.25/0.875,120205e-5/57721e-5}
+             SELECT (7920.0 / 9504.0),
+                    (7.25 / 0.875),
+                    (1.2020500000000001 / 0.57721)
+        - uri: /{7+2.125, 7+271828e-5, 2.125+271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                         |
+            -+-----------------------------------------+-
+             | 7+2.125 | 7+271828e-5 | 2.125+271828e-5 |
+            -+---------+-------------+-----------------+-
+             |   9.125 |     9.71828 |         4.84328 |
+                                                 (1 row)
+
+             ----
+             /{7+2.125,7+271828e-5,2.125+271828e-5}
+             SELECT (7.0 + 2.125),
+                    (7.0 + 2.71828),
+                    (2.125 + 2.71828)
+        - uri: /{7-2.125, 7-271828e-5, 2.125-271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                         |
+            -+-----------------------------------------+-
+             | 7-2.125 | 7-271828e-5 | 2.125-271828e-5 |
+            -+---------+-------------+-----------------+-
+             |   4.875 |     4.28172 |        -0.59328 |
+                                                 (1 row)
+
+             ----
+             /{7-2.125,7-271828e-5,2.125-271828e-5}
+             SELECT (7.0 - 2.125),
+                    (7.0 - 2.71828),
+                    (2.125 - 2.71828)
+        - uri: /{7*2.125, 7*271828e-5, 2.125*271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                         |
+            -+-----------------------------------------+-
+             | 7*2.125 | 7*271828e-5 | 2.125*271828e-5 |
+            -+---------+-------------+-----------------+-
+             |  14.875 |    19.02796 |        5.776345 |
+                                                 (1 row)
+
+             ----
+             /{7*2.125,7*271828e-5,2.125*271828e-5}
+             SELECT (7.0 * 2.125),
+                    (7.0 * 2.71828),
+                    (2.125 * 2.71828)
+        - uri: /{7/2.125, 7/271828e-5, 2.125/271828e-5}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                 |
+            -+-------------------------------------------------+-
+             | 7/2.125       | 7/271828e-5   | 2.125/271828e-5 |
+            -+---------------+---------------+-----------------+-
+             | 3.29411764706 | 2.57515782039 |  0.781744338332 |
+                                                         (1 row)
+
+             ----
+             /{7/2.125,7/271828e-5,2.125/271828e-5}
+             SELECT (7.0 / 2.125),
+                    (7.0 / 2.71828),
+                    (2.125 / 2.71828)
+        - uri: /{'cinq'+7}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{'cinq'+7}
+                  ^^^^^^^^
+        - uri: /{2.125-date('2010-04-15')}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{2.125-date('2010-04-15')}
+                  ^^^^^^^^^^^^^^^^^^^^^^^^
+        - uri: /{true()/271828e-5}
+          status: 400 Bad Request
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |
+            bind error: incompatible arguments:
+                /{true()/271828e-5}
+                  ^^^^^^^^^^^^^^^^
+        - uri: /{7*2147483647, 9223372036854775807+1}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                      |
+            -+--------------------------------------+-
+             | 7*2147483647 | 9223372036854775807+1 |
+            -+--------------+-----------------------+-
+             |  15032385529 |  -9223372036854775808 |
+                                              (1 row)
+
+             ----
+             /{7*2147483647,9223372036854775807+1}
+             SELECT (7 * 2147483647),
+                    (9223372036854775807 + 1)
+        - uri: /{7/0, 7/0.0, 7/0e0}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                     |
+            -+---------------------+-
+             | 7/0 | 7/0.0 | 7/0e0 |
+            -+-----+-------+-------+-
+             |     |       |       |
+                             (1 row)
+
+             ----
+             /{7/0,7/0.0,7/0e0}
+             SELECT (7.0 / 0.0),
+                    (7.0 / 0.0),
+                    (7.0 / 0.0)
+        - uri: /{round(3272.78125,2)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                     |
+            -+---------------------+-
+             | round(3272.78125,2) |
+            -+---------------------+-
+             |             3272.78 |
+                             (1 row)
+
+             ----
+             /{round(3272.78125,2)}
+             SELECT ROUND(3272.78125, 2)
+        - uri: /{round(3272.78125), round(271828e-5)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                      |
+            -+--------------------------------------+-
+             | round(3272.78125) | round(271828e-5) |
+            -+-------------------+------------------+-
+             |            3273.0 |              3.0 |
+                                              (1 row)
+
+             ----
+             /{round(3272.78125),round(271828e-5)}
+             SELECT ROUND(3272.78125),
+                    ROUND(2.71828)
+        - uri: /{round(9973)}
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |             |
+            -+-------------+-
+             | round(9973) |
+            -+-------------+-
+             |      9973.0 |
+                     (1 row)
+
+             ----
+             /{round(9973)}
+             SELECT ROUND(9973.0)
   - include: test/input/translation.yaml
     output:
       id: translation