Data-Dictionary: Difference between revisions

From Webhuis wiki
Jump to navigation Jump to search
(Created page with "= Data Dictionary = '''Project:''' pgcobol — Prime Numbers Application '''Version:''' 1.0 (reverse-engineered) '''Date:''' 2026-03-17 ----- == 1. Conventions == {| ! Column ! Meaning |- | Name | COBOL data-name as written in source |- | Level | 01 / 03 / 05 / 07 hierarchy level |- | Picture | COBOL PICTURE clause |- | Usage | DISPLAY (default) / COMP-3 / COMP-5 |- | Source | Copybook or program where defined |- | Description | Semantic meaning and valid values |} Condi...")
 
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
<span id="data-dictionary"></span>
= Data Dictionary = '''Project:''' pgcobol — Prime Numbers Application
= Data Dictionary =
'''Version:''' 1.0 (reverse-engineered)

'''Date:''' 2026-03-17 ----- == 1. Conventions == {| ! Column ! Meaning |- | Name | COBOL data-name as written in source |- | Level | 01 / 03 / 05 / 07 hierarchy level |- | Picture | COBOL PICTURE clause |- | Usage | DISPLAY (default) / COMP-3 / COMP-5 |- | Source | Copybook or program where defined |- | Description | Semantic meaning and valid values |} Condition-names (88-level) are listed under the field they qualify. ----- == 2. Copybook: primes-session.cpy == '''Control block for the session (main → business-logic) tier.''' {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | primes-session | 01 | — | — | Root of session control block; passed as linkage to primesgen |- | methods | 03 | X(32) | DISPLAY | Operation verb set by primesmain before calling primesgen |- | — report-primes | 88 | — | — | VALUE “report” — run the report path |- | — generate-primes | 88 | — | — | VALUE “generate” — run the sieve path |- | — start-primes | 88 | — | — | VALUE “start” — (reserved, not used in current flow) |- | — stop-primes | 88 | — | — | VALUE “stop” — (reserved, not used in current flow) |- | — invalid-method | 88 | — | — | VALUE “bad” — sentinel for bad dispatch |- | session-result | 03 | 9(2) | DISPLAY | Result code written back by primesgen; initial value ZERO |- | — session-method-ok | 88 | — | — | VALUE 0 — operation succeeded |- | — session-method-nok | 88 | — | — | VALUE 1 — operation failed |- | — session-method-eof | 88 | — | — | VALUE 9 — cursor exhausted (end of data) |} ----- == 3. Copybook: primes-dal.cpy == '''Control block for the DAL (business-logic → data-access) tier.''' {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | primes-dal | 01 | — | — | Root of DAL control block; passed as linkage to primes |- | dal-methods | 03 | X(32) | DISPLAY | Operation verb set by caller |- | — next-prime | 88 | — | — | VALUE “next-prime” — fetch next row from cursor |- | — next-divider | 88 | — | — | VALUE “next-divider” — select divider by ident |- | — write-prime | 88 | — | — | VALUE “write” — insert prime into table |- | — db-cursor | 88 | — | — | VALUE “cursor” — start transaction and open cursor |- | — db-connect | 88 | — | — | VALUE “connect” — connect to PostgreSQL |- | — db-disconnect | 88 | — | — | VALUE “disconnect” — disconnect from PostgreSQL |- | — invalid-method | 88 | — | — | VALUE “bad” — sentinel for bad dispatch |- | primes-data | 03 | — | — | One-row data payload |- | primes-sequence | 05 | 9(9) | DISPLAY | Sequence / ident of the current prime row |- | prime-number | 05 | 9(9) | DISPLAY | Value of the current prime |- | dal-result | 03 | 9(2) | DISPLAY | Result code written back by primes; initial value ZERO |- | — dal-method-ok | 88 | — | — | VALUE 0 — operation succeeded |- | — dal-method-nok | 88 | — | — | VALUE 1 — operation failed |- | — dal-method-eof | 88 | — | — | VALUE 99 — cursor exhausted |} ----- == 4. Copybook: primes-ui.cpy == '''Control block for the UI tier; included by all four programs.''' {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | primes-ui | 01 | — | — | Root of UI control block; passed as linkage to primesui |- | ui-methods | 03 | X(32) | DISPLAY | Operation verb set by caller |- | — write-ui | 88 | — | — | VALUE “write” — add one prime row to print buffer |- | — message-ui | 88 | — | — | VALUE “log-message” — display console message |- | — start-ui | 88 | — | — | VALUE “start” — open print file |- | — stop-ui | 88 | — | — | VALUE “stop” — flush and close print file |- | process-message | 03 | — | — | Structured console log record |- | program-name | 05 | X(20) | DISPLAY | Name of the calling program (for log messages) |- | program-line | 05 | — | — | Group: paragraph name + message text |- | program-paragraph | 07 | X(20) | DISPLAY | Name of the calling paragraph |- | program-message | 07 | X(92) | DISPLAY | Human-readable status or error message |- | u-primes | 03 | — | — | One prime row for the print writer |- | u-sequence | 05 | 9(9) | DISPLAY | Prime sequence number (ident) to print |- | u-number | 05 | 9(9) | DISPLAY | Prime value to print |- | ui-method-result | 03 | 9(2) | DISPLAY | Result code from primesui; initial value ZERO |- | — ui-method-ok | 88 | — | — | VALUE 0 — operation succeeded |- | — ui-method-nok | 88 | — | — | VALUE 1 — operation failed |} ----- == 5. Copybook: primes-table.cpy == '''SQL host variable — character (DISPLAY) format.''' {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | primes-table | 01 | — | — | Host variable group for SQL bind/into |- | ident | 03 | S9(9) | DISPLAY | Row identity (sequence number), signed |- | prime | 03 | S9(9) | DISPLAY | Prime value, signed |} ----- == 6. Copybook: primes_table.cpy == '''SQL host variable — packed-decimal (COMP-3) format. Alternate version of primes-table.cpy.''' {| ! Name ! Level ! Picture ! Usage ! Description |- | primes_table | 01 | — | — | Host variable group for SQL bind/into |- | ident | 03 | S9(9) | COMP-3 | Row identity, packed decimal |- | prime | 03 | S9(9) | COMP-3 | Prime value, packed decimal |} ----- == 7. Copybook: SQLCA.cpy == '''GixSQL SQL Communications Area — standard across all embedded-SQL programs.''' {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | SQLCA | 01 | — | — | SQL communications area |- | SQLCAID | 05 | X(8) | DISPLAY | SQLCA identifier string |- | SQLCABC | 05 | S9(9) | COMP-5 | Byte length of SQLCA |- | SQLCODE | 05 | S9(9) | COMP-5 | SQL return code: 0 = success, negative = error, +100 = not found |- | SQLERRM | 05 | — | — | Error message group |- | SQLERRML | 49 | S9(4) | COMP-5 | Length of error message text |- | SQLERRMC | 49 | X(70) | DISPLAY | Error message text |- | SQLERRP | 05 | X(8) | DISPLAY | Error program (not used) |- | SQLERRD | 05 | S9(9) OCCURS 6 | COMP-5 | Diagnostic codes; SQLERRD(3) = rows processed |- | SQLWARN | 05 | — | — | Warning flags group (not used) |- | SQLWARN0–SQLWARN7 | 10 | X(1) | DISPLAY | Individual warning flags |- | SQLSTATE | 05 | X(5) | DISPLAY | ANSI SQL state code |} ----- == 8. Program: primesmain — Working Storage == {| !width="16%"| Name !width="16%"| Level !width="16%"| Picture !width="16%"| Usage !width="16%"| Source !width="16%"| Description |- | filler | 01 | X(32) VALUE “Start WS primesmain” | DISPLAY | primesmain.cbl | Debug marker to locate WS in memory dump |- | commandline-args | 01 | X(32) | DISPLAY | primesmain.cbl | Command-line argument accepted from OS |- | — execute-generate | 88 | — | — | primesmain.cbl | VALUE “generate” |- | — execute-report | 88 | — | — | primesmain.cbl | VALUE “report” |- | primes-session | 01 | (group) | — | COPY | See §2 |- | primes-ui | 01 | (group) | — | COPY | See §4 |} ----- == 9. Program: primesgen — Working Storage == {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | filler | 01 | X(32) VALUE “Start WS primesgen” | DISPLAY | Debug WS marker |- | file-buffer | 01 | X(132) | DISPLAY | FD record area for fprinter (declared but file not opened in primesgen) |- | printer | 01 | — | — | Print control group (unused in primesgen; print handled by primesui) |- | print-buffer | 03 | X(132) | DISPLAY | Line buffer |- | line-number | 03 | 99 VALUE 99 | DISPLAY | Current line counter |- | page-number | 03 | 9(4) VALUE ZERO | DISPLAY | Current page counter |- | test-quot | 01 | 9(9) | DISPLAY | Quotient from DIVIDE in sieve loop |- | primes | 01 | — | — | Local sieve control group (mirrors primes-dal structure) |- | gen-methods | 03 | X(32) | DISPLAY | Method verb for internal DAL calls |- | — query-process | 88 | — | — | VALUE “query” |- | — start-process | 88 | — | — | VALUE “start” |- | — next-divider | 88 | — | — | VALUE “get” |- | — write-prime | 88 | — | — | VALUE “put” |- | — stop-process | 88 | — | — | VALUE “stop” |- | primes-result | 03 | 9(2) VALUE ZERO | DISPLAY | Result of sieve DAL call |- | — init-primes-ok | 88 | — | — | VALUE 1 |- | — first-divider-ok | 88 | — | — | VALUE 2 |- | — next-divider-ok | 88 | — | — | VALUE 3 |- | test-number | 03 | 9(9) | DISPLAY | Current candidate being tested for primality |- | test-number-sqr | 03 | 9(9)V9(9) | DISPLAY | Square root of test-number (decimal) |- | test-divider | 03 | 9(9) | DISPLAY | Current trial divisor fetched from DB |- | test-rest | 03 | 9(9)V9(9) | DISPLAY | Remainder from DIVIDE |- | old-test-number | 03 | 9(9) | DISPLAY | Previous test-number (diagnostic / unused) |- | old-ident | 03 | 9(9) | DISPLAY | ident of the last divider fetched; incremented before next fetch |- | new-ident | 03 | 9(9) | DISPLAY | old-ident + 1; used as key in SELECT to get next divider |- | primes-ui | 01 | (group) | — | COPY — see §4 |- | primes-dal | 01 | (group) | — | COPY — see §3 |} '''Linkage section:''' {| ! Name ! Source ! Description |- | primes-session | COPY primes-session | Passed in by primesmain |} ----- == 10. Program: primes (DAL) — Working Storage == {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | filler | 01 | X(32) VALUE “Start WS primes” | DISPLAY | Debug WS marker |- | DATASRC | 01 | X(64) VALUE “pgsql://localhost:5432/primes&default_schema=primes” | DISPLAY | GixSQL connection string |- | DBUSR | 01 | X(64) VALUE “primes_user” | DISPLAY | Database user name |- | DBPWD | 01 | X(64) VALUE “pr1mes_user” | DISPLAY | Database password (plain-text) |- | CUR-STEP | 01 | X(16) | DISPLAY | Diagnostic: current SQL step (“CONNECT” / “DISCONNECT”) |- | primes-row | 01 | — | — | FETCH target for cursor |- | r-ident | 03 | 9(9) | COMP-3 | Fetched ident value |- | r-prime | 03 | 9(9) | COMP-3 | Fetched prime value |- | prime-count | 01 | 9(9) | DISPLAY | (Unused in current flow) |- | prime_seq | 01 | 9(9) | DISPLAY | (Unused in current flow) |- | divider | 01 | 9(9) | DISPLAY | (Unused in current flow) |- | primes | 01 | — | — | Local copy of sieve control (mirrors primes-dal; used for internal paragraphs) |- | SQLCA | 01 | — | — | COPY SQLCA — see §7 |- | primes-table | 01 | — | — | EXEC SQL INCLUDE primes-table — see §5 |- | primes-ui | 01 | — | — | COPY primes-ui — see §4 |} '''Linkage section:''' {| ! Name ! Source ! Description |- | primes-dal | COPY primes-dal | Passed in by primesgen |} ----- == 11. Program: primesui — Working Storage == {| !width="20%"| Name !width="20%"| Level !width="20%"| Picture !width="20%"| Usage !width="20%"| Description |- | filler | 01 | X(32) VALUE “start ws primesui” | DISPLAY | Debug WS marker |- | primes-table | 01 | — | — | 6-column print accumulator (OCCURS 6) |- | primes-cel | 03 | OCCURS 6 INDEXED primes-idx | — | One cell per prime entry on a print line |- | t-ident | 05 | Z(9) | DISPLAY | Sequence number, zero-suppressed |- | filler | 05 | X(2) | DISPLAY | Column separator spaces |- | t-prime | 05 | Z(9) | DISPLAY | Prime value, zero-suppressed |- | filler | 05 | X(2) | DISPLAY | Column separator spaces |- | table-header | 01 | — | — | Heading row (OCCURS 6) — “Sequence Prime” × 6 |- | printer | 01 | — | — | Print control group |- | print-buffer | 03 | X(132) | DISPLAY | Current line being built |- | primes-prt-status | 03 | X(2) | DISPLAY | File-status code for fprinter |- | page-number | 03 | 9(4) VALUE 1 | DISPLAY | Current page number |- | print-new-page | 03 | 9 VALUE 1 | DISPLAY | Flag: 1 = new page needed |- | — new-page | 88 | — | — | VALUE 1 |- | primes-heading | 01 | X(118) VALUE “primes overview” | DISPLAY | Page heading text |- | primes-footing | 01 | — | — | Page footing group |- | filler | 03 | X(118) VALUE SPACE | DISPLAY | Left padding |- | filler | 03 | X(6) VALUE “page:” | DISPLAY | Label |- | f-page-number | 03 | Z(3)9 VALUE 1 | DISPLAY | Formatted page number |- | primes-line | 01 | — | — | (Declared but not used in current flow) |- | primes-total | 01 | — | — | (Declared but not used in current flow) |- | primes-count | 03 | 9(8) | DISPLAY | (Declared but not used in current flow) |} '''Linkage section:''' {| ! Name ! Source ! Description |- | primes-ui | COPY primes-ui | Passed in by all callers |} ----- == 12. Database Objects == {| !width="20%"| Object !width="20%"| Type !width="20%"| Schema !width="20%"| Owner !width="20%"| Definition |- | primes | Schema | — | primes_user | Container schema |- | asc_ident | Sequence | primes | primes_user | INTEGER, START 1, INCREMENT 1 |- | primes | Table | primes | primes_user | See below |- | primescursor | Cursor | runtime | — | DECLARE … CURSOR FOR SELECT * FROM primes |} === Table: primes.primes === {| !width="20%"| Column !width="20%"| Type !width="20%"| Nullable !width="20%"| Default !width="20%"| Description |- | ident | INTEGER | YES | nextval(‘primes.asc_ident’) | Auto-assigned insertion sequence |- | prime | INTEGER | YES | — | Prime number value |}
<blockquote>'''Document ID:''' PGCBL-DDD-001 · '''Version:''' 1.0 · '''Status:''' Approved · '''Last updated:''' 2026-03-17
</blockquote>
'''← [[Technical-Specification|Technical Specification]]''' | [[Flow-Diagrams|Flow Diagrams →]]


-----

<span id="contents"></span>
== Contents ==

# [[#conventions|Conventions]]
# [[#1-control-blocks-copybooks|Control Blocks — Copybooks]]
#* [[#11-primes-session|1.1 primes-session]]
#* [[#12-primes-dal|1.2 primes-dal]]
#* [[#13-primes-ui|1.3 primes-ui]]
#* [[#14-primes-table--sql-host-variable-character|1.4 primes-table (character)]]
#* [[#15-primes_table--sql-host-variable-packed|1.5 primes_table (packed)]]
#* [[#16-sqlca--sql-communications-area|1.6 SQLCA]]
# [[#2-working-storage-variables|Working-Storage Variables]]
#* [[#21-primesmain|2.1 primesmain]]
#* [[#22-primesgen|2.2 primesgen]]
#* [[#23-primes-dal|2.3 primes (DAL)]]
#* [[#24-primesui|2.4 primesui]]
# [[#3-database-objects|Database Objects]]
#* [[#31-schema-primes|3.1 Schema primes]]
#* [[#32-table-primesprimes|3.2 Table primes.primes]]
#* [[#33-sequence-asc_ident|3.3 Sequence asc_ident]]
#* [[#34-cursor-primescursor-runtime|3.4 Cursor primescursor]]


-----

<span id="conventions"></span>
== Conventions ==

{|
!width="50%"| Symbol
!width="50%"| Meaning
|-
| <code>PIC X(n)</code>
| Alphanumeric, n characters
|-
| <code>PIC 9(n)</code>
| Unsigned packed decimal display, n digits
|-
| <code>PIC S9(n)</code>
| Signed packed decimal display, n digits
|-
| <code>PIC 9(n)V9(m)</code>
| Unsigned numeric with m implied decimal places (no decimal point stored)
|-
| <code>PIC Z(n)</code>
| Zero-suppressed display numeric, n digits
|-
| <code>COMP-3</code>
| Packed-decimal binary storage (2 digits per byte + sign nibble)
|-
| <code>COMP-5</code>
| Native binary integer (platform word size)
|-
| <code>88</code>
| Condition-name — a boolean alias tested via <code>IF &lt;name&gt;</code> or <code>WHEN &lt;name&gt;</code>
|-
| <code>—</code>
| Not applicable (group item or 88-level)
|-
| ⚠️
| Known issue or deviation from standard
|}

'''Level hierarchy used in this codebase:'''

<pre>01 Group root
03 Sub-group or elementary item
05 Nested elementary item
07 Doubly-nested elementary item
49 Special level for variable-length groups (SQLERRM in SQLCA)
88 Condition-name (under any level)</pre>

-----

<span id="control-blocks-copybooks"></span>
== 1. Control Blocks — Copybooks ==

<span id="primes-session"></span>
=== 1.1 primes-session ===

<blockquote>'''Source file:''' <code>primes-session.cpy</code><br />
'''Included by:''' <code>primesmain.cbl</code> (WORKING-STORAGE) · <code>primesgen.cbl</code> (LINKAGE SECTION)<br />
'''Purpose:''' Session-tier control block. primesmain sets <code>methods</code>; primesgen reads it and sets <code>session-result</code>.
</blockquote>
{|
!width="16%"| Level
!width="16%"| Name
!width="16%"| PIC
!width="16%"| Usage
!width="16%"| Initial
!width="16%"| Description
|-
| 01
| <code>primes-session</code>
| —
| —
| —
| Root of session control block
|-
| 03
| <code>methods</code>
| <code>X(32)</code>
| DISPLAY
| —
| Method dispatch verb — set by primesmain before calling primesgen
|-
| 88
| <code>report-primes</code>
| —
| —
| <code>&quot;report&quot;</code>
| Run the cursor report path
|-
| 88
| <code>generate-primes</code>
| —
| —
| <code>&quot;generate&quot;</code>
| Run the sieve generation path
|-
| 88
| <code>start-primes</code>
| —
| —
| <code>&quot;start&quot;</code>
| Reserved — not used in current flow
|-
| 88
| <code>stop-primes</code>
| —
| —
| <code>&quot;stop&quot;</code>
| Reserved — not used in current flow
|-
| 88
| <code>invalid-method</code>
| —
| —
| <code>&quot;bad&quot;</code>
| Sentinel for unrecognised verb
|-
| 03
| <code>session-result</code>
| <code>9(2)</code>
| DISPLAY
| 0
| Outcome code written by primesgen
|-
| 88
| <code>session-method-ok</code>
| —
| —
| 0
| Operation succeeded
|-
| 88
| <code>session-method-nok</code>
| —
| —
| 1
| Operation failed
|-
| 88
| <code>session-method-eof</code>
| —
| —
| 9
| End of data (cursor exhausted)
|}

<blockquote>⚠️ <code>session-method-eof</code> (value 9) is never explicitly set in the current code. Fetch failure sets <code>session-result = 1</code> (nok), not 9. See [[Technical-Specification#7-known-technical-issues|Technical Specification — Defect T7]].
</blockquote>

-----

<span id="primes-dal"></span>
=== 1.2 primes-dal ===

<blockquote>'''Source file:''' <code>primes-dal.cpy</code><br />
'''Included by:''' <code>primesgen.cbl</code> (WORKING-STORAGE, caller) · <code>primes.cbl</code> (LINKAGE SECTION, callee)<br />
'''Purpose:''' DAL-tier control block. primesgen sets <code>dal-methods</code> and reads back <code>dal-result</code> and <code>primes-data</code>.
</blockquote>
{|
!width="16%"| Level
!width="16%"| Name
!width="16%"| PIC
!width="16%"| Usage
!width="16%"| Initial
!width="16%"| Description
|-
| 01
| <code>primes-dal</code>
| —
| —
| —
| Root of DAL control block
|-
| 03
| <code>dal-methods</code>
| <code>X(32)</code>
| DISPLAY
| —
| Method dispatch verb
|-
| 88
| <code>next-prime</code>
| —
| —
| <code>&quot;next-prime&quot;</code>
| Fetch next row from open cursor
|-
| 88
| <code>next-divider</code>
| —
| —
| <code>&quot;next-divider&quot;</code>
| SELECT a prime by ident for use as trial divisor
|-
| 88
| <code>write-prime</code>
| —
| —
| <code>&quot;write&quot;</code>
| INSERT a confirmed prime into the table
|-
| 88
| <code>db-cursor</code>
| —
| —
| <code>&quot;cursor&quot;</code>
| START TRANSACTION and OPEN primescursor
|-
| 88
| <code>db-connect</code>
| —
| —
| <code>&quot;connect&quot;</code>
| Establish the PostgreSQL connection
|-
| 88
| <code>db-disconnect</code>
| —
| —
| <code>&quot;disconnect&quot;</code>
| Release the connection
|-
| 88
| <code>invalid-method</code>
| —
| —
| <code>&quot;bad&quot;</code>
| Sentinel for unrecognised verb
|-
| 03
| <code>primes-data</code>
| —
| —
| —
| Single-row data payload (one prime)
|-
| 05
| <code>primes-sequence</code>
| <code>9(9)</code>
| DISPLAY
| —
| Row identity (<code>ident</code>) of the fetched prime
|-
| 05
| <code>prime-number</code>
| <code>9(9)</code>
| DISPLAY
| —
| The prime value itself
|-
| 03
| <code>dal-result</code>
| <code>9(2)</code>
| DISPLAY
| 0
| Outcome code written by primes
|-
| 88
| <code>dal-method-ok</code>
| —
| —
| 0
| Operation succeeded
|-
| 88
| <code>dal-method-nok</code>
| —
| —
| 1
| Operation failed
|-
| 88
| <code>dal-method-eof</code>
| —
| —
| 99
| Cursor exhausted (no more rows)
|}


-----

<span id="primes-ui"></span>
=== 1.3 primes-ui ===

<blockquote>'''Source file:''' <code>primes-ui.cpy</code><br />
'''Included by:''' all four programs<br />
'''Purpose:''' UI-tier control block. Any program sets <code>ui-methods</code> and <code>process-message</code> / <code>u-primes</code>, then calls primesui; primesui sets <code>ui-method-result</code>.
</blockquote>
{|
!width="16%"| Level
!width="16%"| Name
!width="16%"| PIC
!width="16%"| Usage
!width="16%"| Initial
!width="16%"| Description
|-
| 01
| <code>primes-ui</code>
| —
| —
| —
| Root of UI control block
|-
| 03
| <code>ui-methods</code>
| <code>X(32)</code>
| DISPLAY
| —
| Method dispatch verb
|-
| 88
| <code>write-ui</code>
| —
| —
| <code>&quot;write&quot;</code>
| Add one prime row to the print buffer
|-
| 88
| <code>message-ui</code>
| —
| —
| <code>&quot;log-message&quot;</code>
| Write <code>process-message</code> to the console
|-
| 88
| <code>start-ui</code>
| —
| —
| <code>&quot;start&quot;</code>
| Open <code>primes.prt</code>
|-
| 88
| <code>stop-ui</code>
| —
| —
| <code>&quot;stop&quot;</code>
| Flush print buffer and close file
|-
| 03
| <code>process-message</code>
| —
| —
| —
| Structured 132-char console log record
|-
| 05
| <code>program-name</code>
| <code>X(20)</code>
| DISPLAY
| —
| Name of the calling program
|-
| 05
| <code>program-line</code>
| —
| —
| —
| Location within the calling program
|-
| 07
| <code>program-paragraph</code>
| <code>X(20)</code>
| DISPLAY
| —
| Name of the calling paragraph
|-
| 07
| <code>program-message</code>
| <code>X(92)</code>
| DISPLAY
| —
| Human-readable status or error text
|-
| 03
| <code>u-primes</code>
| —
| —
| —
| One prime row for the print writer
|-
| 05
| <code>u-sequence</code>
| <code>9(9)</code>
| DISPLAY
| —
| Sequence number (ident) to write to print buffer
|-
| 05
| <code>u-number</code>
| <code>9(9)</code>
| DISPLAY
| —
| Prime value to write to print buffer
|-
| 03
| <code>ui-method-result</code>
| <code>9(2)</code>
| DISPLAY
| 0
| Outcome code written by primesui
|-
| 88
| <code>ui-method-ok</code>
| —
| —
| 0
| Operation succeeded
|-
| 88
| <code>ui-method-nok</code>
| —
| —
| 1
| Operation failed
|}

'''Console message layout''' (132 characters, left-to-right):

<pre>┌──────────────────────┬──────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐
│ program-name (20) │ program-paragraph(20)│ program-message (92) │
└──────────────────────┴──────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘</pre>

-----

<span id="primes-table-sql-host-variable-character"></span>
=== 1.4 primes-table — SQL Host Variable (character) ===

<blockquote>'''Source file:''' <code>primes-table.cpy</code><br />
'''Included by:''' <code>primes.cbl</code> via <code>EXEC SQL INCLUDE primes-table END-EXEC</code><br />
'''Purpose:''' Host variable layout for GixSQL to bind the <code>primes.primes</code> table columns.
</blockquote>
{|
!width="20%"| Level
!width="20%"| Name
!width="20%"| PIC
!width="20%"| Usage
!width="20%"| Description
|-
| 01
| <code>primes-table</code>
| —
| —
| Host variable group (character format)
|-
| 03
| <code>ident</code>
| <code>S9(9)</code>
| DISPLAY
| Maps to <code>primes.ident</code>; signed for SQL compatibility
|-
| 03
| <code>prime</code>
| <code>S9(9)</code>
| DISPLAY
| Maps to <code>primes.prime</code>; signed for SQL compatibility
|}


-----

<span id="primes_table-sql-host-variable-packed"></span>
=== 1.5 primes_table — SQL Host Variable (packed) ===

<blockquote>'''Source file:''' <code>primes_table.cpy</code><br />
'''Included by:''' <code>primes.cbl</code> (alternative layout)<br />
'''Purpose:''' COMP-3 variant of <code>primes-table</code>. The underscore in both the filename and root name is a deviation from the project’s hyphen convention.
</blockquote>
{|
! Level
! Name
! PIC
! Usage
! Description
|-
| 01
| <code>primes_table</code>
| —
| —
| Host variable group (COMP-3 format)
|-
| 03
| <code>ident</code>
| <code>S9(9)</code>
| COMP-3
| Row identity — packed decimal
|-
| 03
| <code>prime</code>
| <code>S9(9)</code>
| COMP-3
| Prime value — packed decimal
|}

<blockquote>⚠️ Two nearly identical copybooks exist. <code>primes-table.cpy</code> (hyphens, DISPLAY) is used by the cursor FETCH target (<code>primes-row</code>). The canonical version should be designated and the other retired. See [[Technical-Specification#7-known-technical-issues|Technical Specification — Defect T6]].
</blockquote>

-----

<span id="sqlca-sql-communications-area"></span>
=== 1.6 SQLCA — SQL Communications Area ===

<blockquote>'''Source file:''' <code>SQLCA.cpy</code><br />
'''Included by:''' <code>primes.cbl</code> via <code>EXEC SQL INCLUDE SQLCA END-EXEC</code><br />
'''Purpose:''' Standard GixSQL communications area. Updated after every SQL statement.
</blockquote>
{|
!width="20%"| Level
!width="20%"| Name
!width="20%"| PIC
!width="20%"| Usage
!width="20%"| Description
|-
| 01
| <code>SQLCA</code>
| —
| —
| SQL communications area
|-
| 05
| <code>SQLCAID</code>
| <code>X(8)</code>
| DISPLAY
| SQLCA identifier string
|-
| 05
| <code>SQLCABC</code>
| <code>S9(9)</code>
| COMP-5
| Byte length of SQLCA structure
|-
| 05
| <code>SQLCODE</code>
| <code>S9(9)</code>
| COMP-5
| '''SQL return code:''' 0=success · negative=error · +100=not found
|-
| 05
| <code>SQLERRM</code>
| —
| —
| Error message group
|-
| 49
| <code>SQLERRML</code>
| <code>S9(4)</code>
| COMP-5
| Length of error message text
|-
| 49
| <code>SQLERRMC</code>
| <code>X(70)</code>
| DISPLAY
| Error message text from the database engine
|-
| 05
| <code>SQLERRP</code>
| <code>X(8)</code>
| DISPLAY
| Error procedure name (not used in this application)
|-
| 05
| <code>SQLERRD</code>
| <code>S9(9)</code> OCCURS 6
| COMP-5
| Diagnostic array; <code>SQLERRD(3)</code> = number of rows processed
|-
| 05
| <code>SQLWARN</code>
| —
| —
| Warning flags group (not used in this application)
|-
| 05
| <code>SQLSTATE</code>
| <code>X(5)</code>
| DISPLAY
| ISO/ANSI SQL state code (5-char string)
|}

'''SQLCODE reference (PostgreSQL / GixSQL):'''

{|
! Value
! Meaning
|-
| 0
| Statement succeeded
|-
| +100
| No rows found (SELECT returned empty, cursor exhausted)
|-
| negative
| Database error — see <code>SQLERRMC</code> for description
|}


-----

<span id="working-storage-variables"></span>
== 2. Working-Storage Variables ==

<span id="primesmain"></span>
=== 2.1 primesmain ===

<blockquote>'''Source:''' <code>primesmain.cbl</code> WORKING-STORAGE SECTION<br />
'''Copybooks included:''' <code>primes-session</code> · <code>primes-ui</code>
</blockquote>
{|
!width="20%"| Name
!width="20%"| PIC
!width="20%"| Usage
!width="20%"| Initial
!width="20%"| Description
|-
| <code>filler</code>
| <code>X(32)</code>
| DISPLAY
| <code>&quot;Start WS primesmain&quot;</code>
| Debug marker — locates WS start in memory dumps
|-
| <code>commandline-args</code>
| <code>X(32)</code>
| DISPLAY
| —
| Command-line argument from <code>ACCEPT … FROM COMMAND-LINE</code>
|-
| <code>execute-generate</code> (88)
| —
| —
| <code>&quot;generate&quot;</code>
| True when commandline-args = “generate”
|-
| <code>execute-report</code> (88)
| —
| —
| <code>&quot;report&quot;</code>
| True when commandline-args = “report”
|-
| <code>primes-session</code>
| (group)
| —
| —
| COPY primes-session — see [[#11-primes-session|§1.1]]
|-
| <code>primes-ui</code>
| (group)
| —
| —
| COPY primes-ui — see [[#13-primes-ui|§1.3]]
|}


-----

<span id="primesgen"></span>
=== 2.2 primesgen ===

<blockquote>'''Source:''' <code>primesgen.cbl</code> WORKING-STORAGE SECTION<br />
'''Copybooks included:''' <code>primes-ui</code> (WS) · <code>primes-dal</code> (WS) · <code>primes-session</code> (LINKAGE)
</blockquote>
'''Print control group (unused — print handled by primesui):'''

{|
!width="25%"| Name
!width="25%"| PIC
!width="25%"| Initial
!width="25%"| Description
|-
| <code>file-buffer</code>
| <code>X(132)</code>
| —
| FD record area for fprinter — declared but file never opened here ⚠️
|-
| <code>print-buffer</code>
| <code>X(132)</code>
| —
| Working print line buffer
|-
| <code>line-number</code>
| <code>99</code>
| 99
| Current line within page
|-
| <code>page-number</code>
| <code>9999</code>
| 0
| Current page number
|}

'''Sieve control group (01 <code>primes</code>, local to primesgen):'''

{|
!width="25%"| Name
!width="25%"| PIC
!width="25%"| Initial
!width="25%"| Description
|-
| <code>gen-methods</code>
| <code>X(32)</code>
| —
| Verb for the local <code>primes</code> group calls to primes.cbl
|-
| <code>query-process</code> (88)
| —
| <code>&quot;query&quot;</code>
| Internal: query
|-
| <code>start-process</code> (88)
| —
| <code>&quot;start&quot;</code>
| Internal: start
|-
| <code>next-divider</code> (88)
| —
| <code>&quot;get&quot;</code>
| Internal: fetch next divider
|-
| <code>write-prime</code> (88)
| —
| <code>&quot;put&quot;</code>
| Internal: write prime
|-
| <code>stop-process</code> (88)
| —
| <code>&quot;stop&quot;</code>
| Internal: stop
|-
| <code>primes-result</code>
| <code>9(2)</code>
| 0
| Internal result code for local DAL calls
|-
| <code>init-primes-ok</code> (88)
| —
| 1
| Initialisation succeeded
|-
| <code>first-divider-ok</code> (88)
| —
| 2
| First divisor retrieved
|-
| <code>next-divider-ok</code> (88)
| —
| 3
| Next divisor retrieved
|-
| <code>test-number</code>
| <code>9(9)</code>
| —
| '''Current candidate being tested for primality'''
|-
| <code>test-number-sqr</code>
| <code>9(9)V9(9)</code>
| —
| Square root of <code>test-number</code> — upper bound for divisors
|-
| <code>test-divider</code>
| <code>9(9)</code>
| —
| Current trial divisor (prime fetched from DB)
|-
| <code>test-rest</code>
| <code>9(9)V9(9)</code>
| —
| Remainder: <code>test-number MOD test-divider</code>
|-
| <code>old-test-number</code>
| <code>9(9)</code>
| —
| Previous candidate — diagnostic use only, not active
|-
| <code>old-ident</code>
| <code>9(9)</code>
| —
| DB <code>ident</code> of the most recently fetched divisor
|-
| <code>new-ident</code>
| <code>9(9)</code>
| —
| <code>old-ident + 1</code> — used as key for the next divider SELECT
|}

'''Other:'''

{|
!width="25%"| Name
!width="25%"| PIC
!width="25%"| Initial
!width="25%"| Description
|-
| <code>test-quot</code>
| <code>9(9)</code>
| —
| Integer quotient from <code>DIVIDE test-number BY test-divider</code>
|}


-----

<span id="primes-dal-1"></span>
=== 2.3 primes (DAL) ===

<blockquote>'''Source:''' <code>primes.cbl</code> WORKING-STORAGE SECTION<br />
'''Copybooks included:''' <code>primes-ui</code> (WS) · <code>SQLCA</code> (via EXEC SQL INCLUDE) · <code>primes-table</code> (via EXEC SQL INCLUDE) · <code>primes-dal</code> (LINKAGE)
</blockquote>
'''Database credentials:'''

{|
!width="25%"| Name
!width="25%"| PIC
!width="25%"| Initial
!width="25%"| Description
|-
| <code>DATASRC</code>
| <code>X(64)</code>
| <code>&quot;pgsql://localhost:5432/primes&amp;default_schema=primes&quot;</code>
| GixSQL connection string ⚠️ hard-coded
|-
| <code>DBUSR</code>
| <code>X(64)</code>
| <code>&quot;primes_user&quot;</code>
| Database user name ⚠️ hard-coded
|-
| <code>DBPWD</code>
| <code>X(64)</code>
| <code>&quot;pr1mes_user&quot;</code>
| Database password ⚠️ hard-coded in plain text
|-
| <code>CUR-STEP</code>
| <code>X(16)</code>
| —
| Diagnostic step label (<code>&quot;CONNECT&quot;</code> / <code>&quot;DISCONNECT&quot;</code>)
|}

'''Cursor fetch buffer:'''

{|
!width="25%"| Name
!width="25%"| PIC
!width="25%"| Usage
!width="25%"| Description
|-
| <code>primes-row</code>
| (group)
| —
| Target group for <code>FETCH primescursor INTO :primes-row</code>
|-
| <code>r-ident</code>
| <code>9(9)</code>
| COMP-3
| Fetched row identity value
|-
| <code>r-prime</code>
| <code>9(9)</code>
| COMP-3
| Fetched prime value
|}

'''Unused declarations:'''

{|
! Name
! PIC
! Note
|-
| <code>prime-count</code>
| <code>9(9)</code>
| Declared; not written to in current flow
|-
| <code>prime_seq</code>
| <code>9(9)</code>
| Declared; not written to
|-
| <code>divider</code>
| <code>9(9)</code>
| Declared; not written to
|}

'''Local sieve control group (01 <code>primes</code>, mirrors primesgen layout):'''

Mirrors the <code>01 primes</code> group in primesgen. Contains <code>test-divider</code>, <code>old-ident</code>, <code>new-ident</code> etc., used internally by <code>r81-get-next-divider</code>. See [[#22-primesgen|§2.2]] for field descriptions.


-----

<span id="primesui"></span>
=== 2.4 primesui ===

<blockquote>'''Source:''' <code>primesui.cbl</code> WORKING-STORAGE SECTION<br />
'''Copybooks included:''' <code>primes-ui</code> (LINKAGE)
</blockquote>
'''Print row buffer:'''

{|
!width="20%"| Name
!width="20%"| PIC
!width="20%"| Usage
!width="20%"| Initial
!width="20%"| Description
|-
| <code>primes-table</code> (01)
| —
| —
| —
| 6-element row accumulator
|-
| <code>primes-cel</code>
| OCCURS 6 INDEXED <code>primes-idx</code>
| —
| —
| One cell = one prime entry in the output line
|-
| <code>t-ident</code>
| <code>Z(9)</code>
| DISPLAY
| —
| Zero-suppressed sequence number for this cell
|-
| filler
| <code>X(2)</code>
| DISPLAY
| spaces
| Column separator
|-
| <code>t-prime</code>
| <code>Z(9)</code>
| DISPLAY
| —
| Zero-suppressed prime value for this cell
|-
| filler
| <code>X(2)</code>
| DISPLAY
| spaces
| Column separator
|-
| <code>primes-idx</code>
| INDEX
| —
| —
| Current cell position (1–6); set by <code>SET primes-idx</code>
|}

'''Column header:'''

{|
!width="33%"| Name
!width="33%"| PIC
!width="33%"| Description
|-
| <code>table-header</code> (01)
| OCCURS 6
| Static header row — <code>&quot;Sequence Prime &quot;</code> repeated 6 times
|}

'''Print control:'''

{|
!width="20%"| Name
!width="20%"| PIC
!width="20%"| Usage
!width="20%"| Initial
!width="20%"| Description
|-
| <code>print-buffer</code>
| <code>X(132)</code>
| DISPLAY
| —
| Working buffer written to <code>fprinter</code>
|-
| <code>primes-prt-status</code>
| <code>X(2)</code>
| DISPLAY
| —
| File status from last <code>fprinter</code> operation
|-
| <code>page-number</code>
| <code>9(4)</code>
| DISPLAY
| 1
| Current page number
|-
| <code>print-new-page</code>
| <code>9</code>
| DISPLAY
| 1
| New-page flag — 1 = heading must be written
|-
| <code>new-page</code> (88)
| —
| —
| 1
| True when <code>print-new-page = 1</code>
|}

'''Static strings:'''

{|
!width="25%"| Name
!width="25%"| PIC
!width="25%"| Value
!width="25%"| Description
|-
| <code>primes-heading</code>
| <code>X(118)</code>
| <code>&quot;primes overview&quot;</code>
| Left-justified page heading text
|-
| <code>primes-footing</code>
| (group)
| —
| Page footer group
|-
| filler
| <code>X(118)</code>
| SPACE
| Left padding of footer
|-
| filler
| <code>X(6)</code>
| <code>&quot;page: &quot;</code>
| Footer label
|-
| <code>f-page-number</code>
| <code>Z(3)9</code>
| 1
| Formatted page number (zero-suppressed 4-digit)
|}

'''Unused:'''

{|
! Name
! PIC
! Note
|-
| <code>primes-line</code>
| <code>X(132)</code>
| Declared; not written to in current flow
|-
| <code>primes-count</code>
| <code>9(8)</code>
| Declared; not used
|}


-----

<span id="database-objects"></span>
== 3. Database Objects ==

<span id="schema-primes"></span>
=== 3.1 Schema <code>primes</code> ===

{|
!width="25%"| Object
!width="25%"| Type
!width="25%"| Owner
!width="25%"| Description
|-
| <code>primes</code>
| SCHEMA
| <code>primes_user</code>
| Container schema for all application objects
|-
| <code>asc_ident</code>
| SEQUENCE
| <code>primes_user</code>
| Auto-incrementing identity for <code>primes.ident</code>
|-
| <code>primes.primes</code>
| TABLE
| <code>primes_user</code>
| The prime numbers store
|}


-----

<span id="table-primes.primes"></span>
=== 3.2 Table <code>primes.primes</code> ===

<blockquote>'''DDL source:''' <code>primes_schema.sql</code>
</blockquote>
<syntaxhighlight lang="sql">CREATE TABLE primes.primes (
ident integer DEFAULT nextval('primes.asc_ident'::regclass),
prime integer
);</syntaxhighlight>
{|
!width="20%"| Column
!width="20%"| Data type
!width="20%"| Nullable
!width="20%"| Default
!width="20%"| Description
|-
| <code>ident</code>
| INTEGER
| YES
| <code>nextval('primes.asc_ident')</code>
| Auto-assigned insertion sequence; acts as primary key but has no formal PK constraint
|-
| <code>prime</code>
| INTEGER
| YES
| —
| The prime number value
|}

<blockquote>⚠️ No PRIMARY KEY, UNIQUE constraint, or index is defined on either column. The <code>ident</code> column is the key used by <code>r81-get-next-divider</code> (<code>SELECT prime WHERE ident = :new-ident</code>). Without an index, this is a sequential scan. See [[Technical-Specification#7-known-technical-issues|Technical Specification — Defect T5]] (performance concern).
</blockquote>

-----

<span id="sequence-primes.asc_ident"></span>
=== 3.3 Sequence <code>primes.asc_ident</code> ===

{|
! Attribute
! Value
|-
| Data type
| INTEGER
|-
| Start value
| 1
|-
| Increment
| 1
|-
| Minimum
| 1 (default)
|-
| Maximum
| 2,147,483,647 (INTEGER max)
|-
| Cache
| 1
|-
| Cycle
| No
|}


-----

<span id="cursor-primescursor-runtime"></span>
=== 3.4 Cursor <code>primescursor</code> (runtime) ===

<blockquote>Declared at compile time in <code>primes.cbl</code>. Opened and used only in the '''report path'''.
</blockquote>
{|
!width="50%"| Attribute
!width="50%"| Value
|-
| Declaration
| <code>DECLARE primescursor CURSOR FOR SELECT * FROM primes</code>
|-
| Connection alias
| <code>primes</code>
|-
| Declared at
| Compile time in <code>primes.cbl</code>
|-
| Transaction
| Opened inside <code>START TRANSACTION</code> in <code>s01-cursor</code>
|-
| Opened at
| <code>s01-cursor</code> paragraph (<code>EXEC SQL OPEN primescursor</code>)
|-
| Fetch target
| <code>primes-row</code> group (<code>r-ident</code>, <code>r-prime</code>) — COMP-3 fields
|-
| Close
| Not explicit; closed implicitly when <code>CONNECT RESET primes</code> is issued
|}

<blockquote>⚠️ <code>SELECT * FROM primes</code> is used. Best practice is to name columns explicitly (<code>SELECT ident, prime FROM primes</code>) to guard against schema changes. The pre-compiler listing (<code>primes_cbsql.out</code>) shows this was expanded from a <code>SELECT ident, prime</code> form in an earlier version.
</blockquote>

-----

'''← [[Technical-Specification|Technical Specification]]''' | [[Flow-Diagrams|Flow Diagrams →]]

Latest revision as of 22:57, 24 March 2026

Data Dictionary[edit]

Document ID: PGCBL-DDD-001 · Version: 1.0 · Status: Approved · Last updated: 2026-03-17

Technical Specification | Flow Diagrams →



Contents[edit]

  1. Conventions
  2. Control Blocks — Copybooks
  3. Working-Storage Variables
  4. Database Objects



Conventions[edit]

Symbol Meaning
PIC X(n) Alphanumeric, n characters
PIC 9(n) Unsigned packed decimal display, n digits
PIC S9(n) Signed packed decimal display, n digits
PIC 9(n)V9(m) Unsigned numeric with m implied decimal places (no decimal point stored)
PIC Z(n) Zero-suppressed display numeric, n digits
COMP-3 Packed-decimal binary storage (2 digits per byte + sign nibble)
COMP-5 Native binary integer (platform word size)
88 Condition-name — a boolean alias tested via IF <name> or WHEN <name>
Not applicable (group item or 88-level)
⚠️ Known issue or deviation from standard

Level hierarchy used in this codebase:

01  Group root
 03  Sub-group or elementary item
  05  Nested elementary item
   07  Doubly-nested elementary item
   49  Special level for variable-length groups (SQLERRM in SQLCA)
88  Condition-name (under any level)

1. Control Blocks — Copybooks[edit]

1.1 primes-session[edit]

Source file: primes-session.cpy

Included by: primesmain.cbl (WORKING-STORAGE) · primesgen.cbl (LINKAGE SECTION)
Purpose: Session-tier control block. primesmain sets methods; primesgen reads it and sets session-result.

Level Name PIC Usage Initial Description
01 primes-session Root of session control block
03 methods X(32) DISPLAY Method dispatch verb — set by primesmain before calling primesgen
88 report-primes "report" Run the cursor report path
88 generate-primes "generate" Run the sieve generation path
88 start-primes "start" Reserved — not used in current flow
88 stop-primes "stop" Reserved — not used in current flow
88 invalid-method "bad" Sentinel for unrecognised verb
03 session-result 9(2) DISPLAY 0 Outcome code written by primesgen
88 session-method-ok 0 Operation succeeded
88 session-method-nok 1 Operation failed
88 session-method-eof 9 End of data (cursor exhausted)

⚠️ session-method-eof (value 9) is never explicitly set in the current code. Fetch failure sets session-result = 1 (nok), not 9. See Technical Specification — Defect T7.


1.2 primes-dal[edit]

Source file: primes-dal.cpy

Included by: primesgen.cbl (WORKING-STORAGE, caller) · primes.cbl (LINKAGE SECTION, callee)
Purpose: DAL-tier control block. primesgen sets dal-methods and reads back dal-result and primes-data.

Level Name PIC Usage Initial Description
01 primes-dal Root of DAL control block
03 dal-methods X(32) DISPLAY Method dispatch verb
88 next-prime "next-prime" Fetch next row from open cursor
88 next-divider "next-divider" SELECT a prime by ident for use as trial divisor
88 write-prime "write" INSERT a confirmed prime into the table
88 db-cursor "cursor" START TRANSACTION and OPEN primescursor
88 db-connect "connect" Establish the PostgreSQL connection
88 db-disconnect "disconnect" Release the connection
88 invalid-method "bad" Sentinel for unrecognised verb
03 primes-data Single-row data payload (one prime)
05 primes-sequence 9(9) DISPLAY Row identity (ident) of the fetched prime
05 prime-number 9(9) DISPLAY The prime value itself
03 dal-result 9(2) DISPLAY 0 Outcome code written by primes
88 dal-method-ok 0 Operation succeeded
88 dal-method-nok 1 Operation failed
88 dal-method-eof 99 Cursor exhausted (no more rows)



1.3 primes-ui[edit]

Source file: primes-ui.cpy

Included by: all four programs
Purpose: UI-tier control block. Any program sets ui-methods and process-message / u-primes, then calls primesui; primesui sets ui-method-result.

Level Name PIC Usage Initial Description
01 primes-ui Root of UI control block
03 ui-methods X(32) DISPLAY Method dispatch verb
88 write-ui "write" Add one prime row to the print buffer
88 message-ui "log-message" Write process-message to the console
88 start-ui "start" Open primes.prt
88 stop-ui "stop" Flush print buffer and close file
03 process-message Structured 132-char console log record
05 program-name X(20) DISPLAY Name of the calling program
05 program-line Location within the calling program
07 program-paragraph X(20) DISPLAY Name of the calling paragraph
07 program-message X(92) DISPLAY Human-readable status or error text
03 u-primes One prime row for the print writer
05 u-sequence 9(9) DISPLAY Sequence number (ident) to write to print buffer
05 u-number 9(9) DISPLAY Prime value to write to print buffer
03 ui-method-result 9(2) DISPLAY 0 Outcome code written by primesui
88 ui-method-ok 0 Operation succeeded
88 ui-method-nok 1 Operation failed

Console message layout (132 characters, left-to-right):

┌──────────────────────┬──────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐
│  program-name (20)   │ program-paragraph(20)│  program-message (92)                                                                      │
└──────────────────────┴──────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘

1.4 primes-table — SQL Host Variable (character)[edit]

Source file: primes-table.cpy

Included by: primes.cbl via EXEC SQL INCLUDE primes-table END-EXEC
Purpose: Host variable layout for GixSQL to bind the primes.primes table columns.

Level Name PIC Usage Description
01 primes-table Host variable group (character format)
03 ident S9(9) DISPLAY Maps to primes.ident; signed for SQL compatibility
03 prime S9(9) DISPLAY Maps to primes.prime; signed for SQL compatibility



1.5 primes_table — SQL Host Variable (packed)[edit]

Source file: primes_table.cpy

Included by: primes.cbl (alternative layout)
Purpose: COMP-3 variant of primes-table. The underscore in both the filename and root name is a deviation from the project’s hyphen convention.

Level Name PIC Usage Description
01 primes_table Host variable group (COMP-3 format)
03 ident S9(9) COMP-3 Row identity — packed decimal
03 prime S9(9) COMP-3 Prime value — packed decimal

⚠️ Two nearly identical copybooks exist. primes-table.cpy (hyphens, DISPLAY) is used by the cursor FETCH target (primes-row). The canonical version should be designated and the other retired. See Technical Specification — Defect T6.


1.6 SQLCA — SQL Communications Area[edit]

Source file: SQLCA.cpy

Included by: primes.cbl via EXEC SQL INCLUDE SQLCA END-EXEC
Purpose: Standard GixSQL communications area. Updated after every SQL statement.

Level Name PIC Usage Description
01 SQLCA SQL communications area
05 SQLCAID X(8) DISPLAY SQLCA identifier string
05 SQLCABC S9(9) COMP-5 Byte length of SQLCA structure
05 SQLCODE S9(9) COMP-5 SQL return code: 0=success · negative=error · +100=not found
05 SQLERRM Error message group
49 SQLERRML S9(4) COMP-5 Length of error message text
49 SQLERRMC X(70) DISPLAY Error message text from the database engine
05 SQLERRP X(8) DISPLAY Error procedure name (not used in this application)
05 SQLERRD S9(9) OCCURS 6 COMP-5 Diagnostic array; SQLERRD(3) = number of rows processed
05 SQLWARN Warning flags group (not used in this application)
05 SQLSTATE X(5) DISPLAY ISO/ANSI SQL state code (5-char string)

SQLCODE reference (PostgreSQL / GixSQL):

Value Meaning
0 Statement succeeded
+100 No rows found (SELECT returned empty, cursor exhausted)
negative Database error — see SQLERRMC for description



2. Working-Storage Variables[edit]

2.1 primesmain[edit]

Source: primesmain.cbl WORKING-STORAGE SECTION

Copybooks included: primes-session · primes-ui

Name PIC Usage Initial Description
filler X(32) DISPLAY "Start WS primesmain" Debug marker — locates WS start in memory dumps
commandline-args X(32) DISPLAY Command-line argument from ACCEPT … FROM COMMAND-LINE
execute-generate (88) "generate" True when commandline-args = “generate”
execute-report (88) "report" True when commandline-args = “report”
primes-session (group) COPY primes-session — see §1.1
primes-ui (group) COPY primes-ui — see §1.3



2.2 primesgen[edit]

Source: primesgen.cbl WORKING-STORAGE SECTION

Copybooks included: primes-ui (WS) · primes-dal (WS) · primes-session (LINKAGE)

Print control group (unused — print handled by primesui):

Name PIC Initial Description
file-buffer X(132) FD record area for fprinter — declared but file never opened here ⚠️
print-buffer X(132) Working print line buffer
line-number 99 99 Current line within page
page-number 9999 0 Current page number

Sieve control group (01 primes, local to primesgen):

Name PIC Initial Description
gen-methods X(32) Verb for the local primes group calls to primes.cbl
query-process (88) "query" Internal: query
start-process (88) "start" Internal: start
next-divider (88) "get" Internal: fetch next divider
write-prime (88) "put" Internal: write prime
stop-process (88) "stop" Internal: stop
primes-result 9(2) 0 Internal result code for local DAL calls
init-primes-ok (88) 1 Initialisation succeeded
first-divider-ok (88) 2 First divisor retrieved
next-divider-ok (88) 3 Next divisor retrieved
test-number 9(9) Current candidate being tested for primality
test-number-sqr 9(9)V9(9) Square root of test-number — upper bound for divisors
test-divider 9(9) Current trial divisor (prime fetched from DB)
test-rest 9(9)V9(9) Remainder: test-number MOD test-divider
old-test-number 9(9) Previous candidate — diagnostic use only, not active
old-ident 9(9) DB ident of the most recently fetched divisor
new-ident 9(9) old-ident + 1 — used as key for the next divider SELECT

Other:

Name PIC Initial Description
test-quot 9(9) Integer quotient from DIVIDE test-number BY test-divider



2.3 primes (DAL)[edit]

Source: primes.cbl WORKING-STORAGE SECTION

Copybooks included: primes-ui (WS) · SQLCA (via EXEC SQL INCLUDE) · primes-table (via EXEC SQL INCLUDE) · primes-dal (LINKAGE)

Database credentials:

Name PIC Initial Description
DATASRC X(64) "pgsql://localhost:5432/primes&default_schema=primes" GixSQL connection string ⚠️ hard-coded
DBUSR X(64) "primes_user" Database user name ⚠️ hard-coded
DBPWD X(64) "pr1mes_user" Database password ⚠️ hard-coded in plain text
CUR-STEP X(16) Diagnostic step label ("CONNECT" / "DISCONNECT")

Cursor fetch buffer:

Name PIC Usage Description
primes-row (group) Target group for FETCH primescursor INTO :primes-row
r-ident 9(9) COMP-3 Fetched row identity value
r-prime 9(9) COMP-3 Fetched prime value

Unused declarations:

Name PIC Note
prime-count 9(9) Declared; not written to in current flow
prime_seq 9(9) Declared; not written to
divider 9(9) Declared; not written to

Local sieve control group (01 primes, mirrors primesgen layout):

Mirrors the 01 primes group in primesgen. Contains test-divider, old-ident, new-ident etc., used internally by r81-get-next-divider. See §2.2 for field descriptions.



2.4 primesui[edit]

Source: primesui.cbl WORKING-STORAGE SECTION

Copybooks included: primes-ui (LINKAGE)

Print row buffer:

Name PIC Usage Initial Description
primes-table (01) 6-element row accumulator
primes-cel OCCURS 6 INDEXED primes-idx One cell = one prime entry in the output line
t-ident Z(9) DISPLAY Zero-suppressed sequence number for this cell
filler X(2) DISPLAY spaces Column separator
t-prime Z(9) DISPLAY Zero-suppressed prime value for this cell
filler X(2) DISPLAY spaces Column separator
primes-idx INDEX Current cell position (1–6); set by SET primes-idx

Column header:

Name PIC Description
table-header (01) OCCURS 6 Static header row — "Sequence Prime " repeated 6 times

Print control:

Name PIC Usage Initial Description
print-buffer X(132) DISPLAY Working buffer written to fprinter
primes-prt-status X(2) DISPLAY File status from last fprinter operation
page-number 9(4) DISPLAY 1 Current page number
print-new-page 9 DISPLAY 1 New-page flag — 1 = heading must be written
new-page (88) 1 True when print-new-page = 1

Static strings:

Name PIC Value Description
primes-heading X(118) "primes overview" Left-justified page heading text
primes-footing (group) Page footer group
filler X(118) SPACE Left padding of footer
filler X(6) "page: " Footer label
f-page-number Z(3)9 1 Formatted page number (zero-suppressed 4-digit)

Unused:

Name PIC Note
primes-line X(132) Declared; not written to in current flow
primes-count 9(8) Declared; not used



3. Database Objects[edit]

3.1 Schema primes[edit]

Object Type Owner Description
primes SCHEMA primes_user Container schema for all application objects
asc_ident SEQUENCE primes_user Auto-incrementing identity for primes.ident
primes.primes TABLE primes_user The prime numbers store



3.2 Table primes.primes[edit]

DDL source: primes_schema.sql

<syntaxhighlight lang="sql">CREATE TABLE primes.primes (

   ident integer DEFAULT nextval('primes.asc_ident'::regclass),
   prime integer

);</syntaxhighlight>

Column Data type Nullable Default Description
ident INTEGER YES nextval('primes.asc_ident') Auto-assigned insertion sequence; acts as primary key but has no formal PK constraint
prime INTEGER YES The prime number value

⚠️ No PRIMARY KEY, UNIQUE constraint, or index is defined on either column. The ident column is the key used by r81-get-next-divider (SELECT prime WHERE ident = :new-ident). Without an index, this is a sequential scan. See Technical Specification — Defect T5 (performance concern).


3.3 Sequence primes.asc_ident[edit]

Attribute Value
Data type INTEGER
Start value 1
Increment 1
Minimum 1 (default)
Maximum 2,147,483,647 (INTEGER max)
Cache 1
Cycle No



3.4 Cursor primescursor (runtime)[edit]

Declared at compile time in primes.cbl. Opened and used only in the report path.

Attribute Value
Declaration DECLARE primescursor CURSOR FOR SELECT * FROM primes
Connection alias primes
Declared at Compile time in primes.cbl
Transaction Opened inside START TRANSACTION in s01-cursor
Opened at s01-cursor paragraph (EXEC SQL OPEN primescursor)
Fetch target primes-row group (r-ident, r-prime) — COMP-3 fields
Close Not explicit; closed implicitly when CONNECT RESET primes is issued

⚠️ SELECT * FROM primes is used. Best practice is to name columns explicitly (SELECT ident, prime FROM primes) to guard against schema changes. The pre-compiler listing (primes_cbsql.out) shows this was expanded from a SELECT ident, prime form in an earlier version.


Technical Specification | Flow Diagrams →