Skip to content

Commit c87063c

Browse files
committed
Docs update
1 parent 04ab6dd commit c87063c

10 files changed

Lines changed: 189 additions & 37 deletions

File tree

docs/how-to/en/How-to_Custom_React_views.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ The value form selects the renderer: a string literal matching `[A-Z][A-Za-z0-9_
2828

2929
### The component
3030

31-
`OrderBoard` is a named export from a `.jsx` module under `src/main/web`; how the module is compiled and registered is covered in [How-to: Custom client JS modules](How-to_Custom_client_JS_modules.md). The examples here use JSX. For a project [without the build](How-to_Custom_client_JS_modules.md#without-the-build), ship the same component as a `.jsx` file — it is transformed on the server when served; `import` is not available there, so the component works against the platform-provided `window.React` — or write it with `React.createElement` in a plain `.js`. Either file is placed under `src/main/resources/web/init` (auto-loaded) or under `src/main/resources/web` and registered with `onWebClientInit`.
31+
`OrderBoard` is a named export from a `.jsx` module under `src/main/web`; how the module is compiled and registered is covered in [How-to: Custom client JS modules](How-to_Custom_client_JS_modules.md). The examples here use JSX. For a project [without the build](How-to_Custom_client_JS_modules.md#without-the-build), ship the same component as a `.jsx` file — it is transformed on the server when served; `import` and `export` are not available there, so the `export` keyword is dropped and the component works against the platform-provided `window.React` — or write it with `React.createElement` in a plain `.js`. Either file is placed under `src/main/resources/web/init` (auto-loaded) or under `src/main/resources/web` and registered with `onWebClientInit`.
3232

3333
The component is a plain function that receives `props.data` and `props.controller`:
3434

docs/how-to/en/How-to_Custom_view_controller.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Passing a handle (`otherRow.objects`) as an FK value silently sets it to `NULL`,
123123

124124
The format is the same in the read direction: an object property's value arrives in the data row as this same numeric id, so it can be compared with the target row's `row.key` (in a single-object group) or passed back as an FK value without conversion.
125125

126-
If the edited property is marked `APPLY` on the form (the edit is applied at once), `changeProperty` commits the change immediately. For a simple edit from a view — a move, a resize, an in-place value edit — this is preferable to a separate server action; the server action (`exec`) stays for what a property change cannot express: creating an object (`NEW`), multi-step logic, opening a form.
126+
Like a user edit in the standard table, the change is made in the form's [change session](../paradigm/Change_sessions.md): the view sees the new value in `props.data` at once, while it reaches the database when the session is applied — with the Save button or an action with the [`APPLY`](../language/APPLY_operator.md) operator. If the edited property is marked `APPLY` on the form (the edit is applied at once), `changeProperty` commits the change immediately. For a simple edit from a view — a move, a resize, an in-place value edit — this is preferable to a separate server action; the server action (`exec`) stays for what a property change cannot express: creating an object (`NEW`), multi-step logic, opening a form.
127127

128128
```js
129129
// move an object to another parent and edit a primitive in one call:

docs/how-to/ru/How-to_Custom_React_views.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ DESIGN orders {
2828

2929
### Компонент
3030

31-
`OrderBoard` — именованный экспорт из модуля `.jsx` в каталоге `src/main/web`; как этот модуль компилируется и регистрируется, описано в [How-to: Пользовательские клиентские JS-модули](How-to_Custom_client_JS_modules.md). Примеры здесь используют JSX. Для проекта [без сборки](How-to_Custom_client_JS_modules.md#without-the-build) поместите тот же компонент в файл `.jsx` — он преобразуется на сервере при отдаче; `import` там недоступен, поэтому компонент работает с предоставляемым платформой `window.React` — либо напишите его через `React.createElement` в обычном `.js`. Любой из этих файлов кладётся в `src/main/resources/web/init` (автозагрузка) или в `src/main/resources/web` с регистрацией через `onWebClientInit`.
31+
`OrderBoard` — именованный экспорт из модуля `.jsx` в каталоге `src/main/web`; как этот модуль компилируется и регистрируется, описано в [How-to: Пользовательские клиентские JS-модули](How-to_Custom_client_JS_modules.md). Примеры здесь используют JSX. Для проекта [без сборки](How-to_Custom_client_JS_modules.md#without-the-build) поместите тот же компонент в файл `.jsx` — он преобразуется на сервере при отдаче; `import` и `export` там недоступны, поэтому ключевое слово `export` опускается, а компонент работает с предоставляемым платформой `window.React` — либо напишите его через `React.createElement` в обычном `.js`. Любой из этих файлов кладётся в `src/main/resources/web/init` (автозагрузка) или в `src/main/resources/web` с регистрацией через `onWebClientInit`.
3232

3333
Компонент — это обычная функция, получающая `props.data` и `props.controller`:
3434

docs/how-to/ru/How-to_Custom_view_controller.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ controller.changeProperties(['note', 'qty'], [null, row], ['checked', 5]);
123123

124124
В обратную сторону формат тот же: значение объектного свойства приезжает в строку данных этим же числовым id, поэтому его можно сравнить с `row.key` целевой строки (в группе с одним объектом) или передать обратно значением FK без преобразований.
125125

126-
Если редактируемое свойство помечено на форме модификатором `APPLY` (правка применяется сразу), `changeProperty` фиксирует изменение немедленно. Для простой правки из представления — перенос, изменение размера, правка значения по месту — это предпочтительнее отдельного серверного действия; серверное действие (`exec`) остаётся для того, что правкой свойства не выражается: создания объекта (`NEW`), многошаговой логики, открытия формы.
126+
Как и правка пользователя в штатной таблице, изменение выполняется в [сессии изменений](../paradigm/Change_sessions.md) формы: представление сразу видит новое значение в `props.data`, а в базу данных оно попадает при применении сессии — кнопкой «Сохранить» либо действием с оператором [`APPLY`](../language/APPLY_operator.md). Если редактируемое свойство помечено на форме модификатором `APPLY` (правка применяется сразу), `changeProperty` фиксирует изменение немедленно. Для простой правки из представления — перенос, изменение размера, правка значения по месту — это предпочтительнее отдельного серверного действия; серверное действие (`exec`) остаётся для того, что правкой свойства не выражается: создания объекта (`NEW`), многошаговой логики, открытия формы.
127127

128128
```js
129129
// перенос объекта к другому родителю и правка примитива одним вызовом:

docs/paradigm/en/System_Time.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ The signatures below use the built-in time classes `DATE`, `TIME`, `DATETIME` (w
7272
| `subtractSeconds[DATETIME, LONG]` / `subtractSeconds[ZDATETIME, LONG]` | subtract the given number of seconds from a `DATETIME` / `ZDATETIME`, return the same class; PG `$1 - $2 * interval '1 second'` |
7373
| `subtractSeconds[TIME, TIME]` / `subtractSeconds[DATETIME, DATETIME]` / `subtractSeconds[ZDATETIME, ZDATETIME]` | difference of two same-class values in seconds as `INTEGER`, computed as the **second** argument minus the **first** (`subtractSeconds(a, b) = b - a`, positive when `b` is the later value); PG `extract(epoch from (b - a))` |
7474
| `daysBetweenDates[DATE, DATE]` | difference of two dates in days as `INTEGER`, computed as the **first** argument minus the **second** (`daysBetweenDates(a, b) = a - b`, positive when `a` is the later date); PG `$1 - $2`. Note the operand order is the opposite of `subtractSeconds` |
75-
| `daysInclBetweenDates[DATE, DATE]` | inclusive day count between two dates, counting both ends: the **second** argument minus the **first**, plus 1 (`daysInclBetweenDates(a, b) = b - a + 1`) — the opposite operand order from `daysBetweenDates[DATE, DATE]`, since it calls it with the arguments swapped |
75+
| `daysBetweenDatesIncl[DATE, DATE]` | inclusive day count between two dates, counting both ends: the **first** argument minus the **second**, plus 1 (`daysBetweenDatesIncl(a, b) = a - b + 1`) — the same operand order as `daysBetweenDates[DATE, DATE]` |
7676
| `secondsBetweenDates[DATETIME, DATETIME]` | difference of two moments in seconds as `INTEGER`, computed as the **first** argument minus the **second** (`secondsBetweenDates(a, b) = a - b`, positive when `a` is the later moment); PG `extract(epoch from $1) - extract(epoch from $2)` |
7777
| `dateTimeToDateTime[DATE, TIME]` | combines a `DATE` and a `TIME` into a `DATETIME` through a text round-trip; PG `to_timestamp(<date> \|\| <time>, 'YYYY-MM-DDHH24:MI:SS.MS')::timestamp` |
7878
| `dateFromYearWeekDay[INTEGER, INTEGER, INTEGER]` | builds a `DATE` from year, ISO-8601 week number, and ISO day of week (1 = Monday … 7 = Sunday); PG `to_date($1 \|\| ' ' \|\| $2 \|\| ' ' \|\| $3, 'IYYY IW ID')` |

docs/paradigm/ru/System_Time.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ title: 'Time'
7272
| `subtractSeconds[DATETIME, LONG]` / `subtractSeconds[ZDATETIME, LONG]` | вычитают указанное число секунд из `DATETIME` / `ZDATETIME`, возвращают тот же класс; PG `$1 - $2 * interval '1 second'` |
7373
| `subtractSeconds[TIME, TIME]` / `subtractSeconds[DATETIME, DATETIME]` / `subtractSeconds[ZDATETIME, ZDATETIME]` | разность двух значений одного класса в секундах как `INTEGER`, считается как **второй** аргумент минус **первый** (`subtractSeconds(a, b) = b - a`, положительно, когда `b` — более поздняя величина); PG `extract(epoch from (b - a))` |
7474
| `daysBetweenDates[DATE, DATE]` | разность двух дат в днях как `INTEGER`, считается как **первый** аргумент минус **второй** (`daysBetweenDates(a, b) = a - b`, положительно, когда `a` — более поздняя дата); PG `$1 - $2`. Порядок операндов обратен `subtractSeconds` |
75-
| `daysInclBetweenDates[DATE, DATE]` | число дней между двумя датами с учётом обоих концов: **второй** аргумент минус **первый**, плюс 1 (`daysInclBetweenDates(a, b) = b - a + 1`) — порядок операндов обратен `daysBetweenDates[DATE, DATE]`, так как оно вызывается с переставленными аргументами |
75+
| `daysBetweenDatesIncl[DATE, DATE]` | число дней между двумя датами с учётом обоих концов: **первый** аргумент минус **второй**, плюс 1 (`daysBetweenDatesIncl(a, b) = a - b + 1`) — тот же порядок операндов, что у `daysBetweenDates[DATE, DATE]` |
7676
| `secondsBetweenDates[DATETIME, DATETIME]` | разность двух моментов в секундах как `INTEGER`, считается как **первый** аргумент минус **второй** (`secondsBetweenDates(a, b) = a - b`, положительно, когда `a` — более поздний момент); PG `extract(epoch from $1) - extract(epoch from $2)` |
7777
| `dateTimeToDateTime[DATE, TIME]` | собирает `DATETIME` из `DATE` и `TIME` через приведение текста; PG `to_timestamp(<дата> \|\| <время>, 'YYYY-MM-DDHH24:MI:SS.MS')::timestamp` |
7878
| `dateFromYearWeekDay[INTEGER, INTEGER, INTEGER]` | собирает `DATE` по году, номеру недели ISO 8601 и дню недели ISO (1 = понедельник … 7 = воскресенье); PG `to_date($1 \|\| ' ' \|\| $2 \|\| ' ' \|\| $3, 'IYYY IW ID')` |

docs/rules/en/Rules_properties.md

Lines changed: 89 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,37 @@ title: 'Rules: properties'
4747
- `(+)` / `(-)` or `GROUP SUM` produces `0`
4848
(a zero result is returned as `NULL`).
4949

50-
4. The assistant MUST NOT use `GROUP AGGR`
51-
inside arbitrary expressions.
52-
53-
`GROUP AGGR` is allowed only in property definitions.
54-
55-
When reasoning about it, the assistant MUST treat
56-
`GROUP AGGR` as `GROUP MAX`
50+
4. The assistant MUST NOT use `GROUP` with a `BY` block
51+
(including `GROUP AGGR`) inside expressions:
52+
in a type cast, in arithmetic
53+
(including `(+)` / `(-)`), as an argument
54+
of another property, or as an implementation
55+
of an abstract property via `+=`.
56+
57+
Such an operator defines the parameters
58+
of its result itself, so it is allowed only
59+
as an entire property definition:
60+
the right-hand side of a definition via `=`
61+
or an inline definition in square brackets;
62+
in any other position the platform raises
63+
the error `BY clause in GROUP operator
64+
cannot be used in expressions`.
65+
To use the result in an expression,
66+
the assistant SHOULD first rewrite the operator
67+
without `BY`, replacing each grouping
68+
with an equality condition on an outer parameter
69+
(`GROUP SUM f(x) IF g(x) = y`); otherwise,
70+
apply the inline form `[GROUP ... BY ...](...)`
71+
to arguments or declare a separate property
72+
and refer to it.
73+
74+
The restriction is tied specifically
75+
to the `BY` block: `GROUP` without `BY`
76+
takes its parameters from the outer context
77+
and may be used inside expressions.
78+
79+
When reasoning about `GROUP AGGR`, the assistant
80+
MUST treat it as `GROUP MAX`
5781
with an additional constraint.
5882

5983
5. The assistant SHOULD avoid unnecessary conditions
@@ -94,6 +118,11 @@ title: 'Rules: properties'
94118
the name must not be changed — changing `name` is
95119
forbidden by a system constraint.
96120

121+
`name` returns the static object's canonical name —
122+
`<namespace>_<Class>.<object>`, not the short identifier.
123+
When the part after the dot is needed, the assistant
124+
SHOULD use `basicName` from the `Utils` system module.
125+
97126
12. Property names SHOULD be concise
98127
and avoid unnecessary words.
99128

@@ -150,21 +179,67 @@ title: 'Rules: properties'
150179
to the parameters not used in the expressions;
151180
a mismatch in count or classes is an error.
152181

182+
19. `MAX` and `MIN` are prefix operators over a comma-separated
183+
operand list (`MAX a, b`), not infix ones: `a MAX b`
184+
does not parse — the platform reports
185+
`no viable alternative at input 'MAX'`.
186+
187+
The operand list extends as far as the expression allows,
188+
so everything after the comma belongs to the operator:
189+
`MAX a, b * c` is `MAX(a, b * c)`, while `x * MAX a, b`
190+
is fine as it stands. Where a following operator must
191+
apply to the maximum itself, the operator MUST be
192+
parenthesized: `(MAX a, b) * c`.
193+
194+
These operators compare the operands of a single row;
195+
a maximum across rows is `GROUP MAX`.
196+
153197
## Abstract property rules (`+=`)
154198

155199
1. The value class of a `+=` implementation MUST fit within
156200
the value class declared on the abstract property; there
157201
is no implicit cast — an implementation with a wider
158202
class is rejected at server startup with a
159-
"wrong value class of implementation" error.
160-
161-
An expression that widens the value class — above all
162-
string concatenation, which sums the operands' lengths
163-
(`ISTRING[326]` against a declared `ISTRING[250]`) —
164-
the assistant MUST wrap in an explicit cast to the
165-
declared class:
203+
"wrong value class of implementation" error, whose
204+
`specified` and `expected` lines name the implementation's
205+
class and the declared one.
206+
207+
Arithmetic is what widens the class most often, and it
208+
widens further than it looks:
209+
210+
- `+` and `-` — like `MIN` / `MAX` and the selection
211+
operators — take the common ancestor, widening the whole
212+
part and the scale independently, so the result can be
213+
wider than either operand:
214+
`NUMERIC[16,2] + NUMERIC[10,4]` is `NUMERIC[18,4]`;
215+
- `*` adds both the whole parts and the scales:
216+
`NUMERIC[16,2] * NUMERIC[10,4]` is `NUMERIC[26,6]`;
217+
- `/` widens catastrophically: with the default settings
218+
its scale is always the maximum `NUMERIC` scale (`32`),
219+
so `NUMERIC[16,2] / NUMERIC[16,2]` is `NUMERIC[48,32]`.
220+
221+
A `GROUP` aggregate mostly keeps the class of what it
222+
aggregates — a `GROUP SUM`, `GROUP MAX` or `GROUP LAST`
223+
over a `NUMERIC[16,2]` is `NUMERIC[16,2]` — but it carries
224+
outward whatever that expression already widened to.
225+
`GROUP CONCAT` is the aggregate that widens by itself: its
226+
result is a string of unlimited length (`ISTRING` against
227+
a declared `ISTRING[250]`). Plain string concatenation
228+
widens as well, summing the operands' lengths
229+
(`ISTRING[326]` against a declared `ISTRING[250]`).
230+
231+
Any such expression the assistant MUST wrap in an explicit
232+
cast to the declared class:
233+
`f(X x) += NUMERIC[16,2](a(x) / b(x));`
166234
`f(X x) += ISTRING[250](a(x) + b(x));`
167235

236+
For operands of integer classes the cast MUST go on an
237+
operand first, so that the division is not integer
238+
division (see rule 16 of the property rules); the result
239+
still widens to scale `32` like any other division, so
240+
the outer cast is needed as well:
241+
`f(X x) += NUMERIC[16,2](NUMERIC[16,2](a(x)) / b(x));`
242+
168243
## Ordering rules (`ORDER`)
169244

170245
1. Where two rows can share an order key and the answer depends

0 commit comments

Comments
 (0)