From 710463ce06f45fbf910eb3c3a24302d468139bcf Mon Sep 17 00:00:00 2001 From: dc Date: Tue, 20 Oct 2026 16:51:13 +0000 Subject: [PATCH] docs(config): VAR_DEPENDENCIES replaces VAR_ORDER Each row lists every input the expression uses, physical columns and derived variables alike. No sequence number to maintain; statements are emitted in dependency order and a cycle is rejected. --- docs/derived-variables.md | 38 ++++++++++++++++++++------------------ docs/tables/mpe_derived.md | 2 +- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/derived-variables.md b/docs/derived-variables.md index 771cafe..8f6cac7 100644 --- a/docs/derived-variables.md +++ b/docs/derived-variables.md @@ -20,7 +20,7 @@ Each row defines one variable: - `LIBREF` / `DSN` - the target table - `VAR_NM` - the name of the new column - - `VAR_ORDER` - evaluation order; a variable may reference one with a lower order + - `VAR_DEPENDENCIES` - every input the expression uses: the physical columns and any derived variables, space separated - `VAR_TYPE` - `C` for character, `N` for numeric - `VAR_LEN` - character length, or numeric length (1-8) - `VAR_FMT` - optional, eg `DATE9.` or `DOLLAR12.2` @@ -30,27 +30,29 @@ Each row defines one variable: A simple example, deriving a region from a state: ``` -VAR_NM REGION -VAR_ORDER 10 -VAR_TYPE C -VAR_LEN 8 -VAR_FMT (blank) -VAR_LOGIC ifc(STATE in ('CA','OR','WA'),'West','East') -ACTIVE 1 +VAR_NM REGION +VAR_DEPENDENCIES STATE +VAR_TYPE C +VAR_LEN 8 +VAR_FMT (blank) +VAR_LOGIC ifc(STATE in ('CA','OR','WA'),'West','East') +ACTIVE 1 ``` -A later variable can build on it, provided its order is higher: +A second variable can build on it - its dependencies include the physical column and the derived one: ``` -VAR_NM REGION_LABEL -VAR_ORDER 20 -VAR_TYPE C -VAR_LEN 14 -VAR_FMT (blank) -VAR_LOGIC cats(REGION,'-',STATE) -ACTIVE 1 +VAR_NM REGION_LABEL +VAR_DEPENDENCIES REGION STATE +VAR_TYPE C +VAR_LEN 14 +VAR_FMT (blank) +VAR_LOGIC cats(REGION,'-',STATE) +ACTIVE 1 ``` +There is no sequence number to maintain. The statements are emitted in dependency order, so `REGION` is always assigned before `REGION_LABEL`, however the rows are ordered in the table. + For each row, Data Controller generates the following statements when the table is read: ```sas @@ -71,7 +73,7 @@ Derived columns themselves are an EDIT screen feature: the VIEW screen and the d ## Rules and limits - **Expressions only.** `VAR_LOGIC` must be a single SAS expression - no semicolons, macro triggers (`%`, `&`) or comments. Conditional logic is available through functions such as `ifc()`, `choosec()`, `cats()`, `catx()`, `put()`, `input()` and `intnx()`. - - **Ordered.** Statements are generated in `VAR_ORDER` sequence. An expression may reference the physical columns of the table, and any derived variable with a lower `VAR_ORDER`. A reference to a variable that is not defined earlier is rejected, because SAS would otherwise return a missing value without an error. `VAR_ORDER` is required, and must be a positive integer. + - **Dependencies declared.** `VAR_DEPENDENCIES` lists every input the expression uses, physical columns and derived variables alike. Statements are generated in dependency order, so a variable can build on another without a sequence number. The declaration is checked against the expression in both directions: a derived variable that is referenced must be declared, and a declared name that the expression does not reference is an error. A declared name must be a column of the table or a derived variable of the same table, and a cycle is rejected. - **No collisions.** `VAR_NM` must not match an existing column of the target table, or one of the reserved names (`TX_FROM`, `TX_TO`, `PROCESSED_DTTM`, `VAR_TXFROM`, `VAR_TXTO`, `VAR_PROCESSED`, `_____DELETE__THIS__RECORD_____`). - **Read-only.** Derived columns cannot be edited in the grid, and any value submitted for them is discarded before the approval package is created. - **Recomputed on every read.** The value always reflects the current data and the current definition, and there is no history of previous derived values. @@ -80,7 +82,7 @@ A configuration error - a bad name, an invalid type or length, a name collision, Most of these rules are also applied when a row is submitted for approval, through a post edit hook on `MPE_DERIVED`. A bad name, type, length, format or expression - or a reference to a variable that is not defined earlier - is rejected at submit time, while the error can still be corrected, rather than breaking the EDIT screen afterwards. The collision between `VAR_NM` and a physical column of the target table is only checked at read time, as the hook does not have the target library assigned. -The simple rules are also configured as validation rules on the table itself, so they show up in the grid before submission: `VAR_TYPE` is a dropdown of `C` and `N`, `VAR_ORDER` and `VAR_LEN` carry minimum and maximum values, and `VAR_NM`, `VAR_FMT` and `VAR_LOGIC` are pattern checked. Validation rules are evaluated in the browser, so the post edit hook remains the authoritative check. +The simple rules are also configured as validation rules on the table itself, so they show up in the grid before submission: `VAR_TYPE` is a dropdown of `C` and `N`, `VAR_LEN` carries minimum and maximum values, and `VAR_NM`, `VAR_DEPENDENCIES`, `VAR_FMT` and `VAR_LOGIC` are pattern checked. Validation rules are evaluated in the browser, so the post edit hook remains the authoritative check. !!! warning "Derived values can expose hidden data" An expression can reference a column that is hidden from the user by [Column Level Security](/column-level-security/), and the derived column will show the result. Configure derived variables with the same care as any other data exposure. diff --git a/docs/tables/mpe_derived.md b/docs/tables/mpe_derived.md index 2836b49..9a737d3 100644 --- a/docs/tables/mpe_derived.md +++ b/docs/tables/mpe_derived.md @@ -17,7 +17,7 @@ The table is itself registered in [MPE_TABLES](/tables/mpe_tables/), so it is ma - 🔑 `LIBREF char(8)`: The libref of the target table - 🔑 `DSN char(32)`: The target table - 🔑 `VAR_NM char(32)`: The name of the derived column - - `VAR_ORDER num`: Evaluation order; a variable may reference one with a lower order + - `VAR_DEPENDENCIES char(4000)`: Every input the expression uses - physical columns and derived variables, space separated - `VAR_TYPE char(1)`: `C` for character, `N` for numeric - `VAR_LEN num`: Character length, or numeric length (1-8) - `VAR_FMT char(32)`: Optional SAS format, eg `DATE9.`