Data Management (DMS) provides a domain-specific language (DSL) to define security rules for database development workflows. Use DSL rules to control which SQL statements can be submitted, how approvals are routed, and when operations are blocked or flagged as risky.
How it works
A security rule is an IF-THEN or IF-THEN-ELSE statement. When a condition is met, DMS performs the corresponding action.
Basic structure:
if <condition>
then <action>
endExtended structure with multiple branches:
if <condition 1>
then <action 1>
elseif <condition 2>
then <action 2>
[else <action 3>]
endEach rule must contain exactly one if condition. It can have zero or more elseif branches and zero or one else clause. If no branch matches and there is no else clause, DMS takes no action.
DSL components
A security rule consists of three building blocks: conditional clauses, action clauses, and predefined functions.
Conditional clauses
A conditional clause evaluates to true or false. It is built from one or more of the following:
Factors — predefined system variables that represent context at the time of evaluation (for example, SQL statement type, number of affected rows)
Operators — symbols that compare or test values
Connectors —
ANDandOR, which combine multiple expressions
AND has higher priority than OR. Both have lower priority than operators. Use parentheses to override the default evaluation order.
Example: In 1 <= 0 or 1 == 1, DMS evaluates 1 <= 0 and 1 == 1 separately, then applies OR. To make priority explicit: (1 <= 0) == true.
Operators
Operators connect factors and constants in conditional expressions. The following operators are supported:
| Operator | Description | Example |
|---|---|---|
== | Equal to | 1 == 1 |
!= | Not equal to | 1 != 2 |
> | Greater than | @fac.insert_rows > 1000 |
>= | Greater than or equal to | @fac.insert_rows >= 1000 |
< | Less than | @fac.insert_rows < 100 |
<= | Less than or equal to | @fac.insert_rows <= 100 |
in | Belongs to an array | 'a' in ['a', 'b', 'c'] |
not in | Does not belong to an array | 'a' not in ['a', 'b', 'c'] |
matchs | Matches a regular expression | 'idx_aa' matchs 'idx_\\w+' |
not matchs | Does not match a regular expression | 'idx_aa' not matchs 'idx_\\w+' |
isBlank | Value is empty | '' isBlank |
isNotBlank | Value is not empty | '' isNotBlank |
Backslash escaping in regular expressions: To include a literal backslash (\) in a regex pattern, escape it with another backslash. For example, write idx_\\w+ to match idx_\w+.
Factors
Factors are predefined variables that provide context at security rule evaluation time — such as the SQL statement type, the number of rows affected, or whether the target is a logical database. Use them in conditional clauses to write rules based on real operation metadata.
A factor name uses the format @fac.<display-name>. DMS provides different factors for different checkpoints in each module.
| Factor | Description |
|---|---|
@fac.env_type | Environment type. Example values: DEV, PRODUCT. See Change the environment type for an instance. |
@fac.sql_type | SQL statement type. Example values: UPDATE, INSERT. |
@fac.detail_type | Data change ticket type. See valid values below. |
@fac.is_logic | Whether the target database is a logical database. |
@fac.extra_info | Other ticket information. Not currently in use. |
@fac.is_ignore_affect_rows | Whether to skip row-count validation. |
@fac.insert_rows | Number of rows to be inserted. |
@fac.update_delete_rows | Number of rows to be updated or deleted. |
@fac.max_alter_table_size | Size of the largest tablespace containing the table to be modified. |
@fac.is_has_security_column | Whether the SQL statement involves sensitive fields. |
@fac.security_column_list | Sensitive fields involved in the SQL statement. |
@fac.risk_level | Risk level of the operation. |
@fac.risk_reason | Reason for the assigned risk level. |
Valid values for `@fac.detail_type`:
| Value | Ticket type |
|---|---|
COMMON | Normal Data Modify |
CHUNK_DML | Lockless Change |
PROCEDURE | Programmable Object |
CRON_CLEAR_DATA | History Data Clean |
BIG_FILE | Large Data Import |
Example: Check whether an SQL statement is a DML statement:
@fac.sql_type == 'DML'Action clauses
An action defines what DMS does when a condition is met. Action names use the format @act.<display-name>. DMS provides different actions for different checkpoints in each module.
| Action | Description |
|---|---|
@act.allow_submit | Requires the submission of SQL statements to be executed in a ticket. |
@act.allow_execute_direct | Allows execution of SQL statements in SQL Console. |
@act.forbid_execute | Blocks execution of SQL statements. |
@act.mark_risk | Marks the operation with a risk level and a custom message. Example: @act.mark_risk 'middle' 'Medium risk: online environment' |
@act.do_not_approve | Specifies the ID of an approval template. See Configure approval processes. |
@act.choose_approve_template | Selects an approval template. |
@act.choose_approve_template_with_reason | Selects an approval template and includes a reason. |
Predefined functions
Predefined functions can be used in both conditional clauses and action clauses. Function names use the format @fun.<display-name>.
| Function | Input | Output | Description |
|---|---|---|---|
@fun.concat | Multiple strings | String | Concatenates strings into one. |
@fun.char_length | A string | Integer | Returns the length of a string. |
@fun.is_char_lower | A string | Boolean | Returns true if all letters are lowercase. |
@fun.is_char_upper | A string | Boolean | Returns true if all letters are uppercase. |
@fun.array_size | An array | Integer | Returns the number of elements in an array. |
@fun.add | Multiple numeric values | Numeric | Adds multiple values. |
@fun.sub | Two numeric values | Numeric | Subtracts the second value from the first. |
@fun.between | Three values: target, lower bound, upper bound | Boolean | Returns true if the target falls within the closed range [lower, upper]. Supports NUMERIC, DATE, and TIME types. |
@fun.current_datetime | None | String | Returns the current date and time in yyyy-MM-dd HH:mm:ss format. |
@fun.current_date | None | String | Returns the current date in yyyy-MM-dd format. |
@fun.current_time | None | String | Returns the current time in HH:mm:ss format. |
@fun.is_contain_str | Two strings | Boolean | Returns true if the first string contains the second. |
@fun.listEqualIgnoreOrder | Two string lists | Boolean | Returns true if both lists contain the same strings, regardless of order or case. |
Selected examples:
String concatenation:
@fun.concat('d', 'm', 's')
// Output: 'dms'@fun.concat('[Development standards] Enter a comment for the [', @fac.column_name, '] field.')
// Output: a reminder message with the field name insertedChecking whether a numeric value falls within a range:
@fun.between(@fac.export_rows, 2001, 100000)
// Returns true if the number of exported rows is between 2,001 and 100,000@fun.between(@fun.current_datetime(), '2019-10-31 00:00:00', '2019-11-04 00:00:00')
// Returns true if the current date and time fall within the specified windowChecking list equality:
@fun.listEqualIgnoreOrder(@fac.perm_type, ['QUERY'])
// Returns true if only the query permission is requested@fun.listEqualIgnoreOrder(@fac.perm_type, ['CORRECT', 'EXPORT'])
// Returns true if both the change and export permissions are requestedExamples
Limit the number of SQL statements per ticket
Block submission if a ticket contains more than 1,000 SQL statements:
if
@fac.sql_count > 1000
then
@act.reject_execute 'The number of SQL statements in a ticket cannot exceed 1,000.'
endIf the count exceeds 1,000, DMS rejects the ticket and displays the message.
Allow only DML statements
Allow submission only when all SQL statements are DML operations:
if
@fac.sql_type in ['UPDATE', 'DELETE', 'INSERT', 'INSERT_SELECT']
then
@act.allow_submit
end