Evening
I'm seeing a weird effect when concatenting things:
WITH q(tape,dp) AS (SELECT '04E', 1)
SELECT SUBSTR(tape,1,dp-1) || SUBSTR(tape,dp,1)+1 || SUBSTR(tape,dp+1) AS
expect_14E,
SUBSTR(tape,1,dp-1) AS segment_1,
SUBSTR(tape,dp,1)+1 AS segment_2,
SUBSTR(tape,dp+1) AS segment_3
FROM q;
expect_14E segment_1 segment_2 segment_3
---------- ---------- ---------- ----------
14 1 4E
As the name of the column implies... I'm expecting '14E' from that
concatenation, it instead seems to be dropping the last character.
I originally found this in sqlite3 3.19.3 as distributed in 64-bit ubuntu
17.10; on that same system, I get the same effect in the amalgamation
3.22.0, compiled just now, thus:
sqlite-amalgamation-3220000$ gcc -o sqlite3 sqlite3.c shell.c -ldl -lpthread
For entertainment purposes only, I discovered this while trying to
implement a BF interpreter using CTEs, pasted below.
Have a good evening,
Gary
WITH RECURSIVE
program AS (SELECT '+++.,>++++.,<<++++++.,' AS p, 'HELLO' AS input),
jumpdepth AS (SELECT 0 AS idx, 0 AS jumpdepth, '' AS jumplist, NULL as
jumpback, NULL AS direction, p || '0' AS p FROM program
UNION ALL
SELECT idx+1,
CASE SUBSTR(p, idx+1, 1) WHEN '[' THEN jumpdepth+1 WHEN ']' THEN
jumpdepth-1 ELSE jumpdepth END,
CASE SUBSTR(p, idx+1, 1) WHEN '[' THEN SUBSTR('0000' || (idx+1),
-4) || jumplist WHEN ']' THEN SUBSTR(jumplist,5) ELSE jumplist END,
CASE SUBSTR(p, idx+1, 1) WHEN ']' THEN CAST(SUBSTR(jumplist,1,4)
AS INTEGER) ELSE NULL END,
CASE SUBSTR(p, idx+1, 1) WHEN '[' THEN 'L' WHEN ']' THEN 'R' ELSE
NULL END, p
FROM jumpdepth
WHERE LENGTH(p)>=idx),
jumptable(a,b,dir) AS
(SELECT idx,jumpback,'L' FROM jumpdepth WHERE jumpback IS NOT NULL
UNION ALL
SELECT jumpback,idx+1,'R' FROM jumpdepth WHERE jumpback IS NOT NULL),
bf AS (SELECT p, 1 AS ip, 1 AS dp, '' AS output, input, CAST('0' AS TEXT) AS
tape
FROM program
UNION ALL
SELECT p, CASE WHEN jumptable.b IS NOT NULL AND
((dir='L' AND SUBSTR(tape, dp, 1)=0) OR (dir='R' AND
SUBSTR(tape,dp,1)!=0)) THEN jumptable.b ELSE ip+1 END,
CASE SUBSTR(p, ip, 1) WHEN '>' THEN dp+1 WHEN '<' THEN MAX(dp-1,1) ELSE
dp END,
CASE WHEN SUBSTR(p, ip, 1)='.' THEN (output || SUBSTR(tape, dp, 1))
ELSE output END,
CASE WHEN SUBSTR(p, ip, 1)=',' THEN SUBSTR(input, 2) ELSE input END,
CASE SUBSTR(p, ip, 1)
WHEN '<' THEN CASE WHEN dp=1 THEN '0' || tape ELSE tape END
WHEN '>' THEN CASE WHEN dp=LENGTH(tape) THEN tape || '0' ELSE
tape END
WHEN '+' THEN SUBSTR(tape,1,dp-1) || SUBSTR(tape,dp,1)+1 ||
SUBSTR(tape,dp+1)
WHEN '-' THEN SUBSTR(tape,1,dp-1) || SUBSTR(tape,dp,1)-1 ||
SUBSTR(tape,dp+1)
WHEN ',' THEN SUBSTR(tape,1,dp-1) || SUBSTR(input,1,1) ||
SUBSTR(tape,dp+1)
ELSE tape END
FROM bf LEFT JOIN jumptable ON jumptable.a=ip WHERE LENGTH(p) >= ip)
SELECT ip,dp,input,output,tape FROM bf LIMIT 1000;
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users