EPICS Component Reference Manual


EPICS Reference: Table Record (table) §

The table record holds a column-oriented table: a set of named columns, each an array of up to MAXROWS elements of a per-column data type. It is intended to be served over PV Access as a pvData NTTable; the bundled QSRV2 (pvxs) integration publishes the record's columns, labels and timestamp as the structured fields of an NTTable.

Rather than a single value field, the record exposes each column as a bundle of fixed-name fields, in the same spirit as the aSub record's A..U inputs. A column nn (hex 00..3F) is described by CnnNAME, CnnLABEL, CnnTYPE and CnnINP, with its data held in CnnVAL and its runtime status in CnnCHGD and CnnNROWS. Up to 64 such data columns may be configured.

A second family of up to 64 optional columns (COnn...) is provided for per-column metadata: each optional column carries exactly one value per data column (so it is sized to NUMCOLS rows, not MAXROWS) and is published alongside the table, typically as a column attribute.

Columns are configured statically in the database (or filled in by device support) and validated once, when the record initializes; thereafter the column layout is fixed and only the column data changes as the record processes.

Parameter Fields §

The record-specific fields are described below, grouped by function. The 64 data columns share an identical set of per-column fields, named with the column index 00..3F embedded in the field name (for example C00NAME, C01NAME, ..., C3FNAME); only the column 00 fields are tabulated here, the rest follow the same pattern. The 64 optional columns are named CO00.....CO3F... in the same way.

Scan Parameters §

The table record has the standard fields for specifying under what circumstances it will be processed. These fields are listed in Scan Fields.

Table Configuration §

INP is an optional input link for the record as a whole. Device support may use it (for example, the simulation and CSV device supports read their table description or contents through INP); the Soft Channel support ignores it and instead reads each column's own CnnINP link.

MAXROWS is the row capacity allocated for every data column. It must be set before initialization (it is read-only afterwards); if left at zero, init_record forces it to 1. Each data column's value buffer is allocated to hold MAXROWS elements.

NUMCOLS and NUMOPTCOLS report how many data and optional columns are active. They are not set by the user: init_record computes them by counting the configured (non-empty) column names, and they are read-only (SPC_NOMOD).

FieldSummaryTypeDCT DefaultReadWriteCA PP
INPInput SpecificationINLINKYes YesYesNo
MAXROWSMax number of rows per columnULONGNo1YesNoNo
NUMCOLSNumber of active columns (set by device support)ULONGNo YesNoNo
NUMOPTCOLSNumber of active optional columns (set by device support)ULONGNo YesNoNo

Data Columns (C00 .. C3F) §

Each data column is configured by four fields and exposes three more at runtime:

FieldSummaryTypeDCT DefaultReadWriteCA PP
C00NAMEColumn 00 nameSTRING [40]Yes YesNoNo
C00LABELColumn 00 labelSTRING [40]Yes YesYesNo
C00TYPEColumn 00 field typeMENU (menuFtype)YesDOUBLEYesNoNo
C00INPColumn 00 input linkINLINKYes YesYesNo
C00VALColumn 00 dataSet by C00TYPE[MAXROWS]No YesYesYes
C00NROWSColumn 00 number of valid rowsULONGNo YesNoNo
C00CHGDColumn 00 changed flagUCHARNo YesYesNo

Optional Columns (CO00 .. CO3F) §

Optional columns hold one value per data column rather than MAXROWS rows; an optional column's buffer is therefore sized to NUMCOLS elements. They are intended for per-column metadata (for example a units or description attribute for each data column) that is published together with the table.

They follow the same bundle pattern and the same validation rules as data columns, with one addition: an optional column name may contain a single dotted component, prefix.field (matching [A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?), which lets a consumer map the optional column onto a nested attribute. COnnNAME and COnnTYPE are fixed after initialization; COnnVAL, COnnNROWS and COnnCHGD behave as for data columns.

FieldSummaryTypeDCT DefaultReadWriteCA PP
CO00NAMEOptional column 00 nameSTRING [40]Yes YesNoNo
CO00TYPEOptional column 00 field typeMENU (menuFtype)YesDOUBLEYesNoNo
CO00INPOptional column 00 input linkINLINKYes YesYesNo
CO00VALOptional column 00 dataSet by CO00TYPE[NUMCOLS]No YesYesYes
CO00NROWSOptional column 00 number of valid rowsULONGNo YesNoNo
CO00CHGDOptional column 00 changed flagUCHARNo YesYesNo

Record Support §

Record Support Routines §

init_record §

Called twice (pass 0 then pass 1). On pass 0 it:

  1. Verifies that device support is attached: the DSET must be present, and must declare at least 5 routines with a non-NULL read_table. If not, an error is logged and initialization fails.

  2. Forces MAXROWS to 1 if it was left at 0.

  3. Calls the device support's init_record (if any) so it can allocate memory and fill in column names/types. If that routine returns TABLEREC_DEVINIT_PASS1 the record arranges to call it again in pass 1.

  4. Validates the data column names (format, uniqueness, no gaps as described above) and sets NUMCOLS to the number found. The optional column names are validated the same way and NUMOPTCOLS is set.

  5. Allocates any column value buffers not already provided by device support: MAXROWS elements for each data column, NUMCOLS elements for each optional column.

On pass 1, if device support requested it, the device init_record is called once more (now able to read links and other records).

process §

See "Record Processing" below.

special §

CnnVAL and COnnVAL accept array puts via special. Before the data lands (after=0), a STRING column's previous variable-length cells are released; after the put (after=1), the column's CHGD flag is set. Puts to inactive columns are rejected. The column NAME and TYPE fields are read-only at run time (SPC_NOMOD) and cannot be changed once the record has initialized.

cvt_dbaddr, get_array_info, put_array_info §

These present each CnnVAL/COnnVAL field as an array whose element type is the column's TYPE, whose capacity is MAXROWS (data) or NUMCOLS (optional columns), and whose current length is the column's NROWS.

Record Processing §

Routine process implements the following algorithm:

  1. If device support or its read_table routine is missing, set PACT TRUE, log an error and return, so processing is not retried (avoiding error storms).

  2. Clear the CHGD flag of every active data and optional column.

  3. Call the device support read_table routine to refresh the column data. If it succeeds, clear UDF.

  4. Update the time stamp and reset alarms.

  5. Post monitor events for the column data.

  6. If a publisher has registered a notify hook in RPVT (as the QSRV2 NTTable source does), call it synchronously while the record lock is held and this cycle's CHGD flags are still valid.

  7. Scan the forward link, set PACT FALSE and return.

Device Support §

Fields Of Interest To Device Support §

Device support obtains a fresh table whenever read_table is called, and is chiefly interested in the column buffers and counts.

FieldSummaryTypeDCT DefaultReadWriteCA PP
PACTRecord activeUCHARNo YesNoNo
DPVTDevice PrivateNOACCESSNo NoNoNo
UDFUndefinedUCHARYes1YesYesYes
NUMCOLSNumber of active columns (set by device support)ULONGNo YesNoNo
NUMOPTCOLSNumber of active optional columns (set by device support)ULONGNo YesNoNo
MAXROWSMax number of rows per columnULONGNo1YesNoNo

Device Support Interface §

A table device support entry table (tabledset) extends the standard DSET with one routine:

  typedef struct {
      dset common;                              /* standard 5-entry DSET   */
      long (*read_table)(struct tableRecord *prec);
  } tabledset;

read_table must refresh the active column buffers (and their NROWS) and return 0 on success. Device support that needs to allocate buffers or populate column names/types does so from common.init_record. Because reading links is only safe after all records exist, support that must read links at init returns TABLEREC_DEVINIT_PASS1 from its pass-0 init_record to ask the record to call it again in pass 1.

Device Support For Soft Records §

The Soft Channel support (devTableSoft) implements a table whose columns are driven by their individual CnnINP / COnnINP links. At initialization it loads any constant links into the column buffers; on each read_table it re-reads the non-constant links. STRING columns are staged through a temporary buffer and re-encoded into variable-length cells so that numeric-to-string conversions cannot leave stale bytes in a cell.

Variable Strings §

EPICS strings are normally limited to MAX_STRING_SIZE bytes (40), leaving at most 39 usable characters. STRING-typed columns use a variable-length string encoding (defined in tableVStr.h) that lets device support store strings of arbitrary length, including strings with embedded NUL bytes.

Each 40-byte cell in a STRING column buffer is stored in one of three formats, discriminated by two sentinel bytes within the cell:

PV Access clients (NTTable) always receive the full string regardless of encoding type. Channel Access and dbAccess clients see the ordinary DBF_STRING cell: the complete content for Types 1 and 2, and only the 31-byte UTF-8 preview for Type 3.

Writing long strings from device support §

Type 3 cells can only be produced by device support code. The C API in tableVStr.h provides:

  void tablerec_vstr_write(void *colbuf, epicsUInt32 row,
                           const char *bytes, epicsUInt32 len);

The C++ wrapper in tableRecordUtil.h provides write_string_column and vstr_write_cell as higher-level helpers. External writes via caput, dbpf, or PV Access are accepted but the DBF_STRING type caps them at 39 characters, so they produce at most a Type 2 cell.

Overflow heap blocks are freed automatically whenever a cell is overwritten or cleared. The special() handler also frees any overflow pointer before an external put can overwrite a cell, preventing leaks during normal IOC operation. All access to a STRING column buffer must be done while holding the record lock (dbScanLock / process / dbPutField).


EPICS Component Reference Manual