aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/docs/ru/syntax/action.md
blob: 1a309132790d4f929665d2e830e86064fb2fbdfb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# ACTION

## DEFINE ACTION {#define-action}

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

#### Синтаксис

1. `DEFINE ACTION` — объявление действия.
1. [Имя действия](expressions.md#named-nodes), по которому объявляемое действие доступно далее для вызова.
1. В круглых скобках — список имен параметров.
1. Ключевое слово `AS`.
1. Список выражений верхнего уровня.
1. `END DEFINE` — маркер последнего выражения внутри действия.

Один или более последних параметров могут быть помечены знаком вопроса `?` как необязательные. Если они не будут указаны при вызове, то им будет присвоено значение `NULL`.

## DO {#do}

Выполняет `ACTION` с указанными параметрами.

#### Синтаксис

1. `DO` — выполнение действия.
1. Именованное выражение, по которому объявлено действие.
1. В круглых скобках — список значений для использования в роли параметров.

`EMPTY_ACTION` — действие, которое ничего не выполняет.

{% note info %}

В больших запросах объявление действий можно выносить в отдельные файлы и подключать их в основной запрос с помощью [EXPORT](export_import.md#export) + [IMPORT](export_import.md#import), чтобы вместо одного длинного текста получилось несколько логических частей, в которых проще ориентироваться. Важный нюанс: директива `USE my_cluster;` в импортирующем запросе не влияет на поведение объявленных в других файлах действий.

{% endnote %}

#### Пример

```yql
DEFINE ACTION $hello_world($name, $suffix?) AS
    $name = $name ?? ($suffix ?? "world");
    SELECT "Hello, " || $name || "!";
END DEFINE;

DO EMPTY_ACTION();
DO $hello_world(NULL);
DO $hello_world("John");
DO $hello_world(NULL, "Earth");
```

## BEGIN .. END DO {#begin}

Выполнение действия без его объявления (анонимное действие).

#### Синтаксис

1. `BEGIN`;
1. Список выражений верхнего уровня;
1. `END DO`.

Анонимное действие не может содержать параметров.

#### Пример

```yql
DO BEGIN
    SELECT 1;
    SELECT 2  -- здесь и в предыдущем примере ';' перед END можно не ставить
END DO
```

## EVALUATE IF {#evaluate-if}

`EVALUATE IF` — выполнение действия (action) в зависимости от выполнения условия. Далее указывается:

1. Условие;
2. [DO](#do) с именем и параметрами действия или анонимным действием;
3. Опционально `ELSE` и следом второе `DO` для ситуации, когда условие не выполнено.

## EVALUATE FOR {#evaluate-for}

`EVALUATE FOR` — выполнение действия (action) для каждого элемента в списке. Далее указывается:

1. [Именованное выражение](expressions.md#named-nodes), в которое будет подставляться каждый очередной элемент списка;
2. Ключевое слово `IN`;
3. Объявленное выше именованное выражение со списком, по которому будет выполняться действие.
4. [DO](#do) с именем и параметрами действия или анонимным действием, в параметрах можно использовать как текущий элемент из первого пункта, так и любые объявленные выше именованные выражения, в том числе сам список.
5. Опционально `ELSE` и следом второе `DO` для ситуации, когда список пуст.

#### Примеры

```yql
DEFINE ACTION $hello() AS
    SELECT "Hello!";
END DEFINE;

DEFINE ACTION $bye() AS
    SELECT "Bye!";
END DEFINE;

EVALUATE IF RANDOM(0) > 0.5
    DO $hello()
ELSE
    DO $bye();

EVALUATE IF RANDOM(0) > 0.1 DO BEGIN
    SELECT "Hello!";
END DO;

EVALUATE FOR $i IN AsList(1, 2, 3) DO BEGIN
    SELECT $i;
END DO;
```

```yql
-- скопировать таблицу $input в $count новых таблиц
$count = 3;
$input = "my_input";
$inputs = ListReplicate($input, $count);
$outputs = ListMap(
    ListFromRange(0, $count),
    ($i) -> {
        RETURN "tmp/out_" || CAST($i as String)
    }
);
$pairs = ListZip($inputs, $outputs);

DEFINE ACTION $copy_table($pair) as
    $input = $pair.0;
    $output = $pair.1;
    INSERT INTO $output WITH TRUNCATE
    SELECT * FROM $input;
END DEFINE;

EVALUATE FOR $pair IN $pairs
    DO $copy_table($pair)
ELSE
    DO EMPTY_ACTION(); -- такой ELSE можно было не указывать,
                       -- ничего не делать подразумевается по умолчанию
```

{% note info %}

Стоит учитывать, что `EVALUATE` выполняется до начала работы основного запроса.

{% endnote %}