# The following tests have results equivalent to Postgres (differences
# in string representation and number of decimals returned, but otherwise
# the same). These do not pass using the inf package. The inf package
# (http://gopkg.in/inf.v0) is what we used to use, but it had various problems
# (for example, all the test cases below), and was replaced with apd.

# inf returns 0
query R
SELECT (1.4238790346995263e-40::DECIMAL / 6.011482313728436e+41::DECIMAL)
----
2.3685988919035999994E-82

# inf returns -108.4851126682386588
query R
SELECT ln(7.682705743584112e-48::DECIMAL)
----
-108.48511266823882051

# inf returns 0
query R
SELECT sqrt(9.789765531128956e-34::DECIMAL)
----
3.1288601009199749773E-17

# inf returns 0.1547300000000000
query R
SELECT pow(4.727998800941528e-14::DECIMAL, 0.06081860494226844::DECIMAL)
----
0.15472926640705911955

# inf returns 0, 0
query RR
SELECT pow(sqrt(1e-10::DECIMAL), 2), sqrt(pow(1e-5::DECIMAL, 2))
----
1.0000000000000000000E-10  0.000010000000000000000000

# inf returns 1e-16, 0, 2e-16
query RRR
SELECT 1e-16::DECIMAL / 2, 1e-16::DECIMAL / 3, 1e-16::DECIMAL / 2 * 2
----
5.0000000000000000000E-17  3.3333333333333333333E-17  1.00000000000000000000E-16

# inf returns 1e-8, 0, 0, 0
query RRRR
SELECT pow(1e-4::DECIMAL, 2), pow(1e-5::DECIMAL, 2), pow(1e-8::DECIMAL, 2), pow(1e-9::DECIMAL, 2)
----
1E-8  1E-10  1E-16  1E-18

# inf returns argument too large
query R
SELECT pow(1e-10::DECIMAL, 2)
----
1E-20

# inf panics (#13051)
query RR
SELECT 'NaN'::FLOAT::DECIMAL, 'NaN'::DECIMAL
----
NaN NaN

# Regression test for #102217.
query R
SELECT '0'::decimal(19,9)
----
0.000000000

# Ensure trailing zeros are kept for decimal types with no listed scale,
# and enforced when the scale is listed.

statement ok
CREATE TABLE t (d decimal, v decimal(3, 1))

statement ok
INSERT INTO t VALUES (0.000::decimal, 0.00::decimal), (1.00::decimal, 1.00::decimal), (2.0::decimal, 2.0::decimal), (3::decimal, 3::decimal)

query RR
SELECT * FROM t ORDER BY d
----
0.000  0.0
1.00   1.0
2.0    2.0
3      3.0

# Ensure trailing zeros are kept in an index.

statement ok
CREATE TABLE t2 (d decimal, v decimal(3, 1), primary key (d, v))

statement ok
INSERT INTO t2 VALUES
  (1.00::decimal, 1.00::decimal),
  (2.0::decimal, 2.0::decimal),
  (3::decimal, 3::decimal),
  ('NaN'::decimal, 'NaN'::decimal),
  ('Inf'::decimal, 'Inf'::decimal),
  ('-Inf'::decimal, '-Inf'::decimal),
  ('-0.0000'::decimal, '-0.0000'::decimal)

query RR
SELECT * FROM t2 ORDER BY d
----
NaN        NaN
-Infinity  -Infinity
0.0000     0.0
1.00       1.0
2.0        2.0
3          3.0
Infinity   Infinity

# Ensure uniqueness in PK columns with +/- NaN and 0.

statement error duplicate key value
INSERT INTO t2 VALUES ('-NaN'::decimal, '-NaN'::decimal)

statement error duplicate key value
INSERT INTO t2 VALUES (0, 0)

# Ensure NaN cannot be signaling or negative.

query RRRR
SELECT 'NaN'::decimal, '-NaN'::decimal, 'sNaN'::decimal, '-sNaN'::decimal
----
NaN NaN NaN NaN

query RR
SELECT * FROM t2 WHERE d IS NaN and v IS NaN
----
NaN NaN

query RR
SELECT * FROM t2 WHERE d = 'Infinity' and v = 'Infinity'
----
Infinity Infinity

query RR
SELECT * FROM t2 WHERE d = '-Infinity' and v = '-Infinity'
----
-Infinity -Infinity

# Ensure special values are handled correctly.

statement ok
CREATE TABLE s (d decimal null, index (d))

statement ok
INSERT INTO s VALUES
  (null),
  ('NaN'::decimal),
  ('-NaN'::decimal),
  ('Inf'::decimal),
  ('-Inf'::decimal),
  ('0'::decimal),
  (1),
  (-1)

statement ok
INSERT INTO s VALUES
  ('-0'::decimal),
  ('-0.0'::decimal),
  ('-0.00'::decimal),
  ('-0.00E-1'::decimal),
  ('-0.0E-3'::decimal)

query R rowsort
SELECT * FROM s WHERE d = 0
----
0
0
0.0
0.00
0.000
0.0000

query R rowsort
SELECT * FROM s WHERE d IS NAN
----
NaN
NaN

query R
SELECT * FROM s WHERE d = 'inf'::decimal
----
Infinity

query R rowsort
SELECT * FROM s WHERE d = 'NaN'
----
NaN
NaN

# In the following tests, the various zero values all compare equal to
# each other so we must use two ORDER BY clauses to obtain a stable result.

# Check the ordering of decimal values.
query R
SELECT d FROM s ORDER BY d, d::TEXT
----
NULL
NaN
NaN
-Infinity
-1
0
0
0.0
0.00
0.000
0.0000
1
Infinity

# Just test the NaN-ness of the values.
query RBBB
SELECT d, d IS NaN, d = 'NaN', isnan(d) FROM s@{FORCE_INDEX=s_pkey} ORDER BY d, d::TEXT
----
NULL       NULL   NULL   NULL
NaN        true   true   true
NaN        true   true   true
-Infinity  false  false  false
-1         false  false  false
0          false  false  false
0          false  false  false
0.0        false  false  false
0.00       false  false  false
0.000      false  false  false
0.0000     false  false  false
1          false  false  false
Infinity   false  false  false

# Just test the NaN-ness of the values in secondary index
query RBBB
SELECT d, d IS NaN, d = 'NaN', isnan(d) FROM s@{FORCE_INDEX=s_d_idx} ORDER BY d, d::TEXT
----
NULL       NULL   NULL   NULL
NaN        true   true   true
NaN        true   true   true
-Infinity  false  false  false
-1         false  false  false
0          false  false  false
0          false  false  false
0.0        false  false  false
0.00       false  false  false
0.000      false  false  false
0.0000     false  false  false
1          false  false  false
Infinity   false  false  false

query RB
select d, d > 'NaN' from s@{FORCE_INDEX=s_pkey} where d > 'NaN' ORDER BY d, d::TEXT
----
-Infinity  true
-1         true
0          true
0          true
0.0        true
0.00       true
0.000      true
0.0000     true
1          true
Infinity   true

query RB
select d, d > 'NaN' from s@{FORCE_INDEX=s_d_idx} where d > 'NaN' ORDER BY d, d::TEXT
----
-Infinity  true
-1         true
0          true
0          true
0.0        true
0.00       true
0.000      true
0.0000     true
1          true
Infinity   true

# Verify that decimals don't lose trailing 0s even when used for an index.
statement ok
CREATE INDEX idx ON s (d)

query R rowsort
SELECT * FROM s@idx WHERE d = 0
----
0
0
0.0
0.00
0.000
0.0000

statement ok
INSERT INTO s VALUES
  ('10'::decimal),
  ('10.0'::decimal),
  ('10.00'::decimal),
  ('10.000'::decimal),
  ('100000E-4'::decimal),
  ('1000000E-5'::decimal),
  ('1.0000000E+1'::decimal)

query R rowsort
SELECT * FROM s@s_pkey WHERE d = 10
----
10
10.0
10.00
10.000
10.0000
10.00000
10.000000

query R rowsort
SELECT * FROM s@idx WHERE d = 10
----
10
10.0
10.00
10.000
10.0000
10.00000
10.000000

query R
SELECT 1.00::decimal(6,4)
----
1.0000

statement error value with precision 6, scale 4 must round to an absolute value less than 10\^2
SELECT 101.00::decimal(6,4)

statement error scale \(6\) must be between 0 and precision \(4\)
SELECT 101.00::decimal(4,6)

statement error value with precision 2, scale 2 must round to an absolute value less than 1
SELECT 1::decimal(2, 2)

# Regression test for #16081

statement
CREATE TABLE a (b DECIMAL)

statement
INSERT INTO a VALUES (142378208485490985369999605144727062141206925976498256305323716858805588894693616552055968571135475510700810219028167653516982373238641332965927953273383572708760984694356069974208844865675206339235758647159337463780100273189720943242182911961627806424621091859596571173867825568394327041453823674373002756096)

query R
SELECT * FROM a
----
142378208485490985369999605144727062141206925976498256305323716858805588894693616552055968571135475510700810219028167653516982373238641332965927953273383572708760984694356069974208844865675206339235758647159337463780100273189720943242182911961627806424621091859596571173867825568394327041453823674373002756096

# Verify that NaNs are returned instead of invalid operation.
query R
SELECT 'inf'::decimal + '-inf'::decimal
----
NaN

# Regression test for #40327
query R
SELECT 1.0 / 'Infinity' + 2 FROM a;
----
2

query R
SELECT 2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

# Test with infinity. Many of these tests come from
# https://github.com/postgres/postgres/commit/a57d312a7706321d850faa048a562a0c0c01b835

query RR
SELECT var_pop('inf'::numeric), var_samp('inf'::numeric)
----
NaN  NULL

query RR
SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric)
----
NaN  NULL

query RRR
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('1'), ('infinity')) v(x)
----
Infinity  Infinity  NaN

query RRR
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('infinity'), ('1')) v(x)
----
Infinity  Infinity  NaN

query RRR
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('infinity'), ('infinity')) v(x)
----
Infinity  Infinity  NaN

query RRR
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('-infinity'), ('infinity')) v(x)
----
NaN  NaN  NaN

query RRR
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('-infinity'), ('-infinity')) v(x)
----
-Infinity  -Infinity  NaN

query RRRRR rowsort
WITH v(x) AS
  (VALUES('0'::numeric),('1'::numeric),('-1'::numeric),('4.2'::numeric),('inf'::numeric),('-inf'::numeric),('nan'::numeric))
SELECT x1, x2,
  x1 + x2 AS sum,
  x1 - x2 AS diff,
  x1 * x2 AS prod
FROM v AS v1(x1), v AS v2(x2)
----
0          0          0          0          0
0          1          1          -1         0
0          -1         -1         1          -0
0          4.2        4.2        -4.2       0.0
0          Infinity   Infinity   -Infinity  NaN
0          -Infinity  -Infinity  Infinity   NaN
0          NaN        NaN        NaN        NaN
1          0          1          1          0
1          1          2          0          1
1          -1         0          2          -1
1          4.2        5.2        -3.2       4.2
1          Infinity   Infinity   -Infinity  Infinity
1          -Infinity  -Infinity  Infinity   -Infinity
1          NaN        NaN        NaN        NaN
-1         0          -1         -1         -0
-1         1          0          -2         -1
-1         -1         -2         0          1
-1         4.2        3.2        -5.2       -4.2
-1         Infinity   Infinity   -Infinity  -Infinity
-1         -Infinity  -Infinity  Infinity   Infinity
-1         NaN        NaN        NaN        NaN
4.2        0          4.2        4.2        0.0
4.2        1          5.2        3.2        4.2
4.2        -1         3.2        5.2        -4.2
4.2        4.2        8.4        0.0        17.64
4.2        Infinity   Infinity   -Infinity  Infinity
4.2        -Infinity  -Infinity  Infinity   -Infinity
4.2        NaN        NaN        NaN        NaN
Infinity   0          Infinity   Infinity   NaN
Infinity   1          Infinity   Infinity   Infinity
Infinity   -1         Infinity   Infinity   -Infinity
Infinity   4.2        Infinity   Infinity   Infinity
Infinity   Infinity   Infinity   NaN        Infinity
Infinity   -Infinity  NaN        Infinity   -Infinity
Infinity   NaN        NaN        NaN        NaN
-Infinity  0          -Infinity  -Infinity  NaN
-Infinity  1          -Infinity  -Infinity  -Infinity
-Infinity  -1         -Infinity  -Infinity  Infinity
-Infinity  4.2        -Infinity  -Infinity  -Infinity
-Infinity  Infinity   NaN        -Infinity  -Infinity
-Infinity  -Infinity  -Infinity  NaN        Infinity
-Infinity  NaN        NaN        NaN        NaN
NaN        0          NaN        NaN        NaN
NaN        1          NaN        NaN        NaN
NaN        -1         NaN        NaN        NaN
NaN        4.2        NaN        NaN        NaN
NaN        Infinity   NaN        NaN        NaN
NaN        -Infinity  NaN        NaN        NaN
NaN        NaN        NaN        NaN        NaN

# TODO(#115679): There are a few differences vs postgres in the number of
# decimal places and negative zeros.
query RRRRR
WITH v(id, x) AS (VALUES (1, '0'::numeric), (2, '1'::numeric), (3, '-1'::numeric),
  (4, '4.2'::numeric), (5, 'inf'::numeric), (6, '-inf'::numeric), (7, 'nan'::numeric)
)
SELECT x1, x2,
  x1 / x2 AS quot,
  x1 % x2 AS mod,
  div(x1, x2) AS div
FROM v AS v1(id1, x1), v AS v2(id2, x2) WHERE x2 != 0
ORDER BY id1, id2
----
0          1          0                        0     0
0          -1         -0                       0     -0
0          4.2        0E+1                     0.0   0
0          Infinity   0                        0     0
0          -Infinity  0                        0     -0
0          NaN        NaN                      NaN   NaN
1          1          1.0000000000000000000    0     1
1          -1         -1.0000000000000000000   0     -1
1          4.2        0.23809523809523809524   1.0   0
1          Infinity   0                        1     0
1          -Infinity  0                        1     -0
1          NaN        NaN                      NaN   NaN
-1         1          -1.0000000000000000000   -0    -1
-1         -1         1.0000000000000000000    -0    1
-1         4.2        -0.23809523809523809524  -1.0  -0
-1         Infinity   0                        -1    -0
-1         -Infinity  0                        -1    0
-1         NaN        NaN                      NaN   NaN
4.2        1          4.2000000000000000000    0.2   4
4.2        -1         -4.2000000000000000000   0.2   -4
4.2        4.2        1.0000000000000000000    0.0   1
4.2        Infinity   0                        4.2   0
4.2        -Infinity  0                        4.2   -0
4.2        NaN        NaN                      NaN   NaN
Infinity   1          Infinity                 NaN   Infinity
Infinity   -1         -Infinity                NaN   -Infinity
Infinity   4.2        Infinity                 NaN   Infinity
Infinity   Infinity   NaN                      NaN   NaN
Infinity   -Infinity  NaN                      NaN   NaN
Infinity   NaN        NaN                      NaN   NaN
-Infinity  1          -Infinity                NaN   -Infinity
-Infinity  -1         Infinity                 NaN   Infinity
-Infinity  4.2        -Infinity                NaN   -Infinity
-Infinity  Infinity   NaN                      NaN   NaN
-Infinity  -Infinity  NaN                      NaN   NaN
-Infinity  NaN        NaN                      NaN   NaN
NaN        1          NaN                      NaN   NaN
NaN        -1         NaN                      NaN   NaN
NaN        4.2        NaN                      NaN   NaN
NaN        Infinity   NaN                      NaN   NaN
NaN        -Infinity  NaN                      NaN   NaN
NaN        NaN        NaN                      NaN   NaN

statement error division by zero
SELECT 'inf'::numeric / '0'

statement error division by zero
SELECT '-inf'::numeric / '0'

# Don't throw a division-by-zero error when the numerator is NaN.
query R
SELECT 'NaN'::DECIMAL / 0::DECIMAL;
----
NaN

query R
SELECT 'Infinity'::float8::numeric
----
Infinity

query R
SELECT '-Infinity'::float8::numeric
----
-Infinity

query F
SELECT 'NaN'::numeric::float8
----
NaN

query F
SELECT 'Infinity'::numeric::float8
----
Infinity

query F
SELECT '-Infinity'::numeric::float8
----
-Infinity

statement error integer out of range
SELECT 'NaN'::numeric::int2

statement error integer out of range
SELECT '-Infinity'::numeric::int8

statement error operand, lower bound, and upper bound cannot be infinity
SELECT width_bucket('inf', 3.0, 4.0, 888)

statement error operand, lower bound, and upper bound cannot be infinity
SELECT width_bucket(2.0, 3.0, '-inf', 888)

statement error operand, lower bound, and upper bound cannot be infinity
SELECT width_bucket(0, '-inf', 4.0, 888)

query RRR
select exp('nan'::numeric), exp('inf'::numeric), exp('-inf'::numeric)
----
NaN  Infinity  0

query R rowsort
WITH v(x) AS
(VALUES (' inf '), (' +inf '), (' -inf '), (' Infinity '), (' +inFinity '), (' -INFINITY '))
SELECT x1::decimal
FROM v AS v1(x1)
----
Infinity
Infinity
-Infinity
Infinity
Infinity
-Infinity

statement ok
CREATE TABLE t71926(no_typmod decimal, precision decimal(5), precision_and_width decimal(5,3))

query TI rowsort
SELECT attname, atttypmod FROM pg_attribute WHERE attrelid = 't71926'::regclass::oid AND atttypid = 'decimal'::regtype::oid
----
no_typmod            -1
precision            327684
precision_and_width  327687

# Regression test for #86790
statement ok
CREATE TABLE t86790 (x INT8 NOT NULL)

statement ok
INSERT INTO t86790 VALUES (-4429772553778622992)

query R
SELECT (x / 1)::DECIMAL FROM t86790
----
-4429772553778622992

statement ok
SET testing_optimizer_disable_rule_probability = 1

# The results should be the same as the previous SELECT.
query R
SELECT (x / 1)::DECIMAL FROM t86790
----
-4429772553778622992

statement ok
RESET testing_optimizer_disable_rule_probability

# Regression test for #103633 and #40929 - short-circuit return 0 on division by
# infinity. The results should only have one digit each.
statement ok
CREATE TABLE regression_40929 AS SELECT g FROM (VALUES (1)) AS v(g);

query IRRRR
SELECT
g,
0 / '-Infinity'::DECIMAL,
0 / 'Infinity'::DECIMAL,
1 / '-Infinity'::DECIMAL,
1 / 'Infinity'::DECIMAL
FROM regression_40929
----
1  0  0  0  0

query R
SELECT 0::DECIMAL / 'infinity'::DECIMAL;
----
0
