deccall3-null-v1.patch

text/plain

Filename: deccall3-null-v1.patch
Type: text/plain
Part: 1
Message: ECPG deccall3 functions vs. risnull() inputs

Patch

Format: unified
Series: patch v1
File+
src/interfaces/ecpg/compatlib/informix.c 9 4
src/interfaces/ecpg/test/compat_informix/dec_test.pgc 2 3
src/interfaces/ecpg/test/expected/compat_informix-dec_test.c 2 3
src/interfaces/ecpg/test/expected/compat_informix-dec_test.stdout 116 116
Author:     Noah Misch <noah@leadboat.com>
Commit:     Noah Misch <noah@leadboat.com>

    Fix ECPG decadd(), decdiv(), decmul(), and decsub() for risnull() input.
    
    FIXME not for commit unless Informix testing confirms it
    
    Since commit 757fb0e5a9a61ac8d3a67e334faeea6dc0084b3f, these
    Informix-compat functions return 0 without changing the output
    parameter.  Before that commit, they would rsetnull() the output
    parameter.  Restore the rsetnull() behavior, which is also consistent
    with the SQL arithmetic operators.
    
    Today's behavior might be accidentally working for applications that use
    these functions to calculate x=x+null or x=x*null.  In those
    calculations, the null coincidentally behaves like a 0 for addition and
    like a 1 for multiplication.  Given that possibility and today's
    behavior having stood for 20 years, no back-patch.
    
    Reviewed by FIXME.
    
    Discussion: https://postgr.es/m/FIXME

diff --git a/src/interfaces/ecpg/compatlib/informix.c b/src/interfaces/ecpg/compatlib/informix.c
index 65a0b2e..32f8733 100644
--- a/src/interfaces/ecpg/compatlib/informix.c
+++ b/src/interfaces/ecpg/compatlib/informix.c
@@ -51,6 +51,11 @@ deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
 			   *a2;
 	int			i;
 
+	/*
+	 * risnull() inputs: our only caller is deccmp(), and Informix documents
+	 * deccmp() as returning DECUNKNOWN on null input.
+	 */
+
 	if ((a1 = PGTYPESnumeric_new()) == NULL)
 		return ECPG_INFORMIX_OUT_OF_MEMORY;
 
@@ -90,12 +95,12 @@ deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, n
 			   *nres;
 	int			i;
 
-	/*
-	 * we must NOT set the result to NULL here because it may be the same
-	 * variable as one of the arguments
-	 */
+	/* like a STRICT function in SQL, null arg gives null result */
 	if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
+	{
+		rsetnull(CDECIMALTYPE, (char *) result);
 		return 0;
+	}
 
 	if ((a1 = PGTYPESnumeric_new()) == NULL)
 		return ECPG_INFORMIX_OUT_OF_MEMORY;
diff --git a/src/interfaces/ecpg/test/compat_informix/dec_test.pgc b/src/interfaces/ecpg/test/compat_informix/dec_test.pgc
index 830ab58..20538df 100644
--- a/src/interfaces/ecpg/test/compat_informix/dec_test.pgc
+++ b/src/interfaces/ecpg/test/compat_informix/dec_test.pgc
@@ -143,9 +143,8 @@ main(void)
 			printf("dec[c,%d,%d]: %d\n", i, j, c);
 
 			/*
-			 * decarr[count-1] is risnull(), which makes these functions
-			 * return 0 without changing the output parameter.  Make that
-			 * clear by initializing each output parameter.
+			 * Initialize output parameters, so we get an unambiguous signal
+			 * if any call doesn't change its output parameter.
 			 */
 			deccvint(7654321, &a);
 			deccvint(7654321, &s);
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-dec_test.c b/src/interfaces/ecpg/test/expected/compat_informix-dec_test.c
index 3e68b2e..a9d9d21 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-dec_test.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-dec_test.c
@@ -196,9 +196,8 @@ main(void)
 			printf("dec[c,%d,%d]: %d\n", i, j, c);
 
 			/*
-			 * decarr[count-1] is risnull(), which makes these functions
-			 * return 0 without changing the output parameter.  Make that
-			 * clear by initializing each output parameter.
+			 * Initialize output parameters, so we get an unambiguous signal
+			 * if any call doesn't change its output parameter.
 			 */
 			deccvint(7654321, &a);
 			deccvint(7654321, &s);
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-dec_test.stdout b/src/interfaces/ecpg/test/expected/compat_informix-dec_test.stdout
index 7e50493..9d38629 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-dec_test.stdout
+++ b/src/interfaces/ecpg/test/expected/compat_informix-dec_test.stdout
@@ -222,10 +222,10 @@ dec[s,0,13]:
 dec[m,0,13]: *
 dec[d,0,13]: 
 dec[c,0,14]: 2147483647
-dec[a,0,14]: 7654321.0
-dec[s,0,14]: 7654321.0
-dec[m,0,14]: 7654321.0
-dec[d,0,14]: 7654321.0
+dec[a,0,14]: 
+dec[s,0,14]: 
+dec[m,0,14]: 
+dec[d,0,14]: 
 dec[c,1,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,1,0]: 
@@ -297,10 +297,10 @@ dec[s,1,13]: -1234567890123456789012345680.91
 dec[m,1,13]: -2469135780246913578024691357.82
 dec[d,1,13]: -0.0000000000000000000000000016200000145800001
 dec[c,1,14]: 2147483647
-dec[a,1,14]: 7654321.0
-dec[s,1,14]: 7654321.0
-dec[m,1,14]: 7654321.0
-dec[d,1,14]: 7654321.0
+dec[a,1,14]: 
+dec[s,1,14]: 
+dec[m,1,14]: 
+dec[d,1,14]: 
 dec[c,2,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,2,0]: 
@@ -372,10 +372,10 @@ dec[s,2,13]:
 dec[m,2,13]: 
 dec[d,2,13]: 0.00000000000000000000000000064314000578826005
 dec[c,2,14]: 2147483647
-dec[a,2,14]: 7654321.0
-dec[s,2,14]: 7654321.0
-dec[m,2,14]: 7654321.0
-dec[d,2,14]: 7654321.0
+dec[a,2,14]: 
+dec[s,2,14]: 
+dec[m,2,14]: 
+dec[d,2,14]: 
 dec[c,3,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,3,0]: 
@@ -447,10 +447,10 @@ dec[s,3,13]: -1234567890123456789012345675.47
 dec[m,3,13]: 
 dec[d,3,13]: 0.0000000000000000000000000027864000250776002
 dec[c,3,14]: 2147483647
-dec[a,3,14]: 7654321.0
-dec[s,3,14]: 7654321.0
-dec[m,3,14]: 7654321.0
-dec[d,3,14]: 7654321.0
+dec[a,3,14]: 
+dec[s,3,14]: 
+dec[m,3,14]: 
+dec[d,3,14]: 
 dec[c,4,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,4,0]: 
@@ -522,10 +522,10 @@ dec[s,4,13]: -1233975400123456789012345678.91
 dec[m,4,13]: 
 dec[d,4,13]: 0.00047991690431925214
 dec[c,4,14]: 2147483647
-dec[a,4,14]: 7654321.0
-dec[s,4,14]: 7654321.0
-dec[m,4,14]: 7654321.0
-dec[d,4,14]: 7654321.0
+dec[a,4,14]: 
+dec[s,4,14]: 
+dec[m,4,14]: 
+dec[d,4,14]: 
 dec[c,5,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,5,0]: 
@@ -597,10 +597,10 @@ dec[s,5,13]: -1234567890123456789012674078.91
 dec[m,5,13]: 
 dec[d,5,13]: -0.00000000000000000000026600400239403602
 dec[c,5,14]: 2147483647
-dec[a,5,14]: 7654321.0
-dec[s,5,14]: 7654321.0
-dec[m,5,14]: 7654321.0
-dec[d,5,14]: 7654321.0
+dec[a,5,14]: 
+dec[s,5,14]: 
+dec[m,5,14]: 
+dec[d,5,14]: 
 dec[c,6,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,6,0]: 
@@ -672,10 +672,10 @@ dec[s,6,13]:
 dec[m,6,13]: *
 dec[d,6,13]: *
 dec[c,6,14]: 2147483647
-dec[a,6,14]: 7654321.0
-dec[s,6,14]: 7654321.0
-dec[m,6,14]: 7654321.0
-dec[d,6,14]: 7654321.0
+dec[a,6,14]: 
+dec[s,6,14]: 
+dec[m,6,14]: 
+dec[d,6,14]: 
 dec[c,7,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,7,0]: 
@@ -747,10 +747,10 @@ dec[s,7,13]:
 dec[m,7,13]: 1234567890123456789012345.67891
 dec[d,7,13]: 0.00000000000000000000000000000081000000729000007
 dec[c,7,14]: 2147483647
-dec[a,7,14]: 7654321.0
-dec[s,7,14]: 7654321.0
-dec[m,7,14]: 7654321.0
-dec[d,7,14]: 7654321.0
+dec[a,7,14]: 
+dec[s,7,14]: 
+dec[m,7,14]: 
+dec[d,7,14]: 
 dec[c,8,0]: -1
 dec[a,8,0]: *
 dec[s,8,0]: *
@@ -822,10 +822,10 @@ dec[s,8,13]: -1234567890123456789012345678.91
 dec[m,8,13]: 0.000
 dec[d,8,13]: 0
 dec[c,8,14]: 2147483647
-dec[a,8,14]: 7654321.0
-dec[s,8,14]: 7654321.0
-dec[m,8,14]: 7654321.0
-dec[d,8,14]: 7654321.0
+dec[a,8,14]: 
+dec[s,8,14]: 
+dec[m,8,14]: 
+dec[d,8,14]: 
 dec[c,9,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,9,0]: 
@@ -897,10 +897,10 @@ dec[s,9,13]:
 dec[m,9,13]: 
 dec[d,9,13]: -0.000000000000000000000000000000047991690431925214
 dec[c,9,14]: 2147483647
-dec[a,9,14]: 7654321.0
-dec[s,9,14]: 7654321.0
-dec[m,9,14]: 7654321.0
-dec[d,9,14]: 7654321.0
+dec[a,9,14]: 
+dec[s,9,14]: 
+dec[m,9,14]: 
+dec[d,9,14]: 
 dec[c,10,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,10,0]: 
@@ -972,10 +972,10 @@ dec[s,10,13]:
 dec[m,10,13]: 
 dec[d,10,13]: 0.0000000000000000000000000000026600400239403602
 dec[c,10,14]: 2147483647
-dec[a,10,14]: 7654321.0
-dec[s,10,14]: 7654321.0
-dec[m,10,14]: 7654321.0
-dec[d,10,14]: 7654321.0
+dec[a,10,14]: 
+dec[s,10,14]: 
+dec[m,10,14]: 
+dec[d,10,14]: 
 dec[c,11,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,11,0]: 
@@ -1047,10 +1047,10 @@ dec[s,11,13]:
 dec[m,11,13]: 
 dec[d,11,13]: 0.00000000000000000000000000040500081364500732
 dec[c,11,14]: 2147483647
-dec[a,11,14]: 7654321.0
-dec[s,11,14]: 7654321.0
-dec[m,11,14]: 7654321.0
-dec[d,11,14]: 7654321.0
+dec[a,11,14]: 
+dec[s,11,14]: 
+dec[m,11,14]: 
+dec[d,11,14]: 
 dec[c,12,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,12,0]: 
@@ -1122,10 +1122,10 @@ dec[s,12,13]:
 dec[m,12,13]: 
 dec[d,12,13]: -0.00000000000000000000000000040500008464500076
 dec[c,12,14]: 2147483647
-dec[a,12,14]: 7654321.0
-dec[s,12,14]: 7654321.0
-dec[m,12,14]: 7654321.0
-dec[d,12,14]: 7654321.0
+dec[a,12,14]: 
+dec[s,12,14]: 
+dec[m,12,14]: 
+dec[d,12,14]: 
 dec[c,13,0]: -1
 (errno == PGTYPES_NUM_OVERFLOW) - r: -1200
 dec[s,13,0]: 
@@ -1197,85 +1197,85 @@ dec[s,13,13]: 0.00
 dec[m,13,13]: 
 dec[d,13,13]: 1.00000000000000000
 dec[c,13,14]: 2147483647
-dec[a,13,14]: 7654321.0
-dec[s,13,14]: 7654321.0
-dec[m,13,14]: 7654321.0
-dec[d,13,14]: 7654321.0
+dec[a,13,14]: 
+dec[s,13,14]: 
+dec[m,13,14]: 
+dec[d,13,14]: 
 dec[c,14,0]: 2147483647
-dec[a,14,0]: 7654321.0
-dec[s,14,0]: 7654321.0
-dec[m,14,0]: 7654321.0
-dec[d,14,0]: 7654321.0
+dec[a,14,0]: 
+dec[s,14,0]: 
+dec[m,14,0]: 
+dec[d,14,0]: 
 dec[c,14,1]: 2147483647
-dec[a,14,1]: 7654321.0
-dec[s,14,1]: 7654321.0
-dec[m,14,1]: 7654321.0
-dec[d,14,1]: 7654321.0
+dec[a,14,1]: 
+dec[s,14,1]: 
+dec[m,14,1]: 
+dec[d,14,1]: 
 dec[c,14,2]: 2147483647
-dec[a,14,2]: 7654321.0
-dec[s,14,2]: 7654321.0
-dec[m,14,2]: 7654321.0
-dec[d,14,2]: 7654321.0
+dec[a,14,2]: 
+dec[s,14,2]: 
+dec[m,14,2]: 
+dec[d,14,2]: 
 dec[c,14,3]: 2147483647
-dec[a,14,3]: 7654321.0
-dec[s,14,3]: 7654321.0
-dec[m,14,3]: 7654321.0
-dec[d,14,3]: 7654321.0
+dec[a,14,3]: 
+dec[s,14,3]: 
+dec[m,14,3]: 
+dec[d,14,3]: 
 dec[c,14,4]: 2147483647
-dec[a,14,4]: 7654321.0
-dec[s,14,4]: 7654321.0
-dec[m,14,4]: 7654321.0
-dec[d,14,4]: 7654321.0
+dec[a,14,4]: 
+dec[s,14,4]: 
+dec[m,14,4]: 
+dec[d,14,4]: 
 dec[c,14,5]: 2147483647
-dec[a,14,5]: 7654321.0
-dec[s,14,5]: 7654321.0
-dec[m,14,5]: 7654321.0
-dec[d,14,5]: 7654321.0
+dec[a,14,5]: 
+dec[s,14,5]: 
+dec[m,14,5]: 
+dec[d,14,5]: 
 dec[c,14,6]: 2147483647
-dec[a,14,6]: 7654321.0
-dec[s,14,6]: 7654321.0
-dec[m,14,6]: 7654321.0
-dec[d,14,6]: 7654321.0
+dec[a,14,6]: 
+dec[s,14,6]: 
+dec[m,14,6]: 
+dec[d,14,6]: 
 dec[c,14,7]: 2147483647
-dec[a,14,7]: 7654321.0
-dec[s,14,7]: 7654321.0
-dec[m,14,7]: 7654321.0
-dec[d,14,7]: 7654321.0
+dec[a,14,7]: 
+dec[s,14,7]: 
+dec[m,14,7]: 
+dec[d,14,7]: 
 dec[c,14,8]: 2147483647
-dec[a,14,8]: 7654321.0
-dec[s,14,8]: 7654321.0
-dec[m,14,8]: 7654321.0
-dec[d,14,8]: 7654321.0
+dec[a,14,8]: 
+dec[s,14,8]: 
+dec[m,14,8]: 
+dec[d,14,8]: 
 dec[c,14,9]: 2147483647
-dec[a,14,9]: 7654321.0
-dec[s,14,9]: 7654321.0
-dec[m,14,9]: 7654321.0
-dec[d,14,9]: 7654321.0
+dec[a,14,9]: 
+dec[s,14,9]: 
+dec[m,14,9]: 
+dec[d,14,9]: 
 dec[c,14,10]: 2147483647
-dec[a,14,10]: 7654321.0
-dec[s,14,10]: 7654321.0
-dec[m,14,10]: 7654321.0
-dec[d,14,10]: 7654321.0
+dec[a,14,10]: 
+dec[s,14,10]: 
+dec[m,14,10]: 
+dec[d,14,10]: 
 dec[c,14,11]: 2147483647
-dec[a,14,11]: 7654321.0
-dec[s,14,11]: 7654321.0
-dec[m,14,11]: 7654321.0
-dec[d,14,11]: 7654321.0
+dec[a,14,11]: 
+dec[s,14,11]: 
+dec[m,14,11]: 
+dec[d,14,11]: 
 dec[c,14,12]: 2147483647
-dec[a,14,12]: 7654321.0
-dec[s,14,12]: 7654321.0
-dec[m,14,12]: 7654321.0
-dec[d,14,12]: 7654321.0
+dec[a,14,12]: 
+dec[s,14,12]: 
+dec[m,14,12]: 
+dec[d,14,12]: 
 dec[c,14,13]: 2147483647
-dec[a,14,13]: 7654321.0
-dec[s,14,13]: 7654321.0
-dec[m,14,13]: 7654321.0
-dec[d,14,13]: 7654321.0
+dec[a,14,13]: 
+dec[s,14,13]: 
+dec[m,14,13]: 
+dec[d,14,13]: 
 dec[c,14,14]: 2147483647
-dec[a,14,14]: 7654321.0
-dec[s,14,14]: 7654321.0
-dec[m,14,14]: 7654321.0
-dec[d,14,14]: 7654321.0
+dec[a,14,14]: 
+dec[s,14,14]: 
+dec[m,14,14]: 
+dec[d,14,14]: 
 0: *
 1: -2
 2: 0.794