"buildSelect" q/kdb 中的函数代码生成错误



本白皮书中提供的"buildSelect"函数在我尝试将其应用于选择语句时会产生错误。

tidy:{ssr/[;(""~~";"~~"");("";"")] $[","=first x;1_x;x]};
strBrk:{y,(";" sv x),z};
//replace k representation with equivalent q keyword
kreplace:{[x] $[`=qval:.q?x;x;"~~",string[qval],"~~"]};
funcK:{$[0=t:type x;.z.s each x;t<100h;x;kreplace x]};
//replace eg ,`FD`ABC`DEF with "enlist`FD`ABC`DEF"
ereplace:{"~~enlist",(.Q.s1 first x),"~~"};
ereptest:{((0=type x) & (1=count x) & (11=type first x)) | ((11=type x)
&(1=count x))};
funcEn:{$[ereptest x;ereplace x;0=type x;.z.s each x;x]};
basic:{tidy .Q.s1 funcK funcEn x};
addbraks:{"(",x,")"};
//where clause needs to be a list of where clauses, so if only one where
clause need to enlist.
stringify:{$[(0=type x) & 1=count x;"enlist ";""],basic x};
//if a dictionary apply to both, keys and values
ab:{$[(0=count x) | -1=type x;.Q.s1 x;99=type x;(addbraks stringify key x
),"!",stringify value x;stringify x]};
inner:{[x]
 idxs:2 3 4 5 6 inter ainds:til count x;
 x:@[x;idxs;'[ab;eval]];
 if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
 //for select statements within select statements
 x[1]:$[-11=type x 1;x 1;[idxs,:1;.z.s x 1]];
 x:@[x;ainds except idxs;string];
 x[0],strBrk[1_x;"[";"]"]
 };
buildSelect:{[x]
inner parse x
};

将 buildSelect 应用于简单的选择语句时收到以下错误消息:

错误:"长度(长度不兼容(同步操作的操作数长度不同或表列长度不同(

问题似乎出在您提供给 buildSelect 函数的 select 语句上。我删除了函数现在运行的反勾号。

q)buildSelect"update idx:til count clock from `clock"
'length
  [3]  /home/lholmes/qsqltofunctional.q:23: inner:
     if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
     x[1]:$[-11=type x 1;x 1;[idxs,:1;.z.s x 1]];
         ^
     x:@[x;ainds except idxs;string];
q))
q)buildSelect"update idx:til count clock from clock"
"![clock;();0b;(enlist`idx)!enlist (til;(count;`clock))]"

这将产生以下内容:

q)t:([]time:10#.z.p)
q)update idx:i from t
time                          idx
---------------------------------
2019.06.19D08:39:15.720370000 0
2019.06.19D08:39:15.720370000 1
2019.06.19D08:39:15.720370000 2
2019.06.19D08:39:15.720370000 3
2019.06.19D08:39:15.720370000 4
2019.06.19D08:39:15.720370000 5
2019.06.19D08:39:15.720370000 6
2019.06.19D08:39:15.720370000 7
2019.06.19D08:39:15.720370000 8
2019.06.19D08:39:15.720370000 9

希望这有帮助,如果您有任何其他问题,请随时提问。

对于您的时钟表,您甚至不需要命令selectBuild。Q 函数parse将完成这项工作。利用虚拟列i简化代码

parse "update idx:i from clock"

修改后的输出:

![`clock; (); 0b; enlist[`idx]!enlist `i]

另外,我建议使用

clock: update idx:i from clock

而不是

update idx:i from `clock

因为构建选择不处理第二个表单。此外,您的代码将使用本地时钟表运行。

它不起作用的原因是 buildSelect 只期望通过解析树中的值在表中传递,即索引 1 处的元素应该是原子符号,而不是登记符号,这是按名称解析更新的情况。

q)parse "update col1:val from tab"
!
`tab
()
0b
(,`col1)!,`val
q)parse "update col1:val from `tab"
!
,`tab
()
0b
(,`col1)!,`val

这会导致以下行出现问题inner

x[1]:$[-11=type x 1;x 1;[idxs,:1;.z.s x 1]];

更强大的构建选择可以通过以下调整进行

inner:{[x]
    idxs:2 3 4 5 6 inter ainds:til count x;
    x:@[x;idxs;'[ab;eval]];
    if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
    //for select statements within select statements
    x[1]:$[-11=type x 1;x 1;$[11h=type x 1;[idxs,:1;"`",string first x 1];[idxs,:1;.z.s x 1]]];
    x:@[x;ainds except idxs;string];
    x[0],strBrk[1_x;"[";"]"]
    };

这将允许以下内容

q)buildSelect "update col1:val from `tab"
"![`tab;();0b;(enlist`col1)!enlist`val]"
q)buildSelect "update col1:val from tab"
"![tab;();0b;(enlist`col1)!enlist`val]"

最新更新