aboutsummaryrefslogtreecommitdiff
path: root/src/global.c
diff options
context:
space:
mode:
authordrh <>2021-03-28 23:37:56 +0000
committerdrh <>2021-03-28 23:37:56 +0000
commit1af3fd562fc26c0aaf2bc5c6b3b6097ae17d4abb (patch)
tree8f429c4e4ebec6b8ed5aa44fe0a84f8cd20838c6 /src/global.c
parent9cffb0ffb9b393e1231496d88a3d488e0f877183 (diff)
downloadsqlite-1af3fd562fc26c0aaf2bc5c6b3b6097ae17d4abb.tar.gz
sqlite-1af3fd562fc26c0aaf2bc5c6b3b6097ae17d4abb.zip
Alternative implementation of the comparison opcode speed-up of
check-in [4a8805d9a66dc888] that should pass muster with UBSAN. FossilOrigin-Name: afb18f64541effaeaada2d72c7c91adfe5ec3e2b1418c0bc281083125fb5badb
Diffstat (limited to 'src/global.c')
-rw-r--r--src/global.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/global.c b/src/global.c
index b5239ad81..10c368f72 100644
--- a/src/global.c
+++ b/src/global.c
@@ -37,7 +37,7 @@ const unsigned char sqlite3UpperToLower[] = {
198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
- 252,253,254,255
+ 252,253,254,255,
#endif
#ifdef SQLITE_EBCDIC
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */
@@ -57,7 +57,35 @@ const unsigned char sqlite3UpperToLower[] = {
224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
#endif
+/* All of the upper-to-lower conversion data is above. The following
+** 18 integers are completely unrelated. They are appended to the
+** sqlite3UpperToLower[] array to avoid UBSAN warnings. Here's what is
+** going on:
+**
+** The SQL comparison operators (<>, =, >, <=, <, and >=) are implemented
+** by invoking sqlite3MemCompare(A,B) which compares values A and B and
+** returns negative, zero, or positive if A is less then, equal to, or
+** greater than B, respectively. Then the true false results is found by
+** consulting sqlite3aLTb[opcode], sqlite3aEQb[opcode], or
+** sqlite3aGTb[opcode] depending on whether the result of compare(A,B)
+** is negative, zero, or positive, where opcode is the specific opcode.
+** The only works because the comparison opcodes are consecutive and in
+** this order: NE EQ GT LE LT GE. Various assert()s throughout the code
+** ensure that is the case.
+**
+** These elements must be appended to another array. Otherwise the
+** index (here shown as [256-OP_Ne]) would be out-of-bounds and thus
+** be undefined behavior. That's goofy, but the C-standards people thought
+** it was a good idea, so here we are.
+*/
+/* NE EQ GT LE LT GE */
+ 1, 0, 0, 1, 1, 0, /* aLTb[]: Use when compare(A,B) less than zero */
+ 0, 1, 0, 1, 0, 1, /* aEQb[]: Use when compare(A,B) equals zero */
+ 1, 0, 1, 0, 0, 1 /* aGTb[]: Use when compare(A,B) greater than zero*/
};
+const unsigned char *sqlite3aLTb = &sqlite3UpperToLower[256-OP_Ne];
+const unsigned char *sqlite3aEQb = &sqlite3UpperToLower[256+6-OP_Ne];
+const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP_Ne];
/*
** The following 256 byte lookup table is used to support SQLites built-in