Код функции "buildSelect" в q / kdb генерирует ошибку - PullRequest
0 голосов
/ 19 июня 2019

Функция 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 к простому оператору выбора:

ОШИБКА: 'длина (несовместимые длины (разные длины операндов для синхронизированной операции или длины столбцов таблицы не совпадают)

Ответы [ 3 ]

2 голосов
/ 19 июня 2019

Похоже, проблема связана с оператором select, который вы предоставляете функции buildSelect.Я уберу галочку с обратной функции, которую теперь запускает функция.

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

Надеюсь, это поможет, если у вас есть какие-либо дополнительные вопросы, не стесняйтесь их задавать.

0 голосов
/ 27 июня 2019

Причина, по которой это не работает, состоит в том, что 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]];

Более надежный buildSelect можно выполнить с помощью следующей настройки

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]"
0 голосов
/ 19 июня 2019

Для вашей таблицы часов вам даже не нужна команда 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 не обрабатывает вторую форму.Кроме того, ваш код будет работать с локальной таблицей часов.

...