I am using the queries to check how chr(0) behaves in regexp_like.
CREATE TABLE t1(a char(10));
INSERT INTO t1 VALUES('0123456789');
SELECT CASE WHEN REGEXP_LIKE(a,CHR(0)) THEN 1 ELSE 0 END col, DUMP(a)
FROM t1;
The output I am getting like this -
col dump(a)
----------- -----------------------------------
1 Typ=96 Len=10: 48,49,50,51,52,53,54,55,56,57
I am totally confused, if there is no chr(0) as shown by the dump(a), how regexp_like is finding the chr(0) in the column and returning 1? Shouldn't it return 0 here?
Not an answer, just some experiments, but too long for a comment.
REGEXP_COUNT
seems to be confused bychr(0)
, counting every character aschr(0)
; besides, it seems to find one occurrence more than the size of the string.LIKE
seems to have a good behaviour, while its REGEXP version seems to fail:Same thing for
INSTR
andREGEXP_INSTR
Tested on 11g XE Release 11.2.0.2.0 - 64bit
Aleksej kind of beat me to it, but CHR(0) is the value for the string terminator (kind of like the NULL keyword but not exactly). Think of it like an internal end-of-string indicator that CHR(0) apparently can see. Note that if you try the query with the keyword
NULL
, it will return zero, as nothing can be compared to NULL and the comparison thus will fail (as you were expecting). Interesting. Perhaps someone more experienced with the internal workings can explain further, I would be interested to hear more.CHR(0)
is the character used to terminate a string in the C programming language (among others).When you pass
CHR(0)
to the function it will, in turn, pass it to lower level function that will parse the strings you have passed in and build a regular expression pattern from that string. This regular expression pattern will seeCHR(0)
and think it is the string terminator and ignore the rest of the pattern.The behaviour is easier to see with
REGEXP_REPLACE
:What happens when you run this:
CHR(0)
is compiled into a regular expression and become a string terminator.a
and finds a zero-length string can be matched before thea
so it replaces the nothing it has matched before thea
with and
giving the outputda
.b
todb
.d
.And you will get get the output:
(where _ is the
CHR(0)
character.)Note: the
CHR(0)
in the input is not replaced.If the client program you are using is also truncating the string at
CHR(0)
you may not see the entire output (this is an issue with how your client is representing the string and not with Oracle's output) but it can also be shown usingDUMP()
:Outputs:
[TL;DR] So what is happening with
It will make a zero-length string regular expression pattern and it will look for a zero-length match before the
1
character - which it will find and then return that it has found a match.