---
id: x3
title: "Appendix 3: Control Directives"
sidebar_label: "Appendix 3: Control Directives"
---
<!---
-- Copyright (c) Meta Platforms, Inc. and affiliates.
--
-- This source code is licensed under the MIT license found in the
-- LICENSE file in the root directory of this source tree.
-->
The control directives are those statements that begin with `@` and they are distinguished from other statements because they influence the compiler rather than the program logic.  Some of these are of great importance and discussed elsewhere.

The complete list (as of this writing) is:

`@ENFORCE_STRICT`
`@ENFORCE_NORMAL`

* These enable or disable more strict semanic checking the sub options are
  * `FOREIGN KEY ON UPDATE`: all FK's must choose some `ON UPDATE` strategy
  * `FOREIGN KEY ON DELETE`: all FK's must choose some `ON DELETE` strategy
  * `PROCEDURE`: all procedures must be declared before they are called (eliminating the vanilla `C` call option)
  * `JOIN`: all joins must be ANSI style, the form `FROM A,B` is not allowed (replace with `A INNER JOIN B`
  * `WINDOW FUNC`: window functions are disallowed (useful if targeting old versions of SQLite)
  * `UPSERT STATEMENT`: the upsert form is disallowed (useful if targeting old versions of SQLite)

`@SENSITIVE`
 * marks a column or variable as 'sensitive' for privacy purposes, this behaves somewhat like nullability (See Chapter 3) in that it is radioactive, contaminating anything it touches
 * the intent of this annotation is to make it clear where sensitive data is being returned or consumed in your procedures
 * this information appears in the JSON output for further codegen or for analysis (See Chapter 13)

`@DECLARE_SCHEMA_REGION`
`@DECLARE_DEPLOYABLE_REGION`
`@BEGIN_SCHEMA_REGION`
`@END_SCHEMA_REGION`

 * These directives control the declaration of schema regions and allow you to place things into those regions -- see [Chapter 10](https://cgsql.dev/cql-guide/ch10)

`@SCHEMA_AD_HOC_MIGRATION`
 * Allows for the creation of a ad hoc migration step at a given schema version, (See Chapter 10)

`@ECHO`
 * Emits text into the C output stream, useful for emiting things like function prototypes or preprocessor directives
 * e.g. `echo C, '#define foo bar'

`@RECREATE`
`@CREATE`
`@DELETE`
  * used to mark the schema version where an object is created or deleted, or alternatively indicate the the object is always dropped and recreated when it changes (See Chapter 10)

`@SCHEMA_UPGRADE_VERSION`
 * used to indicate that the code that follows is part of a migration script for the indicated schema version
 * this has the effect of making the schema appear to be how it existed at the indicated version
 * the idea here is that migration procedures operate on previous versions of the schema where (e.g.) some columns/tables hadn't been deleted yet

`@PREVIOUS_SCHEMA`
 * indicates the start of the previous version of the schema for comparison (See Chapter 11)

`@SCHEMA_UPGRADE_SCRIPT`
 * CQL emits a schema upgrade script as part of its upgrade features, this script declares tables in their final form but also creates the same tables as they existed when they were first created
 * this directive instructs CQL to ignore the incompatible creations, the first declaration controls
 * the idea here is that the upgrade script is in the business of getting you to the finish line in an orderly fashion and some of the interim steps are just not all the way there yet
 * note that the upgrade script recapitulates the version history, it does not take you directly to the finish line, this is so that all instances get to the same place the same way (and this fleshes out any bugs in migration)

`@DUMMY_NULLABLES`
`@DUMMY_DEFAULTS`
`@DUMMY_SEED`
 * these control the creation of dummy data for `insert` and `fetch` statements (See Chapters 5 and 12)

`@FILE`
 * a string literal that corresponds to the current file name with a prefix stripped (to remove build lab junk in the path)

`@ATTRIBUTE`
  * the main purpose of `@attribute` is to appear in the JSON output so that it can control later codegen stages in whatever way you deem appropriate
  * the nested nature of attribute values is sufficiently flexible than you could encode an arbitrary LISP program in an attribute, so really anything you might need to express is possible
  * there are a number of attributes known to the compiler which I list below (complete as of this writing)

  * `cql:autodrop=(table1, table2, ...)` when present the indicated tables, which must be temp tables, are dropped when the results of the procedure have been fetched into a rowset
  * `cql:identity=(column1, column2, ...)` the indicated columns are used to create a row comparator for the rowset corresponding to the procedure, this appears in a C macro of the form `procedure_name_row_same(rowset1, row1, rowset2, row2)`
  * `cql:suppress_getters` the annotated procedure should not emit its related column getter functions.
    * Useful if you only indend to call the procedure from CQL.
    * Saves code generation and removes the possibility of C code using the getters.
  * `cql:suppress_result_set` the annotated procedure should not emit its related "fetch results" function.
    * Useful if you only indend to call the procedure from CQL.
    * Saves code generation and removes the possibility of C code using the result set or getters.
    * Implies `cql:suppress_getters`; since there is no result set, getters would be redundant.
    * Note: an `OUT UNION` procedure cannot have a suppressed result set since all such a procedure does is produce a result set. This attribute is ignored for out union procedures.
  * `cql:private` the annotated procedure will be static in the generated C
    * Because the generated function is `static` it cannot be called from other modules and therefore will not go in any CQL exports file (that would be moot since you couldn't call it).
    * This attribute also implies `cql:suppress_result_set` since only CQL code in the same translation unit could possibly call it and hence the result set procedure is useless to other C code.
  * `cql:generate_copy` the code generation for the annotated procedure will produce a `[procedure_name]_copy` function that can make complete or partial copies of its result set.
  * `cql:base_fragment=frag_name` used for base fragments (See [Chapter 14](https://cgsql.dev/cql-guide/ch14#base-query-fragments))
  * `cql:extension_fragment=frag_name` used for extension fragments (See [Chapter 14](https://cgsql.dev/cql-guide/ch14#extension-query-fragments))
  * `cql:assembly_fragment=frag_name` used for assembly fragments (See [Chapter 14](https://cgsql.dev/cql-guide/ch14#extension-query-fragments))
  * `cql:shared_fragment` is used to create shared fragments (See [Chapter 14](https://cgsql.dev/cql-guide/ch14#shared-fragments))
  * `cql:no_table_scan` for query plan processing, indicates that the table in question should never be table scanned in any plan (for better diagnostics)
  * `cql:autotest=([many forms])` declares various autotest features (See Chapter 12)
  * `cql:query_plan_branch=[integer]` is used by the query plan generator to determine which conditional branch to use in query plan analysis when a shared fragment that contains an `IF` statement is used. (See [Chapter 15](/cql-guide/ch15))
  * `cql:alias_of=[c_function_name]` are used on [function declarations](https://cgsql.dev/cql-guide/ch08/#ordinary-scalar-functions) to declare a function or procedure in CQL that calls a function of a different name. This is intended to used for aliasing native (C) functions. Both the aliased function name and the original function name may be declared in CQL at the same time. Note that the compiler does not enforce any consistency in typing between the original and aliased functions.
