One AND-group of conditions. A WHERE clause is a disjunction (OR) of
these groups; a row matches the clause iff it matches every condition of
some group (disjunctive normal form — no parentheses needed).
The outcome of executing one statement. A SELECT fills colnames and
the (nrows, ncols) cells grid; a DML statement fills count; DDL
fills message. Both the REPL and the test suite consume this same
structure, so output is asserted directly rather than scraped from text.
source line -> token stream
source line -> one statement AST
statement AST -> result (drives the engine)
source line -> result (lex + parse + exec)
result -> printed to a unit (the REPL renderer)
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | TK_EOF | = | 0 |
End of input |
| integer, | public, | parameter | :: | TK_IDENT | = | 1 |
Word: keyword or identifier (case decided by the parser) |
| integer, | public, | parameter | :: | TK_INT | = | 2 |
Integer literal |
| integer, | public, | parameter | :: | TK_REAL | = | 3 |
Real literal |
| integer, | public, | parameter | :: | TK_STR | = | 4 |
Quoted string literal (already unescaped) |
| integer, | public, | parameter | :: | TK_PUNCT | = | 5 |
Operator / punctuation ( One lexical token. |
| integer, | public, | parameter | :: | LIT_NULL | = | 0 |
SQL NULL |
| integer, | public, | parameter | :: | LIT_INT | = | 1 |
Integer literal |
| integer, | public, | parameter | :: | LIT_REAL | = | 2 |
Real literal |
| integer, | public, | parameter | :: | LIT_STR | = | 3 |
String literal A parsed literal value, tagged by |
| integer, | public, | parameter | :: | OP_EQ | = | 1 |
|
| integer, | public, | parameter | :: | OP_NE | = | 2 |
|
| integer, | public, | parameter | :: | OP_LT | = | 3 |
|
| integer, | public, | parameter | :: | OP_LE | = | 4 |
|
| integer, | public, | parameter | :: | OP_GT | = | 5 |
|
| integer, | public, | parameter | :: | OP_GE | = | 6 |
|
| integer, | public, | parameter | :: | OP_BETWEEN | = | 7 |
|
| integer, | public, | parameter | :: | OP_ISNULL | = | 8 |
|
| integer, | public, | parameter | :: | OP_ISNOTNULL | = | 9 |
One predicate condition: a column compared to one literal ( |
| integer, | public, | parameter | :: | ST_NONE | = | 0 | |
| integer, | public, | parameter | :: | ST_CREATE_TABLE | = | 1 | |
| integer, | public, | parameter | :: | ST_DROP_TABLE | = | 2 | |
| integer, | public, | parameter | :: | ST_CREATE_INDEX | = | 3 | |
| integer, | public, | parameter | :: | ST_DROP_INDEX | = | 4 | |
| integer, | public, | parameter | :: | ST_ADD_COLUMN | = | 5 | |
| integer, | public, | parameter | :: | ST_DROP_COLUMN | = | 6 | |
| integer, | public, | parameter | :: | ST_INSERT | = | 7 | |
| integer, | public, | parameter | :: | ST_DELETE | = | 8 | |
| integer, | public, | parameter | :: | ST_UPDATE | = | 9 | |
| integer, | public, | parameter | :: | ST_SELECT | = | 10 | |
| integer, | public, | parameter | :: | ST_BEGIN | = | 11 | |
| integer, | public, | parameter | :: | ST_COMMIT | = | 12 | |
| integer, | public, | parameter | :: | ST_ROLLBACK | = | 13 |
One parsed statement. A single fat record tagged by |
| integer, | public, | parameter | :: | SQLRES_NONE | = | 0 |
Nothing to report (e.g. BEGIN) |
| integer, | public, | parameter | :: | SQLRES_ROWS | = | 1 |
A SELECT result set |
| integer, | public, | parameter | :: | SQLRES_COUNT | = | 2 |
A DML row count |
| integer, | public, | parameter | :: | SQLRES_MSG | = | 3 |
A short status message (DDL) One rendered output cell of a SELECT result. |
Tokenise one source line. Always succeeds for well-formed tokens;
reports SQR_INVALID with errmsg (carrying the offending column)
for an unterminated string or a stray character. toks(1:ntok) are
the tokens; a trailing TK_EOF is not appended (callers use
ntok).
Parse one statement. Recursive descent into sql_stmt_t. A
trailing ; is permitted. Reports SQR_INVALID with a
column-anchored errmsg on a syntax error.
Execute one parsed statement against an open database, choosing an
index-driven or scan-driven plan as appropriate, and fill res.
Engine errors propagate through stat/errmsg. db is target
because the transaction façade the executor calls needs it.
Convenience: lex + parse + execute one source line. Equivalent to
sql_parse then sql_exec.
Render a result to a formatted unit: an aligned table for a SELECT,
a "N row(s)" line for DML, or the message for DDL. Used by the
REPL; tests inspect sql_result_t directly instead.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | text |
Source line |
||
| type(sql_token_t), | intent(out), | allocatable | :: | toks(:) |
Tokens |
|
| integer, | intent(out) | :: | ntok |
Token count |
||
| integer, | intent(out), | optional | :: | stat |
|
|
| character(len=*), | intent(inout), | optional | :: | errmsg |
Failure detail |
Tokenise one source line. Always succeeds for well-formed tokens;
reports SQR_INVALID with errmsg (carrying the offending column)
for an unterminated string or a stray character. toks(1:ntok) are
the tokens; a trailing TK_EOF is not appended (callers use
ntok).
Parse one statement. Recursive descent into sql_stmt_t. A
trailing ; is permitted. Reports SQR_INVALID with a
column-anchored errmsg on a syntax error.
Execute one parsed statement against an open database, choosing an
index-driven or scan-driven plan as appropriate, and fill res.
Engine errors propagate through stat/errmsg. db is target
because the transaction façade the executor calls needs it.
Convenience: lex + parse + execute one source line. Equivalent to
sql_parse then sql_exec.
Render a result to a formatted unit: an aligned table for a SELECT,
a "N row(s)" line for DML, or the message for DDL. Used by the
REPL; tests inspect sql_result_t directly instead.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | text |
Source line |
||
| type(sql_stmt_t), | intent(out) | :: | stmt |
Parsed statement |
||
| integer, | intent(out), | optional | :: | stat |
|
|
| character(len=*), | intent(inout), | optional | :: | errmsg |
Failure detail |
Tokenise one source line. Always succeeds for well-formed tokens;
reports SQR_INVALID with errmsg (carrying the offending column)
for an unterminated string or a stray character. toks(1:ntok) are
the tokens; a trailing TK_EOF is not appended (callers use
ntok).
Parse one statement. Recursive descent into sql_stmt_t. A
trailing ; is permitted. Reports SQR_INVALID with a
column-anchored errmsg on a syntax error.
Execute one parsed statement against an open database, choosing an
index-driven or scan-driven plan as appropriate, and fill res.
Engine errors propagate through stat/errmsg. db is target
because the transaction façade the executor calls needs it.
Convenience: lex + parse + execute one source line. Equivalent to
sql_parse then sql_exec.
Render a result to a formatted unit: an aligned table for a SELECT,
a "N row(s)" line for DML, or the message for DDL. Used by the
REPL; tests inspect sql_result_t directly instead.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(db_t), | intent(inout), | target | :: | db |
Open database handle |
|
| type(sql_stmt_t), | intent(in) | :: | stmt |
Statement to run |
||
| type(sql_result_t), | intent(out) | :: | res |
Execution result |
||
| integer, | intent(out), | optional | :: | stat |
|
|
| character(len=*), | intent(inout), | optional | :: | errmsg |
Failure detail |
Tokenise one source line. Always succeeds for well-formed tokens;
reports SQR_INVALID with errmsg (carrying the offending column)
for an unterminated string or a stray character. toks(1:ntok) are
the tokens; a trailing TK_EOF is not appended (callers use
ntok).
Parse one statement. Recursive descent into sql_stmt_t. A
trailing ; is permitted. Reports SQR_INVALID with a
column-anchored errmsg on a syntax error.
Execute one parsed statement against an open database, choosing an
index-driven or scan-driven plan as appropriate, and fill res.
Engine errors propagate through stat/errmsg. db is target
because the transaction façade the executor calls needs it.
Convenience: lex + parse + execute one source line. Equivalent to
sql_parse then sql_exec.
Render a result to a formatted unit: an aligned table for a SELECT,
a "N row(s)" line for DML, or the message for DDL. Used by the
REPL; tests inspect sql_result_t directly instead.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(db_t), | intent(inout), | target | :: | db |
Open database handle |
|
| character(len=*), | intent(in) | :: | text |
Source line |
||
| type(sql_result_t), | intent(out) | :: | res |
Execution result |
||
| integer, | intent(out), | optional | :: | stat |
|
|
| character(len=*), | intent(inout), | optional | :: | errmsg |
Failure detail |
Tokenise one source line. Always succeeds for well-formed tokens;
reports SQR_INVALID with errmsg (carrying the offending column)
for an unterminated string or a stray character. toks(1:ntok) are
the tokens; a trailing TK_EOF is not appended (callers use
ntok).
Parse one statement. Recursive descent into sql_stmt_t. A
trailing ; is permitted. Reports SQR_INVALID with a
column-anchored errmsg on a syntax error.
Execute one parsed statement against an open database, choosing an
index-driven or scan-driven plan as appropriate, and fill res.
Engine errors propagate through stat/errmsg. db is target
because the transaction façade the executor calls needs it.
Convenience: lex + parse + execute one source line. Equivalent to
sql_parse then sql_exec.
Render a result to a formatted unit: an aligned table for a SELECT,
a "N row(s)" line for DML, or the message for DDL. Used by the
REPL; tests inspect sql_result_t directly instead.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(sql_result_t), | intent(in) | :: | res |
Result to print |
||
| integer, | intent(in) | :: | unit |
Output unit |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | kind | = | TK_EOF | ||
| character(len=:), | public, | allocatable | :: | text | |||
| integer, | public | :: | col | = | 0 |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | ltype | = | LIT_NULL | ||
| integer(kind=int32), | public | :: | ival | = | 0_int32 | ||
| real(kind=real64), | public | :: | rval | = | 0.0_real64 | ||
| character(len=:), | public, | allocatable | :: | sval |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(sql_cond_t), | public, | allocatable | :: | conds(:) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | kind | = | ST_NONE | ||
| character(len=SQR_NAME_LEN), | public | :: | table | = | '' | ||
| type(column_t), | public, | allocatable | :: | coldefs(:) | |||
| character(len=SQR_NAME_LEN), | public, | allocatable | :: | names(:) | |||
| logical, | public | :: | select_star | = | .false. |
SELECT * |
|
| logical, | public | :: | unique | = | .false. |
CREATE UNIQUE INDEX |
|
| type(sql_lit_t), | public, | allocatable | :: | values(:,:) | |||
| logical, | public | :: | insert_named | = | .false. |
|
|
| character(len=SQR_NAME_LEN), | public, | allocatable | :: | set_cols(:) | |||
| type(sql_lit_t), | public, | allocatable | :: | set_vals(:) | |||
| logical, | public | :: | has_where | = | .false. | ||
| type(sql_cond_group_t), | public, | allocatable | :: | where_groups(:) | |||
| logical, | public | :: | has_order | = | .false. | ||
| character(len=SQR_NAME_LEN), | public | :: | order_col | = | '' | ||
| logical, | public | :: | order_desc | = | .false. | ||
| logical, | public | :: | has_limit | = | .false. | ||
| integer, | public | :: | limit_n | = | 0 |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | text | |||
| logical, | public | :: | is_null | = | .false. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | kind | = | SQLRES_NONE | ||
| character(len=SQR_NAME_LEN), | public, | allocatable | :: | colnames(:) | |||
| type(sql_cell_t), | public, | allocatable | :: | cells(:,:) | |||
| integer, | public | :: | nrows | = | 0 | ||
| integer, | public | :: | ncols | = | 0 | ||
| integer, | public | :: | count | = | 0 | ||
| character(len=:), | public, | allocatable | :: | message |