В Google bigquery я пытаюсь обновить повторяющееся поле.
Для сравнения, это работает (или, по крайней мере, помечено как действительное), но, конечно, на самом деле не обновляет поле.
UPDATE my.table t
SET my_field = ARRAY(
SELECT AS STRUCT g.foo, g.bar, g.struct_to_set_null
FROM unnest(t.groups) as g
), ... FROM ... etc
Установка struct_to_set_null в ноль дает ошибку:
UPDATE my.table t
SET my_field = ARRAY(
SELECT AS STRUCT g.foo, g.bar, null as struct_to_set_null
FROM unnest(t.groups) as g
), ... FROM ... etc
Value of type ARRAY<STRUCT<... (really long and cut off) cannot be assigned to groups, which has type <ARRAY,STRUCT<... (same, really long, cut off)
Я вижу, что рассматриваемое поле относится к типу RECORD и NULLABLE, поэтому я думаю, что установка его на null разрешена. Есть ли способ заставить это работать?





Repeated - это тип массива, поэтому для него нельзя установить значение NULL.
В настоящее время BigQuery имеет два следующих ограничения в отношении NULL и ARRAYs:
ARRAYs, содержащий элементы NULL, хотя такой ARRAYs можно использовать внутри запроса.NULL ARRAY в пустой ARRAY в результате запроса, хотя внутри запроса NULL и пустой ARRAYs представляют собой два разных значения.Проблема в том, что BigQuery не выводит тип поля структуры только из литерала NULL; вам нужно быть более откровенным. Вот пример:
CREATE TABLE tmp_elliottb.UpdateTable (
my_field ARRAY<STRUCT<foo INT64, bar INT64, struct_to_set_null STRUCT<x STRING, y BOOL, z INT64>>>
);
UPDATE tmp_elliottb.UpdateTable
SET my_field = ARRAY(
SELECT AS STRUCT foo, bar, NULL AS struct_to_set_null FROM UNNEST(my_field)
)
WHERE true;
Это дает мне:
Value of type ARRAY<STRUCT<foo INT64, bar INT64, struct_to_set_null INT64>> cannot be assigned to my_field, which has type ARRAY<STRUCT<foo INT64, bar INT64, struct_to_set_null STRUCT<x STRING, y BOOL, z INT64>>> at [4:16]
Вместо этого я могу использовать выражение IF, которое производит NULL, но имеет struct_to_set_null в одной из ветвей, чтобы принудительно задать нужный мне тип вывода:
UPDATE tmp_elliottb.UpdateTable
SET my_field = ARRAY(
SELECT AS STRUCT
foo, bar,
IF(false, struct_to_set_null, NULL) AS struct_to_set_null
FROM UNNEST(my_field)
)
WHERE true;
Или, как вариант, я могу использовать SELECT * REPLACE:
UPDATE tmp_elliottb.UpdateTable
SET my_field = ARRAY(
SELECT AS STRUCT * REPLACE (IF(false, struct_to_set_null, NULL) AS struct_to_set_null )
FROM UNNEST(my_field)
)
WHERE true;
Обожаю этот трюк с
IF(false, , )! Я никогда не перестаю учиться у тебя - Спасибо, Эллиотт!