3.7. Binary Data Types

BLOBs (Binary Large Objects) are complex structures used to store text and binary data of an undefined length, often very large.

Syntax

BLOB [SUB_TYPE <subtype>]
  [SEGMENT SIZE <segment size>]
  [CHARACTER SET <character set>]

If the SUB_TYPE and CHARACTER SET clauses are absent, then subtype BINARY (or 0) is used. If the SUB_TYPE clause is absent and the CHARACTER SET clause is present, then subtype TEXT (or 1) is used.

Shortened syntax

BLOB (<segment size>)
BLOB (<segment size>, <subtype>)
BLOB (, <subtype>)

The COLLATE clause is part of the data type declaration since Firebird 6.0. In older versions, its position depends on the specific syntax of the statement. This other position can still be used, as long as COLLATE is only specified once.

3.7.1. BLOB Subtypes

The optional SUB_TYPE parameter specifies the nature of data written to the column. Firebird provides two pre-defined subtypes for storing user data:

Subtype 0: BINARY

If a subtype is not specified, the specification is assumed to be for untyped data and the default SUB_TYPE BINARY (or SUB_TYPE 0) is applied. This is the subtype to specify when the data are any form of binary file or stream: images, audio, word-processor files, PDFs and so on.

Subtype 1: TEXT

Subtype 1 has an alias, TEXT, which can be used in declarations and definitions. For instance, BLOB SUB_TYPE TEXT (or BLOB SUB_TYPE 1). It is a specialized subtype used to store plain text data that is too large to fit into a string type. A CHARACTER SET may be specified, if the field is to store text with a different encoding to that specified for the database. A COLLATE clause is also supported in some statements and expressions, but contrary to scalar character types, it’s not part of the data type declaration syntax.

Specifying CHARACTER SET without specifying a SUB_TYPE implies SUB_TYPE TEXT.

Internal subtypes

The Firebird engine uses other positive subtype numbers for internal subtypes in metadata.

Custom subtypes

Negative subtype numbers can be used for user-defined subtypes. Positive subtype numbers are reserved for use by Firebird.

Optionally, you can add a name for such custom subtypes. Custom subtype names can be inserted into the RDB$TYPES table by users with the system privilege CREATE_USER_TYPES.

Define a subtype GZIP with subtype number -21

insert into SYSTEM.RDB$TYPES
  (RDB$FIELD_SUB_TYPE, RDB$TYPE, RDB$TYPE_NAME,
   RDB$SYSTEM_FLAG, RDB$DESCRIPTION)
values
  ('RDB$FIELD_SUB_TYPE', -21, 'GZIP', 0, 'GZIP compressed data');

Both the subtype name and the subtype number can be used: BLOB SUB_TYPE GZIP or BLOB SUB_TYPE -21.

3.7.2. BLOB Specifics

SizeThe maximum size of a BLOB field depends on the page size of the database, whether the blob value is created as a stream blob or a segmented blob, and if segmented, the actual segment sizes used when populating the blob. For most built-in functions, the maximum size of a BLOB field is 4 GB, or data beyond the 4 GB limit is not addressable.

Operations and ExpressionsText BLOBs of any length and any character set can be operands for practically any statement or internal functions. The following operators are fully supported:

=

(assignment)

=, <>, <, <=, >, >=

(comparison)

||

(concatenation)

BETWEEN,

IS [NOT] DISTINCT FROM,

IN,

ANY | SOME,

ALL

 

As an efficient alternative to concatenation, you can also use BLOB_APPEND() or the functions and procedures of system package RDB$BLOB_UTIL.

Partial support:

  • An error occurs with these if the search argument is larger than or equal to 32 KB:

  • Aggregation clauses work not on the contents of the field itself, but on the BLOB ID. Aside from that, there are some quirks:

    SELECT DISTINCT

    returns several NULL values by mistake if they are present

    ORDER BY

     — 

    GROUP BY

    concatenates the same strings if they are adjacent to each other, but does not do it if they are remote from each other

BLOB Storage
  • By default, a regular record is created for each BLOB, and it is stored on a data page that is allocated for it. If the entire BLOB fits onto this page, it is called a level 0 BLOB. The number of this special record is stored in the table record and occupies 8 bytes.

  • If a BLOB does not fit onto one data page, its contents are put onto separate pages allocated exclusively to it (blob pages), while the numbers of these pages are stored into the BLOB record. This is a level 1 BLOB.

  • If the array of page numbers containing the BLOB data does not fit onto a data page, the array is put on separate blob pages, while the numbers of these pages are put into the BLOB record. This is a level 2 BLOB.

  • Levels higher than 2 are not supported.

See alsoFILTER, DECLARE FILTER, BLOB_APPEND(), RDB$BLOB_UTIL