原始SQL
sql
WITH RECURSIVE
input(sud) AS (
VALUES('....754..........8.8.19....3....1.6........34....6817.2.4...6.39......2.53.2.....'),
('3.........5.7.3..8....28.7.7......43...........39.41.54..3..8..1...4....968...2..')
),
digits(z, lp) AS (
VALUES('1', 1)
UNION ALL SELECT
CAST(lp+1 AS TEXT) , lp+1 FROM digits WHERE lp<9
),
x(s, ind) AS (
SELECT sud, instr(sud, '.') FROM input
UNION ALL
SELECT
substr(s, 1, ind-1) || z || substr(s, ind+1),
instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )
FROM x, digits AS z
WHERE ind>0
AND NOT EXISTS (
SELECT 1
FROM digits AS lp
WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)
OR z.z = substr(s, ((ind-1)%9) + (lp-1)*9 + 1, 1)
OR z.z = substr(s, (((ind-1)/3) % 3) * 3
+ ((ind-1)/27) * 27 + lp
+ ((lp-1) / 3) * 6, 1)
)
)
SELECT s FROM x WHERE ind=0;
报错:
ValueError: Error during planning: Projections require unique expression names but the expression "CAST(digits.lp + Int64(1) AS Utf8View)" at position 0 and "digits.lp + Int64(1)" at position 1 have the same name. Consider aliasing ("AS") one of them.
将CAST(lp+1 AS TEXT) , lp+1分别加上别名,以上错误消失,又出来如下错误:
Exception: DataFusion error: type_coercion
caused by
Execution error: Cannot access field at argument 1: type Utf8 is not Struct, Map, or Null
python
s="""
WITH RECURSIVE
input(sud) AS (
VALUES('....754..........8.8.19....3....1.6........34....6817.2.4...6.39......2.53.2.....'),
('3.........5.7.3..8....28.7.7......43...........39.41.54..3..8..1...4....968...2..')
),
digits(z, lp) AS (
VALUES('1', 1)
UNION ALL SELECT
CAST(lp+1 AS TEXT) as z, lp+1 as lp FROM digits WHERE lp<9
),
x(s, ind) AS (
SELECT sud, instr(sud, '.') FROM input
UNION ALL
SELECT
substr(s, 1, ind-1) || z || substr(s, ind+1),
instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )
FROM x, digits AS z
WHERE ind>0
AND NOT EXISTS (
SELECT 1
FROM digits AS lp
WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)
OR z.z = substr(s, ((ind-1)%9) + (lp-1)*9 + 1, 1)
OR z.z = substr(s, (((ind-1)/3) % 3) * 3
+ ((ind-1)/27) * 27 + lp
+ ((lp-1) / 3) * 6, 1)
)
)
SELECT s FROM x WHERE ind=0;
"""
from datafusion import SessionContext
ctx = SessionContext()
ctx.sql(s)
这是由于datafusion把z.z中的第一个 z 当作了列名, 而不是表别名, 将表别名取一个不和列名重复的值,就好了
sql
WITH RECURSIVE
input(sud) AS (
VALUES('....754..........8.8.19....3....1.6........34....6817.2.4...6.39......2.53.2.....'),
('3.........5.7.3..8....28.7.7......43...........39.41.54..3..8..1...4....968...2..')
),
digits(z, lp) AS (
VALUES('1', 1)
UNION ALL SELECT
CAST(lp+1 AS TEXT) as z, lp+1 as lp FROM digits WHERE lp<9
),
x(s, ind) AS (
SELECT sud, instr(sud, '.') FROM input
UNION ALL
SELECT
substr(s, 1, ind-1) || z || substr(s, ind+1),
instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )
FROM x, digits AS d
WHERE ind>0
AND NOT EXISTS (
SELECT 1
FROM digits AS lp
WHERE d.z = substr(s, ((ind-1)/9)*9 + lp, 1)
OR d.z = substr(s, ((ind-1)%9) + (lp-1)*9 + 1, 1)
OR d.z = substr(s, (((ind-1)/3) % 3) * 3
+ ((ind-1)/27) * 27 + lp
+ ((lp-1) / 3) * 6, 1)
)
)
SELECT s FROM x WHERE ind=0;
这次能输出正确的结果
+-----------------------------------------------------------------------------------+
| s |
+-----------------------------------------------------------------------------------+
| 387419526259763418641528379716285943594631782823974165472396851135842697968157234 |
| 693875412145632798782194356357421869816957234429368175274519683968743521531286947 |
+-----------------------------------------------------------------------------------+