This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Conditional Execution Directives
Relevant source files
Purpose and Scope
This document specifies the conditional execution directives used in SQL Logic Test files to control which statements and queries execute based on the target database platform. These directives enable a single test file to support multiple SQL implementations while accommodating platform-specific differences in SQL syntax, feature support, and semantic behavior.
For information about the specific platform differences that necessitate these directives, see Platform-Specific Behaviors. For details on the complete test file format specification, see Test File Format Specification.
Overview
Conditional execution directives are line-based control statements that determine whether subsequent test operations should execute, be skipped, or halt file processing entirely. These directives enable tests to adapt their behavior based on which database engine is executing them, allowing the corpus to validate both SQLite-specific extensions and standard SQL behavior across different implementations.
The directives operate on a simple boolean matching model: each directive specifies a target database platform and controls the execution of the immediately following statement or query. When multiple directives appear consecutively, they create conditional execution chains that can handle complex platform-specific scenarios.
Sources: test/evidence/in1.test:1-10 test/evidence/slt_lang_reindex.test:18-32
Directive Types
skipif Directive
The skipif directive prevents execution of the next statement or query when the current database platform matches the specified identifier.
Syntax:
skipif <database-identifier>
Behavior: If the test runner is executing against the specified database, the immediately following test directive (statement or query) is skipped and execution continues with the subsequent line. If the database does not match, the directive has no effect and normal execution proceeds.
Example Usage:
skipif mssql
statement ok
DROP INDEX t1i1;
In this example from test/evidence/slt_lang_dropindex.test:22-24 the DROP INDEX statement is skipped when running on Microsoft SQL Server because MSSQL uses different syntax for dropping indexes (DROP INDEX table.index instead of DROP INDEX index).
Common Patterns:
| Pattern | Purpose | Example Location |
|---|---|---|
skipif mysql | Skip tests for MySQL syntax incompatibilities | test/evidence/in1.test:398-399 |
skipif mssql | Skip tests for MSSQL syntax differences | test/evidence/slt_lang_dropindex.test:22-24 |
Sources: test/evidence/slt_lang_dropindex.test:22-34 test/evidence/in1.test:398-404 test/evidence/in1.test:421-427
onlyif Directive
The onlyif directive ensures that the next statement or query executes only when the current database platform matches the specified identifier.
Syntax:
onlyif <database-identifier>
Behavior: If the test runner is executing against the specified database, the immediately following test directive proceeds normally. If the database does not match, the following directive is skipped and execution continues.
Example Usage:
onlyif sqlite # empty RHS
query I nosort
SELECT 1 IN ()
----
0
This example from test/evidence/in1.test:22-26 demonstrates a SQLite-specific feature where the IN operator can accept an empty set on the right-hand side. The comment # empty RHS provides context that this test validates non-standard behavior.
File-Level Halting Pattern:
onlyif mssql
halt
When combined with halt, the onlyif directive creates an early-exit mechanism for entire files. The pattern at test/evidence/slt_lang_reindex.test:23-24 causes the test runner to stop processing the file immediately when running on MSSQL, effectively skipping all tests in that file.
Common Patterns:
| Pattern | Purpose | Example Location |
|---|---|---|
onlyif sqlite | Execute SQLite-specific extensions | test/evidence/in1.test:22-26 |
onlyif mysql | Execute MySQL-specific syntax | test/evidence/in1.test:402-404 |
onlyif mssql + halt | Skip entire file on MSSQL | test/evidence/slt_lang_reindex.test:23-24 |
onlyif oracle + halt | Skip entire file on Oracle | test/evidence/in1.test:8-9 |
Sources: test/evidence/in1.test:4-9 test/evidence/in1.test:22-26 test/evidence/slt_lang_reindex.test:23-32
halt Directive
The halt directive immediately stops processing the current test file when encountered.
Syntax:
halt
Behavior: When executed, this directive causes the test runner to cease reading and processing any remaining lines in the file. Execution then proceeds to the next test file in the suite.
Typical Usage Pattern:
The halt directive is almost always used in combination with onlyif to create platform-specific file exclusions:
# skip this entire file if ms sql server
onlyif mssql
halt
# skip this entire file if oracle
onlyif oracle
halt
This pattern from test/evidence/slt_lang_reindex.test:22-28 demonstrates the idiomatic approach: conditional directives at the beginning of a file determine whether the entire file should be skipped based on database platform compatibility.
Sources: test/evidence/in1.test:4-9 test/evidence/slt_lang_reindex.test:22-32
Database Platform Identifiers
Conditional directives recognize the following database platform identifiers:
| Identifier | Database System | Common Usage |
|---|---|---|
sqlite | SQLite | Testing SQLite-specific extensions and non-standard features |
mysql | MySQL | Testing MySQL syntax variations or skipping incompatible features |
mssql | Microsoft SQL Server | Skipping MSSQL-incompatible syntax or testing MSSQL-specific behavior |
oracle | Oracle Database | Skipping Oracle-incompatible features |
postgresql | PostgreSQL | Testing standard SQL compliance on PostgreSQL |
The identifier comparison is case-sensitive and must match exactly as shown above.
Sources: test/evidence/in1.test:4-9 test/evidence/slt_lang_reindex.test:23-32 test/evidence/in1.test:398-427
Directive Execution Model
Single-Statement Control Flow
Sources: test/evidence/in1.test:22-65 test/evidence/slt_lang_dropindex.test:22-34
File-Level Halt Pattern
The most common pattern for excluding entire files based on database platform uses consecutive onlyif + halt pairs:
Sources: test/evidence/in1.test:1-10 test/evidence/slt_lang_reindex.test:22-32
Label-Based Test Organization
Conditional directives work in conjunction with the label system to enable platform-specific variations of the same logical test:
onlyif sqlite
query I nosort label-1
SELECT 1 IN t1
----
0
query I nosort label-1
SELECT 1 IN (SELECT * FROM t1)
----
0
In this pattern from test/evidence/in1.test:69-78 both queries share the same label-1 identifier. The first query uses SQLite's non-standard table-as-operand syntax (1 IN t1), which only executes on SQLite. The second query uses standard SQL subquery syntax and executes on all platforms. Both validate the same logical behavior but accommodate different SQL syntax support.
Label Pattern Analysis:
| Label Pattern | SQLite-Specific Test | Standard SQL Test | Purpose |
|---|---|---|---|
label-1 | SELECT 1 IN t1 | SELECT 1 IN (SELECT * FROM t1) | Empty set IN operator |
label-13 | SELECT 1.23 IN t1 | SELECT 1.23 IN (SELECT * FROM t1) | Float value IN empty set |
label-19 | SELECT 1 IN t4 | SELECT 1 IN (SELECT * FROM t4) | Integer IN non-empty set |
This pattern appears extensively throughout test/evidence/in1.test:69-549 with each label representing a distinct test case that has both SQLite-specific and portable implementations.
Sources: test/evidence/in1.test:69-158 test/evidence/in1.test:239-260
Directive Combination Patterns
Multiple Platform Exclusions
Files that are incompatible with multiple platforms use sequential onlyif + halt pairs:
# skip this entire file if ms sql server
onlyif mssql
halt
# skip this entire file if oracle
onlyif oracle
halt
# skip this entire file if mysql
onlyif mysql
halt
This pattern from test/evidence/slt_lang_reindex.test:22-32 ensures the REINDEX command tests only run on SQLite and PostgreSQL, as these are the only major SQL implementations that support the REINDEX statement.
Sources: test/evidence/slt_lang_reindex.test:18-32
Inline Conditional Execution
For individual statement variations, directives appear immediately before the affected test:
skipif mysql
statement ok
CREATE TABLE t7(a TEXT UNIQUE)
onlyif mysql
statement ok
CREATE TABLE t7(a TEXT, UNIQUE (a(1)))
This pattern from test/evidence/in1.test:398-404 handles MySQL's requirement for indexed prefix lengths on TEXT columns. The first statement creates a standard unique constraint for all databases except MySQL. The second statement uses MySQL's indexed prefix syntax UNIQUE (a(1)) only when running on MySQL.
Sources: test/evidence/in1.test:398-427
Platform-Specific Comment Annotations
Directives often include inline comments explaining why the conditional execution is necessary:
onlyif sqlite # empty RHS
query I nosort
SELECT 1 IN ()
----
0
The comment # empty RHS from test/evidence/in1.test:22-26 documents that this test validates SQLite's non-standard support for empty right-hand side sets in IN expressions. These annotations serve as inline documentation for developers reading the test files.
Sources: test/evidence/in1.test:22-26 test/evidence/in1.test:38-42
Directive Scope and Limitations
Single-Statement Scope
Each skipif or onlyif directive affects exactly one subsequent statement or query directive. Multiple directives cannot be batched under a single conditional:
Valid Pattern:
onlyif sqlite
query I nosort
SELECT 1 IN t1
----
0
onlyif sqlite
query I nosort
SELECT 1 NOT IN t1
----
1
Invalid Pattern (Not Supported):
onlyif sqlite
query I nosort
SELECT 1 IN t1
----
0
query I nosort
SELECT 1 NOT IN t1 # This will execute unconditionally
----
1
Each conditional test requires its own directive prefix, as seen in test/evidence/in1.test:69-90 where consecutive onlyif sqlite directives each control a single query.
Sources: test/evidence/in1.test:69-90 test/evidence/in1.test:163-205
No Nested Conditionals
The directive system does not support logical combinations or nested conditions. Each directive evaluates independently:
- No AND logic:
skipif mysql AND oracle(not supported) - No OR logic:
onlyif sqlite OR postgresql(not supported) - No negation:
skipif NOT mysql(not supported)
To exclude a test from multiple platforms, use separate directive-statement pairs or the file-level halt pattern.
Sources: test/evidence/slt_lang_reindex.test:22-32
Integration with Test Execution
Test Runner Requirements
To implement conditional execution support, test runners must:
- Identify the target platform: Maintain a database identifier string matching one of the recognized platform identifiers
- Parse directives: Recognize
skipif,onlyif, andhaltkeywords at the beginning of lines - Evaluate conditions: Compare the directive's database identifier against the runner's platform identifier
- Control execution flow: Skip or execute the next directive based on the evaluation result
- Handle halt: Immediately terminate file processing when a
haltdirective executes
Sources: test/evidence/in1.test:1-10 test/evidence/slt_lang_dropindex.test:22-34
Execution State Machine
Sources: test/evidence/in1.test:1-65 test/evidence/slt_lang_reindex.test:22-38
Usage Statistics
Analysis of the provided test files reveals the frequency and distribution of conditional directives:
in1.test Directive Distribution
| Directive Pattern | Occurrences | Purpose |
|---|---|---|
onlyif sqlite | ~150 instances | SQLite-specific table-as-operand syntax and empty RHS support |
skipif mysql | 6 instances | MySQL TEXT column unique constraint limitations |
onlyif mysql | 6 instances | MySQL-specific indexed prefix syntax |
onlyif mssql + halt | 1 instance | Exclude entire file from MSSQL |
onlyif oracle + halt | 1 instance | Exclude entire file from Oracle |
Analysis: The heavy use of onlyif sqlite in test/evidence/in1.test reflects this file's focus on validating SQLite's non-standard IN operator extensions, particularly the table-as-operand syntax and empty set support.
Sources: test/evidence/in1.test:1-1156
slt_lang_reindex.test Directive Distribution
| Directive Pattern | Occurrences | Purpose |
|---|---|---|
onlyif mssql + halt | 1 instance | REINDEX not supported on MSSQL |
onlyif oracle + halt | 1 instance | REINDEX not supported on Oracle |
onlyif mysql + halt | 1 instance | MySQL uses REPAIR TABLE instead |
Analysis: This file uses exclusively file-level halt directives, as the REINDEX command is fundamentally incompatible with most database systems except SQLite and PostgreSQL.
Sources: test/evidence/slt_lang_reindex.test:18-32
slt_lang_dropindex.test Directive Distribution
| Directive Pattern | Occurrences | Purpose |
|---|---|---|
skipif mssql | 3 instances | MSSQL uses DROP INDEX table.index syntax |
Analysis: The consistent use of skipif mssql before DROP INDEX statements reflects MSSQL's requirement to qualify the index name with its table name.
Sources: test/evidence/slt_lang_dropindex.test:22-34
This conditional execution system enables the SQL Logic Test corpus to serve as a comprehensive validation suite across multiple database platforms while maintaining a single, unified test file format. The simplicity of the directive syntax—limited to three keywords and platform-specific matching—ensures that test files remain readable and maintainable while supporting complex cross-platform testing scenarios.