Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

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:

PatternPurposeExample Location
skipif mysqlSkip tests for MySQL syntax incompatibilitiestest/evidence/in1.test:398-399
skipif mssqlSkip tests for MSSQL syntax differencestest/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:

PatternPurposeExample Location
onlyif sqliteExecute SQLite-specific extensionstest/evidence/in1.test:22-26
onlyif mysqlExecute MySQL-specific syntaxtest/evidence/in1.test:402-404
onlyif mssql + haltSkip entire file on MSSQLtest/evidence/slt_lang_reindex.test:23-24
onlyif oracle + haltSkip entire file on Oracletest/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:

IdentifierDatabase SystemCommon Usage
sqliteSQLiteTesting SQLite-specific extensions and non-standard features
mysqlMySQLTesting MySQL syntax variations or skipping incompatible features
mssqlMicrosoft SQL ServerSkipping MSSQL-incompatible syntax or testing MSSQL-specific behavior
oracleOracle DatabaseSkipping Oracle-incompatible features
postgresqlPostgreSQLTesting 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 PatternSQLite-Specific TestStandard SQL TestPurpose
label-1SELECT 1 IN t1SELECT 1 IN (SELECT * FROM t1)Empty set IN operator
label-13SELECT 1.23 IN t1SELECT 1.23 IN (SELECT * FROM t1)Float value IN empty set
label-19SELECT 1 IN t4SELECT 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:

  1. Identify the target platform: Maintain a database identifier string matching one of the recognized platform identifiers
  2. Parse directives: Recognize skipif, onlyif, and halt keywords at the beginning of lines
  3. Evaluate conditions: Compare the directive's database identifier against the runner's platform identifier
  4. Control execution flow: Skip or execute the next directive based on the evaluation result
  5. Handle halt: Immediately terminate file processing when a halt directive 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 PatternOccurrencesPurpose
onlyif sqlite~150 instancesSQLite-specific table-as-operand syntax and empty RHS support
skipif mysql6 instancesMySQL TEXT column unique constraint limitations
onlyif mysql6 instancesMySQL-specific indexed prefix syntax
onlyif mssql + halt1 instanceExclude entire file from MSSQL
onlyif oracle + halt1 instanceExclude 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 PatternOccurrencesPurpose
onlyif mssql + halt1 instanceREINDEX not supported on MSSQL
onlyif oracle + halt1 instanceREINDEX not supported on Oracle
onlyif mysql + halt1 instanceMySQL 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 PatternOccurrencesPurpose
skipif mssql3 instancesMSSQL 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.